From 3cf230660a2c244b5b91f10a9b5d4e2d89550526 Mon Sep 17 00:00:00 2001 From: sriramv Date: Mon, 23 Nov 2020 15:46:19 +0530 Subject: [PATCH] GOWTHAM --- .env | 101 + .github/workflows/phpunit.yml | 51 + .htaccess | 48 + README.md | 64 + app/.htaccess | 6 + app/Common.php | 15 + app/Config/App.php | 270 + app/Config/Autoload.php | 68 + app/Config/Boot/development.php | 32 + app/Config/Boot/production.php | 22 + app/Config/Boot/testing.php | 33 + app/Config/Cache.php | 120 + app/Config/Constants.php | 77 + app/Config/ContentSecurityPolicy.php | 48 + app/Config/Database.php | 114 + app/Config/DocTypes.php | 33 + app/Config/Email.php | 171 + app/Config/Encryption.php | 36 + app/Config/Events.php | 52 + app/Config/Exceptions.php | 42 + app/Config/Filters.php | 36 + app/Config/ForeignCharacters.php | 6 + app/Config/Format.php | 85 + app/Config/Honeypot.php | 42 + app/Config/Images.php | 31 + app/Config/Kint.php | 62 + app/Config/Logger.php | 132 + app/Config/Migrations.php | 50 + app/Config/Mimes.php | 530 ++ app/Config/Modules.php | 45 + app/Config/Pager.php | 35 + app/Config/Paths.php | 77 + app/Config/Routes.php | 67 + app/Config/Services.php | 30 + app/Config/Toolbar.php | 68 + app/Config/UserAgents.php | 218 + app/Config/Validation.php | 36 + app/Config/View.php | 34 + app/Controllers/BaseController.php | 46 + app/Controllers/Dashboard.php | 293 + app/Controllers/Donation.php | 41 + app/Controllers/Donor_controller.php | 145 + app/Controllers/Home.php | 81 + app/Controllers/My_controller.php | 141 + app/Controllers/UsersRules.php | 18 + app/Controllers/admin/Donation.php | 20 + app/Database/Migrations/.gitkeep | 0 app/Database/Seeds/.gitkeep | 0 app/Filters/.gitkeep | 0 app/Helpers/.gitkeep | 0 app/Language/.gitkeep | 0 app/Language/en/Validation.php | 4 + app/Libraries/.gitkeep | 0 app/Models/.gitkeep | 0 app/Models/Dashboard_model.php | 62 + app/Models/Donation_cause.php | 37 + app/Models/Donation_data_model.php | 37 + app/Models/Donation_model.php | 25 + app/Models/Donor_model.php | 60 + app/Models/My_model.php | 48 + app/Models/Receipt_model.php | 37 + app/Models/Transaction_model.php | 37 + app/ThirdParty/.gitkeep | 0 app/Validation/UsersRules.php | 19 + app/Views/add_donation_cause.php | 87 + app/Views/dashboard.php | 14 + app/Views/donation_data.php | 59 + app/Views/donation_data_edit.php | 59 + app/Views/donation_data_table.php | 40 + app/Views/donor_edit.php | 150 + app/Views/donor_registration.php | 156 + app/Views/donor_table.php | 45 + app/Views/edit_view.php | 9 + app/Views/errors/cli/error_404.php | 6 + app/Views/errors/cli/error_exception.php | 17 + app/Views/errors/cli/production.php | 5 + app/Views/errors/html/debug.css | 177 + app/Views/errors/html/debug.js | 127 + app/Views/errors/html/error_404.php | 84 + app/Views/errors/html/error_exception.php | 401 + app/Views/errors/html/production.php | 25 + app/Views/list.php | 26 + app/Views/login.php | 50 + app/Views/profile_view.php | 9 + app/Views/receipt_edit.php | 71 + app/Views/receipts.php | 70 + app/Views/receipts_table.php | 41 + app/Views/register.php | 145 + app/Views/show.php | 53 + app/Views/templates/footer.php | 2 + app/Views/templates/header.php | 556 ++ app/Views/transaction_edit.php | 59 + app/Views/transaction_table.php | 40 + app/Views/transaction_upload.php | 65 + app/Views/welcome_message.php | 324 + app/index.html | 11 + builds | 163 + composer.json | 33 + composer.lock | 2144 ++++++ env | 101 + index.php | 45 + license.txt | 22 + phpunit.xml.dist | 60 + public/.htaccess | 48 + public/assets/css/style.css | 3 + public/favicon.ico | Bin 0 -> 5430 bytes public/index.php | 45 + public/robots.txt | 2 + spark | 61 + tests/README.md | 108 + .../2020-02-22-222222_example_migration.php | 61 + .../_support/Database/Seeds/ExampleSeeder.php | 40 + tests/_support/DatabaseTestCase.php | 51 + tests/_support/Libraries/ConfigReader.php | 55 + tests/_support/Models/ExampleModel.php | 26 + tests/_support/SessionTestCase.php | 32 + tests/database/ExampleDatabaseTest.php | 42 + tests/session/ExampleSessionTest.php | 18 + tests/unit/HealthTest.php | 33 + vendor/autoload.php | 7 + vendor/bin/phpunit | 14 + vendor/bin/phpunit.bat | 4 + vendor/codeigniter4/framework/.gitignore | 127 + vendor/codeigniter4/framework/README.md | 57 + vendor/codeigniter4/framework/app/.htaccess | 6 + vendor/codeigniter4/framework/app/Common.php | 15 + .../codeigniter4/framework/app/Config/App.php | 268 + .../framework/app/Config/Autoload.php | 66 + .../framework/app/Config/Boot/development.php | 32 + .../framework/app/Config/Boot/production.php | 22 + .../framework/app/Config/Boot/testing.php | 33 + .../framework/app/Config/Cache.php | 120 + .../framework/app/Config/Constants.php | 77 + .../app/Config/ContentSecurityPolicy.php | 48 + .../framework/app/Config/Database.php | 114 + .../framework/app/Config/DocTypes.php | 33 + .../framework/app/Config/Email.php | 171 + .../framework/app/Config/Encryption.php | 36 + .../framework/app/Config/Events.php | 52 + .../framework/app/Config/Exceptions.php | 42 + .../framework/app/Config/Filters.php | 36 + .../app/Config/ForeignCharacters.php | 6 + .../framework/app/Config/Format.php | 85 + .../framework/app/Config/Honeypot.php | 42 + .../framework/app/Config/Images.php | 31 + .../framework/app/Config/Kint.php | 62 + .../framework/app/Config/Logger.php | 132 + .../framework/app/Config/Migrations.php | 50 + .../framework/app/Config/Mimes.php | 530 ++ .../framework/app/Config/Modules.php | 45 + .../framework/app/Config/Pager.php | 35 + .../framework/app/Config/Paths.php | 73 + .../framework/app/Config/Routes.php | 51 + .../framework/app/Config/Services.php | 30 + .../framework/app/Config/Toolbar.php | 68 + .../framework/app/Config/UserAgents.php | 218 + .../framework/app/Config/Validation.php | 36 + .../framework/app/Config/View.php | 34 + .../app/Controllers/BaseController.php | 46 + .../framework/app/Controllers/Home.php | 12 + .../app/Database/Migrations/.gitkeep | 0 .../framework/app/Database/Seeds/.gitkeep | 0 .../framework/app/Filters/.gitkeep | 0 .../framework/app/Helpers/.gitkeep | 0 .../framework/app/Language/.gitkeep | 0 .../framework/app/Language/en/Validation.php | 4 + .../framework/app/Libraries/.gitkeep | 0 .../framework/app/Models/.gitkeep | 0 .../framework/app/ThirdParty/.gitkeep | 0 .../app/Views/errors/cli/error_404.php | 6 + .../app/Views/errors/cli/error_exception.php | 17 + .../app/Views/errors/cli/production.php | 5 + .../framework/app/Views/errors/html/debug.css | 177 + .../framework/app/Views/errors/html/debug.js | 127 + .../app/Views/errors/html/error_404.php | 84 + .../app/Views/errors/html/error_exception.php | 401 + .../app/Views/errors/html/production.php | 25 + .../framework/app/Views/welcome_message.php | 324 + vendor/codeigniter4/framework/app/index.html | 11 + vendor/codeigniter4/framework/composer.json | 42 + vendor/codeigniter4/framework/env | 101 + vendor/codeigniter4/framework/license.txt | 22 + .../codeigniter4/framework/phpunit.xml.dist | 60 + .../codeigniter4/framework/public/.htaccess | 48 + .../codeigniter4/framework/public/favicon.ico | Bin 0 -> 5430 bytes .../codeigniter4/framework/public/index.php | 45 + .../codeigniter4/framework/public/robots.txt | 2 + vendor/codeigniter4/framework/spark | 61 + .../codeigniter4/framework/system/.htaccess | 6 + .../framework/system/API/ResponseTrait.php | 430 ++ .../system/Autoloader/Autoloader.php | 435 ++ .../system/Autoloader/FileLocator.php | 505 ++ .../framework/system/CLI/BaseCommand.php | 269 + .../codeigniter4/framework/system/CLI/CLI.php | 1169 +++ .../framework/system/CLI/CommandRunner.php | 119 + .../framework/system/CLI/Commands.php | 181 + .../framework/system/CLI/Console.php | 106 + .../system/CLI/Exceptions/CLIException.php | 60 + .../framework/system/Cache/CacheFactory.php | 117 + .../framework/system/Cache/CacheInterface.php | 154 + .../Cache/Exceptions/CacheException.php | 87 + .../Cache/Exceptions/ExceptionInterface.php | 49 + .../system/Cache/Handlers/DummyHandler.php | 185 + .../system/Cache/Handlers/FileHandler.php | 535 ++ .../Cache/Handlers/MemcachedHandler.php | 388 + .../system/Cache/Handlers/PredisHandler.php | 306 + .../system/Cache/Handlers/RedisHandler.php | 352 + .../system/Cache/Handlers/WincacheHandler.php | 263 + .../framework/system/CodeIgniter.php | 1129 +++ .../system/Commands/Cache/ClearCache.php | 73 + .../Commands/Database/CreateMigration.php | 186 + .../system/Commands/Database/CreateSeeder.php | 169 + .../system/Commands/Database/Migrate.php | 167 + .../Commands/Database/MigrateRefresh.php | 127 + .../Commands/Database/MigrateRollback.php | 151 + .../Commands/Database/MigrateStatus.php | 192 + .../system/Commands/Database/Seed.php | 132 + .../framework/system/Commands/Help.php | 121 + .../system/Commands/ListCommands.php | 196 + .../system/Commands/Server/Serve.php | 168 + .../system/Commands/Server/rewrite.php | 35 + .../Commands/Sessions/CreateMigration.php | 136 + .../Commands/Sessions/Views/migration.tpl.php | 52 + .../system/Commands/Utilities/Namespaces.php | 131 + .../system/Commands/Utilities/Routes.php | 150 + .../codeigniter4/framework/system/Common.php | 1142 +++ .../framework/system/ComposerScripts.php | 248 + .../system/Config/AutoloadConfig.php | 113 + .../framework/system/Config/BaseConfig.php | 247 + .../framework/system/Config/BaseService.php | 300 + .../framework/system/Config/Config.php | 161 + .../framework/system/Config/DotEnv.php | 325 + .../system/Config/ForeignCharacters.php | 143 + .../framework/system/Config/Routes.php | 66 + .../framework/system/Config/Services.php | 944 +++ .../framework/system/Config/View.php | 107 + .../framework/system/Controller.php | 223 + .../framework/system/Database/BaseBuilder.php | 3492 +++++++++ .../system/Database/BaseConnection.php | 1883 +++++ .../system/Database/BasePreparedQuery.php | 274 + .../framework/system/Database/BaseResult.php | 631 ++ .../framework/system/Database/BaseUtils.php | 423 ++ .../framework/system/Database/Config.php | 199 + .../system/Database/ConnectionInterface.php | 225 + .../framework/system/Database/Database.php | 138 + .../Database/Exceptions/DataException.php | 65 + .../Database/Exceptions/DatabaseException.php | 51 + .../Exceptions/ExceptionInterface.php | 13 + .../framework/system/Database/Forge.php | 1328 ++++ .../framework/system/Database/Migration.php | 110 + .../system/Database/MigrationRunner.php | 1064 +++ .../system/Database/ModelFactory.php | 111 + .../system/Database/MySQLi/Builder.php | 88 + .../system/Database/MySQLi/Connection.php | 742 ++ .../system/Database/MySQLi/Forge.php | 279 + .../system/Database/MySQLi/PreparedQuery.php | 135 + .../system/Database/MySQLi/Result.php | 211 + .../system/Database/MySQLi/Utils.php | 80 + .../system/Database/Postgre/Builder.php | 433 ++ .../system/Database/Postgre/Connection.php | 626 ++ .../system/Database/Postgre/Forge.php | 261 + .../system/Database/Postgre/PreparedQuery.php | 158 + .../system/Database/Postgre/Result.php | 173 + .../system/Database/Postgre/Utils.php | 79 + .../Database/PreparedQueryInterface.php | 106 + .../framework/system/Database/Query.php | 504 ++ .../system/Database/QueryInterface.php | 159 + .../system/Database/ResultInterface.php | 264 + .../system/Database/SQLite3/Builder.php | 109 + .../system/Database/SQLite3/Connection.php | 566 ++ .../system/Database/SQLite3/Forge.php | 331 + .../system/Database/SQLite3/PreparedQuery.php | 143 + .../system/Database/SQLite3/Result.php | 207 + .../system/Database/SQLite3/Table.php | 440 ++ .../system/Database/SQLite3/Utils.php | 73 + .../framework/system/Database/Seeder.php | 231 + .../framework/system/Debug/Exceptions.php | 513 ++ .../framework/system/Debug/Iterator.php | 179 + .../framework/system/Debug/Timer.php | 181 + .../framework/system/Debug/Toolbar.php | 514 ++ .../Toolbar/Collectors/BaseCollector.php | 318 + .../Debug/Toolbar/Collectors/Config.php | 71 + .../Debug/Toolbar/Collectors/Database.php | 278 + .../Debug/Toolbar/Collectors/Events.php | 187 + .../system/Debug/Toolbar/Collectors/Files.php | 151 + .../Debug/Toolbar/Collectors/History.php | 183 + .../system/Debug/Toolbar/Collectors/Logs.php | 139 + .../Debug/Toolbar/Collectors/Routes.php | 202 + .../Debug/Toolbar/Collectors/Timers.php | 107 + .../system/Debug/Toolbar/Collectors/Views.php | 192 + .../system/Debug/Toolbar/Views/_config.tpl | 48 + .../system/Debug/Toolbar/Views/_database.tpl | 16 + .../system/Debug/Toolbar/Views/_events.tpl | 18 + .../system/Debug/Toolbar/Views/_files.tpl | 16 + .../system/Debug/Toolbar/Views/_history.tpl | 28 + .../system/Debug/Toolbar/Views/_logs.tpl | 20 + .../system/Debug/Toolbar/Views/_routes.tpl | 52 + .../system/Debug/Toolbar/Views/toolbar.css | 609 ++ .../system/Debug/Toolbar/Views/toolbar.js | 661 ++ .../Debug/Toolbar/Views/toolbar.tpl.php | 307 + .../Debug/Toolbar/Views/toolbarloader.js.php | 90 + .../framework/system/Email/Email.php | 2188 ++++++ .../system/Encryption/EncrypterInterface.php | 67 + .../system/Encryption/Encryption.php | 208 + .../Exceptions/EncryptionException.php | 41 + .../Encryption/Handlers/BaseHandler.php | 124 + .../Encryption/Handlers/OpenSSLHandler.php | 175 + .../codeigniter4/framework/system/Entity.php | 614 ++ .../framework/system/Events/Events.php | 348 + .../system/Exceptions/AlertError.php | 10 + .../system/Exceptions/CastException.php | 36 + .../system/Exceptions/ConfigException.php | 21 + .../system/Exceptions/CriticalError.php | 10 + .../system/Exceptions/DownloadException.php | 36 + .../system/Exceptions/EmergencyError.php | 10 + .../system/Exceptions/ExceptionInterface.php | 12 + .../system/Exceptions/FrameworkException.php | 38 + .../system/Exceptions/ModelException.php | 18 + .../Exceptions/PageNotFoundException.php | 31 + .../system/Files/Exceptions/FileException.php | 13 + .../Exceptions/FileNotFoundException.php | 11 + .../framework/system/Files/File.php | 248 + .../framework/system/Filters/CSRF.php | 117 + .../framework/system/Filters/DebugToolbar.php | 82 + .../Filters/Exceptions/FilterException.php | 74 + .../system/Filters/FilterInterface.php | 85 + .../framework/system/Filters/Filters.php | 516 ++ .../framework/system/Filters/Honeypot.php | 86 + .../Format/Exceptions/FormatException.php | 22 + .../system/Format/FormatterInterface.php | 56 + .../framework/system/Format/JSONFormatter.php | 78 + .../framework/system/Format/XMLFormatter.php | 119 + .../framework/system/HTTP/CLIRequest.php | 254 + .../framework/system/HTTP/CURLRequest.php | 830 ++ .../system/HTTP/ContentSecurityPolicy.php | 849 +++ .../system/HTTP/DownloadResponse.php | 549 ++ .../system/HTTP/Exceptions/HTTPException.php | 264 + .../system/HTTP/Files/FileCollection.php | 325 + .../system/HTTP/Files/UploadedFile.php | 414 + .../HTTP/Files/UploadedFileInterface.php | 203 + .../framework/system/HTTP/Header.php | 239 + .../framework/system/HTTP/IncomingRequest.php | 822 ++ .../framework/system/HTTP/Message.php | 402 + .../framework/system/HTTP/Negotiate.php | 463 ++ .../system/HTTP/RedirectResponse.php | 231 + .../framework/system/HTTP/Request.php | 478 ++ .../system/HTTP/RequestInterface.php | 94 + .../framework/system/HTTP/Response.php | 1087 +++ .../system/HTTP/ResponseInterface.php | 274 + .../framework/system/HTTP/URI.php | 1194 +++ .../framework/system/HTTP/UserAgent.php | 502 ++ .../framework/system/Helpers/array_helper.php | 124 + .../system/Helpers/cookie_helper.php | 123 + .../framework/system/Helpers/date_helper.php | 102 + .../system/Helpers/filesystem_helper.php | 512 ++ .../framework/system/Helpers/form_helper.php | 969 +++ .../framework/system/Helpers/html_helper.php | 729 ++ .../system/Helpers/inflector_helper.php | 404 + .../system/Helpers/number_helper.php | 341 + .../system/Helpers/security_helper.php | 99 + .../framework/system/Helpers/test_helper.php | 73 + .../framework/system/Helpers/text_helper.php | 883 +++ .../framework/system/Helpers/url_helper.php | 636 ++ .../framework/system/Helpers/xml_helper.php | 95 + .../Honeypot/Exceptions/HoneypotException.php | 28 + .../framework/system/Honeypot/Honeypot.php | 138 + .../system/I18n/Exceptions/I18nException.php | 128 + .../framework/system/I18n/Time.php | 1365 ++++ .../framework/system/I18n/TimeDifference.php | 364 + .../Images/Exceptions/ImageException.php | 57 + .../system/Images/Handlers/BaseHandler.php | 876 +++ .../system/Images/Handlers/GDHandler.php | 620 ++ .../Images/Handlers/ImageMagickHandler.php | 563 ++ .../framework/system/Images/Image.php | 175 + .../system/Images/ImageHandlerInterface.php | 210 + .../framework/system/Language/Language.php | 369 + .../framework/system/Language/en/CLI.php | 24 + .../framework/system/Language/en/Cache.php | 22 + .../framework/system/Language/en/Cast.php | 23 + .../framework/system/Language/en/Core.php | 23 + .../framework/system/Language/en/Database.php | 33 + .../framework/system/Language/en/Email.php | 36 + .../system/Language/en/Encryption.php | 23 + .../framework/system/Language/en/Entity.php | 18 + .../system/Language/en/Fabricator.php | 20 + .../framework/system/Language/en/Files.php | 19 + .../framework/system/Language/en/Filters.php | 20 + .../framework/system/Language/en/Format.php | 20 + .../framework/system/Language/en/HTTP.php | 77 + .../framework/system/Language/en/Images.php | 38 + .../framework/system/Language/en/Language.php | 19 + .../framework/system/Language/en/Log.php | 19 + .../system/Language/en/Migrations.php | 58 + .../framework/system/Language/en/Number.php | 30 + .../framework/system/Language/en/Pager.php | 27 + .../framework/system/Language/en/RESTful.php | 18 + .../framework/system/Language/en/Redirect.php | 19 + .../framework/system/Language/en/Router.php | 20 + .../framework/system/Language/en/Seed.php | 21 + .../framework/system/Language/en/Session.php | 23 + .../framework/system/Language/en/Time.php | 36 + .../system/Language/en/Validation.php | 75 + .../framework/system/Language/en/View.php | 23 + .../system/Log/Exceptions/LogException.php | 13 + .../system/Log/Handlers/BaseHandler.php | 121 + .../Log/Handlers/ChromeLoggerHandler.php | 216 + .../system/Log/Handlers/FileHandler.php | 164 + .../system/Log/Handlers/HandlerInterface.php | 85 + .../framework/system/Log/Logger.php | 541 ++ .../codeigniter4/framework/system/Model.php | 1842 +++++ .../framework/system/Modules/Modules.php | 88 + .../Pager/Exceptions/PagerException.php | 17 + .../framework/system/Pager/Pager.php | 580 ++ .../framework/system/Pager/PagerInterface.php | 228 + .../framework/system/Pager/PagerRenderer.php | 428 ++ .../system/Pager/Views/default_full.php | 46 + .../system/Pager/Views/default_head.php | 18 + .../system/Pager/Views/default_simple.php | 21 + .../system/RESTful/ResourceController.php | 203 + .../system/RESTful/ResourcePresenter.php | 206 + .../Router/Exceptions/RedirectException.php | 53 + .../Router/Exceptions/RouterException.php | 70 + .../system/Router/RouteCollection.php | 1588 ++++ .../Router/RouteCollectionInterface.php | 276 + .../framework/system/Router/Router.php | 725 ++ .../system/Router/RouterInterface.php | 115 + .../Security/Exceptions/SecurityException.php | 12 + .../framework/system/Security/Security.php | 389 + .../Session/Exceptions/SessionException.php | 32 + .../system/Session/Handlers/ArrayHandler.php | 150 + .../system/Session/Handlers/BaseHandler.php | 218 + .../Session/Handlers/DatabaseHandler.php | 430 ++ .../system/Session/Handlers/FileHandler.php | 422 ++ .../Session/Handlers/MemcachedHandler.php | 405 + .../system/Session/Handlers/RedisHandler.php | 424 ++ .../framework/system/Session/Session.php | 1023 +++ .../system/Session/SessionInterface.php | 251 + .../system/Test/CIDatabaseTestCase.php | 388 + .../framework/system/Test/CIUnitTestCase.php | 361 + .../system/Test/ControllerResponse.php | 227 + .../system/Test/ControllerTester.php | 316 + .../framework/system/Test/DOMParser.php | 359 + .../framework/system/Test/Fabricator.php | 648 ++ .../framework/system/Test/FeatureResponse.php | 439 ++ .../framework/system/Test/FeatureTestCase.php | 75 + .../system/Test/FeatureTestTrait.php | 338 + .../Test/Filters/CITestStreamFilter.php | 81 + .../Test/Interfaces/FabricatorModel.php | 109 + .../system/Test/Mock/MockAppConfig.php | 34 + .../system/Test/Mock/MockAutoload.php | 21 + .../system/Test/Mock/MockBuilder.php | 15 + .../system/Test/Mock/MockCLIConfig.php | 32 + .../system/Test/Mock/MockCURLRequest.php | 50 + .../framework/system/Test/Mock/MockCache.php | 198 + .../system/Test/Mock/MockCodeIgniter.php | 11 + .../framework/system/Test/Mock/MockCommon.php | 37 + .../system/Test/Mock/MockConnection.php | 297 + .../framework/system/Test/Mock/MockEmail.php | 31 + .../framework/system/Test/Mock/MockEvents.php | 66 + .../system/Test/Mock/MockFileLogger.php | 25 + .../system/Test/Mock/MockIncomingRequest.php | 17 + .../system/Test/Mock/MockLanguage.php | 61 + .../framework/system/Test/Mock/MockLogger.php | 98 + .../framework/system/Test/Mock/MockQuery.php | 8 + .../Test/Mock/MockResourceController.php | 23 + .../Test/Mock/MockResourcePresenter.php | 23 + .../system/Test/Mock/MockResponse.php | 30 + .../framework/system/Test/Mock/MockResult.php | 93 + .../system/Test/Mock/MockSecurity.php | 17 + .../system/Test/Mock/MockServices.php | 27 + .../system/Test/Mock/MockSession.php | 72 + .../framework/system/Test/Mock/MockTable.php | 16 + .../system/Test/ReflectionHelper.php | 128 + .../framework/system/Test/TestLogger.php | 82 + .../framework/system/Test/bootstrap.php | 67 + .../system/ThirdParty/Escaper/Escaper.php | 391 + .../Escaper/Exception/ExceptionInterface.php | 13 + .../Exception/InvalidArgumentException.php | 17 + .../Escaper/Exception/RuntimeException.php | 17 + .../system/ThirdParty/Kint/CallFinder.php | 473 ++ .../framework/system/ThirdParty/Kint/Kint.php | 756 ++ .../ThirdParty/Kint/Object/BasicObject.php | 248 + .../ThirdParty/Kint/Object/BlobObject.php | 177 + .../ThirdParty/Kint/Object/ClosureObject.php | 68 + .../ThirdParty/Kint/Object/DateTimeObject.php | 53 + .../ThirdParty/Kint/Object/InstanceObject.php | 78 + .../ThirdParty/Kint/Object/MethodObject.php | 253 + .../Kint/Object/ParameterObject.php | 100 + .../Representation/ColorRepresentation.php | 576 ++ .../DocstringRepresentation.php | 73 + .../MicrotimeRepresentation.php | 71 + .../Object/Representation/Representation.php | 71 + .../Representation/SourceRepresentation.php | 72 + .../SplFileInfoRepresentation.php | 177 + .../ThirdParty/Kint/Object/ResourceObject.php | 49 + .../ThirdParty/Kint/Object/StreamObject.php | 54 + .../Kint/Object/ThrowableObject.php | 54 + .../Kint/Object/TraceFrameObject.php | 100 + .../ThirdParty/Kint/Object/TraceObject.php | 45 + .../Kint/Parser/ArrayObjectPlugin.php | 63 + .../ThirdParty/Kint/Parser/Base64Plugin.php | 95 + .../ThirdParty/Kint/Parser/BinaryPlugin.php | 49 + .../Kint/Parser/BlacklistPlugin.php | 143 + .../Kint/Parser/ClassMethodsPlugin.php | 113 + .../Kint/Parser/ClassStaticsPlugin.php | 122 + .../ThirdParty/Kint/Parser/ClosurePlugin.php | 94 + .../ThirdParty/Kint/Parser/ColorPlugin.php | 63 + .../Kint/Parser/DOMDocumentPlugin.php | 328 + .../ThirdParty/Kint/Parser/DateTimePlugin.php | 55 + .../ThirdParty/Kint/Parser/FsPathPlugin.php | 72 + .../ThirdParty/Kint/Parser/IteratorPlugin.php | 110 + .../ThirdParty/Kint/Parser/JsonPlugin.php | 73 + .../Kint/Parser/MicrotimePlugin.php | 105 + .../ThirdParty/Kint/Parser/MysqliPlugin.php | 129 + .../system/ThirdParty/Kint/Parser/Parser.php | 604 ++ .../system/ThirdParty/Kint/Parser/Plugin.php | 55 + .../ThirdParty/Kint/Parser/ProxyPlugin.php | 66 + .../Kint/Parser/SerializePlugin.php | 108 + .../Kint/Parser/SimpleXMLElementPlugin.php | 154 + .../Kint/Parser/SplFileInfoPlugin.php | 55 + .../Kint/Parser/SplObjectStoragePlugin.php | 54 + .../ThirdParty/Kint/Parser/StreamPlugin.php | 78 + .../ThirdParty/Kint/Parser/TablePlugin.php | 87 + .../Kint/Parser/ThrowablePlugin.php | 60 + .../Kint/Parser/TimestampPlugin.php | 71 + .../ThirdParty/Kint/Parser/ToStringPlugin.php | 67 + .../ThirdParty/Kint/Parser/TracePlugin.php | 92 + .../ThirdParty/Kint/Parser/XmlPlugin.php | 150 + .../ThirdParty/Kint/Renderer/CliRenderer.php | 152 + .../Kint/Renderer/PlainRenderer.php | 237 + .../ThirdParty/Kint/Renderer/Renderer.php | 185 + .../Kint/Renderer/Rich/BinaryPlugin.php | 51 + .../Kint/Renderer/Rich/BlacklistPlugin.php | 36 + .../Kint/Renderer/Rich/CallablePlugin.php | 174 + .../Kint/Renderer/Rich/ClosurePlugin.php | 59 + .../Kint/Renderer/Rich/ColorPlugin.php | 100 + .../Kint/Renderer/Rich/DepthLimitPlugin.php | 36 + .../Kint/Renderer/Rich/DocstringPlugin.php | 70 + .../Kint/Renderer/Rich/MicrotimePlugin.php | 68 + .../Renderer/Rich/ObjectPluginInterface.php | 33 + .../ThirdParty/Kint/Renderer/Rich/Plugin.php | 90 + .../Kint/Renderer/Rich/PluginInterface.php | 33 + .../Kint/Renderer/Rich/RecursionPlugin.php | 36 + .../Renderer/Rich/SimpleXMLElementPlugin.php | 81 + .../Kint/Renderer/Rich/SourcePlugin.php | 79 + .../Kint/Renderer/Rich/TabPluginInterface.php | 33 + .../Kint/Renderer/Rich/TablePlugin.php | 133 + .../Kint/Renderer/Rich/TimestampPlugin.php | 42 + .../Kint/Renderer/Rich/TraceFramePlugin.php | 68 + .../ThirdParty/Kint/Renderer/RichRenderer.php | 612 ++ .../Kint/Renderer/Text/BlacklistPlugin.php | 44 + .../Kint/Renderer/Text/DepthLimitPlugin.php | 44 + .../Kint/Renderer/Text/MicrotimePlugin.php | 128 + .../ThirdParty/Kint/Renderer/Text/Plugin.php | 41 + .../Kint/Renderer/Text/RecursionPlugin.php | 44 + .../Kint/Renderer/Text/TracePlugin.php | 111 + .../ThirdParty/Kint/Renderer/TextRenderer.php | 346 + .../system/ThirdParty/Kint/Utils.php | 240 + .../framework/system/ThirdParty/Kint/init.php | 62 + .../system/ThirdParty/Kint/init_helpers.php | 84 + .../Kint/resources/compiled/aante-light.css | 1 + .../Kint/resources/compiled/microtime.js | 1 + .../Kint/resources/compiled/original.css | 1 + .../Kint/resources/compiled/plain.css | 1 + .../Kint/resources/compiled/plain.js | 1 + .../Kint/resources/compiled/rich.js | 1 + .../Kint/resources/compiled/shared.js | 1 + .../resources/compiled/solarized-dark.css | 1 + .../Kint/resources/compiled/solarized.css | 1 + .../ThirdParty/PSR/Log/AbstractLogger.php | 120 + .../PSR/Log/InvalidArgumentException.php | 7 + .../system/ThirdParty/PSR/Log/LogLevel.php | 18 + .../PSR/Log/LoggerAwareInterface.php | 17 + .../ThirdParty/PSR/Log/LoggerAwareTrait.php | 22 + .../ThirdParty/PSR/Log/LoggerInterface.php | 112 + .../system/ThirdParty/PSR/Log/LoggerTrait.php | 131 + .../system/ThirdParty/PSR/Log/NullLogger.php | 27 + .../framework/system/Throttle/Throttler.php | 212 + .../system/Throttle/ThrottlerInterface.php | 76 + .../system/Typography/Typography.php | 408 + .../system/Validation/CreditCardRules.php | 337 + .../Exceptions/ValidationException.php | 32 + .../framework/system/Validation/FileRules.php | 357 + .../system/Validation/FormatRules.php | 400 + .../framework/system/Validation/Rules.php | 450 ++ .../system/Validation/Validation.php | 868 +++ .../system/Validation/ValidationInterface.php | 166 + .../system/Validation/Views/list.php | 9 + .../system/Validation/Views/single.php | 1 + .../framework/system/View/Cell.php | 283 + .../system/View/Exceptions/ViewException.php | 37 + .../framework/system/View/Filters.php | 361 + .../framework/system/View/Parser.php | 867 +++ .../framework/system/View/Plugins.php | 169 + .../system/View/RendererInterface.php | 123 + .../framework/system/View/Table.php | 580 ++ .../framework/system/View/View.php | 565 ++ .../framework/system/bootstrap.php | 183 + .../codeigniter4/framework/system/index.html | 11 + .../codeigniter4/framework/writable/.htaccess | 6 + .../framework/writable/cache/index.html | 11 + .../framework/writable/logs/index.html | 11 + .../framework/writable/session/index.html | 11 + .../framework/writable/uploads/index.html | 11 + vendor/composer/ClassLoader.php | 445 ++ vendor/composer/LICENSE | 21 + vendor/composer/autoload_classmap.php | 594 ++ vendor/composer/autoload_files.php | 13 + vendor/composer/autoload_namespaces.php | 11 + vendor/composer/autoload_psr4.php | 25 + vendor/composer/autoload_real.php | 73 + vendor/composer/autoload_static.php | 749 ++ vendor/composer/installed.json | 2202 ++++++ .../instantiator/.doctrine-project.json | 26 + .../doctrine/instantiator/.github/FUNDING.yml | 3 + vendor/doctrine/instantiator/CONTRIBUTING.md | 35 + vendor/doctrine/instantiator/LICENSE | 19 + vendor/doctrine/instantiator/README.md | 39 + vendor/doctrine/instantiator/composer.json | 52 + .../doctrine/instantiator/docs/en/index.rst | 68 + .../doctrine/instantiator/docs/en/sidebar.rst | 4 + vendor/doctrine/instantiator/phpbench.json | 4 + vendor/doctrine/instantiator/phpcs.xml.dist | 35 + .../doctrine/instantiator/phpstan.neon.dist | 19 + .../Exception/ExceptionInterface.php | 12 + .../Exception/InvalidArgumentException.php | 37 + .../Exception/UnexpectedValueException.php | 48 + .../Doctrine/Instantiator/Instantiator.php | 203 + .../Instantiator/InstantiatorInterface.php | 20 + vendor/dompdf/dompdf/CONTRIBUTING.md | 65 + vendor/dompdf/dompdf/LICENSE.LGPL | 456 ++ vendor/dompdf/dompdf/README.md | 224 + vendor/dompdf/dompdf/VERSION | 1 + vendor/dompdf/dompdf/composer.json | 57 + vendor/dompdf/dompdf/lib/Cpdf.php | 6466 ++++++++++++++++ .../dompdf/dompdf/lib/fonts/Courier-Bold.afm | 344 + .../dompdf/lib/fonts/Courier-BoldOblique.afm | 344 + .../dompdf/lib/fonts/Courier-Oblique.afm | 344 + vendor/dompdf/dompdf/lib/fonts/Courier.afm | 344 + .../dompdf/lib/fonts/DejaVuSans-Bold.ttf | Bin 0 -> 705684 bytes .../dompdf/lib/fonts/DejaVuSans-Bold.ufm | 6067 +++++++++++++++ .../lib/fonts/DejaVuSans-BoldOblique.ttf | Bin 0 -> 643292 bytes .../lib/fonts/DejaVuSans-BoldOblique.ufm | 5712 ++++++++++++++ .../dompdf/lib/fonts/DejaVuSans-Oblique.ttf | Bin 0 -> 635416 bytes .../dompdf/lib/fonts/DejaVuSans-Oblique.ufm | 5268 +++++++++++++ vendor/dompdf/dompdf/lib/fonts/DejaVuSans.ttf | Bin 0 -> 757076 bytes vendor/dompdf/dompdf/lib/fonts/DejaVuSans.ufm | 6661 +++++++++++++++++ .../dompdf/lib/fonts/DejaVuSansMono-Bold.ttf | Bin 0 -> 331992 bytes .../dompdf/lib/fonts/DejaVuSansMono-Bold.ufm | 3285 ++++++++ .../lib/fonts/DejaVuSansMono-BoldOblique.ttf | Bin 0 -> 253580 bytes .../lib/fonts/DejaVuSansMono-BoldOblique.ufm | 2707 +++++++ .../lib/fonts/DejaVuSansMono-Oblique.ttf | Bin 0 -> 251932 bytes .../lib/fonts/DejaVuSansMono-Oblique.ufm | 2707 +++++++ .../dompdf/lib/fonts/DejaVuSansMono.ttf | Bin 0 -> 340712 bytes .../dompdf/lib/fonts/DejaVuSansMono.ufm | 3284 ++++++++ .../dompdf/lib/fonts/DejaVuSerif-Bold.ttf | Bin 0 -> 356088 bytes .../dompdf/lib/fonts/DejaVuSerif-Bold.ufm | 4013 ++++++++++ .../lib/fonts/DejaVuSerif-BoldItalic.ttf | Bin 0 -> 347460 bytes .../lib/fonts/DejaVuSerif-BoldItalic.ufm | 3892 ++++++++++ .../dompdf/lib/fonts/DejaVuSerif-Italic.ttf | Bin 0 -> 345996 bytes .../dompdf/lib/fonts/DejaVuSerif-Italic.ufm | 3883 ++++++++++ .../dompdf/dompdf/lib/fonts/DejaVuSerif.ttf | Bin 0 -> 380132 bytes .../dompdf/dompdf/lib/fonts/DejaVuSerif.ufm | 4012 ++++++++++ .../dompdf/lib/fonts/Helvetica-Bold.afm | 2829 +++++++ .../lib/fonts/Helvetica-BoldOblique.afm | 2829 +++++++ .../dompdf/lib/fonts/Helvetica-Oblique.afm | 3053 ++++++++ vendor/dompdf/dompdf/lib/fonts/Helvetica.afm | 3053 ++++++++ vendor/dompdf/dompdf/lib/fonts/Symbol.afm | 213 + vendor/dompdf/dompdf/lib/fonts/Times-Bold.afm | 2590 +++++++ .../dompdf/lib/fonts/Times-BoldItalic.afm | 2386 ++++++ .../dompdf/dompdf/lib/fonts/Times-Italic.afm | 2669 +++++++ .../dompdf/dompdf/lib/fonts/Times-Roman.afm | 2421 ++++++ .../dompdf/dompdf/lib/fonts/ZapfDingbats.afm | 225 + .../fonts/dompdf_font_family_cache.dist.php | 95 + vendor/dompdf/dompdf/lib/fonts/mustRead.html | 17 + vendor/dompdf/dompdf/lib/html5lib/Data.php | 123 + .../dompdf/lib/html5lib/InputStream.php | 299 + vendor/dompdf/dompdf/lib/html5lib/Parser.php | 37 + .../dompdf/dompdf/lib/html5lib/Tokenizer.php | 2470 ++++++ .../dompdf/lib/html5lib/TreeBuilder.php | 3989 ++++++++++ .../html5lib/named-character-references.ser | 1 + vendor/dompdf/dompdf/lib/res/broken_image.png | Bin 0 -> 618 bytes vendor/dompdf/dompdf/lib/res/broken_image.svg | 8 + vendor/dompdf/dompdf/lib/res/html.css | 527 ++ vendor/dompdf/dompdf/phpcs.xml | 142 + vendor/dompdf/dompdf/src/Adapter/CPDF.php | 1225 +++ vendor/dompdf/dompdf/src/Adapter/GD.php | 1113 +++ vendor/dompdf/dompdf/src/Adapter/PDFLib.php | 1664 ++++ vendor/dompdf/dompdf/src/Autoloader.php | 42 + vendor/dompdf/dompdf/src/Canvas.php | 442 ++ vendor/dompdf/dompdf/src/CanvasFactory.php | 59 + vendor/dompdf/dompdf/src/Cellmap.php | 913 +++ .../dompdf/src/Css/AttributeTranslator.php | 638 ++ vendor/dompdf/dompdf/src/Css/Color.php | 319 + vendor/dompdf/dompdf/src/Css/Style.php | 3372 +++++++++ vendor/dompdf/dompdf/src/Css/Stylesheet.php | 1754 +++++ vendor/dompdf/dompdf/src/Dompdf.php | 1484 ++++ vendor/dompdf/dompdf/src/Exception.php | 29 + .../dompdf/src/Exception/ImageException.php | 31 + vendor/dompdf/dompdf/src/FontMetrics.php | 578 ++ vendor/dompdf/dompdf/src/Frame.php | 1261 ++++ vendor/dompdf/dompdf/src/Frame/Factory.php | 287 + vendor/dompdf/dompdf/src/Frame/FrameList.php | 35 + .../dompdf/src/Frame/FrameListIterator.php | 91 + vendor/dompdf/dompdf/src/Frame/FrameTree.php | 315 + .../dompdf/src/Frame/FrameTreeIterator.php | 96 + .../dompdf/dompdf/src/Frame/FrameTreeList.php | 35 + .../FrameDecorator/AbstractFrameDecorator.php | 915 +++ .../dompdf/src/FrameDecorator/Block.php | 284 + .../dompdf/src/FrameDecorator/Image.php | 91 + .../dompdf/src/FrameDecorator/Inline.php | 106 + .../dompdf/src/FrameDecorator/ListBullet.php | 87 + .../src/FrameDecorator/ListBulletImage.php | 171 + .../src/FrameDecorator/NullFrameDecorator.php | 34 + .../dompdf/dompdf/src/FrameDecorator/Page.php | 682 ++ .../dompdf/src/FrameDecorator/Table.php | 398 + .../dompdf/src/FrameDecorator/TableCell.php | 144 + .../dompdf/src/FrameDecorator/TableRow.php | 68 + .../src/FrameDecorator/TableRowGroup.php | 70 + .../dompdf/dompdf/src/FrameDecorator/Text.php | 203 + .../FrameReflower/AbstractFrameReflower.php | 529 ++ .../dompdf/dompdf/src/FrameReflower/Block.php | 948 +++ .../dompdf/dompdf/src/FrameReflower/Image.php | 202 + .../dompdf/src/FrameReflower/Inline.php | 103 + .../dompdf/src/FrameReflower/ListBullet.php | 45 + .../src/FrameReflower/NullFrameReflower.php | 39 + .../dompdf/dompdf/src/FrameReflower/Page.php | 205 + .../dompdf/dompdf/src/FrameReflower/Table.php | 589 ++ .../dompdf/src/FrameReflower/TableCell.php | 121 + .../dompdf/src/FrameReflower/TableRow.php | 74 + .../src/FrameReflower/TableRowGroup.php | 72 + .../dompdf/dompdf/src/FrameReflower/Text.php | 512 ++ vendor/dompdf/dompdf/src/Helpers.php | 937 +++ vendor/dompdf/dompdf/src/Image/Cache.php | 208 + .../dompdf/dompdf/src/JavascriptEmbedder.php | 52 + vendor/dompdf/dompdf/src/LineBox.php | 303 + vendor/dompdf/dompdf/src/Options.php | 1005 +++ vendor/dompdf/dompdf/src/PhpEvaluator.php | 63 + .../dompdf/dompdf/src/Positioner/Absolute.php | 118 + .../src/Positioner/AbstractPositioner.php | 48 + vendor/dompdf/dompdf/src/Positioner/Block.php | 54 + vendor/dompdf/dompdf/src/Positioner/Fixed.php | 89 + .../dompdf/dompdf/src/Positioner/Inline.php | 77 + .../dompdf/src/Positioner/ListBullet.php | 78 + .../dompdf/src/Positioner/NullPositioner.php | 28 + .../dompdf/src/Positioner/TableCell.php | 31 + .../dompdf/dompdf/src/Positioner/TableRow.php | 36 + vendor/dompdf/dompdf/src/Renderer.php | 295 + .../dompdf/src/Renderer/AbstractRenderer.php | 1020 +++ vendor/dompdf/dompdf/src/Renderer/Block.php | 266 + vendor/dompdf/dompdf/src/Renderer/Image.php | 143 + vendor/dompdf/dompdf/src/Renderer/Inline.php | 158 + .../dompdf/dompdf/src/Renderer/ListBullet.php | 257 + .../dompdf/dompdf/src/Renderer/TableCell.php | 219 + .../dompdf/src/Renderer/TableRowGroup.php | 50 + vendor/dompdf/dompdf/src/Renderer/Text.php | 167 + vendor/fzaninotto/faker | 1 + vendor/kint-php/kint/LICENSE | 20 + vendor/kint-php/kint/README.md | 82 + vendor/kint-php/kint/composer.json | 83 + vendor/kint-php/kint/init.php | 62 + vendor/kint-php/kint/init_helpers.php | 84 + .../kint/resources/compiled/aante-light.css | 1 + .../kint/resources/compiled/microtime.js | 1 + .../kint/resources/compiled/original.css | 1 + .../kint/resources/compiled/plain.css | 1 + .../kint-php/kint/resources/compiled/plain.js | 1 + .../kint-php/kint/resources/compiled/rich.js | 1 + .../kint/resources/compiled/shared.js | 1 + .../resources/compiled/solarized-dark.css | 1 + .../kint/resources/compiled/solarized.css | 1 + vendor/kint-php/kint/src/CallFinder.php | 473 ++ vendor/kint-php/kint/src/Kint.php | 756 ++ .../kint-php/kint/src/Object/BasicObject.php | 248 + .../kint-php/kint/src/Object/BlobObject.php | 177 + .../kint/src/Object/ClosureObject.php | 68 + .../kint/src/Object/DateTimeObject.php | 53 + .../kint/src/Object/InstanceObject.php | 78 + .../kint-php/kint/src/Object/MethodObject.php | 253 + .../kint/src/Object/ParameterObject.php | 100 + .../Representation/ColorRepresentation.php | 576 ++ .../DocstringRepresentation.php | 73 + .../MicrotimeRepresentation.php | 71 + .../Object/Representation/Representation.php | 71 + .../Representation/SourceRepresentation.php | 72 + .../SplFileInfoRepresentation.php | 177 + .../kint/src/Object/ResourceObject.php | 49 + .../kint-php/kint/src/Object/StreamObject.php | 54 + .../kint/src/Object/ThrowableObject.php | 54 + .../kint/src/Object/TraceFrameObject.php | 100 + .../kint-php/kint/src/Object/TraceObject.php | 45 + .../kint/src/Parser/ArrayObjectPlugin.php | 63 + .../kint-php/kint/src/Parser/Base64Plugin.php | 95 + .../kint-php/kint/src/Parser/BinaryPlugin.php | 49 + .../kint/src/Parser/BlacklistPlugin.php | 143 + .../kint/src/Parser/ClassMethodsPlugin.php | 113 + .../kint/src/Parser/ClassStaticsPlugin.php | 122 + .../kint/src/Parser/ClosurePlugin.php | 94 + .../kint-php/kint/src/Parser/ColorPlugin.php | 63 + .../kint/src/Parser/DOMDocumentPlugin.php | 328 + .../kint/src/Parser/DateTimePlugin.php | 55 + .../kint-php/kint/src/Parser/FsPathPlugin.php | 72 + .../kint/src/Parser/IteratorPlugin.php | 110 + .../kint-php/kint/src/Parser/JsonPlugin.php | 73 + .../kint/src/Parser/MicrotimePlugin.php | 105 + .../kint-php/kint/src/Parser/MysqliPlugin.php | 129 + vendor/kint-php/kint/src/Parser/Parser.php | 604 ++ vendor/kint-php/kint/src/Parser/Plugin.php | 55 + .../kint-php/kint/src/Parser/ProxyPlugin.php | 66 + .../kint/src/Parser/SerializePlugin.php | 108 + .../src/Parser/SimpleXMLElementPlugin.php | 154 + .../kint/src/Parser/SplFileInfoPlugin.php | 55 + .../src/Parser/SplObjectStoragePlugin.php | 54 + .../kint-php/kint/src/Parser/StreamPlugin.php | 78 + .../kint-php/kint/src/Parser/TablePlugin.php | 87 + .../kint/src/Parser/ThrowablePlugin.php | 60 + .../kint/src/Parser/TimestampPlugin.php | 71 + .../kint/src/Parser/ToStringPlugin.php | 67 + .../kint-php/kint/src/Parser/TracePlugin.php | 92 + vendor/kint-php/kint/src/Parser/XmlPlugin.php | 150 + .../kint/src/Renderer/CliRenderer.php | 152 + .../kint/src/Renderer/PlainRenderer.php | 237 + .../kint-php/kint/src/Renderer/Renderer.php | 185 + .../kint/src/Renderer/Rich/BinaryPlugin.php | 51 + .../src/Renderer/Rich/BlacklistPlugin.php | 36 + .../kint/src/Renderer/Rich/CallablePlugin.php | 174 + .../kint/src/Renderer/Rich/ClosurePlugin.php | 59 + .../kint/src/Renderer/Rich/ColorPlugin.php | 100 + .../src/Renderer/Rich/DepthLimitPlugin.php | 36 + .../src/Renderer/Rich/DocstringPlugin.php | 70 + .../src/Renderer/Rich/MicrotimePlugin.php | 68 + .../Renderer/Rich/ObjectPluginInterface.php | 33 + .../kint/src/Renderer/Rich/Plugin.php | 90 + .../src/Renderer/Rich/PluginInterface.php | 33 + .../src/Renderer/Rich/RecursionPlugin.php | 36 + .../Renderer/Rich/SimpleXMLElementPlugin.php | 81 + .../kint/src/Renderer/Rich/SourcePlugin.php | 79 + .../src/Renderer/Rich/TabPluginInterface.php | 33 + .../kint/src/Renderer/Rich/TablePlugin.php | 133 + .../src/Renderer/Rich/TimestampPlugin.php | 42 + .../src/Renderer/Rich/TraceFramePlugin.php | 68 + .../kint/src/Renderer/RichRenderer.php | 612 ++ .../src/Renderer/Text/BlacklistPlugin.php | 44 + .../src/Renderer/Text/DepthLimitPlugin.php | 44 + .../src/Renderer/Text/MicrotimePlugin.php | 128 + .../kint/src/Renderer/Text/Plugin.php | 41 + .../src/Renderer/Text/RecursionPlugin.php | 44 + .../kint/src/Renderer/Text/TracePlugin.php | 111 + .../kint/src/Renderer/TextRenderer.php | 346 + vendor/kint-php/kint/src/Utils.php | 240 + vendor/laminas/laminas-escaper/CHANGELOG.md | 73 + vendor/laminas/laminas-escaper/COPYRIGHT.md | 2 + vendor/laminas/laminas-escaper/LICENSE.md | 27 + vendor/laminas/laminas-escaper/README.md | 28 + vendor/laminas/laminas-escaper/composer.json | 58 + .../laminas/laminas-escaper/src/Escaper.php | 391 + .../src/Exception/ExceptionInterface.php | 13 + .../Exception/InvalidArgumentException.php | 17 + .../src/Exception/RuntimeException.php | 17 + .../.github/FUNDING.yml | 1 + .../workflows/release-on-milestone-closed.yml | 71 + .../laminas-zendframework-bridge/CHANGELOG.md | 686 ++ .../laminas-zendframework-bridge/COPYRIGHT.md | 1 + .../laminas-zendframework-bridge/LICENSE.md | 26 + .../laminas-zendframework-bridge/README.md | 24 + .../composer.json | 58 + .../config/replacements.php | 372 + .../src/Autoloader.php | 172 + .../src/ConfigPostProcessor.php | 434 ++ .../src/Module.php | 54 + .../src/Replacements.php | 46 + .../src/RewriteRules.php | 79 + .../src/autoload.php | 9 + vendor/mikey179/vfsstream/CHANGELOG.md | 247 + vendor/mikey179/vfsstream/LICENSE | 27 + vendor/mikey179/vfsstream/README.md | 8 + vendor/mikey179/vfsstream/appveyor.yml | 22 + vendor/mikey179/vfsstream/composer.json | 33 + vendor/mikey179/vfsstream/phpunit.xml.dist | 44 + .../main/php/org/bovigo/vfs/DotDirectory.php | 35 + .../src/main/php/org/bovigo/vfs/Quota.php | 86 + .../org/bovigo/vfs/content/FileContent.php | 71 + .../bovigo/vfs/content/LargeFileContent.php | 167 + .../vfs/content/SeekableFileContent.php | 134 + .../vfs/content/StringBasedFileContent.php | 97 + .../src/main/php/org/bovigo/vfs/vfsStream.php | 479 ++ .../bovigo/vfs/vfsStreamAbstractContent.php | 418 ++ .../php/org/bovigo/vfs/vfsStreamBlock.php | 34 + .../php/org/bovigo/vfs/vfsStreamContainer.php | 61 + .../bovigo/vfs/vfsStreamContainerIterator.php | 93 + .../php/org/bovigo/vfs/vfsStreamContent.php | 213 + .../php/org/bovigo/vfs/vfsStreamDirectory.php | 266 + .../php/org/bovigo/vfs/vfsStreamException.php | 19 + .../main/php/org/bovigo/vfs/vfsStreamFile.php | 394 + .../php/org/bovigo/vfs/vfsStreamWrapper.php | 1012 +++ .../vfs/visitor/vfsStreamAbstractVisitor.php | 64 + .../vfs/visitor/vfsStreamPrintVisitor.php | 107 + .../vfs/visitor/vfsStreamStructureVisitor.php | 111 + .../bovigo/vfs/visitor/vfsStreamVisitor.php | 55 + .../mikey179/vfsstream/src/test/bootstrap.php | 43 + .../bovigo/vfs/DirectoryIterationTestCase.php | 318 + .../php/org/bovigo/vfs/FilenameTestCase.php | 88 + .../php/org/bovigo/vfs/Issue104TestCase.php | 52 + .../org/bovigo/vfs/PermissionsTestCase.php | 118 + .../test/php/org/bovigo/vfs/QuotaTestCase.php | 80 + .../php/org/bovigo/vfs/UnlinkTestCase.php | 58 + .../vfs/content/LargeFileContentTestCase.php | 225 + .../StringBasedFileContentTestCase.php | 232 + .../proxy/vfsStreamWrapperRecordingProxy.php | 325 + .../vfs/vfsStreamAbstractContentTestCase.php | 1053 +++ .../org/bovigo/vfs/vfsStreamBlockTestCase.php | 89 + .../vfsStreamContainerIteratorTestCase.php | 111 + .../vfsStreamDirectoryIssue134TestCase.php | 64 + .../vfs/vfsStreamDirectoryIssue18TestCase.php | 80 + .../bovigo/vfs/vfsStreamDirectoryTestCase.php | 334 + .../bovigo/vfs/vfsStreamExLockTestCase.php | 55 + .../org/bovigo/vfs/vfsStreamFileTestCase.php | 337 + .../org/bovigo/vfs/vfsStreamGlobTestCase.php | 28 + .../vfsStreamResolveIncludePathTestCase.php | 61 + .../php/org/bovigo/vfs/vfsStreamTestCase.php | 780 ++ .../org/bovigo/vfs/vfsStreamUmaskTestCase.php | 194 + ...StreamWrapperAlreadyRegisteredTestCase.php | 62 + .../vfs/vfsStreamWrapperBaseTestCase.php | 98 + .../vfsStreamWrapperDirSeparatorTestCase.php | 72 + .../vfs/vfsStreamWrapperDirTestCase.php | 500 ++ .../vfs/vfsStreamWrapperFileTestCase.php | 457 ++ .../vfs/vfsStreamWrapperFileTimesTestCase.php | 314 + .../vfs/vfsStreamWrapperFlockTestCase.php | 439 ++ .../vfs/vfsStreamWrapperLargeFileTestCase.php | 81 + .../vfs/vfsStreamWrapperQuotaTestCase.php | 223 + .../vfs/vfsStreamWrapperSetOptionTestCase.php | 75 + .../vfsStreamWrapperStreamSelectTestCase.php | 34 + .../bovigo/vfs/vfsStreamWrapperTestCase.php | 789 ++ .../vfsStreamWrapperUnregisterTestCase.php | 75 + .../vfsStreamWrapperWithoutRootTestCase.php | 63 + .../org/bovigo/vfs/vfsStreamZipTestCase.php | 52 + .../vfsStreamAbstractVisitorTestCase.php | 98 + .../visitor/vfsStreamPrintVisitorTestCase.php | 102 + .../vfsStreamStructureVisitorTestCase.php | 85 + .../vfsstream/src/test/phpt/bug71287.phpt | 23 + .../filesystemcopy/emptyFolder/.gitignore | 0 .../filesystemcopy/withSubfolders/aFile.txt | 1 + .../withSubfolders/subfolder1/file1.txt | 1 + .../withSubfolders/subfolder2/.gitignore | 0 vendor/myclabs/deep-copy/.github/FUNDING.yml | 12 + vendor/myclabs/deep-copy/LICENSE | 20 + vendor/myclabs/deep-copy/README.md | 375 + vendor/myclabs/deep-copy/composer.json | 38 + .../deep-copy/src/DeepCopy/DeepCopy.php | 298 + .../src/DeepCopy/Exception/CloneException.php | 9 + .../DeepCopy/Exception/PropertyException.php | 9 + .../Doctrine/DoctrineCollectionFilter.php | 33 + .../DoctrineEmptyCollectionFilter.php | 28 + .../Filter/Doctrine/DoctrineProxyFilter.php | 22 + .../deep-copy/src/DeepCopy/Filter/Filter.php | 18 + .../src/DeepCopy/Filter/KeepFilter.php | 16 + .../src/DeepCopy/Filter/ReplaceFilter.php | 39 + .../src/DeepCopy/Filter/SetNullFilter.php | 24 + .../Matcher/Doctrine/DoctrineProxyMatcher.php | 22 + .../src/DeepCopy/Matcher/Matcher.php | 14 + .../src/DeepCopy/Matcher/PropertyMatcher.php | 39 + .../DeepCopy/Matcher/PropertyNameMatcher.php | 32 + .../DeepCopy/Matcher/PropertyTypeMatcher.php | 46 + .../DeepCopy/Reflection/ReflectionHelper.php | 78 + .../TypeFilter/Date/DateIntervalFilter.php | 33 + .../src/DeepCopy/TypeFilter/ReplaceFilter.php | 30 + .../DeepCopy/TypeFilter/ShallowCopyFilter.php | 17 + .../TypeFilter/Spl/ArrayObjectFilter.php | 36 + .../TypeFilter/Spl/SplDoublyLinkedList.php | 10 + .../Spl/SplDoublyLinkedListFilter.php | 51 + .../src/DeepCopy/TypeFilter/TypeFilter.php | 13 + .../src/DeepCopy/TypeMatcher/TypeMatcher.php | 29 + .../deep-copy/src/DeepCopy/deep_copy.php | 20 + vendor/phar-io/manifest/.gitignore | 7 + vendor/phar-io/manifest/.php_cs | 67 + vendor/phar-io/manifest/.travis.yml | 33 + vendor/phar-io/manifest/LICENSE | 31 + vendor/phar-io/manifest/README.md | 30 + vendor/phar-io/manifest/build.xml | 50 + vendor/phar-io/manifest/composer.json | 42 + vendor/phar-io/manifest/composer.lock | 69 + .../phar-io/manifest/examples/example-01.php | 23 + vendor/phar-io/manifest/phive.xml | 4 + vendor/phar-io/manifest/phpunit.xml | 20 + .../manifest/src/ManifestDocumentMapper.php | 193 + .../phar-io/manifest/src/ManifestLoader.php | 66 + .../manifest/src/ManifestSerializer.php | 163 + .../manifest/src/exceptions/Exception.php | 14 + .../InvalidApplicationNameException.php | 16 + .../src/exceptions/InvalidEmailException.php | 14 + .../src/exceptions/InvalidUrlException.php | 14 + .../exceptions/ManifestDocumentException.php | 6 + .../ManifestDocumentMapperException.php | 6 + .../exceptions/ManifestElementException.php | 6 + .../exceptions/ManifestLoaderException.php | 6 + .../manifest/src/values/Application.php | 20 + .../manifest/src/values/ApplicationName.php | 65 + vendor/phar-io/manifest/src/values/Author.php | 57 + .../manifest/src/values/AuthorCollection.php | 43 + .../src/values/AuthorCollectionIterator.php | 56 + .../manifest/src/values/BundledComponent.php | 48 + .../src/values/BundledComponentCollection.php | 43 + .../BundledComponentCollectionIterator.php | 56 + .../src/values/CopyrightInformation.php | 42 + vendor/phar-io/manifest/src/values/Email.php | 47 + .../phar-io/manifest/src/values/Extension.php | 75 + .../phar-io/manifest/src/values/Library.php | 20 + .../phar-io/manifest/src/values/License.php | 42 + .../phar-io/manifest/src/values/Manifest.php | 138 + .../src/values/PhpExtensionRequirement.php | 32 + .../src/values/PhpVersionRequirement.php | 31 + .../manifest/src/values/Requirement.php | 14 + .../src/values/RequirementCollection.php | 43 + .../values/RequirementCollectionIterator.php | 56 + vendor/phar-io/manifest/src/values/Type.php | 60 + vendor/phar-io/manifest/src/values/Url.php | 47 + .../manifest/src/xml/AuthorElement.php | 21 + .../src/xml/AuthorElementCollection.php | 19 + .../manifest/src/xml/BundlesElement.php | 19 + .../manifest/src/xml/ComponentElement.php | 21 + .../src/xml/ComponentElementCollection.php | 19 + .../manifest/src/xml/ContainsElement.php | 31 + .../manifest/src/xml/CopyrightElement.php | 25 + .../manifest/src/xml/ElementCollection.php | 58 + .../phar-io/manifest/src/xml/ExtElement.php | 17 + .../manifest/src/xml/ExtElementCollection.php | 20 + .../manifest/src/xml/ExtensionElement.php | 21 + .../manifest/src/xml/LicenseElement.php | 21 + .../manifest/src/xml/ManifestDocument.php | 118 + .../xml/ManifestDocumentLoadingException.php | 48 + .../manifest/src/xml/ManifestElement.php | 100 + .../phar-io/manifest/src/xml/PhpElement.php | 27 + .../manifest/src/xml/RequiresElement.php | 19 + .../tests/ManifestDocumentMapperTest.php | 110 + .../manifest/tests/ManifestLoaderTest.php | 83 + .../manifest/tests/ManifestSerializerTest.php | 114 + .../manifest/tests/_fixture/custom.xml | 10 + .../_fixture/extension-invalidcompatible.xml | 13 + .../manifest/tests/_fixture/extension.xml | 13 + .../tests/_fixture/invalidversion.xml | 11 + .../_fixture/invalidversionconstraint.xml | 11 + .../manifest/tests/_fixture/library.xml | 11 + .../manifest/tests/_fixture/manifest.xml | 11 + .../manifest/tests/_fixture/phpunit-5.6.5.xml | 46 + .../phar-io/manifest/tests/_fixture/test.phar | Bin 0 -> 7165 bytes .../ManifestDocumentLoadingExceptionTest.php | 19 + .../tests/values/ApplicationNameTest.php | 57 + .../manifest/tests/values/ApplicationTest.php | 44 + .../tests/values/AuthorCollectionTest.php | 62 + .../manifest/tests/values/AuthorTest.php | 45 + .../values/BundledComponentCollectionTest.php | 63 + .../tests/values/BundledComponentTest.php | 42 + .../tests/values/CopyrightInformationTest.php | 62 + .../manifest/tests/values/EmailTest.php | 35 + .../manifest/tests/values/ExtensionTest.php | 109 + .../manifest/tests/values/LibraryTest.php | 44 + .../manifest/tests/values/LicenseTest.php | 41 + .../manifest/tests/values/ManifestTest.php | 187 + .../values/PhpExtensionRequirementTest.php | 26 + .../values/PhpVersionRequirementTest.php | 38 + .../values/RequirementCollectionTest.php | 63 + .../phar-io/manifest/tests/values/UrlTest.php | 35 + .../tests/xml/AuthorElementCollectionTest.php | 18 + .../manifest/tests/xml/AuthorElementTest.php | 25 + .../manifest/tests/xml/BundlesElementTest.php | 41 + .../xml/ComponentElementCollectionTest.php | 18 + .../tests/xml/ComponentElementTest.php | 25 + .../tests/xml/ContainsElementTest.php | 63 + .../tests/xml/CopyrightElementTest.php | 52 + .../tests/xml/ExtElementCollectionTest.php | 19 + .../manifest/tests/xml/ExtElementTest.php | 21 + .../tests/xml/ExtensionElementTest.php | 25 + .../manifest/tests/xml/LicenseElementTest.php | 25 + .../tests/xml/ManifestDocumentTest.php | 110 + .../manifest/tests/xml/PhpElementTest.php | 48 + .../tests/xml/RequiresElementTest.php | 37 + vendor/phar-io/version/.gitignore | 7 + vendor/phar-io/version/.php_cs | 67 + vendor/phar-io/version/.travis.yml | 33 + vendor/phar-io/version/CHANGELOG.md | 44 + vendor/phar-io/version/LICENSE | 31 + vendor/phar-io/version/README.md | 61 + vendor/phar-io/version/build.xml | 41 + vendor/phar-io/version/composer.json | 34 + vendor/phar-io/version/phive.xml | 5 + vendor/phar-io/version/phpunit.xml | 19 + .../phar-io/version/src/PreReleaseSuffix.php | 95 + vendor/phar-io/version/src/Version.php | 175 + .../version/src/VersionConstraintParser.php | 122 + .../version/src/VersionConstraintValue.php | 123 + vendor/phar-io/version/src/VersionNumber.php | 41 + .../constraints/AbstractVersionConstraint.php | 32 + .../constraints/AndVersionConstraintGroup.php | 43 + .../src/constraints/AnyVersionConstraint.php | 29 + .../constraints/ExactVersionConstraint.php | 22 + .../GreaterThanOrEqualToVersionConstraint.php | 38 + .../constraints/OrVersionConstraintGroup.php | 43 + ...SpecificMajorAndMinorVersionConstraint.php | 48 + .../SpecificMajorVersionConstraint.php | 37 + .../src/constraints/VersionConstraint.php | 26 + .../version/src/exceptions/Exception.php | 14 + .../InvalidPreReleaseSuffixException.php | 7 + .../exceptions/InvalidVersionException.php | 6 + .../UnsupportedVersionConstraintException.php | 14 + .../VersionConstraintParserTest.php | 146 + .../Unit/AbstractVersionConstraintTest.php | 25 + .../Unit/AndVersionConstraintGroupTest.php | 52 + .../tests/Unit/AnyVersionConstraintTest.php | 41 + .../tests/Unit/ExactVersionConstraintTest.php | 58 + ...aterThanOrEqualToVersionConstraintTest.php | 47 + .../Unit/OrVersionConstraintGroupTest.php | 65 + .../tests/Unit/PreReleaseSuffixTest.php | 46 + ...ificMajorAndMinorVersionConstraintTest.php | 45 + .../SpecificMajorVersionConstraintTest.php | 44 + .../version/tests/Unit/VersionTest.php | 113 + vendor/phenx/php-font-lib/.gitattributes | 12 + vendor/phenx/php-font-lib/.gitignore | 5 + vendor/phenx/php-font-lib/.htaccess | 1 + vendor/phenx/php-font-lib/.travis.yml | 36 + vendor/phenx/php-font-lib/LICENSE | 456 ++ vendor/phenx/php-font-lib/README.md | 29 + vendor/phenx/php-font-lib/bower.json | 23 + vendor/phenx/php-font-lib/composer.json | 24 + vendor/phenx/php-font-lib/index.php | 1 + .../maps/adobe-standard-encoding.map | 231 + vendor/phenx/php-font-lib/maps/cp1250.map | 251 + vendor/phenx/php-font-lib/maps/cp1251.map | 255 + vendor/phenx/php-font-lib/maps/cp1252.map | 251 + vendor/phenx/php-font-lib/maps/cp1253.map | 239 + vendor/phenx/php-font-lib/maps/cp1254.map | 249 + vendor/phenx/php-font-lib/maps/cp1255.map | 233 + vendor/phenx/php-font-lib/maps/cp1257.map | 244 + vendor/phenx/php-font-lib/maps/cp1258.map | 247 + vendor/phenx/php-font-lib/maps/cp874.map | 225 + vendor/phenx/php-font-lib/maps/iso-8859-1.map | 256 + .../phenx/php-font-lib/maps/iso-8859-11.map | 248 + .../phenx/php-font-lib/maps/iso-8859-15.map | 256 + .../phenx/php-font-lib/maps/iso-8859-16.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-2.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-4.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-5.map | 256 + vendor/phenx/php-font-lib/maps/iso-8859-7.map | 250 + vendor/phenx/php-font-lib/maps/iso-8859-9.map | 256 + vendor/phenx/php-font-lib/maps/koi8-r.map | 256 + vendor/phenx/php-font-lib/maps/koi8-u.map | 256 + vendor/phenx/php-font-lib/phpunit.xml.dist | 19 + .../sample-fonts/IntelClear-Light.ttf | Bin 0 -> 96664 bytes .../sample-fonts/NotoSansShavian-Regular.ttf | Bin 0 -> 6020 bytes .../src/FontLib/AdobeFontMetrics.php | 217 + .../php-font-lib/src/FontLib/Autoloader.php | 43 + .../php-font-lib/src/FontLib/BinaryStream.php | 444 ++ .../php-font-lib/src/FontLib/EOT/File.php | 160 + .../php-font-lib/src/FontLib/EOT/Header.php | 113 + .../php-font-lib/src/FontLib/EncodingMap.php | 37 + .../Exception/FontNotFoundException.php | 11 + .../phenx/php-font-lib/src/FontLib/Font.php | 89 + .../src/FontLib/Glyph/Outline.php | 110 + .../src/FontLib/Glyph/OutlineComponent.php | 31 + .../src/FontLib/Glyph/OutlineComposite.php | 242 + .../src/FontLib/Glyph/OutlineSimple.php | 335 + .../phenx/php-font-lib/src/FontLib/Header.php | 37 + .../src/FontLib/OpenType/File.php | 18 + .../FontLib/OpenType/TableDirectoryEntry.php | 18 + .../src/FontLib/Table/DirectoryEntry.php | 129 + .../php-font-lib/src/FontLib/Table/Table.php | 93 + .../src/FontLib/Table/Type/cmap.php | 298 + .../src/FontLib/Table/Type/glyf.php | 154 + .../src/FontLib/Table/Type/head.php | 46 + .../src/FontLib/Table/Type/hhea.php | 44 + .../src/FontLib/Table/Type/hmtx.php | 59 + .../src/FontLib/Table/Type/kern.php | 80 + .../src/FontLib/Table/Type/loca.php | 80 + .../src/FontLib/Table/Type/maxp.php | 42 + .../src/FontLib/Table/Type/name.php | 193 + .../src/FontLib/Table/Type/nameRecord.php | 53 + .../src/FontLib/Table/Type/os2.php | 47 + .../src/FontLib/Table/Type/post.php | 141 + .../src/FontLib/TrueType/Collection.php | 100 + .../src/FontLib/TrueType/File.php | 471 ++ .../src/FontLib/TrueType/Header.php | 31 + .../FontLib/TrueType/TableDirectoryEntry.php | 33 + .../php-font-lib/src/FontLib/WOFF/File.php | 81 + .../php-font-lib/src/FontLib/WOFF/Header.php | 32 + .../src/FontLib/WOFF/TableDirectoryEntry.php | 34 + .../php-font-lib/tests/FontLib/FontTest.php | 49 + vendor/phenx/php-svg-lib/.gitattributes | 9 + vendor/phenx/php-svg-lib/.gitignore | 3 + vendor/phenx/php-svg-lib/.travis.yml | 20 + vendor/phenx/php-svg-lib/COPYING | 165 + vendor/phenx/php-svg-lib/COPYING.GPL | 674 ++ vendor/phenx/php-svg-lib/README.md | 14 + vendor/phenx/php-svg-lib/composer.json | 29 + vendor/phenx/php-svg-lib/phpunit.xml | 19 + .../php-svg-lib/src/Svg/DefaultStyle.php | 29 + vendor/phenx/php-svg-lib/src/Svg/Document.php | 404 + .../php-svg-lib/src/Svg/Gradient/Stop.php | 16 + vendor/phenx/php-svg-lib/src/Svg/Style.php | 550 ++ .../php-svg-lib/src/Svg/Surface/CPdf.php | 4768 ++++++++++++ .../src/Svg/Surface/SurfaceCpdf.php | 486 ++ .../src/Svg/Surface/SurfaceGmagick.php | 308 + .../src/Svg/Surface/SurfaceInterface.php | 90 + .../src/Svg/Surface/SurfacePDFLib.php | 422 ++ .../php-svg-lib/src/Svg/Tag/AbstractTag.php | 190 + .../phenx/php-svg-lib/src/Svg/Tag/Anchor.php | 14 + .../phenx/php-svg-lib/src/Svg/Tag/Circle.php | 31 + .../php-svg-lib/src/Svg/Tag/ClipPath.php | 33 + .../phenx/php-svg-lib/src/Svg/Tag/Ellipse.php | 37 + .../phenx/php-svg-lib/src/Svg/Tag/Group.php | 33 + .../phenx/php-svg-lib/src/Svg/Tag/Image.php | 62 + vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php | 38 + .../src/Svg/Tag/LinearGradient.php | 83 + vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php | 528 ++ .../phenx/php-svg-lib/src/Svg/Tag/Polygon.php | 33 + .../php-svg-lib/src/Svg/Tag/Polyline.php | 31 + .../src/Svg/Tag/RadialGradient.php | 17 + vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php | 55 + .../phenx/php-svg-lib/src/Svg/Tag/Shape.php | 63 + vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php | 17 + .../php-svg-lib/src/Svg/Tag/StyleTag.php | 27 + vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php | 70 + .../phenx/php-svg-lib/src/Svg/Tag/UseTag.php | 96 + vendor/phenx/php-svg-lib/src/autoload.php | 17 + .../phenx/php-svg-lib/tests/Svg/StyleTest.php | 59 + .../reflection-common/.github/dependabot.yml | 7 + .../.github/workflows/push.yml | 223 + .../phpdocumentor/reflection-common/LICENSE | 22 + .../phpdocumentor/reflection-common/README.md | 11 + .../reflection-common/composer.json | 28 + .../reflection-common/src/Element.php | 30 + .../reflection-common/src/File.php | 35 + .../reflection-common/src/Fqsen.php | 89 + .../reflection-common/src/Location.php | 53 + .../reflection-common/src/Project.php | 25 + .../reflection-common/src/ProjectFactory.php | 28 + .../phpdocumentor/reflection-docblock/LICENSE | 21 + .../reflection-docblock/README.md | 75 + .../reflection-docblock/composer.json | 41 + .../reflection-docblock/src/DocBlock.php | 204 + .../src/DocBlock/Description.php | 114 + .../src/DocBlock/DescriptionFactory.php | 177 + .../src/DocBlock/ExampleFinder.php | 157 + .../src/DocBlock/Serializer.php | 151 + .../src/DocBlock/StandardTagFactory.php | 347 + .../reflection-docblock/src/DocBlock/Tag.php | 32 + .../src/DocBlock/TagFactory.php | 84 + .../src/DocBlock/Tags/Author.php | 100 + .../src/DocBlock/Tags/BaseTag.php | 53 + .../src/DocBlock/Tags/Covers.php | 100 + .../src/DocBlock/Tags/Deprecated.php | 108 + .../src/DocBlock/Tags/Example.php | 199 + .../DocBlock/Tags/Factory/StaticMethod.php | 25 + .../src/DocBlock/Tags/Formatter.php | 24 + .../Tags/Formatter/AlignFormatter.php | 49 + .../Tags/Formatter/PassthroughFormatter.php | 29 + .../src/DocBlock/Tags/Generic.php | 88 + .../src/DocBlock/Tags/InvalidTag.php | 144 + .../src/DocBlock/Tags/Link.php | 78 + .../src/DocBlock/Tags/Method.php | 279 + .../src/DocBlock/Tags/Param.php | 172 + .../src/DocBlock/Tags/Property.php | 119 + .../src/DocBlock/Tags/PropertyRead.php | 119 + .../src/DocBlock/Tags/PropertyWrite.php | 119 + .../src/DocBlock/Tags/Reference/Fqsen.php | 38 + .../src/DocBlock/Tags/Reference/Reference.php | 22 + .../src/DocBlock/Tags/Reference/Url.php | 36 + .../src/DocBlock/Tags/Return_.php | 64 + .../src/DocBlock/Tags/See.php | 105 + .../src/DocBlock/Tags/Since.php | 102 + .../src/DocBlock/Tags/Source.php | 117 + .../src/DocBlock/Tags/TagWithType.php | 65 + .../src/DocBlock/Tags/Throws.php | 64 + .../src/DocBlock/Tags/Uses.php | 99 + .../src/DocBlock/Tags/Var_.php | 120 + .../src/DocBlock/Tags/Version.php | 105 + .../src/DocBlockFactory.php | 286 + .../src/DocBlockFactoryInterface.php | 23 + .../src/Exception/PcreException.php | 38 + .../reflection-docblock/src/Utils.php | 57 + vendor/phpdocumentor/type-resolver/LICENSE | 21 + vendor/phpdocumentor/type-resolver/README.md | 177 + .../phpdocumentor/type-resolver/composer.json | 34 + .../phpdocumentor/type-resolver/composer.lock | 71 + .../phpdocumentor/type-resolver/phpbench.json | 10 + .../type-resolver/src/FqsenResolver.php | 79 + .../type-resolver/src/PseudoType.php | 19 + .../type-resolver/src/PseudoTypes/False_.php | 39 + .../type-resolver/src/PseudoTypes/True_.php | 39 + .../phpdocumentor/type-resolver/src/Type.php | 25 + .../type-resolver/src/TypeResolver.php | 543 ++ .../type-resolver/src/Types/AbstractList.php | 83 + .../src/Types/AggregatedType.php | 124 + .../type-resolver/src/Types/Array_.php | 29 + .../type-resolver/src/Types/Boolean.php | 32 + .../type-resolver/src/Types/Callable_.php | 32 + .../type-resolver/src/Types/ClassString.php | 56 + .../type-resolver/src/Types/Collection.php | 68 + .../type-resolver/src/Types/Compound.php | 38 + .../type-resolver/src/Types/Context.php | 97 + .../src/Types/ContextFactory.php | 423 ++ .../type-resolver/src/Types/Expression.php | 51 + .../type-resolver/src/Types/Float_.php | 32 + .../type-resolver/src/Types/Integer.php | 32 + .../type-resolver/src/Types/Intersection.php | 37 + .../type-resolver/src/Types/Iterable_.php | 38 + .../type-resolver/src/Types/Mixed_.php | 32 + .../type-resolver/src/Types/Null_.php | 32 + .../type-resolver/src/Types/Nullable.php | 51 + .../type-resolver/src/Types/Object_.php | 68 + .../type-resolver/src/Types/Parent_.php | 34 + .../type-resolver/src/Types/Resource_.php | 32 + .../type-resolver/src/Types/Scalar.php | 32 + .../type-resolver/src/Types/Self_.php | 34 + .../type-resolver/src/Types/Static_.php | 39 + .../type-resolver/src/Types/String_.php | 32 + .../type-resolver/src/Types/This.php | 35 + .../type-resolver/src/Types/Void_.php | 35 + vendor/phpspec/prophecy/CHANGES.md | 274 + vendor/phpspec/prophecy/LICENSE | 23 + vendor/phpspec/prophecy/README.md | 404 + vendor/phpspec/prophecy/composer.json | 50 + .../prophecy/src/Prophecy/Argument.php | 239 + .../Prophecy/Argument/ArgumentsWildcard.php | 101 + .../Prophecy/Argument/Token/AnyValueToken.php | 52 + .../Argument/Token/AnyValuesToken.php | 52 + .../Argument/Token/ApproximateValueToken.php | 55 + .../Argument/Token/ArrayCountToken.php | 86 + .../Argument/Token/ArrayEntryToken.php | 143 + .../Argument/Token/ArrayEveryEntryToken.php | 82 + .../Prophecy/Argument/Token/CallbackToken.php | 75 + .../Argument/Token/ExactValueToken.php | 118 + .../Argument/Token/IdenticalValueToken.php | 74 + .../Prophecy/Argument/Token/InArrayToken.php | 74 + .../Argument/Token/LogicalAndToken.php | 80 + .../Argument/Token/LogicalNotToken.php | 73 + .../Argument/Token/NotInArrayToken.php | 75 + .../Argument/Token/ObjectStateToken.php | 104 + .../Argument/Token/StringContainsToken.php | 67 + .../Argument/Token/TokenInterface.php | 43 + .../src/Prophecy/Argument/Token/TypeToken.php | 76 + .../prophecy/src/Prophecy/Call/Call.php | 162 + .../prophecy/src/Prophecy/Call/CallCenter.php | 240 + .../Prophecy/Comparator/ClosureComparator.php | 44 + .../src/Prophecy/Comparator/Factory.php | 47 + .../Comparator/ProphecyComparator.php | 28 + .../src/Prophecy/Doubler/CachedDoubler.php | 66 + .../ClassPatch/ClassPatchInterface.php | 48 + .../ClassPatch/DisableConstructorPatch.php | 76 + .../Doubler/ClassPatch/HhvmExceptionPatch.php | 63 + .../Doubler/ClassPatch/KeywordPatch.php | 68 + .../Doubler/ClassPatch/MagicCallPatch.php | 94 + .../ClassPatch/ProphecySubjectPatch.php | 113 + .../ReflectionClassNewInstancePatch.php | 57 + .../Doubler/ClassPatch/SplFileInfoPatch.php | 123 + .../Doubler/ClassPatch/ThrowablePatch.php | 95 + .../Doubler/ClassPatch/TraversablePatch.php | 83 + .../src/Prophecy/Doubler/DoubleInterface.php | 22 + .../prophecy/src/Prophecy/Doubler/Doubler.php | 146 + .../Doubler/Generator/ClassCodeGenerator.php | 110 + .../Doubler/Generator/ClassCreator.php | 67 + .../Doubler/Generator/ClassMirror.php | 243 + .../Doubler/Generator/Node/ArgumentNode.php | 133 + .../Generator/Node/ArgumentTypeNode.php | 10 + .../Doubler/Generator/Node/ClassNode.php | 169 + .../Doubler/Generator/Node/MethodNode.php | 210 + .../Doubler/Generator/Node/ReturnTypeNode.php | 31 + .../Generator/Node/TypeNodeAbstract.php | 87 + .../Doubler/Generator/ReflectionInterface.php | 22 + .../Doubler/Generator/TypeHintReference.php | 43 + .../src/Prophecy/Doubler/LazyDouble.php | 127 + .../src/Prophecy/Doubler/NameGenerator.php | 52 + .../Call/UnexpectedCallException.php | 40 + .../Doubler/ClassCreatorException.php | 31 + .../Doubler/ClassMirrorException.php | 31 + .../Doubler/ClassNotFoundException.php | 33 + .../Exception/Doubler/DoubleException.php | 18 + .../Exception/Doubler/DoublerException.php | 18 + .../Doubler/InterfaceNotFoundException.php | 20 + .../Doubler/MethodNotExtendableException.php | 41 + .../Doubler/MethodNotFoundException.php | 60 + .../Doubler/ReturnByReferenceException.php | 41 + .../src/Prophecy/Exception/Exception.php | 26 + .../Exception/InvalidArgumentException.php | 16 + .../Prediction/AggregateException.php | 51 + .../Prediction/FailedPredictionException.php | 24 + .../Exception/Prediction/NoCallsException.php | 18 + .../Prediction/PredictionException.php | 18 + .../UnexpectedCallsCountException.php | 31 + .../Prediction/UnexpectedCallsException.php | 32 + .../Prophecy/MethodProphecyException.php | 34 + .../Prophecy/ObjectProphecyException.php | 34 + .../Exception/Prophecy/ProphecyException.php | 18 + .../ClassAndInterfaceTagRetriever.php | 69 + .../PhpDocumentor/ClassTagRetriever.php | 60 + .../PhpDocumentor/LegacyClassTagRetriever.php | 35 + .../MethodTagRetrieverInterface.php | 30 + .../Prophecy/Prediction/CallPrediction.php | 86 + .../Prediction/CallTimesPrediction.php | 107 + .../Prediction/CallbackPrediction.php | 65 + .../Prophecy/Prediction/NoCallsPrediction.php | 68 + .../Prediction/PredictionInterface.php | 37 + .../src/Prophecy/Promise/CallbackPromise.php | 66 + .../src/Prophecy/Promise/PromiseInterface.php | 35 + .../Promise/ReturnArgumentPromise.php | 61 + .../src/Prophecy/Promise/ReturnPromise.php | 55 + .../src/Prophecy/Promise/ThrowPromise.php | 100 + .../src/Prophecy/Prophecy/MethodProphecy.php | 565 ++ .../src/Prophecy/Prophecy/ObjectProphecy.php | 286 + .../Prophecy/Prophecy/ProphecyInterface.php | 27 + .../Prophecy/ProphecySubjectInterface.php | 34 + .../src/Prophecy/Prophecy/Revealer.php | 44 + .../Prophecy/Prophecy/RevealerInterface.php | 29 + .../phpspec/prophecy/src/Prophecy/Prophet.php | 138 + .../prophecy/src/Prophecy/Util/ExportUtil.php | 210 + .../prophecy/src/Prophecy/Util/StringUtil.php | 99 + .../phpunit/php-code-coverage/.gitattributes | 3 + .../php-code-coverage/.github/CONTRIBUTING.md | 1 + .../php-code-coverage/.github/FUNDING.yml | 1 + .../.github/ISSUE_TEMPLATE.md | 18 + vendor/phpunit/php-code-coverage/.gitignore | 7 + vendor/phpunit/php-code-coverage/.php_cs.dist | 197 + vendor/phpunit/php-code-coverage/.travis.yml | 60 + vendor/phpunit/php-code-coverage/ChangeLog.md | 131 + vendor/phpunit/php-code-coverage/LICENSE | 33 + vendor/phpunit/php-code-coverage/README.md | 40 + vendor/phpunit/php-code-coverage/build.xml | 30 + .../phpunit/php-code-coverage/composer.json | 61 + vendor/phpunit/php-code-coverage/phive.xml | 4 + vendor/phpunit/php-code-coverage/phpunit.xml | 21 + .../php-code-coverage/src/CodeCoverage.php | 1006 +++ .../php-code-coverage/src/Driver/Driver.php | 47 + .../php-code-coverage/src/Driver/PCOV.php | 45 + .../php-code-coverage/src/Driver/PHPDBG.php | 96 + .../php-code-coverage/src/Driver/Xdebug.php | 112 + .../CoveredCodeNotExecutedException.php | 17 + .../src/Exception/Exception.php | 17 + .../Exception/InvalidArgumentException.php | 36 + .../MissingCoversAnnotationException.php | 17 + .../src/Exception/RuntimeException.php | 14 + .../UnintentionallyCoveredCodeException.php | 44 + .../phpunit/php-code-coverage/src/Filter.php | 174 + .../src/Node/AbstractNode.php | 328 + .../php-code-coverage/src/Node/Builder.php | 227 + .../php-code-coverage/src/Node/Directory.php | 427 ++ .../php-code-coverage/src/Node/File.php | 611 ++ .../php-code-coverage/src/Node/Iterator.php | 89 + .../php-code-coverage/src/Report/Clover.php | 258 + .../php-code-coverage/src/Report/Crap4j.php | 165 + .../src/Report/Html/Facade.php | 167 + .../src/Report/Html/Renderer.php | 277 + .../src/Report/Html/Renderer/Dashboard.php | 281 + .../src/Report/Html/Renderer/Directory.php | 98 + .../src/Report/Html/Renderer/File.php | 529 ++ .../Renderer/Template/coverage_bar.html.dist | 5 + .../Renderer/Template/css/bootstrap.min.css | 7 + .../Html/Renderer/Template/css/custom.css | 0 .../Html/Renderer/Template/css/nv.d3.min.css | 1 + .../Html/Renderer/Template/css/octicons.css | 5 + .../Html/Renderer/Template/css/style.css | 122 + .../Renderer/Template/dashboard.html.dist | 281 + .../Renderer/Template/directory.html.dist | 60 + .../Template/directory_item.html.dist | 13 + .../Html/Renderer/Template/file.html.dist | 72 + .../Renderer/Template/file_item.html.dist | 14 + .../Renderer/Template/icons/file-code.svg | 1 + .../Template/icons/file-directory.svg | 1 + .../Renderer/Template/js/bootstrap.min.js | 7 + .../Html/Renderer/Template/js/d3.min.js | 5 + .../Report/Html/Renderer/Template/js/file.js | 62 + .../Html/Renderer/Template/js/jquery.min.js | 2 + .../Html/Renderer/Template/js/nv.d3.min.js | 8 + .../Html/Renderer/Template/js/popper.min.js | 5 + .../Renderer/Template/method_item.html.dist | 11 + .../php-code-coverage/src/Report/PHP.php | 64 + .../php-code-coverage/src/Report/Text.php | 283 + .../src/Report/Xml/BuildInformation.php | 81 + .../src/Report/Xml/Coverage.php | 69 + .../src/Report/Xml/Directory.php | 14 + .../src/Report/Xml/Facade.php | 287 + .../php-code-coverage/src/Report/Xml/File.php | 81 + .../src/Report/Xml/Method.php | 56 + .../php-code-coverage/src/Report/Xml/Node.php | 87 + .../src/Report/Xml/Project.php | 85 + .../src/Report/Xml/Report.php | 92 + .../src/Report/Xml/Source.php | 38 + .../src/Report/Xml/Tests.php | 46 + .../src/Report/Xml/Totals.php | 140 + .../php-code-coverage/src/Report/Xml/Unit.php | 95 + vendor/phpunit/php-code-coverage/src/Util.php | 40 + .../phpunit/php-code-coverage/src/Version.php | 30 + .../php-code-coverage/tests/TestCase.php | 395 + .../tests/_files/BankAccount-clover.xml | 26 + .../tests/_files/BankAccount-crap4j.xml | 59 + .../tests/_files/BankAccount-text.txt | 12 + .../tests/_files/BankAccount.php | 33 + .../tests/_files/BankAccountTest.php | 66 + .../_files/CoverageClassExtendedTest.php | 14 + .../tests/_files/CoverageClassTest.php | 14 + .../CoverageFunctionParenthesesTest.php | 13 + ...erageFunctionParenthesesWhitespaceTest.php | 13 + .../tests/_files/CoverageFunctionTest.php | 13 + .../CoverageMethodOneLineAnnotationTest.php | 12 + .../_files/CoverageMethodParenthesesTest.php | 14 + ...overageMethodParenthesesWhitespaceTest.php | 14 + .../tests/_files/CoverageMethodTest.php | 14 + .../tests/_files/CoverageNoneTest.php | 11 + .../tests/_files/CoverageNotPrivateTest.php | 14 + .../tests/_files/CoverageNotProtectedTest.php | 14 + .../tests/_files/CoverageNotPublicTest.php | 14 + .../tests/_files/CoverageNothingTest.php | 15 + .../tests/_files/CoveragePrivateTest.php | 14 + .../tests/_files/CoverageProtectedTest.php | 14 + .../tests/_files/CoveragePublicTest.php | 14 + .../CoverageTwoDefaultClassAnnotations.php | 17 + .../tests/_files/CoveredClass.php | 36 + .../tests/_files/CoveredFunction.php | 4 + .../php-code-coverage/tests/_files/Crash.php | 2 + .../NamespaceCoverageClassExtendedTest.php | 14 + .../_files/NamespaceCoverageClassTest.php | 14 + ...NamespaceCoverageCoversClassPublicTest.php | 17 + .../NamespaceCoverageCoversClassTest.php | 22 + .../_files/NamespaceCoverageMethodTest.php | 14 + .../NamespaceCoverageNotPrivateTest.php | 14 + .../NamespaceCoverageNotProtectedTest.php | 14 + .../_files/NamespaceCoverageNotPublicTest.php | 14 + .../_files/NamespaceCoveragePrivateTest.php | 14 + .../_files/NamespaceCoverageProtectedTest.php | 14 + .../_files/NamespaceCoveragePublicTest.php | 14 + .../tests/_files/NamespaceCoveredClass.php | 38 + .../_files/NotExistingCoveredElementTest.php | 26 + .../BankAccount.php.html | 249 + .../CoverageForBankAccount/dashboard.html | 287 + .../HTML/CoverageForBankAccount/index.html | 118 + .../dashboard.html | 285 + .../index.html | 118 + ...with_class_and_anonymous_function.php.html | 172 + .../dashboard.html | 283 + .../index.html | 108 + .../source_with_ignore.php.html | 196 + .../BankAccount.php.xml | 262 + .../XML/CoverageForBankAccount/index.xml | 33 + .../index.xml | 30 + ..._with_class_and_anonymous_function.php.xml | 161 + .../CoverageForFileWithIgnoredLines/index.xml | 30 + .../source_with_ignore.php.xml | 187 + .../class-with-anonymous-function-clover.xml | 21 + .../class-with-anonymous-function-crap4j.xml | 26 + .../class-with-anonymous-function-text.txt | 12 + .../tests/_files/ignored-lines-clover.xml | 17 + .../tests/_files/ignored-lines-crap4j.xml | 37 + .../tests/_files/ignored-lines-text.txt | 10 + ...urce_with_class_and_anonymous_function.php | 19 + .../tests/_files/source_with_ignore.php | 37 + .../tests/_files/source_with_namespace.php | 20 + .../source_with_oneline_annotations.php | 36 + .../_files/source_with_use_statements.php | 23 + .../tests/_files/source_without_ignore.php | 4 + .../tests/_files/source_without_namespace.php | 18 + .../php-code-coverage/tests/bootstrap.php | 7 + .../tests/tests/BuilderTest.php | 246 + .../tests/tests/CloverTest.php | 48 + .../tests/tests/CodeCoverageTest.php | 359 + .../tests/tests/Crap4jTest.php | 48 + ...nintentionallyCoveredCodeExceptionTest.php | 51 + .../tests/tests/FilterTest.php | 213 + .../tests/tests/HTMLTest.php | 102 + .../tests/tests/TextTest.php | 48 + .../tests/tests/UtilTest.php | 28 + .../php-code-coverage/tests/tests/XmlTest.php | 97 + .../phpunit/php-file-iterator/.gitattributes | 1 + .../php-file-iterator/.github/stale.yml | 40 + vendor/phpunit/php-file-iterator/.gitignore | 5 + vendor/phpunit/php-file-iterator/.php_cs.dist | 168 + vendor/phpunit/php-file-iterator/.travis.yml | 32 + vendor/phpunit/php-file-iterator/ChangeLog.md | 70 + vendor/phpunit/php-file-iterator/LICENSE | 33 + vendor/phpunit/php-file-iterator/README.md | 14 + .../phpunit/php-file-iterator/composer.json | 37 + vendor/phpunit/php-file-iterator/phpunit.xml | 21 + .../phpunit/php-file-iterator/src/Facade.php | 112 + .../phpunit/php-file-iterator/src/Factory.php | 83 + .../php-file-iterator/src/Iterator.php | 112 + .../php-file-iterator/tests/FactoryTest.php | 50 + .../phpunit/php-text-template/.gitattributes | 1 + vendor/phpunit/php-text-template/.gitignore | 5 + vendor/phpunit/php-text-template/LICENSE | 33 + vendor/phpunit/php-text-template/README.md | 14 + .../phpunit/php-text-template/composer.json | 29 + .../php-text-template/src/Template.php | 135 + vendor/phpunit/php-timer/.gitattributes | 1 + vendor/phpunit/php-timer/.github/FUNDING.yml | 1 + vendor/phpunit/php-timer/.github/stale.yml | 40 + vendor/phpunit/php-timer/.gitignore | 5 + vendor/phpunit/php-timer/.php_cs.dist | 197 + vendor/phpunit/php-timer/.travis.yml | 23 + vendor/phpunit/php-timer/ChangeLog.md | 36 + vendor/phpunit/php-timer/LICENSE | 33 + vendor/phpunit/php-timer/README.md | 49 + vendor/phpunit/php-timer/build.xml | 20 + vendor/phpunit/php-timer/composer.json | 42 + vendor/phpunit/php-timer/phpunit.xml | 19 + vendor/phpunit/php-timer/src/Exception.php | 14 + .../php-timer/src/RuntimeException.php | 14 + vendor/phpunit/php-timer/src/Timer.php | 100 + vendor/phpunit/php-timer/tests/TimerTest.php | 134 + .../phpunit/php-token-stream/.gitattributes | 1 + .../php-token-stream/.github/FUNDING.yml | 1 + vendor/phpunit/php-token-stream/.gitignore | 3 + vendor/phpunit/php-token-stream/.travis.yml | 26 + vendor/phpunit/php-token-stream/ChangeLog.md | 57 + vendor/phpunit/php-token-stream/LICENSE | 33 + vendor/phpunit/php-token-stream/README.md | 14 + vendor/phpunit/php-token-stream/build.xml | 21 + vendor/phpunit/php-token-stream/composer.json | 39 + vendor/phpunit/php-token-stream/phpunit.xml | 21 + vendor/phpunit/php-token-stream/src/Token.php | 1361 ++++ .../php-token-stream/src/Token/Stream.php | 609 ++ .../src/Token/Stream/CachingFactory.php | 46 + .../php-token-stream/src/Token/Util.php | 19 + .../tests/Token/ClassTest.php | 152 + .../tests/Token/ClosureTest.php | 64 + .../tests/Token/FunctionTest.php | 124 + .../tests/Token/IncludeTest.php | 53 + .../tests/Token/InterfaceTest.php | 169 + .../tests/Token/NamespaceTest.php | 62 + .../_fixture/classExtendsNamespacedClass.php | 10 + .../tests/_fixture/classInNamespace.php | 6 + .../tests/_fixture/classInScopedNamespace.php | 9 + .../_fixture/classUsesNamespacedFunction.php | 8 + .../class_with_method_named_empty.php | 7 + ...h_method_that_declares_anonymous_class.php | 15 + ..._method_that_declares_anonymous_class2.php | 16 + ...ltiple_anonymous_classes_and_functions.php | 26 + .../tests/_fixture/closure.php | 7 + .../tests/_fixture/issue19.php | 3 + .../tests/_fixture/issue30.php | 8 + ...tipleNamespacesWithOneClassUsingBraces.php | 12 + ...espacesWithOneClassUsingNonBraceSyntax.php | 14 + .../_fixture/php-code-coverage-issue-424.php | 13 + .../tests/_fixture/source.php | 42 + .../tests/_fixture/source2.php | 6 + .../tests/_fixture/source3.php | 14 + .../tests/_fixture/source4.php | 30 + .../tests/_fixture/source5.php | 5 + .../php-token-stream/tests/bootstrap.php | 15 + vendor/phpunit/phpunit/.gitattributes | 14 + vendor/phpunit/phpunit/.gitignore | 30 + vendor/phpunit/phpunit/.phive/phars.xml | 10 + vendor/phpunit/phpunit/.phpstorm.meta.php | 45 + vendor/phpunit/phpunit/ChangeLog-8.5.md | 88 + vendor/phpunit/phpunit/LICENSE | 33 + vendor/phpunit/phpunit/README.md | 41 + vendor/phpunit/phpunit/composer.json | 89 + vendor/phpunit/phpunit/phpunit | 61 + vendor/phpunit/phpunit/phpunit.xsd | 317 + vendor/phpunit/phpunit/src/Exception.php | 17 + .../phpunit/phpunit/src/Framework/Assert.php | 3556 +++++++++ .../src/Framework/Assert/Functions.php | 2597 +++++++ .../src/Framework/Constraint/ArrayHasKey.php | 80 + .../src/Framework/Constraint/ArraySubset.php | 129 + .../src/Framework/Constraint/Attribute.php | 79 + .../src/Framework/Constraint/Callback.php | 45 + .../Constraint/ClassHasAttribute.php | 86 + .../Constraint/ClassHasStaticAttribute.php | 59 + .../src/Framework/Constraint/Composite.php | 68 + .../src/Framework/Constraint/Constraint.php | 154 + .../src/Framework/Constraint/Count.php | 123 + .../Framework/Constraint/DirectoryExists.php | 53 + .../src/Framework/Constraint/Exception.php | 80 + .../Framework/Constraint/ExceptionCode.php | 61 + .../Framework/Constraint/ExceptionMessage.php | 71 + .../ExceptionMessageRegularExpression.php | 69 + .../src/Framework/Constraint/FileExists.php | 53 + .../src/Framework/Constraint/GreaterThan.php | 51 + .../src/Framework/Constraint/IsAnything.php | 51 + .../src/Framework/Constraint/IsEmpty.php | 65 + .../src/Framework/Constraint/IsEqual.php | 138 + .../src/Framework/Constraint/IsFalse.php | 35 + .../src/Framework/Constraint/IsFinite.php | 35 + .../src/Framework/Constraint/IsIdentical.php | 138 + .../src/Framework/Constraint/IsInfinite.php | 35 + .../src/Framework/Constraint/IsInstanceOf.php | 86 + .../src/Framework/Constraint/IsJson.php | 73 + .../src/Framework/Constraint/IsNan.php | 35 + .../src/Framework/Constraint/IsNull.php | 35 + .../src/Framework/Constraint/IsReadable.php | 53 + .../src/Framework/Constraint/IsTrue.php | 35 + .../src/Framework/Constraint/IsType.php | 199 + .../src/Framework/Constraint/IsWritable.php | 53 + .../src/Framework/Constraint/JsonMatches.php | 107 + .../JsonMatchesErrorMessageProvider.php | 62 + .../src/Framework/Constraint/LessThan.php | 51 + .../src/Framework/Constraint/LogicalAnd.php | 119 + .../src/Framework/Constraint/LogicalNot.php | 165 + .../src/Framework/Constraint/LogicalOr.php | 116 + .../src/Framework/Constraint/LogicalXor.php | 121 + .../Constraint/ObjectHasAttribute.php | 32 + .../Constraint/RegularExpression.php | 54 + .../src/Framework/Constraint/SameSize.php | 18 + .../Framework/Constraint/StringContains.php | 74 + .../Framework/Constraint/StringEndsWith.php | 46 + .../StringMatchesFormatDescription.php | 101 + .../Framework/Constraint/StringStartsWith.php | 52 + .../Constraint/TraversableContains.php | 115 + .../Constraint/TraversableContainsEqual.php | 84 + .../TraversableContainsIdentical.php | 83 + .../Constraint/TraversableContainsOnly.php | 87 + .../src/Framework/DataProviderTestSuite.php | 61 + .../src/Framework/Error/Deprecated.php | 14 + .../phpunit/src/Framework/Error/Error.php | 23 + .../phpunit/src/Framework/Error/Notice.php | 14 + .../phpunit/src/Framework/Error/Warning.php | 14 + .../Exception/AssertionFailedError.php | 24 + .../Exception/CodeCoverageException.php | 17 + .../CoveredCodeNotExecutedException.php | 17 + .../src/Framework/Exception/Exception.php | 77 + .../Exception/ExpectationFailedException.php | 41 + .../Exception/IncompleteTestError.php | 17 + .../Exception/InvalidArgumentException.php | 37 + .../InvalidCoversTargetException.php | 17 + .../InvalidDataProviderException.php | 17 + .../MissingCoversAnnotationException.php | 17 + .../Exception/NoChildTestSuiteException.php | 17 + .../src/Framework/Exception/OutputError.php | 17 + .../Exception/PHPTAssertionFailedError.php | 32 + .../Framework/Exception/RiskyTestError.php | 17 + .../Framework/Exception/SkippedTestError.php | 17 + .../Exception/SkippedTestSuiteError.php | 17 + .../Framework/Exception/SyntheticError.php | 61 + .../Exception/SyntheticSkippedError.php | 17 + .../UnintentionallyCoveredCodeError.php | 17 + .../src/Framework/Exception/Warning.php | 24 + .../src/Framework/ExceptionWrapper.php | 117 + .../phpunit/src/Framework/IncompleteTest.php | 17 + .../src/Framework/IncompleteTestCase.php | 71 + .../InvalidParameterGroupException.php | 17 + .../src/Framework/MockObject/Api/Api.php | 97 + .../src/Framework/MockObject/Api/Method.php | 28 + .../MockObject/Api/MockedCloneMethod.php | 21 + .../MockObject/Api/UnmockedCloneMethod.php | 23 + .../Framework/MockObject/Builder/Identity.php | 25 + .../MockObject/Builder/InvocationMocker.php | 293 + .../MockObject/Builder/InvocationStubber.php | 61 + .../Framework/MockObject/Builder/Match.php | 26 + .../MockObject/Builder/MethodNameMatch.php | 26 + .../MockObject/Builder/ParametersMatch.php | 48 + .../src/Framework/MockObject/Builder/Stub.php | 24 + .../MockObject/ConfigurableMethod.php | 53 + .../Exception/BadMethodCallException.php | 17 + ...ableMethodsAlreadyInitializedException.php | 17 + .../MockObject/Exception/Exception.php | 17 + .../IncompatibleReturnValueException.php | 17 + .../MockObject/Exception/RuntimeException.php | 17 + .../src/Framework/MockObject/Generator.php | 1050 +++ .../MockObject/Generator/deprecation.tpl | 2 + .../MockObject/Generator/mocked_class.tpl | 6 + .../MockObject/Generator/mocked_method.tpl | 22 + .../Generator/mocked_method_void.tpl | 20 + .../Generator/mocked_static_method.tpl | 5 + .../MockObject/Generator/proxied_method.tpl | 22 + .../Generator/proxied_method_void.tpl | 22 + .../MockObject/Generator/trait_class.tpl | 6 + .../MockObject/Generator/wsdl_class.tpl | 9 + .../MockObject/Generator/wsdl_method.tpl | 4 + .../src/Framework/MockObject/Invocation.php | 190 + .../MockObject/InvocationHandler.php | 194 + .../src/Framework/MockObject/Matcher.php | 274 + .../MockObject/MethodNameConstraint.php | 45 + .../src/Framework/MockObject/MockBuilder.php | 506 ++ .../src/Framework/MockObject/MockClass.php | 60 + .../src/Framework/MockObject/MockMethod.php | 372 + .../Framework/MockObject/MockMethodSet.php | 41 + .../src/Framework/MockObject/MockObject.php | 25 + .../src/Framework/MockObject/MockTrait.php | 46 + .../src/Framework/MockObject/MockType.php | 18 + .../MockObject/Rule/AnyInvokedCount.php | 36 + .../MockObject/Rule/AnyParameters.php | 31 + .../MockObject/Rule/ConsecutiveParameters.php | 132 + .../MockObject/Rule/InvocationOrder.php | 46 + .../MockObject/Rule/InvokedAtIndex.php | 71 + .../MockObject/Rule/InvokedAtLeastCount.php | 64 + .../MockObject/Rule/InvokedAtLeastOnce.php | 50 + .../MockObject/Rule/InvokedAtMostCount.php | 64 + .../MockObject/Rule/InvokedCount.php | 101 + .../Framework/MockObject/Rule/MethodName.php | 63 + .../Framework/MockObject/Rule/Parameters.php | 156 + .../MockObject/Rule/ParametersRule.php | 25 + .../phpunit/src/Framework/MockObject/Stub.php | 24 + .../MockObject/Stub/ConsecutiveCalls.php | 55 + .../Framework/MockObject/Stub/Exception.php | 44 + .../MockObject/Stub/ReturnArgument.php | 40 + .../MockObject/Stub/ReturnCallback.php | 54 + .../MockObject/Stub/ReturnReference.php | 44 + .../Framework/MockObject/Stub/ReturnSelf.php | 32 + .../Framework/MockObject/Stub/ReturnStub.php | 44 + .../MockObject/Stub/ReturnValueMap.php | 50 + .../src/Framework/MockObject/Stub/Stub.php | 27 + .../src/Framework/MockObject/Verifiable.php | 26 + .../phpunit/src/Framework/SelfDescribing.php | 21 + .../phpunit/src/Framework/SkippedTest.php | 17 + .../phpunit/src/Framework/SkippedTestCase.php | 71 + vendor/phpunit/phpunit/src/Framework/Test.php | 23 + .../phpunit/src/Framework/TestBuilder.php | 232 + .../phpunit/src/Framework/TestCase.php | 2526 +++++++ .../phpunit/src/Framework/TestFailure.php | 154 + .../phpunit/src/Framework/TestListener.php | 82 + .../TestListenerDefaultImplementation.php | 56 + .../phpunit/src/Framework/TestResult.php | 1220 +++ .../phpunit/src/Framework/TestSuite.php | 780 ++ .../src/Framework/TestSuiteIterator.php | 79 + .../phpunit/src/Framework/WarningTestCase.php | 73 + .../phpunit/src/Runner/BaseTestRunner.php | 156 + .../src/Runner/DefaultTestResultCache.php | 217 + .../phpunit/phpunit/src/Runner/Exception.php | 17 + .../Filter/ExcludeGroupFilterIterator.php | 21 + .../phpunit/src/Runner/Filter/Factory.php | 54 + .../src/Runner/Filter/GroupFilterIterator.php | 54 + .../Filter/IncludeGroupFilterIterator.php | 21 + .../src/Runner/Filter/NameFilterIterator.php | 126 + .../Runner/Hook/AfterIncompleteTestHook.php | 15 + .../src/Runner/Hook/AfterLastTestHook.php | 15 + .../src/Runner/Hook/AfterRiskyTestHook.php | 15 + .../src/Runner/Hook/AfterSkippedTestHook.php | 15 + .../Runner/Hook/AfterSuccessfulTestHook.php | 15 + .../src/Runner/Hook/AfterTestErrorHook.php | 15 + .../src/Runner/Hook/AfterTestFailureHook.php | 15 + .../phpunit/src/Runner/Hook/AfterTestHook.php | 21 + .../src/Runner/Hook/AfterTestWarningHook.php | 15 + .../src/Runner/Hook/BeforeFirstTestHook.php | 15 + .../src/Runner/Hook/BeforeTestHook.php | 15 + .../phpunit/phpunit/src/Runner/Hook/Hook.php | 14 + .../phpunit/src/Runner/Hook/TestHook.php | 14 + .../src/Runner/Hook/TestListenerAdapter.php | 140 + .../src/Runner/NullTestResultCache.php | 42 + .../phpunit/src/Runner/PhptTestCase.php | 751 ++ .../src/Runner/ResultCacheExtension.php | 107 + .../src/Runner/StandardTestSuiteLoader.php | 153 + .../phpunit/src/Runner/TestResultCache.php | 28 + .../phpunit/src/Runner/TestSuiteLoader.php | 22 + .../phpunit/src/Runner/TestSuiteSorter.php | 434 ++ vendor/phpunit/phpunit/src/Runner/Version.php | 66 + vendor/phpunit/phpunit/src/TextUI/Command.php | 1332 ++++ .../phpunit/phpunit/src/TextUI/Exception.php | 17 + vendor/phpunit/phpunit/src/TextUI/Help.php | 246 + .../phpunit/src/TextUI/ResultPrinter.php | 572 ++ .../phpunit/phpunit/src/TextUI/TestRunner.php | 1363 ++++ .../phpunit/src/Util/Annotation/DocBlock.php | 578 ++ .../phpunit/src/Util/Annotation/Registry.php | 89 + vendor/phpunit/phpunit/src/Util/Blacklist.php | 216 + vendor/phpunit/phpunit/src/Util/Color.php | 143 + .../phpunit/src/Util/Configuration.php | 1205 +++ .../src/Util/ConfigurationGenerator.php | 64 + .../phpunit/phpunit/src/Util/ErrorHandler.php | 145 + vendor/phpunit/phpunit/src/Util/Exception.php | 17 + .../phpunit/phpunit/src/Util/FileLoader.php | 77 + .../phpunit/phpunit/src/Util/Filesystem.php | 35 + vendor/phpunit/phpunit/src/Util/Filter.php | 107 + vendor/phpunit/phpunit/src/Util/Getopt.php | 181 + .../phpunit/phpunit/src/Util/GlobalState.php | 179 + .../src/Util/InvalidDataSetException.php | 17 + vendor/phpunit/phpunit/src/Util/Json.php | 86 + vendor/phpunit/phpunit/src/Util/Log/JUnit.php | 422 ++ .../phpunit/phpunit/src/Util/Log/TeamCity.php | 378 + .../src/Util/PHP/AbstractPhpProcess.php | 399 + .../src/Util/PHP/DefaultPhpProcess.php | 216 + .../src/Util/PHP/Template/PhptTestCase.tpl | 40 + .../src/Util/PHP/Template/TestCaseClass.tpl | 108 + .../src/Util/PHP/Template/TestCaseMethod.tpl | 111 + .../src/Util/PHP/WindowsPhpProcess.php | 46 + vendor/phpunit/phpunit/src/Util/Printer.php | 145 + .../phpunit/src/Util/RegularExpression.php | 28 + vendor/phpunit/phpunit/src/Util/Test.php | 894 +++ .../src/Util/TestDox/CliTestDoxPrinter.php | 352 + .../src/Util/TestDox/HtmlResultPrinter.php | 131 + .../src/Util/TestDox/NamePrettifier.php | 291 + .../src/Util/TestDox/ResultPrinter.php | 339 + .../src/Util/TestDox/TestDoxPrinter.php | 377 + .../src/Util/TestDox/TextResultPrinter.php | 46 + .../src/Util/TestDox/XmlResultPrinter.php | 248 + .../phpunit/src/Util/TextTestListRenderer.php | 49 + vendor/phpunit/phpunit/src/Util/Type.php | 50 + .../src/Util/VersionComparisonOperator.php | 54 + .../src/Util/XdebugFilterScriptGenerator.php | 75 + vendor/phpunit/phpunit/src/Util/Xml.php | 293 + .../phpunit/src/Util/XmlTestListRenderer.php | 85 + vendor/psr/log/LICENSE | 19 + vendor/psr/log/Psr/Log/AbstractLogger.php | 128 + .../log/Psr/Log/InvalidArgumentException.php | 7 + vendor/psr/log/Psr/Log/LogLevel.php | 18 + .../psr/log/Psr/Log/LoggerAwareInterface.php | 18 + vendor/psr/log/Psr/Log/LoggerAwareTrait.php | 26 + vendor/psr/log/Psr/Log/LoggerInterface.php | 125 + vendor/psr/log/Psr/Log/LoggerTrait.php | 142 + vendor/psr/log/Psr/Log/NullLogger.php | 30 + vendor/psr/log/Psr/Log/Test/DummyTest.php | 18 + .../log/Psr/Log/Test/LoggerInterfaceTest.php | 138 + vendor/psr/log/Psr/Log/Test/TestLogger.php | 147 + vendor/psr/log/README.md | 58 + vendor/psr/log/composer.json | 26 + vendor/sabberworm/php-css-parser/.gitignore | 1 + vendor/sabberworm/php-css-parser/.travis.yml | 22 + vendor/sabberworm/php-css-parser/CHANGELOG.md | 224 + vendor/sabberworm/php-css-parser/Doxyfile | 2310 ++++++ vendor/sabberworm/php-css-parser/README.md | 642 ++ .../sabberworm/php-css-parser/composer.json | 21 + .../sabberworm/php-css-parser/composer.lock | 1478 ++++ .../CSS/CSSList/AtRuleBlockList.php | 50 + .../Sabberworm/CSS/CSSList/CSSBlockList.php | 107 + .../lib/Sabberworm/CSS/CSSList/CSSList.php | 348 + .../lib/Sabberworm/CSS/CSSList/Document.php | 110 + .../lib/Sabberworm/CSS/CSSList/KeyFrame.php | 56 + .../lib/Sabberworm/CSS/Comment/Comment.php | 51 + .../Sabberworm/CSS/Comment/Commentable.php | 23 + .../lib/Sabberworm/CSS/OutputFormat.php | 322 + .../lib/Sabberworm/CSS/Parser.php | 41 + .../CSS/Parsing/OutputException.php | 12 + .../Sabberworm/CSS/Parsing/ParserState.php | 310 + .../CSS/Parsing/SourceException.php | 18 + .../CSS/Parsing/UnexpectedTokenException.php | 31 + .../lib/Sabberworm/CSS/Property/AtRule.php | 16 + .../Sabberworm/CSS/Property/CSSNamespace.php | 75 + .../lib/Sabberworm/CSS/Property/Charset.php | 66 + .../lib/Sabberworm/CSS/Property/Import.php | 69 + .../lib/Sabberworm/CSS/Property/Selector.php | 74 + .../lib/Sabberworm/CSS/Renderable.php | 9 + .../lib/Sabberworm/CSS/Rule/Rule.php | 236 + .../lib/Sabberworm/CSS/RuleSet/AtRuleSet.php | 44 + .../CSS/RuleSet/DeclarationBlock.php | 628 ++ .../lib/Sabberworm/CSS/RuleSet/RuleSet.php | 212 + .../lib/Sabberworm/CSS/Settings.php | 54 + .../lib/Sabberworm/CSS/Value/CSSFunction.php | 40 + .../lib/Sabberworm/CSS/Value/CSSString.php | 66 + .../lib/Sabberworm/CSS/Value/CalcFunction.php | 62 + .../CSS/Value/CalcRuleValueList.php | 14 + .../lib/Sabberworm/CSS/Value/Color.php | 95 + .../lib/Sabberworm/CSS/Value/LineName.php | 41 + .../Sabberworm/CSS/Value/PrimitiveValue.php | 10 + .../Sabberworm/CSS/Value/RuleValueList.php | 9 + .../lib/Sabberworm/CSS/Value/Size.php | 122 + .../lib/Sabberworm/CSS/Value/URL.php | 49 + .../lib/Sabberworm/CSS/Value/Value.php | 131 + .../lib/Sabberworm/CSS/Value/ValueList.php | 47 + vendor/sabberworm/php-css-parser/phpunit.xml | 10 + .../CSS/CSSList/AtRuleBlockListTest.php | 27 + .../Sabberworm/CSS/CSSList/DocumentTest.php | 26 + .../tests/Sabberworm/CSS/OutputFormatTest.php | 170 + .../tests/Sabberworm/CSS/ParserTest.php | 714 ++ .../CSS/RuleSet/DeclarationBlockTest.php | 267 + .../CSS/RuleSet/LenientParsingTest.php | 76 + .../php-css-parser/tests/bootstrap.php | 10 + .../files/-calc-no-space-around-minus.css | 1 + .../tests/files/-charset-after-rule.css | 5 + .../tests/files/-charset-in-block.css | 3 + .../tests/files/-empty-grid-linename.css | 1 + .../php-css-parser/tests/files/-empty.css | 0 .../tests/files/-end-token-2.css | 1 + .../php-css-parser/tests/files/-end-token.css | 1 + .../tests/files/-fault-tolerance.css | 15 + .../php-css-parser/tests/files/-tobedone.css | 9 + .../php-css-parser/tests/files/1readme.css | 10 + .../php-css-parser/tests/files/2readme.css | 5 + .../php-css-parser/tests/files/atrules.css | 57 + .../tests/files/calc-nested.css | 4 + .../php-css-parser/tests/files/calc.css | 6 + .../tests/files/case-insensitivity.css | 15 + .../php-css-parser/tests/files/colortest.css | 12 + .../php-css-parser/tests/files/comments.css | 17 + .../tests/files/create-shorthands.css | 6 + .../php-css-parser/tests/files/docuwiki.css | 1 + .../tests/files/empty-grid-linename.css | 1 + .../tests/files/expand-shorthands.css | 7 + .../php-css-parser/tests/files/functions.css | 21 + .../tests/files/grid-linename.css | 2 + .../php-css-parser/tests/files/hex-alpha.css | 2 + .../php-css-parser/tests/files/ie-hacks.css | 9 + .../php-css-parser/tests/files/ie.css | 6 + .../php-css-parser/tests/files/important.css | 8 + .../tests/files/inner-color.css | 3 + .../tests/files/line-numbers.css | 32 + .../tests/files/missing-property-value.css | 4 + .../php-css-parser/tests/files/ms-filter.css | 1 + .../php-css-parser/tests/files/namespaces.css | 18 + .../php-css-parser/tests/files/nested.css | 17 + .../php-css-parser/tests/files/slashed.css | 4 + .../tests/files/specificity.css | 7 + .../tests/files/trailing-whitespace.css | 2 + .../tests/files/unicode-range.css | 3 + .../php-css-parser/tests/files/unicode.css | 12 + .../tests/files/unmatched_braces.css | 18 + .../tests/files/unopened-close-brackets.css | 3 + .../php-css-parser/tests/files/url.css | 4 + .../php-css-parser/tests/files/values.css | 14 + .../php-css-parser/tests/files/webkit.css | 1 + .../php-css-parser/tests/files/whitespace.css | 3 + .../php-css-parser/tests/phpunit.xml | 1 + .../php-css-parser/tests/quickdump.php | 20 + .../code-unit-reverse-lookup/.gitignore | 4 + .../code-unit-reverse-lookup/.php_cs | 67 + .../code-unit-reverse-lookup/.travis.yml | 25 + .../code-unit-reverse-lookup/ChangeLog.md | 10 + .../code-unit-reverse-lookup/LICENSE | 33 + .../code-unit-reverse-lookup/README.md | 14 + .../code-unit-reverse-lookup/build.xml | 22 + .../code-unit-reverse-lookup/composer.json | 28 + .../code-unit-reverse-lookup/phpunit.xml | 21 + .../code-unit-reverse-lookup/src/Wizard.php | 111 + .../tests/WizardTest.php | 45 + vendor/sebastian/comparator/.github/stale.yml | 40 + vendor/sebastian/comparator/.gitignore | 4 + vendor/sebastian/comparator/.php_cs.dist | 189 + vendor/sebastian/comparator/.travis.yml | 33 + vendor/sebastian/comparator/ChangeLog.md | 59 + vendor/sebastian/comparator/LICENSE | 33 + vendor/sebastian/comparator/README.md | 37 + vendor/sebastian/comparator/build.xml | 21 + vendor/sebastian/comparator/composer.json | 54 + vendor/sebastian/comparator/phpunit.xml | 21 + .../comparator/src/ArrayComparator.php | 130 + .../sebastian/comparator/src/Comparator.php | 61 + .../comparator/src/ComparisonFailure.php | 128 + .../comparator/src/DOMNodeComparator.php | 86 + .../comparator/src/DateTimeComparator.php | 86 + .../comparator/src/DoubleComparator.php | 56 + .../comparator/src/ExceptionComparator.php | 52 + vendor/sebastian/comparator/src/Factory.php | 138 + .../comparator/src/MockObjectComparator.php | 47 + .../comparator/src/NumericComparator.php | 68 + .../comparator/src/ObjectComparator.php | 106 + .../comparator/src/ResourceComparator.php | 52 + .../comparator/src/ScalarComparator.php | 91 + .../src/SplObjectStorageComparator.php | 69 + .../comparator/src/TypeComparator.php | 59 + .../comparator/tests/ArrayComparatorTest.php | 161 + .../tests/ComparisonFailureTest.php | 59 + .../tests/DOMNodeComparatorTest.php | 180 + .../tests/DateTimeComparatorTest.php | 213 + .../comparator/tests/DoubleComparatorTest.php | 135 + .../tests/ExceptionComparatorTest.php | 136 + .../comparator/tests/FactoryTest.php | 117 + .../tests/MockObjectComparatorTest.php | 168 + .../tests/NumericComparatorTest.php | 123 + .../comparator/tests/ObjectComparatorTest.php | 150 + .../tests/ResourceComparatorTest.php | 122 + .../comparator/tests/ScalarComparatorTest.php | 164 + .../tests/SplObjectStorageComparatorTest.php | 145 + .../comparator/tests/TypeComparatorTest.php | 107 + .../comparator/tests/_fixture/Author.php | 26 + .../comparator/tests/_fixture/Book.php | 19 + .../tests/_fixture/ClassWithToString.php | 18 + .../comparator/tests/_fixture/SampleClass.php | 29 + .../comparator/tests/_fixture/Struct.php | 23 + .../comparator/tests/_fixture/TestClass.php | 14 + .../tests/_fixture/TestClassComparator.php | 14 + vendor/sebastian/diff/.github/stale.yml | 40 + vendor/sebastian/diff/.gitignore | 6 + vendor/sebastian/diff/.php_cs.dist | 168 + vendor/sebastian/diff/.travis.yml | 26 + vendor/sebastian/diff/ChangeLog.md | 53 + vendor/sebastian/diff/LICENSE | 33 + vendor/sebastian/diff/README.md | 195 + vendor/sebastian/diff/build.xml | 22 + vendor/sebastian/diff/composer.json | 39 + vendor/sebastian/diff/phpunit.xml | 21 + vendor/sebastian/diff/src/Chunk.php | 90 + vendor/sebastian/diff/src/Diff.php | 67 + vendor/sebastian/diff/src/Differ.php | 330 + .../src/Exception/ConfigurationException.php | 40 + .../diff/src/Exception/Exception.php | 15 + .../Exception/InvalidArgumentException.php | 15 + vendor/sebastian/diff/src/Line.php | 44 + .../LongestCommonSubsequenceCalculator.php | 24 + ...ientLongestCommonSubsequenceCalculator.php | 81 + .../src/Output/AbstractChunkOutputBuilder.php | 56 + .../diff/src/Output/DiffOnlyOutputBuilder.php | 68 + .../src/Output/DiffOutputBuilderInterface.php | 20 + .../Output/StrictUnifiedDiffOutputBuilder.php | 318 + .../src/Output/UnifiedDiffOutputBuilder.php | 264 + vendor/sebastian/diff/src/Parser.php | 106 + ...ientLongestCommonSubsequenceCalculator.php | 66 + vendor/sebastian/diff/tests/ChunkTest.php | 73 + vendor/sebastian/diff/tests/DiffTest.php | 55 + vendor/sebastian/diff/tests/DifferTest.php | 444 ++ .../Exception/ConfigurationExceptionTest.php | 41 + .../InvalidArgumentExceptionTest.php | 33 + vendor/sebastian/diff/tests/LineTest.php | 44 + .../tests/LongestCommonSubsequenceTest.php | 201 + .../MemoryEfficientImplementationTest.php | 22 + .../Output/AbstractChunkOutputBuilderTest.php | 152 + .../Output/DiffOnlyOutputBuilderTest.php | 76 + ...nifiedDiffOutputBuilderIntegrationTest.php | 299 + ...nifiedDiffOutputBuilderIntegrationTest.php | 163 + ...ctUnifiedDiffOutputBuilderDataProvider.php | 189 + .../StrictUnifiedDiffOutputBuilderTest.php | 684 ++ .../UnifiedDiffOutputBuilderDataProvider.php | 396 + .../Output/UnifiedDiffOutputBuilderTest.php | 90 + vendor/sebastian/diff/tests/ParserTest.php | 170 + .../tests/TimeEfficientImplementationTest.php | 22 + .../sebastian/diff/tests/Utils/FileUtils.php | 31 + .../tests/Utils/UnifiedDiffAssertTrait.php | 277 + .../UnifiedDiffAssertTraitIntegrationTest.php | 129 + .../Utils/UnifiedDiffAssertTraitTest.php | 434 ++ .../diff/tests/fixtures/.editorconfig | 1 + .../1_a.txt | 1 + .../1_b.txt | 0 .../2_a.txt | 35 + .../2_b.txt | 18 + .../diff/tests/fixtures/out/.editorconfig | 1 + .../diff/tests/fixtures/out/.gitignore | 2 + .../sebastian/diff/tests/fixtures/patch.txt | 9 + .../sebastian/diff/tests/fixtures/patch2.txt | 21 + .../diff/tests/fixtures/serialized_diff.bin | Bin 0 -> 4143 bytes .../sebastian/environment/.github/FUNDING.yml | 1 + vendor/sebastian/environment/.gitignore | 6 + vendor/sebastian/environment/.php_cs.dist | 199 + vendor/sebastian/environment/.travis.yml | 28 + vendor/sebastian/environment/ChangeLog.md | 120 + vendor/sebastian/environment/LICENSE | 33 + vendor/sebastian/environment/README.md | 17 + vendor/sebastian/environment/build.xml | 19 + vendor/sebastian/environment/composer.json | 37 + vendor/sebastian/environment/phpunit.xml | 20 + vendor/sebastian/environment/src/Console.php | 164 + .../environment/src/OperatingSystem.php | 48 + vendor/sebastian/environment/src/Runtime.php | 265 + .../environment/tests/ConsoleTest.php | 64 + .../environment/tests/OperatingSystemTest.php | 60 + .../environment/tests/RuntimeTest.php | 165 + vendor/sebastian/exporter/.github/FUNDING.yml | 1 + vendor/sebastian/exporter/.gitignore | 5 + vendor/sebastian/exporter/.php_cs.dist | 190 + vendor/sebastian/exporter/.travis.yml | 24 + vendor/sebastian/exporter/ChangeLog.md | 15 + vendor/sebastian/exporter/LICENSE | 33 + vendor/sebastian/exporter/README.md | 171 + vendor/sebastian/exporter/build.xml | 19 + vendor/sebastian/exporter/composer.json | 53 + vendor/sebastian/exporter/phpunit.xml | 19 + vendor/sebastian/exporter/src/Exporter.php | 303 + .../sebastian/exporter/tests/ExporterTest.php | 432 ++ .../sebastian/global-state/.github/stale.yml | 40 + vendor/sebastian/global-state/.gitignore | 6 + vendor/sebastian/global-state/.php_cs.dist | 197 + vendor/sebastian/global-state/.travis.yml | 24 + vendor/sebastian/global-state/ChangeLog.md | 16 + vendor/sebastian/global-state/LICENSE | 33 + vendor/sebastian/global-state/README.md | 16 + vendor/sebastian/global-state/build.xml | 19 + vendor/sebastian/global-state/composer.json | 48 + vendor/sebastian/global-state/phpunit.xml | 27 + .../sebastian/global-state/src/Blacklist.php | 118 + .../global-state/src/CodeExporter.php | 91 + .../sebastian/global-state/src/Restorer.php | 132 + .../sebastian/global-state/src/Snapshot.php | 419 ++ .../global-state/src/exceptions/Exception.php | 14 + .../src/exceptions/RuntimeException.php | 14 + .../global-state/tests/BlacklistTest.php | 117 + .../global-state/tests/CodeExporterTest.php | 35 + .../global-state/tests/RestorerTest.php | 68 + .../global-state/tests/SnapshotTest.php | 120 + .../tests/_fixture/BlacklistedChildClass.php | 14 + .../tests/_fixture/BlacklistedClass.php | 15 + .../tests/_fixture/BlacklistedImplementor.php | 15 + .../tests/_fixture/BlacklistedInterface.php | 14 + .../tests/_fixture/SnapshotClass.php | 35 + .../tests/_fixture/SnapshotDomDocument.php | 16 + .../tests/_fixture/SnapshotFunctions.php | 14 + .../tests/_fixture/SnapshotTrait.php | 14 + vendor/sebastian/object-enumerator/.gitignore | 8 + vendor/sebastian/object-enumerator/.php_cs | 67 + .../sebastian/object-enumerator/.travis.yml | 26 + .../sebastian/object-enumerator/ChangeLog.md | 53 + vendor/sebastian/object-enumerator/LICENSE | 33 + vendor/sebastian/object-enumerator/README.md | 14 + vendor/sebastian/object-enumerator/build.xml | 22 + .../sebastian/object-enumerator/composer.json | 35 + .../sebastian/object-enumerator/phpunit.xml | 20 + .../object-enumerator/src/Enumerator.php | 85 + .../object-enumerator/src/Exception.php | 15 + .../src/InvalidArgumentException.php | 15 + .../tests/EnumeratorTest.php | 139 + .../tests/_fixture/ExceptionThrower.php | 28 + vendor/sebastian/object-reflector/.gitignore | 4 + vendor/sebastian/object-reflector/.php_cs | 79 + vendor/sebastian/object-reflector/.travis.yml | 26 + .../sebastian/object-reflector/ChangeLog.md | 20 + vendor/sebastian/object-reflector/LICENSE | 33 + vendor/sebastian/object-reflector/README.md | 14 + vendor/sebastian/object-reflector/build.xml | 22 + .../sebastian/object-reflector/composer.json | 33 + vendor/sebastian/object-reflector/phpunit.xml | 19 + .../object-reflector/src/Exception.php | 17 + .../src/InvalidArgumentException.php | 17 + .../object-reflector/src/ObjectReflector.php | 51 + .../tests/ObjectReflectorTest.php | 70 + .../tests/_fixture/ChildClass.php | 25 + .../ClassWithIntegerAttributeName.php | 22 + .../tests/_fixture/ParentClass.php | 20 + vendor/sebastian/recursion-context/.gitignore | 3 + .../sebastian/recursion-context/.travis.yml | 23 + vendor/sebastian/recursion-context/LICENSE | 33 + vendor/sebastian/recursion-context/README.md | 14 + vendor/sebastian/recursion-context/build.xml | 21 + .../sebastian/recursion-context/composer.json | 36 + .../sebastian/recursion-context/phpunit.xml | 19 + .../recursion-context/src/Context.php | 167 + .../recursion-context/src/Exception.php | 17 + .../src/InvalidArgumentException.php | 17 + .../recursion-context/tests/ContextTest.php | 142 + .../resource-operations/.github/stale.yml | 40 + .../sebastian/resource-operations/.gitignore | 5 + .../resource-operations/.php_cs.dist | 191 + .../resource-operations/ChangeLog.md | 26 + vendor/sebastian/resource-operations/LICENSE | 33 + .../sebastian/resource-operations/README.md | 14 + .../sebastian/resource-operations/build.xml | 38 + .../resource-operations/build/generate.php | 65 + .../resource-operations/composer.json | 33 + .../src/ResourceOperations.php | 2232 ++++++ .../tests/ResourceOperationsTest.php | 26 + vendor/sebastian/type/.gitattributes | 2 + vendor/sebastian/type/.github/FUNDING.yml | 1 + vendor/sebastian/type/.gitignore | 72 + vendor/sebastian/type/.php_cs.dist | 200 + vendor/sebastian/type/.travis.yml | 53 + vendor/sebastian/type/ChangeLog.md | 38 + vendor/sebastian/type/LICENSE | 33 + vendor/sebastian/type/README.md | 17 + vendor/sebastian/type/build.xml | 31 + vendor/sebastian/type/composer.json | 49 + vendor/sebastian/type/phive.xml | 5 + vendor/sebastian/type/phpunit.xml | 23 + vendor/sebastian/type/psalm.xml | 53 + vendor/sebastian/type/src/CallableType.php | 182 + .../sebastian/type/src/GenericObjectType.php | 46 + vendor/sebastian/type/src/IterableType.php | 67 + vendor/sebastian/type/src/NullType.php | 28 + vendor/sebastian/type/src/ObjectType.php | 63 + vendor/sebastian/type/src/SimpleType.php | 86 + vendor/sebastian/type/src/Type.php | 75 + vendor/sebastian/type/src/TypeName.php | 77 + vendor/sebastian/type/src/UnknownType.php | 28 + vendor/sebastian/type/src/VoidType.php | 28 + .../type/src/exception/Exception.php | 14 + .../type/src/exception/RuntimeException.php | 14 + .../type/tests/_fixture/ChildClass.php | 14 + .../_fixture/ClassWithCallbackMethods.php | 21 + .../tests/_fixture/ClassWithInvokeMethod.php | 17 + .../type/tests/_fixture/Iterator.php | 33 + .../type/tests/_fixture/ParentClass.php | 17 + .../type/tests/_fixture/callback_function.php | 14 + .../type/tests/unit/CallableTypeTest.php | 150 + .../type/tests/unit/GenericObjectTypeTest.php | 86 + .../type/tests/unit/IterableTypeTest.php | 97 + .../type/tests/unit/NullTypeTest.php | 72 + .../type/tests/unit/ObjectTypeTest.php | 140 + .../type/tests/unit/SimpleTypeTest.php | 162 + .../type/tests/unit/TypeNameTest.php | 59 + vendor/sebastian/type/tests/unit/TypeTest.php | 85 + .../type/tests/unit/UnknownTypeTest.php | 58 + .../type/tests/unit/VoidTypeTest.php | 70 + vendor/sebastian/version/.gitattributes | 1 + vendor/sebastian/version/.gitignore | 1 + vendor/sebastian/version/.php_cs | 66 + vendor/sebastian/version/LICENSE | 33 + vendor/sebastian/version/README.md | 43 + vendor/sebastian/version/composer.json | 29 + vendor/sebastian/version/src/Version.php | 109 + vendor/symfony/polyfill-ctype/Ctype.php | 227 + vendor/symfony/polyfill-ctype/LICENSE | 19 + vendor/symfony/polyfill-ctype/README.md | 12 + vendor/symfony/polyfill-ctype/bootstrap.php | 46 + vendor/symfony/polyfill-ctype/composer.json | 38 + vendor/theseer/tokenizer/.php_cs.dist | 213 + vendor/theseer/tokenizer/CHANGELOG.md | 63 + vendor/theseer/tokenizer/LICENSE | 30 + vendor/theseer/tokenizer/README.md | 49 + vendor/theseer/tokenizer/composer.json | 27 + vendor/theseer/tokenizer/src/Exception.php | 5 + vendor/theseer/tokenizer/src/NamespaceUri.php | 25 + .../tokenizer/src/NamespaceUriException.php | 5 + vendor/theseer/tokenizer/src/Token.php | 35 + .../theseer/tokenizer/src/TokenCollection.php | 93 + .../src/TokenCollectionException.php | 5 + vendor/theseer/tokenizer/src/Tokenizer.php | 137 + .../theseer/tokenizer/src/XMLSerializer.php | 79 + vendor/webmozart/assert/.editorconfig | 12 + vendor/webmozart/assert/CHANGELOG.md | 175 + vendor/webmozart/assert/LICENSE | 20 + vendor/webmozart/assert/README.md | 283 + vendor/webmozart/assert/composer.json | 38 + vendor/webmozart/assert/psalm.xml | 14 + vendor/webmozart/assert/src/Assert.php | 2048 +++++ vendor/webmozart/assert/src/Mixin.php | 1971 +++++ writable/.htaccess | 6 + writable/cache/index.html | 11 + writable/debugbar/.gitkeep | 0 writable/debugbar/debugbar_1606125960.json | 1 + writable/debugbar/debugbar_1606125961.json | 1 + writable/debugbar/debugbar_1606126068.json | 1 + writable/debugbar/debugbar_1606126069.json | 1 + writable/debugbar/debugbar_1606126144.json | 1 + writable/debugbar/debugbar_1606126145.json | 1 + writable/debugbar/debugbar_1606126148.json | 1 + writable/debugbar/debugbar_1606126149.json | 1 + writable/debugbar/debugbar_1606126159.json | 1 + writable/debugbar/debugbar_1606126160.json | 1 + writable/debugbar/debugbar_1606126161.json | 1 + writable/debugbar/debugbar_1606126162.json | 1 + writable/debugbar/debugbar_1606126164.json | 1 + writable/debugbar/debugbar_1606126172.json | 1 + writable/debugbar/debugbar_1606126173.json | 1 + writable/debugbar/debugbar_1606126186.json | 1 + writable/debugbar/debugbar_1606126187.json | 1 + writable/debugbar/debugbar_1606126232.json | 1 + writable/debugbar/debugbar_1606126233.json | 1 + writable/debugbar/debugbar_1606126239.json | 1 + writable/debugbar/debugbar_1606126241.json | 1 + writable/logs/index.html | 11 + ...ci_session04tdbauigi4bltm1lefpv6dv6v97503n | 1 + ...ci_session088hbi278cnj24brm5qgb21jhjoat0dt | 1 + ...ci_session09dca1ja5recdm111soapgagh4189drh | 1 + ...ci_session0acdga4ht0q1bf9765b089m7g95l84iu | 1 + ...ci_session0al9n5o0psah5atkoae2tot6p593pe3u | 1 + ...ci_session0bhr720mesn9si1e1k411bqi0m78i1r5 | 1 + ...ci_session0gcqfgfas4hse2pkk4g8uhikdib4d99p | 1 + ...ci_session0hgki3cuce05m4o9e99uckue59u7fngc | 1 + ...ci_session0opu017b572p42b10mhpdsuohs9d6hun | 1 + ...ci_session0pioirjpaft1sfpmu2vkkdj3devlusds | 1 + ...ci_session0pqo738djncmeajs3f1q8d4uersclrcq | 1 + ...ci_session0qidupcqgnl2fb9porf79hbera4sv8as | 1 + ...ci_session0rmqu0c2ukj75q600ps7ohdjc8vat2cf | 1 + ...ci_session16kvibjmqqr32v0kdq9ue79cmpk8c9f4 | 1 + ...ci_session1a6kk2bte2o53r0nd76sbrfahl5hq4dr | 1 + ...ci_session1aivp7vsj085dovu6naltbs1kud7a7t1 | 1 + ...ci_session1di4otssj7g6orshhm3731atcef0e3u1 | 1 + ...ci_session1g5rirvhntefcjaffplkajqn7s1n7f7u | 1 + ...ci_session1gdesiuamifnh0hp5geqcrf393l6p4gu | 1 + ...ci_session1k8o4suv0ggbhfsoa8ga456u4dlpl1qb | 1 + ...ci_session1qte9ihcd7vl97ckp8u023eujio1hfn7 | 1 + ...ci_session1sbu968fn4hm8l25m3971eip34594ph4 | 1 + ...ci_session20hvc0f26rr0h7ojk4esv7u7aej9k79k | 1 + ...ci_session21il06tdjiknsaflvh2jj1n5gn0nl05r | 1 + ...ci_session2anlt5spjqll2ga0kuakv3tu8tg0hibh | 1 + ...ci_session2bjf76r4i7880s2v8fi1pvof0lcpqd8o | 1 + ...ci_session2ekmsiujl42b4n0fqu3pvocg71esiln3 | 1 + ...ci_session2lbih2ll21355h314u919lr4se5d5ufe | 1 + ...ci_session2lcjvscemjcfp6bla4kjl2i5geucn6n3 | 1 + ...ci_session2mb3s28kridq52snfpi06pli1abhclik | 1 + ...ci_session3fau6aabcuvl1d05ie3deaktmdfhmgak | 1 + ...ci_session3j3f5ikcmthmrn1jrqsft5knld9urucs | 1 + ...ci_session3jq12qmd9i0e5bghk0es1reso1jgre2n | 1 + ...ci_session3pra6oan9gts4gbombtfolh8hf0v9i04 | 1 + ...ci_session3sdhav4eqqcjkpa3c1ong9avqsim5fn3 | 1 + ...ci_session3su5tf1vvebs7m0ti71vc2mhkk5vpbks | 1 + ...ci_session45tojjlt5gcu930qv8r982po7onkfc3n | 1 + ...ci_session45vibugm4n5dlc8vigi4gclpne6tnm2g | 1 + ...ci_session474ka2vlqficlead0pi4rgug8cqhpbfa | 1 + ...ci_session47b84n02plfomcht0uh6eemm0p1ellc5 | 1 + ...ci_session4a44v87b1bn510mesrc4tac3e19e3g5l | 1 + ...ci_session4he0br81kjkb4it00k8kf3m3ht65eb9n | 1 + ...ci_session4i89ai8g9lv8btqq8lui8ji2fpup1dhm | 1 + ...ci_session4up09sdoq2a61qe6hepcvg8mregepr4a | 1 + ...ci_session59uu6e4b8l0vkrto5mcguldpvcadhbit | 1 + ...ci_session5emqdiovemci4cspj00ipl3iapc8ebac | 1 + ...ci_session5fhga8elirpscb68j0q1lgecd0qsmudm | 1 + ...ci_session5kclo7leht8cgngcu95equ6s03lkbcio | 1 + ...ci_session5otislqsvcule34gr7n9obiel43737h4 | 1 + ...ci_session5ph2muil3v0815cqqaq58cnqvsjns4vl | 1 + ...ci_session61sbr15tubctuguv5a62lv87ct4piioh | 1 + ...ci_session646j64r0cja7jqvav1s58fvpk2j4ep95 | 1 + ...ci_session64pgpq7jes17uq4odeulr5k5vnpm79sk | 1 + ...ci_session6ktchjbodu0q97ptchkmddkj2onbr3np | 1 + ...ci_session6lo33p15f97q8b6q7a90t54qgj2qrdmr | 1 + ...ci_session6okm3maao8i74kcsr3j5uit38jplste9 | 1 + ...ci_session6q2o5lr03kjl9jadrmhssa67cfbibcu8 | 1 + ...ci_session6s02cphd7k56pjrskek5hjsn4nmr6msu | 1 + ...ci_session6u95ht2pgbl2t333rrb40pt6pipjd5dd | 1 + ...ci_session72mi8f39d8bdh1fkfkvcp3t0p6mikg1k | 1 + ...ci_session778fe271efhqq5r5d95gkh4dmq6o47qh | 1 + ...ci_session7s9koloiufpq5sn07annpm0jih1u73k2 | 1 + ...ci_session7tj423ntne3h443ocq5nc0vldedo284q | 1 + ...ci_session8cbhiv06ciaes1aki05dtvvmjtft4n76 | 1 + ...ci_session8fpt7srj018i999r6c5shvp1n6iq6lqj | 1 + ...ci_session8lg75nnjgp8sqiihvl9pda8pscan178l | 1 + ...ci_session8n3aqdonc1rcs0v3mi7usr69u0sqqf6l | 1 + ...ci_session8vpll4c9lpr2a4bbvm2psr0a1k6mona1 | 1 + ...ci_session92t5d9i2mkk98artlc7575gsi5lh9v1q | 1 + ...ci_session93ofqbjphe8dtmhed6s917ic91u8pi80 | 1 + ...ci_session940l3k8p856gtsj9fggiiknphid1qe46 | 1 + ...ci_session98i0arn4mbd1e0bvp1dfjtvf7n6qg3hi | 1 + ...ci_session9cvjmf0kc10saikb3e7abl3i0br5bshp | 1 + ...ci_session9n85e08iiemvag2pgikomqhc94plt5hg | 1 + ...ci_session9qb5776d2nplv58j9h38el14q6cg6q58 | 1 + ...ci_sessionac68krfans71fomm5fg1682kvo1jd6l2 | 1 + ...ci_sessionae1l999fqji3rcpii8kd0fob42daik99 | 1 + ...ci_sessionaes9ad5o4oau7cp4sdhfaavdngbkvqe6 | 1 + ...ci_sessionaf3ocuh14ps3t1rckpf6sr460p3v9ln9 | 1 + ...ci_sessionaig5qm3n2jrbe7c0j2rb4iups5csoenj | 1 + ...ci_sessionapfuh9n2upp1u1i8ub83i749fva6lgfv | 1 + ...ci_sessionas2fdl3eshnk0eakgndgcqshmcrp8qn6 | 1 + ...ci_sessionasmgt9kiftf5rqmqkjs1fas6j8ojqqu9 | 1 + ...ci_sessionatc38o656kesuf6mnm7418ulog4rs6bc | 1 + ...ci_sessionauj12av2dj55j9ih0dn2b2f6b1qllnj6 | 1 + ...ci_sessionavev1kdm9kp6f4q4faeru65ric2npjge | 1 + ...ci_sessionavqa9m291sap04po6k6mvktpnus94h3p | 1 + ...ci_sessionb69pc4df2gurgf392le3uc8djisqk07b | 1 + ...ci_sessionbclnpnjud527fti9t5geunf1n8s7ppsg | 1 + ...ci_sessionbhm7eunaoq2420d1ge17tfc5psns01m2 | 1 + ...ci_sessionbmoas2h38298moa0v9rgp8ntnkd26dnb | 1 + ...ci_sessionbo3rg9cvdmsh87cle6dnfafl6o5dkek9 | 1 + ...ci_sessionbu1dgi93pgot640k3bsvgmkv5pcbbab7 | 1 + ...ci_sessionc2v1n8ron574d6pujjr4h67moqkd7pbt | 1 + ...ci_sessionc9ont924kmb8v5ja9sojjkh4d697n7ji | 1 + ...ci_sessionchp2cbm8c9qkc4gtrp0ljpb5e1sg8soe | 1 + ...ci_sessioncikio11mec5ncfg864adhmnl8gcl0a7h | 1 + ...ci_sessioncrsif2p7c585n8i8er1nlr7a8rh5c0ta | 1 + ...ci_sessioncvek4389hf8lggv21vcqbkn83unkd9cm | 1 + ...ci_sessiond6r4507fdtnbnl6lhmdnnvo87rigm3lf | 1 + ...ci_sessiond80an0rqlj2lfutffpj8f2g1mh8h8jt0 | 1 + ...ci_sessiond8blsho945m6282kiamamgrk7ljm4t4c | 1 + ...ci_sessiondgibd2aq4vm8aom3a5t7q7i478che9nq | 1 + ...ci_sessiondj9f14p9c87c4seqncd7u3m6h9nt543v | 1 + ...ci_sessiondjfmv0464tnkh02m31eip1mcqhp70oo5 | 1 + ...ci_sessiondsnc3irs1jaijaqeomjsh8t91rou0bc9 | 1 + ...ci_sessiondu89ejhkjs0teehk3nlj4fss13uu17s5 | 1 + ...ci_sessione36qsn8d35ap90as82uf4rmshmdfnutq | 1 + ...ci_sessione5fguno70i95i5ietl4sral7m1e6eti6 | 1 + ...ci_sessione7aijevv9becv3aipp7m4f56ei5nbu3a | 1 + ...ci_sessionec3secsh35ge1p61nlmo6a2m1mq6br2u | 1 + ...ci_sessioneebb0kcon2tchhqtdssjocrfhdm2secg | 1 + ...ci_sessionej123t6468ta98u03cf9cmsq8jivnuot | 1 + ...ci_sessionev0860f2uke7qoe7phtf8m5pm93ii998 | 1 + ...ci_sessionf7tj449jjtqb7fbobqoteccl4tmhie9a | 1 + ...ci_sessionf8umabnpftjnp78h6kc61rq6fc0sur8k | 1 + ...ci_sessionfbrq89ujc39grg04tdad43j0mspo3sru | 1 + ...ci_sessionfbufoghthijvnmpcsdebrr5obie0d3vl | 1 + ...ci_sessionfd8unj9mjtgtqn00kffcksju3vq8kk32 | 1 + ...ci_sessionfl792n7lr0tsmfh4l7kg8m4b3rc0pim2 | 1 + ...ci_sessionfmi49a6fnnepg9eq99hb28k0haqibl8h | 1 + ...ci_sessiong9r3d2ih8r7qpfrh505m42a7nupmqd7j | 1 + ...ci_sessionga8k14tjvksppap8o1f5g7klnnqep6n1 | 1 + ...ci_sessiongo1ss8q1ge9s3eqqrndo8sp0jrtce8o1 | 1 + ...ci_sessiongsb6ebqksp7lo8nivh5fdk1pnoclgib3 | 1 + ...ci_sessionh5dvm4s2muqvrorjv4vsd2j38tvj0lb8 | 1 + ...ci_sessionh6ku3qcj3u9k97g77224t9p4uq9n6ogb | 1 + ...ci_sessionh90e3j80ruji7a44tqbfviapvkd0dpd0 | 1 + ...ci_sessionhagvoqvbkn7birnp2a5r5k5lq5lrib6a | 1 + ...ci_sessionherj0bjkmnqfdqfsuu3dnbggsvtfbj02 | 1 + ...ci_sessionhk5hav81u2at4ed6qc4uqgq2ufakchi3 | 1 + ...ci_sessionhnp4o1b64ec29lb633vqj949iaaqessc | 1 + ...ci_sessionhqn74a26erh9pk2985o73eo5aiuo1tds | 1 + ...ci_sessioni8tr3ova6dh5fffskcdfcrl29hj7488e | 1 + ...ci_sessionihb4ovjcg1402q6pj283a29bh3eho00f | 1 + ...ci_sessionilhngvti8cmvmivsr16qi2r28jsbu7fn | 1 + ...ci_sessioniptcn09bbvu5sc9l5p2583gvuva55f2q | 1 + ...ci_sessionj0ofb8ei3coae747ramem6jqnfet2s5r | 1 + ...ci_sessionjbcflluvuc2eeeqtompantlqfsahgvn8 | 1 + ...ci_sessionjdgos1svru55aidarnhusubqv2q800ii | 1 + ...ci_sessionjj0vrojn98e7rb3dhe9ro94abmr95t5i | 1 + ...ci_sessionjlj0flbime4tff9bl5toqslvupv21194 | 1 + ...ci_sessionjph4lhe1amhgg0rpokrjqdkdateqag7q | 1 + ...ci_sessionjqclq4v358j5u6c9i79aoqhluo62b8hv | 1 + ...ci_sessionjqhpc7r9og0lr9ndcr928r4um7jat5ah | 1 + ...ci_sessionjt1vkd49gsa09h70kpfj1uaq1eg59r3n | 1 + ...ci_sessionkh5qtemgj39vcijnlafrol4hu5gg5tfe | 1 + ...ci_sessionkmajs8u618ts2ja1503detbhej5o9o9l | 1 + ...ci_sessionl6ogogjpjkeb2ta837mk7v63s4eb5fm1 | 1 + ...ci_sessionl6ot90pv54k9o8tm1u110p19a36brsh4 | 1 + ...ci_sessionl8tb6elilbleea8cin7d9t3g2lehmvbh | 1 + ...ci_sessionlafvdf15ppsmcmkj8ogacte4sv5nmfp5 | 1 + ...ci_sessionlcjqhcmegscuv5lkqoc2v1arb3q3jfq8 | 1 + ...ci_sessionlfht6ij0159too3gpmejlidk6gdolpd9 | 1 + ...ci_sessionlilrg2emsk0tf93lr0mv0i824pd943q6 | 1 + ...ci_sessionlrkecrd2f1ag7uqcss1jnfjor4i9nd5p | 1 + ...ci_sessionm4fp70du8ushpsbo5a14sgpa588rkids | 1 + ...ci_sessionmbk2vnif1p2ee3ohr2bue9guk37u1lsg | 1 + ...ci_sessionmibptl61qvu5l5ucii7pkmmfqtgtg73t | 1 + ...ci_sessionmid2uj8al8pn1jsdstss7s5ste502473 | 1 + ...ci_sessionmmiolheoljm9p9lakhbi326ifncirbhc | 1 + ...ci_sessionmv1bci4vbvoer8114sf6bsmi61lsq78h | 1 + ...ci_sessionn0m9ne59fip3gvpi2grap9auda82ua9o | 1 + ...ci_sessionn38r4uqhg4iepulmv76k12vit28ln4lf | 1 + ...ci_sessionn871kd0re4ff3jjggvobec1alkj1713b | 1 + ...ci_sessionn9n1c4impv2lgvue3e79acg6gtlq7luu | 1 + ...ci_sessionnag9ud6fa39nfo40tjtbh6po89u93jg0 | 1 + ...ci_sessionnasa1l0mce9shkgfvguomr5poggnta0p | 1 + ...ci_sessionnihherorn13m5ttapfe8msof4j18a83p | 1 + ...ci_sessionnqucuns6buv1kdh9s8m6kgjerc3mj7nm | 1 + ...ci_sessionobl47kj8e3mi47jni435u6arfk9tc0oe | 1 + ...ci_sessionon9b2ht88n71uctpd9a82idvaku0l4q9 | 1 + ...ci_sessionpcnvii6gumnjnqhcgorc0gqt40khb0o5 | 1 + ...ci_sessionpu6e4pths82g3ptm3ops2he55hqq45jb | 1 + ...ci_sessionq0pa7oih560jfe5020kb3dpai3g1fuuv | 1 + ...ci_sessionq3p5rh7iqbtmr5ijfv3oma3e6td5h1iu | 1 + ...ci_sessionq9jbtl49k2pvmlqkem60jd9dr70g0khs | 1 + ...ci_sessionqekqmlh0eneq4i50b99ddknaa7jbmuig | 1 + ...ci_sessionqh4qaj0hnqg4f4crgld7et2laikni6ns | 1 + ...ci_sessionqk64fb3qqudoi04a8eisap4f0kv96he9 | 1 + ...ci_sessionr89ujj0afqdf8s4jbvpceovfg46p9jgd | 1 + ...ci_sessionrf9a7boc7v1ghvjlq239tj32nl8jnns6 | 1 + ...ci_sessionrj27r0p3061o8lce1bfk96ek528cup5q | 1 + ...ci_sessionrq949401hp65sn95i2ieuacjpm9u47pp | 1 + ...ci_sessionrqfhca1pm9opjfite1si80a86l8b8rd5 | 1 + ...ci_sessionrs9dcrcn05uk1afcjmf9jtvk2jgh1put | 1 + ...ci_sessionsndiuqnp8gou46ukt2dldbqjnsqcelf9 | 1 + ...ci_sessionsp82k4uau9jpgk06nteilq3f3gsa2f9e | 1 + ...ci_sessionss45iaqbl9d07520eujiv2isaderdqe8 | 1 + ...ci_sessionsvur5jhtm381lai4coas5i9rl09vdf11 | 1 + ...ci_sessiont124voped9modag151tqhgjpgdbdtr77 | 1 + ...ci_sessiont1bf5fsrlptko7t0d3o60n6glrq4hh70 | 1 + ...ci_sessionthts800uk692vgkmk57o212i8nqjliak | 1 + ...ci_sessiontjr2bh6d8bo45hftmgujb18gem4i5nf0 | 1 + ...ci_sessiontksn9kluikr3ch2hohsue54t142ttp67 | 1 + ...ci_sessiontlpandoce86cspvu5cu55e0qv21r7e58 | 1 + ...ci_sessiontv0r3og19vithol967vtfrcevvh41994 | 1 + ...ci_sessiontvq641raih981pd5efhf9uns6edff4of | 1 + ...ci_sessionu10nlpvvd6dlv8j1tds0u6ochjb9jbem | 1 + ...ci_sessionu2s9vv590311n0eicllh9pi2e6ia824q | 1 + ...ci_sessionu45bt690jg562rga9rq5il68ml7ajus3 | 1 + ...ci_sessionu7l363efl412ngdranlg05sm28hjje15 | 1 + ...ci_sessionuk6gp7k9jic18ip5rjvta2425imm87rm | 1 + ...ci_sessionumiak3lkmjun7273jvcckgn4jv8onb9g | 1 + ...ci_sessionupnradcpfqmgpsauc8p388qvqibpbeve | 1 + ...ci_sessionurs00qtmmq5egndc5dqo2pa5q7ig9r9s | 1 + ...ci_sessionusf50ol7vsbqc0tebsa2thfgufoqci2l | 1 + ...ci_sessionut0evbo4kto9396gh29e6t4e09beandt | 1 + ...ci_sessionv2kidk27grj07lg75o1a25vlenpe11n0 | 1 + ...ci_sessionvc06rh4ko4jue36ml4fqhqncf400b17d | 1 + writable/session/index.html | 11 + writable/uploads/index.html | 11 + 2529 files changed, 394562 insertions(+) create mode 100644 .env create mode 100644 .github/workflows/phpunit.yml create mode 100644 .htaccess create mode 100644 README.md create mode 100644 app/.htaccess create mode 100644 app/Common.php create mode 100644 app/Config/App.php create mode 100644 app/Config/Autoload.php create mode 100644 app/Config/Boot/development.php create mode 100644 app/Config/Boot/production.php create mode 100644 app/Config/Boot/testing.php create mode 100644 app/Config/Cache.php create mode 100644 app/Config/Constants.php create mode 100644 app/Config/ContentSecurityPolicy.php create mode 100644 app/Config/Database.php create mode 100644 app/Config/DocTypes.php create mode 100644 app/Config/Email.php create mode 100644 app/Config/Encryption.php create mode 100644 app/Config/Events.php create mode 100644 app/Config/Exceptions.php create mode 100644 app/Config/Filters.php create mode 100644 app/Config/ForeignCharacters.php create mode 100644 app/Config/Format.php create mode 100644 app/Config/Honeypot.php create mode 100644 app/Config/Images.php create mode 100644 app/Config/Kint.php create mode 100644 app/Config/Logger.php create mode 100644 app/Config/Migrations.php create mode 100644 app/Config/Mimes.php create mode 100644 app/Config/Modules.php create mode 100644 app/Config/Pager.php create mode 100644 app/Config/Paths.php create mode 100644 app/Config/Routes.php create mode 100644 app/Config/Services.php create mode 100644 app/Config/Toolbar.php create mode 100644 app/Config/UserAgents.php create mode 100644 app/Config/Validation.php create mode 100644 app/Config/View.php create mode 100644 app/Controllers/BaseController.php create mode 100644 app/Controllers/Dashboard.php create mode 100644 app/Controllers/Donation.php create mode 100644 app/Controllers/Donor_controller.php create mode 100644 app/Controllers/Home.php create mode 100644 app/Controllers/My_controller.php create mode 100644 app/Controllers/UsersRules.php create mode 100644 app/Controllers/admin/Donation.php create mode 100644 app/Database/Migrations/.gitkeep create mode 100644 app/Database/Seeds/.gitkeep create mode 100644 app/Filters/.gitkeep create mode 100644 app/Helpers/.gitkeep create mode 100644 app/Language/.gitkeep create mode 100644 app/Language/en/Validation.php create mode 100644 app/Libraries/.gitkeep create mode 100644 app/Models/.gitkeep create mode 100644 app/Models/Dashboard_model.php create mode 100644 app/Models/Donation_cause.php create mode 100644 app/Models/Donation_data_model.php create mode 100644 app/Models/Donation_model.php create mode 100644 app/Models/Donor_model.php create mode 100644 app/Models/My_model.php create mode 100644 app/Models/Receipt_model.php create mode 100644 app/Models/Transaction_model.php create mode 100644 app/ThirdParty/.gitkeep create mode 100644 app/Validation/UsersRules.php create mode 100644 app/Views/add_donation_cause.php create mode 100644 app/Views/dashboard.php create mode 100644 app/Views/donation_data.php create mode 100644 app/Views/donation_data_edit.php create mode 100644 app/Views/donation_data_table.php create mode 100644 app/Views/donor_edit.php create mode 100644 app/Views/donor_registration.php create mode 100644 app/Views/donor_table.php create mode 100644 app/Views/edit_view.php create mode 100644 app/Views/errors/cli/error_404.php create mode 100644 app/Views/errors/cli/error_exception.php create mode 100644 app/Views/errors/cli/production.php create mode 100644 app/Views/errors/html/debug.css create mode 100644 app/Views/errors/html/debug.js create mode 100644 app/Views/errors/html/error_404.php create mode 100644 app/Views/errors/html/error_exception.php create mode 100644 app/Views/errors/html/production.php create mode 100644 app/Views/list.php create mode 100644 app/Views/login.php create mode 100644 app/Views/profile_view.php create mode 100644 app/Views/receipt_edit.php create mode 100644 app/Views/receipts.php create mode 100644 app/Views/receipts_table.php create mode 100644 app/Views/register.php create mode 100644 app/Views/show.php create mode 100644 app/Views/templates/footer.php create mode 100644 app/Views/templates/header.php create mode 100644 app/Views/transaction_edit.php create mode 100644 app/Views/transaction_table.php create mode 100644 app/Views/transaction_upload.php create mode 100644 app/Views/welcome_message.php create mode 100644 app/index.html create mode 100644 builds create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 env create mode 100644 index.php create mode 100644 license.txt create mode 100644 phpunit.xml.dist create mode 100644 public/.htaccess create mode 100644 public/assets/css/style.css create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 public/robots.txt create mode 100644 spark create mode 100644 tests/README.md create mode 100644 tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php create mode 100644 tests/_support/Database/Seeds/ExampleSeeder.php create mode 100644 tests/_support/DatabaseTestCase.php create mode 100644 tests/_support/Libraries/ConfigReader.php create mode 100644 tests/_support/Models/ExampleModel.php create mode 100644 tests/_support/SessionTestCase.php create mode 100644 tests/database/ExampleDatabaseTest.php create mode 100644 tests/session/ExampleSessionTest.php create mode 100644 tests/unit/HealthTest.php create mode 100644 vendor/autoload.php create mode 100644 vendor/bin/phpunit create mode 100644 vendor/bin/phpunit.bat create mode 100644 vendor/codeigniter4/framework/.gitignore create mode 100644 vendor/codeigniter4/framework/README.md create mode 100644 vendor/codeigniter4/framework/app/.htaccess create mode 100644 vendor/codeigniter4/framework/app/Common.php create mode 100644 vendor/codeigniter4/framework/app/Config/App.php create mode 100644 vendor/codeigniter4/framework/app/Config/Autoload.php create mode 100644 vendor/codeigniter4/framework/app/Config/Boot/development.php create mode 100644 vendor/codeigniter4/framework/app/Config/Boot/production.php create mode 100644 vendor/codeigniter4/framework/app/Config/Boot/testing.php create mode 100644 vendor/codeigniter4/framework/app/Config/Cache.php create mode 100644 vendor/codeigniter4/framework/app/Config/Constants.php create mode 100644 vendor/codeigniter4/framework/app/Config/ContentSecurityPolicy.php create mode 100644 vendor/codeigniter4/framework/app/Config/Database.php create mode 100644 vendor/codeigniter4/framework/app/Config/DocTypes.php create mode 100644 vendor/codeigniter4/framework/app/Config/Email.php create mode 100644 vendor/codeigniter4/framework/app/Config/Encryption.php create mode 100644 vendor/codeigniter4/framework/app/Config/Events.php create mode 100644 vendor/codeigniter4/framework/app/Config/Exceptions.php create mode 100644 vendor/codeigniter4/framework/app/Config/Filters.php create mode 100644 vendor/codeigniter4/framework/app/Config/ForeignCharacters.php create mode 100644 vendor/codeigniter4/framework/app/Config/Format.php create mode 100644 vendor/codeigniter4/framework/app/Config/Honeypot.php create mode 100644 vendor/codeigniter4/framework/app/Config/Images.php create mode 100644 vendor/codeigniter4/framework/app/Config/Kint.php create mode 100644 vendor/codeigniter4/framework/app/Config/Logger.php create mode 100644 vendor/codeigniter4/framework/app/Config/Migrations.php create mode 100644 vendor/codeigniter4/framework/app/Config/Mimes.php create mode 100644 vendor/codeigniter4/framework/app/Config/Modules.php create mode 100644 vendor/codeigniter4/framework/app/Config/Pager.php create mode 100644 vendor/codeigniter4/framework/app/Config/Paths.php create mode 100644 vendor/codeigniter4/framework/app/Config/Routes.php create mode 100644 vendor/codeigniter4/framework/app/Config/Services.php create mode 100644 vendor/codeigniter4/framework/app/Config/Toolbar.php create mode 100644 vendor/codeigniter4/framework/app/Config/UserAgents.php create mode 100644 vendor/codeigniter4/framework/app/Config/Validation.php create mode 100644 vendor/codeigniter4/framework/app/Config/View.php create mode 100644 vendor/codeigniter4/framework/app/Controllers/BaseController.php create mode 100644 vendor/codeigniter4/framework/app/Controllers/Home.php create mode 100644 vendor/codeigniter4/framework/app/Database/Migrations/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Database/Seeds/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Filters/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Helpers/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Language/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Language/en/Validation.php create mode 100644 vendor/codeigniter4/framework/app/Libraries/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Models/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/ThirdParty/.gitkeep create mode 100644 vendor/codeigniter4/framework/app/Views/errors/cli/error_404.php create mode 100644 vendor/codeigniter4/framework/app/Views/errors/cli/error_exception.php create mode 100644 vendor/codeigniter4/framework/app/Views/errors/cli/production.php create mode 100644 vendor/codeigniter4/framework/app/Views/errors/html/debug.css create mode 100644 vendor/codeigniter4/framework/app/Views/errors/html/debug.js create mode 100644 vendor/codeigniter4/framework/app/Views/errors/html/error_404.php create mode 100644 vendor/codeigniter4/framework/app/Views/errors/html/error_exception.php create mode 100644 vendor/codeigniter4/framework/app/Views/errors/html/production.php create mode 100644 vendor/codeigniter4/framework/app/Views/welcome_message.php create mode 100644 vendor/codeigniter4/framework/app/index.html create mode 100644 vendor/codeigniter4/framework/composer.json create mode 100644 vendor/codeigniter4/framework/env create mode 100644 vendor/codeigniter4/framework/license.txt create mode 100644 vendor/codeigniter4/framework/phpunit.xml.dist create mode 100644 vendor/codeigniter4/framework/public/.htaccess create mode 100644 vendor/codeigniter4/framework/public/favicon.ico create mode 100644 vendor/codeigniter4/framework/public/index.php create mode 100644 vendor/codeigniter4/framework/public/robots.txt create mode 100644 vendor/codeigniter4/framework/spark create mode 100644 vendor/codeigniter4/framework/system/.htaccess create mode 100644 vendor/codeigniter4/framework/system/API/ResponseTrait.php create mode 100644 vendor/codeigniter4/framework/system/Autoloader/Autoloader.php create mode 100644 vendor/codeigniter4/framework/system/Autoloader/FileLocator.php create mode 100644 vendor/codeigniter4/framework/system/CLI/BaseCommand.php create mode 100644 vendor/codeigniter4/framework/system/CLI/CLI.php create mode 100644 vendor/codeigniter4/framework/system/CLI/CommandRunner.php create mode 100644 vendor/codeigniter4/framework/system/CLI/Commands.php create mode 100644 vendor/codeigniter4/framework/system/CLI/Console.php create mode 100644 vendor/codeigniter4/framework/system/CLI/Exceptions/CLIException.php create mode 100644 vendor/codeigniter4/framework/system/Cache/CacheFactory.php create mode 100644 vendor/codeigniter4/framework/system/Cache/CacheInterface.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Exceptions/CacheException.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Exceptions/ExceptionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/DummyHandler.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/FileHandler.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/MemcachedHandler.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/PredisHandler.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/RedisHandler.php create mode 100644 vendor/codeigniter4/framework/system/Cache/Handlers/WincacheHandler.php create mode 100644 vendor/codeigniter4/framework/system/CodeIgniter.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Cache/ClearCache.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/CreateMigration.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/CreateSeeder.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/Migrate.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/MigrateRefresh.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/MigrateRollback.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/MigrateStatus.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Database/Seed.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Help.php create mode 100644 vendor/codeigniter4/framework/system/Commands/ListCommands.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Server/Serve.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Server/rewrite.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Sessions/CreateMigration.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Sessions/Views/migration.tpl.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Utilities/Namespaces.php create mode 100644 vendor/codeigniter4/framework/system/Commands/Utilities/Routes.php create mode 100644 vendor/codeigniter4/framework/system/Common.php create mode 100644 vendor/codeigniter4/framework/system/ComposerScripts.php create mode 100644 vendor/codeigniter4/framework/system/Config/AutoloadConfig.php create mode 100644 vendor/codeigniter4/framework/system/Config/BaseConfig.php create mode 100644 vendor/codeigniter4/framework/system/Config/BaseService.php create mode 100644 vendor/codeigniter4/framework/system/Config/Config.php create mode 100644 vendor/codeigniter4/framework/system/Config/DotEnv.php create mode 100644 vendor/codeigniter4/framework/system/Config/ForeignCharacters.php create mode 100644 vendor/codeigniter4/framework/system/Config/Routes.php create mode 100644 vendor/codeigniter4/framework/system/Config/Services.php create mode 100644 vendor/codeigniter4/framework/system/Config/View.php create mode 100644 vendor/codeigniter4/framework/system/Controller.php create mode 100644 vendor/codeigniter4/framework/system/Database/BaseBuilder.php create mode 100644 vendor/codeigniter4/framework/system/Database/BaseConnection.php create mode 100644 vendor/codeigniter4/framework/system/Database/BasePreparedQuery.php create mode 100644 vendor/codeigniter4/framework/system/Database/BaseResult.php create mode 100644 vendor/codeigniter4/framework/system/Database/BaseUtils.php create mode 100644 vendor/codeigniter4/framework/system/Database/Config.php create mode 100644 vendor/codeigniter4/framework/system/Database/ConnectionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Database/Database.php create mode 100644 vendor/codeigniter4/framework/system/Database/Exceptions/DataException.php create mode 100644 vendor/codeigniter4/framework/system/Database/Exceptions/DatabaseException.php create mode 100644 vendor/codeigniter4/framework/system/Database/Exceptions/ExceptionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Database/Forge.php create mode 100644 vendor/codeigniter4/framework/system/Database/Migration.php create mode 100644 vendor/codeigniter4/framework/system/Database/MigrationRunner.php create mode 100644 vendor/codeigniter4/framework/system/Database/ModelFactory.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/Builder.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/Forge.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/PreparedQuery.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/Result.php create mode 100644 vendor/codeigniter4/framework/system/Database/MySQLi/Utils.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/Builder.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/Connection.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/Forge.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/PreparedQuery.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/Result.php create mode 100644 vendor/codeigniter4/framework/system/Database/Postgre/Utils.php create mode 100644 vendor/codeigniter4/framework/system/Database/PreparedQueryInterface.php create mode 100644 vendor/codeigniter4/framework/system/Database/Query.php create mode 100644 vendor/codeigniter4/framework/system/Database/QueryInterface.php create mode 100644 vendor/codeigniter4/framework/system/Database/ResultInterface.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Builder.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Connection.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Forge.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/PreparedQuery.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Result.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Table.php create mode 100644 vendor/codeigniter4/framework/system/Database/SQLite3/Utils.php create mode 100644 vendor/codeigniter4/framework/system/Database/Seeder.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Exceptions.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Iterator.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Timer.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/BaseCollector.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Config.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Database.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Events.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Files.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/History.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Logs.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Routes.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Timers.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Views.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_config.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_database.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_events.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_files.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_history.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_logs.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_routes.tpl create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.css create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.js create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.tpl.php create mode 100644 vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbarloader.js.php create mode 100644 vendor/codeigniter4/framework/system/Email/Email.php create mode 100644 vendor/codeigniter4/framework/system/Encryption/EncrypterInterface.php create mode 100644 vendor/codeigniter4/framework/system/Encryption/Encryption.php create mode 100644 vendor/codeigniter4/framework/system/Encryption/Exceptions/EncryptionException.php create mode 100644 vendor/codeigniter4/framework/system/Encryption/Handlers/BaseHandler.php create mode 100644 vendor/codeigniter4/framework/system/Encryption/Handlers/OpenSSLHandler.php create mode 100644 vendor/codeigniter4/framework/system/Entity.php create mode 100644 vendor/codeigniter4/framework/system/Events/Events.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/AlertError.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/CastException.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/ConfigException.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/CriticalError.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/DownloadException.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/EmergencyError.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/ExceptionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/FrameworkException.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/ModelException.php create mode 100644 vendor/codeigniter4/framework/system/Exceptions/PageNotFoundException.php create mode 100644 vendor/codeigniter4/framework/system/Files/Exceptions/FileException.php create mode 100644 vendor/codeigniter4/framework/system/Files/Exceptions/FileNotFoundException.php create mode 100644 vendor/codeigniter4/framework/system/Files/File.php create mode 100644 vendor/codeigniter4/framework/system/Filters/CSRF.php create mode 100644 vendor/codeigniter4/framework/system/Filters/DebugToolbar.php create mode 100644 vendor/codeigniter4/framework/system/Filters/Exceptions/FilterException.php create mode 100644 vendor/codeigniter4/framework/system/Filters/FilterInterface.php create mode 100644 vendor/codeigniter4/framework/system/Filters/Filters.php create mode 100644 vendor/codeigniter4/framework/system/Filters/Honeypot.php create mode 100644 vendor/codeigniter4/framework/system/Format/Exceptions/FormatException.php create mode 100644 vendor/codeigniter4/framework/system/Format/FormatterInterface.php create mode 100644 vendor/codeigniter4/framework/system/Format/JSONFormatter.php create mode 100644 vendor/codeigniter4/framework/system/Format/XMLFormatter.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/CLIRequest.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/CURLRequest.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/ContentSecurityPolicy.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/DownloadResponse.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Exceptions/HTTPException.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Files/FileCollection.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Files/UploadedFile.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Files/UploadedFileInterface.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Header.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/IncomingRequest.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Message.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Negotiate.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/RedirectResponse.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Request.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/RequestInterface.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/Response.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/ResponseInterface.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/URI.php create mode 100644 vendor/codeigniter4/framework/system/HTTP/UserAgent.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/array_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/cookie_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/date_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/filesystem_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/form_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/html_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/inflector_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/number_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/security_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/test_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/text_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/url_helper.php create mode 100644 vendor/codeigniter4/framework/system/Helpers/xml_helper.php create mode 100644 vendor/codeigniter4/framework/system/Honeypot/Exceptions/HoneypotException.php create mode 100644 vendor/codeigniter4/framework/system/Honeypot/Honeypot.php create mode 100644 vendor/codeigniter4/framework/system/I18n/Exceptions/I18nException.php create mode 100644 vendor/codeigniter4/framework/system/I18n/Time.php create mode 100644 vendor/codeigniter4/framework/system/I18n/TimeDifference.php create mode 100644 vendor/codeigniter4/framework/system/Images/Exceptions/ImageException.php create mode 100644 vendor/codeigniter4/framework/system/Images/Handlers/BaseHandler.php create mode 100644 vendor/codeigniter4/framework/system/Images/Handlers/GDHandler.php create mode 100644 vendor/codeigniter4/framework/system/Images/Handlers/ImageMagickHandler.php create mode 100644 vendor/codeigniter4/framework/system/Images/Image.php create mode 100644 vendor/codeigniter4/framework/system/Images/ImageHandlerInterface.php create mode 100644 vendor/codeigniter4/framework/system/Language/Language.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/CLI.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Cache.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Cast.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Core.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Database.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Email.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Encryption.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Entity.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Fabricator.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Files.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Filters.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Format.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/HTTP.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Images.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Language.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Log.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Migrations.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Number.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Pager.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/RESTful.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Redirect.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Router.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Seed.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Session.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Time.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/Validation.php create mode 100644 vendor/codeigniter4/framework/system/Language/en/View.php create mode 100644 vendor/codeigniter4/framework/system/Log/Exceptions/LogException.php create mode 100644 vendor/codeigniter4/framework/system/Log/Handlers/BaseHandler.php create mode 100644 vendor/codeigniter4/framework/system/Log/Handlers/ChromeLoggerHandler.php create mode 100644 vendor/codeigniter4/framework/system/Log/Handlers/FileHandler.php create mode 100644 vendor/codeigniter4/framework/system/Log/Handlers/HandlerInterface.php create mode 100644 vendor/codeigniter4/framework/system/Log/Logger.php create mode 100644 vendor/codeigniter4/framework/system/Model.php create mode 100644 vendor/codeigniter4/framework/system/Modules/Modules.php create mode 100644 vendor/codeigniter4/framework/system/Pager/Exceptions/PagerException.php create mode 100644 vendor/codeigniter4/framework/system/Pager/Pager.php create mode 100644 vendor/codeigniter4/framework/system/Pager/PagerInterface.php create mode 100644 vendor/codeigniter4/framework/system/Pager/PagerRenderer.php create mode 100644 vendor/codeigniter4/framework/system/Pager/Views/default_full.php create mode 100644 vendor/codeigniter4/framework/system/Pager/Views/default_head.php create mode 100644 vendor/codeigniter4/framework/system/Pager/Views/default_simple.php create mode 100644 vendor/codeigniter4/framework/system/RESTful/ResourceController.php create mode 100644 vendor/codeigniter4/framework/system/RESTful/ResourcePresenter.php create mode 100644 vendor/codeigniter4/framework/system/Router/Exceptions/RedirectException.php create mode 100644 vendor/codeigniter4/framework/system/Router/Exceptions/RouterException.php create mode 100644 vendor/codeigniter4/framework/system/Router/RouteCollection.php create mode 100644 vendor/codeigniter4/framework/system/Router/RouteCollectionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Router/Router.php create mode 100644 vendor/codeigniter4/framework/system/Router/RouterInterface.php create mode 100644 vendor/codeigniter4/framework/system/Security/Exceptions/SecurityException.php create mode 100644 vendor/codeigniter4/framework/system/Security/Security.php create mode 100644 vendor/codeigniter4/framework/system/Session/Exceptions/SessionException.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/ArrayHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/BaseHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/DatabaseHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/FileHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/MemcachedHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Handlers/RedisHandler.php create mode 100644 vendor/codeigniter4/framework/system/Session/Session.php create mode 100644 vendor/codeigniter4/framework/system/Session/SessionInterface.php create mode 100644 vendor/codeigniter4/framework/system/Test/CIDatabaseTestCase.php create mode 100644 vendor/codeigniter4/framework/system/Test/CIUnitTestCase.php create mode 100644 vendor/codeigniter4/framework/system/Test/ControllerResponse.php create mode 100644 vendor/codeigniter4/framework/system/Test/ControllerTester.php create mode 100644 vendor/codeigniter4/framework/system/Test/DOMParser.php create mode 100644 vendor/codeigniter4/framework/system/Test/Fabricator.php create mode 100644 vendor/codeigniter4/framework/system/Test/FeatureResponse.php create mode 100644 vendor/codeigniter4/framework/system/Test/FeatureTestCase.php create mode 100644 vendor/codeigniter4/framework/system/Test/FeatureTestTrait.php create mode 100644 vendor/codeigniter4/framework/system/Test/Filters/CITestStreamFilter.php create mode 100644 vendor/codeigniter4/framework/system/Test/Interfaces/FabricatorModel.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockAppConfig.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockAutoload.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockBuilder.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockCLIConfig.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockCURLRequest.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockCache.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockCodeIgniter.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockCommon.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockConnection.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockEmail.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockEvents.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockFileLogger.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockIncomingRequest.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockLanguage.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockLogger.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockQuery.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockResourceController.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockResourcePresenter.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockResponse.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockResult.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockSecurity.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockServices.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockSession.php create mode 100644 vendor/codeigniter4/framework/system/Test/Mock/MockTable.php create mode 100644 vendor/codeigniter4/framework/system/Test/ReflectionHelper.php create mode 100644 vendor/codeigniter4/framework/system/Test/TestLogger.php create mode 100644 vendor/codeigniter4/framework/system/Test/bootstrap.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Escaper/Escaper.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/ExceptionInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/InvalidArgumentException.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/RuntimeException.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/CallFinder.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Kint.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BasicObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BlobObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ClosureObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/DateTimeObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/InstanceObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/MethodObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ParameterObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/ColorRepresentation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/DocstringRepresentation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/MicrotimeRepresentation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/Representation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SourceRepresentation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SplFileInfoRepresentation.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ResourceObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/StreamObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ThrowableObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceFrameObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceObject.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Base64Plugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BinaryPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BlacklistPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClosurePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ColorPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DOMDocumentPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DateTimePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/FsPathPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/IteratorPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/JsonPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MicrotimePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MysqliPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Parser.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Plugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ProxyPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SerializePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplObjectStoragePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/StreamPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TablePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ThrowablePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TimestampPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ToStringPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TracePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/XmlPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/CliRenderer.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/PlainRenderer.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Renderer.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ObjectPluginInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/Plugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/RecursionPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TablePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/RichRenderer.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/Plugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/TextRenderer.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/Utils.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/init.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/init_helpers.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/aante-light.css create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/microtime.js create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/original.css create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.css create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.js create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/rich.js create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/shared.js create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/solarized-dark.css create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/solarized.css create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/AbstractLogger.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/InvalidArgumentException.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LogLevel.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerAwareInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerAwareTrait.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerInterface.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerTrait.php create mode 100644 vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/NullLogger.php create mode 100644 vendor/codeigniter4/framework/system/Throttle/Throttler.php create mode 100644 vendor/codeigniter4/framework/system/Throttle/ThrottlerInterface.php create mode 100644 vendor/codeigniter4/framework/system/Typography/Typography.php create mode 100644 vendor/codeigniter4/framework/system/Validation/CreditCardRules.php create mode 100644 vendor/codeigniter4/framework/system/Validation/Exceptions/ValidationException.php create mode 100644 vendor/codeigniter4/framework/system/Validation/FileRules.php create mode 100644 vendor/codeigniter4/framework/system/Validation/FormatRules.php create mode 100644 vendor/codeigniter4/framework/system/Validation/Rules.php create mode 100644 vendor/codeigniter4/framework/system/Validation/Validation.php create mode 100644 vendor/codeigniter4/framework/system/Validation/ValidationInterface.php create mode 100644 vendor/codeigniter4/framework/system/Validation/Views/list.php create mode 100644 vendor/codeigniter4/framework/system/Validation/Views/single.php create mode 100644 vendor/codeigniter4/framework/system/View/Cell.php create mode 100644 vendor/codeigniter4/framework/system/View/Exceptions/ViewException.php create mode 100644 vendor/codeigniter4/framework/system/View/Filters.php create mode 100644 vendor/codeigniter4/framework/system/View/Parser.php create mode 100644 vendor/codeigniter4/framework/system/View/Plugins.php create mode 100644 vendor/codeigniter4/framework/system/View/RendererInterface.php create mode 100644 vendor/codeigniter4/framework/system/View/Table.php create mode 100644 vendor/codeigniter4/framework/system/View/View.php create mode 100644 vendor/codeigniter4/framework/system/bootstrap.php create mode 100644 vendor/codeigniter4/framework/system/index.html create mode 100644 vendor/codeigniter4/framework/writable/.htaccess create mode 100644 vendor/codeigniter4/framework/writable/cache/index.html create mode 100644 vendor/codeigniter4/framework/writable/logs/index.html create mode 100644 vendor/codeigniter4/framework/writable/session/index.html create mode 100644 vendor/codeigniter4/framework/writable/uploads/index.html create mode 100644 vendor/composer/ClassLoader.php create mode 100644 vendor/composer/LICENSE create mode 100644 vendor/composer/autoload_classmap.php create mode 100644 vendor/composer/autoload_files.php create mode 100644 vendor/composer/autoload_namespaces.php create mode 100644 vendor/composer/autoload_psr4.php create mode 100644 vendor/composer/autoload_real.php create mode 100644 vendor/composer/autoload_static.php create mode 100644 vendor/composer/installed.json create mode 100644 vendor/doctrine/instantiator/.doctrine-project.json create mode 100644 vendor/doctrine/instantiator/.github/FUNDING.yml create mode 100644 vendor/doctrine/instantiator/CONTRIBUTING.md create mode 100644 vendor/doctrine/instantiator/LICENSE create mode 100644 vendor/doctrine/instantiator/README.md create mode 100644 vendor/doctrine/instantiator/composer.json create mode 100644 vendor/doctrine/instantiator/docs/en/index.rst create mode 100644 vendor/doctrine/instantiator/docs/en/sidebar.rst create mode 100644 vendor/doctrine/instantiator/phpbench.json create mode 100644 vendor/doctrine/instantiator/phpcs.xml.dist create mode 100644 vendor/doctrine/instantiator/phpstan.neon.dist create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/InvalidArgumentException.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php create mode 100644 vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php create mode 100644 vendor/dompdf/dompdf/CONTRIBUTING.md create mode 100644 vendor/dompdf/dompdf/LICENSE.LGPL create mode 100644 vendor/dompdf/dompdf/README.md create mode 100644 vendor/dompdf/dompdf/VERSION create mode 100644 vendor/dompdf/dompdf/composer.json create mode 100644 vendor/dompdf/dompdf/lib/Cpdf.php create mode 100644 vendor/dompdf/dompdf/lib/fonts/Courier-Bold.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Courier-BoldOblique.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Courier-Oblique.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Courier.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Oblique.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Oblique.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSans.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Bold.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Bold.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Italic.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Italic.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif.ttf create mode 100644 vendor/dompdf/dompdf/lib/fonts/DejaVuSerif.ufm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Helvetica-Bold.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Helvetica-BoldOblique.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Helvetica-Oblique.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Helvetica.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Symbol.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Times-Bold.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Times-BoldItalic.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Times-Italic.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/Times-Roman.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/ZapfDingbats.afm create mode 100644 vendor/dompdf/dompdf/lib/fonts/dompdf_font_family_cache.dist.php create mode 100644 vendor/dompdf/dompdf/lib/fonts/mustRead.html create mode 100644 vendor/dompdf/dompdf/lib/html5lib/Data.php create mode 100644 vendor/dompdf/dompdf/lib/html5lib/InputStream.php create mode 100644 vendor/dompdf/dompdf/lib/html5lib/Parser.php create mode 100644 vendor/dompdf/dompdf/lib/html5lib/Tokenizer.php create mode 100644 vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php create mode 100644 vendor/dompdf/dompdf/lib/html5lib/named-character-references.ser create mode 100644 vendor/dompdf/dompdf/lib/res/broken_image.png create mode 100644 vendor/dompdf/dompdf/lib/res/broken_image.svg create mode 100644 vendor/dompdf/dompdf/lib/res/html.css create mode 100644 vendor/dompdf/dompdf/phpcs.xml create mode 100644 vendor/dompdf/dompdf/src/Adapter/CPDF.php create mode 100644 vendor/dompdf/dompdf/src/Adapter/GD.php create mode 100644 vendor/dompdf/dompdf/src/Adapter/PDFLib.php create mode 100644 vendor/dompdf/dompdf/src/Autoloader.php create mode 100644 vendor/dompdf/dompdf/src/Canvas.php create mode 100644 vendor/dompdf/dompdf/src/CanvasFactory.php create mode 100644 vendor/dompdf/dompdf/src/Cellmap.php create mode 100644 vendor/dompdf/dompdf/src/Css/AttributeTranslator.php create mode 100644 vendor/dompdf/dompdf/src/Css/Color.php create mode 100644 vendor/dompdf/dompdf/src/Css/Style.php create mode 100644 vendor/dompdf/dompdf/src/Css/Stylesheet.php create mode 100644 vendor/dompdf/dompdf/src/Dompdf.php create mode 100644 vendor/dompdf/dompdf/src/Exception.php create mode 100644 vendor/dompdf/dompdf/src/Exception/ImageException.php create mode 100644 vendor/dompdf/dompdf/src/FontMetrics.php create mode 100644 vendor/dompdf/dompdf/src/Frame.php create mode 100644 vendor/dompdf/dompdf/src/Frame/Factory.php create mode 100644 vendor/dompdf/dompdf/src/Frame/FrameList.php create mode 100644 vendor/dompdf/dompdf/src/Frame/FrameListIterator.php create mode 100644 vendor/dompdf/dompdf/src/Frame/FrameTree.php create mode 100644 vendor/dompdf/dompdf/src/Frame/FrameTreeIterator.php create mode 100644 vendor/dompdf/dompdf/src/Frame/FrameTreeList.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Block.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Image.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Inline.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/ListBullet.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/ListBulletImage.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/NullFrameDecorator.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Page.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Table.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/TableCell.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/TableRow.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/TableRowGroup.php create mode 100644 vendor/dompdf/dompdf/src/FrameDecorator/Text.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/AbstractFrameReflower.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Block.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Image.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Inline.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/ListBullet.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/NullFrameReflower.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Page.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Table.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/TableCell.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/TableRow.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php create mode 100644 vendor/dompdf/dompdf/src/FrameReflower/Text.php create mode 100644 vendor/dompdf/dompdf/src/Helpers.php create mode 100644 vendor/dompdf/dompdf/src/Image/Cache.php create mode 100644 vendor/dompdf/dompdf/src/JavascriptEmbedder.php create mode 100644 vendor/dompdf/dompdf/src/LineBox.php create mode 100644 vendor/dompdf/dompdf/src/Options.php create mode 100644 vendor/dompdf/dompdf/src/PhpEvaluator.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/Absolute.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/AbstractPositioner.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/Block.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/Fixed.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/Inline.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/ListBullet.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/NullPositioner.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/TableCell.php create mode 100644 vendor/dompdf/dompdf/src/Positioner/TableRow.php create mode 100644 vendor/dompdf/dompdf/src/Renderer.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/Block.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/Image.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/Inline.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/ListBullet.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/TableCell.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/TableRowGroup.php create mode 100644 vendor/dompdf/dompdf/src/Renderer/Text.php create mode 160000 vendor/fzaninotto/faker create mode 100644 vendor/kint-php/kint/LICENSE create mode 100644 vendor/kint-php/kint/README.md create mode 100644 vendor/kint-php/kint/composer.json create mode 100644 vendor/kint-php/kint/init.php create mode 100644 vendor/kint-php/kint/init_helpers.php create mode 100644 vendor/kint-php/kint/resources/compiled/aante-light.css create mode 100644 vendor/kint-php/kint/resources/compiled/microtime.js create mode 100644 vendor/kint-php/kint/resources/compiled/original.css create mode 100644 vendor/kint-php/kint/resources/compiled/plain.css create mode 100644 vendor/kint-php/kint/resources/compiled/plain.js create mode 100644 vendor/kint-php/kint/resources/compiled/rich.js create mode 100644 vendor/kint-php/kint/resources/compiled/shared.js create mode 100644 vendor/kint-php/kint/resources/compiled/solarized-dark.css create mode 100644 vendor/kint-php/kint/resources/compiled/solarized.css create mode 100644 vendor/kint-php/kint/src/CallFinder.php create mode 100644 vendor/kint-php/kint/src/Kint.php create mode 100644 vendor/kint-php/kint/src/Object/BasicObject.php create mode 100644 vendor/kint-php/kint/src/Object/BlobObject.php create mode 100644 vendor/kint-php/kint/src/Object/ClosureObject.php create mode 100644 vendor/kint-php/kint/src/Object/DateTimeObject.php create mode 100644 vendor/kint-php/kint/src/Object/InstanceObject.php create mode 100644 vendor/kint-php/kint/src/Object/MethodObject.php create mode 100644 vendor/kint-php/kint/src/Object/ParameterObject.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/ColorRepresentation.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/DocstringRepresentation.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/MicrotimeRepresentation.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/Representation.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/SourceRepresentation.php create mode 100644 vendor/kint-php/kint/src/Object/Representation/SplFileInfoRepresentation.php create mode 100644 vendor/kint-php/kint/src/Object/ResourceObject.php create mode 100644 vendor/kint-php/kint/src/Object/StreamObject.php create mode 100644 vendor/kint-php/kint/src/Object/ThrowableObject.php create mode 100644 vendor/kint-php/kint/src/Object/TraceFrameObject.php create mode 100644 vendor/kint-php/kint/src/Object/TraceObject.php create mode 100644 vendor/kint-php/kint/src/Parser/ArrayObjectPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/Base64Plugin.php create mode 100644 vendor/kint-php/kint/src/Parser/BinaryPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/BlacklistPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ClassMethodsPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ClassStaticsPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ClosurePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ColorPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/DOMDocumentPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/DateTimePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/FsPathPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/IteratorPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/JsonPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/MicrotimePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/MysqliPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/Parser.php create mode 100644 vendor/kint-php/kint/src/Parser/Plugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ProxyPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/SerializePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/SimpleXMLElementPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/SplFileInfoPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/SplObjectStoragePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/StreamPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/TablePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ThrowablePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/TimestampPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/ToStringPlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/TracePlugin.php create mode 100644 vendor/kint-php/kint/src/Parser/XmlPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/CliRenderer.php create mode 100644 vendor/kint-php/kint/src/Renderer/PlainRenderer.php create mode 100644 vendor/kint-php/kint/src/Renderer/Renderer.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/BinaryPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/BlacklistPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/CallablePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/ClosurePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/ColorPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/DepthLimitPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/DocstringPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/MicrotimePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/ObjectPluginInterface.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/Plugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/PluginInterface.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/RecursionPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/SimpleXMLElementPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/SourcePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/TabPluginInterface.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/TablePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/TimestampPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Rich/TraceFramePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/RichRenderer.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/BlacklistPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/DepthLimitPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/MicrotimePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/Plugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/RecursionPlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/Text/TracePlugin.php create mode 100644 vendor/kint-php/kint/src/Renderer/TextRenderer.php create mode 100644 vendor/kint-php/kint/src/Utils.php create mode 100644 vendor/laminas/laminas-escaper/CHANGELOG.md create mode 100644 vendor/laminas/laminas-escaper/COPYRIGHT.md create mode 100644 vendor/laminas/laminas-escaper/LICENSE.md create mode 100644 vendor/laminas/laminas-escaper/README.md create mode 100644 vendor/laminas/laminas-escaper/composer.json create mode 100644 vendor/laminas/laminas-escaper/src/Escaper.php create mode 100644 vendor/laminas/laminas-escaper/src/Exception/ExceptionInterface.php create mode 100644 vendor/laminas/laminas-escaper/src/Exception/InvalidArgumentException.php create mode 100644 vendor/laminas/laminas-escaper/src/Exception/RuntimeException.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/.github/FUNDING.yml create mode 100644 vendor/laminas/laminas-zendframework-bridge/.github/workflows/release-on-milestone-closed.yml create mode 100644 vendor/laminas/laminas-zendframework-bridge/CHANGELOG.md create mode 100644 vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md create mode 100644 vendor/laminas/laminas-zendframework-bridge/LICENSE.md create mode 100644 vendor/laminas/laminas-zendframework-bridge/README.md create mode 100644 vendor/laminas/laminas-zendframework-bridge/composer.json create mode 100644 vendor/laminas/laminas-zendframework-bridge/config/replacements.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/Module.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/Replacements.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php create mode 100644 vendor/laminas/laminas-zendframework-bridge/src/autoload.php create mode 100644 vendor/mikey179/vfsstream/CHANGELOG.md create mode 100644 vendor/mikey179/vfsstream/LICENSE create mode 100644 vendor/mikey179/vfsstream/README.md create mode 100644 vendor/mikey179/vfsstream/appveyor.yml create mode 100644 vendor/mikey179/vfsstream/composer.json create mode 100644 vendor/mikey179/vfsstream/phpunit.xml.dist create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/DotDirectory.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/Quota.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/FileContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/LargeFileContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/SeekableFileContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/StringBasedFileContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamAbstractContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamBlock.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContainer.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContainerIterator.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContent.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamDirectory.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamException.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamFile.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamWrapper.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitor.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitor.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitor.php create mode 100644 vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamVisitor.php create mode 100644 vendor/mikey179/vfsstream/src/test/bootstrap.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/DirectoryIterationTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/FilenameTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/Issue104TestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/PermissionsTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/QuotaTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/UnlinkTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/LargeFileContentTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/StringBasedFileContentTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/proxy/vfsStreamWrapperRecordingProxy.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamAbstractContentTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamBlockTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamContainerIteratorTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue134TestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue18TestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamExLockTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamFileTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamGlobTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamResolveIncludePathTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamUmaskTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperAlreadyRegisteredTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperBaseTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirSeparatorTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTimesTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFlockTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperLargeFileTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperQuotaTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperSetOptionTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperStreamSelectTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperUnregisterTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperWithoutRootTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamZipTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitorTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitorTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitorTestCase.php create mode 100644 vendor/mikey179/vfsstream/src/test/phpt/bug71287.phpt create mode 100644 vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/emptyFolder/.gitignore create mode 100644 vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/aFile.txt create mode 100644 vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder1/file1.txt create mode 100644 vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder2/.gitignore create mode 100644 vendor/myclabs/deep-copy/.github/FUNDING.yml create mode 100644 vendor/myclabs/deep-copy/LICENSE create mode 100644 vendor/myclabs/deep-copy/README.md create mode 100644 vendor/myclabs/deep-copy/composer.json create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Exception/PropertyException.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineCollectionFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/KeepFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/ReplaceFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Matcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyMatcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/ArrayObjectFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedListFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/TypeMatcher/TypeMatcher.php create mode 100644 vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php create mode 100644 vendor/phar-io/manifest/.gitignore create mode 100644 vendor/phar-io/manifest/.php_cs create mode 100644 vendor/phar-io/manifest/.travis.yml create mode 100644 vendor/phar-io/manifest/LICENSE create mode 100644 vendor/phar-io/manifest/README.md create mode 100644 vendor/phar-io/manifest/build.xml create mode 100644 vendor/phar-io/manifest/composer.json create mode 100644 vendor/phar-io/manifest/composer.lock create mode 100644 vendor/phar-io/manifest/examples/example-01.php create mode 100644 vendor/phar-io/manifest/phive.xml create mode 100644 vendor/phar-io/manifest/phpunit.xml create mode 100644 vendor/phar-io/manifest/src/ManifestDocumentMapper.php create mode 100644 vendor/phar-io/manifest/src/ManifestLoader.php create mode 100644 vendor/phar-io/manifest/src/ManifestSerializer.php create mode 100644 vendor/phar-io/manifest/src/exceptions/Exception.php create mode 100644 vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/ManifestElementException.php create mode 100644 vendor/phar-io/manifest/src/exceptions/ManifestLoaderException.php create mode 100644 vendor/phar-io/manifest/src/values/Application.php create mode 100644 vendor/phar-io/manifest/src/values/ApplicationName.php create mode 100644 vendor/phar-io/manifest/src/values/Author.php create mode 100644 vendor/phar-io/manifest/src/values/AuthorCollection.php create mode 100644 vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php create mode 100644 vendor/phar-io/manifest/src/values/BundledComponent.php create mode 100644 vendor/phar-io/manifest/src/values/BundledComponentCollection.php create mode 100644 vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php create mode 100644 vendor/phar-io/manifest/src/values/CopyrightInformation.php create mode 100644 vendor/phar-io/manifest/src/values/Email.php create mode 100644 vendor/phar-io/manifest/src/values/Extension.php create mode 100644 vendor/phar-io/manifest/src/values/Library.php create mode 100644 vendor/phar-io/manifest/src/values/License.php create mode 100644 vendor/phar-io/manifest/src/values/Manifest.php create mode 100644 vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php create mode 100644 vendor/phar-io/manifest/src/values/PhpVersionRequirement.php create mode 100644 vendor/phar-io/manifest/src/values/Requirement.php create mode 100644 vendor/phar-io/manifest/src/values/RequirementCollection.php create mode 100644 vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php create mode 100644 vendor/phar-io/manifest/src/values/Type.php create mode 100644 vendor/phar-io/manifest/src/values/Url.php create mode 100644 vendor/phar-io/manifest/src/xml/AuthorElement.php create mode 100644 vendor/phar-io/manifest/src/xml/AuthorElementCollection.php create mode 100644 vendor/phar-io/manifest/src/xml/BundlesElement.php create mode 100644 vendor/phar-io/manifest/src/xml/ComponentElement.php create mode 100644 vendor/phar-io/manifest/src/xml/ComponentElementCollection.php create mode 100644 vendor/phar-io/manifest/src/xml/ContainsElement.php create mode 100644 vendor/phar-io/manifest/src/xml/CopyrightElement.php create mode 100644 vendor/phar-io/manifest/src/xml/ElementCollection.php create mode 100644 vendor/phar-io/manifest/src/xml/ExtElement.php create mode 100644 vendor/phar-io/manifest/src/xml/ExtElementCollection.php create mode 100644 vendor/phar-io/manifest/src/xml/ExtensionElement.php create mode 100644 vendor/phar-io/manifest/src/xml/LicenseElement.php create mode 100644 vendor/phar-io/manifest/src/xml/ManifestDocument.php create mode 100644 vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php create mode 100644 vendor/phar-io/manifest/src/xml/ManifestElement.php create mode 100644 vendor/phar-io/manifest/src/xml/PhpElement.php create mode 100644 vendor/phar-io/manifest/src/xml/RequiresElement.php create mode 100644 vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php create mode 100644 vendor/phar-io/manifest/tests/ManifestLoaderTest.php create mode 100644 vendor/phar-io/manifest/tests/ManifestSerializerTest.php create mode 100644 vendor/phar-io/manifest/tests/_fixture/custom.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/extension.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/invalidversion.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/library.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/manifest.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml create mode 100644 vendor/phar-io/manifest/tests/_fixture/test.phar create mode 100644 vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php create mode 100644 vendor/phar-io/manifest/tests/values/ApplicationNameTest.php create mode 100644 vendor/phar-io/manifest/tests/values/ApplicationTest.php create mode 100644 vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/values/AuthorTest.php create mode 100644 vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/values/BundledComponentTest.php create mode 100644 vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php create mode 100644 vendor/phar-io/manifest/tests/values/EmailTest.php create mode 100644 vendor/phar-io/manifest/tests/values/ExtensionTest.php create mode 100644 vendor/phar-io/manifest/tests/values/LibraryTest.php create mode 100644 vendor/phar-io/manifest/tests/values/LicenseTest.php create mode 100644 vendor/phar-io/manifest/tests/values/ManifestTest.php create mode 100644 vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php create mode 100644 vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php create mode 100644 vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/values/UrlTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/AuthorElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/BundlesElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ComponentElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ContainsElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ExtElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/LicenseElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/PhpElementTest.php create mode 100644 vendor/phar-io/manifest/tests/xml/RequiresElementTest.php create mode 100644 vendor/phar-io/version/.gitignore create mode 100644 vendor/phar-io/version/.php_cs create mode 100644 vendor/phar-io/version/.travis.yml create mode 100644 vendor/phar-io/version/CHANGELOG.md create mode 100644 vendor/phar-io/version/LICENSE create mode 100644 vendor/phar-io/version/README.md create mode 100644 vendor/phar-io/version/build.xml create mode 100644 vendor/phar-io/version/composer.json create mode 100644 vendor/phar-io/version/phive.xml create mode 100644 vendor/phar-io/version/phpunit.xml create mode 100644 vendor/phar-io/version/src/PreReleaseSuffix.php create mode 100644 vendor/phar-io/version/src/Version.php create mode 100644 vendor/phar-io/version/src/VersionConstraintParser.php create mode 100644 vendor/phar-io/version/src/VersionConstraintValue.php create mode 100644 vendor/phar-io/version/src/VersionNumber.php create mode 100644 vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php create mode 100644 vendor/phar-io/version/src/constraints/AnyVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/ExactVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php create mode 100644 vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php create mode 100644 vendor/phar-io/version/src/constraints/VersionConstraint.php create mode 100644 vendor/phar-io/version/src/exceptions/Exception.php create mode 100644 vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php create mode 100644 vendor/phar-io/version/src/exceptions/InvalidVersionException.php create mode 100644 vendor/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php create mode 100644 vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php create mode 100644 vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php create mode 100644 vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php create mode 100644 vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php create mode 100644 vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php create mode 100644 vendor/phar-io/version/tests/Unit/VersionTest.php create mode 100644 vendor/phenx/php-font-lib/.gitattributes create mode 100644 vendor/phenx/php-font-lib/.gitignore create mode 100644 vendor/phenx/php-font-lib/.htaccess create mode 100644 vendor/phenx/php-font-lib/.travis.yml create mode 100644 vendor/phenx/php-font-lib/LICENSE create mode 100644 vendor/phenx/php-font-lib/README.md create mode 100644 vendor/phenx/php-font-lib/bower.json create mode 100644 vendor/phenx/php-font-lib/composer.json create mode 100644 vendor/phenx/php-font-lib/index.php create mode 100644 vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1250.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1251.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1252.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1253.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1254.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1255.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1257.map create mode 100644 vendor/phenx/php-font-lib/maps/cp1258.map create mode 100644 vendor/phenx/php-font-lib/maps/cp874.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-1.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-11.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-15.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-16.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-2.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-4.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-5.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-7.map create mode 100644 vendor/phenx/php-font-lib/maps/iso-8859-9.map create mode 100644 vendor/phenx/php-font-lib/maps/koi8-r.map create mode 100644 vendor/phenx/php-font-lib/maps/koi8-u.map create mode 100644 vendor/phenx/php-font-lib/phpunit.xml.dist create mode 100644 vendor/phenx/php-font-lib/sample-fonts/IntelClear-Light.ttf create mode 100644 vendor/phenx/php-font-lib/sample-fonts/NotoSansShavian-Regular.ttf create mode 100644 vendor/phenx/php-font-lib/src/FontLib/AdobeFontMetrics.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Autoloader.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EOT/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Font.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Table.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php create mode 100644 vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php create mode 100644 vendor/phenx/php-font-lib/tests/FontLib/FontTest.php create mode 100644 vendor/phenx/php-svg-lib/.gitattributes create mode 100644 vendor/phenx/php-svg-lib/.gitignore create mode 100644 vendor/phenx/php-svg-lib/.travis.yml create mode 100644 vendor/phenx/php-svg-lib/COPYING create mode 100644 vendor/phenx/php-svg-lib/COPYING.GPL create mode 100644 vendor/phenx/php-svg-lib/README.md create mode 100644 vendor/phenx/php-svg-lib/composer.json create mode 100644 vendor/phenx/php-svg-lib/phpunit.xml create mode 100644 vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Document.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Style.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php create mode 100644 vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php create mode 100644 vendor/phenx/php-svg-lib/src/autoload.php create mode 100644 vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php create mode 100644 vendor/phpdocumentor/reflection-common/.github/dependabot.yml create mode 100644 vendor/phpdocumentor/reflection-common/.github/workflows/push.yml create mode 100644 vendor/phpdocumentor/reflection-common/LICENSE create mode 100644 vendor/phpdocumentor/reflection-common/README.md create mode 100644 vendor/phpdocumentor/reflection-common/composer.json create mode 100644 vendor/phpdocumentor/reflection-common/src/Element.php create mode 100644 vendor/phpdocumentor/reflection-common/src/File.php create mode 100644 vendor/phpdocumentor/reflection-common/src/Fqsen.php create mode 100644 vendor/phpdocumentor/reflection-common/src/Location.php create mode 100644 vendor/phpdocumentor/reflection-common/src/Project.php create mode 100644 vendor/phpdocumentor/reflection-common/src/ProjectFactory.php create mode 100644 vendor/phpdocumentor/reflection-docblock/LICENSE create mode 100644 vendor/phpdocumentor/reflection-docblock/README.md create mode 100644 vendor/phpdocumentor/reflection-docblock/composer.json create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php create mode 100644 vendor/phpdocumentor/reflection-docblock/src/Utils.php create mode 100644 vendor/phpdocumentor/type-resolver/LICENSE create mode 100644 vendor/phpdocumentor/type-resolver/README.md create mode 100644 vendor/phpdocumentor/type-resolver/composer.json create mode 100644 vendor/phpdocumentor/type-resolver/composer.lock create mode 100644 vendor/phpdocumentor/type-resolver/phpbench.json create mode 100644 vendor/phpdocumentor/type-resolver/src/FqsenResolver.php create mode 100644 vendor/phpdocumentor/type-resolver/src/PseudoType.php create mode 100644 vendor/phpdocumentor/type-resolver/src/PseudoTypes/False_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/PseudoTypes/True_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Type.php create mode 100644 vendor/phpdocumentor/type-resolver/src/TypeResolver.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Array_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Boolean.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Callable_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/ClassString.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Collection.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Compound.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Context.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Expression.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Float_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Integer.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Intersection.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Null_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Nullable.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Object_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Parent_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Resource_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Scalar.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Self_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Static_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/String_.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/This.php create mode 100644 vendor/phpdocumentor/type-resolver/src/Types/Void_.php create mode 100644 vendor/phpspec/prophecy/CHANGES.md create mode 100644 vendor/phpspec/prophecy/LICENSE create mode 100644 vendor/phpspec/prophecy/README.md create mode 100644 vendor/phpspec/prophecy/composer.json create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/InArrayToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/NotInArrayToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Call/Call.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentTypeNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ReturnTypeNode.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Prophet.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php create mode 100644 vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php create mode 100644 vendor/phpunit/php-code-coverage/.gitattributes create mode 100644 vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md create mode 100644 vendor/phpunit/php-code-coverage/.github/FUNDING.yml create mode 100644 vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md create mode 100644 vendor/phpunit/php-code-coverage/.gitignore create mode 100644 vendor/phpunit/php-code-coverage/.php_cs.dist create mode 100644 vendor/phpunit/php-code-coverage/.travis.yml create mode 100644 vendor/phpunit/php-code-coverage/ChangeLog.md create mode 100644 vendor/phpunit/php-code-coverage/LICENSE create mode 100644 vendor/phpunit/php-code-coverage/README.md create mode 100644 vendor/phpunit/php-code-coverage/build.xml create mode 100644 vendor/phpunit/php-code-coverage/composer.json create mode 100644 vendor/phpunit/php-code-coverage/phive.xml create mode 100644 vendor/phpunit/php-code-coverage/phpunit.xml create mode 100644 vendor/phpunit/php-code-coverage/src/CodeCoverage.php create mode 100644 vendor/phpunit/php-code-coverage/src/Driver/Driver.php create mode 100644 vendor/phpunit/php-code-coverage/src/Driver/PCOV.php create mode 100644 vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php create mode 100644 vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/Exception.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php create mode 100644 vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php create mode 100644 vendor/phpunit/php-code-coverage/src/Filter.php create mode 100644 vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php create mode 100644 vendor/phpunit/php-code-coverage/src/Node/Builder.php create mode 100644 vendor/phpunit/php-code-coverage/src/Node/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/Node/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/Node/Iterator.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Clover.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Crap4j.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/d3.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/nv.d3.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist create mode 100644 vendor/phpunit/php-code-coverage/src/Report/PHP.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Text.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/File.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php create mode 100644 vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php create mode 100644 vendor/phpunit/php-code-coverage/src/Util.php create mode 100644 vendor/phpunit/php-code-coverage/src/Version.php create mode 100644 vendor/phpunit/php-code-coverage/tests/TestCase.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodOneLineAnnotationTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Crash.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassExtendedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_ignore.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_namespace.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_oneline_annotations.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_with_use_statements.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php create mode 100644 vendor/phpunit/php-code-coverage/tests/_files/source_without_namespace.php create mode 100644 vendor/phpunit/php-code-coverage/tests/bootstrap.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/BuilderTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/TextTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php create mode 100644 vendor/phpunit/php-code-coverage/tests/tests/XmlTest.php create mode 100644 vendor/phpunit/php-file-iterator/.gitattributes create mode 100644 vendor/phpunit/php-file-iterator/.github/stale.yml create mode 100644 vendor/phpunit/php-file-iterator/.gitignore create mode 100644 vendor/phpunit/php-file-iterator/.php_cs.dist create mode 100644 vendor/phpunit/php-file-iterator/.travis.yml create mode 100644 vendor/phpunit/php-file-iterator/ChangeLog.md create mode 100644 vendor/phpunit/php-file-iterator/LICENSE create mode 100644 vendor/phpunit/php-file-iterator/README.md create mode 100644 vendor/phpunit/php-file-iterator/composer.json create mode 100644 vendor/phpunit/php-file-iterator/phpunit.xml create mode 100644 vendor/phpunit/php-file-iterator/src/Facade.php create mode 100644 vendor/phpunit/php-file-iterator/src/Factory.php create mode 100644 vendor/phpunit/php-file-iterator/src/Iterator.php create mode 100644 vendor/phpunit/php-file-iterator/tests/FactoryTest.php create mode 100644 vendor/phpunit/php-text-template/.gitattributes create mode 100644 vendor/phpunit/php-text-template/.gitignore create mode 100644 vendor/phpunit/php-text-template/LICENSE create mode 100644 vendor/phpunit/php-text-template/README.md create mode 100644 vendor/phpunit/php-text-template/composer.json create mode 100644 vendor/phpunit/php-text-template/src/Template.php create mode 100644 vendor/phpunit/php-timer/.gitattributes create mode 100644 vendor/phpunit/php-timer/.github/FUNDING.yml create mode 100644 vendor/phpunit/php-timer/.github/stale.yml create mode 100644 vendor/phpunit/php-timer/.gitignore create mode 100644 vendor/phpunit/php-timer/.php_cs.dist create mode 100644 vendor/phpunit/php-timer/.travis.yml create mode 100644 vendor/phpunit/php-timer/ChangeLog.md create mode 100644 vendor/phpunit/php-timer/LICENSE create mode 100644 vendor/phpunit/php-timer/README.md create mode 100644 vendor/phpunit/php-timer/build.xml create mode 100644 vendor/phpunit/php-timer/composer.json create mode 100644 vendor/phpunit/php-timer/phpunit.xml create mode 100644 vendor/phpunit/php-timer/src/Exception.php create mode 100644 vendor/phpunit/php-timer/src/RuntimeException.php create mode 100644 vendor/phpunit/php-timer/src/Timer.php create mode 100644 vendor/phpunit/php-timer/tests/TimerTest.php create mode 100644 vendor/phpunit/php-token-stream/.gitattributes create mode 100644 vendor/phpunit/php-token-stream/.github/FUNDING.yml create mode 100644 vendor/phpunit/php-token-stream/.gitignore create mode 100644 vendor/phpunit/php-token-stream/.travis.yml create mode 100644 vendor/phpunit/php-token-stream/ChangeLog.md create mode 100644 vendor/phpunit/php-token-stream/LICENSE create mode 100644 vendor/phpunit/php-token-stream/README.md create mode 100644 vendor/phpunit/php-token-stream/build.xml create mode 100644 vendor/phpunit/php-token-stream/composer.json create mode 100644 vendor/phpunit/php-token-stream/phpunit.xml create mode 100644 vendor/phpunit/php-token-stream/src/Token.php create mode 100644 vendor/phpunit/php-token-stream/src/Token/Stream.php create mode 100644 vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php create mode 100644 vendor/phpunit/php-token-stream/src/Token/Util.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/ClassTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classInNamespace.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classInScopedNamespace.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/classUsesNamespacedFunction.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_named_empty.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_method_that_declares_anonymous_class2.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/closure.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/issue19.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/issue30.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingBraces.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/multipleNamespacesWithOneClassUsingNonBraceSyntax.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/php-code-coverage-issue-424.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source2.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source3.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source4.php create mode 100644 vendor/phpunit/php-token-stream/tests/_fixture/source5.php create mode 100644 vendor/phpunit/php-token-stream/tests/bootstrap.php create mode 100644 vendor/phpunit/phpunit/.gitattributes create mode 100644 vendor/phpunit/phpunit/.gitignore create mode 100644 vendor/phpunit/phpunit/.phive/phars.xml create mode 100644 vendor/phpunit/phpunit/.phpstorm.meta.php create mode 100644 vendor/phpunit/phpunit/ChangeLog-8.5.md create mode 100644 vendor/phpunit/phpunit/LICENSE create mode 100644 vendor/phpunit/phpunit/README.md create mode 100644 vendor/phpunit/phpunit/composer.json create mode 100644 vendor/phpunit/phpunit/phpunit create mode 100644 vendor/phpunit/phpunit/phpunit.xsd create mode 100644 vendor/phpunit/phpunit/src/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Assert.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Assert/Functions.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Count.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php create mode 100644 vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Error.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Notice.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Error/Warning.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Exception/Warning.php create mode 100644 vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php create mode 100644 vendor/phpunit/phpunit/src/Framework/IncompleteTest.php create mode 100644 vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php create mode 100644 vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SelfDescribing.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTest.php create mode 100644 vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/Test.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestBuilder.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestCase.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestFailure.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestListener.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestResult.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestSuite.php create mode 100644 vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php create mode 100644 vendor/phpunit/phpunit/src/Framework/WarningTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php create mode 100644 vendor/phpunit/phpunit/src/Runner/DefaultTestResultCache.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/Factory.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/Hook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/TestHook.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php create mode 100644 vendor/phpunit/phpunit/src/Runner/NullTestResultCache.php create mode 100644 vendor/phpunit/phpunit/src/Runner/PhptTestCase.php create mode 100644 vendor/phpunit/phpunit/src/Runner/ResultCacheExtension.php create mode 100644 vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php create mode 100644 vendor/phpunit/phpunit/src/Runner/TestResultCache.php create mode 100644 vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php create mode 100644 vendor/phpunit/phpunit/src/Runner/TestSuiteSorter.php create mode 100644 vendor/phpunit/phpunit/src/Runner/Version.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/Command.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/Exception.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/Help.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/TextUI/TestRunner.php create mode 100644 vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php create mode 100644 vendor/phpunit/phpunit/src/Util/Annotation/Registry.php create mode 100644 vendor/phpunit/phpunit/src/Util/Blacklist.php create mode 100644 vendor/phpunit/phpunit/src/Util/Color.php create mode 100644 vendor/phpunit/phpunit/src/Util/Configuration.php create mode 100644 vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php create mode 100644 vendor/phpunit/phpunit/src/Util/ErrorHandler.php create mode 100644 vendor/phpunit/phpunit/src/Util/Exception.php create mode 100644 vendor/phpunit/phpunit/src/Util/FileLoader.php create mode 100644 vendor/phpunit/phpunit/src/Util/Filesystem.php create mode 100644 vendor/phpunit/phpunit/src/Util/Filter.php create mode 100644 vendor/phpunit/phpunit/src/Util/Getopt.php create mode 100644 vendor/phpunit/phpunit/src/Util/GlobalState.php create mode 100644 vendor/phpunit/phpunit/src/Util/InvalidDataSetException.php create mode 100644 vendor/phpunit/phpunit/src/Util/Json.php create mode 100644 vendor/phpunit/phpunit/src/Util/Log/JUnit.php create mode 100644 vendor/phpunit/phpunit/src/Util/Log/TeamCity.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Template/PhptTestCase.tpl create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseClass.tpl create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl create mode 100644 vendor/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php create mode 100644 vendor/phpunit/phpunit/src/Util/Printer.php create mode 100644 vendor/phpunit/phpunit/src/Util/RegularExpression.php create mode 100644 vendor/phpunit/phpunit/src/Util/Test.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/TestDoxPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php create mode 100644 vendor/phpunit/phpunit/src/Util/TextTestListRenderer.php create mode 100644 vendor/phpunit/phpunit/src/Util/Type.php create mode 100644 vendor/phpunit/phpunit/src/Util/VersionComparisonOperator.php create mode 100644 vendor/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php create mode 100644 vendor/phpunit/phpunit/src/Util/Xml.php create mode 100644 vendor/phpunit/phpunit/src/Util/XmlTestListRenderer.php create mode 100644 vendor/psr/log/LICENSE create mode 100644 vendor/psr/log/Psr/Log/AbstractLogger.php create mode 100644 vendor/psr/log/Psr/Log/InvalidArgumentException.php create mode 100644 vendor/psr/log/Psr/Log/LogLevel.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerAwareTrait.php create mode 100644 vendor/psr/log/Psr/Log/LoggerInterface.php create mode 100644 vendor/psr/log/Psr/Log/LoggerTrait.php create mode 100644 vendor/psr/log/Psr/Log/NullLogger.php create mode 100644 vendor/psr/log/Psr/Log/Test/DummyTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/LoggerInterfaceTest.php create mode 100644 vendor/psr/log/Psr/Log/Test/TestLogger.php create mode 100644 vendor/psr/log/README.md create mode 100644 vendor/psr/log/composer.json create mode 100644 vendor/sabberworm/php-css-parser/.gitignore create mode 100644 vendor/sabberworm/php-css-parser/.travis.yml create mode 100644 vendor/sabberworm/php-css-parser/CHANGELOG.md create mode 100644 vendor/sabberworm/php-css-parser/Doxyfile create mode 100644 vendor/sabberworm/php-css-parser/README.md create mode 100644 vendor/sabberworm/php-css-parser/composer.json create mode 100644 vendor/sabberworm/php-css-parser/composer.lock create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/AtRuleBlockList.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSBlockList.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/CSSList.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/Document.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/CSSList/KeyFrame.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Comment.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Comment/Commentable.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/OutputFormat.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parser.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/OutputException.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/ParserState.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/SourceException.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Parsing/UnexpectedTokenException.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/AtRule.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/CSSNamespace.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Charset.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Import.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Property/Selector.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Renderable.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Rule/Rule.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/AtRuleSet.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/DeclarationBlock.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/RuleSet/RuleSet.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Settings.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSFunction.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CSSString.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CalcFunction.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/CalcRuleValueList.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Color.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/LineName.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/PrimitiveValue.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/RuleValueList.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Size.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/URL.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/Value.php create mode 100644 vendor/sabberworm/php-css-parser/lib/Sabberworm/CSS/Value/ValueList.php create mode 100644 vendor/sabberworm/php-css-parser/phpunit.xml create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/AtRuleBlockListTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/CSSList/DocumentTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/OutputFormatTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/ParserTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/DeclarationBlockTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/Sabberworm/CSS/RuleSet/LenientParsingTest.php create mode 100644 vendor/sabberworm/php-css-parser/tests/bootstrap.php create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-calc-no-space-around-minus.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-charset-after-rule.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-charset-in-block.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-empty-grid-linename.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-empty.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-end-token-2.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-end-token.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-fault-tolerance.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/-tobedone.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/1readme.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/2readme.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/atrules.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/calc-nested.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/calc.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/case-insensitivity.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/colortest.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/comments.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/create-shorthands.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/docuwiki.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/empty-grid-linename.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/expand-shorthands.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/functions.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/grid-linename.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/hex-alpha.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/ie-hacks.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/ie.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/important.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/inner-color.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/line-numbers.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/missing-property-value.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/ms-filter.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/namespaces.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/nested.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/slashed.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/specificity.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/trailing-whitespace.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/unicode-range.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/unicode.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/unmatched_braces.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/unopened-close-brackets.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/url.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/values.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/webkit.css create mode 100644 vendor/sabberworm/php-css-parser/tests/files/whitespace.css create mode 100644 vendor/sabberworm/php-css-parser/tests/phpunit.xml create mode 100644 vendor/sabberworm/php-css-parser/tests/quickdump.php create mode 100644 vendor/sebastian/code-unit-reverse-lookup/.gitignore create mode 100644 vendor/sebastian/code-unit-reverse-lookup/.php_cs create mode 100644 vendor/sebastian/code-unit-reverse-lookup/.travis.yml create mode 100644 vendor/sebastian/code-unit-reverse-lookup/ChangeLog.md create mode 100644 vendor/sebastian/code-unit-reverse-lookup/LICENSE create mode 100644 vendor/sebastian/code-unit-reverse-lookup/README.md create mode 100644 vendor/sebastian/code-unit-reverse-lookup/build.xml create mode 100644 vendor/sebastian/code-unit-reverse-lookup/composer.json create mode 100644 vendor/sebastian/code-unit-reverse-lookup/phpunit.xml create mode 100644 vendor/sebastian/code-unit-reverse-lookup/src/Wizard.php create mode 100644 vendor/sebastian/code-unit-reverse-lookup/tests/WizardTest.php create mode 100644 vendor/sebastian/comparator/.github/stale.yml create mode 100644 vendor/sebastian/comparator/.gitignore create mode 100644 vendor/sebastian/comparator/.php_cs.dist create mode 100644 vendor/sebastian/comparator/.travis.yml create mode 100644 vendor/sebastian/comparator/ChangeLog.md create mode 100644 vendor/sebastian/comparator/LICENSE create mode 100644 vendor/sebastian/comparator/README.md create mode 100644 vendor/sebastian/comparator/build.xml create mode 100644 vendor/sebastian/comparator/composer.json create mode 100644 vendor/sebastian/comparator/phpunit.xml create mode 100644 vendor/sebastian/comparator/src/ArrayComparator.php create mode 100644 vendor/sebastian/comparator/src/Comparator.php create mode 100644 vendor/sebastian/comparator/src/ComparisonFailure.php create mode 100644 vendor/sebastian/comparator/src/DOMNodeComparator.php create mode 100644 vendor/sebastian/comparator/src/DateTimeComparator.php create mode 100644 vendor/sebastian/comparator/src/DoubleComparator.php create mode 100644 vendor/sebastian/comparator/src/ExceptionComparator.php create mode 100644 vendor/sebastian/comparator/src/Factory.php create mode 100644 vendor/sebastian/comparator/src/MockObjectComparator.php create mode 100644 vendor/sebastian/comparator/src/NumericComparator.php create mode 100644 vendor/sebastian/comparator/src/ObjectComparator.php create mode 100644 vendor/sebastian/comparator/src/ResourceComparator.php create mode 100644 vendor/sebastian/comparator/src/ScalarComparator.php create mode 100644 vendor/sebastian/comparator/src/SplObjectStorageComparator.php create mode 100644 vendor/sebastian/comparator/src/TypeComparator.php create mode 100644 vendor/sebastian/comparator/tests/ArrayComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ComparisonFailureTest.php create mode 100644 vendor/sebastian/comparator/tests/DOMNodeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/DateTimeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/DoubleComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ExceptionComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/FactoryTest.php create mode 100644 vendor/sebastian/comparator/tests/MockObjectComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/NumericComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ObjectComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ResourceComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/ScalarComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/SplObjectStorageComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/TypeComparatorTest.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/Author.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/Book.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/ClassWithToString.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/SampleClass.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/Struct.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/TestClass.php create mode 100644 vendor/sebastian/comparator/tests/_fixture/TestClassComparator.php create mode 100644 vendor/sebastian/diff/.github/stale.yml create mode 100644 vendor/sebastian/diff/.gitignore create mode 100644 vendor/sebastian/diff/.php_cs.dist create mode 100644 vendor/sebastian/diff/.travis.yml create mode 100644 vendor/sebastian/diff/ChangeLog.md create mode 100644 vendor/sebastian/diff/LICENSE create mode 100644 vendor/sebastian/diff/README.md create mode 100644 vendor/sebastian/diff/build.xml create mode 100644 vendor/sebastian/diff/composer.json create mode 100644 vendor/sebastian/diff/phpunit.xml create mode 100644 vendor/sebastian/diff/src/Chunk.php create mode 100644 vendor/sebastian/diff/src/Diff.php create mode 100644 vendor/sebastian/diff/src/Differ.php create mode 100644 vendor/sebastian/diff/src/Exception/ConfigurationException.php create mode 100644 vendor/sebastian/diff/src/Exception/Exception.php create mode 100644 vendor/sebastian/diff/src/Exception/InvalidArgumentException.php create mode 100644 vendor/sebastian/diff/src/Line.php create mode 100644 vendor/sebastian/diff/src/LongestCommonSubsequenceCalculator.php create mode 100644 vendor/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php create mode 100644 vendor/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/DiffOutputBuilderInterface.php create mode 100644 vendor/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php create mode 100644 vendor/sebastian/diff/src/Parser.php create mode 100644 vendor/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php create mode 100644 vendor/sebastian/diff/tests/ChunkTest.php create mode 100644 vendor/sebastian/diff/tests/DiffTest.php create mode 100644 vendor/sebastian/diff/tests/DifferTest.php create mode 100644 vendor/sebastian/diff/tests/Exception/ConfigurationExceptionTest.php create mode 100644 vendor/sebastian/diff/tests/Exception/InvalidArgumentExceptionTest.php create mode 100644 vendor/sebastian/diff/tests/LineTest.php create mode 100644 vendor/sebastian/diff/tests/LongestCommonSubsequenceTest.php create mode 100644 vendor/sebastian/diff/tests/MemoryEfficientImplementationTest.php create mode 100644 vendor/sebastian/diff/tests/Output/AbstractChunkOutputBuilderTest.php create mode 100644 vendor/sebastian/diff/tests/Output/DiffOnlyOutputBuilderTest.php create mode 100644 vendor/sebastian/diff/tests/Output/Integration/StrictUnifiedDiffOutputBuilderIntegrationTest.php create mode 100644 vendor/sebastian/diff/tests/Output/Integration/UnifiedDiffOutputBuilderIntegrationTest.php create mode 100644 vendor/sebastian/diff/tests/Output/StrictUnifiedDiffOutputBuilderDataProvider.php create mode 100644 vendor/sebastian/diff/tests/Output/StrictUnifiedDiffOutputBuilderTest.php create mode 100644 vendor/sebastian/diff/tests/Output/UnifiedDiffOutputBuilderDataProvider.php create mode 100644 vendor/sebastian/diff/tests/Output/UnifiedDiffOutputBuilderTest.php create mode 100644 vendor/sebastian/diff/tests/ParserTest.php create mode 100644 vendor/sebastian/diff/tests/TimeEfficientImplementationTest.php create mode 100644 vendor/sebastian/diff/tests/Utils/FileUtils.php create mode 100644 vendor/sebastian/diff/tests/Utils/UnifiedDiffAssertTrait.php create mode 100644 vendor/sebastian/diff/tests/Utils/UnifiedDiffAssertTraitIntegrationTest.php create mode 100644 vendor/sebastian/diff/tests/Utils/UnifiedDiffAssertTraitTest.php create mode 100644 vendor/sebastian/diff/tests/fixtures/.editorconfig create mode 100644 vendor/sebastian/diff/tests/fixtures/UnifiedDiffAssertTraitIntegrationTest/1_a.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/UnifiedDiffAssertTraitIntegrationTest/1_b.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/UnifiedDiffAssertTraitIntegrationTest/2_a.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/UnifiedDiffAssertTraitIntegrationTest/2_b.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/out/.editorconfig create mode 100644 vendor/sebastian/diff/tests/fixtures/out/.gitignore create mode 100644 vendor/sebastian/diff/tests/fixtures/patch.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/patch2.txt create mode 100644 vendor/sebastian/diff/tests/fixtures/serialized_diff.bin create mode 100644 vendor/sebastian/environment/.github/FUNDING.yml create mode 100644 vendor/sebastian/environment/.gitignore create mode 100644 vendor/sebastian/environment/.php_cs.dist create mode 100644 vendor/sebastian/environment/.travis.yml create mode 100644 vendor/sebastian/environment/ChangeLog.md create mode 100644 vendor/sebastian/environment/LICENSE create mode 100644 vendor/sebastian/environment/README.md create mode 100644 vendor/sebastian/environment/build.xml create mode 100644 vendor/sebastian/environment/composer.json create mode 100644 vendor/sebastian/environment/phpunit.xml create mode 100644 vendor/sebastian/environment/src/Console.php create mode 100644 vendor/sebastian/environment/src/OperatingSystem.php create mode 100644 vendor/sebastian/environment/src/Runtime.php create mode 100644 vendor/sebastian/environment/tests/ConsoleTest.php create mode 100644 vendor/sebastian/environment/tests/OperatingSystemTest.php create mode 100644 vendor/sebastian/environment/tests/RuntimeTest.php create mode 100644 vendor/sebastian/exporter/.github/FUNDING.yml create mode 100644 vendor/sebastian/exporter/.gitignore create mode 100644 vendor/sebastian/exporter/.php_cs.dist create mode 100644 vendor/sebastian/exporter/.travis.yml create mode 100644 vendor/sebastian/exporter/ChangeLog.md create mode 100644 vendor/sebastian/exporter/LICENSE create mode 100644 vendor/sebastian/exporter/README.md create mode 100644 vendor/sebastian/exporter/build.xml create mode 100644 vendor/sebastian/exporter/composer.json create mode 100644 vendor/sebastian/exporter/phpunit.xml create mode 100644 vendor/sebastian/exporter/src/Exporter.php create mode 100644 vendor/sebastian/exporter/tests/ExporterTest.php create mode 100644 vendor/sebastian/global-state/.github/stale.yml create mode 100644 vendor/sebastian/global-state/.gitignore create mode 100644 vendor/sebastian/global-state/.php_cs.dist create mode 100644 vendor/sebastian/global-state/.travis.yml create mode 100644 vendor/sebastian/global-state/ChangeLog.md create mode 100644 vendor/sebastian/global-state/LICENSE create mode 100644 vendor/sebastian/global-state/README.md create mode 100644 vendor/sebastian/global-state/build.xml create mode 100644 vendor/sebastian/global-state/composer.json create mode 100644 vendor/sebastian/global-state/phpunit.xml create mode 100644 vendor/sebastian/global-state/src/Blacklist.php create mode 100644 vendor/sebastian/global-state/src/CodeExporter.php create mode 100644 vendor/sebastian/global-state/src/Restorer.php create mode 100644 vendor/sebastian/global-state/src/Snapshot.php create mode 100644 vendor/sebastian/global-state/src/exceptions/Exception.php create mode 100644 vendor/sebastian/global-state/src/exceptions/RuntimeException.php create mode 100644 vendor/sebastian/global-state/tests/BlacklistTest.php create mode 100644 vendor/sebastian/global-state/tests/CodeExporterTest.php create mode 100644 vendor/sebastian/global-state/tests/RestorerTest.php create mode 100644 vendor/sebastian/global-state/tests/SnapshotTest.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedChildClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedImplementor.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/BlacklistedInterface.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotClass.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotDomDocument.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotFunctions.php create mode 100644 vendor/sebastian/global-state/tests/_fixture/SnapshotTrait.php create mode 100644 vendor/sebastian/object-enumerator/.gitignore create mode 100644 vendor/sebastian/object-enumerator/.php_cs create mode 100644 vendor/sebastian/object-enumerator/.travis.yml create mode 100644 vendor/sebastian/object-enumerator/ChangeLog.md create mode 100644 vendor/sebastian/object-enumerator/LICENSE create mode 100644 vendor/sebastian/object-enumerator/README.md create mode 100644 vendor/sebastian/object-enumerator/build.xml create mode 100644 vendor/sebastian/object-enumerator/composer.json create mode 100644 vendor/sebastian/object-enumerator/phpunit.xml create mode 100644 vendor/sebastian/object-enumerator/src/Enumerator.php create mode 100644 vendor/sebastian/object-enumerator/src/Exception.php create mode 100644 vendor/sebastian/object-enumerator/src/InvalidArgumentException.php create mode 100644 vendor/sebastian/object-enumerator/tests/EnumeratorTest.php create mode 100644 vendor/sebastian/object-enumerator/tests/_fixture/ExceptionThrower.php create mode 100644 vendor/sebastian/object-reflector/.gitignore create mode 100644 vendor/sebastian/object-reflector/.php_cs create mode 100644 vendor/sebastian/object-reflector/.travis.yml create mode 100644 vendor/sebastian/object-reflector/ChangeLog.md create mode 100644 vendor/sebastian/object-reflector/LICENSE create mode 100644 vendor/sebastian/object-reflector/README.md create mode 100644 vendor/sebastian/object-reflector/build.xml create mode 100644 vendor/sebastian/object-reflector/composer.json create mode 100644 vendor/sebastian/object-reflector/phpunit.xml create mode 100644 vendor/sebastian/object-reflector/src/Exception.php create mode 100644 vendor/sebastian/object-reflector/src/InvalidArgumentException.php create mode 100644 vendor/sebastian/object-reflector/src/ObjectReflector.php create mode 100644 vendor/sebastian/object-reflector/tests/ObjectReflectorTest.php create mode 100644 vendor/sebastian/object-reflector/tests/_fixture/ChildClass.php create mode 100644 vendor/sebastian/object-reflector/tests/_fixture/ClassWithIntegerAttributeName.php create mode 100644 vendor/sebastian/object-reflector/tests/_fixture/ParentClass.php create mode 100644 vendor/sebastian/recursion-context/.gitignore create mode 100644 vendor/sebastian/recursion-context/.travis.yml create mode 100644 vendor/sebastian/recursion-context/LICENSE create mode 100644 vendor/sebastian/recursion-context/README.md create mode 100644 vendor/sebastian/recursion-context/build.xml create mode 100644 vendor/sebastian/recursion-context/composer.json create mode 100644 vendor/sebastian/recursion-context/phpunit.xml create mode 100644 vendor/sebastian/recursion-context/src/Context.php create mode 100644 vendor/sebastian/recursion-context/src/Exception.php create mode 100644 vendor/sebastian/recursion-context/src/InvalidArgumentException.php create mode 100644 vendor/sebastian/recursion-context/tests/ContextTest.php create mode 100644 vendor/sebastian/resource-operations/.github/stale.yml create mode 100644 vendor/sebastian/resource-operations/.gitignore create mode 100644 vendor/sebastian/resource-operations/.php_cs.dist create mode 100644 vendor/sebastian/resource-operations/ChangeLog.md create mode 100644 vendor/sebastian/resource-operations/LICENSE create mode 100644 vendor/sebastian/resource-operations/README.md create mode 100644 vendor/sebastian/resource-operations/build.xml create mode 100644 vendor/sebastian/resource-operations/build/generate.php create mode 100644 vendor/sebastian/resource-operations/composer.json create mode 100644 vendor/sebastian/resource-operations/src/ResourceOperations.php create mode 100644 vendor/sebastian/resource-operations/tests/ResourceOperationsTest.php create mode 100644 vendor/sebastian/type/.gitattributes create mode 100644 vendor/sebastian/type/.github/FUNDING.yml create mode 100644 vendor/sebastian/type/.gitignore create mode 100644 vendor/sebastian/type/.php_cs.dist create mode 100644 vendor/sebastian/type/.travis.yml create mode 100644 vendor/sebastian/type/ChangeLog.md create mode 100644 vendor/sebastian/type/LICENSE create mode 100644 vendor/sebastian/type/README.md create mode 100644 vendor/sebastian/type/build.xml create mode 100644 vendor/sebastian/type/composer.json create mode 100644 vendor/sebastian/type/phive.xml create mode 100644 vendor/sebastian/type/phpunit.xml create mode 100644 vendor/sebastian/type/psalm.xml create mode 100644 vendor/sebastian/type/src/CallableType.php create mode 100644 vendor/sebastian/type/src/GenericObjectType.php create mode 100644 vendor/sebastian/type/src/IterableType.php create mode 100644 vendor/sebastian/type/src/NullType.php create mode 100644 vendor/sebastian/type/src/ObjectType.php create mode 100644 vendor/sebastian/type/src/SimpleType.php create mode 100644 vendor/sebastian/type/src/Type.php create mode 100644 vendor/sebastian/type/src/TypeName.php create mode 100644 vendor/sebastian/type/src/UnknownType.php create mode 100644 vendor/sebastian/type/src/VoidType.php create mode 100644 vendor/sebastian/type/src/exception/Exception.php create mode 100644 vendor/sebastian/type/src/exception/RuntimeException.php create mode 100644 vendor/sebastian/type/tests/_fixture/ChildClass.php create mode 100644 vendor/sebastian/type/tests/_fixture/ClassWithCallbackMethods.php create mode 100644 vendor/sebastian/type/tests/_fixture/ClassWithInvokeMethod.php create mode 100644 vendor/sebastian/type/tests/_fixture/Iterator.php create mode 100644 vendor/sebastian/type/tests/_fixture/ParentClass.php create mode 100644 vendor/sebastian/type/tests/_fixture/callback_function.php create mode 100644 vendor/sebastian/type/tests/unit/CallableTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/GenericObjectTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/IterableTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/NullTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/ObjectTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/SimpleTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/TypeNameTest.php create mode 100644 vendor/sebastian/type/tests/unit/TypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/UnknownTypeTest.php create mode 100644 vendor/sebastian/type/tests/unit/VoidTypeTest.php create mode 100644 vendor/sebastian/version/.gitattributes create mode 100644 vendor/sebastian/version/.gitignore create mode 100644 vendor/sebastian/version/.php_cs create mode 100644 vendor/sebastian/version/LICENSE create mode 100644 vendor/sebastian/version/README.md create mode 100644 vendor/sebastian/version/composer.json create mode 100644 vendor/sebastian/version/src/Version.php create mode 100644 vendor/symfony/polyfill-ctype/Ctype.php create mode 100644 vendor/symfony/polyfill-ctype/LICENSE create mode 100644 vendor/symfony/polyfill-ctype/README.md create mode 100644 vendor/symfony/polyfill-ctype/bootstrap.php create mode 100644 vendor/symfony/polyfill-ctype/composer.json create mode 100644 vendor/theseer/tokenizer/.php_cs.dist create mode 100644 vendor/theseer/tokenizer/CHANGELOG.md create mode 100644 vendor/theseer/tokenizer/LICENSE create mode 100644 vendor/theseer/tokenizer/README.md create mode 100644 vendor/theseer/tokenizer/composer.json create mode 100644 vendor/theseer/tokenizer/src/Exception.php create mode 100644 vendor/theseer/tokenizer/src/NamespaceUri.php create mode 100644 vendor/theseer/tokenizer/src/NamespaceUriException.php create mode 100644 vendor/theseer/tokenizer/src/Token.php create mode 100644 vendor/theseer/tokenizer/src/TokenCollection.php create mode 100644 vendor/theseer/tokenizer/src/TokenCollectionException.php create mode 100644 vendor/theseer/tokenizer/src/Tokenizer.php create mode 100644 vendor/theseer/tokenizer/src/XMLSerializer.php create mode 100644 vendor/webmozart/assert/.editorconfig create mode 100644 vendor/webmozart/assert/CHANGELOG.md create mode 100644 vendor/webmozart/assert/LICENSE create mode 100644 vendor/webmozart/assert/README.md create mode 100644 vendor/webmozart/assert/composer.json create mode 100644 vendor/webmozart/assert/psalm.xml create mode 100644 vendor/webmozart/assert/src/Assert.php create mode 100644 vendor/webmozart/assert/src/Mixin.php create mode 100644 writable/.htaccess create mode 100644 writable/cache/index.html create mode 100644 writable/debugbar/.gitkeep create mode 100644 writable/debugbar/debugbar_1606125960.json create mode 100644 writable/debugbar/debugbar_1606125961.json create mode 100644 writable/debugbar/debugbar_1606126068.json create mode 100644 writable/debugbar/debugbar_1606126069.json create mode 100644 writable/debugbar/debugbar_1606126144.json create mode 100644 writable/debugbar/debugbar_1606126145.json create mode 100644 writable/debugbar/debugbar_1606126148.json create mode 100644 writable/debugbar/debugbar_1606126149.json create mode 100644 writable/debugbar/debugbar_1606126159.json create mode 100644 writable/debugbar/debugbar_1606126160.json create mode 100644 writable/debugbar/debugbar_1606126161.json create mode 100644 writable/debugbar/debugbar_1606126162.json create mode 100644 writable/debugbar/debugbar_1606126164.json create mode 100644 writable/debugbar/debugbar_1606126172.json create mode 100644 writable/debugbar/debugbar_1606126173.json create mode 100644 writable/debugbar/debugbar_1606126186.json create mode 100644 writable/debugbar/debugbar_1606126187.json create mode 100644 writable/debugbar/debugbar_1606126232.json create mode 100644 writable/debugbar/debugbar_1606126233.json create mode 100644 writable/debugbar/debugbar_1606126239.json create mode 100644 writable/debugbar/debugbar_1606126241.json create mode 100644 writable/logs/index.html create mode 100644 writable/session/ci_session04tdbauigi4bltm1lefpv6dv6v97503n create mode 100644 writable/session/ci_session088hbi278cnj24brm5qgb21jhjoat0dt create mode 100644 writable/session/ci_session09dca1ja5recdm111soapgagh4189drh create mode 100644 writable/session/ci_session0acdga4ht0q1bf9765b089m7g95l84iu create mode 100644 writable/session/ci_session0al9n5o0psah5atkoae2tot6p593pe3u create mode 100644 writable/session/ci_session0bhr720mesn9si1e1k411bqi0m78i1r5 create mode 100644 writable/session/ci_session0gcqfgfas4hse2pkk4g8uhikdib4d99p create mode 100644 writable/session/ci_session0hgki3cuce05m4o9e99uckue59u7fngc create mode 100644 writable/session/ci_session0opu017b572p42b10mhpdsuohs9d6hun create mode 100644 writable/session/ci_session0pioirjpaft1sfpmu2vkkdj3devlusds create mode 100644 writable/session/ci_session0pqo738djncmeajs3f1q8d4uersclrcq create mode 100644 writable/session/ci_session0qidupcqgnl2fb9porf79hbera4sv8as create mode 100644 writable/session/ci_session0rmqu0c2ukj75q600ps7ohdjc8vat2cf create mode 100644 writable/session/ci_session16kvibjmqqr32v0kdq9ue79cmpk8c9f4 create mode 100644 writable/session/ci_session1a6kk2bte2o53r0nd76sbrfahl5hq4dr create mode 100644 writable/session/ci_session1aivp7vsj085dovu6naltbs1kud7a7t1 create mode 100644 writable/session/ci_session1di4otssj7g6orshhm3731atcef0e3u1 create mode 100644 writable/session/ci_session1g5rirvhntefcjaffplkajqn7s1n7f7u create mode 100644 writable/session/ci_session1gdesiuamifnh0hp5geqcrf393l6p4gu create mode 100644 writable/session/ci_session1k8o4suv0ggbhfsoa8ga456u4dlpl1qb create mode 100644 writable/session/ci_session1qte9ihcd7vl97ckp8u023eujio1hfn7 create mode 100644 writable/session/ci_session1sbu968fn4hm8l25m3971eip34594ph4 create mode 100644 writable/session/ci_session20hvc0f26rr0h7ojk4esv7u7aej9k79k create mode 100644 writable/session/ci_session21il06tdjiknsaflvh2jj1n5gn0nl05r create mode 100644 writable/session/ci_session2anlt5spjqll2ga0kuakv3tu8tg0hibh create mode 100644 writable/session/ci_session2bjf76r4i7880s2v8fi1pvof0lcpqd8o create mode 100644 writable/session/ci_session2ekmsiujl42b4n0fqu3pvocg71esiln3 create mode 100644 writable/session/ci_session2lbih2ll21355h314u919lr4se5d5ufe create mode 100644 writable/session/ci_session2lcjvscemjcfp6bla4kjl2i5geucn6n3 create mode 100644 writable/session/ci_session2mb3s28kridq52snfpi06pli1abhclik create mode 100644 writable/session/ci_session3fau6aabcuvl1d05ie3deaktmdfhmgak create mode 100644 writable/session/ci_session3j3f5ikcmthmrn1jrqsft5knld9urucs create mode 100644 writable/session/ci_session3jq12qmd9i0e5bghk0es1reso1jgre2n create mode 100644 writable/session/ci_session3pra6oan9gts4gbombtfolh8hf0v9i04 create mode 100644 writable/session/ci_session3sdhav4eqqcjkpa3c1ong9avqsim5fn3 create mode 100644 writable/session/ci_session3su5tf1vvebs7m0ti71vc2mhkk5vpbks create mode 100644 writable/session/ci_session45tojjlt5gcu930qv8r982po7onkfc3n create mode 100644 writable/session/ci_session45vibugm4n5dlc8vigi4gclpne6tnm2g create mode 100644 writable/session/ci_session474ka2vlqficlead0pi4rgug8cqhpbfa create mode 100644 writable/session/ci_session47b84n02plfomcht0uh6eemm0p1ellc5 create mode 100644 writable/session/ci_session4a44v87b1bn510mesrc4tac3e19e3g5l create mode 100644 writable/session/ci_session4he0br81kjkb4it00k8kf3m3ht65eb9n create mode 100644 writable/session/ci_session4i89ai8g9lv8btqq8lui8ji2fpup1dhm create mode 100644 writable/session/ci_session4up09sdoq2a61qe6hepcvg8mregepr4a create mode 100644 writable/session/ci_session59uu6e4b8l0vkrto5mcguldpvcadhbit create mode 100644 writable/session/ci_session5emqdiovemci4cspj00ipl3iapc8ebac create mode 100644 writable/session/ci_session5fhga8elirpscb68j0q1lgecd0qsmudm create mode 100644 writable/session/ci_session5kclo7leht8cgngcu95equ6s03lkbcio create mode 100644 writable/session/ci_session5otislqsvcule34gr7n9obiel43737h4 create mode 100644 writable/session/ci_session5ph2muil3v0815cqqaq58cnqvsjns4vl create mode 100644 writable/session/ci_session61sbr15tubctuguv5a62lv87ct4piioh create mode 100644 writable/session/ci_session646j64r0cja7jqvav1s58fvpk2j4ep95 create mode 100644 writable/session/ci_session64pgpq7jes17uq4odeulr5k5vnpm79sk create mode 100644 writable/session/ci_session6ktchjbodu0q97ptchkmddkj2onbr3np create mode 100644 writable/session/ci_session6lo33p15f97q8b6q7a90t54qgj2qrdmr create mode 100644 writable/session/ci_session6okm3maao8i74kcsr3j5uit38jplste9 create mode 100644 writable/session/ci_session6q2o5lr03kjl9jadrmhssa67cfbibcu8 create mode 100644 writable/session/ci_session6s02cphd7k56pjrskek5hjsn4nmr6msu create mode 100644 writable/session/ci_session6u95ht2pgbl2t333rrb40pt6pipjd5dd create mode 100644 writable/session/ci_session72mi8f39d8bdh1fkfkvcp3t0p6mikg1k create mode 100644 writable/session/ci_session778fe271efhqq5r5d95gkh4dmq6o47qh create mode 100644 writable/session/ci_session7s9koloiufpq5sn07annpm0jih1u73k2 create mode 100644 writable/session/ci_session7tj423ntne3h443ocq5nc0vldedo284q create mode 100644 writable/session/ci_session8cbhiv06ciaes1aki05dtvvmjtft4n76 create mode 100644 writable/session/ci_session8fpt7srj018i999r6c5shvp1n6iq6lqj create mode 100644 writable/session/ci_session8lg75nnjgp8sqiihvl9pda8pscan178l create mode 100644 writable/session/ci_session8n3aqdonc1rcs0v3mi7usr69u0sqqf6l create mode 100644 writable/session/ci_session8vpll4c9lpr2a4bbvm2psr0a1k6mona1 create mode 100644 writable/session/ci_session92t5d9i2mkk98artlc7575gsi5lh9v1q create mode 100644 writable/session/ci_session93ofqbjphe8dtmhed6s917ic91u8pi80 create mode 100644 writable/session/ci_session940l3k8p856gtsj9fggiiknphid1qe46 create mode 100644 writable/session/ci_session98i0arn4mbd1e0bvp1dfjtvf7n6qg3hi create mode 100644 writable/session/ci_session9cvjmf0kc10saikb3e7abl3i0br5bshp create mode 100644 writable/session/ci_session9n85e08iiemvag2pgikomqhc94plt5hg create mode 100644 writable/session/ci_session9qb5776d2nplv58j9h38el14q6cg6q58 create mode 100644 writable/session/ci_sessionac68krfans71fomm5fg1682kvo1jd6l2 create mode 100644 writable/session/ci_sessionae1l999fqji3rcpii8kd0fob42daik99 create mode 100644 writable/session/ci_sessionaes9ad5o4oau7cp4sdhfaavdngbkvqe6 create mode 100644 writable/session/ci_sessionaf3ocuh14ps3t1rckpf6sr460p3v9ln9 create mode 100644 writable/session/ci_sessionaig5qm3n2jrbe7c0j2rb4iups5csoenj create mode 100644 writable/session/ci_sessionapfuh9n2upp1u1i8ub83i749fva6lgfv create mode 100644 writable/session/ci_sessionas2fdl3eshnk0eakgndgcqshmcrp8qn6 create mode 100644 writable/session/ci_sessionasmgt9kiftf5rqmqkjs1fas6j8ojqqu9 create mode 100644 writable/session/ci_sessionatc38o656kesuf6mnm7418ulog4rs6bc create mode 100644 writable/session/ci_sessionauj12av2dj55j9ih0dn2b2f6b1qllnj6 create mode 100644 writable/session/ci_sessionavev1kdm9kp6f4q4faeru65ric2npjge create mode 100644 writable/session/ci_sessionavqa9m291sap04po6k6mvktpnus94h3p create mode 100644 writable/session/ci_sessionb69pc4df2gurgf392le3uc8djisqk07b create mode 100644 writable/session/ci_sessionbclnpnjud527fti9t5geunf1n8s7ppsg create mode 100644 writable/session/ci_sessionbhm7eunaoq2420d1ge17tfc5psns01m2 create mode 100644 writable/session/ci_sessionbmoas2h38298moa0v9rgp8ntnkd26dnb create mode 100644 writable/session/ci_sessionbo3rg9cvdmsh87cle6dnfafl6o5dkek9 create mode 100644 writable/session/ci_sessionbu1dgi93pgot640k3bsvgmkv5pcbbab7 create mode 100644 writable/session/ci_sessionc2v1n8ron574d6pujjr4h67moqkd7pbt create mode 100644 writable/session/ci_sessionc9ont924kmb8v5ja9sojjkh4d697n7ji create mode 100644 writable/session/ci_sessionchp2cbm8c9qkc4gtrp0ljpb5e1sg8soe create mode 100644 writable/session/ci_sessioncikio11mec5ncfg864adhmnl8gcl0a7h create mode 100644 writable/session/ci_sessioncrsif2p7c585n8i8er1nlr7a8rh5c0ta create mode 100644 writable/session/ci_sessioncvek4389hf8lggv21vcqbkn83unkd9cm create mode 100644 writable/session/ci_sessiond6r4507fdtnbnl6lhmdnnvo87rigm3lf create mode 100644 writable/session/ci_sessiond80an0rqlj2lfutffpj8f2g1mh8h8jt0 create mode 100644 writable/session/ci_sessiond8blsho945m6282kiamamgrk7ljm4t4c create mode 100644 writable/session/ci_sessiondgibd2aq4vm8aom3a5t7q7i478che9nq create mode 100644 writable/session/ci_sessiondj9f14p9c87c4seqncd7u3m6h9nt543v create mode 100644 writable/session/ci_sessiondjfmv0464tnkh02m31eip1mcqhp70oo5 create mode 100644 writable/session/ci_sessiondsnc3irs1jaijaqeomjsh8t91rou0bc9 create mode 100644 writable/session/ci_sessiondu89ejhkjs0teehk3nlj4fss13uu17s5 create mode 100644 writable/session/ci_sessione36qsn8d35ap90as82uf4rmshmdfnutq create mode 100644 writable/session/ci_sessione5fguno70i95i5ietl4sral7m1e6eti6 create mode 100644 writable/session/ci_sessione7aijevv9becv3aipp7m4f56ei5nbu3a create mode 100644 writable/session/ci_sessionec3secsh35ge1p61nlmo6a2m1mq6br2u create mode 100644 writable/session/ci_sessioneebb0kcon2tchhqtdssjocrfhdm2secg create mode 100644 writable/session/ci_sessionej123t6468ta98u03cf9cmsq8jivnuot create mode 100644 writable/session/ci_sessionev0860f2uke7qoe7phtf8m5pm93ii998 create mode 100644 writable/session/ci_sessionf7tj449jjtqb7fbobqoteccl4tmhie9a create mode 100644 writable/session/ci_sessionf8umabnpftjnp78h6kc61rq6fc0sur8k create mode 100644 writable/session/ci_sessionfbrq89ujc39grg04tdad43j0mspo3sru create mode 100644 writable/session/ci_sessionfbufoghthijvnmpcsdebrr5obie0d3vl create mode 100644 writable/session/ci_sessionfd8unj9mjtgtqn00kffcksju3vq8kk32 create mode 100644 writable/session/ci_sessionfl792n7lr0tsmfh4l7kg8m4b3rc0pim2 create mode 100644 writable/session/ci_sessionfmi49a6fnnepg9eq99hb28k0haqibl8h create mode 100644 writable/session/ci_sessiong9r3d2ih8r7qpfrh505m42a7nupmqd7j create mode 100644 writable/session/ci_sessionga8k14tjvksppap8o1f5g7klnnqep6n1 create mode 100644 writable/session/ci_sessiongo1ss8q1ge9s3eqqrndo8sp0jrtce8o1 create mode 100644 writable/session/ci_sessiongsb6ebqksp7lo8nivh5fdk1pnoclgib3 create mode 100644 writable/session/ci_sessionh5dvm4s2muqvrorjv4vsd2j38tvj0lb8 create mode 100644 writable/session/ci_sessionh6ku3qcj3u9k97g77224t9p4uq9n6ogb create mode 100644 writable/session/ci_sessionh90e3j80ruji7a44tqbfviapvkd0dpd0 create mode 100644 writable/session/ci_sessionhagvoqvbkn7birnp2a5r5k5lq5lrib6a create mode 100644 writable/session/ci_sessionherj0bjkmnqfdqfsuu3dnbggsvtfbj02 create mode 100644 writable/session/ci_sessionhk5hav81u2at4ed6qc4uqgq2ufakchi3 create mode 100644 writable/session/ci_sessionhnp4o1b64ec29lb633vqj949iaaqessc create mode 100644 writable/session/ci_sessionhqn74a26erh9pk2985o73eo5aiuo1tds create mode 100644 writable/session/ci_sessioni8tr3ova6dh5fffskcdfcrl29hj7488e create mode 100644 writable/session/ci_sessionihb4ovjcg1402q6pj283a29bh3eho00f create mode 100644 writable/session/ci_sessionilhngvti8cmvmivsr16qi2r28jsbu7fn create mode 100644 writable/session/ci_sessioniptcn09bbvu5sc9l5p2583gvuva55f2q create mode 100644 writable/session/ci_sessionj0ofb8ei3coae747ramem6jqnfet2s5r create mode 100644 writable/session/ci_sessionjbcflluvuc2eeeqtompantlqfsahgvn8 create mode 100644 writable/session/ci_sessionjdgos1svru55aidarnhusubqv2q800ii create mode 100644 writable/session/ci_sessionjj0vrojn98e7rb3dhe9ro94abmr95t5i create mode 100644 writable/session/ci_sessionjlj0flbime4tff9bl5toqslvupv21194 create mode 100644 writable/session/ci_sessionjph4lhe1amhgg0rpokrjqdkdateqag7q create mode 100644 writable/session/ci_sessionjqclq4v358j5u6c9i79aoqhluo62b8hv create mode 100644 writable/session/ci_sessionjqhpc7r9og0lr9ndcr928r4um7jat5ah create mode 100644 writable/session/ci_sessionjt1vkd49gsa09h70kpfj1uaq1eg59r3n create mode 100644 writable/session/ci_sessionkh5qtemgj39vcijnlafrol4hu5gg5tfe create mode 100644 writable/session/ci_sessionkmajs8u618ts2ja1503detbhej5o9o9l create mode 100644 writable/session/ci_sessionl6ogogjpjkeb2ta837mk7v63s4eb5fm1 create mode 100644 writable/session/ci_sessionl6ot90pv54k9o8tm1u110p19a36brsh4 create mode 100644 writable/session/ci_sessionl8tb6elilbleea8cin7d9t3g2lehmvbh create mode 100644 writable/session/ci_sessionlafvdf15ppsmcmkj8ogacte4sv5nmfp5 create mode 100644 writable/session/ci_sessionlcjqhcmegscuv5lkqoc2v1arb3q3jfq8 create mode 100644 writable/session/ci_sessionlfht6ij0159too3gpmejlidk6gdolpd9 create mode 100644 writable/session/ci_sessionlilrg2emsk0tf93lr0mv0i824pd943q6 create mode 100644 writable/session/ci_sessionlrkecrd2f1ag7uqcss1jnfjor4i9nd5p create mode 100644 writable/session/ci_sessionm4fp70du8ushpsbo5a14sgpa588rkids create mode 100644 writable/session/ci_sessionmbk2vnif1p2ee3ohr2bue9guk37u1lsg create mode 100644 writable/session/ci_sessionmibptl61qvu5l5ucii7pkmmfqtgtg73t create mode 100644 writable/session/ci_sessionmid2uj8al8pn1jsdstss7s5ste502473 create mode 100644 writable/session/ci_sessionmmiolheoljm9p9lakhbi326ifncirbhc create mode 100644 writable/session/ci_sessionmv1bci4vbvoer8114sf6bsmi61lsq78h create mode 100644 writable/session/ci_sessionn0m9ne59fip3gvpi2grap9auda82ua9o create mode 100644 writable/session/ci_sessionn38r4uqhg4iepulmv76k12vit28ln4lf create mode 100644 writable/session/ci_sessionn871kd0re4ff3jjggvobec1alkj1713b create mode 100644 writable/session/ci_sessionn9n1c4impv2lgvue3e79acg6gtlq7luu create mode 100644 writable/session/ci_sessionnag9ud6fa39nfo40tjtbh6po89u93jg0 create mode 100644 writable/session/ci_sessionnasa1l0mce9shkgfvguomr5poggnta0p create mode 100644 writable/session/ci_sessionnihherorn13m5ttapfe8msof4j18a83p create mode 100644 writable/session/ci_sessionnqucuns6buv1kdh9s8m6kgjerc3mj7nm create mode 100644 writable/session/ci_sessionobl47kj8e3mi47jni435u6arfk9tc0oe create mode 100644 writable/session/ci_sessionon9b2ht88n71uctpd9a82idvaku0l4q9 create mode 100644 writable/session/ci_sessionpcnvii6gumnjnqhcgorc0gqt40khb0o5 create mode 100644 writable/session/ci_sessionpu6e4pths82g3ptm3ops2he55hqq45jb create mode 100644 writable/session/ci_sessionq0pa7oih560jfe5020kb3dpai3g1fuuv create mode 100644 writable/session/ci_sessionq3p5rh7iqbtmr5ijfv3oma3e6td5h1iu create mode 100644 writable/session/ci_sessionq9jbtl49k2pvmlqkem60jd9dr70g0khs create mode 100644 writable/session/ci_sessionqekqmlh0eneq4i50b99ddknaa7jbmuig create mode 100644 writable/session/ci_sessionqh4qaj0hnqg4f4crgld7et2laikni6ns create mode 100644 writable/session/ci_sessionqk64fb3qqudoi04a8eisap4f0kv96he9 create mode 100644 writable/session/ci_sessionr89ujj0afqdf8s4jbvpceovfg46p9jgd create mode 100644 writable/session/ci_sessionrf9a7boc7v1ghvjlq239tj32nl8jnns6 create mode 100644 writable/session/ci_sessionrj27r0p3061o8lce1bfk96ek528cup5q create mode 100644 writable/session/ci_sessionrq949401hp65sn95i2ieuacjpm9u47pp create mode 100644 writable/session/ci_sessionrqfhca1pm9opjfite1si80a86l8b8rd5 create mode 100644 writable/session/ci_sessionrs9dcrcn05uk1afcjmf9jtvk2jgh1put create mode 100644 writable/session/ci_sessionsndiuqnp8gou46ukt2dldbqjnsqcelf9 create mode 100644 writable/session/ci_sessionsp82k4uau9jpgk06nteilq3f3gsa2f9e create mode 100644 writable/session/ci_sessionss45iaqbl9d07520eujiv2isaderdqe8 create mode 100644 writable/session/ci_sessionsvur5jhtm381lai4coas5i9rl09vdf11 create mode 100644 writable/session/ci_sessiont124voped9modag151tqhgjpgdbdtr77 create mode 100644 writable/session/ci_sessiont1bf5fsrlptko7t0d3o60n6glrq4hh70 create mode 100644 writable/session/ci_sessionthts800uk692vgkmk57o212i8nqjliak create mode 100644 writable/session/ci_sessiontjr2bh6d8bo45hftmgujb18gem4i5nf0 create mode 100644 writable/session/ci_sessiontksn9kluikr3ch2hohsue54t142ttp67 create mode 100644 writable/session/ci_sessiontlpandoce86cspvu5cu55e0qv21r7e58 create mode 100644 writable/session/ci_sessiontv0r3og19vithol967vtfrcevvh41994 create mode 100644 writable/session/ci_sessiontvq641raih981pd5efhf9uns6edff4of create mode 100644 writable/session/ci_sessionu10nlpvvd6dlv8j1tds0u6ochjb9jbem create mode 100644 writable/session/ci_sessionu2s9vv590311n0eicllh9pi2e6ia824q create mode 100644 writable/session/ci_sessionu45bt690jg562rga9rq5il68ml7ajus3 create mode 100644 writable/session/ci_sessionu7l363efl412ngdranlg05sm28hjje15 create mode 100644 writable/session/ci_sessionuk6gp7k9jic18ip5rjvta2425imm87rm create mode 100644 writable/session/ci_sessionumiak3lkmjun7273jvcckgn4jv8onb9g create mode 100644 writable/session/ci_sessionupnradcpfqmgpsauc8p388qvqibpbeve create mode 100644 writable/session/ci_sessionurs00qtmmq5egndc5dqo2pa5q7ig9r9s create mode 100644 writable/session/ci_sessionusf50ol7vsbqc0tebsa2thfgufoqci2l create mode 100644 writable/session/ci_sessionut0evbo4kto9396gh29e6t4e09beandt create mode 100644 writable/session/ci_sessionv2kidk27grj07lg75o1a25vlenpe11n0 create mode 100644 writable/session/ci_sessionvc06rh4ko4jue36ml4fqhqncf400b17d create mode 100644 writable/session/index.html create mode 100644 writable/uploads/index.html diff --git a/.env b/.env new file mode 100644 index 0000000..0f21ccf --- /dev/null +++ b/.env @@ -0,0 +1,101 @@ +#-------------------------------------------------------------------- +# Example Environment Configuration file +# +# This file can be used as a starting point for your own +# custom .env files, and contains most of the possible settings +# available in a default install. +# +# By default, all of the settings are commented out. If you want +# to override the setting, you must un-comment it by removing the '#' +# at the beginning of the line. +#-------------------------------------------------------------------- + +#-------------------------------------------------------------------- +# ENVIRONMENT +#-------------------------------------------------------------------- + + CI_ENVIRONMENT = development + +#-------------------------------------------------------------------- +# APP +#-------------------------------------------------------------------- + + app.baseURL = 'http://localhost/donation/' +# app.forceGlobalSecureRequests = false + +# app.sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler' +# app.sessionCookieName = 'ci_session' +# app.sessionSavePath = NULL +# app.sessionMatchIP = false +# app.sessionTimeToUpdate = 300 +# app.sessionRegenerateDestroy = false + +# app.cookiePrefix = '' +# app.cookieDomain = '' +# app.cookiePath = '/' +# app.cookieSecure = false +# app.cookieHTTPOnly = false + +# app.CSRFProtection = false +# app.CSRFTokenName = 'csrf_test_name' +# app.CSRFCookieName = 'csrf_cookie_name' +# app.CSRFExpire = 7200 +# app.CSRFRegenerate = true +# app.CSRFExcludeURIs = [] + +# app.CSPEnabled = false + +#-------------------------------------------------------------------- +# DATABASE +#-------------------------------------------------------------------- + + database.default.hostname = localhost + database.default.database = donation + database.default.username = root + database.default.password = + database.default.DBDriver = MySQLi + +# database.tests.hostname = localhost +# database.tests.database = ci4 +# database.tests.username = root +# database.tests.password = root +# database.tests.DBDriver = MySQLi + +#-------------------------------------------------------------------- +# CONTENT SECURITY POLICY +#-------------------------------------------------------------------- + +# contentsecuritypolicy.reportOnly = false +# contentsecuritypolicy.defaultSrc = 'none' +# contentsecuritypolicy.scriptSrc = 'self' +# contentsecuritypolicy.styleSrc = 'self' +# contentsecuritypolicy.imageSrc = 'self' +# contentsecuritypolicy.base_uri = null +# contentsecuritypolicy.childSrc = null +# contentsecuritypolicy.connectSrc = 'self' +# contentsecuritypolicy.fontSrc = null +# contentsecuritypolicy.formAction = null +# contentsecuritypolicy.frameAncestors = null +# contentsecuritypolicy.mediaSrc = null +# contentsecuritypolicy.objectSrc = null +# contentsecuritypolicy.pluginTypes = null +# contentsecuritypolicy.reportURI = null +# contentsecuritypolicy.sandbox = false +# contentsecuritypolicy.upgradeInsecureRequests = false + +#-------------------------------------------------------------------- +# ENCRYPTION +#-------------------------------------------------------------------- + +# encryption.key = +# encryption.driver = OpenSSL + +#-------------------------------------------------------------------- +# HONEYPOT +#-------------------------------------------------------------------- + +# honeypot.hidden = 'true' +# honeypot.label = 'Fill This Field' +# honeypot.name = 'honeypot' +# honeypot.template = '' +# honeypot.container = '
{template}
' diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..1e647e0 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,51 @@ +name: PHPUnit + +on: + pull_request: + branches: + - develop + +jobs: + main: + name: Build and test + + strategy: + matrix: + php-versions: ['7.2', '7.3', '7.4'] + + runs-on: ubuntu-latest + + if: "!contains(github.event.head_commit.message, '[ci skip]')" + + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Setup PHP, with composer and extensions + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php-versions }} + tools: composer, pecl, phpunit + extensions: intl, json, mbstring, mysqlnd, xdebug, xml, sqlite3 + coverage: xdebug + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install dependencies + run: composer install --no-progress --no-suggest --no-interaction --prefer-dist --optimize-autoloader + # To prevent rate limiting you may need to supply an OAuth token in Settings > Secrets + # env: + # https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens + # COMPOSER_AUTH: ${{ secrets.COMPOSER_AUTH }} + + - name: Test with phpunit + run: vendor/bin/phpunit --coverage-text diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..02026a3 --- /dev/null +++ b/.htaccess @@ -0,0 +1,48 @@ +# Disable directory browsing +Options All -Indexes + +# ---------------------------------------------------------------------- +# Rewrite engine +# ---------------------------------------------------------------------- + +# Turning on the rewrite engine is necessary for the following rules and features. +# FollowSymLinks must be enabled for this to work. + + Options +FollowSymlinks + RewriteEngine On + + # If you installed CodeIgniter in a subfolder, you will need to + # change the following line to match the subfolder you need. + # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase + # RewriteBase / + + # Redirect Trailing Slashes... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)/$ /$1 [L,R=301] + + # Rewrite "www.example.com -> example.com" + RewriteCond %{HTTPS} !=on + RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] + RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] + + # Checks to see if the user is attempting to access a valid file, + # such as an image or css document, if this isn't true it sends the + # request to the front controller, index.php + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA] + + # Ensure Authorization header is passed along + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + + + # If we don't have mod_rewrite installed, all 404's + # can be sent to index.php, and everything works as normal. + ErrorDocument 404 index.php + + +# Disable server signature start + ServerSignature Off +# Disable server signature end diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c20eb1 --- /dev/null +++ b/README.md @@ -0,0 +1,64 @@ +# CodeIgniter 4 Application Starter + +## What is CodeIgniter? + +CodeIgniter is a PHP full-stack web framework that is light, fast, flexible, and secure. +More information can be found at the [official site](http://codeigniter.com). + +This repository holds a composer-installable app starter. +It has been built from the +[development repository](https://github.com/codeigniter4/CodeIgniter4). + +More information about the plans for version 4 can be found in [the announcement](http://forum.codeigniter.com/thread-62615.html) on the forums. + +The user guide corresponding to this version of the framework can be found +[here](https://codeigniter4.github.io/userguide/). + +## Installation & updates + +`composer create-project codeigniter4/appstarter` then `composer update` whenever +there is a new release of the framework. + +When updating, check the release notes to see if there are any changes you might need to apply +to your `app` folder. The affected files can be copied or merged from +`vendor/codeigniter4/framework/app`. + +## Setup + +Copy `env` to `.env` and tailor for your app, specifically the baseURL +and any database settings. + +## Important Change with index.php + +`index.php` is no longer in the root of the project! It has been moved inside the *public* folder, +for better security and separation of components. + +This means that you should configure your web server to "point" to your project's *public* folder, and +not to the project root. A better practice would be to configure a virtual host to point there. A poor practice would be to point your web server to the project root and expect to enter *public/...*, as the rest of your logic and the +framework are exposed. + +**Please** read the user guide for a better explanation of how CI4 works! +The user guide updating and deployment is a bit awkward at the moment, but we are working on it! + +## Repository Management + +We use Github issues, in our main repository, to track **BUGS** and to track approved **DEVELOPMENT** work packages. +We use our [forum](http://forum.codeigniter.com) to provide SUPPORT and to discuss +FEATURE REQUESTS. + +This repository is a "distribution" one, built by our release preparation script. +Problems with it can be raised on our forum, or as issues in the main repository. + +## Server Requirements + +PHP version 7.2 or higher is required, with the following extensions installed: + +- [intl](http://php.net/manual/en/intl.requirements.php) +- [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library + +Additionally, make sure that the following extensions are enabled in your PHP: + +- json (enabled by default - don't turn it off) +- [mbstring](http://php.net/manual/en/mbstring.installation.php) +- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) +- xml (enabled by default - don't turn it off) diff --git a/app/.htaccess b/app/.htaccess new file mode 100644 index 0000000..f24db0a --- /dev/null +++ b/app/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + diff --git a/app/Common.php b/app/Common.php new file mode 100644 index 0000000..780ba3f --- /dev/null +++ b/app/Common.php @@ -0,0 +1,15 @@ + SYSTEMPATH, + * 'App' => APPPATH + * ]; + * + * @var array + */ + public $psr4 = [ + APP_NAMESPACE => APPPATH, // For custom app namespace + 'Config' => APPPATH . 'Config', + 'Dompdf' => APPPATH . 'ThirdParty/dompdf/src', + ]; + + + /** + * ------------------------------------------------------------------- + * Class Map + * ------------------------------------------------------------------- + * The class map provides a map of class names and their exact + * location on the drive. Classes loaded in this manner will have + * slightly faster performance because they will not have to be + * searched for within one or more directories as they would if they + * were being autoloaded through a namespace. + * + * Prototype: + * + * $classmap = [ + * 'MyClass' => '/path/to/class/file.php' + * ]; + * + * @var array + */ + public $classmap = []; +} diff --git a/app/Config/Boot/development.php b/app/Config/Boot/development.php new file mode 100644 index 0000000..63fdd88 --- /dev/null +++ b/app/Config/Boot/development.php @@ -0,0 +1,32 @@ + '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, + ]; + + /* + | ------------------------------------------------------------------------- + | Redis settings + | ------------------------------------------------------------------------- + | Your Redis server can be specified below, if you are using + | the Redis or Predis drivers. + | + */ + public $redis = [ + 'host' => '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, + ]; + + /* + |-------------------------------------------------------------------------- + | Available Cache Handlers + |-------------------------------------------------------------------------- + | + | This is an array of cache engine alias' and class names. Only engines + | that are listed here are allowed to be used. + | + */ + public $validHandlers = [ + 'dummy' => \CodeIgniter\Cache\Handlers\DummyHandler::class, + 'file' => \CodeIgniter\Cache\Handlers\FileHandler::class, + 'memcached' => \CodeIgniter\Cache\Handlers\MemcachedHandler::class, + 'predis' => \CodeIgniter\Cache\Handlers\PredisHandler::class, + 'redis' => \CodeIgniter\Cache\Handlers\RedisHandler::class, + 'wincache' => \CodeIgniter\Cache\Handlers\WincacheHandler::class, + ]; +} diff --git a/app/Config/Constants.php b/app/Config/Constants.php new file mode 100644 index 0000000..b25f71c --- /dev/null +++ b/app/Config/Constants.php @@ -0,0 +1,77 @@ + '', + 'hostname' => 'localhost', + 'username' => '', + 'password' => '', + 'database' => '', + 'DBDriver' => 'MySQLi', + 'DBPrefix' => '', + 'pConnect' => false, + 'DBDebug' => (ENVIRONMENT !== 'production'), + 'cacheOn' => false, + 'cacheDir' => '', + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + 'port' => 3306, + ]; + + /** + * This database connection is used when + * running PHPUnit database tests. + * + * @var array + */ + public $tests = [ + 'DSN' => '', + 'hostname' => '127.0.0.1', + 'username' => '', + 'password' => '', + 'database' => ':memory:', + 'DBDriver' => 'SQLite3', + 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS + 'pConnect' => false, + 'DBDebug' => (ENVIRONMENT !== 'production'), + 'cacheOn' => false, + 'cacheDir' => '', + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + 'port' => 3306, + ]; + + //-------------------------------------------------------------------- + + public function __construct() + { + parent::__construct(); + + // Ensure that we always set the database group to 'tests' if + // we are currently running an automated test suite, so that + // we don't overwrite live data on accident. + if (ENVIRONMENT === 'testing') + { + $this->defaultGroup = 'tests'; + + // Under Travis-CI, we can set an ENV var named 'DB_GROUP' + // so that we can test against multiple databases. + if ($group = getenv('DB')) + { + if (is_file(TESTPATH . 'travis/Database.php')) + { + require TESTPATH . 'travis/Database.php'; + + if (! empty($dbconfig) && array_key_exists($group, $dbconfig)) + { + $this->tests = $dbconfig[$group]; + } + } + } + } + } + + //-------------------------------------------------------------------- + +} diff --git a/app/Config/DocTypes.php b/app/Config/DocTypes.php new file mode 100644 index 0000000..67d5dd2 --- /dev/null +++ b/app/Config/DocTypes.php @@ -0,0 +1,33 @@ + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'xhtml-basic11' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '', + 'mathml1' => '', + 'mathml2' => '', + 'svg10' => '', + 'svg11' => '', + 'svg11-basic' => '', + 'svg11-tiny' => '', + 'xhtml-math-svg-xh' => '', + 'xhtml-math-svg-sh' => '', + 'xhtml-rdfa-1' => '', + 'xhtml-rdfa-2' => '', + ]; +} diff --git a/app/Config/Email.php b/app/Config/Email.php new file mode 100644 index 0000000..d9ca142 --- /dev/null +++ b/app/Config/Email.php @@ -0,0 +1,171 @@ + 0) + { + ob_end_flush(); + } + + ob_start(function ($buffer) { + return $buffer; + }); + } + + /* + * -------------------------------------------------------------------- + * Debug Toolbar Listeners. + * -------------------------------------------------------------------- + * If you delete, they will no longer be collected. + */ + if (ENVIRONMENT !== 'production') + { + Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); + Services::toolbar()->respond(); + } +}); diff --git a/app/Config/Exceptions.php b/app/Config/Exceptions.php new file mode 100644 index 0000000..5fe33d3 --- /dev/null +++ b/app/Config/Exceptions.php @@ -0,0 +1,42 @@ + \CodeIgniter\Filters\CSRF::class, + 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, + 'honeypot' => \CodeIgniter\Filters\Honeypot::class, + ]; + + // Always applied before every request + public $globals = [ + 'before' => [ + //'honeypot' + // 'csrf', + ], + 'after' => [ + 'toolbar', + //'honeypot' + ], + ]; + + // Works on all of a particular HTTP method + // (GET, POST, etc) as BEFORE filters only + // like: 'post' => ['CSRF', 'throttle'], + public $methods = []; + + // List filter aliases and any before/after uri patterns + // that they should run on, like: + // 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']], + public $filters = []; +} diff --git a/app/Config/ForeignCharacters.php b/app/Config/ForeignCharacters.php new file mode 100644 index 0000000..8ee6f11 --- /dev/null +++ b/app/Config/ForeignCharacters.php @@ -0,0 +1,6 @@ + \CodeIgniter\Format\JSONFormatter::class, + 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, + 'text/xml' => \CodeIgniter\Format\XMLFormatter::class, + ]; + + /* + |-------------------------------------------------------------------------- + | Formatters Options + |-------------------------------------------------------------------------- + | + | Additional Options to adjust default formatters behaviour. + | For each mime type, list the additional options that should be used. + | + */ + public $formatterOptions = [ + 'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, + 'application/xml' => 0, + 'text/xml' => 0, + ]; + //-------------------------------------------------------------------- + + /** + * A Factory method to return the appropriate formatter for the given mime type. + * + * @param string $mime + * + * @return \CodeIgniter\Format\FormatterInterface + */ + public function getFormatter(string $mime) + { + if (! array_key_exists($mime, $this->formatters)) + { + throw new \InvalidArgumentException('No Formatter defined for mime type: ' . $mime); + } + + $class = $this->formatters[$mime]; + + if (! class_exists($class)) + { + throw new \BadMethodCallException($class . ' is not a valid Formatter.'); + } + + return new $class(); + } + + //-------------------------------------------------------------------- + +} diff --git a/app/Config/Honeypot.php b/app/Config/Honeypot.php new file mode 100644 index 0000000..3d9e372 --- /dev/null +++ b/app/Config/Honeypot.php @@ -0,0 +1,42 @@ +{label}'; + + /** + * Honeypot container + * + * @var string + */ + public $container = '
{template}
'; +} diff --git a/app/Config/Images.php b/app/Config/Images.php new file mode 100644 index 0000000..a416b8b --- /dev/null +++ b/app/Config/Images.php @@ -0,0 +1,31 @@ + \CodeIgniter\Images\Handlers\GDHandler::class, + 'imagick' => \CodeIgniter\Images\Handlers\ImageMagickHandler::class, + ]; +} diff --git a/app/Config/Kint.php b/app/Config/Kint.php new file mode 100644 index 0000000..09db83d --- /dev/null +++ b/app/Config/Kint.php @@ -0,0 +1,62 @@ + [ + + /* + * The log levels that this handler will handle. + */ + 'handles' => [ + 'critical', + 'alert', + 'emergency', + 'debug', + 'error', + 'info', + 'notice', + 'warning', + ], + + /* + * The default filename extension for log files. + * An extension of 'php' allows for protecting the log files via basic + * scripting, when they are to be stored under a publicly accessible directory. + * + * Note: Leaving it blank will default to 'log'. + */ + 'fileExtension' => '', + + /* + * The file system permissions to be applied on newly created log files. + * + * IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal + * integer notation (i.e. 0700, 0644, etc.) + */ + 'filePermissions' => 0644, + + /* + * Logging Directory Path + * + * By default, logs are written to WRITEPATH . 'logs/' + * Specify a different destination here, if desired. + */ + 'path' => '', + ], + + /** + * The ChromeLoggerHandler requires the use of the Chrome web browser + * and the ChromeLogger extension. Uncomment this block to use it. + */ + // 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [ + // /* + // * The log levels that this handler will handle. + // */ + // 'handles' => ['critical', 'alert', 'emergency', 'debug', + // 'error', 'info', 'notice', 'warning'], + // ] + ]; +} diff --git a/app/Config/Migrations.php b/app/Config/Migrations.php new file mode 100644 index 0000000..b83fe90 --- /dev/null +++ b/app/Config/Migrations.php @@ -0,0 +1,50 @@ + php spark migrate:create + | + | Typical formats: + | YmdHis_ + | Y-m-d-His_ + | Y_m_d_His_ + | + */ + public $timestampFormat = 'Y-m-d-His_'; + +} diff --git a/app/Config/Mimes.php b/app/Config/Mimes.php new file mode 100644 index 0000000..41014d4 --- /dev/null +++ b/app/Config/Mimes.php @@ -0,0 +1,530 @@ + [ + 'application/mac-binhex40', + 'application/mac-binhex', + 'application/x-binhex40', + 'application/x-mac-binhex40', + ], + 'cpt' => 'application/mac-compactpro', + 'csv' => [ + 'text/csv', + 'text/x-comma-separated-values', + 'text/comma-separated-values', + 'application/octet-stream', + 'application/vnd.ms-excel', + 'application/x-csv', + 'text/x-csv', + 'application/csv', + 'application/excel', + 'application/vnd.msexcel', + 'text/plain', + ], + 'bin' => [ + 'application/macbinary', + 'application/mac-binary', + 'application/octet-stream', + 'application/x-binary', + 'application/x-macbinary', + ], + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => [ + 'application/octet-stream', + 'application/x-msdownload', + ], + 'class' => 'application/octet-stream', + 'psd' => [ + 'application/x-photoshop', + 'image/vnd.adobe.photoshop', + ], + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => [ + 'application/pdf', + 'application/force-download', + 'application/x-download', + 'binary/octet-stream', + ], + 'ai' => [ + 'application/pdf', + 'application/postscript', + ], + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => [ + 'application/vnd.ms-excel', + 'application/msexcel', + 'application/x-msexcel', + 'application/x-ms-excel', + 'application/x-excel', + 'application/x-dos_ms_excel', + 'application/xls', + 'application/x-xls', + 'application/excel', + 'application/download', + 'application/vnd.ms-office', + 'application/msword', + ], + 'ppt' => [ + 'application/vnd.ms-powerpoint', + 'application/powerpoint', + 'application/vnd.ms-office', + 'application/msword', + ], + 'pptx' => [ + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/x-zip', + 'application/zip', + ], + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => [ + 'application/x-php', + 'application/x-httpd-php', + 'application/php', + 'text/php', + 'text/x-php', + 'application/x-httpd-php-source', + ], + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => [ + 'application/x-javascript', + 'text/plain', + ], + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => [ + 'application/x-tar', + 'application/x-gzip-compressed', + ], + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => [ + 'application/x-zip', + 'application/zip', + 'application/x-zip-compressed', + 'application/s-compressed', + 'multipart/x-zip', + ], + 'rar' => [ + 'application/x-rar', + 'application/rar', + 'application/x-rar-compressed', + ], + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => [ + 'audio/mpeg', + 'audio/mpg', + 'audio/mpeg3', + 'audio/mp3', + ], + 'aif' => [ + 'audio/x-aiff', + 'audio/aiff', + ], + 'aiff' => [ + 'audio/x-aiff', + 'audio/aiff', + ], + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => [ + 'audio/x-wav', + 'audio/wave', + 'audio/wav', + ], + 'bmp' => [ + 'image/bmp', + 'image/x-bmp', + 'image/x-bitmap', + 'image/x-xbitmap', + 'image/x-win-bitmap', + 'image/x-windows-bmp', + 'image/ms-bmp', + 'image/x-ms-bmp', + 'application/bmp', + 'application/x-bmp', + 'application/x-win-bitmap', + ], + 'gif' => 'image/gif', + 'jpg' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jpeg' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jpe' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jp2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'j2k' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpf' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpg2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpx' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpm' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'mj2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'mjp2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'png' => [ + 'image/png', + 'image/x-png', + ], + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'css' => [ + 'text/css', + 'text/plain', + ], + 'html' => [ + 'text/html', + 'text/plain', + ], + 'htm' => [ + 'text/html', + 'text/plain', + ], + 'shtml' => [ + 'text/html', + 'text/plain', + ], + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => [ + 'text/plain', + 'text/x-log', + ], + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => [ + 'application/xml', + 'text/xml', + 'text/plain', + ], + 'xsl' => [ + 'application/xml', + 'text/xsl', + 'text/xml', + ], + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => [ + 'video/x-msvideo', + 'video/msvideo', + 'video/avi', + 'application/x-troff-msvideo', + ], + 'movie' => 'video/x-sgi-movie', + 'doc' => [ + 'application/msword', + 'application/vnd.ms-office', + ], + 'docx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + 'application/x-zip', + ], + 'dot' => [ + 'application/msword', + 'application/vnd.ms-office', + ], + 'dotx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + ], + 'xlsx' => [ + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/zip', + 'application/vnd.ms-excel', + 'application/msword', + 'application/x-zip', + ], + 'word' => [ + 'application/msword', + 'application/octet-stream', + ], + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => [ + 'application/json', + 'text/json', + ], + 'pem' => [ + 'application/x-x509-user-cert', + 'application/x-pem-file', + 'application/octet-stream', + ], + 'p10' => [ + 'application/x-pkcs10', + 'application/pkcs10', + ], + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => [ + 'application/pkcs7-mime', + 'application/x-pkcs7-mime', + ], + 'p7m' => [ + 'application/pkcs7-mime', + 'application/x-pkcs7-mime', + ], + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => [ + 'application/x-x509-ca-cert', + 'application/x-x509-user-cert', + 'application/pkix-cert', + ], + 'crl' => [ + 'application/pkix-crl', + 'application/pkcs-crl', + ], + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => [ + 'application/pkix-cert', + 'application/x-x509-ca-cert', + ], + '3g2' => 'video/3gpp2', + '3gp' => [ + 'video/3gp', + 'video/3gpp', + ], + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => [ + 'video/mp4', + 'video/x-f4v', + ], + 'flv' => 'video/x-flv', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => [ + 'video/x-ms-wmv', + 'video/x-ms-asf', + ], + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => [ + 'audio/ogg', + 'video/ogg', + 'application/ogg', + ], + 'kmz' => [ + 'application/vnd.google-earth.kmz', + 'application/zip', + 'application/x-zip', + ], + 'kml' => [ + 'application/vnd.google-earth.kml+xml', + 'application/xml', + 'text/xml', + ], + 'ics' => 'text/calendar', + 'ical' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7zip' => [ + 'application/x-compressed', + 'application/x-zip-compressed', + 'application/zip', + 'multipart/x-zip', + ], + 'cdr' => [ + 'application/cdr', + 'application/coreldraw', + 'application/x-cdr', + 'application/x-coreldraw', + 'image/cdr', + 'image/x-cdr', + 'zz-application/zz-winassoc-cdr', + ], + 'wma' => [ + 'audio/x-ms-wma', + 'video/x-ms-asf', + ], + 'jar' => [ + 'application/java-archive', + 'application/x-java-application', + 'application/x-jar', + 'application/x-compressed', + ], + 'svg' => [ + 'image/svg+xml', + 'application/xml', + 'text/xml', + ], + 'vcf' => 'text/x-vcard', + 'srt' => [ + 'text/srt', + 'text/plain', + ], + 'vtt' => [ + 'text/vtt', + 'text/plain', + ], + 'ico' => [ + 'image/x-icon', + 'image/x-ico', + 'image/vnd.microsoft.icon', + ], + ]; + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the best mime type for the given file extension. + * + * @param string $extension + * + * @return string|null The mime type found, or none if unable to determine. + */ + public static function guessTypeFromExtension(string $extension) + { + $extension = trim(strtolower($extension), '. '); + + if (! array_key_exists($extension, static::$mimes)) + { + return null; + } + + return is_array(static::$mimes[$extension]) ? static::$mimes[$extension][0] : static::$mimes[$extension]; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the best file extension for a given mime type. + * + * @param string $type + * @param string $proposed_extension - default extension (in case there is more than one with the same mime type) + * + * @return string|null The extension determined, or null if unable to match. + */ + public static function guessExtensionFromType(string $type, ?string $proposed_extension = null) + { + $type = trim(strtolower($type), '. '); + + $proposed_extension = trim(strtolower($proposed_extension)); + + if (! is_null($proposed_extension) && array_key_exists($proposed_extension, static::$mimes) && in_array($type, is_string(static::$mimes[$proposed_extension]) ? [static::$mimes[$proposed_extension]] : static::$mimes[$proposed_extension])) + { + return $proposed_extension; + } + + foreach (static::$mimes as $ext => $types) + { + if ((is_string($types) && $types === $type) || (is_array($types) && in_array($type, $types))) + { + return $ext; + } + } + + return null; + } + + //-------------------------------------------------------------------- + +} diff --git a/app/Config/Modules.php b/app/Config/Modules.php new file mode 100644 index 0000000..40cb987 --- /dev/null +++ b/app/Config/Modules.php @@ -0,0 +1,45 @@ + 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + 'default_head' => 'CodeIgniter\Pager\Views\default_head', + ]; + + /* + |-------------------------------------------------------------------------- + | Items Per Page + |-------------------------------------------------------------------------- + | + | The default number of results shown in a single page. + | + */ + public $perPage = 20; +} diff --git a/app/Config/Paths.php b/app/Config/Paths.php new file mode 100644 index 0000000..6251124 --- /dev/null +++ b/app/Config/Paths.php @@ -0,0 +1,77 @@ +setDefaultNamespace('App\Controllers'); +$routes->setDefaultController('Donor_controller'); +$routes->setDefaultMethod('index'); +$routes->setTranslateURIDashes(false); +$routes->set404Override(); +$routes->setAutoRoute(true); + +/** + * -------------------------------------------------------------------- + * Route Definitions + * -------------------------------------------------------------------- + */ + +// We get a performance increase by specifying the default +// route since we don't have to scan directories. +$routes->get('/', 'Donor_controller::index'); +$routes->match(['get','post'],'register','Donor_controller::register'); +$routes->match(['get','post'],'login','Donor_controller::login'); +$routes->match(['get'],'fetch_country','Donor_controller::fetch_country'); +$routes->match(['get','post'],'fetch_state','Donor_controller::fetch_state'); +$routes->match(['get','post'],'fetch_city','Donor_controller::fetch_city'); + +$routes->match(['get','post'],'receipt','Dashboard::generate_receipts'); +$routes->match(['get','post'],'transaction','Dashboard::transaction_upload'); +$routes->match(['get','post'],'donation_data','Dashboard::donation_data_upload'); +$routes->match(['get','post'],'donor_register','My_controller::donor_register'); + +$routes->match(['get'],'fetch_donor_id','Dashboard::fetch_donor_id'); +$routes->match(['get','post'],'add_donation_cause','Dashboard::add_donation_cause'); +// $routes->add('register','Donation::register'); +// $routes->add('list','Donation::edit_view'); +// $routes->add('store','Home::store'); + +/** + * -------------------------------------------------------------------- + * Additional Routing + * -------------------------------------------------------------------- + * + * There will often be times that you need additional routing and you + * need it to be able to override any defaults in this file. Environment + * based routes is one such time. require() additional route files here + * to make that happen. + * + * You will have access to the $routes object within that file without + * needing to reload it. + */ +if (file_exists(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) +{ + require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; +} diff --git a/app/Config/Services.php b/app/Config/Services.php new file mode 100644 index 0000000..c58da70 --- /dev/null +++ b/app/Config/Services.php @@ -0,0 +1,30 @@ + 'Windows 10', + 'windows nt 6.3' => 'Windows 8.1', + 'windows nt 6.2' => 'Windows 8', + 'windows nt 6.1' => 'Windows 7', + 'windows nt 6.0' => 'Windows Vista', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows phone' => 'Windows Phone', + 'windows' => 'Unknown Windows OS', + 'android' => 'Android', + 'blackberry' => 'BlackBerry', + 'iphone' => 'iOS', + 'ipad' => 'iOS', + 'ipod' => 'iOS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS', + 'symbian' => 'Symbian OS', + ]; + + // The order of this array should NOT be changed. Many browsers return + // multiple browser types so we want to identify the sub-type first. + public $browsers = [ + 'OPR' => 'Opera', + 'Flock' => 'Flock', + 'Edge' => 'Spartan', + 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string + 'Opera.*?Version' => 'Opera', + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Trident.* rv' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse', + 'Maxthon' => 'Maxthon', + 'Ubuntu' => 'Ubuntu Web Browser', + 'Vivaldi' => 'Vivaldi', + ]; + + public $mobiles = [ + // legacy array, old values commented out + 'mobileexplorer' => 'Mobile Explorer', + // 'openwave' => 'Open Wave', + // 'opera mini' => 'Opera Mini', + // 'operamini' => 'Opera Mini', + // 'elaine' => 'Palm', + 'palmsource' => 'Palm', + // 'digital paths' => 'Palm', + // 'avantgo' => 'Avantgo', + // 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', + // 'nokia' => 'Nokia', + // 'ericsson' => 'Ericsson', + // 'blackberry' => 'BlackBerry', + // 'motorola' => 'Motorola' + + // Phones and Manufacturers + 'motorola' => 'Motorola', + 'nokia' => 'Nokia', + 'palm' => 'Palm', + 'iphone' => 'Apple iPhone', + 'ipad' => 'iPad', + 'ipod' => 'Apple iPod Touch', + 'sony' => 'Sony Ericsson', + 'ericsson' => 'Sony Ericsson', + 'blackberry' => 'BlackBerry', + 'cocoon' => 'O2 Cocoon', + 'blazer' => 'Treo', + 'lg' => 'LG', + 'amoi' => 'Amoi', + 'xda' => 'XDA', + 'mda' => 'MDA', + 'vario' => 'Vario', + 'htc' => 'HTC', + 'samsung' => 'Samsung', + 'sharp' => 'Sharp', + 'sie-' => 'Siemens', + 'alcatel' => 'Alcatel', + 'benq' => 'BenQ', + 'ipaq' => 'HP iPaq', + 'mot-' => 'Motorola', + 'playstation portable' => 'PlayStation Portable', + 'playstation 3' => 'PlayStation 3', + 'playstation vita' => 'PlayStation Vita', + 'hiptop' => 'Danger Hiptop', + 'nec-' => 'NEC', + 'panasonic' => 'Panasonic', + 'philips' => 'Philips', + 'sagem' => 'Sagem', + 'sanyo' => 'Sanyo', + 'spv' => 'SPV', + 'zte' => 'ZTE', + 'sendo' => 'Sendo', + 'nintendo dsi' => 'Nintendo DSi', + 'nintendo ds' => 'Nintendo DS', + 'nintendo 3ds' => 'Nintendo 3DS', + 'wii' => 'Nintendo Wii', + 'open web' => 'Open Web', + 'openweb' => 'OpenWeb', + + // Operating Systems + 'android' => 'Android', + 'symbian' => 'Symbian', + 'SymbianOS' => 'SymbianOS', + 'elaine' => 'Palm', + 'series60' => 'Symbian S60', + 'windows ce' => 'Windows CE', + + // Browsers + 'obigo' => 'Obigo', + 'netfront' => 'Netfront Browser', + 'openwave' => 'Openwave Browser', + 'mobilexplorer' => 'Mobile Explorer', + 'operamini' => 'Opera Mini', + 'opera mini' => 'Opera Mini', + 'opera mobi' => 'Opera Mobile', + 'fennec' => 'Firefox Mobile', + + // Other + 'digital paths' => 'Digital Paths', + 'avantgo' => 'AvantGo', + 'xiino' => 'Xiino', + 'novarra' => 'Novarra Transcoder', + 'vodafone' => 'Vodafone', + 'docomo' => 'NTT DoCoMo', + 'o2' => 'O2', + + // Fallback + 'mobile' => 'Generic Mobile', + 'wireless' => 'Generic Mobile', + 'j2me' => 'Generic Mobile', + 'midp' => 'Generic Mobile', + 'cldc' => 'Generic Mobile', + 'up.link' => 'Generic Mobile', + 'up.browser' => 'Generic Mobile', + 'smartphone' => 'Generic Mobile', + 'cellphone' => 'Generic Mobile', + ]; + + // There are hundreds of bots but these are the most common. + public $robots = [ + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'baiduspider' => 'Baiduspider', + 'bingbot' => 'Bing', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'ask jeeves' => 'Ask Jeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos', + 'yandex' => 'YandexBot', + 'mediapartners-google' => 'MediaPartners Google', + 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', + 'adsbot-google' => 'AdsBot Google', + 'feedfetcher-google' => 'Feedfetcher Google', + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot', + ]; +} diff --git a/app/Config/Validation.php b/app/Config/Validation.php new file mode 100644 index 0000000..97f08c7 --- /dev/null +++ b/app/Config/Validation.php @@ -0,0 +1,36 @@ + 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + ]; + + //-------------------------------------------------------------------- + // Rules + //-------------------------------------------------------------------- +} diff --git a/app/Config/View.php b/app/Config/View.php new file mode 100644 index 0000000..f66b253 --- /dev/null +++ b/app/Config/View.php @@ -0,0 +1,34 @@ +session = \Config\Services::session(); + } + +} diff --git a/app/Controllers/Dashboard.php b/app/Controllers/Dashboard.php new file mode 100644 index 0000000..2791dc6 --- /dev/null +++ b/app/Controllers/Dashboard.php @@ -0,0 +1,293 @@ +dModel = new Dashboard_model(); + $this->rModel = new Receipt_model(); + $this->tModel = new Transaction_model(); + $this->ddModel = new Donation_data_model(); + $this->MyModel = new My_model(); + $this->dcModel = new Donation_cause(); + } + public function index() + { + + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + $name= session()->get('logged_user'); + $data['userdata']=$this->dModel->getLoggedInUserData($name); + echo view('templates/header',$data); + echo view('dashboard'); + echo view('templates/footer'); + } + public function logout() + { + session()->remove('logged_user'); + session()->destroy(); + return redirect()->to(base_url()); + } + public function receipts() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + $name= session()->get('logged_user'); + $data['donor']=$this->MyModel->fetch_donor_id(); + echo view('templates/header'); + echo view('receipts'); + echo view('templates/footer'); + } + function fetch_donor_id() + { + + echo $this->MyModel->fetch_donor_id(); + + } + + public function generate_receipts() + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Receipt_model(); + $receiptData=[ + 'receipt_no' =>$this->request->getVar('receipt_no'), + 'date' =>$this->request->getVar('date'), + 'donor_id' =>$this->request->getVar('donor_id'), + 'amount' =>$this->request->getVar('amount'), + 'mode_of_receipt' =>$this->request->getVar('mode_of_receipt'), + 'receipt_details' =>$this->request->getVar('receipt_details'), + 'cause_name' =>$this->request->getVar('cause_name'), + 'remarks' =>$this->request->getVar('remarks'), + + + ]; + $model->save($receiptData); + return redirect()->to(base_url().'/Dashboard'); + } + public function all_receipt() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + + $data['receiptdata']=$this->rModel->all_receipt(); + echo view('templates/header',$data); + echo view('receipts_table'); + echo view('templates/footer'); + } + + function edit_receipt($receipt_id) + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Receipt_model(); + $receipt_data=$model->find($receipt_id); + $data= [ 'post'=>$receipt_data ]; + + if($this->request->getMethod() == 'post') + { + $model = new Receipt_model(); + $_POST['receipt_id'] = $receipt_id; + $model->save($_POST); + return redirect()->to(base_url()."/Dashboard/all_receipt"); + } + echo view('templates/header',$data); + echo view('receipt_edit'); + echo view('templates/footer'); + + } + public function transaction() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + $name= session()->get('logged_user'); + //$data['userdata']=$this->dModel->getLoggedInUserData($name); + echo view('templates/header'); + echo view('transaction_upload'); + echo view('templates/footer'); + } + public function transaction_upload() + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Transaction_model(); + $transactionData=[ + 'date' =>$this->request->getVar('date'), + 'ref_1' =>$this->request->getVar('ref_1'), + 'ref_2' =>$this->request->getVar('ref_2'), + 'remarks' =>$this->request->getVar('remarks'), + 'amount' =>$this->request->getVar('amount'), + 'donation_ref' =>$this->request->getVar('donation_ref'), + + ]; + $model->save($transactionData); + return redirect()->to(base_url().'/Dashboard'); + } + public function all_transaction() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + + $data['receiptdata']=$this->tModel->all_transaction(); + echo view('templates/header',$data); + echo view('transaction_table'); + echo view('templates/footer'); + } + function edit_transaction($id) + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Transaction_model(); + $transaction_data=$model->find($id); + $data= [ 'post'=>$transaction_data ]; + + if($this->request->getMethod() == 'post') + { + $model = new Transaction_model(); + $_POST['id'] = $id; + $model->save($_POST); + return redirect()->to(base_url()."/Dashboard/all_transaction"); + } + echo view('templates/header',$data); + echo view('transaction_edit'); + echo view('templates/footer'); + + } + public function donation_data() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + $name= session()->get('logged_user'); + //$data['userdata']=$this->dModel->getLoggedInUserData($name); + echo view('templates/header'); + echo view('donation_data'); + echo view('templates/footer'); + } + public function donation_data_upload() + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Donation_data_model(); + $donationData=[ + 'date' =>$this->request->getVar('date'), + 'cause_name' =>$this->request->getVar('cause_name'), + 'amount' =>$this->request->getVar('amount'), + 'mode_of_payment' =>$this->request->getVar('mode_of_payment'), + 'ref_1' =>$this->request->getVar('ref_1'), + 'donation_ref' =>$this->request->getVar('donation_ref'), + + ]; + $model->save($donationData); + return redirect()->to(base_url().'/Dashboard'); + } + public function all_donation_data() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + + $data['donationdata']=$this->ddModel->all_donation_data(); + echo view('templates/header',$data); + echo view('donation_data_table'); + echo view('templates/footer'); + } + function edit_donation_data($id) + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Donation_data_model(); + $donation_data=$model->find($id); + $data= [ 'post'=>$donation_data ]; + + if($this->request->getMethod() == 'post') + { + $model = new Donation_data_model(); + $_POST['id'] = $id; + $model->save($_POST); + return redirect()->to(base_url()."/Dashboard/all_donation_data"); + } + echo view('templates/header',$data); + echo view('donation_data_edit'); + echo view('templates/footer'); + + } + public function donation_cause() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + $name= session()->get('logged_user'); + $data['donationcause']=$this->dcModel->all_donation_cause(); + echo view('templates/header',$data); + echo view('add_donation_cause'); + echo view('templates/footer'); + } + public function add_donation_cause() + { + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + $model = new Donation_cause(); + $donationCause=[ + + 'cause_name' =>$this->request->getVar('cause_name'), + 'from_date' =>$this->request->getVar('from_date'), + 'to_date' =>$this->request->getVar('to_date'), + + ]; + $model->save($donationCause); + return $this->donation_cause(); + + } +} \ No newline at end of file diff --git a/app/Controllers/Donation.php b/app/Controllers/Donation.php new file mode 100644 index 0000000..6ba5e60 --- /dev/null +++ b/app/Controllers/Donation.php @@ -0,0 +1,41 @@ +orderBy('id', 'DESC')->findAll(); + + return view('list', $data); + } + + public function test($type,$type2) + { + echo '

this is a product:'.$type.'and'.$type2.'

'; + //return view('show'); + } + public function register() + { + if($this->request->getMethod() == 'post'){ + $model = new Donation_model(); + $model->save($_POST); + } + return view('show'); + } + + + + + + //-------------------------------------------------------------------- + +} diff --git a/app/Controllers/Donor_controller.php b/app/Controllers/Donor_controller.php new file mode 100644 index 0000000..d853248 --- /dev/null +++ b/app/Controllers/Donor_controller.php @@ -0,0 +1,145 @@ +session = session(); + $this->Donor_model = new Donor_model(); + $this->Dashboard_model = new Dashboard_model(); + } + public function index() + { + $data=[]; + helper(['form']); + + if($this->request->getmethod() == 'post') + { + + $email = $this->request->getVar('email'); + $password = $this->request->getVar('password'); + $userdata = $this->Donor_model->verifyEmail($email); + if($userdata) + { + if(password_verify($password, $userdata['password'])) + { + + $this->session->set('logged_user',$userdata['id']); + return redirect()->to(base_url().'/Dashboard'); + } + else{ + $this->session->setTempdata('error','sorry wrong password entered for the Email',3); + return redirect()->to(current_url()); + } + }else + { + $this->session->setTempdata('error','sorry Email does not existe',3); + return redirect()->to(current_url()); + } + + + } + echo view('templates/header',$data); + echo view('login'); + echo view('templates/footer'); + //return view('donor_registration'); +} + + + + + public function register() + { + $data['country']=$this->Dashboard_model->fetch_country(); + helper(['form']); + + if($this->request->getmethod() == 'post') + { + // validate + $rules=[ + 'name' =>'required|min_length[3]|max_length[20]', + 'phone' =>'required|min_length[3]|max_length[20]', + 'email' =>'required|min_length[6]|max_length[50]|valid_email|is_unique[donar_management.email]', + 'pan' =>'required|min_length[3]|max_length[20]', + 'address' =>'required|min_length[3]|max_length[20]', + 'country' =>'required', + 'state' =>'required', + 'city' =>'required', + 'pin_code' =>'required|min_length[6]|max_length[6]', + 'date_of_birth' =>'required|min_length[3]|max_length[20]', + 'gender' =>'required|min_length[3]|max_length[20]', + 'org_name' =>'required|min_length[3]|max_length[20]', + 'gstin' =>'required|min_length[3]|max_length[20]', + 'password' =>'required|min_length[8]|max_length[200]', + 'password_confirm' =>'matches[password]', + ]; + + if(! $this->validate($rules)) + { + $data['validation'] = $this->validator; + }else{ + //store the donor in database + $model = new Donor_model(); + $donorData=[ + 'name' =>$this->request->getVar('name'), + 'phone' =>$this->request->getVar('phone'), + 'email' =>$this->request->getVar('email'), + 'pan' =>$this->request->getVar('pan'), + 'address' =>$this->request->getVar('address'), + 'country' =>$this->request->getVar('country'), + 'state' =>$this->request->getVar('state'), + 'city' =>$this->request->getVar('city'), + 'pin_code' =>$this->request->getVar('pin_code'), + 'date_of_birth' =>$this->request->getVar('date_of_birth'), + 'gender' =>$this->request->getVar('gender'), + 'org_name' =>$this->request->getVar('org_name'), + 'gstin' =>$this->request->getVar('gstin'), + 'foreign_key' =>$this->request->getVar('email'), + 'password' =>$this->request->getVar('password'), + + ]; + $model->save($donorData); + $session = session(); + $session ->setFlashdata('success','Successful Registration'); + return redirect()->to(base_url()); + } + } + + echo view('templates/header',$data); + echo view('register'); + echo view('templates/footer'); + + } + + function fetch_country() + { + + echo $this->Dashboard_model->fetch_country(); + + } + function fetch_state() + { + + if($this->request->getVar('country_id')) + { + echo $this->Dashboard_model->fetch_state($this->request->getVar('country_id')); + } + } + + function fetch_city() + { + if($this->request->getVar('state_id')) + { + echo $this->Dashboard_model->fetch_city($this->request->getVar('state_id')); + } + } + + + //-------------------------------------------------------------------- + +} diff --git a/app/Controllers/Home.php b/app/Controllers/Home.php new file mode 100644 index 0000000..b024394 --- /dev/null +++ b/app/Controllers/Home.php @@ -0,0 +1,81 @@ +test('7777','9999'); + // } + + public function store() + { + helper(['form', 'url']); + + $model = new Donation_model(); + + $data = [ + 'email' => $this->request->getVar('email'), + 'name' => $this->request->getVar('name'), + 'department' => $this->request->getVar('department'), + + ]; + + $save = $model->insert($data); + return redirect()->to( base_url('show') ); + } + + public function edit($id = null) + { + $model = new Donation_model(); + $post = $model->find($id); + $data=['post' => $post,]; + return view('edit_view', $data); + //return view('edit_view',['firstci4'=>$this->$model->find($id)]); + } + + public function update() + { + helper(['form', 'url']); + + $model = new Donation_model(); + + $id = $this->request->getVar('id'); + $data = [ + 'name' => $this->request->getVar('name'), + 'email' => $this->request->getVar('email'), + ]; + $save = $model->update($id,$data); + $donation = new Donation(); + echo $donation->edit_view(); + //return redirect()->to( base_url('users') ); + } + + public function userDelete($id = null) + { + $model = new Donation_model(); + $data['user'] = $model->where('id', $id)->delete(); + $donation = new Donation(); + echo $donation->edit_view(); + // return redirect()->to( base_url('users') ); + } + public function profile($id = null) + { + $model = new Donation_model(); + $post = $model->find($id); + $data=['post' => $post,]; + return view('profile_view', $data); + + } + + //-------------------------------------------------------------------- + +} diff --git a/app/Controllers/My_controller.php b/app/Controllers/My_controller.php new file mode 100644 index 0000000..1df7f27 --- /dev/null +++ b/app/Controllers/My_controller.php @@ -0,0 +1,141 @@ +session = session(); + $this->My_model = new My_model(); + $this->Dashboard_model = new Dashboard_model(); + } + + + + + + public function donor_register() + { + $data['country']=$this->Dashboard_model->fetch_country(); + helper(['form']); + + if($this->request->getmethod() == 'post') + { + // validate + $rules=[ + 'name' =>'required|min_length[3]|max_length[20]', + 'phone' =>'required|min_length[3]|max_length[20]', + 'email' =>'required|min_length[6]|max_length[50]|valid_email|is_unique[donar_management.email]', + 'pan' =>'required|min_length[3]|max_length[20]', + 'address' =>'required|min_length[3]|max_length[20]', + 'country' =>'required', + 'state' =>'required', + 'city' =>'required', + 'pin_code' =>'required|min_length[6]|max_length[6]', + 'date_of_birth' =>'required|min_length[3]|max_length[20]', + 'gender' =>'required|min_length[3]|max_length[20]', + 'org_name' =>'required|min_length[3]|max_length[20]', + 'gstin' =>'required|min_length[3]|max_length[20]', + + ]; + + if(! $this->validate($rules)) + { + $data['validation'] = $this->validator; + }else{ + //store the donor in database + $model = new My_model(); + $donorData=[ + 'name' =>$this->request->getVar('name'), + 'phone' =>$this->request->getVar('phone'), + 'email' =>$this->request->getVar('email'), + 'pan' =>$this->request->getVar('pan'), + 'address' =>$this->request->getVar('address'), + 'country' =>$this->request->getVar('country'), + 'state' =>$this->request->getVar('state'), + 'city' =>$this->request->getVar('city'), + 'pin_code' =>$this->request->getVar('pin_code'), + 'date_of_birth' =>$this->request->getVar('date_of_birth'), + 'gender' =>$this->request->getVar('gender'), + 'org_name' =>$this->request->getVar('org_name'), + 'gstin' =>$this->request->getVar('gstin'), + + + ]; + $model->save($donorData); + $session = session(); + $session ->setFlashdata('success','Successful Registration'); + return redirect()->to(base_url().'/Dashboard'); + } + } + + echo view('templates/header',$data); + echo view('donor_registration'); + echo view('templates/footer'); + + } + + public function all_donor() + { + $data = []; + if(!session()->has('logged_user')) + { + return redirect()->to(base_url()); + } + + + $data['receiptdata']=$this->My_model->all_donor(); + echo view('templates/header',$data); + echo view('donor_table'); + echo view('templates/footer'); + } + function edit_donor($id) + { + $model = new My_model(); + $donor_data=$model->find($id); + $data= [ 'post'=>$donor_data ]; + + if($this->request->getMethod() == 'post') + { + $model = new My_model(); + $_POST['id'] = $id; + $model->save($_POST); + return redirect()->to(base_url()."/My_controller/all_donor"); + } + echo view('templates/header',$data); + echo view('donor_edit'); + echo view('templates/footer'); + + } + + function fetch_country() + { + + echo $this->Dashboard_model->fetch_country(); + + } + function fetch_state() + { + + if($this->request->getVar('country_id')) + { + echo $this->Dashboard_model->fetch_state($this->request->getVar('country_id')); + } + } + + function fetch_city() + { + if($this->request->getVar('state_id')) + { + echo $this->Dashboard_model->fetch_city($this->request->getVar('state_id')); + } + } + + + //-------------------------------------------------------------------- + +} diff --git a/app/Controllers/UsersRules.php b/app/Controllers/UsersRules.php new file mode 100644 index 0000000..ca51a30 --- /dev/null +++ b/app/Controllers/UsersRules.php @@ -0,0 +1,18 @@ +where('email',$data['email']) + ->first(); + if($Donor) + return false; + return password_verify($data['password'],$Donor['password']); + } + +} \ No newline at end of file diff --git a/app/Controllers/admin/Donation.php b/app/Controllers/admin/Donation.php new file mode 100644 index 0000000..271d968 --- /dev/null +++ b/app/Controllers/admin/Donation.php @@ -0,0 +1,20 @@ +this is a product:'.$type.'and'.$type2.''; + //return view('show'); + } + + //-------------------------------------------------------------------- + +} diff --git a/app/Database/Migrations/.gitkeep b/app/Database/Migrations/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Database/Seeds/.gitkeep b/app/Database/Seeds/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Filters/.gitkeep b/app/Filters/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Helpers/.gitkeep b/app/Helpers/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Language/.gitkeep b/app/Language/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Language/en/Validation.php b/app/Language/en/Validation.php new file mode 100644 index 0000000..54d1e7a --- /dev/null +++ b/app/Language/en/Validation.php @@ -0,0 +1,4 @@ +db->table('user_management'); + $builder->where('id',$id); + $result = $builder->get(); + if(count($result->getResultArray()) ==1) + { + return $result->getRow(); + }else{ + return false; + } + + } + function fetch_country() + { + + $builder = $this->db->table('country'); + $query = $builder->get(); + //print_r($query);die(); + $output = ''; + foreach($query->getResult() as $row) + { + $output .= ''; + } + return $output; + } + function fetch_state($country_id) + { + + $builder = $this->db->table('state'); + $builder->where('country_id',$country_id); + $query = $builder->get(); + //print_r($query);die(); + $output = ''; + foreach($query->getResult() as $row) + { + $output .= ''; + } + return $output; + } + function fetch_city($state_id) + { + + $builder = $this->db->table('city'); + $builder->where('state_id',$state_id); + $query = $builder->get(); + //print_r($query);die(); + $output = ''; + foreach($query->getResult() as $row) + { + $output .= ''; + } + return $output; + } + +} \ No newline at end of file diff --git a/app/Models/Donation_cause.php b/app/Models/Donation_cause.php new file mode 100644 index 0000000..4a28b29 --- /dev/null +++ b/app/Models/Donation_cause.php @@ -0,0 +1,37 @@ +db->table('donation_cause'); + $result = $builder->get(); + $output = $result->getResultArray(); + return $output; + } + + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/Models/Donation_data_model.php b/app/Models/Donation_data_model.php new file mode 100644 index 0000000..9fc1410 --- /dev/null +++ b/app/Models/Donation_data_model.php @@ -0,0 +1,37 @@ +db->table('donation_data'); + $result = $builder->get(); + $output = $result->getResultArray(); + return $output; + } + + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/Models/Donation_model.php b/app/Models/Donation_model.php new file mode 100644 index 0000000..ba30c18 --- /dev/null +++ b/app/Models/Donation_model.php @@ -0,0 +1,25 @@ +passwordHash($data); + return $data; + } + + protected function beforeUpdate(array $data){ + $data= $this->passwordHash($data); + return $data; + } + + protected function passwordHash(array $data) + { + if(isset($data['data']['password'])) + $data['data']['password'] = password_hash($data['data']['password'],PASSWORD_DEFAULT); + return $data; + } + public function verifyEmail($email) + { + + $builder = $this->db->table('user_management'); + $builder -> select("id,phone,email,password"); + $builder -> where('email',$email); + $result = $builder->get(); + if(count($result->getResultArray()) ==1) + { + return $result->getRowArray(); + }else{ + return false; + } + } + + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/Models/My_model.php b/app/Models/My_model.php new file mode 100644 index 0000000..0dc0492 --- /dev/null +++ b/app/Models/My_model.php @@ -0,0 +1,48 @@ +db->table('donar_management'); + $result = $builder->get(); + $output = $result->getResultArray(); + return $output; + } +function fetch_donor_id() + { + + $builder = $this->db->table('donar_management'); + $query = $builder->get(); + //print_r($query);die(); + $output = ''; + foreach($query->getResult() as $row) + { + $output .= ''; + } + return $output; + } + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/Models/Receipt_model.php b/app/Models/Receipt_model.php new file mode 100644 index 0000000..d1c9927 --- /dev/null +++ b/app/Models/Receipt_model.php @@ -0,0 +1,37 @@ +db->table('receipts'); + $result = $builder->get(); + $output = $result->getResultArray(); + return $output; + } + + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/Models/Transaction_model.php b/app/Models/Transaction_model.php new file mode 100644 index 0000000..c9284c0 --- /dev/null +++ b/app/Models/Transaction_model.php @@ -0,0 +1,37 @@ +db->table('transactions_uploads'); + $result = $builder->get(); + $output = $result->getResultArray(); + return $output; + } + + + // protected $returnType = 'array'; + // protected $useSoftDeletes = true; + + + + // protected $useTimestamps = false; + // protected $createdField = 'created_at'; + // protected $updatedField = 'updated_at'; + // protected $deletedField = 'deleted_at'; + + // protected $validationRules = []; + // protected $validationMessages = []; + // protected $skipValidation = false; +} \ No newline at end of file diff --git a/app/ThirdParty/.gitkeep b/app/ThirdParty/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/app/Validation/UsersRules.php b/app/Validation/UsersRules.php new file mode 100644 index 0000000..8da50aa --- /dev/null +++ b/app/Validation/UsersRules.php @@ -0,0 +1,19 @@ +where('email',$data['email']) + ->first(); + if(!$Donor) + return false; + + return password_verify($data['password'],$user['password']); + } + +} \ No newline at end of file diff --git a/app/Views/add_donation_cause.php b/app/Views/add_donation_cause.php new file mode 100644 index 0000000..6f29eb5 --- /dev/null +++ b/app/Views/add_donation_cause.php @@ -0,0 +1,87 @@ +
+ +
+
+
+
+
+
+

Donation Cause

+

+
+ +
+
+
+
+
+
+
+ +
+ +
+ +
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+
+
+
+
+

+
+
+
+
+
+

Donation Cause List

+

+
+
+
+
+ + + + + + + + + + + + + + + + + + + +
Cause Name From Date To Date Action
Edit
+ + + + diff --git a/app/Views/dashboard.php b/app/Views/dashboard.php new file mode 100644 index 0000000..2351a4b --- /dev/null +++ b/app/Views/dashboard.php @@ -0,0 +1,14 @@ +
+
+
+
+
+

Welcome , name);?>


+

Mobile:phone;?>


+

Email :email;?>


+

Organization Name :org_name;?>


+


+
+
+
+ diff --git a/app/Views/donation_data.php b/app/Views/donation_data.php new file mode 100644 index 0000000..dbb3ce2 --- /dev/null +++ b/app/Views/donation_data.php @@ -0,0 +1,59 @@ +
+ +
+
+
+
+
+
+

Transaction upload

+

+
+ +
+
" > +
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
diff --git a/app/Views/donation_data_edit.php b/app/Views/donation_data_edit.php new file mode 100644 index 0000000..ab5b8b2 --- /dev/null +++ b/app/Views/donation_data_edit.php @@ -0,0 +1,59 @@ +
+ +
+
+
+
+
+
+

Donation Data Edit

+

+
+ +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
diff --git a/app/Views/donation_data_table.php b/app/Views/donation_data_table.php new file mode 100644 index 0000000..0d8017d --- /dev/null +++ b/app/Views/donation_data_table.php @@ -0,0 +1,40 @@ +
+
+
+
+
+

Donation Data

+

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
Donation Date Cause Name Amount Payment Mode Referance 1 Donation Ref Action
Edit
+ + + + \ No newline at end of file diff --git a/app/Views/donor_edit.php b/app/Views/donor_edit.php new file mode 100644 index 0000000..a0cb2d8 --- /dev/null +++ b/app/Views/donor_edit.php @@ -0,0 +1,150 @@ + +
+ + + +

REGISTER

+ +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+ + +
+
+
+
+ +
+
+ + + + +
\ No newline at end of file diff --git a/app/Views/donor_registration.php b/app/Views/donor_registration.php new file mode 100644 index 0000000..a456da6 --- /dev/null +++ b/app/Views/donor_registration.php @@ -0,0 +1,156 @@ + +
+ + + +

REGISTER

+ +
" > +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+ +
+ +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+ + +
+
+listErrors() ?> +
+
+ +
+
+
+
+ +
+
+ + + + +
\ No newline at end of file diff --git a/app/Views/donor_table.php b/app/Views/donor_table.php new file mode 100644 index 0000000..bf68f28 --- /dev/null +++ b/app/Views/donor_table.php @@ -0,0 +1,45 @@ +
+
+
+
+
+

Donors List

+

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
Name Phone Email Pan Address DOB Gender Org Name GSTIN Action
Edit
+ + + + \ No newline at end of file diff --git a/app/Views/edit_view.php b/app/Views/edit_view.php new file mode 100644 index 0000000..9884a6a --- /dev/null +++ b/app/Views/edit_view.php @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/Views/errors/cli/error_404.php b/app/Views/errors/cli/error_404.php new file mode 100644 index 0000000..d5bccb4 --- /dev/null +++ b/app/Views/errors/cli/error_404.php @@ -0,0 +1,6 @@ + +Message: +Filename: getFile(), "\n"; ?> +Line Number: getLine(); ?> + + + + Backtrace: + getTrace() as $error): ?> + + + + + + diff --git a/app/Views/errors/cli/production.php b/app/Views/errors/cli/production.php new file mode 100644 index 0000000..7db744e --- /dev/null +++ b/app/Views/errors/cli/production.php @@ -0,0 +1,5 @@ + + + + + 404 Page Not Found + + + + +
+

404 - File Not Found

+ +

+ + + + Sorry! Cannot seem to find the page you were looking for. + +

+
+ + diff --git a/app/Views/errors/html/error_exception.php b/app/Views/errors/html/error_exception.php new file mode 100644 index 0000000..09fddcb --- /dev/null +++ b/app/Views/errors/html/error_exception.php @@ -0,0 +1,401 @@ + + + + + + + + <?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8') ?> + + + + + + + +
+
+

getCode() ? ' #' . $exception->getCode() : '') ?>

+

+ getMessage() ?> + getMessage())) ?>" + rel="noreferrer" target="_blank">search → +

+
+
+ + +
+

at line

+ + +
+ +
+ +
+ +
+ + + +
+ + +
+ +
    + $row) : ?> + +
  1. +

    + + + + + {PHP internal code} + + + + +   —   + + + ( arguments ) +

    +
+ + getParameters(); + } + foreach ($row['args'] as $key => $value) : ?> + + + + + + +
name : "#$key", ENT_SUBSTITUTE, 'UTF-8') ?>
+
+ + () + + + + +   —   () + +

+ + + +
+ +
+ + + + + + +
+ + +
+ + + +

$

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ + + + + + +

Constants

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pathuri ?>
HTTP MethodgetMethod(true) ?>
IP AddressgetIPAddress() ?>
Is AJAX Request?isAJAX() ? 'yes' : 'no' ?>
Is CLI Request?isCLI() ? 'yes' : 'no' ?>
Is Secure Request?isSecure() ? 'yes' : 'no' ?>
User AgentgetUserAgent()->getAgentString() ?>
+ + + + + + + + +

$

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ + + + + +
+ No $_GET, $_POST, or $_COOKIE Information to show. +
+ + + + getHeaders(); ?> + + +

Headers

+ + + + + + + + + + + + + + + + + + + + +
HeaderValue
getName(), 'html') ?>getValueLine(), 'html') ?>
+ + +
+ + + setStatusCode(http_response_code()); + ?> +
+ + + + + +
Response StatusgetStatusCode() . ' - ' . $response->getReason() ?>
+ + getHeaders(); ?> + + + +

Headers

+ + + + + + + + + + $value) : ?> + + + + + + +
HeaderValue
getHeaderLine($name), 'html') ?>
+ + +
+ + +
+ + +
    + +
  1. + +
+
+ + +
+ + + + + + + + + + + + + + + + +
Memory Usage
Peak Memory Usage:
Memory Limit:
+ +
+ +
+ +
+ + + + + diff --git a/app/Views/errors/html/production.php b/app/Views/errors/html/production.php new file mode 100644 index 0000000..cca49c2 --- /dev/null +++ b/app/Views/errors/html/production.php @@ -0,0 +1,25 @@ + + + + + + + Whoops! + + + + + +
+ +

Whoops!

+ +

We seem to have hit a snag. Please try again later...

+ +
+ + + + diff --git a/app/Views/list.php b/app/Views/list.php new file mode 100644 index 0000000..9fe983a --- /dev/null +++ b/app/Views/list.php @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + +
NameEmailAction
Edit + Delete + private view
+
+
+ \ No newline at end of file diff --git a/app/Views/login.php b/app/Views/login.php new file mode 100644 index 0000000..495c025 --- /dev/null +++ b/app/Views/login.php @@ -0,0 +1,50 @@ +
+
+
+
+ +

LOGIN

+ +
"> +get('success')): ?> + + +
+EMAIL ID     + +
+
+PASSWORD + +
+ +
+
+listErrors() ?> +
+
+ +getTempdata('error')):?> +
+
+getTempdata('error'); ?> +
+
+ +
+
+ +
+
+ + +
+ +
+
+
+
\ No newline at end of file diff --git a/app/Views/profile_view.php b/app/Views/profile_view.php new file mode 100644 index 0000000..3dd277d --- /dev/null +++ b/app/Views/profile_view.php @@ -0,0 +1,9 @@ + + +


+


+


+ + +
+ \ No newline at end of file diff --git a/app/Views/receipt_edit.php b/app/Views/receipt_edit.php new file mode 100644 index 0000000..079156f --- /dev/null +++ b/app/Views/receipt_edit.php @@ -0,0 +1,71 @@ +
+ +
+
+
+
+
+
+

EDIT RECEIPTS

+

+
+ +
+
+
+
+
+
+
+ +
+
+ + +
+ +
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
diff --git a/app/Views/receipts.php b/app/Views/receipts.php new file mode 100644 index 0000000..650243d --- /dev/null +++ b/app/Views/receipts.php @@ -0,0 +1,70 @@ +
+ +
+
+
+
+
+
+

GENERATE RECEIPTS

+

+
+ +
+
" > +
+
+
+
+
+ +
+
+ + +
+
+
+
+ +
+
+ +
+
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
diff --git a/app/Views/receipts_table.php b/app/Views/receipts_table.php new file mode 100644 index 0000000..536b3ec --- /dev/null +++ b/app/Views/receipts_table.php @@ -0,0 +1,41 @@ +
+
+
+
+
+

ALL RECEIPTS

+

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Receipt No Date Donor Id Amount Mode Details Cause Action
Edit
+ + + + \ No newline at end of file diff --git a/app/Views/register.php b/app/Views/register.php new file mode 100644 index 0000000..eca012f --- /dev/null +++ b/app/Views/register.php @@ -0,0 +1,145 @@ + +
+ + + +

REGISTER

+ +
" > +
+
+
+
+ + +
+
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+ + + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+
+
+
+ + +
+
+
+
+ + +
+
+
+ +
+ + +
+
+listErrors() ?> +
+
+ +
+
+ +
+
+ + +
+ diff --git a/app/Views/show.php b/app/Views/show.php new file mode 100644 index 0000000..438eff2 --- /dev/null +++ b/app/Views/show.php @@ -0,0 +1,53 @@ + + + + + + + + + + + + + Form Validation + + +
+
"> +POSTS +
+POSTID +
+ + +
+
+
+

Form Validation

+
"> +
+ + +
+
+ + + We'll never share your email with anyone else. +
+ +
+ + +
+ + +
+ + + + + + + + \ No newline at end of file diff --git a/app/Views/templates/footer.php b/app/Views/templates/footer.php new file mode 100644 index 0000000..691287b --- /dev/null +++ b/app/Views/templates/footer.php @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/app/Views/templates/header.php b/app/Views/templates/header.php new file mode 100644 index 0000000..8bfc167 --- /dev/null +++ b/app/Views/templates/header.php @@ -0,0 +1,556 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +has('logged_user')): ?> + + \ No newline at end of file diff --git a/app/Views/transaction_edit.php b/app/Views/transaction_edit.php new file mode 100644 index 0000000..6b9cb24 --- /dev/null +++ b/app/Views/transaction_edit.php @@ -0,0 +1,59 @@ +
+ +
+
+
+
+
+
+

Transaction Edit

+

+
+ +
+
+
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
diff --git a/app/Views/transaction_table.php b/app/Views/transaction_table.php new file mode 100644 index 0000000..0fd6b9d --- /dev/null +++ b/app/Views/transaction_table.php @@ -0,0 +1,40 @@ +
+
+
+
+
+

ALL TRANSACTIONS

+

+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + +
Transaction Date Reference 1 Reference 1 Remarks Amount Donation Ref dAction
Edit
+ + + + \ No newline at end of file diff --git a/app/Views/transaction_upload.php b/app/Views/transaction_upload.php new file mode 100644 index 0000000..c2dccb3 --- /dev/null +++ b/app/Views/transaction_upload.php @@ -0,0 +1,65 @@ + +
+ +
+
+
+
+
+
+

Transaction upload

+

+
+ +
+
" > +
+
+
+
+
+ + +
+
+ +
+
+
+
+ +
+
+ +
+
+
+
+
+
+ +
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+ +
+ +
+
+
+
+ + + diff --git a/app/Views/welcome_message.php b/app/Views/welcome_message.php new file mode 100644 index 0000000..1c88df0 --- /dev/null +++ b/app/Views/welcome_message.php @@ -0,0 +1,324 @@ + + + + + Welcome to CodeIgniter 4! + + + + + + + + + + +
+ + + +
+ +

Welcome to CodeIgniter Tutorial

+ +

The small framework with powerful features

+ +
+ +
+ + + +
+ +

About this page

+ +

The page you are looking at is being generated dynamically by CodeIgniter.

+ +

If you would like to edit this page you will find it located at:

+ +
app/Views/welcome_message.php
+ +

The corresponding controller for this page can be found at:

+ +
app/Controllers/Home.php
+ +
+ +
+ +
+ +

Go further

+ +

+ + Learn +

+ +

The User Guide contains an introduction, tutorial, a number of "how to" + guides, and then reference documentation for the components that make up + the framework. Check the User Guide !

+ +

+ + Discuss +

+ +

CodeIgniter is a community-developed open source project, with several + venues for the community members to gather and exchange ideas. View all + the threads on CodeIgniter's forum, or chat on Slack !

+ +

+ + Contribute +

+ +

CodeIgniter is a community driven project and accepts contributions + of code and documentation from the community. Why not + + join us ?

+ +
+ +
+ + + +
+
+ +

Page rendered in {elapsed_time} seconds

+ +

Environment:

+ +
+ +
+ +

© CodeIgniter Foundation. CodeIgniter is open source project released under the MIT + open source licence.

+ +
+ +
+ + + + + + + + + diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/app/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/builds b/builds new file mode 100644 index 0000000..268e7a8 --- /dev/null +++ b/builds @@ -0,0 +1,163 @@ +#!/usr/bin/env php + 'vcs', + 'url' => GITHUB_URL, + ]; + } + + // Define the "require" + $array['require']['codeigniter4/codeigniter4'] = 'dev-develop'; + unset($array['require']['codeigniter4/framework']); + } + + // Release + else + { + // Clear 'minimum-stability' + unset($array['minimum-stability']); + + // If the repo is configured then clear it + if (isset($array['repositories'])) + { + // Check for the CodeIgniter repo + foreach ($array['repositories'] as $i => $repository) + { + if ($repository['url'] == GITHUB_URL) + { + unset($array['repositories'][$i]); + break; + } + } + if (empty($array['repositories'])) + { + unset($array['repositories']); + } + } + + // Define the "require" + $array['require']['codeigniter4/framework'] = LATEST_RELEASE; + unset($array['require']['codeigniter4/codeigniter4']); + } + + // Write out a new composer.json + file_put_contents($file, json_encode($array, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES) . PHP_EOL); + $modified[] = $file; + } + else + { + echo 'Warning: Unable to decode composer.json! Skipping...' . PHP_EOL; + } + } + else + { + echo 'Warning: Unable to read composer.json! Skipping...' . PHP_EOL; + } +} + +// Paths config and PHPUnit XMLs +$files = [ + __DIR__ . DIRECTORY_SEPARATOR . 'app/Config/Paths.php', + __DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml.dist', + __DIR__ . DIRECTORY_SEPARATOR . 'phpunit.xml', +]; + +foreach ($files as $file) +{ + if (is_file($file)) + { + $contents = file_get_contents($file); + + // Development + if ($dev) + { + $contents = str_replace('vendor/codeigniter4/framework', 'vendor/codeigniter4/codeigniter4', $contents); + } + + // Release + else + { + $contents = str_replace('vendor/codeigniter4/codeigniter4', 'vendor/codeigniter4/framework', $contents); + } + + file_put_contents($file, $contents); + $modified[] = $file; + } +} + +if (empty($modified)) +{ + echo 'No files modified' . PHP_EOL; +} +else +{ + echo 'The following files were modified:' . PHP_EOL; + foreach ($modified as $file) + { + echo " * {$file}" . PHP_EOL; + } + echo 'Run `composer update` to sync changes with your vendor folder' . PHP_EOL; +} diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..17ad157 --- /dev/null +++ b/composer.json @@ -0,0 +1,33 @@ +{ + "name": "codeigniter4/appstarter", + "type": "project", + "description": "CodeIgniter4 starter app", + "homepage": "https://codeigniter.com", + "license": "MIT", + "require": { + "php": ">=7.2", + "codeigniter4/framework": "^4", + "dompdf/dompdf": "^0.8.6" + }, + "require-dev": { + "fzaninotto/faker": "^1.9@dev", + "mikey179/vfsstream": "1.6.*", + "phpunit/phpunit": "^8.5" + }, + "autoload-dev": { + "psr-4": { + "Tests\\Support\\": "tests/_support" + } + }, + "scripts": { + "post-update-cmd": [ + "@composer dump-autoload" + ], + "test": "phpunit" + }, + "support": { + "forum": "http://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..82c07ba --- /dev/null +++ b/composer.lock @@ -0,0 +1,2144 @@ +{ + "_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": "2b4574ab618335dcb406d7416cebbdfb", + "packages": [ + { + "name": "codeigniter4/framework", + "version": "v4.0.4", + "source": { + "type": "git", + "url": "https://github.com/codeigniter4/framework.git", + "reference": "1edcf84f77ff794640fddbfc59a10a024cd15b50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/codeigniter4/framework/zipball/1edcf84f77ff794640fddbfc59a10a024cd15b50", + "reference": "1edcf84f77ff794640fddbfc59a10a024cd15b50", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "kint-php/kint": "^3.3", + "laminas/laminas-escaper": "^2.6", + "php": ">=7.2", + "psr/log": "^1.1" + }, + "require-dev": { + "codeigniter4/codeigniter4-standard": "^1.0", + "fzaninotto/faker": "^1.9@dev", + "mikey179/vfsstream": "1.6.*", + "phpunit/phpunit": "^8.5", + "predis/predis": "^1.1", + "squizlabs/php_codesniffer": "^3.3" + }, + "type": "project", + "autoload": { + "psr-4": { + "CodeIgniter\\": "system/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The CodeIgniter framework v4", + "homepage": "https://codeigniter.com", + "time": "2020-07-16T03:44:28+00:00" + }, + { + "name": "dompdf/dompdf", + "version": "v0.8.6", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/db91d81866c69a42dad1d2926f61515a1e3f42c5", + "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "phenx/php-font-lib": "^0.5.2", + "phenx/php-svg-lib": "^0.3.3", + "php": "^7.1" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.7-dev" + } + }, + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + }, + { + "name": "Brian Sweeney", + "email": "eclecticgeek@gmail.com" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "time": "2020-08-30T22:54:22+00:00" + }, + { + "name": "kint-php/kint", + "version": "3.3", + "source": { + "type": "git", + "url": "https://github.com/kint-php/kint.git", + "reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kint-php/kint/zipball/335ac1bcaf04d87df70d8aa51e8887ba2c6d203b", + "reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b", + "shasum": "" + }, + "require": { + "php": ">=5.3.6" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpunit/phpunit": "^4.0", + "seld/phar-utils": "^1.0", + "symfony/finder": "^2.0 || ^3.0 || ^4.0", + "vimeo/psalm": "^3.0" + }, + "suggest": { + "ext-ctype": "Simple data type tests", + "ext-iconv": "Provides fallback detection for ambiguous legacy string encodings such as the Windows and ISO 8859 code pages", + "ext-mbstring": "Provides string encoding detection", + "kint-php/kint-js": "Provides a simplified dump to console.log()", + "kint-php/kint-twig": "Provides d() and s() functions in twig templates", + "symfony/polyfill-ctype": "Replacement for ext-ctype if missing", + "symfony/polyfill-iconv": "Replacement for ext-iconv if missing", + "symfony/polyfill-mbstring": "Replacement for ext-mbstring if missing" + }, + "type": "library", + "autoload": { + "files": [ + "init.php" + ], + "psr-4": { + "Kint\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Vollebregt", + "homepage": "https://github.com/jnvsor" + }, + { + "name": "Rokas Šleinius", + "homepage": "https://github.com/raveren" + }, + { + "name": "Contributors", + "homepage": "https://github.com/kint-php/kint/graphs/contributors" + } + ], + "description": "Kint - debugging tool for PHP developers", + "homepage": "https://kint-php.github.io/kint/", + "keywords": [ + "debug", + "kint", + "php" + ], + "time": "2019-10-17T18:05:24+00:00" + }, + { + "name": "laminas/laminas-escaper", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/25f2a053eadfa92ddacb609dcbbc39362610da70", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-escaper": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ], + "time": "2019-12-31T16:43:30+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", + "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2020-09-14T14:23:00+00:00" + }, + { + "name": "phenx/php-font-lib", + "version": "0.5.2", + "source": { + "type": "git", + "url": "https://github.com/PhenX/php-font-lib.git", + "reference": "ca6ad461f032145fff5971b5985e5af9e7fa88d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/ca6ad461f032145fff5971b5985e5af9e7fa88d8", + "reference": "ca6ad461f032145fff5971b5985e5af9e7fa88d8", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5 || ^6 || ^7" + }, + "type": "library", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "time": "2020-03-08T15:31:32+00:00" + }, + { + "name": "phenx/php-svg-lib", + "version": "v0.3.3", + "source": { + "type": "git", + "url": "https://github.com/PhenX/php-svg-lib.git", + "reference": "5fa61b65e612ce1ae15f69b3d223cb14ecc60e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/5fa61b65e612ce1ae15f69b3d223cb14ecc60e32", + "reference": "5fa61b65e612ce1ae15f69b3d223cb14ecc60e32", + "shasum": "" + }, + "require": { + "sabberworm/php-css-parser": "^8.3" + }, + "require-dev": { + "phpunit/phpunit": "^5.5|^6.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "time": "2019-09-11T20:02:13+00:00" + }, + { + "name": "psr/log", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2020-03-23T09:12:05+00:00" + }, + { + "name": "sabberworm/php-css-parser", + "version": "8.3.1", + "source": { + "type": "git", + "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", + "reference": "d217848e1396ef962fb1997cf3e2421acba7f796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/d217848e1396ef962fb1997cf3e2421acba7f796", + "reference": "d217848e1396ef962fb1997cf3e2421acba7f796", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "codacy/coverage": "^1.4", + "phpunit/phpunit": "~4.8" + }, + "type": "library", + "autoload": { + "psr-0": { + "Sabberworm\\CSS": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "http://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ], + "time": "2020-06-01T09:10:00+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-05-29T17:27:14+00:00" + }, + { + "name": "fzaninotto/faker", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "ac73e5287024f5e98dd6d0bf10e6a6f7877b7513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/ac73e5287024f5e98dd6d0bf10e6a6f7877b7513", + "reference": "ac73e5287024f5e98dd6d0bf10e6a6f7877b7513", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7", + "squizlabs/php_codesniffer": "^2.9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "abandoned": true, + "time": "2020-10-27T14:15:58+00:00" + }, + { + "name": "mikey179/vfsstream", + "version": "v1.6.8", + "source": { + "type": "git", + "url": "https://github.com/bovigo/vfsStream.git", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/", + "time": "2019-10-30T15:31:00+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2018-07-08T19:23:20+00:00" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.2", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-09-03T19:13:55+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-09-17T18:55:26+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-09-29T09:10:42+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "7.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.1.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.2.2" + }, + "suggest": { + "ext-xdebug": "^2.7.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2019-11-20T13:55:58+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "050bedf145a257b1ff02746c31894800e5122946" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-09-13T20:33:42+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2019-06-07T04:22:29+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true, + "time": "2019-09-17T06:23:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "8.5.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.2", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.5-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-22T07:06:58+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "time": "2017-03-04T06:30:41+00:00" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-07-12T15:12:46+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2019-02-04T06:01:07+00:00" + }, + { + "name": "sebastian/environment", + "version": "4.2.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2019-11-20T08:46:58+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2019-09-14T09:02:43+00:00" + }, + { + "name": "sebastian/global-state", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "shasum": "" + }, + "require": { + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2019-02-01T05:30:01+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "time": "2017-08-03T12:35:26+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2017-03-29T09:07:27+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2018-10-04T04:07:39+00:00" + }, + { + "name": "sebastian/type", + "version": "1.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "time": "2019-07-02T08:10:15+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-14T12:35:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "fzaninotto/faker": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.2" + }, + "platform-dev": [], + "plugin-api-version": "1.1.0" +} diff --git a/env b/env new file mode 100644 index 0000000..9b8720f --- /dev/null +++ b/env @@ -0,0 +1,101 @@ +#-------------------------------------------------------------------- +# Example Environment Configuration file +# +# This file can be used as a starting point for your own +# custom .env files, and contains most of the possible settings +# available in a default install. +# +# By default, all of the settings are commented out. If you want +# to override the setting, you must un-comment it by removing the '#' +# at the beginning of the line. +#-------------------------------------------------------------------- + +#-------------------------------------------------------------------- +# ENVIRONMENT +#-------------------------------------------------------------------- + +#CI_ENVIRONMENT = production + +#-------------------------------------------------------------------- +# APP +#-------------------------------------------------------------------- + +#app.baseURL = '' +# app.forceGlobalSecureRequests = false + +# app.sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler' +# app.sessionCookieName = 'ci_session' +# app.sessionSavePath = NULL +# app.sessionMatchIP = false +# app.sessionTimeToUpdate = 300 +# app.sessionRegenerateDestroy = false + +# app.cookiePrefix = '' +# app.cookieDomain = '' +# app.cookiePath = '/' +# app.cookieSecure = false +# app.cookieHTTPOnly = false + +# app.CSRFProtection = false +# app.CSRFTokenName = 'csrf_test_name' +# app.CSRFCookieName = 'csrf_cookie_name' +# app.CSRFExpire = 7200 +# app.CSRFRegenerate = true +# app.CSRFExcludeURIs = [] + +# app.CSPEnabled = false + +#-------------------------------------------------------------------- +# DATABASE +#-------------------------------------------------------------------- + +# database.default.hostname = localhost +# database.default.database = ci4 +# database.default.username = root +# database.default.password = root +# database.default.DBDriver = MySQLi + +# database.tests.hostname = localhost +# database.tests.database = ci4 +# database.tests.username = root +# database.tests.password = root +# database.tests.DBDriver = MySQLi + +#-------------------------------------------------------------------- +# CONTENT SECURITY POLICY +#-------------------------------------------------------------------- + +# contentsecuritypolicy.reportOnly = false +# contentsecuritypolicy.defaultSrc = 'none' +# contentsecuritypolicy.scriptSrc = 'self' +# contentsecuritypolicy.styleSrc = 'self' +# contentsecuritypolicy.imageSrc = 'self' +# contentsecuritypolicy.base_uri = null +# contentsecuritypolicy.childSrc = null +# contentsecuritypolicy.connectSrc = 'self' +# contentsecuritypolicy.fontSrc = null +# contentsecuritypolicy.formAction = null +# contentsecuritypolicy.frameAncestors = null +# contentsecuritypolicy.mediaSrc = null +# contentsecuritypolicy.objectSrc = null +# contentsecuritypolicy.pluginTypes = null +# contentsecuritypolicy.reportURI = null +# contentsecuritypolicy.sandbox = false +# contentsecuritypolicy.upgradeInsecureRequests = false + +#-------------------------------------------------------------------- +# ENCRYPTION +#-------------------------------------------------------------------- + +# encryption.key = +# encryption.driver = OpenSSL + +#-------------------------------------------------------------------- +# HONEYPOT +#-------------------------------------------------------------------- + +# honeypot.hidden = 'true' +# honeypot.label = 'Fill This Field' +# honeypot.name = 'honeypot' +# honeypot.template = '' +# honeypot.container = '
{template}
' diff --git a/index.php b/index.php new file mode 100644 index 0000000..9f9b05b --- /dev/null +++ b/index.php @@ -0,0 +1,45 @@ +systemDirectory, '/ ') . '/bootstrap.php'; + +/* + *--------------------------------------------------------------- + * LAUNCH THE APPLICATION + *--------------------------------------------------------------- + * Now that everything is setup, it's time to actually fire + * up the engines and make this app do its thang. + */ +$app->run(); diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..2fb1bdd --- /dev/null +++ b/license.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014-2019 British Columbia Institute of Technology +Copyright (c) 2019-2020 CodeIgniter Foundation + +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/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..96947df --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,60 @@ + + + + + ./tests + + + + + + ./app + + ./app/Views + ./app/Config/Routes.php + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..02026a3 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,48 @@ +# Disable directory browsing +Options All -Indexes + +# ---------------------------------------------------------------------- +# Rewrite engine +# ---------------------------------------------------------------------- + +# Turning on the rewrite engine is necessary for the following rules and features. +# FollowSymLinks must be enabled for this to work. + + Options +FollowSymlinks + RewriteEngine On + + # If you installed CodeIgniter in a subfolder, you will need to + # change the following line to match the subfolder you need. + # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase + # RewriteBase / + + # Redirect Trailing Slashes... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)/$ /$1 [L,R=301] + + # Rewrite "www.example.com -> example.com" + RewriteCond %{HTTPS} !=on + RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] + RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] + + # Checks to see if the user is attempting to access a valid file, + # such as an image or css document, if this isn't true it sends the + # request to the front controller, index.php + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA] + + # Ensure Authorization header is passed along + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + + + # If we don't have mod_rewrite installed, all 404's + # can be sent to index.php, and everything works as normal. + ErrorDocument 404 index.php + + +# Disable server signature start + ServerSignature Off +# Disable server signature end diff --git a/public/assets/css/style.css b/public/assets/css/style.css new file mode 100644 index 0000000..d9b3405 --- /dev/null +++ b/public/assets/css/style.css @@ -0,0 +1,3 @@ +body{ + background-color : #e1e1e1; +} diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ecfce214cbdbedc15d8348babeff5cd7e720488 GIT binary patch literal 5430 zcmeHL&npB`9Dn5Kuy>cuLGmAPauLohTgugsgTofC9NbV!aa0tgTofgxl%f=?Y?Sh& zWMxI9hibZ5LZ@~9&$;7J-7ai$2=7ByD3A3P1*hfQz|8$LL= zUz~w$;90HjJ=)Ss!V^NuI2Za%(z#lli~7u{+nbyOi;~<-#pGX{K<~tb_C6Lj^YSY9 zuHBEb(bRJ+>$(mjNuamQtlmY!MgdXJjDiJ*`fSvC!*oskp+}sjm(MWyz%r29BW!f*m(x|(w?cOiYFaD0y8pq z9eCfscMhGYa>i@!YdSYJ(-6XZ(W@wc#d9lm1l3S%FF!rC_waiB@V}AM)ez?!Gp$os wgQ-p&yk8A*^lZ5Jw#)Gj@LI_qy{H^P{^jt7C;ag)RHAYMwkN>;6;PJx7hHm1jsO4v literal 0 HcmV?d00001 diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..3eaa592 --- /dev/null +++ b/public/index.php @@ -0,0 +1,45 @@ +systemDirectory, '/ ') . '/bootstrap.php'; + +/* + *--------------------------------------------------------------- + * LAUNCH THE APPLICATION + *--------------------------------------------------------------- + * Now that everything is setup, it's time to actually fire + * up the engines and make this app do its thang. + */ +$app->run(); diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..9e60f97 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/spark b/spark new file mode 100644 index 0000000..0a0908d --- /dev/null +++ b/spark @@ -0,0 +1,61 @@ +#!/usr/bin/env php +systemDirectory, '/ ') . '/bootstrap.php'; + +// Grab our Console +$console = new \CodeIgniter\CLI\Console($app); + +// We want errors to be shown when using it from the CLI. +error_reporting(-1); +ini_set('display_errors', 1); + +// Show basic information before we do anything else. +$console->showHeader(); + +// fire off the command in the main framework. +$response = $console->run(); +if ($response->getStatusCode() >= 300) +{ + exit($response->getStatusCode()); +} diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000..545ccfe --- /dev/null +++ b/tests/README.md @@ -0,0 +1,108 @@ +# Running Application Tests + +This is the quick-start to CodeIgniter testing. Its intent is to describe what +it takes to set up your application and get it ready to run unit tests. +It is not intended to be a full description of the test features that you can +use to test your application. Those details can be found in the documentation. + +## Resources +* [CodeIgniter 4 User Guide on Testing](https://codeigniter4.github.io/userguide/testing/index.html) +* [PHPUnit docs](https://phpunit.readthedocs.io/en/8.3/index.html) + +## Requirements + +It is recommended to use the latest version of PHPUnit. At the time of this +writing we are running version 8.5.2. Support for this has been built into the +**composer.json** file that ships with CodeIgniter and can easily be installed +via [Composer](https://getcomposer.org/) if you don't already have it installed globally. + + > composer install + +If running under OS X or Linux, you can create a symbolic link to make running tests a touch nicer. + + > ln -s ./vendor/bin/phpunit ./phpunit + +You also need to install [XDebug](https://xdebug.org/index.php) in order +for code coverage to be calculated successfully. + +## Setting Up + +A number of the tests use a running database. +In order to set up the database edit the details for the `tests` group in +**app/Config/Database.php** or **phpunit.xml**. Make sure that you provide a database engine +that is currently running on your machine. More details on a test database setup are in the +*Docs>>Testing>>Testing Your Database* section of the documentation. + +If you want to run the tests without using live database you can +exclude @DatabaseLive group. Or make a copy of **phpunit.dist.xml** - +call it **phpunit.xml** - and comment out the named "database". This will make +the tests run quite a bit faster. + +## Running the tests + +The entire test suite can be run by simply typing one command-line command from the main directory. + + > ./phpunit + +You can limit tests to those within a single test directory by specifying the +directory name after phpunit. + + > ./phpunit app/Models + +## Generating Code Coverage + +To generate coverage information, including HTML reports you can view in your browser, +you can use the following command: + + > ./phpunit --colors --coverage-text=tests/coverage.txt --coverage-html=tests/coverage/ -d memory_limit=1024m + +This runs all of the tests again collecting information about how many lines, +functions, and files are tested. It also reports the percentage of the code that is covered by tests. +It is collected in two formats: a simple text file that provides an overview as well +as a comprehensive collection of HTML files that show the status of every line of code in the project. + +The text file can be found at **tests/coverage.txt**. +The HTML files can be viewed by opening **tests/coverage/index.html** in your favorite browser. + +## PHPUnit XML Configuration + +The repository has a ``phpunit.xml.dist`` file in the project root that's used for +PHPUnit configuration. This is used to provide a default configuration if you +do not have your own configuration file in the project root. + +The normal practice would be to copy ``phpunit.xml.dist`` to ``phpunit.xml`` +(which is git ignored), and to tailor it as you see fit. +For instance, you might wish to exclude database tests, or automatically generate +HTML code coverage reports. + +## Test Cases + +Every test needs a *test case*, or class that your tests extend. CodeIgniter 4 +provides a few that you may use directly: +* `CodeIgniter\Test\CIUnitTestCase` - for basic tests with no other service needs +* `CodeIgniter\Test\CIDatabaseTestCase` - for tests that need database access + +Most of the time you will want to write your own test cases to hold functions and services +common to your test suites. + +## Creating Tests + +All tests go in the **tests/** directory. Each test file is a class that extends a +**Test Case** (see above) and contains methods for the individual tests. These method +names must start with the word "test" and should have descriptive names for precisely what +they are testing: +`testUserCanModifyFile()` `testOutputColorMatchesInput()` `testIsLoggedInFailsWithInvalidUser()` + +Writing tests is an art, and there are many resources available to help learn how. +Review the links above and always pay attention to your code coverage. + +### Database Tests + +Tests can include migrating, seeding, and testing against a mock or live1 database. +Be sure to modify the test case (or create your own) to point to your seed and migrations +and include any additional steps to be run before tests in the `setUp()` method. + +1 Note: If you are using database tests that require a live database connection +you will need to rename **phpunit.xml.dist** to **phpunit.xml**, uncomment the database +configuration lines and add your connection details. Prevent **phpunit.xml** from being +tracked in your repo by adding it to **.gitignore**. diff --git a/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php new file mode 100644 index 0000000..1bfd4a3 --- /dev/null +++ b/tests/_support/Database/Migrations/2020-02-22-222222_example_migration.php @@ -0,0 +1,61 @@ + [ + 'type' => 'varchar', + 'constraint' => 31, + ], + 'uid' => [ + 'type' => 'varchar', + 'constraint' => 31, + ], + 'class' => [ + 'type' => 'varchar', + 'constraint' => 63, + ], + 'icon' => [ + 'type' => 'varchar', + 'constraint' => 31, + ], + 'summary' => [ + 'type' => 'varchar', + 'constraint' => 255, + ], + 'created_at' => [ + 'type' => 'datetime', + 'null' => true, + ], + 'updated_at' => [ + 'type' => 'datetime', + 'null' => true, + ], + 'deleted_at' => [ + 'type' => 'datetime', + 'null' => true, + ], + ]; + + $this->forge->addField('id'); + $this->forge->addField($fields); + + $this->forge->addKey('name'); + $this->forge->addKey('uid'); + $this->forge->addKey(['deleted_at', 'id']); + $this->forge->addKey('created_at'); + + $this->forge->createTable('factories'); + } + + public function down() + { + $this->forge->dropTable('factories'); + } +} diff --git a/tests/_support/Database/Seeds/ExampleSeeder.php b/tests/_support/Database/Seeds/ExampleSeeder.php new file mode 100644 index 0000000..1b14ced --- /dev/null +++ b/tests/_support/Database/Seeds/ExampleSeeder.php @@ -0,0 +1,40 @@ + 'Test Factory', + 'uid' => 'test001', + 'class' => 'Factories\Tests\NewFactory', + 'icon' => 'fas fa-puzzle-piece', + 'summary' => 'Longer sample text for testing', + ], + [ + 'name' => 'Widget Factory', + 'uid' => 'widget', + 'class' => 'Factories\Tests\WidgetPlant', + 'icon' => 'fas fa-puzzle-piece', + 'summary' => 'Create widgets in your factory', + ], + [ + 'name' => 'Evil Factory', + 'uid' => 'evil-maker', + 'class' => 'Factories\Evil\MyFactory', + 'icon' => 'fas fa-book-dead', + 'summary' => 'Abandon all hope, ye who enter here', + ], + ]; + + $builder = $this->db->table('factories'); + + foreach ($factories as $factory) + { + $builder->insert($factory); + } + } +} diff --git a/tests/_support/DatabaseTestCase.php b/tests/_support/DatabaseTestCase.php new file mode 100644 index 0000000..8b094d3 --- /dev/null +++ b/tests/_support/DatabaseTestCase.php @@ -0,0 +1,51 @@ +mockSession(); + } + + /** + * Pre-loads the mock session driver into $this->session. + * + * @var string + */ + protected function mockSession() + { + $config = config('App'); + $this->session = new MockSession(new ArrayHandler($config, '0.0.0.0'), $config); + \Config\Services::injectMock('session', $this->session); + } +} diff --git a/tests/database/ExampleDatabaseTest.php b/tests/database/ExampleDatabaseTest.php new file mode 100644 index 0000000..2de0b6a --- /dev/null +++ b/tests/database/ExampleDatabaseTest.php @@ -0,0 +1,42 @@ +findAll(); + + // Make sure the count is as expected + $this->assertCount(3, $objects); + } + + public function testSoftDeleteLeavesRow() + { + $model = new ExampleModel(); + $this->setPrivateProperty($model, 'useSoftDeletes', true); + $this->setPrivateProperty($model, 'tempUseSoftDeletes', true); + + $object = $model->first(); + $model->delete($object->id); + + // The model should no longer find it + $this->assertNull($model->find($object->id)); + + // ... but it should still be in the database + $result = $model->builder()->where('id', $object->id)->get()->getResult(); + + $this->assertCount(1, $result); + } +} diff --git a/tests/session/ExampleSessionTest.php b/tests/session/ExampleSessionTest.php new file mode 100644 index 0000000..6ec0d01 --- /dev/null +++ b/tests/session/ExampleSessionTest.php @@ -0,0 +1,18 @@ +session->set('logged_in', 123); + + $value = $this->session->get('logged_in'); + + $this->assertEquals(123, $value); + } +} diff --git a/tests/unit/HealthTest.php b/tests/unit/HealthTest.php new file mode 100644 index 0000000..1d059d0 --- /dev/null +++ b/tests/unit/HealthTest.php @@ -0,0 +1,33 @@ +assertTrue($test); + } + + public function testBaseUrlHasBeenSet() + { + $env = $config = false; + + // First check in .env + if (is_file(HOMEPATH . '.env')) + { + $env = (bool) preg_grep("/^app\.baseURL = './", file(HOMEPATH . '.env')); + } + + // Then check the actual config file + $reader = new \Tests\Support\Libraries\ConfigReader(); + $config = ! empty($reader->baseUrl); + + $this->assertTrue($env || $config); + } +} diff --git a/vendor/autoload.php b/vendor/autoload.php new file mode 100644 index 0000000..fef5340 --- /dev/null +++ b/vendor/autoload.php @@ -0,0 +1,7 @@ + /dev/null; cd "../phpunit/phpunit" && pwd) + +if [ -d /proc/cygdrive ]; then + case $(which php) in + $(readlink -n /proc/cygdrive)/*) + # We are in Cygwin using Windows php, so the path must be translated + dir=$(cygpath -m "$dir"); + ;; + esac +fi + +"${dir}/phpunit" "$@" diff --git a/vendor/bin/phpunit.bat b/vendor/bin/phpunit.bat new file mode 100644 index 0000000..b177923 --- /dev/null +++ b/vendor/bin/phpunit.bat @@ -0,0 +1,4 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/../phpunit/phpunit/phpunit +php "%BIN_TARGET%" %* diff --git a/vendor/codeigniter4/framework/.gitignore b/vendor/codeigniter4/framework/.gitignore new file mode 100644 index 0000000..11abea6 --- /dev/null +++ b/vendor/codeigniter4/framework/.gitignore @@ -0,0 +1,127 @@ +#------------------------- +# Operating Specific Junk Files +#------------------------- + +# OS X +.DS_Store +.AppleDouble +.LSOverride + +# OS X Thumbnails +._* + +# Windows image file caches +Thumbs.db +ehthumbs.db +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# Linux +*~ + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +#------------------------- +# Environment Files +#------------------------- +# These should never be under version control, +# as it poses a security risk. +.env +.vagrant +Vagrantfile + +#------------------------- +# Temporary Files +#------------------------- +writable/cache/* +!writable/cache/index.html + +writable/logs/* +!writable/logs/index.html + +writable/session/* +!writable/session/index.html + +writable/uploads/* +!writable/uploads/index.html + +writable/debugbar/* + +php_errors.log + +#------------------------- +# User Guide Temp Files +#------------------------- +user_guide_src/build/* +user_guide_src/cilexer/build/* +user_guide_src/cilexer/dist/* +user_guide_src/cilexer/pycilexer.egg-info/* + +#------------------------- +# Test Files +#------------------------- +tests/coverage* + +# Don't save phpunit under version control. +phpunit + +#------------------------- +# Composer +#------------------------- +vendor/ + +#------------------------- +# IDE / Development Files +#------------------------- + +# Modules Testing +_modules/* + +# phpenv local config +.php-version + +# Jetbrains editors (PHPStorm, etc) +.idea/ +*.iml + +# Netbeans +nbproject/ +build/ +nbbuild/ +dist/ +nbdist/ +nbactions.xml +nb-configuration.xml +.nb-gradle/ + +# Sublime Text +*.tmlanguage.cache +*.tmPreferences.cache +*.stTheme.cache +*.sublime-workspace +*.sublime-project +.phpintel +/api/ + +# Visual Studio Code +.vscode/ + +/results/ +/phpunit*.xml +/.phpunit.*.cache + diff --git a/vendor/codeigniter4/framework/README.md b/vendor/codeigniter4/framework/README.md new file mode 100644 index 0000000..275f015 --- /dev/null +++ b/vendor/codeigniter4/framework/README.md @@ -0,0 +1,57 @@ +# CodeIgniter 4 Framework + +## What is CodeIgniter? + +CodeIgniter is a PHP full-stack web framework that is light, fast, flexible, and secure. +More information can be found at the [official site](http://codeigniter.com). + +This repository holds the distributable version of the framework, +including the user guide. It has been built from the +[development repository](https://github.com/codeigniter4/CodeIgniter4). + +More information about the plans for version 4 can be found in [the announcement](http://forum.codeigniter.com/thread-62615.html) on the forums. + +The user guide corresponding to this version of the framework can be found +[here](https://codeigniter4.github.io/userguide/). + + +## Important Change with index.php + +`index.php` is no longer in the root of the project! It has been moved inside the *public* folder, +for better security and separation of components. + +This means that you should configure your web server to "point" to your project's *public* folder, and +not to the project root. A better practice would be to configure a virtual host to point there. A poor practice would be to point your web server to the project root and expect to enter *public/...*, as the rest of your logic and the +framework are exposed. + +**Please** read the user guide for a better explanation of how CI4 works! +The user guide updating and deployment is a bit awkward at the moment, but we are working on it! + +## Repository Management + +We use Github issues, in our main repository, to track **BUGS** and to track approved **DEVELOPMENT** work packages. +We use our [forum](http://forum.codeigniter.com) to provide SUPPORT and to discuss +FEATURE REQUESTS. + +This repository is a "distribution" one, built by our release preparation script. +Problems with it can be raised on our forum, or as issues in the main repository. + +## Contributing + +We welcome contributions from the community. + +Please read the [*Contributing to CodeIgniter*](https://github.com/codeigniter4/CodeIgniter4/blob/develop/contributing.md) section in the development repository. + +## Server Requirements + +PHP version 7.2 or higher is required, with the following extensions installed: + +- [intl](http://php.net/manual/en/intl.requirements.php) +- [libcurl](http://php.net/manual/en/curl.requirements.php) if you plan to use the HTTP\CURLRequest library + +Additionally, make sure that the following extensions are enabled in your PHP: + +- json (enabled by default - don't turn it off) +- [mbstring](http://php.net/manual/en/mbstring.installation.php) +- [mysqlnd](http://php.net/manual/en/mysqlnd.install.php) +- xml (enabled by default - don't turn it off) diff --git a/vendor/codeigniter4/framework/app/.htaccess b/vendor/codeigniter4/framework/app/.htaccess new file mode 100644 index 0000000..f24db0a --- /dev/null +++ b/vendor/codeigniter4/framework/app/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + diff --git a/vendor/codeigniter4/framework/app/Common.php b/vendor/codeigniter4/framework/app/Common.php new file mode 100644 index 0000000..780ba3f --- /dev/null +++ b/vendor/codeigniter4/framework/app/Common.php @@ -0,0 +1,15 @@ + SYSTEMPATH, + * 'App' => APPPATH + * ]; + * + * @var array + */ + public $psr4 = [ + APP_NAMESPACE => APPPATH, // For custom app namespace + 'Config' => APPPATH . 'Config', + ]; + + /** + * ------------------------------------------------------------------- + * Class Map + * ------------------------------------------------------------------- + * The class map provides a map of class names and their exact + * location on the drive. Classes loaded in this manner will have + * slightly faster performance because they will not have to be + * searched for within one or more directories as they would if they + * were being autoloaded through a namespace. + * + * Prototype: + * + * $classmap = [ + * 'MyClass' => '/path/to/class/file.php' + * ]; + * + * @var array + */ + public $classmap = []; +} diff --git a/vendor/codeigniter4/framework/app/Config/Boot/development.php b/vendor/codeigniter4/framework/app/Config/Boot/development.php new file mode 100644 index 0000000..63fdd88 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Boot/development.php @@ -0,0 +1,32 @@ + '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, + ]; + + /* + | ------------------------------------------------------------------------- + | Redis settings + | ------------------------------------------------------------------------- + | Your Redis server can be specified below, if you are using + | the Redis or Predis drivers. + | + */ + public $redis = [ + 'host' => '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, + ]; + + /* + |-------------------------------------------------------------------------- + | Available Cache Handlers + |-------------------------------------------------------------------------- + | + | This is an array of cache engine alias' and class names. Only engines + | that are listed here are allowed to be used. + | + */ + public $validHandlers = [ + 'dummy' => \CodeIgniter\Cache\Handlers\DummyHandler::class, + 'file' => \CodeIgniter\Cache\Handlers\FileHandler::class, + 'memcached' => \CodeIgniter\Cache\Handlers\MemcachedHandler::class, + 'predis' => \CodeIgniter\Cache\Handlers\PredisHandler::class, + 'redis' => \CodeIgniter\Cache\Handlers\RedisHandler::class, + 'wincache' => \CodeIgniter\Cache\Handlers\WincacheHandler::class, + ]; +} diff --git a/vendor/codeigniter4/framework/app/Config/Constants.php b/vendor/codeigniter4/framework/app/Config/Constants.php new file mode 100644 index 0000000..b25f71c --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Constants.php @@ -0,0 +1,77 @@ + '', + 'hostname' => 'localhost', + 'username' => '', + 'password' => '', + 'database' => '', + 'DBDriver' => 'MySQLi', + 'DBPrefix' => '', + 'pConnect' => false, + 'DBDebug' => (ENVIRONMENT !== 'production'), + 'cacheOn' => false, + 'cacheDir' => '', + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + 'port' => 3306, + ]; + + /** + * This database connection is used when + * running PHPUnit database tests. + * + * @var array + */ + public $tests = [ + 'DSN' => '', + 'hostname' => '127.0.0.1', + 'username' => '', + 'password' => '', + 'database' => ':memory:', + 'DBDriver' => 'SQLite3', + 'DBPrefix' => 'db_', // Needed to ensure we're working correctly with prefixes live. DO NOT REMOVE FOR CI DEVS + 'pConnect' => false, + 'DBDebug' => (ENVIRONMENT !== 'production'), + 'cacheOn' => false, + 'cacheDir' => '', + 'charset' => 'utf8', + 'DBCollat' => 'utf8_general_ci', + 'swapPre' => '', + 'encrypt' => false, + 'compress' => false, + 'strictOn' => false, + 'failover' => [], + 'port' => 3306, + ]; + + //-------------------------------------------------------------------- + + public function __construct() + { + parent::__construct(); + + // Ensure that we always set the database group to 'tests' if + // we are currently running an automated test suite, so that + // we don't overwrite live data on accident. + if (ENVIRONMENT === 'testing') + { + $this->defaultGroup = 'tests'; + + // Under Travis-CI, we can set an ENV var named 'DB_GROUP' + // so that we can test against multiple databases. + if ($group = getenv('DB')) + { + if (is_file(TESTPATH . 'travis/Database.php')) + { + require TESTPATH . 'travis/Database.php'; + + if (! empty($dbconfig) && array_key_exists($group, $dbconfig)) + { + $this->tests = $dbconfig[$group]; + } + } + } + } + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/app/Config/DocTypes.php b/vendor/codeigniter4/framework/app/Config/DocTypes.php new file mode 100644 index 0000000..67d5dd2 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/DocTypes.php @@ -0,0 +1,33 @@ + '', + 'xhtml1-strict' => '', + 'xhtml1-trans' => '', + 'xhtml1-frame' => '', + 'xhtml-basic11' => '', + 'html5' => '', + 'html4-strict' => '', + 'html4-trans' => '', + 'html4-frame' => '', + 'mathml1' => '', + 'mathml2' => '', + 'svg10' => '', + 'svg11' => '', + 'svg11-basic' => '', + 'svg11-tiny' => '', + 'xhtml-math-svg-xh' => '', + 'xhtml-math-svg-sh' => '', + 'xhtml-rdfa-1' => '', + 'xhtml-rdfa-2' => '', + ]; +} diff --git a/vendor/codeigniter4/framework/app/Config/Email.php b/vendor/codeigniter4/framework/app/Config/Email.php new file mode 100644 index 0000000..d9ca142 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Email.php @@ -0,0 +1,171 @@ + 0) + { + ob_end_flush(); + } + + ob_start(function ($buffer) { + return $buffer; + }); + } + + /* + * -------------------------------------------------------------------- + * Debug Toolbar Listeners. + * -------------------------------------------------------------------- + * If you delete, they will no longer be collected. + */ + if (ENVIRONMENT !== 'production') + { + Events::on('DBQuery', 'CodeIgniter\Debug\Toolbar\Collectors\Database::collect'); + Services::toolbar()->respond(); + } +}); diff --git a/vendor/codeigniter4/framework/app/Config/Exceptions.php b/vendor/codeigniter4/framework/app/Config/Exceptions.php new file mode 100644 index 0000000..5fe33d3 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Exceptions.php @@ -0,0 +1,42 @@ + \CodeIgniter\Filters\CSRF::class, + 'toolbar' => \CodeIgniter\Filters\DebugToolbar::class, + 'honeypot' => \CodeIgniter\Filters\Honeypot::class, + ]; + + // Always applied before every request + public $globals = [ + 'before' => [ + //'honeypot' + // 'csrf', + ], + 'after' => [ + 'toolbar', + //'honeypot' + ], + ]; + + // Works on all of a particular HTTP method + // (GET, POST, etc) as BEFORE filters only + // like: 'post' => ['CSRF', 'throttle'], + public $methods = []; + + // List filter aliases and any before/after uri patterns + // that they should run on, like: + // 'isLoggedIn' => ['before' => ['account/*', 'profiles/*']], + public $filters = []; +} diff --git a/vendor/codeigniter4/framework/app/Config/ForeignCharacters.php b/vendor/codeigniter4/framework/app/Config/ForeignCharacters.php new file mode 100644 index 0000000..8ee6f11 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/ForeignCharacters.php @@ -0,0 +1,6 @@ + \CodeIgniter\Format\JSONFormatter::class, + 'application/xml' => \CodeIgniter\Format\XMLFormatter::class, + 'text/xml' => \CodeIgniter\Format\XMLFormatter::class, + ]; + + /* + |-------------------------------------------------------------------------- + | Formatters Options + |-------------------------------------------------------------------------- + | + | Additional Options to adjust default formatters behaviour. + | For each mime type, list the additional options that should be used. + | + */ + public $formatterOptions = [ + 'application/json' => JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES, + 'application/xml' => 0, + 'text/xml' => 0, + ]; + //-------------------------------------------------------------------- + + /** + * A Factory method to return the appropriate formatter for the given mime type. + * + * @param string $mime + * + * @return \CodeIgniter\Format\FormatterInterface + */ + public function getFormatter(string $mime) + { + if (! array_key_exists($mime, $this->formatters)) + { + throw new \InvalidArgumentException('No Formatter defined for mime type: ' . $mime); + } + + $class = $this->formatters[$mime]; + + if (! class_exists($class)) + { + throw new \BadMethodCallException($class . ' is not a valid Formatter.'); + } + + return new $class(); + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/app/Config/Honeypot.php b/vendor/codeigniter4/framework/app/Config/Honeypot.php new file mode 100644 index 0000000..3d9e372 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Honeypot.php @@ -0,0 +1,42 @@ +{label}'; + + /** + * Honeypot container + * + * @var string + */ + public $container = '
{template}
'; +} diff --git a/vendor/codeigniter4/framework/app/Config/Images.php b/vendor/codeigniter4/framework/app/Config/Images.php new file mode 100644 index 0000000..a416b8b --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Images.php @@ -0,0 +1,31 @@ + \CodeIgniter\Images\Handlers\GDHandler::class, + 'imagick' => \CodeIgniter\Images\Handlers\ImageMagickHandler::class, + ]; +} diff --git a/vendor/codeigniter4/framework/app/Config/Kint.php b/vendor/codeigniter4/framework/app/Config/Kint.php new file mode 100644 index 0000000..09db83d --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Kint.php @@ -0,0 +1,62 @@ + [ + + /* + * The log levels that this handler will handle. + */ + 'handles' => [ + 'critical', + 'alert', + 'emergency', + 'debug', + 'error', + 'info', + 'notice', + 'warning', + ], + + /* + * The default filename extension for log files. + * An extension of 'php' allows for protecting the log files via basic + * scripting, when they are to be stored under a publicly accessible directory. + * + * Note: Leaving it blank will default to 'log'. + */ + 'fileExtension' => '', + + /* + * The file system permissions to be applied on newly created log files. + * + * IMPORTANT: This MUST be an integer (no quotes) and you MUST use octal + * integer notation (i.e. 0700, 0644, etc.) + */ + 'filePermissions' => 0644, + + /* + * Logging Directory Path + * + * By default, logs are written to WRITEPATH . 'logs/' + * Specify a different destination here, if desired. + */ + 'path' => '', + ], + + /** + * The ChromeLoggerHandler requires the use of the Chrome web browser + * and the ChromeLogger extension. Uncomment this block to use it. + */ + // 'CodeIgniter\Log\Handlers\ChromeLoggerHandler' => [ + // /* + // * The log levels that this handler will handle. + // */ + // 'handles' => ['critical', 'alert', 'emergency', 'debug', + // 'error', 'info', 'notice', 'warning'], + // ] + ]; +} diff --git a/vendor/codeigniter4/framework/app/Config/Migrations.php b/vendor/codeigniter4/framework/app/Config/Migrations.php new file mode 100644 index 0000000..b83fe90 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Migrations.php @@ -0,0 +1,50 @@ + php spark migrate:create + | + | Typical formats: + | YmdHis_ + | Y-m-d-His_ + | Y_m_d_His_ + | + */ + public $timestampFormat = 'Y-m-d-His_'; + +} diff --git a/vendor/codeigniter4/framework/app/Config/Mimes.php b/vendor/codeigniter4/framework/app/Config/Mimes.php new file mode 100644 index 0000000..41014d4 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Mimes.php @@ -0,0 +1,530 @@ + [ + 'application/mac-binhex40', + 'application/mac-binhex', + 'application/x-binhex40', + 'application/x-mac-binhex40', + ], + 'cpt' => 'application/mac-compactpro', + 'csv' => [ + 'text/csv', + 'text/x-comma-separated-values', + 'text/comma-separated-values', + 'application/octet-stream', + 'application/vnd.ms-excel', + 'application/x-csv', + 'text/x-csv', + 'application/csv', + 'application/excel', + 'application/vnd.msexcel', + 'text/plain', + ], + 'bin' => [ + 'application/macbinary', + 'application/mac-binary', + 'application/octet-stream', + 'application/x-binary', + 'application/x-macbinary', + ], + 'dms' => 'application/octet-stream', + 'lha' => 'application/octet-stream', + 'lzh' => 'application/octet-stream', + 'exe' => [ + 'application/octet-stream', + 'application/x-msdownload', + ], + 'class' => 'application/octet-stream', + 'psd' => [ + 'application/x-photoshop', + 'image/vnd.adobe.photoshop', + ], + 'so' => 'application/octet-stream', + 'sea' => 'application/octet-stream', + 'dll' => 'application/octet-stream', + 'oda' => 'application/oda', + 'pdf' => [ + 'application/pdf', + 'application/force-download', + 'application/x-download', + 'binary/octet-stream', + ], + 'ai' => [ + 'application/pdf', + 'application/postscript', + ], + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + 'smi' => 'application/smil', + 'smil' => 'application/smil', + 'mif' => 'application/vnd.mif', + 'xls' => [ + 'application/vnd.ms-excel', + 'application/msexcel', + 'application/x-msexcel', + 'application/x-ms-excel', + 'application/x-excel', + 'application/x-dos_ms_excel', + 'application/xls', + 'application/x-xls', + 'application/excel', + 'application/download', + 'application/vnd.ms-office', + 'application/msword', + ], + 'ppt' => [ + 'application/vnd.ms-powerpoint', + 'application/powerpoint', + 'application/vnd.ms-office', + 'application/msword', + ], + 'pptx' => [ + 'application/vnd.openxmlformats-officedocument.presentationml.presentation', + 'application/x-zip', + 'application/zip', + ], + 'wbxml' => 'application/wbxml', + 'wmlc' => 'application/wmlc', + 'dcr' => 'application/x-director', + 'dir' => 'application/x-director', + 'dxr' => 'application/x-director', + 'dvi' => 'application/x-dvi', + 'gtar' => 'application/x-gtar', + 'gz' => 'application/x-gzip', + 'gzip' => 'application/x-gzip', + 'php' => [ + 'application/x-php', + 'application/x-httpd-php', + 'application/php', + 'text/php', + 'text/x-php', + 'application/x-httpd-php-source', + ], + 'php4' => 'application/x-httpd-php', + 'php3' => 'application/x-httpd-php', + 'phtml' => 'application/x-httpd-php', + 'phps' => 'application/x-httpd-php-source', + 'js' => [ + 'application/x-javascript', + 'text/plain', + ], + 'swf' => 'application/x-shockwave-flash', + 'sit' => 'application/x-stuffit', + 'tar' => 'application/x-tar', + 'tgz' => [ + 'application/x-tar', + 'application/x-gzip-compressed', + ], + 'z' => 'application/x-compress', + 'xhtml' => 'application/xhtml+xml', + 'xht' => 'application/xhtml+xml', + 'zip' => [ + 'application/x-zip', + 'application/zip', + 'application/x-zip-compressed', + 'application/s-compressed', + 'multipart/x-zip', + ], + 'rar' => [ + 'application/x-rar', + 'application/rar', + 'application/x-rar-compressed', + ], + 'mid' => 'audio/midi', + 'midi' => 'audio/midi', + 'mpga' => 'audio/mpeg', + 'mp2' => 'audio/mpeg', + 'mp3' => [ + 'audio/mpeg', + 'audio/mpg', + 'audio/mpeg3', + 'audio/mp3', + ], + 'aif' => [ + 'audio/x-aiff', + 'audio/aiff', + ], + 'aiff' => [ + 'audio/x-aiff', + 'audio/aiff', + ], + 'aifc' => 'audio/x-aiff', + 'ram' => 'audio/x-pn-realaudio', + 'rm' => 'audio/x-pn-realaudio', + 'rpm' => 'audio/x-pn-realaudio-plugin', + 'ra' => 'audio/x-realaudio', + 'rv' => 'video/vnd.rn-realvideo', + 'wav' => [ + 'audio/x-wav', + 'audio/wave', + 'audio/wav', + ], + 'bmp' => [ + 'image/bmp', + 'image/x-bmp', + 'image/x-bitmap', + 'image/x-xbitmap', + 'image/x-win-bitmap', + 'image/x-windows-bmp', + 'image/ms-bmp', + 'image/x-ms-bmp', + 'application/bmp', + 'application/x-bmp', + 'application/x-win-bitmap', + ], + 'gif' => 'image/gif', + 'jpg' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jpeg' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jpe' => [ + 'image/jpeg', + 'image/pjpeg', + ], + 'jp2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'j2k' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpf' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpg2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpx' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'jpm' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'mj2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'mjp2' => [ + 'image/jp2', + 'video/mj2', + 'image/jpx', + 'image/jpm', + ], + 'png' => [ + 'image/png', + 'image/x-png', + ], + 'tif' => 'image/tiff', + 'tiff' => 'image/tiff', + 'css' => [ + 'text/css', + 'text/plain', + ], + 'html' => [ + 'text/html', + 'text/plain', + ], + 'htm' => [ + 'text/html', + 'text/plain', + ], + 'shtml' => [ + 'text/html', + 'text/plain', + ], + 'txt' => 'text/plain', + 'text' => 'text/plain', + 'log' => [ + 'text/plain', + 'text/x-log', + ], + 'rtx' => 'text/richtext', + 'rtf' => 'text/rtf', + 'xml' => [ + 'application/xml', + 'text/xml', + 'text/plain', + ], + 'xsl' => [ + 'application/xml', + 'text/xsl', + 'text/xml', + ], + 'mpeg' => 'video/mpeg', + 'mpg' => 'video/mpeg', + 'mpe' => 'video/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + 'avi' => [ + 'video/x-msvideo', + 'video/msvideo', + 'video/avi', + 'application/x-troff-msvideo', + ], + 'movie' => 'video/x-sgi-movie', + 'doc' => [ + 'application/msword', + 'application/vnd.ms-office', + ], + 'docx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + 'application/x-zip', + ], + 'dot' => [ + 'application/msword', + 'application/vnd.ms-office', + ], + 'dotx' => [ + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', + 'application/zip', + 'application/msword', + ], + 'xlsx' => [ + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', + 'application/zip', + 'application/vnd.ms-excel', + 'application/msword', + 'application/x-zip', + ], + 'word' => [ + 'application/msword', + 'application/octet-stream', + ], + 'xl' => 'application/excel', + 'eml' => 'message/rfc822', + 'json' => [ + 'application/json', + 'text/json', + ], + 'pem' => [ + 'application/x-x509-user-cert', + 'application/x-pem-file', + 'application/octet-stream', + ], + 'p10' => [ + 'application/x-pkcs10', + 'application/pkcs10', + ], + 'p12' => 'application/x-pkcs12', + 'p7a' => 'application/x-pkcs7-signature', + 'p7c' => [ + 'application/pkcs7-mime', + 'application/x-pkcs7-mime', + ], + 'p7m' => [ + 'application/pkcs7-mime', + 'application/x-pkcs7-mime', + ], + 'p7r' => 'application/x-pkcs7-certreqresp', + 'p7s' => 'application/pkcs7-signature', + 'crt' => [ + 'application/x-x509-ca-cert', + 'application/x-x509-user-cert', + 'application/pkix-cert', + ], + 'crl' => [ + 'application/pkix-crl', + 'application/pkcs-crl', + ], + 'der' => 'application/x-x509-ca-cert', + 'kdb' => 'application/octet-stream', + 'pgp' => 'application/pgp', + 'gpg' => 'application/gpg-keys', + 'sst' => 'application/octet-stream', + 'csr' => 'application/octet-stream', + 'rsa' => 'application/x-pkcs7', + 'cer' => [ + 'application/pkix-cert', + 'application/x-x509-ca-cert', + ], + '3g2' => 'video/3gpp2', + '3gp' => [ + 'video/3gp', + 'video/3gpp', + ], + 'mp4' => 'video/mp4', + 'm4a' => 'audio/x-m4a', + 'f4v' => [ + 'video/mp4', + 'video/x-f4v', + ], + 'flv' => 'video/x-flv', + 'webm' => 'video/webm', + 'aac' => 'audio/x-acc', + 'm4u' => 'application/vnd.mpegurl', + 'm3u' => 'text/plain', + 'xspf' => 'application/xspf+xml', + 'vlc' => 'application/videolan', + 'wmv' => [ + 'video/x-ms-wmv', + 'video/x-ms-asf', + ], + 'au' => 'audio/x-au', + 'ac3' => 'audio/ac3', + 'flac' => 'audio/x-flac', + 'ogg' => [ + 'audio/ogg', + 'video/ogg', + 'application/ogg', + ], + 'kmz' => [ + 'application/vnd.google-earth.kmz', + 'application/zip', + 'application/x-zip', + ], + 'kml' => [ + 'application/vnd.google-earth.kml+xml', + 'application/xml', + 'text/xml', + ], + 'ics' => 'text/calendar', + 'ical' => 'text/calendar', + 'zsh' => 'text/x-scriptzsh', + '7zip' => [ + 'application/x-compressed', + 'application/x-zip-compressed', + 'application/zip', + 'multipart/x-zip', + ], + 'cdr' => [ + 'application/cdr', + 'application/coreldraw', + 'application/x-cdr', + 'application/x-coreldraw', + 'image/cdr', + 'image/x-cdr', + 'zz-application/zz-winassoc-cdr', + ], + 'wma' => [ + 'audio/x-ms-wma', + 'video/x-ms-asf', + ], + 'jar' => [ + 'application/java-archive', + 'application/x-java-application', + 'application/x-jar', + 'application/x-compressed', + ], + 'svg' => [ + 'image/svg+xml', + 'application/xml', + 'text/xml', + ], + 'vcf' => 'text/x-vcard', + 'srt' => [ + 'text/srt', + 'text/plain', + ], + 'vtt' => [ + 'text/vtt', + 'text/plain', + ], + 'ico' => [ + 'image/x-icon', + 'image/x-ico', + 'image/vnd.microsoft.icon', + ], + ]; + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the best mime type for the given file extension. + * + * @param string $extension + * + * @return string|null The mime type found, or none if unable to determine. + */ + public static function guessTypeFromExtension(string $extension) + { + $extension = trim(strtolower($extension), '. '); + + if (! array_key_exists($extension, static::$mimes)) + { + return null; + } + + return is_array(static::$mimes[$extension]) ? static::$mimes[$extension][0] : static::$mimes[$extension]; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the best file extension for a given mime type. + * + * @param string $type + * @param string $proposed_extension - default extension (in case there is more than one with the same mime type) + * + * @return string|null The extension determined, or null if unable to match. + */ + public static function guessExtensionFromType(string $type, ?string $proposed_extension = null) + { + $type = trim(strtolower($type), '. '); + + $proposed_extension = trim(strtolower($proposed_extension)); + + if (! is_null($proposed_extension) && array_key_exists($proposed_extension, static::$mimes) && in_array($type, is_string(static::$mimes[$proposed_extension]) ? [static::$mimes[$proposed_extension]] : static::$mimes[$proposed_extension])) + { + return $proposed_extension; + } + + foreach (static::$mimes as $ext => $types) + { + if ((is_string($types) && $types === $type) || (is_array($types) && in_array($type, $types))) + { + return $ext; + } + } + + return null; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/app/Config/Modules.php b/vendor/codeigniter4/framework/app/Config/Modules.php new file mode 100644 index 0000000..40cb987 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Modules.php @@ -0,0 +1,45 @@ + 'CodeIgniter\Pager\Views\default_full', + 'default_simple' => 'CodeIgniter\Pager\Views\default_simple', + 'default_head' => 'CodeIgniter\Pager\Views\default_head', + ]; + + /* + |-------------------------------------------------------------------------- + | Items Per Page + |-------------------------------------------------------------------------- + | + | The default number of results shown in a single page. + | + */ + public $perPage = 20; +} diff --git a/vendor/codeigniter4/framework/app/Config/Paths.php b/vendor/codeigniter4/framework/app/Config/Paths.php new file mode 100644 index 0000000..6ca2d37 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Paths.php @@ -0,0 +1,73 @@ +setDefaultNamespace('App\Controllers'); +$routes->setDefaultController('Home'); +$routes->setDefaultMethod('index'); +$routes->setTranslateURIDashes(false); +$routes->set404Override(); +$routes->setAutoRoute(true); + +/** + * -------------------------------------------------------------------- + * Route Definitions + * -------------------------------------------------------------------- + */ + +// We get a performance increase by specifying the default +// route since we don't have to scan directories. +$routes->get('/', 'Home::index'); + +/** + * -------------------------------------------------------------------- + * Additional Routing + * -------------------------------------------------------------------- + * + * There will often be times that you need additional routing and you + * need it to be able to override any defaults in this file. Environment + * based routes is one such time. require() additional route files here + * to make that happen. + * + * You will have access to the $routes object within that file without + * needing to reload it. + */ +if (file_exists(APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php')) +{ + require APPPATH . 'Config/' . ENVIRONMENT . '/Routes.php'; +} diff --git a/vendor/codeigniter4/framework/app/Config/Services.php b/vendor/codeigniter4/framework/app/Config/Services.php new file mode 100644 index 0000000..c58da70 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Services.php @@ -0,0 +1,30 @@ + 'Windows 10', + 'windows nt 6.3' => 'Windows 8.1', + 'windows nt 6.2' => 'Windows 8', + 'windows nt 6.1' => 'Windows 7', + 'windows nt 6.0' => 'Windows Vista', + 'windows nt 5.2' => 'Windows 2003', + 'windows nt 5.1' => 'Windows XP', + 'windows nt 5.0' => 'Windows 2000', + 'windows nt 4.0' => 'Windows NT 4.0', + 'winnt4.0' => 'Windows NT 4.0', + 'winnt 4.0' => 'Windows NT', + 'winnt' => 'Windows NT', + 'windows 98' => 'Windows 98', + 'win98' => 'Windows 98', + 'windows 95' => 'Windows 95', + 'win95' => 'Windows 95', + 'windows phone' => 'Windows Phone', + 'windows' => 'Unknown Windows OS', + 'android' => 'Android', + 'blackberry' => 'BlackBerry', + 'iphone' => 'iOS', + 'ipad' => 'iOS', + 'ipod' => 'iOS', + 'os x' => 'Mac OS X', + 'ppc mac' => 'Power PC Mac', + 'freebsd' => 'FreeBSD', + 'ppc' => 'Macintosh', + 'linux' => 'Linux', + 'debian' => 'Debian', + 'sunos' => 'Sun Solaris', + 'beos' => 'BeOS', + 'apachebench' => 'ApacheBench', + 'aix' => 'AIX', + 'irix' => 'Irix', + 'osf' => 'DEC OSF', + 'hp-ux' => 'HP-UX', + 'netbsd' => 'NetBSD', + 'bsdi' => 'BSDi', + 'openbsd' => 'OpenBSD', + 'gnu' => 'GNU/Linux', + 'unix' => 'Unknown Unix OS', + 'symbian' => 'Symbian OS', + ]; + + // The order of this array should NOT be changed. Many browsers return + // multiple browser types so we want to identify the sub-type first. + public $browsers = [ + 'OPR' => 'Opera', + 'Flock' => 'Flock', + 'Edge' => 'Spartan', + 'Chrome' => 'Chrome', + // Opera 10+ always reports Opera/9.80 and appends Version/ to the user agent string + 'Opera.*?Version' => 'Opera', + 'Opera' => 'Opera', + 'MSIE' => 'Internet Explorer', + 'Internet Explorer' => 'Internet Explorer', + 'Trident.* rv' => 'Internet Explorer', + 'Shiira' => 'Shiira', + 'Firefox' => 'Firefox', + 'Chimera' => 'Chimera', + 'Phoenix' => 'Phoenix', + 'Firebird' => 'Firebird', + 'Camino' => 'Camino', + 'Netscape' => 'Netscape', + 'OmniWeb' => 'OmniWeb', + 'Safari' => 'Safari', + 'Mozilla' => 'Mozilla', + 'Konqueror' => 'Konqueror', + 'icab' => 'iCab', + 'Lynx' => 'Lynx', + 'Links' => 'Links', + 'hotjava' => 'HotJava', + 'amaya' => 'Amaya', + 'IBrowse' => 'IBrowse', + 'Maxthon' => 'Maxthon', + 'Ubuntu' => 'Ubuntu Web Browser', + 'Vivaldi' => 'Vivaldi', + ]; + + public $mobiles = [ + // legacy array, old values commented out + 'mobileexplorer' => 'Mobile Explorer', + // 'openwave' => 'Open Wave', + // 'opera mini' => 'Opera Mini', + // 'operamini' => 'Opera Mini', + // 'elaine' => 'Palm', + 'palmsource' => 'Palm', + // 'digital paths' => 'Palm', + // 'avantgo' => 'Avantgo', + // 'xiino' => 'Xiino', + 'palmscape' => 'Palmscape', + // 'nokia' => 'Nokia', + // 'ericsson' => 'Ericsson', + // 'blackberry' => 'BlackBerry', + // 'motorola' => 'Motorola' + + // Phones and Manufacturers + 'motorola' => 'Motorola', + 'nokia' => 'Nokia', + 'palm' => 'Palm', + 'iphone' => 'Apple iPhone', + 'ipad' => 'iPad', + 'ipod' => 'Apple iPod Touch', + 'sony' => 'Sony Ericsson', + 'ericsson' => 'Sony Ericsson', + 'blackberry' => 'BlackBerry', + 'cocoon' => 'O2 Cocoon', + 'blazer' => 'Treo', + 'lg' => 'LG', + 'amoi' => 'Amoi', + 'xda' => 'XDA', + 'mda' => 'MDA', + 'vario' => 'Vario', + 'htc' => 'HTC', + 'samsung' => 'Samsung', + 'sharp' => 'Sharp', + 'sie-' => 'Siemens', + 'alcatel' => 'Alcatel', + 'benq' => 'BenQ', + 'ipaq' => 'HP iPaq', + 'mot-' => 'Motorola', + 'playstation portable' => 'PlayStation Portable', + 'playstation 3' => 'PlayStation 3', + 'playstation vita' => 'PlayStation Vita', + 'hiptop' => 'Danger Hiptop', + 'nec-' => 'NEC', + 'panasonic' => 'Panasonic', + 'philips' => 'Philips', + 'sagem' => 'Sagem', + 'sanyo' => 'Sanyo', + 'spv' => 'SPV', + 'zte' => 'ZTE', + 'sendo' => 'Sendo', + 'nintendo dsi' => 'Nintendo DSi', + 'nintendo ds' => 'Nintendo DS', + 'nintendo 3ds' => 'Nintendo 3DS', + 'wii' => 'Nintendo Wii', + 'open web' => 'Open Web', + 'openweb' => 'OpenWeb', + + // Operating Systems + 'android' => 'Android', + 'symbian' => 'Symbian', + 'SymbianOS' => 'SymbianOS', + 'elaine' => 'Palm', + 'series60' => 'Symbian S60', + 'windows ce' => 'Windows CE', + + // Browsers + 'obigo' => 'Obigo', + 'netfront' => 'Netfront Browser', + 'openwave' => 'Openwave Browser', + 'mobilexplorer' => 'Mobile Explorer', + 'operamini' => 'Opera Mini', + 'opera mini' => 'Opera Mini', + 'opera mobi' => 'Opera Mobile', + 'fennec' => 'Firefox Mobile', + + // Other + 'digital paths' => 'Digital Paths', + 'avantgo' => 'AvantGo', + 'xiino' => 'Xiino', + 'novarra' => 'Novarra Transcoder', + 'vodafone' => 'Vodafone', + 'docomo' => 'NTT DoCoMo', + 'o2' => 'O2', + + // Fallback + 'mobile' => 'Generic Mobile', + 'wireless' => 'Generic Mobile', + 'j2me' => 'Generic Mobile', + 'midp' => 'Generic Mobile', + 'cldc' => 'Generic Mobile', + 'up.link' => 'Generic Mobile', + 'up.browser' => 'Generic Mobile', + 'smartphone' => 'Generic Mobile', + 'cellphone' => 'Generic Mobile', + ]; + + // There are hundreds of bots but these are the most common. + public $robots = [ + 'googlebot' => 'Googlebot', + 'msnbot' => 'MSNBot', + 'baiduspider' => 'Baiduspider', + 'bingbot' => 'Bing', + 'slurp' => 'Inktomi Slurp', + 'yahoo' => 'Yahoo', + 'ask jeeves' => 'Ask Jeeves', + 'fastcrawler' => 'FastCrawler', + 'infoseek' => 'InfoSeek Robot 1.0', + 'lycos' => 'Lycos', + 'yandex' => 'YandexBot', + 'mediapartners-google' => 'MediaPartners Google', + 'CRAZYWEBCRAWLER' => 'Crazy Webcrawler', + 'adsbot-google' => 'AdsBot Google', + 'feedfetcher-google' => 'Feedfetcher Google', + 'curious george' => 'Curious George', + 'ia_archiver' => 'Alexa Crawler', + 'MJ12bot' => 'Majestic-12', + 'Uptimebot' => 'Uptimebot', + ]; +} diff --git a/vendor/codeigniter4/framework/app/Config/Validation.php b/vendor/codeigniter4/framework/app/Config/Validation.php new file mode 100644 index 0000000..97f08c7 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/Validation.php @@ -0,0 +1,36 @@ + 'CodeIgniter\Validation\Views\list', + 'single' => 'CodeIgniter\Validation\Views\single', + ]; + + //-------------------------------------------------------------------- + // Rules + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/app/Config/View.php b/vendor/codeigniter4/framework/app/Config/View.php new file mode 100644 index 0000000..f66b253 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Config/View.php @@ -0,0 +1,34 @@ +session = \Config\Services::session(); + } + +} diff --git a/vendor/codeigniter4/framework/app/Controllers/Home.php b/vendor/codeigniter4/framework/app/Controllers/Home.php new file mode 100644 index 0000000..8798cdd --- /dev/null +++ b/vendor/codeigniter4/framework/app/Controllers/Home.php @@ -0,0 +1,12 @@ + +Message: +Filename: getFile(), "\n"; ?> +Line Number: getLine(); ?> + + + + Backtrace: + getTrace() as $error): ?> + + + + + + diff --git a/vendor/codeigniter4/framework/app/Views/errors/cli/production.php b/vendor/codeigniter4/framework/app/Views/errors/cli/production.php new file mode 100644 index 0000000..7db744e --- /dev/null +++ b/vendor/codeigniter4/framework/app/Views/errors/cli/production.php @@ -0,0 +1,5 @@ + + + + + 404 Page Not Found + + + + +
+

404 - File Not Found

+ +

+ + + + Sorry! Cannot seem to find the page you were looking for. + +

+
+ + diff --git a/vendor/codeigniter4/framework/app/Views/errors/html/error_exception.php b/vendor/codeigniter4/framework/app/Views/errors/html/error_exception.php new file mode 100644 index 0000000..09fddcb --- /dev/null +++ b/vendor/codeigniter4/framework/app/Views/errors/html/error_exception.php @@ -0,0 +1,401 @@ + + + + + + + + <?= htmlspecialchars($title, ENT_SUBSTITUTE, 'UTF-8') ?> + + + + + + + +
+
+

getCode() ? ' #' . $exception->getCode() : '') ?>

+

+ getMessage() ?> + getMessage())) ?>" + rel="noreferrer" target="_blank">search → +

+
+
+ + +
+

at line

+ + +
+ +
+ +
+ +
+ + + +
+ + +
+ +
    + $row) : ?> + +
  1. +

    + + + + + {PHP internal code} + + + + +   —   + + + ( arguments ) +

    +
+ + getParameters(); + } + foreach ($row['args'] as $key => $value) : ?> + + + + + + +
name : "#$key", ENT_SUBSTITUTE, 'UTF-8') ?>
+
+ + () + + + + +   —   () + +

+ + + +
+ +
+ + + + + + +
+ + +
+ + + +

$

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ + + + + + +

Constants

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ +
+ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Pathuri ?>
HTTP MethodgetMethod(true) ?>
IP AddressgetIPAddress() ?>
Is AJAX Request?isAJAX() ? 'yes' : 'no' ?>
Is CLI Request?isCLI() ? 'yes' : 'no' ?>
Is Secure Request?isSecure() ? 'yes' : 'no' ?>
User AgentgetUserAgent()->getAgentString() ?>
+ + + + + + + + +

$

+ + + + + + + + + + $value) : ?> + + + + + + +
KeyValue
+ + + + ' . print_r($value, true) ?> + +
+ + + + + +
+ No $_GET, $_POST, or $_COOKIE Information to show. +
+ + + + getHeaders(); ?> + + +

Headers

+ + + + + + + + + + + + + + + + + + + + +
HeaderValue
getName(), 'html') ?>getValueLine(), 'html') ?>
+ + +
+ + + setStatusCode(http_response_code()); + ?> +
+ + + + + +
Response StatusgetStatusCode() . ' - ' . $response->getReason() ?>
+ + getHeaders(); ?> + + + +

Headers

+ + + + + + + + + + $value) : ?> + + + + + + +
HeaderValue
getHeaderLine($name), 'html') ?>
+ + +
+ + +
+ + +
    + +
  1. + +
+
+ + +
+ + + + + + + + + + + + + + + + +
Memory Usage
Peak Memory Usage:
Memory Limit:
+ +
+ +
+ +
+ + + + + diff --git a/vendor/codeigniter4/framework/app/Views/errors/html/production.php b/vendor/codeigniter4/framework/app/Views/errors/html/production.php new file mode 100644 index 0000000..cca49c2 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Views/errors/html/production.php @@ -0,0 +1,25 @@ + + + + + + + Whoops! + + + + + +
+ +

Whoops!

+ +

We seem to have hit a snag. Please try again later...

+ +
+ + + + diff --git a/vendor/codeigniter4/framework/app/Views/welcome_message.php b/vendor/codeigniter4/framework/app/Views/welcome_message.php new file mode 100644 index 0000000..f2a7389 --- /dev/null +++ b/vendor/codeigniter4/framework/app/Views/welcome_message.php @@ -0,0 +1,324 @@ + + + + + Welcome to CodeIgniter 4! + + + + + + + + + + + +
+ + + +
+ +

Welcome to CodeIgniter

+ +

The small framework with powerful features

+ +
+ +
+ + + +
+ +

About this page

+ +

The page you are looking at is being generated dynamically by CodeIgniter.

+ +

If you would like to edit this page you will find it located at:

+ +
app/Views/welcome_message.php
+ +

The corresponding controller for this page can be found at:

+ +
app/Controllers/Home.php
+ +
+ +
+ +
+ +

Go further

+ +

+ + Learn +

+ +

The User Guide contains an introduction, tutorial, a number of "how to" + guides, and then reference documentation for the components that make up + the framework. Check the User Guide !

+ +

+ + Discuss +

+ +

CodeIgniter is a community-developed open source project, with several + venues for the community members to gather and exchange ideas. View all + the threads on CodeIgniter's forum, or chat on Slack !

+ +

+ + Contribute +

+ +

CodeIgniter is a community driven project and accepts contributions + of code and documentation from the community. Why not + + join us ?

+ +
+ +
+ + + +
+
+ +

Page rendered in {elapsed_time} seconds

+ +

Environment:

+ +
+ +
+ +

© CodeIgniter Foundation. CodeIgniter is open source project released under the MIT + open source licence.

+ +
+ +
+ + + + + + + + + diff --git a/vendor/codeigniter4/framework/app/index.html b/vendor/codeigniter4/framework/app/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/app/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/codeigniter4/framework/composer.json b/vendor/codeigniter4/framework/composer.json new file mode 100644 index 0000000..3f3b9d5 --- /dev/null +++ b/vendor/codeigniter4/framework/composer.json @@ -0,0 +1,42 @@ +{ + "name": "codeigniter4/framework", + "type": "project", + "description": "The CodeIgniter framework v4", + "homepage": "https://codeigniter.com", + "license": "MIT", + "require": { + "php": ">=7.2", + "ext-curl": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "kint-php/kint": "^3.3", + "laminas/laminas-escaper": "^2.6", + "psr/log": "^1.1" + }, + "require-dev": { + "codeigniter4/codeigniter4-standard": "^1.0", + "fzaninotto/faker": "^1.9@dev", + "mikey179/vfsstream": "1.6.*", + "phpunit/phpunit": "^8.5", + "predis/predis": "^1.1", + "squizlabs/php_codesniffer": "^3.3" + }, + "autoload": { + "psr-4": { + "CodeIgniter\\": "system/" + } + }, + "scripts": { + "post-update-cmd": [ + "@composer dump-autoload", + "CodeIgniter\\ComposerScripts::postUpdate" + ], + "test": "phpunit" + }, + "support": { + "forum": "http://forum.codeigniter.com/", + "source": "https://github.com/codeigniter4/CodeIgniter4", + "slack": "https://codeigniterchat.slack.com" + } +} diff --git a/vendor/codeigniter4/framework/env b/vendor/codeigniter4/framework/env new file mode 100644 index 0000000..11f4161 --- /dev/null +++ b/vendor/codeigniter4/framework/env @@ -0,0 +1,101 @@ +#-------------------------------------------------------------------- +# Example Environment Configuration file +# +# This file can be used as a starting point for your own +# custom .env files, and contains most of the possible settings +# available in a default install. +# +# By default, all of the settings are commented out. If you want +# to override the setting, you must un-comment it by removing the '#' +# at the beginning of the line. +#-------------------------------------------------------------------- + +#-------------------------------------------------------------------- +# ENVIRONMENT +#-------------------------------------------------------------------- + +# CI_ENVIRONMENT = production + +#-------------------------------------------------------------------- +# APP +#-------------------------------------------------------------------- + +# app.baseURL = '' +# app.forceGlobalSecureRequests = false + +# app.sessionDriver = 'CodeIgniter\Session\Handlers\FileHandler' +# app.sessionCookieName = 'ci_session' +# app.sessionSavePath = NULL +# app.sessionMatchIP = false +# app.sessionTimeToUpdate = 300 +# app.sessionRegenerateDestroy = false + +# app.cookiePrefix = '' +# app.cookieDomain = '' +# app.cookiePath = '/' +# app.cookieSecure = false +# app.cookieHTTPOnly = false + +# app.CSRFProtection = false +# app.CSRFTokenName = 'csrf_test_name' +# app.CSRFCookieName = 'csrf_cookie_name' +# app.CSRFExpire = 7200 +# app.CSRFRegenerate = true +# app.CSRFExcludeURIs = [] + +# app.CSPEnabled = false + +#-------------------------------------------------------------------- +# DATABASE +#-------------------------------------------------------------------- + +# database.default.hostname = localhost +# database.default.database = ci4 +# database.default.username = root +# database.default.password = root +# database.default.DBDriver = MySQLi + +# database.tests.hostname = localhost +# database.tests.database = ci4 +# database.tests.username = root +# database.tests.password = root +# database.tests.DBDriver = MySQLi + +#-------------------------------------------------------------------- +# CONTENT SECURITY POLICY +#-------------------------------------------------------------------- + +# contentsecuritypolicy.reportOnly = false +# contentsecuritypolicy.defaultSrc = 'none' +# contentsecuritypolicy.scriptSrc = 'self' +# contentsecuritypolicy.styleSrc = 'self' +# contentsecuritypolicy.imageSrc = 'self' +# contentsecuritypolicy.base_uri = null +# contentsecuritypolicy.childSrc = null +# contentsecuritypolicy.connectSrc = 'self' +# contentsecuritypolicy.fontSrc = null +# contentsecuritypolicy.formAction = null +# contentsecuritypolicy.frameAncestors = null +# contentsecuritypolicy.mediaSrc = null +# contentsecuritypolicy.objectSrc = null +# contentsecuritypolicy.pluginTypes = null +# contentsecuritypolicy.reportURI = null +# contentsecuritypolicy.sandbox = false +# contentsecuritypolicy.upgradeInsecureRequests = false + +#-------------------------------------------------------------------- +# ENCRYPTION +#-------------------------------------------------------------------- + +# encryption.key = +# encryption.driver = OpenSSL + +#-------------------------------------------------------------------- +# HONEYPOT +#-------------------------------------------------------------------- + +# honeypot.hidden = 'true' +# honeypot.label = 'Fill This Field' +# honeypot.name = 'honeypot' +# honeypot.template = '' +# honeypot.container = '
{template}
' diff --git a/vendor/codeigniter4/framework/license.txt b/vendor/codeigniter4/framework/license.txt new file mode 100644 index 0000000..2fb1bdd --- /dev/null +++ b/vendor/codeigniter4/framework/license.txt @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014-2019 British Columbia Institute of Technology +Copyright (c) 2019-2020 CodeIgniter Foundation + +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/codeigniter4/framework/phpunit.xml.dist b/vendor/codeigniter4/framework/phpunit.xml.dist new file mode 100644 index 0000000..88aca1f --- /dev/null +++ b/vendor/codeigniter4/framework/phpunit.xml.dist @@ -0,0 +1,60 @@ + + + + + ./tests + + + + + + ./app + + ./app/Views + ./app/Config/Routes.php + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/codeigniter4/framework/public/.htaccess b/vendor/codeigniter4/framework/public/.htaccess new file mode 100644 index 0000000..02026a3 --- /dev/null +++ b/vendor/codeigniter4/framework/public/.htaccess @@ -0,0 +1,48 @@ +# Disable directory browsing +Options All -Indexes + +# ---------------------------------------------------------------------- +# Rewrite engine +# ---------------------------------------------------------------------- + +# Turning on the rewrite engine is necessary for the following rules and features. +# FollowSymLinks must be enabled for this to work. + + Options +FollowSymlinks + RewriteEngine On + + # If you installed CodeIgniter in a subfolder, you will need to + # change the following line to match the subfolder you need. + # http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewritebase + # RewriteBase / + + # Redirect Trailing Slashes... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^(.*)/$ /$1 [L,R=301] + + # Rewrite "www.example.com -> example.com" + RewriteCond %{HTTPS} !=on + RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC] + RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L] + + # Checks to see if the user is attempting to access a valid file, + # such as an image or css document, if this isn't true it sends the + # request to the front controller, index.php + RewriteCond %{REQUEST_FILENAME} !-f + RewriteCond %{REQUEST_FILENAME} !-d + RewriteRule ^([\s\S]*)$ index.php/$1 [L,NC,QSA] + + # Ensure Authorization header is passed along + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + + + # If we don't have mod_rewrite installed, all 404's + # can be sent to index.php, and everything works as normal. + ErrorDocument 404 index.php + + +# Disable server signature start + ServerSignature Off +# Disable server signature end diff --git a/vendor/codeigniter4/framework/public/favicon.ico b/vendor/codeigniter4/framework/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..7ecfce214cbdbedc15d8348babeff5cd7e720488 GIT binary patch literal 5430 zcmeHL&npB`9Dn5Kuy>cuLGmAPauLohTgugsgTofC9NbV!aa0tgTofgxl%f=?Y?Sh& zWMxI9hibZ5LZ@~9&$;7J-7ai$2=7ByD3A3P1*hfQz|8$LL= zUz~w$;90HjJ=)Ss!V^NuI2Za%(z#lli~7u{+nbyOi;~<-#pGX{K<~tb_C6Lj^YSY9 zuHBEb(bRJ+>$(mjNuamQtlmY!MgdXJjDiJ*`fSvC!*oskp+}sjm(MWyz%r29BW!f*m(x|(w?cOiYFaD0y8pq z9eCfscMhGYa>i@!YdSYJ(-6XZ(W@wc#d9lm1l3S%FF!rC_waiB@V}AM)ez?!Gp$os wgQ-p&yk8A*^lZ5Jw#)Gj@LI_qy{H^P{^jt7C;ag)RHAYMwkN>;6;PJx7hHm1jsO4v literal 0 HcmV?d00001 diff --git a/vendor/codeigniter4/framework/public/index.php b/vendor/codeigniter4/framework/public/index.php new file mode 100644 index 0000000..3eaa592 --- /dev/null +++ b/vendor/codeigniter4/framework/public/index.php @@ -0,0 +1,45 @@ +systemDirectory, '/ ') . '/bootstrap.php'; + +/* + *--------------------------------------------------------------- + * LAUNCH THE APPLICATION + *--------------------------------------------------------------- + * Now that everything is setup, it's time to actually fire + * up the engines and make this app do its thang. + */ +$app->run(); diff --git a/vendor/codeigniter4/framework/public/robots.txt b/vendor/codeigniter4/framework/public/robots.txt new file mode 100644 index 0000000..9e60f97 --- /dev/null +++ b/vendor/codeigniter4/framework/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/vendor/codeigniter4/framework/spark b/vendor/codeigniter4/framework/spark new file mode 100644 index 0000000..0a0908d --- /dev/null +++ b/vendor/codeigniter4/framework/spark @@ -0,0 +1,61 @@ +#!/usr/bin/env php +systemDirectory, '/ ') . '/bootstrap.php'; + +// Grab our Console +$console = new \CodeIgniter\CLI\Console($app); + +// We want errors to be shown when using it from the CLI. +error_reporting(-1); +ini_set('display_errors', 1); + +// Show basic information before we do anything else. +$console->showHeader(); + +// fire off the command in the main framework. +$response = $console->run(); +if ($response->getStatusCode() >= 300) +{ + exit($response->getStatusCode()); +} diff --git a/vendor/codeigniter4/framework/system/.htaccess b/vendor/codeigniter4/framework/system/.htaccess new file mode 100644 index 0000000..3462048 --- /dev/null +++ b/vendor/codeigniter4/framework/system/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + diff --git a/vendor/codeigniter4/framework/system/API/ResponseTrait.php b/vendor/codeigniter4/framework/system/API/ResponseTrait.php new file mode 100644 index 0000000..49248eb --- /dev/null +++ b/vendor/codeigniter4/framework/system/API/ResponseTrait.php @@ -0,0 +1,430 @@ + 201, + 'deleted' => 200, + 'updated' => 200, + 'no_content' => 204, + 'invalid_request' => 400, + 'unsupported_response_type' => 400, + 'invalid_scope' => 400, + 'temporarily_unavailable' => 400, + 'invalid_grant' => 400, + 'invalid_credentials' => 400, + 'invalid_refresh' => 400, + 'no_data' => 400, + 'invalid_data' => 400, + 'access_denied' => 401, + 'unauthorized' => 401, + 'invalid_client' => 401, + 'forbidden' => 403, + 'resource_not_found' => 404, + 'not_acceptable' => 406, + 'resource_exists' => 409, + 'conflict' => 409, + 'resource_gone' => 410, + 'payload_too_large' => 413, + 'unsupported_media_type' => 415, + 'too_many_requests' => 429, + 'server_error' => 500, + 'unsupported_grant_type' => 501, + 'not_implemented' => 501, + ]; + + /** + * How to format the response data. + * Either 'json' or 'xml'. If blank will be + * determine through content negotiation. + * + * @var string + */ + protected $format = 'json'; + + //-------------------------------------------------------------------- + + /** + * Provides a single, simple method to return an API response, formatted + * to match the requested format, with proper content-type and status code. + * + * @param array|string|null $data + * @param integer $status + * @param string $message + * + * @return mixed + */ + public function respond($data = null, int $status = null, string $message = '') + { + // If data is null and status code not provided, exit and bail + if ($data === null && $status === null) + { + $status = 404; + + // Create the output var here in case of $this->response([]); + $output = null; + } // If data is null but status provided, keep the output empty. + elseif ($data === null && is_numeric($status)) + { + $output = null; + } + else + { + $status = empty($status) ? 200 : $status; + $output = $this->format($data); + } + + return $this->response->setBody($output) + ->setStatusCode($status, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used for generic failures that no custom methods exist for. + * + * @param string|array $messages + * @param integer|null $status HTTP status code + * @param string|null $code Custom, API-specific, error code + * @param string $customMessage + * + * @return mixed + */ + public function fail($messages, int $status = 400, string $code = null, string $customMessage = '') + { + if (! is_array($messages)) + { + $messages = ['error' => $messages]; + } + + $response = [ + 'status' => $status, + 'error' => $code === null ? $status : $code, + 'messages' => $messages, + ]; + + return $this->respond($response, $status, $customMessage); + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Response Helpers + //-------------------------------------------------------------------- + + /** + * Used after successfully creating a new resource. + * + * @param mixed $data Data. + * @param string $message Message. + * + * @return mixed + */ + public function respondCreated($data = null, string $message = '') + { + return $this->respond($data, $this->codes['created'], $message); + } + + //-------------------------------------------------------------------- + + /** + * Used after a resource has been successfully deleted. + * + * @param mixed $data Data. + * @param string $message Message. + * + * @return mixed + */ + public function respondDeleted($data = null, string $message = '') + { + return $this->respond($data, $this->codes['deleted'], $message); + } + + /** + * Used after a resource has been successfully updated. + * + * @param mixed $data Data. + * @param string $message Message. + * + * @return mixed + */ + public function respondUpdated($data = null, string $message = '') + { + return $this->respond($data, $this->codes['updated'], $message); + } + + //-------------------------------------------------------------------- + + /** + * Used after a command has been successfully executed but there is no + * meaningful reply to send back to the client. + * + * @param string $message Message. + * + * @return mixed + */ + public function respondNoContent(string $message = 'No Content') + { + return $this->respond(null, $this->codes['no_content'], $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when the client is either didn't send authorization information, + * or had bad authorization credentials. User is encouraged to try again + * with the proper information. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failUnauthorized(string $description = 'Unauthorized', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['unauthorized'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when access is always denied to this resource and no amount + * of trying again will help. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failForbidden(string $description = 'Forbidden', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['forbidden'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when a specified resource cannot be found. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failNotFound(string $description = 'Not Found', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['resource_not_found'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when the data provided by the client cannot be validated. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failValidationError(string $description = 'Bad Request', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['invalid_data'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Use when trying to create a new resource and it already exists. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failResourceExists(string $description = 'Conflict', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['resource_exists'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Use when a resource was previously deleted. This is different than + * Not Found, because here we know the data previously existed, but is now gone, + * where Not Found means we simply cannot find any information about it. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failResourceGone(string $description = 'Gone', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['resource_gone'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when the user has made too many requests for the resource recently. + * + * @param string $description + * @param string $code + * @param string $message + * + * @return mixed + */ + public function failTooManyRequests(string $description = 'Too Many Requests', string $code = null, string $message = '') + { + return $this->fail($description, $this->codes['too_many_requests'], $code, $message); + } + + //-------------------------------------------------------------------- + + /** + * Used when there is a server error. + * + * @param string $description The error message to show the user. + * @param string|null $code A custom, API-specific, error code. + * @param string $message A custom "reason" message to return. + * + * @return Response The value of the Response's send() method. + */ + public function failServerError(string $description = 'Internal Server Error', string $code = null, string $message = ''): Response + { + return $this->fail($description, $this->codes['server_error'], $code, $message); + } + + //-------------------------------------------------------------------- + // Utility Methods + //-------------------------------------------------------------------- + + /** + * Handles formatting a response. Currently makes some heavy assumptions + * and needs updating! :) + * + * @param string|array|null $data + * + * @return string|null + */ + protected function format($data = null) + { + // If the data is a string, there's not much we can do to it... + if (is_string($data)) + { + // The content type should be text/... and not application/... + $contentType = $this->response->getHeaderLine('Content-Type'); + $contentType = str_replace('application/json', 'text/html', $contentType); + $contentType = str_replace('application/', 'text/', $contentType); + $this->response->setContentType($contentType); + + return $data; + } + + $config = new Format(); + $format = "application/$this->format"; + + // Determine correct response type through content negotiation if not explicitly declared + if (empty($this->format) || ! in_array($this->format, ['json', 'xml'])) + { + $format = $this->request->negotiate('media', $config->supportedResponseFormats, false); + } + + $this->response->setContentType($format); + + // if we don't have a formatter, make one + if (! isset($this->formatter)) + { + // if no formatter, use the default + $this->formatter = $config->getFormatter($format); + } + + if ($format !== 'application/json') + { + // Recursively convert objects into associative arrays + // Conversion not required for JSONFormatter + $data = json_decode(json_encode($data), true); + } + + return $this->formatter->format($data); + } + + /** + * Sets the format the response should be in. + * + * @param string $format + * + * @return $this + */ + public function setResponseFormat(string $format = null) + { + $this->format = strtolower($format); + + return $this; + } +} diff --git a/vendor/codeigniter4/framework/system/Autoloader/Autoloader.php b/vendor/codeigniter4/framework/system/Autoloader/Autoloader.php new file mode 100644 index 0000000..fa5c9a2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Autoloader/Autoloader.php @@ -0,0 +1,435 @@ + [ + * 'Foo\Bar' => '/path/to/packages/foo-bar' + * ], + * 'classmap' => [ + * 'MyClass' => '/path/to/class/file.php' + * ] + * ]; + * + * Example: + * + * register(); + * + * @package CodeIgniter\Autoloader + */ +class Autoloader +{ + /** + * Stores namespaces as key, and path as values. + * + * @var array + */ + protected $prefixes = []; + + /** + * Stores class name as key, and path as values. + * + * @var array + */ + protected $classmap = []; + + //-------------------------------------------------------------------- + + /** + * Reads in the configuration array (described above) and stores + * the valid parts that we'll need. + * + * @param \Config\Autoload $config + * @param \Config\Modules $moduleConfig + * + * @return $this + */ + public function initialize(\Config\Autoload $config, \Config\Modules $moduleConfig) + { + // We have to have one or the other, though we don't enforce the need + // to have both present in order to work. + if (empty($config->psr4) && empty($config->classmap)) + { + throw new \InvalidArgumentException('Config array must contain either the \'psr4\' key or the \'classmap\' key.'); + } + + if (isset($config->psr4)) + { + $this->addNamespace($config->psr4); + } + + if (isset($config->classmap)) + { + $this->classmap = $config->classmap; + } + + // Should we load through Composer's namespaces, also? + if ($moduleConfig->discoverInComposer) + { + $this->discoverComposerNamespaces(); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Register the loader with the SPL autoloader stack. + */ + public function register() + { + // Since the default file extensions are searched + // in order of .inc then .php, but we always use .php, + // put the .php extension first to eek out a bit + // better performance. + // http://php.net/manual/en/function.spl-autoload.php#78053 + spl_autoload_extensions('.php,.inc'); + + // Prepend the PSR4 autoloader for maximum performance. + spl_autoload_register([$this, 'loadClass'], true, true); + + // Now prepend another loader for the files in our class map. + $config = is_array($this->classmap) ? $this->classmap : []; + + spl_autoload_register(function ($class) use ($config) { + if (empty($config[$class])) + { + return false; + } + + include_once $config[$class]; + }, true, // Throw exception + true // Prepend + ); + } + + //-------------------------------------------------------------------- + + /** + * Registers namespaces with the autoloader. + * + * @param array|string $namespace + * @param string $path + * + * @return Autoloader + */ + public function addNamespace($namespace, string $path = null) + { + if (is_array($namespace)) + { + foreach ($namespace as $prefix => $path) + { + $prefix = trim($prefix, '\\'); + + if (is_array($path)) + { + foreach ($path as $dir) + { + $this->prefixes[$prefix][] = rtrim($dir, '/') . '/'; + } + + continue; + } + + $this->prefixes[$prefix][] = rtrim($path, '/') . '/'; + } + } + else + { + $this->prefixes[trim($namespace, '\\')][] = rtrim($path, '/') . '/'; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Get namespaces with prefixes as keys and paths as values. + * + * If a prefix param is set, returns only paths to the given prefix. + * + * @var string|null $prefix + * + * @return array + */ + public function getNamespace(string $prefix = null) + { + if ($prefix === null) + { + return $this->prefixes; + } + + return $this->prefixes[trim($prefix, '\\')] ?? []; + } + + //-------------------------------------------------------------------- + + /** + * Removes a single namespace from the psr4 settings. + * + * @param string $namespace + * + * @return Autoloader + */ + public function removeNamespace(string $namespace) + { + unset($this->prefixes[trim($namespace, '\\')]); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Loads the class file for a given class name. + * + * @param string $class The fully qualified class name. + * + * @return string|false The mapped file on success, or boolean false + * on failure. + */ + public function loadClass(string $class) + { + $class = trim($class, '\\'); + $class = str_ireplace('.php', '', $class); + + $mapped_file = $this->loadInNamespace($class); + + // Nothing? One last chance by looking + // in common CodeIgniter folders. + if (! $mapped_file) + { + $mapped_file = $this->loadLegacy($class); + } + + return $mapped_file; + } + + //-------------------------------------------------------------------- + + /** + * Loads the class file for a given class name. + * + * @param string $class The fully-qualified class name + * + * @return string|false The mapped file name on success, or boolean false on fail + */ + protected function loadInNamespace(string $class) + { + if (strpos($class, '\\') === false) + { + return false; + } + + foreach ($this->prefixes as $namespace => $directories) + { + foreach ($directories as $directory) + { + $directory = rtrim($directory, '/'); + + if (strpos($class, $namespace) === 0) + { + $filePath = $directory . str_replace('\\', '/', + substr($class, strlen($namespace))) . '.php'; + $filename = $this->requireFile($filePath); + + if ($filename) + { + return $filename; + } + } + } + } + + // never found a mapped file + return false; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to load the class from common locations in previous + * version of CodeIgniter, namely 'app/Libraries', and + * 'app/Models'. + * + * @param string $class The class name. This typically should NOT have a namespace. + * + * @return mixed The mapped file name on success, or boolean false on failure + */ + protected function loadLegacy(string $class) + { + // If there is a namespace on this class, then + // we cannot load it from traditional locations. + if (strpos($class, '\\') !== false) + { + return false; + } + + $paths = [ + APPPATH . 'Controllers/', + APPPATH . 'Libraries/', + APPPATH . 'Models/', + ]; + + $class = str_replace('\\', '/', $class) . '.php'; + + foreach ($paths as $path) + { + if ($file = $this->requireFile($path . $class)) + { + return $file; + } + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * A central way to require a file is loaded. Split out primarily + * for testing purposes. + * + * @param string $file + * + * @return string|false The filename on success, false if the file is not loaded + */ + protected function requireFile(string $file) + { + $file = $this->sanitizeFilename($file); + + if (is_file($file)) + { + require_once $file; + + return $file; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Sanitizes a filename, replacing spaces with dashes. + * + * Removes special characters that are illegal in filenames on certain + * operating systems and special characters requiring special escaping + * to manipulate at the command line. Replaces spaces and consecutive + * dashes with a single dash. Trim period, dash and underscore from beginning + * and end of filename. + * + * @param string $filename + * + * @return string The sanitized filename + */ + public function sanitizeFilename(string $filename): string + { + // Only allow characters deemed safe for POSIX portable filenames. + // Plus the forward slash for directory separators since this might + // be a path. + // http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_278 + // Modified to allow backslash and colons for on Windows machines. + $filename = preg_replace('/[^0-9\p{L}\s\/\-\_\.\:\\\\]/u', '', $filename); + + // Clean up our filename edges. + $filename = trim($filename, '.-_'); + + return $filename; + } + + //-------------------------------------------------------------------- + + /** + * Locates all PSR4 compatible namespaces from Composer. + */ + protected function discoverComposerNamespaces() + { + if (! is_file(COMPOSER_PATH)) + { + return false; + } + + $composer = include COMPOSER_PATH; + + $paths = $composer->getPrefixesPsr4(); + unset($composer); + + // Get rid of CodeIgniter so we don't have duplicates + if (isset($paths['CodeIgniter\\'])) + { + unset($paths['CodeIgniter\\']); + } + + // Composer stores namespaces with trailing slash. We don't. + $newPaths = []; + foreach ($paths as $key => $value) + { + $newPaths[rtrim($key, '\\ ')] = $value; + } + + $this->prefixes = array_merge($this->prefixes, $newPaths); + } +} diff --git a/vendor/codeigniter4/framework/system/Autoloader/FileLocator.php b/vendor/codeigniter4/framework/system/Autoloader/FileLocator.php new file mode 100644 index 0000000..c9d2b78 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Autoloader/FileLocator.php @@ -0,0 +1,505 @@ +autoloader = $autoloader; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to locate a file by examining the name for a namespace + * and looking through the PSR-4 namespaced files that we know about. + * + * @param string $file The namespaced file to locate + * @param string $folder The folder within the namespace that we should look for the file. + * @param string $ext The file extension the file should have. + * + * @return string|false The path to the file, or false if not found. + */ + public function locateFile(string $file, string $folder = null, string $ext = 'php') + { + $file = $this->ensureExt($file, $ext); + + // Clears the folder name if it is at the beginning of the filename + if (! empty($folder) && ($pos = strpos($file, $folder)) === 0) + { + $file = substr($file, strlen($folder . '/')); + } + + // Is not namespaced? Try the application folder. + if (strpos($file, '\\') === false) + { + return $this->legacyLocate($file, $folder); + } + + // Standardize slashes to handle nested directories. + $file = strtr($file, '/', '\\'); + + $segments = explode('\\', $file); + + // The first segment will be empty if a slash started the filename. + if (empty($segments[0])) + { + unset($segments[0]); + } + + $paths = []; + $prefix = ''; + $filename = ''; + + // Namespaces always comes with arrays of paths + $namespaces = $this->autoloader->getNamespace(); + + while (! empty($segments)) + { + $prefix .= empty($prefix) ? array_shift($segments) : '\\' . array_shift($segments); + + if (empty($namespaces[$prefix])) + { + continue; + } + $paths = $namespaces[$prefix]; + + $filename = implode('/', $segments); + break; + } + + // if no namespaces matched then quit + if (empty($paths)) + { + return false; + } + + // Check each path in the namespace + foreach ($paths as $path) + { + // Ensure trailing slash + $path = rtrim($path, '/') . '/'; + + // If we have a folder name, then the calling function + // expects this file to be within that folder, like 'Views', + // or 'libraries'. + if (! empty($folder) && strpos($path . $filename, '/' . $folder . '/') === false) + { + $path .= trim($folder, '/') . '/'; + } + + $path .= $filename; + if (is_file($path)) + { + return $path; + } + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Examines a file and returns the fully qualified domain name. + * + * @param string $file + * + * @return string + */ + public function getClassname(string $file) : string + { + $php = file_get_contents($file); + $tokens = token_get_all($php); + $dlm = false; + $namespace = ''; + $class_name = ''; + + foreach ($tokens as $i => $token) + { + if ($i < 2) + { + continue; + } + + if ((isset($tokens[$i - 2][1]) && ($tokens[$i - 2][1] === 'phpnamespace' || $tokens[$i - 2][1] === 'namespace')) || ($dlm && $tokens[$i - 1][0] === T_NS_SEPARATOR && $token[0] === T_STRING)) + { + if (! $dlm) + { + $namespace = 0; + } + if (isset($token[1])) + { + $namespace = $namespace ? $namespace . '\\' . $token[1] : $token[1]; + $dlm = true; + } + } + elseif ($dlm && ($token[0] !== T_NS_SEPARATOR) && ($token[0] !== T_STRING)) + { + $dlm = false; + } + if (($tokens[$i - 2][0] === T_CLASS || (isset($tokens[$i - 2][1]) && $tokens[$i - 2][1] === 'phpclass')) + && $tokens[$i - 1][0] === T_WHITESPACE + && $token[0] === T_STRING) + { + $class_name = $token[1]; + break; + } + } + + if (empty( $class_name )) + { + return ''; + } + + return $namespace . '\\' . $class_name; + } + + //-------------------------------------------------------------------- + + /** + * Searches through all of the defined namespaces looking for a file. + * Returns an array of all found locations for the defined file. + * + * Example: + * + * $locator->search('Config/Routes.php'); + * // Assuming PSR4 namespaces include foo and bar, might return: + * [ + * 'app/Modules/foo/Config/Routes.php', + * 'app/Modules/bar/Config/Routes.php', + * ] + * + * @param string $path + * @param string $ext + * @param boolean $prioritizeApp + * + * @return array + */ + public function search(string $path, string $ext = 'php', bool $prioritizeApp = true): array + { + $path = $this->ensureExt($path, $ext); + + $foundPaths = []; + $appPaths = []; + + foreach ($this->getNamespaces() as $namespace) + { + if (isset($namespace['path']) && is_file($namespace['path'] . $path)) + { + $fullPath = $namespace['path'] . $path; + if ($prioritizeApp) + { + $foundPaths[] = $fullPath; + } + else + { + if (strpos($fullPath, APPPATH) === 0) + { + $appPaths[] = $fullPath; + } + else + { + $foundPaths[] = $fullPath; + } + } + } + } + + if (! $prioritizeApp && ! empty($appPaths)) + { + $foundPaths = array_merge($foundPaths, $appPaths); + } + + // Remove any duplicates + $foundPaths = array_unique($foundPaths); + + return $foundPaths; + } + + //-------------------------------------------------------------------- + + /** + * Ensures a extension is at the end of a filename + * + * @param string $path + * @param string $ext + * + * @return string + */ + protected function ensureExt(string $path, string $ext): string + { + if ($ext) + { + $ext = '.' . $ext; + + if (substr($path, -strlen($ext)) !== $ext) + { + $path .= $ext; + } + } + + return $path; + } + + //-------------------------------------------------------------------- + + /** + * Return the namespace mappings we know about. + * + * @return array|string + */ + protected function getNamespaces() + { + $namespaces = []; + + // Save system for last + $system = []; + + foreach ($this->autoloader->getNamespace() as $prefix => $paths) + { + foreach ($paths as $path) + { + if ($prefix === 'CodeIgniter') + { + $system = [ + 'prefix' => $prefix, + 'path' => rtrim($path, '\\/') . DIRECTORY_SEPARATOR, + ]; + + continue; + } + + $namespaces[] = [ + 'prefix' => $prefix, + 'path' => rtrim($path, '\\/') . DIRECTORY_SEPARATOR, + ]; + } + } + + $namespaces[] = $system; + + return $namespaces; + } + + //-------------------------------------------------------------------- + + /** + * Find the qualified name of a file according to + * the namespace of the first matched namespace path. + * + * @param string $path + * + * @return string|false The qualified name or false if the path is not found + */ + public function findQualifiedNameFromPath(string $path) + { + $path = realpath($path); + + if (! $path) + { + return false; + } + + foreach ($this->getNamespaces() as $namespace) + { + $namespace['path'] = realpath($namespace['path']); + + if (empty($namespace['path'])) + { + continue; + } + + if (mb_strpos($path, $namespace['path']) === 0) + { + $className = '\\' . $namespace['prefix'] . '\\' . + ltrim(str_replace('/', '\\', mb_substr( + $path, mb_strlen($namespace['path'])) + ), '\\'); + // Remove the file extension (.php) + $className = mb_substr($className, 0, -4); + + // Check if this exists + if (class_exists($className)) + { + return $className; + } + } + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Scans the defined namespaces, returning a list of all files + * that are contained within the subpath specified by $path. + * + * @param string $path + * + * @return array + */ + public function listFiles(string $path): array + { + if (empty($path)) + { + return []; + } + + $files = []; + helper('filesystem'); + + foreach ($this->getNamespaces() as $namespace) + { + $fullPath = realpath($namespace['path'] . $path); + + if (! is_dir($fullPath)) + { + continue; + } + + $tempFiles = get_filenames($fullPath, true); + + if (! empty($tempFiles)) + { + $files = array_merge($files, $tempFiles); + } + } + + return $files; + } + + //-------------------------------------------------------------------- + + /** + * Scans the provided namespace, returning a list of all files + * that are contained within the subpath specified by $path. + * + * @param string $prefix + * @param string $path + * + * @return array + */ + public function listNamespaceFiles(string $prefix, string $path): array + { + if (empty($path) || empty($prefix)) + { + return []; + } + + $files = []; + helper('filesystem'); + + // autoloader->getNamespace($prefix) returns an array of paths for that namespace + foreach ($this->autoloader->getNamespace($prefix) as $namespacePath) + { + $fullPath = realpath(rtrim($namespacePath, '/') . '/' . $path); + + if (! is_dir($fullPath)) + { + continue; + } + + $tempFiles = get_filenames($fullPath, true); + + if (! empty($tempFiles)) + { + $files = array_merge($files, $tempFiles); + } + } + + return $files; + } + + //-------------------------------------------------------------------- + + /** + * Checks the application folder to see if the file can be found. + * Only for use with filenames that DO NOT include namespacing. + * + * @param string $file + * @param string|null $folder + * + * @return string|false The path to the file, or false if not found. + */ + protected function legacyLocate(string $file, string $folder = null) + { + $paths = [ + APPPATH, + SYSTEMPATH, + ]; + + foreach ($paths as $path) + { + $path .= empty($folder) ? $file : $folder . '/' . $file; + + if (is_file($path)) + { + return $path; + } + } + + return false; + } +} diff --git a/vendor/codeigniter4/framework/system/CLI/BaseCommand.php b/vendor/codeigniter4/framework/system/CLI/BaseCommand.php new file mode 100644 index 0000000..024daf1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/BaseCommand.php @@ -0,0 +1,269 @@ +logger = $logger; + $this->commands = $commands; + } + + //-------------------------------------------------------------------- + + /** + * Actually execute a command. + * This has to be over-ridden in any concrete implementation. + * + * @param array $params + */ + abstract public function run(array $params); + + //-------------------------------------------------------------------- + + /** + * Can be used by a command to run other commands. + * + * @param string $command + * @param array $params + * + * @return mixed + * @throws \ReflectionException + */ + protected function call(string $command, array $params = []) + { + // The CommandRunner will grab the first element + // for the command name. + array_unshift($params, $command); + + return $this->commands->run($command, $params); + } + + //-------------------------------------------------------------------- + + /** + * A simple method to display an error with line/file, + * in child commands. + * + * @param \Exception $e + */ + protected function showError(\Exception $e) + { + CLI::newLine(); + CLI::error($e->getMessage()); + CLI::write($e->getFile() . ' - ' . $e->getLine()); + CLI::newLine(); + } + + //-------------------------------------------------------------------- + + /** + * Makes it simple to access our protected properties. + * + * @param string $key + * + * @return mixed + */ + public function __get(string $key) + { + if (isset($this->$key)) + { + return $this->$key; + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Makes it simple to check our protected properties. + * + * @param string $key + * + * @return boolean + */ + public function __isset(string $key): bool + { + return isset($this->$key); + } + + //-------------------------------------------------------------------- + + /** + * show Help include (usage,arguments,description,options) + */ + public function showHelp() + { + // 4 spaces instead of tab + $tab = ' '; + CLI::write(lang('CLI.helpDescription'), 'yellow'); + CLI::write($tab . $this->description); + CLI::newLine(); + + CLI::write(lang('CLI.helpUsage'), 'yellow'); + $usage = empty($this->usage) ? $this->name . ' [arguments]' : $this->usage; + CLI::write($tab . $usage); + CLI::newLine(); + + $pad = max($this->getPad($this->options, 6), $this->getPad($this->arguments, 6)); + + if (! empty($this->arguments)) + { + CLI::write(lang('CLI.helpArguments'), 'yellow'); + foreach ($this->arguments as $argument => $description) + { + CLI::write($tab . CLI::color(str_pad($argument, $pad), 'green') . $description, 'yellow'); + } + CLI::newLine(); + } + + if (! empty($this->options)) + { + CLI::write(lang('CLI.helpOptions'), 'yellow'); + foreach ($this->options as $option => $description) + { + CLI::write($tab . CLI::color(str_pad($option, $pad), 'green') . $description, 'yellow'); + } + CLI::newLine(); + } + } + + //-------------------------------------------------------------------- + + /** + * Get pad for $key => $value array output + * + * @param array $array + * @param integer $pad + * + * @return integer + */ + public function getPad(array $array, int $pad): int + { + $max = 0; + foreach ($array as $key => $value) + { + $max = max($max, strlen($key)); + } + return $max + $pad; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/CLI/CLI.php b/vendor/codeigniter4/framework/system/CLI/CLI.php new file mode 100644 index 0000000..4b6d3d2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/CLI.php @@ -0,0 +1,1169 @@ + '0;30', + 'dark_gray' => '1;30', + 'blue' => '0;34', + 'dark_blue' => '0;34', + 'light_blue' => '1;34', + 'green' => '0;32', + 'light_green' => '1;32', + 'cyan' => '0;36', + 'light_cyan' => '1;36', + 'red' => '0;31', + 'light_red' => '1;31', + 'purple' => '0;35', + 'light_purple' => '1;35', + 'yellow' => '0;33', + 'light_yellow' => '1;33', + 'light_gray' => '0;37', + 'white' => '1;37', + ]; + + /** + * Background color list + * + * @var array + */ + protected static $background_colors = [ + 'black' => '40', + 'red' => '41', + 'green' => '42', + 'yellow' => '43', + 'blue' => '44', + 'magenta' => '45', + 'cyan' => '46', + 'light_gray' => '47', + ]; + + /** + * List of array segments. + * + * @var array + */ + protected static $segments = []; + + /** + * @var array + */ + protected static $options = []; + + /** + * Helps track internally whether the last + * output was a "write" or a "print" to + * keep the output clean and as expected. + * + * @var string + */ + protected static $lastWrite; + + /** + * Height of the CLI window + * + * @var integer + */ + protected static $height; + + /** + * Width of the CLI window + * + * @var integer + */ + protected static $width; + + /** + * Whether the current stream supports colored output. + * + * @var boolean + */ + protected static $isColored = false; + + //-------------------------------------------------------------------- + + /** + * Static "constructor". + */ + public static function init() + { + if (is_cli()) + { + // Readline is an extension for PHP that makes interactivity with PHP + // much more bash-like. + // http://www.php.net/manual/en/readline.installation.php + static::$readline_support = extension_loaded('readline'); + + // clear segments & options to keep testing clean + static::$segments = []; + static::$options = []; + + // Check our stream resource for color support + static::$isColored = static::hasColorSupport(STDOUT); + + static::parseCommandLine(); + + static::$initialized = true; + } + else + { + // If the command is being called from a controller + // we need to define STDOUT ourselves + // @codeCoverageIgnoreStart + define('STDOUT', 'php://output'); + // @codeCoverageIgnoreEnd + } + } + + //-------------------------------------------------------------------- + + /** + * Get input from the shell, using readline or the standard STDIN + * + * Named options must be in the following formats: + * php index.php user -v --v -name=John --name=John + * + * @param string $prefix + * @return string + * + * @codeCoverageIgnore + */ + public static function input(string $prefix = null): string + { + if (static::$readline_support) + { + return readline($prefix); + } + + echo $prefix; + + return fgets(STDIN); + } + + //-------------------------------------------------------------------- + + /** + * Asks the user for input. + * + * Usage: + * + * // Takes any input + * $color = CLI::prompt('What is your favorite color?'); + * + * // Takes any input, but offers default + * $color = CLI::prompt('What is your favourite color?', 'white'); + * + * // Will validate options with the in_list rule and accept only if one of the list + * $color = CLI::prompt('What is your favourite color?', array('red','blue')); + * + * // Do not provide options but requires a valid email + * $email = CLI::prompt('What is your email?', null, 'required|valid_email'); + * + * @param string $field Output "field" question + * @param string|array $options String to a default value, array to a list of options (the first option will be the default value) + * @param string $validation Validation rules + * + * @return string The user input + * + * @codeCoverageIgnore + */ + public static function prompt(string $field, $options = null, string $validation = null): string + { + $extra_output = ''; + $default = ''; + + if (is_string($options)) + { + $extra_output = ' [' . static::color($options, 'white') . ']'; + $default = $options; + } + + if (is_array($options) && $options) + { + $opts = $options; + $extra_output_default = static::color($opts[0], 'white'); + + unset($opts[0]); + + if (empty($opts)) + { + $extra_output = $extra_output_default; + } + else + { + $extra_output = ' [' . $extra_output_default . ', ' . implode(', ', $opts) . ']'; + $validation .= '|in_list[' . implode(',', $options) . ']'; + $validation = trim($validation, '|'); + } + + $default = $options[0]; + } + + static::fwrite(STDOUT, $field . $extra_output . ': '); + + // Read the input from keyboard. + $input = trim(static::input()) ?: $default; + + if (isset($validation)) + { + while (! static::validate($field, $input, $validation)) + { + $input = static::prompt($field, $options, $validation); + } + } + + return empty($input) ? '' : $input; + } + + //-------------------------------------------------------------------- + + /** + * Validate one prompt "field" at a time + * + * @param string $field Prompt "field" output + * @param string $value Input value + * @param string $rules Validation rules + * + * @return boolean + * + * @codeCoverageIgnore + */ + protected static function validate(string $field, string $value, string $rules): bool + { + $label = $field; + $field = 'temp'; + $validation = \Config\Services::validation(null, false); + $validation->setRule($field, $label, $rules); + $validation->run([$field => $value]); + + if ($validation->hasError($field)) + { + static::error($validation->getError($field)); + + return false; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Outputs a string to the CLI without any surrounding newlines. + * Useful for showing repeating elements on a single line. + * + * @param string $text + * @param string|null $foreground + * @param string|null $background + */ + public static function print(string $text = '', string $foreground = null, string $background = null) + { + if ($foreground || $background) + { + $text = static::color($text, $foreground, $background); + } + + static::$lastWrite = null; + + static::fwrite(STDOUT, $text); + } + + /** + * Outputs a string to the cli on it's own line. + * + * @param string $text The text to output + * @param string $foreground + * @param string $background + */ + public static function write(string $text = '', string $foreground = null, string $background = null) + { + if ($foreground || $background) + { + $text = static::color($text, $foreground, $background); + } + + if (static::$lastWrite !== 'write') + { + $text = PHP_EOL . $text; + static::$lastWrite = 'write'; + } + + static::fwrite(STDOUT, $text . PHP_EOL); + } + + //-------------------------------------------------------------------- + + /** + * Outputs an error to the CLI using STDERR instead of STDOUT + * + * @param string|array $text The text to output, or array of errors + * @param string $foreground + * @param string $background + */ + public static function error(string $text, string $foreground = 'light_red', string $background = null) + { + // Check color support for STDERR + $stdout = static::$isColored; + static::$isColored = static::hasColorSupport(STDERR); + + if ($foreground || $background) + { + $text = static::color($text, $foreground, $background); + } + + static::fwrite(STDERR, $text . PHP_EOL); + + // return STDOUT color support + static::$isColored = $stdout; + } + + //-------------------------------------------------------------------- + + /** + * Beeps a certain number of times. + * + * @param integer $num The number of times to beep + */ + public static function beep(int $num = 1) + { + echo str_repeat("\x07", $num); + } + + //-------------------------------------------------------------------- + + /** + * Waits a certain number of seconds, optionally showing a wait message and + * waiting for a key press. + * + * @param integer $seconds Number of seconds + * @param boolean $countdown Show a countdown or not + */ + public static function wait(int $seconds, bool $countdown = false) + { + if ($countdown === true) + { + $time = $seconds; + + while ($time > 0) + { + static::fwrite(STDOUT, $time . '... '); + sleep(1); + $time --; + } + static::write(); + } + else + { + if ($seconds > 0) + { + sleep($seconds); + } + else + { + // this chunk cannot be tested because of keyboard input + // @codeCoverageIgnoreStart + static::write(static::$wait_msg); + static::input(); + // @codeCoverageIgnoreEnd + } + } + } + + //-------------------------------------------------------------------- + + /** + * if operating system === windows + * + * @return boolean + */ + public static function isWindows(): bool + { + return stripos(PHP_OS, 'WIN') === 0; + } + + //-------------------------------------------------------------------- + + /** + * Enter a number of empty lines + * + * @param integer $num Number of lines to output + * + * @return void + */ + public static function newLine(int $num = 1) + { + // Do it once or more, write with empty string gives us a new line + for ($i = 0; $i < $num; $i ++) + { + static::write(); + } + } + + //-------------------------------------------------------------------- + + /** + * Clears the screen of output + * + * @return void + * + * @codeCoverageIgnore + */ + public static function clearScreen() + { + // Unix systems, and Windows with VT100 Terminal support (i.e. Win10) + // can handle CSI sequences. For lower than Win10 we just shove in 40 new lines. + static::isWindows() && ! static::streamSupports('sapi_windows_vt100_support', STDOUT) + ? static::newLine(40) + : static::fwrite(STDOUT, "\033[H\033[2J"); + } + + //-------------------------------------------------------------------- + + /** + * Returns the given text with the correct color codes for a foreground and + * optionally a background color. + * + * @param string $text The text to color + * @param string $foreground The foreground color + * @param string $background The background color + * @param string $format Other formatting to apply. Currently only 'underline' is understood + * + * @return string The color coded string + */ + public static function color(string $text, string $foreground, string $background = null, string $format = null): string + { + if (! static::$isColored) + { + return $text; + } + + if (! array_key_exists($foreground, static::$foreground_colors)) + { + throw CLIException::forInvalidColor('foreground', $foreground); + } + + if ($background !== null && ! array_key_exists($background, static::$background_colors)) + { + throw CLIException::forInvalidColor('background', $background); + } + + $string = "\033[" . static::$foreground_colors[$foreground] . 'm'; + + if ($background !== null) + { + $string .= "\033[" . static::$background_colors[$background] . 'm'; + } + + if ($format === 'underline') + { + $string .= "\033[4m"; + } + + // Detect if color method was already in use with this text + if (strpos($text, "\033[0m") !== false) + { + // Split the text into parts so that we can see + // if any part missing the color definition + $chunks = mb_split("\\033\[0m", $text); + // Reset text + $text = ''; + + foreach ($chunks as $chunk) + { + if ($chunk === '') + { + continue; + } + + // If chunk doesn't have colors defined we need to add them + if (strpos($chunk, "\033[") === false) + { + $chunk = static::color($chunk, $foreground, $background, $format); + // Add color reset before chunk and clear end of the string + $text .= rtrim("\033[0m" . $chunk, "\033[0m"); + } + else + { + $text .= $chunk; + } + } + } + + return $string . $text . "\033[0m"; + } + + //-------------------------------------------------------------------- + + /** + * Get the number of characters in string having encoded characters + * and ignores styles set by the color() function + * + * @param string $string + * + * @return integer + */ + public static function strlen(?string $string): int + { + if (is_null($string)) + { + return 0; + } + + foreach (static::$foreground_colors as $color) + { + $string = strtr($string, ["\033[" . $color . 'm' => '']); + } + + foreach (static::$background_colors as $color) + { + $string = strtr($string, ["\033[" . $color . 'm' => '']); + } + + $string = strtr($string, ["\033[4m" => '', "\033[0m" => '']); + + return mb_strlen($string); + } + + //-------------------------------------------------------------------- + + /** + * Checks whether the current stream resource supports or + * refers to a valid terminal type device. + * + * @param string $function + * @param resource $resource + * + * @return boolean + */ + public static function streamSupports(string $function, $resource): bool + { + if (ENVIRONMENT === 'testing') + { + // In the current setup of the tests we cannot fully check + // if the stream supports the function since we are using + // filtered streams. + return function_exists($function); + } + + // @codeCoverageIgnoreStart + return function_exists($function) && @$function($resource); + // @codeCoverageIgnoreEnd + } + + //-------------------------------------------------------------------- + + /** + * Returns true if the stream resource supports colors. + * + * This is tricky on Windows, because Cygwin, Msys2 etc. emulate pseudo + * terminals via named pipes, so we can only check the environment. + * + * Reference: https://github.com/composer/xdebug-handler/blob/master/src/Process.php + * + * @param resource $resource + * + * @return boolean + */ + public static function hasColorSupport($resource): bool + { + // Follow https://no-color.org/ + if (isset($_SERVER['NO_COLOR']) || getenv('NO_COLOR') !== false) + { + return false; + } + + if (getenv('TERM_PROGRAM') === 'Hyper') + { + return true; + } + + if (static::isWindows()) + { + // @codeCoverageIgnoreStart + return static::streamSupports('sapi_windows_vt100_support', $resource) + || isset($_SERVER['ANSICON']) + || getenv('ANSICON') !== false + || getenv('ConEmuANSI') === 'ON' + || getenv('TERM') === 'xterm'; + // @codeCoverageIgnoreEnd + } + + return static::streamSupports('stream_isatty', $resource); + } + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the width of the viewable CLI window. + * + * @param integer $default + * + * @return integer + */ + public static function getWidth(int $default = 80): int + { + if (\is_null(static::$width)) + { + static::generateDimensions(); + } + + return static::$width ?: $default; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to determine the height of the viewable CLI window. + * + * @param integer $default + * + * @return integer + */ + public static function getHeight(int $default = 32): int + { + if (\is_null(static::$height)) + { + static::generateDimensions(); + } + + return static::$height ?: $default; + } + + //-------------------------------------------------------------------- + + /** + * Populates the CLI's dimensions. + * + * @return void + */ + public static function generateDimensions() + { + if (static::isWindows()) + { + // Shells such as `Cygwin` and `Git bash` returns incorrect values + // when executing `mode CON`, so we use `tput` instead + // @codeCoverageIgnoreStart + if (($shell = getenv('SHELL')) && preg_match('/(?:bash|zsh)(?:\.exe)?$/', $shell) || getenv('TERM')) + { + static::$height = (int) exec('tput lines'); + static::$width = (int) exec('tput cols'); + } + else + { + $return = -1; + $output = []; + exec('mode CON', $output, $return); + + if ($return === 0 && $output) + { + // Look for the next lines ending in ": " + // Searching for "Columns:" or "Lines:" will fail on non-English locales + if (preg_match('/:\s*(\d+)\n[^:]+:\s*(\d+)\n/', implode("\n", $output), $matches)) + { + static::$height = (int) $matches[1]; + static::$width = (int) $matches[2]; + } + } + } + // @codeCoverageIgnoreEnd + } + else + { + if (($size = exec('stty size')) && preg_match('/(\d+)\s+(\d+)/', $size, $matches)) + { + static::$height = (int) $matches[1]; + static::$width = (int) $matches[2]; + } + else + { + // @codeCoverageIgnoreStart + static::$height = (int) exec('tput lines'); + static::$width = (int) exec('tput cols'); + // @codeCoverageIgnoreEnd + } + } + } + + //-------------------------------------------------------------------- + + /** + * Displays a progress bar on the CLI. You must call it repeatedly + * to update it. Set $thisStep = false to erase the progress bar. + * + * @param integer|boolean $thisStep + * @param integer $totalSteps + */ + public static function showProgress($thisStep = 1, int $totalSteps = 10) + { + static $inProgress = false; + + // restore cursor position when progress is continuing. + if ($inProgress !== false && $inProgress <= $thisStep) + { + static::fwrite(STDOUT, "\033[1A"); + } + $inProgress = $thisStep; + + if ($thisStep !== false) + { + // Don't allow div by zero or negative numbers.... + $thisStep = abs($thisStep); + $totalSteps = $totalSteps < 1 ? 1 : $totalSteps; + + $percent = intval(($thisStep / $totalSteps) * 100); + $step = (int) round($percent / 10); + + // Write the progress bar + static::fwrite(STDOUT, "[\033[32m" . str_repeat('#', $step) . str_repeat('.', 10 - $step) . "\033[0m]"); + // Textual representation... + static::fwrite(STDOUT, sprintf(' %3d%% Complete', $percent) . PHP_EOL); + } + else + { + static::fwrite(STDOUT, "\007"); + } + } + + //-------------------------------------------------------------------- + + /** + * Takes a string and writes it to the command line, wrapping to a maximum + * width. If no maximum width is specified, will wrap to the window's max + * width. + * + * If an int is passed into $pad_left, then all strings after the first + * will padded with that many spaces to the left. Useful when printing + * short descriptions that need to start on an existing line. + * + * @param string $string + * @param integer $max + * @param integer $pad_left + * + * @return string + */ + public static function wrap(string $string = null, int $max = 0, int $pad_left = 0): string + { + if (empty($string)) + { + return ''; + } + + if ($max === 0) + { + $max = CLI::getWidth(); + } + + if (CLI::getWidth() < $max) + { + $max = CLI::getWidth(); + } + + $max = $max - $pad_left; + + $lines = wordwrap($string, $max, PHP_EOL); + + if ($pad_left > 0) + { + $lines = explode(PHP_EOL, $lines); + + $first = true; + + array_walk($lines, function (&$line, $index) use ($pad_left, &$first) { + if (! $first) + { + $line = str_repeat(' ', $pad_left) . $line; + } + else + { + $first = false; + } + }); + + $lines = implode(PHP_EOL, $lines); + } + + return $lines; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Command-Line 'URI' support + //-------------------------------------------------------------------- + + /** + * Parses the command line it was called from and collects all + * options and valid segments. + * + * I tried to use getopt but had it fail occasionally to find any + * options but argc has always had our back. We don't have all of the power + * of getopt but this does us just fine. + */ + protected static function parseCommandLine() + { + // start picking segments off from #1, ignoring the invoking program + for ($i = 1; $i < $_SERVER['argc']; $i ++) + { + // If there's no '-' at the beginning of the argument + // then add it to our segments. + if (mb_strpos($_SERVER['argv'][$i], '-') !== 0) + { + static::$segments[] = $_SERVER['argv'][$i]; + continue; + } + + $arg = str_replace('-', '', $_SERVER['argv'][$i]); + $value = null; + + // if there is a following segment, and it doesn't start with a dash, it's a value. + if (isset($_SERVER['argv'][$i + 1]) && mb_strpos($_SERVER['argv'][$i + 1], '-') !== 0) + { + $value = $_SERVER['argv'][$i + 1]; + $i ++; + } + + static::$options[$arg] = $value; + } + } + + //-------------------------------------------------------------------- + + /** + * Returns the command line string portions of the arguments, minus + * any options, as a string. This is used to pass along to the main + * CodeIgniter application. + * + * @return string + */ + public static function getURI(): string + { + return implode('/', static::$segments); + } + + //-------------------------------------------------------------------- + + /** + * Returns an individual segment. + * + * This ignores any options that might have been dispersed between + * valid segments in the command: + * + * // segment(3) is 'three', not '-f' or 'anOption' + * > php spark one two -f anOption three + * + * @param integer $index + * + * @return mixed|null + */ + public static function getSegment(int $index) + { + if (! isset(static::$segments[$index - 1])) + { + return null; + } + + return static::$segments[$index - 1]; + } + + //-------------------------------------------------------------------- + + /** + * Returns the raw array of segments found. + * + * @return array + */ + public static function getSegments(): array + { + return static::$segments; + } + + //-------------------------------------------------------------------- + + /** + * Gets a single command-line option. Returns TRUE if the option + * exists, but doesn't have a value, and is simply acting as a flag. + * + * @param string $name + * + * @return boolean|mixed|null + */ + public static function getOption(string $name) + { + if (! array_key_exists($name, static::$options)) + { + return null; + } + + // If the option didn't have a value, simply return TRUE + // so they know it was set, otherwise return the actual value. + $val = static::$options[$name] === null ? true : static::$options[$name]; + + return $val; + } + + //-------------------------------------------------------------------- + + /** + * Returns the raw array of options found. + * + * @return array + */ + public static function getOptions(): array + { + return static::$options; + } + + //-------------------------------------------------------------------- + + /** + * Returns the options as a string, suitable for passing along on + * the CLI to other commands. + * + * @return string + */ + public static function getOptionString(): string + { + if (empty(static::$options)) + { + return ''; + } + + $out = ''; + + foreach (static::$options as $name => $value) + { + // If there's a space, we need to group + // so it will pass correctly. + if (mb_strpos($value, ' ') !== false) + { + $value = '"' . $value . '"'; + } + + $out .= "-{$name} $value "; + } + + return $out; + } + + //-------------------------------------------------------------------- + + /** + * Returns a well formatted table + * + * @param array $tbody List of rows + * @param array $thead List of columns + * + * @return void + */ + public static function table(array $tbody, array $thead = []) + { + // All the rows in the table will be here until the end + $table_rows = []; + + // We need only indexes and not keys + if (! empty($thead)) + { + $table_rows[] = array_values($thead); + } + + foreach ($tbody as $tr) + { + $table_rows[] = array_values($tr); + } + + // Yes, it really is necessary to know this count + $total_rows = count($table_rows); + + // Store all columns lengths + // $all_cols_lengths[row][column] = length + $all_cols_lengths = []; + + // Store maximum lengths by column + // $max_cols_lengths[column] = length + $max_cols_lengths = []; + + // Read row by row and define the longest columns + for ($row = 0; $row < $total_rows; $row ++) + { + $column = 0; // Current column index + foreach ($table_rows[$row] as $col) + { + // Sets the size of this column in the current row + $all_cols_lengths[$row][$column] = static::strlen($col); + + // If the current column does not have a value among the larger ones + // or the value of this is greater than the existing one + // then, now, this assumes the maximum length + if (! isset($max_cols_lengths[$column]) || $all_cols_lengths[$row][$column] > $max_cols_lengths[$column]) + { + $max_cols_lengths[$column] = $all_cols_lengths[$row][$column]; + } + + // We can go check the size of the next column... + $column ++; + } + } + + // Read row by row and add spaces at the end of the columns + // to match the exact column length + for ($row = 0; $row < $total_rows; $row ++) + { + $column = 0; + foreach ($table_rows[$row] as $col) + { + $diff = $max_cols_lengths[$column] - static::strlen($col); + if ($diff) + { + $table_rows[$row][$column] = $table_rows[$row][$column] . str_repeat(' ', $diff); + } + $column ++; + } + } + + $table = ''; + + // Joins columns and append the well formatted rows to the table + for ($row = 0; $row < $total_rows; $row ++) + { + // Set the table border-top + if ($row === 0) + { + $cols = '+'; + foreach ($table_rows[$row] as $col) + { + $cols .= str_repeat('-', static::strlen($col) + 2) . '+'; + } + $table .= $cols . PHP_EOL; + } + + // Set the columns borders + $table .= '| ' . implode(' | ', $table_rows[$row]) . ' |' . PHP_EOL; + + // Set the thead and table borders-bottom + if ($row === 0 && ! empty($thead) || $row + 1 === $total_rows) + { + $table .= $cols . PHP_EOL; + } + } + + static::write($table); + } + + //-------------------------------------------------------------------- + + /** + * While the library is intended for use on CLI commands, + * commands can be called from controllers and elsewhere + * so we need a way to allow them to still work. + * + * For now, just echo the content, but look into a better + * solution down the road. + * + * @param resource $handle + * @param string $string + */ + protected static function fwrite($handle, string $string) + { + if (is_cli()) + { + fwrite($handle, $string); + return; + } + + // @codeCoverageIgnoreStart + echo $string; + // @codeCoverageIgnoreEnd + } +} + +// Ensure the class is initialized. Done outside of code coverage +// @codeCoverageIgnoreStart +CLI::init(); +// @codeCoverageIgnoreEnd diff --git a/vendor/codeigniter4/framework/system/CLI/CommandRunner.php b/vendor/codeigniter4/framework/system/CLI/CommandRunner.php new file mode 100644 index 0000000..466ef33 --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/CommandRunner.php @@ -0,0 +1,119 @@ +commands = service('commands'); + } + + /** + * We map all un-routed CLI methods through this function + * so we have the chance to look for a Command first. + * + * @param string $method + * @param array ...$params + * + * @return mixed + * @throws \ReflectionException + */ + public function _remap($method, ...$params) + { + // The first param is usually empty, so scrap it. + if (empty($params[0])) + { + array_shift($params); + } + + return $this->index($params); + } + + //-------------------------------------------------------------------- + + /** + * Default command. + * + * @param array $params + * + * @return mixed + * @throws \ReflectionException + */ + public function index(array $params) + { + $command = array_shift($params); + + if (is_null($command)) + { + $command = 'list'; + } + + return service('commands')->run($command, $params); + } + + /** + * Allows access to the current commands that have been found. + * + * @return array + */ + public function getCommands(): array + { + return $this->commands->getCommands(); + } +} diff --git a/vendor/codeigniter4/framework/system/CLI/Commands.php b/vendor/codeigniter4/framework/system/CLI/Commands.php new file mode 100644 index 0000000..cb6d8fd --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/Commands.php @@ -0,0 +1,181 @@ +logger = $logger ?? service('logger'); + } + + /** + * Runs a command given + * + * @param string $command + * @param array $params + */ + public function run(string $command, array $params) + { + $this->discoverCommands(); + + if (! isset($this->commands[$command])) + { + CLI::error(lang('CLI.commandNotFound', [$command])); + CLI::newLine(); + return; + } + + // The file would have already been loaded during the + // createCommandList function... + $className = $this->commands[$command]['class']; + $class = new $className($this->logger, $this); + + return $class->run($params); + } + + /** + * Provide access to the list of commands. + * + * @return array + */ + public function getCommands() + { + $this->discoverCommands(); + + return $this->commands; + } + + /** + * Discovers all commands in the framework and within user code, + * and collects instances of them to work with. + */ + public function discoverCommands() + { + if (! empty($this->commands)) + { + return; + } + + $files = service('locator')->listFiles('Commands/'); + + // If no matching command files were found, bail + if (empty($files)) + { + // This should never happen in unit testing. + // if it does, we have far bigger problems! + // @codeCoverageIgnoreStart + return; + // @codeCoverageIgnoreEnd + } + + // Loop over each file checking to see if a command with that + // alias exists in the class. If so, return it. Otherwise, try the next. + foreach ($files as $file) + { + $className = Services::locator()->findQualifiedNameFromPath($file); + if (empty($className) || ! class_exists($className)) + { + continue; + } + + try + { + $class = new \ReflectionClass($className); + + if (! $class->isInstantiable() || ! $class->isSubclassOf(BaseCommand::class)) + { + continue; + } + + $class = new $className($this->logger, $this); + + // Store it! + if ($class->group !== null) + { + $this->commands[$class->name] = [ + 'class' => $className, + 'file' => $file, + 'group' => $class->group, + 'description' => $class->description, + ]; + } + + $class = null; + unset($class); + } + catch (\ReflectionException $e) + { + $this->logger->error($e->getMessage()); + } + } + + asort($this->commands); + } +} diff --git a/vendor/codeigniter4/framework/system/CLI/Console.php b/vendor/codeigniter4/framework/system/CLI/Console.php new file mode 100644 index 0000000..cf50384 --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/Console.php @@ -0,0 +1,106 @@ +app = $app; + } + + //-------------------------------------------------------------------- + + /** + * Runs the current command discovered on the CLI. + * + * @param boolean $useSafeOutput + * + * @return \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed + * @throws \Exception + */ + public function run(bool $useSafeOutput = false) + { + $path = CLI::getURI() ?: 'list'; + + // Set the path for the application to route to. + $this->app->setPath("ci{$path}"); + + return $this->app->useSafeOutput($useSafeOutput)->run(); + } + + //-------------------------------------------------------------------- + + /** + * Displays basic information about the Console. + */ + public function showHeader() + { + CLI::newLine(1); + + CLI::write(CLI::color('CodeIgniter CLI Tool', 'green') + . ' - Version ' . CodeIgniter::CI_VERSION + . ' - Server-Time: ' . date('Y-m-d H:i:sa')); + + CLI::newLine(1); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/CLI/Exceptions/CLIException.php b/vendor/codeigniter4/framework/system/CLI/Exceptions/CLIException.php new file mode 100644 index 0000000..474064e --- /dev/null +++ b/vendor/codeigniter4/framework/system/CLI/Exceptions/CLIException.php @@ -0,0 +1,60 @@ +validHandlers) || ! is_array($config->validHandlers)) + { + throw CacheException::forInvalidHandlers(); + } + + if (! isset($config->handler) || ! isset($config->backupHandler)) + { + throw CacheException::forNoBackup(); + } + + $handler = ! empty($handler) ? $handler : $config->handler; + $backup = ! empty($backup) ? $backup : $config->backupHandler; + + if (! array_key_exists($handler, $config->validHandlers) || ! array_key_exists($backup, $config->validHandlers)) + { + throw CacheException::forHandlerNotFound(); + } + + // Get an instance of our handler. + $adapter = new $config->validHandlers[$handler]($config); + + if (! $adapter->isSupported()) + { + $adapter = new $config->validHandlers[$backup]($config); + + if (! $adapter->isSupported()) + { + // Log stuff here, don't throw exception. No need to raise a fuss. + // Fall back to the dummy adapter. + $adapter = new $config->validHandlers['dummy'](); + } + } + + // If $adapter->initialization throws a CriticalError exception, we will attempt to + // use the $backup handler, if that also fails, we resort to the dummy handler. + try + { + $adapter->initialize(); + } + catch (CriticalError $e) + { + // log the fact that an exception occurred as well what handler we are resorting to + log_message('critical', $e->getMessage() . ' Resorting to using ' . $backup . ' handler.'); + + // get the next best cache handler (or dummy if the $backup also fails) + $adapter = self::getHandler($config, $backup, 'dummy'); + } + + return $adapter; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Cache/CacheInterface.php b/vendor/codeigniter4/framework/system/Cache/CacheInterface.php new file mode 100644 index 0000000..108c63d --- /dev/null +++ b/vendor/codeigniter4/framework/system/Cache/CacheInterface.php @@ -0,0 +1,154 @@ +storePath) ? $config->storePath : WRITEPATH . 'cache'; + if (! is_really_writable($path)) + { + throw CacheException::forUnableToWrite($path); + } + + $this->prefix = $config->prefix ?: ''; + $this->path = rtrim($path, '/') . '/'; + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any handler-specific setup that must be done. + */ + public function initialize() + { + // Not to see here... + } + + //-------------------------------------------------------------------- + + /** + * Attempts to fetch an item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + */ + public function get(string $key) + { + $key = $this->prefix . $key; + + $data = $this->getItem($key); + + return is_array($data) ? $data['data'] : null; + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * @param string $key Cache item name + * @param mixed $value The data to save + * @param integer $ttl Time To Live, in seconds (default 60) + * + * @return mixed + */ + public function save(string $key, $value, int $ttl = 60) + { + $key = $this->prefix . $key; + + $contents = [ + 'time' => time(), + 'ttl' => $ttl, + 'data' => $value, + ]; + + if ($this->writeFile($this->path . $key, serialize($contents))) + { + chmod($this->path . $key, 0640); + + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return boolean + */ + public function delete(string $key) + { + $key = $this->prefix . $key; + + return is_file($this->path . $key) && unlink($this->path . $key); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function increment(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $data = $this->getItem($key); + + if ($data === false) + { + $data = [ + 'data' => 0, + 'ttl' => 60, + ]; + } + elseif (! is_int($data['data'])) + { + return false; + } + + $new_value = $data['data'] + $offset; + + return $this->save($key, $new_value, $data['ttl']) ? $new_value : false; + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function decrement(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $data = $this->getItem($key); + + if ($data === false) + { + $data = [ + 'data' => 0, + 'ttl' => 60, + ]; + } + elseif (! is_int($data['data'])) + { + return false; + } + + $new_value = $data['data'] - $offset; + + return $this->save($key, $new_value, $data['ttl']) ? $new_value : false; + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return boolean + */ + public function clean() + { + return $this->deleteFiles($this->path, false, true); + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + */ + public function getCacheInfo() + { + return $this->getDirFileInfo($this->path); + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + */ + public function getMetaData(string $key) + { + $key = $this->prefix . $key; + + if (! is_file($this->path . $key)) + { + return false; + } + + $data = @unserialize(file_get_contents($this->path . $key)); + + if (is_array($data)) + { + $mtime = filemtime($this->path . $key); + + if (! isset($data['ttl'])) + { + return false; + } + + return [ + 'expire' => $mtime + $data['ttl'], + 'mtime' => $mtime, + 'data' => $data['data'], + ]; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return is_writable($this->path); + } + + //-------------------------------------------------------------------- + + /** + * Does the heavy lifting of actually retrieving the file and + * verifying it's age. + * + * @param string $key + * + * @return boolean|mixed + */ + protected function getItem(string $key) + { + if (! is_file($this->path . $key)) + { + return false; + } + + $data = unserialize(file_get_contents($this->path . $key)); + + if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) + { + // If the file is still there then remove it + if (is_file($this->path . $key)) + { + unlink($this->path . $key); + } + + return false; + } + + return $data; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // SUPPORT METHODS FOR FILES + //-------------------------------------------------------------------- + + /** + * Writes a file to disk, or returns false if not successful. + * + * @param string $path + * @param string $data + * @param string $mode + * + * @return boolean + */ + protected function writeFile($path, $data, $mode = 'wb') + { + if (($fp = @fopen($path, $mode)) === false) + { + return false; + } + + flock($fp, LOCK_EX); + + for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($data, $written))) === false) + { + break; + } + } + + flock($fp, LOCK_UN); + fclose($fp); + + return is_int($result); + } + + //-------------------------------------------------------------------- + + /** + * Delete Files + * + * Deletes all files contained in the supplied directory path. + * Files must be writable or owned by the system in order to be deleted. + * If the second parameter is set to TRUE, any directories contained + * within the supplied base directory will be nuked as well. + * + * @param string $path File path + * @param boolean $del_dir Whether to delete any directories found in the path + * @param boolean $htdocs Whether to skip deleting .htaccess and index page files + * @param integer $_level Current directory depth level (default: 0; internal use only) + * + * @return boolean + */ + protected function deleteFiles(string $path, bool $del_dir = false, bool $htdocs = false, int $_level = 0): bool + { + // Trim the trailing slash + $path = rtrim($path, '/\\'); + + if (! $current_dir = @opendir($path)) + { + return false; + } + + while (false !== ($filename = @readdir($current_dir))) + { + if ($filename !== '.' && $filename !== '..') + { + if (is_dir($path . DIRECTORY_SEPARATOR . $filename) && $filename[0] !== '.') + { + $this->deleteFiles($path . DIRECTORY_SEPARATOR . $filename, $del_dir, $htdocs, $_level + 1); + } + elseif ($htdocs !== true || ! preg_match('/^(\.htaccess|index\.(html|htm|php)|web\.config)$/i', $filename)) + { + @unlink($path . DIRECTORY_SEPARATOR . $filename); + } + } + } + + closedir($current_dir); + + return ($del_dir === true && $_level > 0) ? @rmdir($path) : true; + } + + //-------------------------------------------------------------------- + + /** + * Get Directory File Information + * + * Reads the specified directory and builds an array containing the filenames, + * filesize, dates, and permissions + * + * Any sub-folders contained within the specified path are read as well. + * + * @param string $source_dir Path to source + * @param boolean $top_level_only Look only at the top level directory specified? + * @param boolean $_recursion Internal variable to determine recursion status - do not use in calls + * + * @return array|false + */ + protected function getDirFileInfo(string $source_dir, bool $top_level_only = true, bool $_recursion = false) + { + static $_filedata = []; + $relative_path = $source_dir; + + if ($fp = @opendir($source_dir)) + { + // reset the array and make sure $source_dir has a trailing slash on the initial call + if ($_recursion === false) + { + $_filedata = []; + $source_dir = rtrim(realpath($source_dir), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + } + + // Used to be foreach (scandir($source_dir, 1) as $file), but scandir() is simply not as fast + while (false !== ($file = readdir($fp))) + { + if (is_dir($source_dir . $file) && $file[0] !== '.' && $top_level_only === false) + { + $this->getDirFileInfo($source_dir . $file . DIRECTORY_SEPARATOR, $top_level_only, true); + } + elseif ($file[0] !== '.') + { + $_filedata[$file] = $this->getFileInfo($source_dir . $file); + $_filedata[$file]['relative_path'] = $relative_path; + } + } + + closedir($fp); + + return $_filedata; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Get File Info + * + * Given a file and path, returns the name, path, size, date modified + * Second parameter allows you to explicitly declare what information you want returned + * Options are: name, server_path, size, date, readable, writable, executable, fileperms + * Returns FALSE if the file cannot be found. + * + * @param string $file Path to file + * @param mixed $returned_values Array or comma separated string of information returned + * + * @return array|false + */ + protected function getFileInfo(string $file, $returned_values = ['name', 'server_path', 'size', 'date']) + { + if (! is_file($file)) + { + return false; + } + + if (is_string($returned_values)) + { + $returned_values = explode(',', $returned_values); + } + + foreach ($returned_values as $key) + { + switch ($key) + { + case 'name': + $fileInfo['name'] = basename($file); + break; + case 'server_path': + $fileInfo['server_path'] = $file; + break; + case 'size': + $fileInfo['size'] = filesize($file); + break; + case 'date': + $fileInfo['date'] = filemtime($file); + break; + case 'readable': + $fileInfo['readable'] = is_readable($file); + break; + case 'writable': + $fileInfo['writable'] = is_writable($file); + break; + case 'executable': + $fileInfo['executable'] = is_executable($file); + break; + case 'fileperms': + $fileInfo['fileperms'] = fileperms($file); + break; + } + } + + return $fileInfo; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Cache/Handlers/MemcachedHandler.php b/vendor/codeigniter4/framework/system/Cache/Handlers/MemcachedHandler.php new file mode 100644 index 0000000..b729a20 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Cache/Handlers/MemcachedHandler.php @@ -0,0 +1,388 @@ + '127.0.0.1', + 'port' => 11211, + 'weight' => 1, + 'raw' => false, + ]; + + //-------------------------------------------------------------------- + + /** + * Constructor. + * + * @param \Config\Cache $config + */ + public function __construct($config) + { + $this->prefix = $config->prefix ?: ''; + + if (! empty($config)) + { + $this->config = array_merge($this->config, $config->memcached); + } + } + + /** + * Class destructor + * + * Closes the connection to Memcache(d) if present. + */ + public function __destruct() + { + if ($this->memcached instanceof \Memcached) + { + $this->memcached->quit(); + } + elseif ($this->memcached instanceof \Memcache) + { + $this->memcached->close(); + } + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any handler-specific setup that must be done. + */ + public function initialize() + { + // Try to connect to Memcache or Memcached, if an issue occurs throw a CriticalError exception, + // so that the CacheFactory can attempt to initiate the next cache handler. + try + { + if (class_exists('\Memcached')) + { + // Create new instance of \Memcached + $this->memcached = new \Memcached(); + if ($this->config['raw']) + { + $this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); + } + + // Add server + $this->memcached->addServer( + $this->config['host'], $this->config['port'], $this->config['weight'] + ); + + // attempt to get status of servers + $stats = $this->memcached->getStats(); + + // $stats should be an associate array with a key in the format of host:port. + // If it doesn't have the key, we know the server is not working as expected. + if (! isset($stats[$this->config['host'] . ':' . $this->config['port']])) + { + throw new CriticalError('Cache: Memcached connection failed.'); + } + } + elseif (class_exists('\Memcache')) + { + // Create new instance of \Memcache + $this->memcached = new \Memcache(); + + // Check if we can connect to the server + $can_connect = $this->memcached->connect( + $this->config['host'], $this->config['port'] + ); + + // If we can't connect, throw a CriticalError exception + if ($can_connect === false) + { + throw new CriticalError('Cache: Memcache connection failed.'); + } + + // Add server, third parameter is persistence and defaults to TRUE. + $this->memcached->addServer( + $this->config['host'], $this->config['port'], true, $this->config['weight'] + ); + } + else + { + throw new CriticalError('Cache: Not support Memcache(d) extension.'); + } + } + catch (CriticalError $e) + { + // If a CriticalError exception occurs, throw it up. + throw $e; + } + catch (\Exception $e) + { + // If an \Exception occurs, convert it into a CriticalError exception and throw it. + throw new CriticalError('Cache: Memcache(d) connection refused (' . $e->getMessage() . ').'); + } + } + + //-------------------------------------------------------------------- + + /** + * Attempts to fetch an item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + */ + public function get(string $key) + { + $key = $this->prefix . $key; + + if ($this->memcached instanceof \Memcached) + { + $data = $this->memcached->get($key); + + // check for unmatched key + if ($this->memcached->getResultCode() === \Memcached::RES_NOTFOUND) + { + return null; + } + } + elseif ($this->memcached instanceof \Memcache) + { + $flags = false; + $data = $this->memcached->get($key, $flags); + + // check for unmatched key (i.e. $flags is untouched) + if ($flags === false) + { + return null; + } + } + + return is_array($data) ? $data[0] : $data; + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * @param string $key Cache item name + * @param mixed $value The data to save + * @param integer $ttl Time To Live, in seconds (default 60) + * + * @return mixed + */ + public function save(string $key, $value, int $ttl = 60) + { + $key = $this->prefix . $key; + + if (! $this->config['raw']) + { + $value = [ + $value, + time(), + $ttl, + ]; + } + + if ($this->memcached instanceof \Memcached) + { + return $this->memcached->set($key, $value, $ttl); + } + + if ($this->memcached instanceof \Memcache) + { + return $this->memcached->set($key, $value, 0, $ttl); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return boolean + */ + public function delete(string $key) + { + $key = $this->prefix . $key; + + return $this->memcached->delete($key); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function increment(string $key, int $offset = 1) + { + if (! $this->config['raw']) + { + return false; + } + + $key = $this->prefix . $key; + + return $this->memcached->increment($key, $offset, $offset, 60); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function decrement(string $key, int $offset = 1) + { + if (! $this->config['raw']) + { + return false; + } + + $key = $this->prefix . $key; + + //FIXME: third parameter isn't other handler actions. + return $this->memcached->decrement($key, $offset, $offset, 60); + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return boolean + */ + public function clean() + { + return $this->memcached->flush(); + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + */ + public function getCacheInfo() + { + return $this->memcached->getStats(); + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + */ + public function getMetaData(string $key) + { + $key = $this->prefix . $key; + + $stored = $this->memcached->get($key); + + // if not an array, don't try to count for PHP7.2 + if (! is_array($stored) || count($stored) !== 3) + { + return false; + } + + list($data, $time, $ttl) = $stored; + + return [ + 'expire' => $time + $ttl, + 'mtime' => $time, + 'data' => $data, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return (extension_loaded('memcached') || extension_loaded('memcache')); + } + +} diff --git a/vendor/codeigniter4/framework/system/Cache/Handlers/PredisHandler.php b/vendor/codeigniter4/framework/system/Cache/Handlers/PredisHandler.php new file mode 100644 index 0000000..bdfcea0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Cache/Handlers/PredisHandler.php @@ -0,0 +1,306 @@ + 'tcp', + 'host' => '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + ]; + + /** + * Predis connection + * + * @var \Predis\Client + */ + protected $redis; + + //-------------------------------------------------------------------- + + /** + * Constructor. + * + * @param \Config\Cache $config + */ + public function __construct($config) + { + $this->prefix = $config->prefix ?: ''; + + if (isset($config->redis)) + { + $this->config = array_merge($this->config, $config->redis); + } + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any handler-specific setup that must be done. + */ + public function initialize() + { + // Try to connect to Redis, if an issue occurs throw a CriticalError exception, + // so that the CacheFactory can attempt to initiate the next cache handler. + try + { + // Create a new instance of Predis\Client + $this->redis = new \Predis\Client($this->config, ['prefix' => $this->prefix]); + + // Check if the connection is valid by trying to get the time. + $this->redis->time(); + } + catch (\Exception $e) + { + // thrown if can't connect to redis server. + throw new CriticalError('Cache: Predis connection refused (' . $e->getMessage() . ').'); + } + } + + //-------------------------------------------------------------------- + + /** + * Attempts to fetch an item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + */ + public function get(string $key) + { + $data = array_combine([ + '__ci_type', + '__ci_value', + ], $this->redis->hmget($key, ['__ci_type', '__ci_value']) + ); + + if (! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false) + { + return null; + } + + switch ($data['__ci_type']) + { + case 'array': + case 'object': + return unserialize($data['__ci_value']); + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null; + case 'resource': + default: + return null; + } + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * @param string $key Cache item name + * @param mixed $value The data to save + * @param integer $ttl Time To Live, in seconds (default 60) + * + * @return mixed + */ + public function save(string $key, $value, int $ttl = 60) + { + switch ($data_type = gettype($value)) + { + case 'array': + case 'object': + $value = serialize($value); + break; + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + break; + case 'resource': + default: + return false; + } + + if (! $this->redis->hmset($key, ['__ci_type' => $data_type, '__ci_value' => $value])) + { + return false; + } + + $this->redis->expireat($key, time() + $ttl); + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return boolean + */ + public function delete(string $key) + { + return ($this->redis->del($key) === 1); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function increment(string $key, int $offset = 1) + { + return $this->redis->hincrby($key, 'data', $offset); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function decrement(string $key, int $offset = 1) + { + return $this->redis->hincrby($key, 'data', -$offset); + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return boolean + */ + public function clean() + { + return $this->redis->flushdb()->getPayload() === 'OK'; + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + */ + public function getCacheInfo() + { + return $this->redis->info(); + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + */ + public function getMetaData(string $key) + { + $data = array_combine(['__ci_value'], $this->redis->hmget($key, ['__ci_value'])); + + if (isset($data['__ci_value']) && $data['__ci_value'] !== false) + { + $time = time(); + return [ + 'expire' => $time + $this->redis->ttl($key), + 'mtime' => $time, + 'data' => $data['__ci_value'], + ]; + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return class_exists('\Predis\Client'); + } + +} diff --git a/vendor/codeigniter4/framework/system/Cache/Handlers/RedisHandler.php b/vendor/codeigniter4/framework/system/Cache/Handlers/RedisHandler.php new file mode 100644 index 0000000..639d5f5 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Cache/Handlers/RedisHandler.php @@ -0,0 +1,352 @@ + '127.0.0.1', + 'password' => null, + 'port' => 6379, + 'timeout' => 0, + 'database' => 0, + ]; + + /** + * Redis connection + * + * @var \Redis + */ + protected $redis; + + //-------------------------------------------------------------------- + + /** + * Constructor. + * + * @param \Config\Cache $config + */ + public function __construct($config) + { + $this->prefix = $config->prefix ?: ''; + + if (! empty($config)) + { + $this->config = array_merge($this->config, $config->redis); + } + } + + /** + * Class destructor + * + * Closes the connection to Redis if present. + */ + public function __destruct() + { + if ($this->redis) + { + $this->redis->close(); + } + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any handler-specific setup that must be done. + */ + public function initialize() + { + $config = $this->config; + + $this->redis = new \Redis(); + + // Try to connect to Redis, if an issue occurs throw a CriticalError exception, + // so that the CacheFactory can attempt to initiate the next cache handler. + try + { + // Note:: If Redis is your primary cache choice, and it is "offline", every page load will end up been delayed by the timeout duration. + // I feel like some sort of temporary flag should be set, to indicate that we think Redis is "offline", allowing us to bypass the timeout for a set period of time. + + if (! $this->redis->connect($config['host'], ($config['host'][0] === '/' ? 0 : $config['port']), $config['timeout'])) + { + // Note:: I'm unsure if log_message() is necessary, however I'm not 100% comfortable removing it. + log_message('error', 'Cache: Redis connection failed. Check your configuration.'); + throw new CriticalError('Cache: Redis connection failed. Check your configuration.'); + } + + if (isset($config['password']) && ! $this->redis->auth($config['password'])) + { + log_message('error', 'Cache: Redis authentication failed.'); + throw new CriticalError('Cache: Redis authentication failed.'); + } + + if (isset($config['database']) && ! $this->redis->select($config['database'])) + { + log_message('error', 'Cache: Redis select database failed.'); + throw new CriticalError('Cache: Redis select database failed.'); + } + } + catch (\RedisException $e) + { + // $this->redis->connect() can sometimes throw a RedisException. + // We need to convert the exception into a CriticalError exception and throw it. + throw new CriticalError('Cache: RedisException occurred with message (' . $e->getMessage() . ').'); + } + } + + //-------------------------------------------------------------------- + + /** + * Attempts to fetch an item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + */ + public function get(string $key) + { + $key = $this->prefix . $key; + + $data = $this->redis->hMGet($key, ['__ci_type', '__ci_value']); + + if (! isset($data['__ci_type'], $data['__ci_value']) || $data['__ci_value'] === false) + { + return null; + } + + switch ($data['__ci_type']) + { + case 'array': + case 'object': + return unserialize($data['__ci_value']); + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : null; + case 'resource': + default: + return null; + } + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * @param string $key Cache item name + * @param mixed $value The data to save + * @param integer $ttl Time To Live, in seconds (default 60) + * + * @return mixed + */ + public function save(string $key, $value, int $ttl = 60) + { + $key = $this->prefix . $key; + + switch ($data_type = gettype($value)) + { + case 'array': + case 'object': + $value = serialize($value); + break; + case 'boolean': + case 'integer': + case 'double': // Yes, 'double' is returned and NOT 'float' + case 'string': + case 'NULL': + break; + case 'resource': + default: + return false; + } + + if (! $this->redis->hMSet($key, ['__ci_type' => $data_type, '__ci_value' => $value])) + { + return false; + } + elseif ($ttl) + { + $this->redis->expireAt($key, time() + $ttl); + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return boolean + */ + public function delete(string $key) + { + $key = $this->prefix . $key; + + return ($this->redis->del($key) === 1); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function increment(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + return $this->redis->hIncrBy($key, 'data', $offset); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function decrement(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + return $this->redis->hIncrBy($key, 'data', -$offset); + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return boolean + */ + public function clean() + { + return $this->redis->flushDB(); + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + */ + public function getCacheInfo() + { + return $this->redis->info(); + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + */ + public function getMetaData(string $key) + { + $key = $this->prefix . $key; + + $value = $this->get($key); + + if ($value !== null) + { + $time = time(); + return [ + 'expire' => $time + $this->redis->ttl($key), + 'mtime' => $time, + 'data' => $value, + ]; + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return extension_loaded('redis'); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Cache/Handlers/WincacheHandler.php b/vendor/codeigniter4/framework/system/Cache/Handlers/WincacheHandler.php new file mode 100644 index 0000000..2adf812 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Cache/Handlers/WincacheHandler.php @@ -0,0 +1,263 @@ +prefix = $config->prefix ?: ''; + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any handler-specific setup that must be done. + * + * @codeCoverageIgnore + */ + public function initialize() + { + // Nothing to see here... + } + + //-------------------------------------------------------------------- + + /** + * Attempts to fetch an item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function get(string $key) + { + $key = $this->prefix . $key; + + $success = false; + $data = wincache_ucache_get($key, $success); + + // Success returned by reference from wincache_ucache_get() + return ($success) ? $data : null; + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * @param string $key Cache item name + * @param mixed $value The data to save + * @param integer $ttl Time To Live, in seconds (default 60) + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function save(string $key, $value, int $ttl = 60) + { + $key = $this->prefix . $key; + + return wincache_ucache_set($key, $value, $ttl); + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return boolean + * + * @codeCoverageIgnore + */ + public function delete(string $key) + { + $key = $this->prefix . $key; + + return wincache_ucache_delete($key); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function increment(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $success = false; + $value = wincache_ucache_inc($key, $offset, $success); + + return ($success === true) ? $value : false; + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function decrement(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $success = false; + $value = wincache_ucache_dec($key, $offset, $success); + + return ($success === true) ? $value : false; + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return boolean + * + * @codeCoverageIgnore + */ + public function clean() + { + return wincache_ucache_clear(); + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function getCacheInfo() + { + return wincache_ucache_info(true); + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + * + * @codeCoverageIgnore + */ + public function getMetaData(string $key) + { + $key = $this->prefix . $key; + + if ($stored = wincache_ucache_info(false, $key)) + { + $age = $stored['ucache_entries'][1]['age_seconds']; + $ttl = $stored['ucache_entries'][1]['ttl_seconds']; + $hitcount = $stored['ucache_entries'][1]['hitcount']; + + return [ + 'expire' => $ttl - $age, + 'hitcount' => $hitcount, + 'age' => $age, + 'ttl' => $ttl, + ]; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return (extension_loaded('wincache') && ini_get('wincache.ucenabled')); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/CodeIgniter.php b/vendor/codeigniter4/framework/system/CodeIgniter.php new file mode 100644 index 0000000..5859268 --- /dev/null +++ b/vendor/codeigniter4/framework/system/CodeIgniter.php @@ -0,0 +1,1129 @@ +startTime = microtime(true); + $this->config = $config; + } + + //-------------------------------------------------------------------- + + /** + * Handles some basic app and environment setup. + */ + public function initialize() + { + // Set default locale on the server + locale_set_default($this->config->defaultLocale ?? 'en'); + + // Set default timezone on the server + date_default_timezone_set($this->config->appTimezone ?? 'UTC'); + + // Define environment variables + $this->detectEnvironment(); + $this->bootstrapEnvironment(); + + // Setup Exception Handling + Services::exceptions() + ->initialize(); + + $this->initializeKint(); + + if (! CI_DEBUG) + { + // @codeCoverageIgnoreStart + \Kint::$enabled_mode = false; + // @codeCoverageIgnoreEnd + } + } + + //-------------------------------------------------------------------- + + /** + * Initializes Kint + */ + protected function initializeKint() + { + // If we have KINT_DIR it means it's already loaded via composer + if (! defined('KINT_DIR')) + { + spl_autoload_register(function ($class) { + $class = explode('\\', $class); + + if ('Kint' !== array_shift($class)) + { + return; + } + + $file = SYSTEMPATH . 'ThirdParty/Kint/' . implode('/', $class) . '.php'; + + file_exists($file) && require_once $file; + }); + + require_once SYSTEMPATH . 'ThirdParty/Kint/init.php'; + } + + /** + * Config\Kint + */ + $config = config('Config\Kint'); + + \Kint::$max_depth = $config->maxDepth; + \Kint::$display_called_from = $config->displayCalledFrom; + \Kint::$expanded = $config->expanded; + + if (! empty($config->plugins) && is_array($config->plugins)) + { + \Kint::$plugins = $config->plugins; + } + + \Kint\Renderer\RichRenderer::$theme = $config->richTheme; + \Kint\Renderer\RichRenderer::$folder = $config->richFolder; + \Kint\Renderer\RichRenderer::$sort = $config->richSort; + if (! empty($config->richObjectPlugins) && is_array($config->richObjectPlugins)) + { + \Kint\Renderer\RichRenderer::$object_plugins = $config->richObjectPlugins; + } + if (! empty($config->richTabPlugins) && is_array($config->richTabPlugins)) + { + \Kint\Renderer\RichRenderer::$tab_plugins = $config->richTabPlugins; + } + + \Kint\Renderer\CliRenderer::$cli_colors = $config->cliColors; + \Kint\Renderer\CliRenderer::$force_utf8 = $config->cliForceUTF8; + \Kint\Renderer\CliRenderer::$detect_width = $config->cliDetectWidth; + \Kint\Renderer\CliRenderer::$min_terminal_width = $config->cliMinWidth; + } + + //-------------------------------------------------------------------- + + /** + * Launch the application! + * + * This is "the loop" if you will. The main entry point into the script + * that gets the required class instances, fires off the filters, + * tries to route the response, loads the controller and generally + * makes all of the pieces work together. + * + * @param \CodeIgniter\Router\RouteCollectionInterface $routes + * @param boolean $returnResponse + * + * @return boolean|\CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function run(RouteCollectionInterface $routes = null, bool $returnResponse = false) + { + $this->startBenchmark(); + + $this->getRequestObject(); + $this->getResponseObject(); + + $this->forceSecureAccess(); + + $this->spoofRequestMethod(); + + Events::trigger('pre_system'); + + // Check for a cached page. Execution will stop + // if the page has been cached. + $cacheConfig = new Cache(); + $response = $this->displayCache($cacheConfig); + if ($response instanceof ResponseInterface) + { + if ($returnResponse) + { + return $response; + } + + $this->response->pretend($this->useSafeOutput)->send(); + $this->callExit(EXIT_SUCCESS); + } + + try + { + return $this->handleRequest($routes, $cacheConfig, $returnResponse); + } + catch (RedirectException $e) + { + $logger = Services::logger(); + $logger->info('REDIRECTED ROUTE at ' . $e->getMessage()); + + // If the route is a 'redirect' route, it throws + // the exception with the $to as the message + $this->response->redirect(base_url($e->getMessage()), 'auto', $e->getCode()); + $this->sendResponse(); + + $this->callExit(EXIT_SUCCESS); + } + catch (PageNotFoundException $e) + { + $this->display404errors($e); + } + } + + //-------------------------------------------------------------------- + + /** + * Set our Response instance to "pretend" mode so that things like + * cookies and headers are not actually sent, allowing PHP 7.2+ to + * not complain when ini_set() function is used. + * + * @param boolean $safe + * + * @return $this + */ + public function useSafeOutput(bool $safe = true) + { + $this->useSafeOutput = $safe; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Handles the main request logic and fires the controller. + * + * @param \CodeIgniter\Router\RouteCollectionInterface $routes + * @param $cacheConfig + * @param boolean $returnResponse + * + * @return \CodeIgniter\HTTP\RequestInterface|\CodeIgniter\HTTP\Response|\CodeIgniter\HTTP\ResponseInterface|mixed + * @throws \CodeIgniter\Router\Exceptions\RedirectException + */ + protected function handleRequest(RouteCollectionInterface $routes = null, $cacheConfig, bool $returnResponse = false) + { + $routeFilter = $this->tryToRouteIt($routes); + + // Run "before" filters + $filters = Services::filters(); + + // If any filters were specified within the routes file, + // we need to ensure it's active for the current request + if (! is_null($routeFilter)) + { + $filters->enableFilter($routeFilter, 'before'); + $filters->enableFilter($routeFilter, 'after'); + } + + $uri = $this->request instanceof CLIRequest ? $this->request->getPath() : $this->request->uri->getPath(); + + // Never run filters when running through Spark cli + if (! defined('SPARKED')) + { + $possibleRedirect = $filters->run($uri, 'before'); + if ($possibleRedirect instanceof RedirectResponse) + { + return $possibleRedirect->send(); + } + // If a Response instance is returned, the Response will be sent back to the client and script execution will stop + if ($possibleRedirect instanceof ResponseInterface) + { + return $possibleRedirect->send(); + } + } + + $returned = $this->startController(); + + // Closure controller has run in startController(). + if (! is_callable($this->controller)) + { + $controller = $this->createController(); + + // Is there a "post_controller_constructor" event? + Events::trigger('post_controller_constructor'); + + $returned = $this->runController($controller); + } + else + { + $this->benchmark->stop('controller_constructor'); + $this->benchmark->stop('controller'); + } + + // If $returned is a string, then the controller output something, + // probably a view, instead of echoing it directly. Send it along + // so it can be used with the output. + $this->gatherOutput($cacheConfig, $returned); + + // Never run filters when running through Spark cli + if (! defined('SPARKED')) + { + $filters->setResponse($this->response); + // Run "after" filters + $response = $filters->run($uri, 'after'); + } + else + { + $response = $this->response; + + // Set response code for CLI command failures + if (is_numeric($returned) || $returned === false) + { + $response->setStatusCode(400); + } + } + + if ($response instanceof Response) + { + $this->response = $response; + } + + // Save our current URI as the previous URI in the session + // for safer, more accurate use with `previous_url()` helper function. + $this->storePreviousURL((string)current_url(true)); + + unset($uri); + + if (! $returnResponse) + { + $this->sendResponse(); + } + + //-------------------------------------------------------------------- + // Is there a post-system event? + //-------------------------------------------------------------------- + Events::trigger('post_system'); + + return $this->response; + } + + //-------------------------------------------------------------------- + + /** + * You can load different configurations depending on your + * current environment. Setting the environment also influences + * things like logging and error reporting. + * + * This can be set to anything, but default usage is: + * + * development + * testing + * production + */ + protected function detectEnvironment() + { + // Make sure ENVIRONMENT isn't already set by other means. + if (! defined('ENVIRONMENT')) + { + // running under Continuous Integration server? + if (getenv('CI') !== false) + { + define('ENVIRONMENT', 'testing'); + } + else + { + define('ENVIRONMENT', $_SERVER['CI_ENVIRONMENT'] ?? 'production'); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Load any custom boot files based upon the current environment. + * + * If no boot file exists, we shouldn't continue because something + * is wrong. At the very least, they should have error reporting setup. + */ + protected function bootstrapEnvironment() + { + if (is_file(APPPATH . 'Config/Boot/' . ENVIRONMENT . '.php')) + { + require_once APPPATH . 'Config/Boot/' . ENVIRONMENT . '.php'; + } + else + { + // @codeCoverageIgnoreStart + header('HTTP/1.1 503 Service Unavailable.', true, 503); + echo 'The application environment is not set correctly.'; + exit(1); // EXIT_ERROR + // @codeCoverageIgnoreEnd + } + } + + //-------------------------------------------------------------------- + + /** + * Start the Benchmark + * + * The timer is used to display total script execution both in the + * debug toolbar, and potentially on the displayed page. + */ + protected function startBenchmark() + { + $this->startTime = microtime(true); + + $this->benchmark = Services::timer(); + $this->benchmark->start('total_execution', $this->startTime); + $this->benchmark->start('bootstrap'); + } + + //-------------------------------------------------------------------- + + /** + * Sets a Request object to be used for this request. + * Used when running certain tests. + * + * @param \CodeIgniter\HTTP\Request $request + * + * @return \CodeIgniter\CodeIgniter + */ + public function setRequest(Request $request) + { + $this->request = $request; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Get our Request object, (either IncomingRequest or CLIRequest) + * and set the server protocol based on the information provided + * by the server. + */ + protected function getRequestObject() + { + if ($this->request instanceof Request) + { + return; + } + + if (is_cli() && ENVIRONMENT !== 'testing') + { + // @codeCoverageIgnoreStart + $this->request = Services::clirequest($this->config); + // @codeCoverageIgnoreEnd + } + else + { + $this->request = Services::request($this->config); + // guess at protocol if needed + $this->request->setProtocolVersion($_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.1'); + } + } + + //-------------------------------------------------------------------- + + /** + * Get our Response object, and set some default values, including + * the HTTP protocol version and a default successful response. + */ + protected function getResponseObject() + { + $this->response = Services::response($this->config); + + if (! is_cli() || ENVIRONMENT === 'testing') + { + $this->response->setProtocolVersion($this->request->getProtocolVersion()); + } + + // Assume success until proven otherwise. + $this->response->setStatusCode(200); + } + + //-------------------------------------------------------------------- + + /** + * Force Secure Site Access? If the config value 'forceGlobalSecureRequests' + * is true, will enforce that all requests to this site are made through + * HTTPS. Will redirect the user to the current page with HTTPS, as well + * as set the HTTP Strict Transport Security header for those browsers + * that support it. + * + * @param integer $duration How long the Strict Transport Security + * should be enforced for this URL. + */ + protected function forceSecureAccess($duration = 31536000) + { + if ($this->config->forceGlobalSecureRequests !== true) + { + return; + } + + force_https($duration, $this->request, $this->response); + } + + //-------------------------------------------------------------------- + + /** + * Determines if a response has been cached for the given URI. + * + * @param \Config\Cache $config + * + * @throws \Exception + * + * @return boolean|\CodeIgniter\HTTP\ResponseInterface + */ + public function displayCache($config) + { + if ($cachedResponse = cache()->get($this->generateCacheName($config))) + { + $cachedResponse = unserialize($cachedResponse); + if (! is_array($cachedResponse) || ! isset($cachedResponse['output']) || ! isset($cachedResponse['headers'])) + { + throw new Exception('Error unserializing page cache'); + } + + $headers = $cachedResponse['headers']; + $output = $cachedResponse['output']; + + // Clear all default headers + foreach ($this->response->getHeaders() as $key => $val) + { + $this->response->removeHeader($key); + } + + // Set cached headers + foreach ($headers as $name => $value) + { + $this->response->setHeader($name, $value); + } + + $output = $this->displayPerformanceMetrics($output); + $this->response->setBody($output); + + return $this->response; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Tells the app that the final output should be cached. + * + * @param integer $time + * + * @return void + */ + public static function cache(int $time) + { + static::$cacheTTL = $time; + } + + //-------------------------------------------------------------------- + + /** + * Caches the full response from the current request. Used for + * full-page caching for very high performance. + * + * @param \Config\Cache $config + * + * @return mixed + */ + public function cachePage(Cache $config) + { + $headers = []; + foreach ($this->response->getHeaders() as $header) + { + $headers[$header->getName()] = $header->getValueLine(); + } + + return cache()->save( + $this->generateCacheName($config), serialize(['headers' => $headers, 'output' => $this->output]), static::$cacheTTL + ); + } + + //-------------------------------------------------------------------- + + /** + * Returns an array with our basic performance stats collected. + * + * @return array + */ + public function getPerformanceStats(): array + { + return [ + 'startTime' => $this->startTime, + 'totalTime' => $this->totalTime, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Generates the cache name to use for our full-page caching. + * + * @param $config + * + * @return string + */ + protected function generateCacheName($config): string + { + if (get_class($this->request) === CLIRequest::class) + { + return md5($this->request->getPath()); + } + + $uri = $this->request->uri; + + if ($config->cacheQueryString) + { + $name = URI::createURIString( + $uri->getScheme(), $uri->getAuthority(), $uri->getPath(), $uri->getQuery() + ); + } + else + { + $name = URI::createURIString( + $uri->getScheme(), $uri->getAuthority(), $uri->getPath() + ); + } + + return md5($name); + } + + //-------------------------------------------------------------------- + + /** + * Replaces the memory_usage and elapsed_time tags. + * + * @param string $output + * + * @return string + */ + public function displayPerformanceMetrics(string $output): string + { + $this->totalTime = $this->benchmark->getElapsedTime('total_execution'); + + return str_replace('{elapsed_time}', $this->totalTime, $output); + } + + //-------------------------------------------------------------------- + + /** + * Try to Route It - As it sounds like, works with the router to + * match a route against the current URI. If the route is a + * "redirect route", will also handle the redirect. + * + * @param RouteCollectionInterface $routes An collection interface to use in place + * of the config file. + * + * @return string + * @throws \CodeIgniter\Router\Exceptions\RedirectException + */ + protected function tryToRouteIt(RouteCollectionInterface $routes = null) + { + if (empty($routes) || ! $routes instanceof RouteCollectionInterface) + { + require APPPATH . 'Config/Routes.php'; + } + + // $routes is defined in Config/Routes.php + $this->router = Services::router($routes, $this->request); + + $path = $this->determinePath(); + + $this->benchmark->stop('bootstrap'); + $this->benchmark->start('routing'); + + ob_start(); + + $this->controller = $this->router->handle($path); + $this->method = $this->router->methodName(); + + // If a {locale} segment was matched in the final route, + // then we need to set the correct locale on our Request. + if ($this->router->hasLocale()) + { + $this->request->setLocale($this->router->getLocale()); + } + + $this->benchmark->stop('routing'); + + return $this->router->getFilter(); + } + + //-------------------------------------------------------------------- + + /** + * Determines the path to use for us to try to route to, based + * on user input (setPath), or the CLI/IncomingRequest path. + */ + protected function determinePath() + { + if (! empty($this->path)) + { + return $this->path; + } + + return (is_cli() && ! (ENVIRONMENT === 'testing')) ? $this->request->getPath() : $this->request->uri->getPath(); + } + + //-------------------------------------------------------------------- + + /** + * Allows the request path to be set from outside the class, + * instead of relying on CLIRequest or IncomingRequest for the path. + * + * This is primarily used by the Console. + * + * @param string $path + * + * @return $this + */ + public function setPath(string $path) + { + $this->path = $path; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Now that everything has been setup, this method attempts to run the + * controller method and make the script go. If it's not able to, will + * show the appropriate Page Not Found error. + */ + protected function startController() + { + $this->benchmark->start('controller'); + $this->benchmark->start('controller_constructor'); + + // Is it routed to a Closure? + if (is_object($this->controller) && (get_class($this->controller) === 'Closure')) + { + $controller = $this->controller; + return $controller(...$this->router->params()); + } + + // No controller specified - we don't know what to do now. + if (empty($this->controller)) + { + throw PageNotFoundException::forEmptyController(); + } + + // Try to autoload the class + if (! class_exists($this->controller, true) || $this->method[0] === '_') + { + throw PageNotFoundException::forControllerNotFound($this->controller, $this->method); + } + else if (! method_exists($this->controller, '_remap') && + ! is_callable([$this->controller, $this->method], false) + ) + { + throw PageNotFoundException::forMethodNotFound($this->method); + } + } + + //-------------------------------------------------------------------- + + /** + * Instantiates the controller class. + * + * @return mixed + */ + protected function createController() + { + $class = new $this->controller(); + $class->initController($this->request, $this->response, Services::logger()); + + $this->benchmark->stop('controller_constructor'); + + return $class; + } + + //-------------------------------------------------------------------- + + /** + * Runs the controller, allowing for _remap methods to function. + * + * @param mixed $class + * + * @return mixed + */ + protected function runController($class) + { + // If this is a console request then use the input segments as parameters + $params = defined('SPARKED') ? $this->request->getSegments() : $this->router->params(); + + if (method_exists($class, '_remap')) + { + $output = $class->_remap($this->method, ...$params); + } + else + { + $output = $class->{$this->method}(...$params); + } + + $this->benchmark->stop('controller'); + + return $output; + } + + //-------------------------------------------------------------------- + + /** + * Displays a 404 Page Not Found error. If set, will try to + * call the 404Override controller/method that was set in routing config. + * + * @param PageNotFoundException $e + */ + protected function display404errors(PageNotFoundException $e) + { + // Is there a 404 Override available? + if ($override = $this->router->get404Override()) + { + if ($override instanceof Closure) + { + echo $override($e->getMessage()); + } + else if (is_array($override)) + { + $this->benchmark->start('controller'); + $this->benchmark->start('controller_constructor'); + + $this->controller = $override[0]; + $this->method = $override[1]; + + unset($override); + + $controller = $this->createController(); + $this->runController($controller); + } + + $cacheConfig = new Cache(); + $this->gatherOutput($cacheConfig); + $this->sendResponse(); + + return; + } + + // Display 404 Errors + $this->response->setStatusCode($e->getCode()); + + if (ENVIRONMENT !== 'testing') + { + // @codeCoverageIgnoreStart + if (ob_get_level() > 0) + { + ob_end_flush(); + } + // @codeCoverageIgnoreEnd + } + else + { + // When testing, one is for phpunit, another is for test case. + if (ob_get_level() > 2) + { + ob_end_flush(); + } + } + + throw PageNotFoundException::forPageNotFound(ENVIRONMENT !== 'production' || is_cli() ? $e->getMessage() : ''); + } + + //-------------------------------------------------------------------- + + /** + * Gathers the script output from the buffer, replaces some execution + * time tag in the output and displays the debug toolbar, if required. + * + * @param null $cacheConfig + * @param null $returned + */ + protected function gatherOutput($cacheConfig = null, $returned = null) + { + $this->output = ob_get_contents(); + // If buffering is not null. + // Clean (erase) the output buffer and turn off output buffering + if (ob_get_length()) + { + ob_end_clean(); + } + + if ($returned instanceof DownloadResponse) + { + $this->response = $returned; + return; + } + // If the controller returned a response object, + // we need to grab the body from it so it can + // be added to anything else that might have been + // echoed already. + // We also need to save the instance locally + // so that any status code changes, etc, take place. + if ($returned instanceof Response) + { + $this->response = $returned; + $returned = $returned->getBody(); + } + + if (is_string($returned)) + { + $this->output .= $returned; + } + + // Cache it without the performance metrics replaced + // so that we can have live speed updates along the way. + if (static::$cacheTTL > 0) + { + $this->cachePage($cacheConfig); + } + + $this->output = $this->displayPerformanceMetrics($this->output); + + $this->response->setBody($this->output); + } + + //-------------------------------------------------------------------- + + /** + * If we have a session object to use, store the current URI + * as the previous URI. This is called just prior to sending the + * response to the client, and will make it available next request. + * + * This helps provider safer, more reliable previous_url() detection. + * + * @param \CodeIgniter\HTTP\URI $uri + */ + public function storePreviousURL($uri) + { + // Ignore CLI requests + if (is_cli()) + { + return; + } + // Ignore AJAX requests + if (method_exists($this->request, 'isAJAX') && $this->request->isAJAX()) + { + return; + } + + // This is mainly needed during testing... + if (is_string($uri)) + { + $uri = new URI($uri); + } + + if (isset($_SESSION)) + { + $_SESSION['_ci_previous_url'] = (string) $uri; + } + } + + //-------------------------------------------------------------------- + + /** + * Modifies the Request Object to use a different method if a POST + * variable called _method is found. + */ + public function spoofRequestMethod() + { + // Only works with POSTED forms + if ($this->request->getMethod() !== 'post') + { + return; + } + + $method = $this->request->getPost('_method'); + + if (empty($method)) + { + return; + } + + $this->request = $this->request->setMethod($method); + } + + /** + * Sends the output of this request back to the client. + * This is what they've been waiting for! + */ + protected function sendResponse() + { + $this->response->pretend($this->useSafeOutput)->send(); + } + + //-------------------------------------------------------------------- + + /** + * Exits the application, setting the exit code for CLI-based applications + * that might be watching. + * + * Made into a separate method so that it can be mocked during testing + * without actually stopping script execution. + * + * @param $code + */ + protected function callExit($code) + { + // @codeCoverageIgnoreStart + exit($code); + // @codeCoverageIgnoreEnd + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Commands/Cache/ClearCache.php b/vendor/codeigniter4/framework/system/Commands/Cache/ClearCache.php new file mode 100644 index 0000000..35c6581 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Cache/ClearCache.php @@ -0,0 +1,73 @@ + 'The cache driver to use', + ]; + + /** + * Creates a new migration file with the current timestamp. + * + * @param array $params + */ + public function run(array $params = []) + { + $config = config('Cache'); + + $handler = $params[0] ?? $config->handler; + if (! array_key_exists($handler, $config->validHandlers)) + { + CLI::error($handler . ' is not a valid cache handler.'); + return; + } + + $config->handler = $handler; + $cache = CacheFactory::getHandler($config); + + if (! $cache->clean()) + { + CLI::error('Error while clearing the cache.'); + return; + } + + CLI::write(CLI::color('Done', 'green')); + } +} diff --git a/vendor/codeigniter4/framework/system/Commands/Database/CreateMigration.php b/vendor/codeigniter4/framework/system/Commands/Database/CreateMigration.php new file mode 100644 index 0000000..3983d67 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Database/CreateMigration.php @@ -0,0 +1,186 @@ + 'The migration file name', + ]; + + /** + * the Command's Options + * + * @var array + */ + protected $options = [ + '-n' => 'Set migration namespace', + ]; + + /** + * Creates a new migration file with the current timestamp. + * + * @param array $params + */ + public function run(array $params = []) + { + helper('inflector'); + $name = array_shift($params); + + if (empty($name)) + { + $name = CLI::prompt(lang('Migrations.nameMigration')); + } + + if (empty($name)) + { + CLI::error(lang('Migrations.badCreateName')); + return; + } + + $ns = $params['-n'] ?? CLI::getOption('n'); + $homepath = APPPATH; + + if (! empty($ns)) + { + // Get all namespaces + $namespaces = Services::autoloader()->getNamespace(); + + foreach ($namespaces as $namespace => $path) + { + if ($namespace === $ns) + { + $homepath = realpath(reset($path)); + break; + } + } + } + else + { + $ns = 'App'; + } + + // Always use UTC/GMT so global teams can work together + $config = config('Migrations'); + $fileName = gmdate($config->timestampFormat) . $name; + + // full path + $path = $homepath . '/Database/Migrations/' . $fileName . '.php'; + + // Class name should be pascal case now (camel case with upper first letter) + $name = pascalize($name); + + $template = << 'The seeder file name', + ]; + + /** + * the Command's Options + * + * @var array + */ + protected $options = [ + '-n' => 'Set seeder namespace', + ]; + + /** + * Creates a new migration file with the current timestamp. + * + * @param array $params + */ + public function run(array $params = []) + { + helper('inflector'); + + $name = array_shift($params); + + if (empty($name)) + { + $name = CLI::prompt(lang('Seed.nameFile'), null, 'required'); + } + + $ns = $params['-n'] ?? CLI::getOption('n'); + $homepath = APPPATH; + + if (! empty($ns)) + { + // Get all namespaces + $namespaces = Services::autoloader()->getNamespace(); + + foreach ($namespaces as $namespace => $path) + { + if ($namespace === $ns) + { + $homepath = realpath(reset($path)) . DIRECTORY_SEPARATOR; + break; + } + } + } + else + { + $ns = defined('APP_NAMESPACE') ? APP_NAMESPACE : 'App'; + } + + // full path + $path = $homepath . 'Database/Seeds/' . $name . '.php'; + + // Class name should be pascal case now (camel case with upper first letter) + $name = pascalize($name); + + $template = << 'Set migration namespace', + '-g' => 'Set database group', + '-all' => 'Set for all namespaces, will ignore (-n) option', + ]; + + /** + * Ensures that all migrations have been run. + * + * @param array $params + */ + public function run(array $params = []) + { + $runner = Services::migrations(); + $runner->clearCliMessages(); + + CLI::write(lang('Migrations.latest'), 'yellow'); + + $namespace = $params['-n'] ?? CLI::getOption('n'); + $group = $params['-g'] ?? CLI::getOption('g'); + + try + { + // Check for 'all' namespaces + if ($this->isAllNamespace($params)) + { + $runner->setNamespace(null); + } + // Check for a specified namespace + elseif ($namespace) + { + $runner->setNamespace($namespace); + } + + if (! $runner->latest($group)) + { + CLI::write(lang('Migrations.generalFault'), 'red'); + } + + $messages = $runner->getCliMessages(); + foreach ($messages as $message) + { + CLI::write($message); + } + + CLI::write('Done'); + } + catch (\Exception $e) + { + $this->showError($e); + } + } + + /** + * To migrate all namespaces to the latest migration + * + * Demo: + * 1. command line: php spark migrate:latest -all + * 2. command file: $this->call('migrate:latest', ['-g' => 'test','-all']); + * + * @param array $params + * @return boolean + */ + private function isAllNamespace(array $params): bool + { + if (array_search('-all', $params) !== false) + { + return true; + } + + return ! is_null(CLI::getOption('all')); + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Database/MigrateRefresh.php b/vendor/codeigniter4/framework/system/Commands/Database/MigrateRefresh.php new file mode 100644 index 0000000..bf6b4f8 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Database/MigrateRefresh.php @@ -0,0 +1,127 @@ + 'Set migration namespace', + '-g' => 'Set database group', + '-all' => 'Set latest for all namespace, will ignore (-n) option', + '-f' => 'Force command - this option allows you to bypass the confirmation question when running this command in a production environment', + ]; + + /** + * Does a rollback followed by a latest to refresh the current state + * of the database. + * + * @param array $params + */ + public function run(array $params = []) + { + $params = ['-b' => 0]; + + if (ENVIRONMENT === 'production') + { + $force = $params['-f'] ?? CLI::getOption('f'); + if (is_null($force) && CLI::prompt(lang('Migrations.refreshConfirm'), ['y', 'n']) === 'n') + { + return; + } + + $params['-f'] = ''; + } + + $this->call('migrate:rollback', $params); + $this->call('migrate'); + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Database/MigrateRollback.php b/vendor/codeigniter4/framework/system/Commands/Database/MigrateRollback.php new file mode 100644 index 0000000..b2dca1c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Database/MigrateRollback.php @@ -0,0 +1,151 @@ + 'Specify a batch to roll back to; e.g. "3" to return to batch #3 or "-2" to roll back twice', + '-g' => 'Set database group', + '-f' => 'Force command - this option allows you to bypass the confirmation question when running this command in a production environment', + ]; + + /** + * Runs all of the migrations in reverse order, until they have + * all been un-applied. + * + * @param array $params + */ + public function run(array $params = []) + { + if (ENVIRONMENT === 'production') + { + $force = $params['-f'] ?? CLI::getOption('f'); + if (is_null($force) && CLI::prompt(lang('Migrations.rollBackConfirm'), ['y', 'n']) === 'n') + { + return; + } + } + + $runner = Services::migrations(); + + $group = $params['-g'] ?? CLI::getOption('g'); + + if (! is_null($group)) + { + $runner->setGroup($group); + } + + try + { + $batch = $params['-b'] ?? CLI::getOption('b') ?? $runner->getLastBatch() - 1; + CLI::write(lang('Migrations.rollingBack') . ' ' . $batch, 'yellow'); + + if (! $runner->regress($batch)) + { + CLI::write(lang('Migrations.generalFault'), 'red'); + } + + $messages = $runner->getCliMessages(); + foreach ($messages as $message) + { + CLI::write($message); + } + + CLI::write('Done'); + } + catch (\Exception $e) + { + $this->showError($e); + } + } +} diff --git a/vendor/codeigniter4/framework/system/Commands/Database/MigrateStatus.php b/vendor/codeigniter4/framework/system/Commands/Database/MigrateStatus.php new file mode 100644 index 0000000..94ad3ea --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Database/MigrateStatus.php @@ -0,0 +1,192 @@ + 'Set database group', + ]; + + /** + * Namespaces to ignore when looking for migrations. + * + * @var type + */ + protected $ignoredNamespaces = [ + 'CodeIgniter', + 'Config', + 'Tests\Support', + 'Kint', + 'Laminas\ZendFrameworkBridge', + 'Laminas\Escaper', + 'Psr\Log', + ]; + + /** + * Displays a list of all migrations and whether they've been run or not. + * + * @param array $params + */ + public function run(array $params = []) + { + $runner = Services::migrations(); + + $group = $params['-g'] ?? CLI::getOption('g'); + + if (! is_null($group)) + { + $runner->setGroup($group); + } + + // Get all namespaces + $namespaces = Services::autoloader()->getNamespace(); + + // Determines whether any migrations were found + $found = false; + + // Loop for all $namespaces + foreach ($namespaces as $namespace => $path) + { + if (in_array($namespace, $this->ignoredNamespaces)) + { + continue; + } + + $runner->setNamespace($namespace); + $migrations = $runner->findMigrations(); + + if (empty($migrations)) + { + continue; + } + + $found = true; + $history = $runner->getHistory(); + + CLI::write($namespace); + + ksort($migrations); + + $max = 0; + foreach ($migrations as $version => $migration) + { + $file = substr($migration->name, strpos($migration->name, $version . '_')); + $migrations[$version]->name = $file; + + $max = max($max, strlen($file)); + } + + CLI::write(' ' . str_pad(lang('Migrations.filename'), $max + 4) . lang('Migrations.on'), 'yellow'); + + foreach ($migrations as $uid => $migration) + { + $date = ''; + foreach ($history as $row) + { + if ($runner->getObjectUid($row) !== $uid) + { + continue; + } + + $date = date('Y-m-d H:i:s', $row->time); + } + CLI::write(str_pad(' ' . $migration->name, $max + 6) . ($date ? $date : '---')); + } + } + + if (! $found) + { + CLI::error(lang('Migrations.noneFound')); + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Database/Seed.php b/vendor/codeigniter4/framework/system/Commands/Database/Seed.php new file mode 100644 index 0000000..ee09e0a --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Database/Seed.php @@ -0,0 +1,132 @@ + 'The seeder name to run', + ]; + + /** + * the Command's Options + * + * @var array + */ + protected $options = []; + + /** + * Passes to Seeder to populate the database. + * + * @param array $params + */ + public function run(array $params = []) + { + $seeder = new Seeder(new \Config\Database()); + + $seedName = array_shift($params); + + if (empty($seedName)) + { + $seedName = CLI::prompt(lang('Migrations.migSeeder'), 'DatabaseSeeder'); + } + + if (empty($seedName)) + { + CLI::error(lang('Migrations.migMissingSeeder')); + return; + } + + try + { + $seeder->call($seedName); + } + catch (\Exception $e) + { + $this->showError($e); + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Help.php b/vendor/codeigniter4/framework/system/Commands/Help.php new file mode 100644 index 0000000..5769685 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Help.php @@ -0,0 +1,121 @@ + 'The command name [default: "help"]', + ]; + + /** + * the Command's Options + * + * @var array + */ + protected $options = []; + + //-------------------------------------------------------------------- + + /** + * Displays the help for the spark cli script itself. + * + * @param array $params + */ + public function run(array $params) + { + $command = array_shift($params); + if (is_null($command)) + { + $command = 'help'; + } + + $commands = $this->commands->getCommands(); + $class = new $commands[$command]['class']($this->logger, $this->commands); + + $class->showHelp(); + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/ListCommands.php b/vendor/codeigniter4/framework/system/Commands/ListCommands.php new file mode 100644 index 0000000..c20fe32 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/ListCommands.php @@ -0,0 +1,196 @@ +commands->getCommands(); + + $this->describeCommands($commands); + + CLI::newLine(); + } + + //-------------------------------------------------------------------- + + /** + * Displays the commands on the CLI. + * + * @param array $commands + */ + protected function describeCommands(array $commands = []) + { + ksort($commands); + + // Sort into buckets by group + $sorted = []; + $maxTitleLength = 0; + + foreach ($commands as $title => $command) + { + if (! isset($sorted[$command['group']])) + { + $sorted[$command['group']] = []; + } + + $sorted[$command['group']][$title] = $command; + + $maxTitleLength = max($maxTitleLength, strlen($title)); + } + + ksort($sorted); + + // Display it all... + foreach ($sorted as $group => $items) + { + CLI::newLine(); + CLI::write($group); + + foreach ($items as $title => $item) + { + $title = $this->padTitle($title, $maxTitleLength, 2, 2); + + $out = CLI::color($title, 'yellow'); + + if (isset($item['description'])) + { + $out .= CLI::wrap($item['description'], 125, strlen($title)); + } + + CLI::write($out); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Pads our string out so that all titles are the same length to nicely line up descriptions. + * + * @param string $item + * @param integer $max + * @param integer $extra // How many extra spaces to add at the end + * @param integer $indent + * + * @return string + */ + protected function padTitle(string $item, int $max, int $extra = 2, int $indent = 0): string + { + $max += $extra + $indent; + + $item = str_repeat(' ', $indent) . $item; + + return str_pad($item, $max); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Commands/Server/Serve.php b/vendor/codeigniter4/framework/system/Commands/Server/Serve.php new file mode 100644 index 0000000..9e65862 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Server/Serve.php @@ -0,0 +1,168 @@ + 'The PHP Binary [default: "PHP_BINARY"]', + '-host' => 'The HTTP Host [default: "localhost"]', + '-port' => 'The HTTP Host Port [default: "8080"]', + ]; + + /** + * Run the server + * + * @param array $params Parameters + * + * @return void + */ + public function run(array $params) + { + // Valid PHP Version? + if (phpversion() < $this->minPHPVersion) + { + // @codeCoverageIgnoreStart + die('Your PHP version must be ' . $this->minPHPVersion . + ' or higher to run CodeIgniter. Current version: ' . phpversion()); + // @codeCoverageIgnoreEnd + } + + // Collect any user-supplied options and apply them. + $php = escapeshellarg(CLI::getOption('php') ?? PHP_BINARY); + $host = CLI::getOption('host') ?? 'localhost'; + $port = (int) (CLI::getOption('port') ?? '8080') + $this->portOffset; + + // Get the party started. + CLI::write('CodeIgniter development server started on http://' . $host . ':' . $port, 'green'); + CLI::write('Press Control-C to stop.'); + + // Set the Front Controller path as Document Root. + $docroot = escapeshellarg(FCPATH); + + // Mimic Apache's mod_rewrite functionality with user settings. + $rewrite = escapeshellarg(__DIR__ . '/rewrite.php'); + + // Call PHP's built-in webserver, making sure to set our + // base path to the public folder, and to use the rewrite file + // to ensure our environment is set and it simulates basic mod_rewrite. + passthru($php . ' -S ' . $host . ':' . $port . ' -t ' . $docroot . ' ' . $rewrite, $status); + + if ($status && $this->portOffset < $this->tries) + { + $this->portOffset += 1; + + $this->run($params); + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Server/rewrite.php b/vendor/codeigniter4/framework/system/Commands/Server/rewrite.php new file mode 100644 index 0000000..94b7d15 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Server/rewrite.php @@ -0,0 +1,35 @@ + 'Set migration namespace', + '-g' => 'Set database group', + '-t' => 'Set table name', + ]; + + /** + * Creates a new migration file with the current timestamp. + * + * @param array $params + */ + public function run(array $params = []) + { + $config = new App(); + + $tableName = CLI::getOption('t') ?? 'ci_sessions'; + + $path = APPPATH . 'Database/Migrations/' . date('YmdHis_') . 'create_' . $tableName . '_table' . '.php'; + + $data = [ + 'namespace' => CLI::getOption('n') ?? APP_NAMESPACE ?? 'App', + 'DBGroup' => CLI::getOption('g'), + 'tableName' => $tableName, + 'matchIP' => $config->sessionMatchIP ?? false, + ]; + + $template = view('\CodeIgniter\Commands\Sessions\Views\migration.tpl.php', $data, ['debug' => false]); + $template = str_replace('@php', '\Database\Migrations; + +use CodeIgniter\Database\Migration; + +class Migration_create__table extends Migration +{ + + protected $DBGroup = ''; + + + public function up() + { + $this->forge->addField([ + 'id' => [ + 'type' => 'VARCHAR', + 'constraint' => 128, + 'null' => false + ], + 'ip_address' => [ + 'type' => 'VARCHAR', + 'constraint' => 45, + 'null' => false + ], + 'timestamp' => [ + 'type' => 'INT', + 'constraint' => 10, + 'unsigned' => true, + 'null' => false, + 'default' => 0 + ], + 'data' => [ + 'type' => 'TEXT', + 'null' => false, + 'default' => '' + ], + ]); + + $this->forge->addKey(['id', 'ip_address'], true); + + $this->forge->addKey('id', true); + + $this->forge->addKey('timestamp'); + $this->forge->createTable('', true); + } + + //-------------------------------------------------------------------- + + public function down() + { + $this->forge->dropTable('', true); + } +} diff --git a/vendor/codeigniter4/framework/system/Commands/Utilities/Namespaces.php b/vendor/codeigniter4/framework/system/Commands/Utilities/Namespaces.php new file mode 100644 index 0000000..0472277 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Utilities/Namespaces.php @@ -0,0 +1,131 @@ +psr4 as $ns => $path) + { + $path = realpath($path) ?: $path; + + $tbody[] = [ + $ns, + realpath($path) ?: $path, + is_dir($path) ? 'Yes' : 'MISSING', + ]; + } + + $thead = [ + 'Namespace', + 'Path', + 'Found?', + ]; + + CLI::table($tbody, $thead); + } + +} diff --git a/vendor/codeigniter4/framework/system/Commands/Utilities/Routes.php b/vendor/codeigniter4/framework/system/Commands/Utilities/Routes.php new file mode 100644 index 0000000..4d4a2ef --- /dev/null +++ b/vendor/codeigniter4/framework/system/Commands/Utilities/Routes.php @@ -0,0 +1,150 @@ +getRoutes($method); + + foreach ($routes as $route => $handler) + { + // filter for strings, as callbacks aren't displayable + if (is_string($handler)) + { + $tbody[] = [ + strtoupper($method), + $route, + $handler, + ]; + } + } + } + + $thead = [ + 'Method', + 'Route', + 'Handler', + ]; + + CLI::table($tbody, $thead); + } + +} diff --git a/vendor/codeigniter4/framework/system/Common.php b/vendor/codeigniter4/framework/system/Common.php new file mode 100644 index 0000000..22dd413 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Common.php @@ -0,0 +1,1142 @@ +appTimezone; + } +} + +if (! function_exists('cache')) +{ + /** + * A convenience method that provides access to the Cache + * object. If no parameter is provided, will return the object, + * otherwise, will attempt to return the cached value. + * + * Examples: + * cache()->save('foo', 'bar'); + * $foo = cache('bar'); + * + * @param string|null $key + * + * @return \CodeIgniter\Cache\CacheInterface|mixed + */ + function cache(string $key = null) + { + $cache = Services::cache(); + + // No params - return cache object + if (is_null($key)) + { + return $cache; + } + + // Still here? Retrieve the value. + return $cache->get($key); + } +} + +if (! function_exists('command')) +{ + /** + * Runs a single command. + * Input expected in a single string as would + * be used on the command line itself: + * + * > command('migrate:create SomeMigration'); + * + * @param string $command + * + * @return false|string + */ + function command(string $command) + { + $runner = service('commands'); + + $params = explode(' ', $command); + $command = array_shift($params); + + ob_start(); + $runner->run($command, $params); + $output = ob_get_clean(); + + return $output; + } +} + +if (! function_exists('config')) +{ + /** + * More simple way of getting config instances + * + * @param string $name + * @param boolean $getShared + * + * @return mixed + */ + function config(string $name, bool $getShared = true) + { + return Config::get($name, $getShared); + } +} + +if (! function_exists('csrf_token')) +{ + /** + * Returns the CSRF token name. + * Can be used in Views when building hidden inputs manually, + * or used in javascript vars when using APIs. + * + * @return string + */ + function csrf_token(): string + { + $config = config(App::class); + + return $config->CSRFTokenName; + } +} + +if (! function_exists('csrf_header')) +{ + /** + * Returns the CSRF header name. + * Can be used in Views by adding it to the meta tag + * or used in javascript to define a header name when using APIs. + * + * @return string + */ + function csrf_header(): string + { + $config = config(App::class); + + return $config->CSRFHeaderName; + } +} + +if (! function_exists('csrf_hash')) +{ + /** + * Returns the current hash value for the CSRF protection. + * Can be used in Views when building hidden inputs manually, + * or used in javascript vars for API usage. + * + * @return string + */ + function csrf_hash(): string + { + $security = Services::security(null, true); + + return $security->getCSRFHash(); + } +} + +if (! function_exists('csrf_field')) +{ + /** + * Generates a hidden input field for use within manually generated forms. + * + * @param string|null $id + * + * @return string + */ + function csrf_field(string $id = null): string + { + return ''; + } +} + +if (! function_exists('csrf_meta')) +{ + /** + * Generates a meta tag for use within javascript calls. + * + * @param string|null $id + * + * @return string + */ + function csrf_meta(string $id = null): string + { + return ''; + } +} + +if (! function_exists('db_connect')) +{ + /** + * Grabs a database connection and returns it to the user. + * + * This is a convenience wrapper for \Config\Database::connect() + * and supports the same parameters. Namely: + * + * When passing in $db, you may pass any of the following to connect: + * - group name + * - existing connection instance + * - array of database configuration values + * + * If $getShared === false then a new connection instance will be provided, + * otherwise it will all calls will return the same instance. + * + * @param \CodeIgniter\Database\ConnectionInterface|array|string $db + * @param boolean $getShared + * + * @return \CodeIgniter\Database\BaseConnection + */ + function db_connect($db = null, bool $getShared = true) + { + return Database::connect($db, $getShared); + } +} + +if (! function_exists('dd')) +{ + /** + * Prints a Kint debug report and exits. + * + * @param array ...$vars + * + * @codeCoverageIgnore Can't be tested ... exits + */ + function dd(...$vars) + { + // @codeCoverageIgnoreStart + Kint::$aliases[] = 'dd'; + Kint::dump(...$vars); + exit; + // @codeCoverageIgnoreEnd + } +} + +if (! function_exists('env')) +{ + /** + * Allows user to retrieve values from the environment + * variables that have been set. Especially useful for + * retrieving values set from the .env file for + * use in config files. + * + * @param string $key + * @param null $default + * + * @return mixed + */ + function env(string $key, $default = null) + { + $value = getenv($key); + if ($value === false) + { + $value = $_ENV[$key] ?? $_SERVER[$key] ?? false; + } + + // Not found? Return the default value + if ($value === false) + { + return $default; + } + + // Handle any boolean values + switch (strtolower($value)) + { + case 'true': + return true; + case 'false': + return false; + case 'empty': + return ''; + case 'null': + return null; + } + + return $value; + } +} + +if (! function_exists('esc')) +{ + /** + * Performs simple auto-escaping of data for security reasons. + * Might consider making this more complex at a later date. + * + * If $data is a string, then it simply escapes and returns it. + * If $data is an array, then it loops over it, escaping each + * 'value' of the key/value pairs. + * + * Valid context values: html, js, css, url, attr, raw, null + * + * @param string|array $data + * @param string $context + * @param string $encoding + * + * @return string|array + * @throws \InvalidArgumentException + */ + function esc($data, string $context = 'html', string $encoding = null) + { + if (is_array($data)) + { + foreach ($data as &$value) + { + $value = esc($value, $context); + } + } + + if (is_string($data)) + { + $context = strtolower($context); + + // Provide a way to NOT escape data since + // this could be called automatically by + // the View library. + if (empty($context) || $context === 'raw') + { + return $data; + } + + if (! in_array($context, ['html', 'js', 'css', 'url', 'attr'])) + { + throw new InvalidArgumentException('Invalid escape context provided.'); + } + + if ($context === 'attr') + { + $method = 'escapeHtmlAttr'; + } + else + { + $method = 'escape' . ucfirst($context); + } + + static $escaper; + if (! $escaper) + { + $escaper = new Escaper($encoding); + } + + if ($encoding && $escaper->getEncoding() !== $encoding) + { + $escaper = new Escaper($encoding); + } + + $data = $escaper->$method($data); + } + + return $data; + } +} + +if (! function_exists('force_https')) +{ + /** + * Used to force a page to be accessed in via HTTPS. + * Uses a standard redirect, plus will set the HSTS header + * for modern browsers that support, which gives best + * protection against man-in-the-middle attacks. + * + * @see https://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security + * + * @param integer $duration How long should the SSL header be set for? (in seconds) + * Defaults to 1 year. + * @param RequestInterface $request + * @param ResponseInterface $response + * + * @throws \CodeIgniter\HTTP\Exceptions\HTTPException + */ + function force_https(int $duration = 31536000, RequestInterface $request = null, ResponseInterface $response = null) + { + if (is_null($request)) + { + $request = Services::request(null, true); + } + if (is_null($response)) + { + $response = Services::response(null, true); + } + + if ((ENVIRONMENT !== 'testing' && (is_cli() || $request->isSecure())) || (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'test')) + { + // @codeCoverageIgnoreStart + return; + // @codeCoverageIgnoreEnd + } + + // If the session status is active, we should regenerate + // the session ID for safety sake. + if (ENVIRONMENT !== 'testing' && session_status() === PHP_SESSION_ACTIVE) + { + // @codeCoverageIgnoreStart + Services::session(null, true) + ->regenerate(); + // @codeCoverageIgnoreEnd + } + + $baseURL = config(App::class)->baseURL; + + if (strpos($baseURL, 'https://') === 0) + { + $baseURL = (string) substr($baseURL, strlen('https://')); + } + elseif (strpos($baseURL, 'http://') === 0) + { + $baseURL = (string) substr($baseURL, strlen('http://')); + } + + $uri = URI::createURIString( + 'https', $baseURL, $request->uri->getPath(), // Absolute URIs should use a "/" for an empty path + $request->uri->getQuery(), $request->uri->getFragment() + ); + + // Set an HSTS header + $response->setHeader('Strict-Transport-Security', 'max-age=' . $duration); + $response->redirect($uri); + $response->sendHeaders(); + + if (ENVIRONMENT !== 'testing') + { + // @codeCoverageIgnoreStart + exit(); + // @codeCoverageIgnoreEnd + } + } +} + +if (! function_exists('function_usable')) +{ + /** + * Function usable + * + * Executes a function_exists() check, and if the Suhosin PHP + * extension is loaded - checks whether the function that is + * checked might be disabled in there as well. + * + * This is useful as function_exists() will return FALSE for + * functions disabled via the *disable_functions* php.ini + * setting, but not for *suhosin.executor.func.blacklist* and + * *suhosin.executor.disable_eval*. These settings will just + * terminate script execution if a disabled function is executed. + * + * The above described behavior turned out to be a bug in Suhosin, + * but even though a fix was committed for 0.9.34 on 2012-02-12, + * that version is yet to be released. This function will therefore + * be just temporary, but would probably be kept for a few years. + * + * @link http://www.hardened-php.net/suhosin/ + * @param string $function_name Function to check for + * @return boolean TRUE if the function exists and is safe to call, + * FALSE otherwise. + * + * @codeCoverageIgnore This is too exotic + */ + function function_usable(string $function_name): bool + { + static $_suhosin_func_blacklist; + + if (function_exists($function_name)) + { + if (! isset($_suhosin_func_blacklist)) + { + $_suhosin_func_blacklist = extension_loaded('suhosin') ? explode(',', trim(ini_get('suhosin.executor.func.blacklist'))) : []; + } + + return ! in_array($function_name, $_suhosin_func_blacklist, true); + } + + return false; + } +} + +if (! function_exists('helper')) +{ + /** + * Loads a helper file into memory. Supports namespaced helpers, + * both in and out of the 'helpers' directory of a namespaced directory. + * + * Will load ALL helpers of the matching name, in the following order: + * 1. app/Helpers + * 2. {namespace}/Helpers + * 3. system/Helpers + * + * @param string|array $filenames + * @throws \CodeIgniter\Files\Exceptions\FileNotFoundException + */ + function helper($filenames) + { + $loader = Services::locator(true); + + if (! is_array($filenames)) + { + $filenames = [$filenames]; + } + + // Store a list of all files to include... + $includes = []; + + foreach ($filenames as $filename) + { + // Store our system and application helper + // versions so that we can control the load ordering. + $systemHelper = null; + $appHelper = null; + $localIncludes = []; + + if (strpos($filename, '_helper') === false) + { + $filename .= '_helper'; + } + + // If the file is namespaced, we'll just grab that + // file and not search for any others + if (strpos($filename, '\\') !== false) + { + $path = $loader->locateFile($filename, 'Helpers'); + + if (empty($path)) + { + throw FileNotFoundException::forFileNotFound($filename); + } + + $includes[] = $path; + } + + // No namespaces, so search in all available locations + else + { + $paths = $loader->search('Helpers/' . $filename); + + if (! empty($paths)) + { + foreach ($paths as $path) + { + if (strpos($path, APPPATH) === 0) + { + // @codeCoverageIgnoreStart + $appHelper = $path; + // @codeCoverageIgnoreEnd + } + elseif (strpos($path, SYSTEMPATH) === 0) + { + $systemHelper = $path; + } + else + { + $localIncludes[] = $path; + } + } + } + + // App-level helpers should override all others + if (! empty($appHelper)) + { + // @codeCoverageIgnoreStart + $includes[] = $appHelper; + // @codeCoverageIgnoreEnd + } + + // All namespaced files get added in next + $includes = array_merge($includes, $localIncludes); + + // And the system default one should be added in last. + if (! empty($systemHelper)) + { + $includes[] = $systemHelper; + } + } + } + + // Now actually include all of the files + if (! empty($includes)) + { + foreach ($includes as $path) + { + include_once($path); + } + } + } +} + +if (! function_exists('is_cli')) +{ + /** + * Is CLI? + * + * Test to see if a request was made from the command line. + * + * @return boolean + */ + function is_cli(): bool + { + return (PHP_SAPI === 'cli' || defined('STDIN')); + } +} + +if (! function_exists('is_really_writable')) +{ + /** + * Tests for file writability + * + * is_writable() returns TRUE on Windows servers when you really can't write to + * the file, based on the read-only attribute. is_writable() is also unreliable + * on Unix servers if safe_mode is on. + * + * @link https://bugs.php.net/bug.php?id=54709 + * + * @param string $file + * + * @return boolean + * + * @throws \Exception + * @codeCoverageIgnore Not practical to test, as travis runs on linux + */ + function is_really_writable(string $file): bool + { + // If we're on a Unix server with safe_mode off we call is_writable + if (DIRECTORY_SEPARATOR === '/' || ! ini_get('safe_mode')) + { + return is_writable($file); + } + + /* For Windows servers and safe_mode "on" installations we'll actually + * write a file then read it. Bah... + */ + if (is_dir($file)) + { + $file = rtrim($file, '/') . '/' . bin2hex(random_bytes(16)); + if (($fp = @fopen($file, 'ab')) === false) + { + return false; + } + + fclose($fp); + @chmod($file, 0777); + @unlink($file); + + return true; + } + elseif (! is_file($file) || ( $fp = @fopen($file, 'ab')) === false) + { + return false; + } + + fclose($fp); + + return true; + } +} + +if (! function_exists('lang')) +{ + /** + * A convenience method to translate a string or array of them and format + * the result with the intl extension's MessageFormatter. + * + * @param string|[] $line + * @param array $args + * @param string $locale + * + * @return string + */ + function lang(string $line, array $args = [], string $locale = null) + { + return Services::language($locale) + ->getLine($line, $args); + } +} + +if (! function_exists('log_message')) +{ + /** + * A convenience/compatibility method for logging events through + * the Log system. + * + * Allowed log levels are: + * - emergency + * - alert + * - critical + * - error + * - warning + * - notice + * - info + * - debug + * + * @param string $level + * @param string $message + * @param array|null $context + * + * @return mixed + */ + function log_message(string $level, string $message, array $context = []) + { + // When running tests, we want to always ensure that the + // TestLogger is running, which provides utilities for + // for asserting that logs were called in the test code. + if (ENVIRONMENT === 'testing') + { + $logger = new TestLogger(new Logger()); + + return $logger->log($level, $message, $context); + } + + // @codeCoverageIgnoreStart + return Services::logger(true) + ->log($level, $message, $context); + // @codeCoverageIgnoreEnd + } +} + +if (! function_exists('model')) +{ + /** + * More simple way of getting model instances + * + * @param string $name + * @param boolean $getShared + * @param ConnectionInterface|null $conn + * + * @return mixed + */ + function model(string $name, bool $getShared = true, ConnectionInterface &$conn = null) + { + return \CodeIgniter\Database\ModelFactory::get($name, $getShared, $conn); + } +} + +if (! function_exists('old')) +{ + /** + * Provides access to "old input" that was set in the session + * during a redirect()->withInput(). + * + * @param string $key + * @param null $default + * @param string|boolean $escape + * + * @return mixed|null + */ + function old(string $key, $default = null, $escape = 'html') + { + // Ensure the session is loaded + if (session_status() === PHP_SESSION_NONE && ENVIRONMENT !== 'testing') + { + // @codeCoverageIgnoreStart + session(); + // @codeCoverageIgnoreEnd + } + + $request = Services::request(); + + $value = $request->getOldInput($key); + + // Return the default value if nothing + // found in the old input. + if (is_null($value)) + { + return $default; + } + + // If the result was serialized array or string, then unserialize it for use... + if (is_string($value)) + { + if (strpos($value, 'a:') === 0 || strpos($value, 's:') === 0) + { + $value = unserialize($value); + } + } + + return $escape === false ? $value : esc($value, $escape); + } +} + +if (! function_exists('redirect')) +{ + /** + * Convenience method that works with the current global $request and + * $router instances to redirect using named/reverse-routed routes + * to determine the URL to go to. If nothing is found, will treat + * as a traditional redirect and pass the string in, letting + * $response->redirect() determine the correct method and code. + * + * If more control is needed, you must use $response->redirect explicitly. + * + * @param string $uri + * + * @return \CodeIgniter\HTTP\RedirectResponse + */ + function redirect(string $uri = null): RedirectResponse + { + $response = Services::redirectResponse(null, true); + + if (! empty($uri)) + { + return $response->route($uri); + } + + return $response; + } +} + +if (! function_exists('remove_invisible_characters')) +{ + /** + * Remove Invisible Characters + * + * This prevents sandwiching null characters + * between ascii characters, like Java\0script. + * + * @param string $str + * @param boolean $urlEncoded + * + * @return string + */ + function remove_invisible_characters(string $str, bool $urlEncoded = true): string + { + $nonDisplayables = []; + + // every control character except newline (dec 10), + // carriage return (dec 13) and horizontal tab (dec 09) + if ($urlEncoded) + { + $nonDisplayables[] = '/%0[0-8bcef]/'; // url encoded 00-08, 11, 12, 14, 15 + $nonDisplayables[] = '/%1[0-9a-f]/'; // url encoded 16-31 + } + + $nonDisplayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S'; // 00-08, 11, 12, 14-31, 127 + + do + { + $str = preg_replace($nonDisplayables, '', $str, -1, $count); + } + while ($count); + + return $str; + } +} + +if (! function_exists('route_to')) +{ + /** + * Given a controller/method string and any params, + * will attempt to build the relative URL to the + * matching route. + * + * NOTE: This requires the controller/method to + * have a route defined in the routes Config file. + * + * @param string $method + * @param array ...$params + * + * @return false|string + */ + function route_to(string $method, ...$params) + { + return Services::routes()->reverseRoute($method, ...$params); + } +} + +if (! function_exists('session')) +{ + /** + * A convenience method for accessing the session instance, + * or an item that has been set in the session. + * + * Examples: + * session()->set('foo', 'bar'); + * $foo = session('bar'); + * + * @param string $val + * + * @return \CodeIgniter\Session\Session|mixed|null + */ + function session(string $val = null) + { + $session = Services::session(); + + // Returning a single item? + if (is_string($val)) + { + return $session->get($val); + } + + return $session; + } +} + +if (! function_exists('service')) +{ + /** + * Allows cleaner access to the Services Config file. + * Always returns a SHARED instance of the class, so + * calling the function multiple times should always + * return the same instance. + * + * These are equal: + * - $timer = service('timer') + * - $timer = \CodeIgniter\Config\Services::timer(); + * + * @param string $name + * @param array ...$params + * + * @return mixed + */ + function service(string $name, ...$params) + { + return Services::$name(...$params); + } +} + +if (! function_exists('single_service')) +{ + /** + * Allow cleaner access to a Service. + * Always returns a new instance of the class. + * + * @param string $name + * @param array|null $params + * + * @return mixed + */ + function single_service(string $name, ...$params) + { + // Ensure it's NOT a shared instance + array_push($params, false); + + return Services::$name(...$params); + } +} + +if (! function_exists('slash_item')) +{ + //Unlike CI3, this function is placed here because + //it's not a config, or part of a config. + /** + * Fetch a config file item with slash appended (if not empty) + * + * @param string $item Config item name + * + * @return string|null The configuration item or NULL if + * the item doesn't exist + */ + function slash_item(string $item): ?string + { + $config = config(App::class); + $configItem = $config->{$item}; + + if (! isset($configItem) || empty(trim($configItem))) + { + return $configItem; + } + + return rtrim($configItem, '/') . '/'; + } +} + +if (! function_exists('stringify_attributes')) +{ + /** + * Stringify attributes for use in HTML tags. + * + * Helper function used to convert a string, array, or object + * of attributes to a string. + * + * @param mixed $attributes string, array, object + * @param boolean $js + * + * @return string + */ + function stringify_attributes($attributes, bool $js = false): string + { + $atts = ''; + + if (empty($attributes)) + { + return $atts; + } + + if (is_string($attributes)) + { + return ' ' . $attributes; + } + + $attributes = (array) $attributes; + + foreach ($attributes as $key => $val) + { + $atts .= ($js) ? $key . '=' . esc($val, 'js') . ',' : ' ' . $key . '="' . esc($val, 'attr') . '"'; + } + + return rtrim($atts, ','); + } +} + +if (! function_exists('timer')) +{ + /** + * A convenience method for working with the timer. + * If no parameter is passed, it will return the timer instance, + * otherwise will start or stop the timer intelligently. + * + * @param string|null $name + * + * @return \CodeIgniter\Debug\Timer|mixed + */ + function timer(string $name = null) + { + $timer = Services::timer(); + + if (empty($name)) + { + return $timer; + } + + if ($timer->has($name)) + { + return $timer->stop($name); + } + + return $timer->start($name); + } +} + +if (! function_exists('trace')) +{ + /** + * Provides a backtrace to the current execution point, from Kint. + */ + function trace() + { + Kint::$aliases[] = 'trace'; + Kint::trace(); + } +} + +if (! function_exists('view')) +{ + /** + * Grabs the current RendererInterface-compatible class + * and tells it to render the specified view. Simply provides + * a convenience method that can be used in Controllers, + * libraries, and routed closures. + * + * NOTE: Does not provide any escaping of the data, so that must + * all be handled manually by the developer. + * + * @param string $name + * @param array $data + * @param array $options Unused - reserved for third-party extensions. + * + * @return string + */ + function view(string $name, array $data = [], array $options = []): string + { + /** + * @var CodeIgniter\View\View $renderer + */ + $renderer = Services::renderer(); + + $saveData = config(View::class)->saveData; + + if (array_key_exists('saveData', $options)) + { + $saveData = (bool) $options['saveData']; + unset($options['saveData']); + } + + return $renderer->setData($data, 'raw') + ->render($name, $options, $saveData); + } +} + +if (! function_exists('view_cell')) +{ + /** + * View cells are used within views to insert HTML chunks that are managed + * by other classes. + * + * @param string $library + * @param null $params + * @param integer $ttl + * @param string|null $cacheName + * + * @return string + * @throws \ReflectionException + */ + function view_cell(string $library, $params = null, int $ttl = 0, string $cacheName = null): string + { + return Services::viewcell() + ->render($library, $params, $ttl, $cacheName); + } +} diff --git a/vendor/codeigniter4/framework/system/ComposerScripts.php b/vendor/codeigniter4/framework/system/ComposerScripts.php new file mode 100644 index 0000000..6ebb122 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ComposerScripts.php @@ -0,0 +1,248 @@ +getFileName(); + } + + //-------------------------------------------------------------------- + + /** + * A recursive remove directory method. + * + * @param $dir + */ + protected static function removeDir($dir) + { + if (is_dir($dir)) + { + $objects = scandir($dir); + foreach ($objects as $object) + { + if ($object !== '.' && $object !== '..') + { + if (filetype($dir . '/' . $object) === 'dir') + { + static::removeDir($dir . '/' . $object); + } + else + { + unlink($dir . '/' . $object); + } + } + } + reset($objects); + rmdir($dir); + } + } + + protected static function copyDir($source, $dest) + { + $dir = opendir($source); + @mkdir($dest); + + while (false !== ( $file = readdir($dir))) + { + if (( $file !== '.' ) && ( $file !== '..' )) + { + if (is_dir($source . '/' . $file)) + { + static::copyDir($source . '/' . $file, $dest . '/' . $file); + } + else + { + copy($source . '/' . $file, $dest . '/' . $file); + } + } + } + + closedir($dir); + } + + /** + * Moves the Laminas Escaper files into our base repo so that it's + * available for packaged releases where the users don't user Composer. + * + * @throws \ReflectionException + */ + public static function moveEscaper() + { + if (class_exists('\\Laminas\\Escaper\\Escaper') && is_file(static::getClassFilePath('\\Laminas\\Escaper\\Escaper'))) + { + $base = basename(__DIR__) . '/' . static::$basePath . 'Escaper'; + + foreach ([$base, $base . '/Exception'] as $path) + { + if (! is_dir($path)) + { + mkdir($path, 0755); + } + } + + $files = [ + static::getClassFilePath('\\Laminas\\Escaper\\Exception\\ExceptionInterface') => $base . '/Exception/ExceptionInterface.php', + static::getClassFilePath('\\Laminas\\Escaper\\Exception\\InvalidArgumentException') => $base . '/Exception/InvalidArgumentException.php', + static::getClassFilePath('\\Laminas\\Escaper\\Exception\\RuntimeException') => $base . '/Exception/RuntimeException.php', + static::getClassFilePath('\\Laminas\\Escaper\\Escaper') => $base . '/Escaper.php', + ]; + + foreach ($files as $source => $dest) + { + if (! static::moveFile($source, $dest)) + { + // @codeCoverageIgnoreStart + die('Error moving: ' . $source); + // @codeCoverageIgnoreEnd + } + } + } + } + + //-------------------------------------------------------------------- + + /** + * Moves the Kint file into our base repo so that it's + * available for packaged releases where the users don't user Composer. + */ + public static function moveKint() + { + $dir = 'vendor/kint-php/kint/src'; + + if (is_dir($dir)) + { + $base = basename(__DIR__) . '/' . static::$basePath . 'Kint'; + + // Remove the contents of the previous Kint folder, if any. + if (is_dir($base)) + { + static::removeDir($base); + } + + // Create Kint if it doesn't exist already + if (! is_dir($base)) + { + mkdir($base, 0755); + } + + static::copyDir($dir, $base); + static::copyDir($dir . '/../resources', $base . '/resources'); + copy($dir . '/../init.php', $base . '/init.php'); + copy($dir . '/../init_helpers.php', $base . '/init_helpers.php'); + } + } +} diff --git a/vendor/codeigniter4/framework/system/Config/AutoloadConfig.php b/vendor/codeigniter4/framework/system/Config/AutoloadConfig.php new file mode 100644 index 0000000..349fcb0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/AutoloadConfig.php @@ -0,0 +1,113 @@ + SYSTEMPATH, + 'App' => APPPATH // To ensure filters, etc still found, + ]; + + /** + * ------------------------------------------------------------------- + * Class Map + * ------------------------------------------------------------------- + * The class map provides a map of class names and their exact + * location on the drive. Classes loaded in this manner will have + * slightly faster performance because they will not have to be + * searched for within one or more directories as they would if they + * were being autoloaded through a namespace. + * + * @var array + */ + protected $coreClassmap = [ + 'Psr\Log\AbstractLogger' => SYSTEMPATH . 'ThirdParty/PSR/Log/AbstractLogger.php', + 'Psr\Log\InvalidArgumentException' => SYSTEMPATH . 'ThirdParty/PSR/Log/InvalidArgumentException.php', + 'Psr\Log\LoggerAwareInterface' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareInterface.php', + 'Psr\Log\LoggerAwareTrait' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerAwareTrait.php', + 'Psr\Log\LoggerInterface' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerInterface.php', + 'Psr\Log\LoggerTrait' => SYSTEMPATH . 'ThirdParty/PSR/Log/LoggerTrait.php', + 'Psr\Log\LogLevel' => SYSTEMPATH . 'ThirdParty/PSR/Log/LogLevel.php', + 'Psr\Log\NullLogger' => SYSTEMPATH . 'ThirdParty/PSR/Log/NullLogger.php', + 'Laminas\Escaper\Escaper' => SYSTEMPATH . 'ThirdParty/Escaper/Escaper.php' + ]; + + //-------------------------------------------------------------------- + + /** + * Constructor. + * + * Merge the built-in and developer-configured psr4 and classmap, + * with preference to the developer ones. + */ + public function __construct() + { + if (isset($_SERVER['CI_ENVIRONMENT']) && $_SERVER['CI_ENVIRONMENT'] === 'testing') + { + $this->psr4['Tests\Support'] = SUPPORTPATH; + $this->classmap['CodeIgniter\Log\TestLogger'] = SYSTEMPATH . 'Test/TestLogger.php'; + $this->classmap['CIDatabaseTestCase'] = SYSTEMPATH . 'Test/CIDatabaseTestCase.php'; + } + + $this->psr4 = array_merge($this->corePsr4, $this->psr4); + $this->classmap = array_merge($this->coreClassmap, $this->classmap); + } +} diff --git a/vendor/codeigniter4/framework/system/Config/BaseConfig.php b/vendor/codeigniter4/framework/system/Config/BaseConfig.php new file mode 100644 index 0000000..256f376 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/BaseConfig.php @@ -0,0 +1,247 @@ +initEnvValue($this->$property, $property, $prefix, $shortPrefix); + + // Handle hex2bin prefix + if ($shortPrefix === 'encryption' && $property === 'key' && strpos($this->$property, 'hex2bin:') === 0) + { + $this->$property = hex2bin(substr($this->$property, 8)); + } + } + + if (defined('ENVIRONMENT') && ENVIRONMENT !== 'testing') + { + // well, this won't happen during unit testing + // @codeCoverageIgnoreStart + $this->registerProperties(); + // @codeCoverageIgnoreEnd + } + } + + //-------------------------------------------------------------------- + + /** + * Initialization an environment-specific configuration setting + * + * @param mixed &$property + * @param string $name + * @param string $prefix + * @param string $shortPrefix + * + * @return mixed + */ + protected function initEnvValue(&$property, string $name, string $prefix, string $shortPrefix) + { + if (is_array($property)) + { + foreach ($property as $key => $val) + { + $this->initEnvValue($property[$key], "{$name}.{$key}", $prefix, $shortPrefix); + } + } + else + { + if (($value = $this->getEnvValue($name, $prefix, $shortPrefix)) !== false) + { + if (! is_null($value)) + { + if ($value === 'false') + { + $value = false; + } + elseif ($value === 'true') + { + $value = true; + } + + $property = is_bool($value) ? $value : trim($value, '\'"'); + } + } + } + return $property; + } + + //-------------------------------------------------------------------- + + /** + * Retrieve an environment-specific configuration setting + * + * @param string $property + * @param string $prefix + * @param string $shortPrefix + * + * @return mixed + */ + protected function getEnvValue(string $property, string $prefix, string $shortPrefix) + { + $shortPrefix = ltrim($shortPrefix, '\\'); + switch (true) + { + case array_key_exists("{$shortPrefix}.{$property}", $_ENV): + return $_ENV["{$shortPrefix}.{$property}"]; + case array_key_exists("{$shortPrefix}.{$property}", $_SERVER): + return $_SERVER["{$shortPrefix}.{$property}"]; + case array_key_exists("{$prefix}.{$property}", $_ENV): + return $_ENV["{$prefix}.{$property}"]; + case array_key_exists("{$prefix}.{$property}", $_SERVER): + return $_SERVER["{$prefix}.{$property}"]; + default: + $value = getenv($property); + return $value === false ? null : $value; + } + } + + //-------------------------------------------------------------------- + + /** + * Provides external libraries a simple way to register one or more + * options into a config file. + * + * @throws \ReflectionException + */ + protected function registerProperties() + { + if (! static::$moduleConfig->shouldDiscover('registrars')) + { + return; + } + + if (! static::$didDiscovery) + { + $locator = \Config\Services::locator(); + $registrarsFiles = $locator->search('Config/Registrar.php'); + + foreach ($registrarsFiles as $file) + { + $className = $locator->getClassname($file); + static::$registrars[] = new $className(); + } + + static::$didDiscovery = true; + } + + $shortName = (new \ReflectionClass($this))->getShortName(); + + // Check the registrar class for a method named after this class' shortName + foreach (static::$registrars as $callable) + { + // ignore non-applicable registrars + if (! method_exists($callable, $shortName)) + { + continue; + } + + $properties = $callable::$shortName(); + + if (! is_array($properties)) + { + throw new \RuntimeException('Registrars must return an array of properties and their values.'); + } + + foreach ($properties as $property => $value) + { + if (isset($this->$property) && is_array($this->$property) && is_array($value)) + { + $this->$property = array_merge($this->$property, $value); + } + else + { + $this->$property = $value; + } + } + } + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Config/BaseService.php b/vendor/codeigniter4/framework/system/Config/BaseService.php new file mode 100644 index 0000000..65aceb1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/BaseService.php @@ -0,0 +1,300 @@ +initialize(new Autoload(), new Modules()); + } + } + + //-------------------------------------------------------------------- + + /** + * Inject mock object for testing. + * + * @param string $name + * @param $mock + */ + public static function injectMock(string $name, $mock) + { + $name = strtolower($name); + static::$mocks[$name] = $mock; + } + + //-------------------------------------------------------------------- + + /** + * Will scan all psr4 namespaces registered with system to look + * for new Config\Services files. Caches a copy of each one, then + * looks for the service method in each, returning an instance of + * the service, if available. + * + * @param string $name + * @param array $arguments + * + * @return mixed + */ + protected static function discoverServices(string $name, array $arguments) + { + if (! static::$discovered) + { + $config = config('Modules'); + + if ($config->shouldDiscover('services')) + { + $locator = static::locator(); + $files = $locator->search('Config/Services'); + + if (empty($files)) + { + // no files at all found - this would be really, really bad + return null; + } + + // Get instances of all service classes and cache them locally. + foreach ($files as $file) + { + $classname = $locator->getClassname($file); + + if (! in_array($classname, ['CodeIgniter\\Config\\Services'])) + { + static::$services[] = new $classname(); + } + } + } + + static::$discovered = true; + } + + if (! static::$services) + { + // we found stuff, but no services - this would be really bad + return null; + } + + // Try to find the desired service method + foreach (static::$services as $class) + { + if (method_exists(get_class($class), $name)) + { + return $class::$name(...$arguments); + } + } + + return null; + } +} diff --git a/vendor/codeigniter4/framework/system/Config/Config.php b/vendor/codeigniter4/framework/system/Config/Config.php new file mode 100644 index 0000000..1e425d3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/Config.php @@ -0,0 +1,161 @@ +locateFile($name, 'Config'); + + if (empty($file)) + { + // No file found - check if the class was namespaced + if (strpos($name, '\\') !== false) + { + // Class was namespaced and locateFile couldn't find it + return null; + } + + // Check all namespaces + $files = $locator->search('Config/' . $name); + if (empty($files)) + { + return null; + } + + // Get the first match (prioritizes user and framework) + $file = reset($files); + } + + $name = $locator->getClassname($file); + + if (empty($name)) + { + return null; + } + + return new $name(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Config/DotEnv.php b/vendor/codeigniter4/framework/system/Config/DotEnv.php new file mode 100644 index 0000000..2b7d912 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/DotEnv.php @@ -0,0 +1,325 @@ +path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $file; + } + + //-------------------------------------------------------------------- + + /** + * The main entry point, will load the .env file and process it + * so that we end up with all settings in the PHP environment vars + * (i.e. getenv(), $_ENV, and $_SERVER) + * + * @return boolean + */ + public function load(): bool + { + $vars = $this->parse(); + + return ($vars === null ? false : true); + } + + //-------------------------------------------------------------------- + + /** + * Parse the .env file into an array of key => value + * + * @return array|null + */ + public function parse(): ?array + { + // We don't want to enforce the presence of a .env file, they should be optional. + if (! is_file($this->path)) + { + return null; + } + + // Ensure the file is readable + if (! is_readable($this->path)) + { + throw new \InvalidArgumentException("The .env file is not readable: {$this->path}"); + } + + $vars = []; + + $lines = file($this->path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); + + foreach ($lines as $line) + { + // Is it a comment? + if (strpos(trim($line), '#') === 0) + { + continue; + } + + // If there is an equal sign, then we know we are assigning a variable. + if (strpos($line, '=') !== false) + { + list($name, $value) = $this->normaliseVariable($line); + $vars[$name] = $value; + $this->setVariable($name, $value); + } + } + + return $vars; + } + + //-------------------------------------------------------------------- + + /** + * Sets the variable into the environment. Will parse the string + * first to look for {name}={value} pattern, ensure that nested + * variables are handled, and strip it of single and double quotes. + * + * @param string $name + * @param string $value + */ + protected function setVariable(string $name, string $value = '') + { + if (! getenv($name, true)) + { + putenv("$name=$value"); + } + if (empty($_ENV[$name])) + { + $_ENV[$name] = $value; + } + if (empty($_SERVER[$name])) + { + $_SERVER[$name] = $value; + } + } + + //-------------------------------------------------------------------- + + /** + * Parses for assignment, cleans the $name and $value, and ensures + * that nested variables are handled. + * + * @param string $name + * @param string $value + * + * @return array + */ + public function normaliseVariable(string $name, string $value = ''): array + { + // Split our compound string into it's parts. + if (strpos($name, '=') !== false) + { + list($name, $value) = explode('=', $name, 2); + } + + $name = trim($name); + $value = trim($value); + + // Sanitize the name + $name = str_replace(['export', '\'', '"'], '', $name); + + // Sanitize the value + $value = $this->sanitizeValue($value); + + $value = $this->resolveNestedVariables($value); + + // Handle hex2bin prefix + if ($name === 'encryption.key' && strpos($value, 'hex2bin:') === 0) + { + $value = hex2bin(substr($value, 8)); + } + + return [ + $name, + $value, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Strips quotes from the environment variable value. + * + * This was borrowed from the excellent phpdotenv with very few changes. + * https://github.com/vlucas/phpdotenv + * + * @param string $value + * + * @return string + * @throws \InvalidArgumentException + */ + protected function sanitizeValue(string $value): string + { + if (! $value) + { + return $value; + } + + // Does it begin with a quote? + if (strpbrk($value[0], '"\'') !== false) + { + // value starts with a quote + $quote = $value[0]; + $regexPattern = sprintf( + '/^ + %1$s # match a quote at the start of the value + ( # capturing sub-pattern used + (?: # we do not need to capture this + [^%1$s\\\\] # any character other than a quote or backslash + |\\\\\\\\ # or two backslashes together + |\\\\%1$s # or an escaped quote e.g \" + )* # as many characters that match the previous rules + ) # end of the capturing sub-pattern + %1$s # and the closing quote + .*$ # and discard any string after the closing quote + /mx', $quote + ); + $value = preg_replace($regexPattern, '$1', $value); + $value = str_replace("\\$quote", $quote, $value); + $value = str_replace('\\\\', '\\', $value); + } + else + { + $parts = explode(' #', $value, 2); + + $value = trim($parts[0]); + + // Unquoted values cannot contain whitespace + if (preg_match('/\s+/', $value) > 0) + { + throw new \InvalidArgumentException('.env values containing spaces must be surrounded by quotes.'); + } + } + + return $value; + } + + //-------------------------------------------------------------------- + + /** + * Resolve the nested variables. + * + * Look for ${varname} patterns in the variable value and replace with an existing + * environment variable. + * + * This was borrowed from the excellent phpdotenv with very few changes. + * https://github.com/vlucas/phpdotenv + * + * @param $value + * + * @return string + */ + protected function resolveNestedVariables(string $value): string + { + if (strpos($value, '$') !== false) + { + $loader = $this; + + $value = preg_replace_callback( + '/\${([a-zA-Z0-9_]+)}/', + function ($matchedPatterns) use ($loader) { + $nestedVariable = $loader->getVariable($matchedPatterns[1]); + + if (is_null($nestedVariable)) + { + return $matchedPatterns[0]; + } + + return $nestedVariable; + }, + $value + ); + } + + return $value; + } + + //-------------------------------------------------------------------- + + /** + * Search the different places for environment variables and return first value found. + * + * This was borrowed from the excellent phpdotenv with very few changes. + * https://github.com/vlucas/phpdotenv + * + * @param string $name + * + * @return string|null + */ + protected function getVariable(string $name) + { + switch (true) + { + case array_key_exists($name, $_ENV): + return $_ENV[$name]; + case array_key_exists($name, $_SERVER): + return $_SERVER[$name]; + default: + $value = getenv($name); + + // switch getenv default to null + return $value === false ? null : $value; + } + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Config/ForeignCharacters.php b/vendor/codeigniter4/framework/system/Config/ForeignCharacters.php new file mode 100644 index 0000000..11d0f6c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/ForeignCharacters.php @@ -0,0 +1,143 @@ + 'ae', + '/ö|Å“/' => 'oe', + '/ü/' => 'ue', + '/Ä/' => 'Ae', + '/Ü/' => 'Ue', + '/Ö/' => 'Oe', + '/À|Ã|Â|Ã|Ä|Ã…|Ǻ|Ä€|Ä‚|Ä„|Ç|Α|Ά|Ả|Ạ|Ầ|Ẫ|Ẩ|Ậ|Ằ|Ắ|Ẵ|Ẳ|Ặ|Ð/' => 'A', + '/à|á|â|ã|Ã¥|Ç»|Ä|ă|Ä…|ÇŽ|ª|α|ά|ả|ạ|ầ|ấ|ẫ|ẩ|ậ|ằ|ắ|ẵ|ẳ|ặ|а/' => 'a', + '/Б/' => 'B', + '/б/' => 'b', + '/Ç|Ć|Ĉ|ÄŠ|ÄŒ/' => 'C', + '/ç|ć|ĉ|Ä‹|Ä/' => 'c', + '/Д/' => 'D', + '/д/' => 'd', + '/Ã|ÄŽ|Ä|Δ/' => 'Dj', + '/ð|Ä|Ä‘|δ/' => 'dj', + '/È|É|Ê|Ë|Ä’|Ä”|Ä–|Ę|Äš|Ε|Έ|Ẽ|Ẻ|Ẹ|Ề|Ế|Ễ|Ể|Ệ|Е|Э/' => 'E', + '/è|é|ê|ë|Ä“|Ä•|Ä—|Ä™|Ä›|έ|ε|ẽ|ẻ|ẹ|á»|ế|á»…|ể|ệ|е|Ñ/' => 'e', + '/Ф/' => 'F', + '/Ñ„/' => 'f', + '/Äœ|Äž|Ä |Ä¢|Γ|Г|Ò/' => 'G', + '/Ä|ÄŸ|Ä¡|Ä£|γ|г|Ò‘/' => 'g', + '/Ĥ|Ħ/' => 'H', + '/Ä¥|ħ/' => 'h', + '/ÃŒ|Ã|ÃŽ|Ã|Ĩ|Ī|Ĭ|Ç|Ä®|İ|Η|Ή|Ί|Ι|Ϊ|Ỉ|Ị|И|Ы/' => 'I', + '/ì|í|î|ï|Ä©|Ä«|Ä­|Ç|į|ı|η|ή|ί|ι|ÏŠ|ỉ|ị|и|Ñ‹|Ñ—/' => 'i', + '/Ä´/' => 'J', + '/ĵ/' => 'j', + '/Ķ|Κ|К/' => 'K', + '/Ä·|κ|к/' => 'k', + '/Ĺ|Ä»|Ľ|Ä¿|Å|Λ|Л/' => 'L', + '/ĺ|ļ|ľ|Å€|Å‚|λ|л/' => 'l', + '/М/' => 'M', + '/м/' => 'm', + '/Ñ|Ń|Å…|Ň|Î|Ð/' => 'N', + '/ñ|Å„|ņ|ň|ʼn|ν|н/' => 'n', + '/Ã’|Ó|Ô|Õ|ÅŒ|ÅŽ|Ç‘|Å|Æ |Ø|Ǿ|Ο|ÎŒ|Ω|Î|Ỏ|Ọ|á»’|á»|á»–|á»”|Ộ|Ờ|Ớ|á» |Ở|Ợ|О/' => 'O', + '/ò|ó|ô|õ|Å|Å|Ç’|Å‘|Æ¡|ø|Ç¿|º|ο|ÏŒ|ω|ÏŽ|á»|á»|ồ|ố|á»—|ổ|á»™|á»|á»›|ỡ|ở|ợ|о/' => 'o', + '/П/' => 'P', + '/п/' => 'p', + '/Å”|Å–|Ř|Ρ|Р/' => 'R', + '/Å•|Å—|Å™|Ï|Ñ€/' => 'r', + '/Åš|Åœ|Åž|Ș|Å |Σ|С/' => 'S', + '/Å›|Å|ÅŸ|È™|Å¡|Å¿|σ|Ï‚|Ñ/' => 's', + '/Èš|Å¢|Ť|Ŧ|Ï„|Т/' => 'T', + '/È›|Å£|Å¥|ŧ|Ñ‚/' => 't', + '/Ù|Ú|Û|Ũ|Ū|Ŭ|Å®|Ű|Ų|Ư|Ç“|Ç•|Ç—|Ç™|Ç›|Ũ|Ủ|Ụ|Ừ|Ứ|á»®|Ử|á»°|У/' => 'U', + '/ù|ú|û|Å©|Å«|Å­|ů|ű|ų|ư|Ç”|Ç–|ǘ|Çš|Çœ|Ï…|Ï|Ï‹|á»§|ụ|ừ|ứ|ữ|á»­|á»±|у/' => 'u', + '/Ƴ|ÉŽ|á»´|Ẏ|Ó²|Ó®|ÐŽ|Ã|Ÿ|Ŷ|Î¥|ÎŽ|Ϋ|Ỳ|Ỹ|á»¶|á»´|Й/' => 'Y', + '/ẙ|Ê|Æ´|É|ỵ|áº|Ó³|Ó¯|Ñž|ý|ÿ|Å·|ỳ|ỹ|á»·|ỵ|й/' => 'y', + '/Ð’/' => 'V', + '/в/' => 'v', + '/Å´/' => 'W', + '/ŵ/' => 'w', + '/Ź|Å»|Ž|Ζ|З/' => 'Z', + '/ź|ż|ž|ζ|з/' => 'z', + '/Æ|Ǽ/' => 'AE', + '/ß/' => 'ss', + '/IJ/' => 'IJ', + '/ij/' => 'ij', + '/Å’/' => 'OE', + '/Æ’/' => 'f', + '/ξ/' => 'ks', + '/Ï€/' => 'p', + '/β/' => 'v', + '/μ/' => 'm', + '/ψ/' => 'ps', + '/Ð/' => 'Yo', + '/Ñ‘/' => 'yo', + '/Є/' => 'Ye', + '/Ñ”/' => 'ye', + '/Ї/' => 'Yi', + '/Ж/' => 'Zh', + '/ж/' => 'zh', + '/Ð¥/' => 'Kh', + '/Ñ…/' => 'kh', + '/Ц/' => 'Ts', + '/ц/' => 'ts', + '/Ч/' => 'Ch', + '/ч/' => 'ch', + '/Ш/' => 'Sh', + '/ш/' => 'sh', + '/Щ/' => 'Shch', + '/щ/' => 'shch', + '/Ъ|ÑŠ|Ь|ÑŒ/' => '', + '/Ю/' => 'Yu', + '/ÑŽ/' => 'yu', + '/Я/' => 'Ya', + '/Ñ/' => 'ya', + ]; + +} diff --git a/vendor/codeigniter4/framework/system/Config/Routes.php b/vendor/codeigniter4/framework/system/Config/Routes.php new file mode 100644 index 0000000..c891ec3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/Routes.php @@ -0,0 +1,66 @@ +add('basecontroller(:any)', function () { + throw PageNotFoundException::forPageNotFound(); +}); + +// Migrations +$routes->cli('migrations/(:segment)/(:segment)', '\CodeIgniter\Commands\MigrationsCommand::$1/$2'); +$routes->cli('migrations/(:segment)', '\CodeIgniter\Commands\MigrationsCommand::$1'); +$routes->cli('migrations', '\CodeIgniter\Commands\MigrationsCommand::index'); + +// CLI Catchall - uses a _remap to call Commands +$routes->cli('ci(:any)', '\CodeIgniter\CLI\CommandRunner::index/$1'); + +// Prevent access to initController method +$routes->add('(:any)/initController', function () { + throw PageNotFoundException::forPageNotFound(); +}); diff --git a/vendor/codeigniter4/framework/system/Config/Services.php b/vendor/codeigniter4/framework/system/Config/Services.php new file mode 100644 index 0000000..b3c9854 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/Services.php @@ -0,0 +1,944 @@ +initialize($config); + } + + //-------------------------------------------------------------------- + + /** + * The Exceptions class holds the methods that handle: + * + * - set_exception_handler + * - set_error_handler + * - register_shutdown_function + * + * @param \Config\Exceptions $config + * @param \CodeIgniter\HTTP\IncomingRequest $request + * @param \CodeIgniter\HTTP\Response $response + * @param boolean $getShared + * + * @return \CodeIgniter\Debug\Exceptions + */ + public static function exceptions( + \Config\Exceptions $config = null, + IncomingRequest $request = null, + Response $response = null, + bool $getShared = true + ) + { + if ($getShared) + { + return static::getSharedInstance('exceptions', $config, $request, $response); + } + + if (empty($config)) + { + $config = new \Config\Exceptions(); + } + + if (empty($request)) + { + $request = static::request(); + } + + if (empty($response)) + { + $response = static::response(); + } + + return (new Exceptions($config, $request, $response)); + } + + //-------------------------------------------------------------------- + + /** + * Filters allow you to run tasks before and/or after a controller + * is executed. During before filters, the request can be modified, + * and actions taken based on the request, while after filters can + * act on or modify the response itself before it is sent to the client. + * + * @param mixed $config + * @param boolean $getShared + * + * @return \CodeIgniter\Filters\Filters + */ + public static function filters($config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('filters', $config); + } + + if (empty($config)) + { + $config = new \Config\Filters(); + } + + return new Filters($config, static::request(), static::response()); + } + + //-------------------------------------------------------------------- + + /** + * The Honeypot provides a secret input on forms that bots should NOT + * fill in, providing an additional safeguard when accepting user input. + * + * @param \CodeIgniter\Config\BaseConfig|null $config + * @param boolean $getShared + * + * @return \CodeIgniter\Honeypot\Honeypot|mixed + */ + public static function honeypot(BaseConfig $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('honeypot', $config); + } + + if (is_null($config)) + { + $config = new \Config\Honeypot(); + } + + return new Honeypot($config); + } + + //-------------------------------------------------------------------- + + /** + * Acts as a factory for ImageHandler classes and returns an instance + * of the handler. Used like Services::image()->withFile($path)->rotate(90)->save(); + * + * @param string|null $handler + * @param \Config\Images|null $config + * @param boolean $getShared + * + * @return \CodeIgniter\Images\Handlers\BaseHandler + */ + public static function image(string $handler = null, $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('image', $handler, $config); + } + + if (empty($config)) + { + $config = new Images(); + } + + $handler = is_null($handler) ? $config->defaultHandler : $handler; + + $class = $config->handlers[$handler]; + + return new $class($config); + } + + //-------------------------------------------------------------------- + + /** + * The Iterator class provides a simple way of looping over a function + * and timing the results and memory usage. Used when debugging and + * optimizing applications. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Debug\Iterator + */ + public static function iterator(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('iterator'); + } + + return new Iterator(); + } + + //-------------------------------------------------------------------- + + /** + * Responsible for loading the language string translations. + * + * @param string $locale + * @param boolean $getShared + * + * @return \CodeIgniter\Language\Language + */ + public static function language(string $locale = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('language', $locale) + ->setLocale($locale); + } + + $locale = ! empty($locale) ? $locale : static::request() + ->getLocale(); + + return new Language($locale); + } + + //-------------------------------------------------------------------- + + /** + * The Logger class is a PSR-3 compatible Logging class that supports + * multiple handlers that process the actual logging. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Log\Logger + */ + public static function logger(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('logger'); + } + + return new \CodeIgniter\Log\Logger(new Logger()); + } + + //-------------------------------------------------------------------- + + /** + * Return the appropriate Migration runner. + * + * @param \CodeIgniter\Config\BaseConfig $config + * @param \CodeIgniter\Database\ConnectionInterface $db + * @param boolean $getShared + * + * @return \CodeIgniter\Database\MigrationRunner + */ + public static function migrations(BaseConfig $config = null, ConnectionInterface $db = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('migrations', $config, $db); + } + + $config = empty($config) ? new Migrations() : $config; + + return new MigrationRunner($config, $db); + } + + //-------------------------------------------------------------------- + + /** + * The Negotiate class provides the content negotiation features for + * working the request to determine correct language, encoding, charset, + * and more. + * + * @param \CodeIgniter\HTTP\RequestInterface $request + * @param boolean $getShared + * + * @return \CodeIgniter\HTTP\Negotiate + */ + public static function negotiator(RequestInterface $request = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('negotiator', $request); + } + + if (is_null($request)) + { + $request = static::request(); + } + + return new Negotiate($request); + } + + //-------------------------------------------------------------------- + + /** + * Return the appropriate pagination handler. + * + * @param mixed $config + * @param \CodeIgniter\View\RendererInterface $view + * @param boolean $getShared + * + * @return \CodeIgniter\Pager\Pager + */ + public static function pager($config = null, RendererInterface $view = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('pager', $config, $view); + } + + if (empty($config)) + { + $config = config('Pager'); + } + + if (! $view instanceof RendererInterface) + { + $view = static::renderer(); + } + + return new Pager($config, $view); + } + + //-------------------------------------------------------------------- + + /** + * The Parser is a simple template parser. + * + * @param string $viewPath + * @param mixed $config + * @param boolean $getShared + * + * @return \CodeIgniter\View\Parser + */ + public static function parser(string $viewPath = null, $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('parser', $viewPath, $config); + } + + if (is_null($config)) + { + $config = new \Config\View(); + } + + if (is_null($viewPath)) + { + $paths = config('Paths'); + $viewPath = $paths->viewDirectory; + } + + return new Parser($config, $viewPath, static::locator(), CI_DEBUG, static::logger()); + } + + //-------------------------------------------------------------------- + + /** + * The Renderer class is the class that actually displays a file to the user. + * The default View class within CodeIgniter is intentionally simple, but this + * service could easily be replaced by a template engine if the user needed to. + * + * @param string $viewPath + * @param mixed $config + * @param boolean $getShared + * + * @return \CodeIgniter\View\View + */ + public static function renderer(string $viewPath = null, $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('renderer', $viewPath, $config); + } + + if (is_null($config)) + { + $config = new \Config\View(); + } + + if (is_null($viewPath)) + { + $paths = config('Paths'); + + $viewPath = $paths->viewDirectory; + } + + return new \CodeIgniter\View\View($config, $viewPath, static::locator(), CI_DEBUG, static::logger()); + } + + //-------------------------------------------------------------------- + + /** + * The Request class models an HTTP request. + * + * @param \Config\App $config + * @param boolean $getShared + * + * @return \CodeIgniter\HTTP\IncomingRequest + */ + public static function request(App $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('request', $config); + } + + if (! is_object($config)) + { + $config = config(App::class); + } + + return new IncomingRequest( + $config, + static::uri(), + 'php://input', + new UserAgent() + ); + } + + //-------------------------------------------------------------------- + + /** + * The Response class models an HTTP response. + * + * @param \Config\App $config + * @param boolean $getShared + * + * @return \CodeIgniter\HTTP\Response + */ + public static function response(App $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('response', $config); + } + + if (! is_object($config)) + { + $config = config(App::class); + } + + return new Response($config); + } + + //-------------------------------------------------------------------- + + /** + * The Redirect class provides nice way of working with redirects. + * + * @param \Config\App $config + * @param boolean $getShared + * + * @return \CodeIgniter\HTTP\Response + */ + public static function redirectResponse(App $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('redirectResponse', $config); + } + + if (! is_object($config)) + { + $config = config(App::class); + } + + $response = new RedirectResponse($config); + $response->setProtocolVersion(static::request() + ->getProtocolVersion()); + + return $response; + } + + //-------------------------------------------------------------------- + + /** + * The Routes service is a class that allows for easily building + * a collection of routes. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Router\RouteCollection + */ + public static function routes(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('routes'); + } + + return new RouteCollection(static::locator(), config('Modules')); + } + + //-------------------------------------------------------------------- + + /** + * The Router class uses a RouteCollection's array of routes, and determines + * the correct Controller and Method to execute. + * + * @param \CodeIgniter\Router\RouteCollectionInterface $routes + * @param \CodeIgniter\HTTP\Request $request + * @param boolean $getShared + * + * @return \CodeIgniter\Router\Router + */ + public static function router(RouteCollectionInterface $routes = null, Request $request = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('router', $routes, $request); + } + + if (empty($routes)) + { + $routes = static::routes(); + } + + return new Router($routes, $request); + } + + //-------------------------------------------------------------------- + + /** + * The Security class provides a few handy tools for keeping the site + * secure, most notably the CSRF protection tools. + * + * @param \Config\App $config + * @param boolean $getShared + * + * @return \CodeIgniter\Security\Security + */ + public static function security(App $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('security', $config); + } + + if (! is_object($config)) + { + $config = config(App::class); + } + + return new Security($config); + } + + //-------------------------------------------------------------------- + + /** + * Return the session manager. + * + * @param \Config\App $config + * @param boolean $getShared + * + * @return \CodeIgniter\Session\Session + */ + public static function session(App $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('session', $config); + } + + if (! is_object($config)) + { + $config = config(App::class); + } + + $logger = static::logger(); + + $driverName = $config->sessionDriver; + $driver = new $driverName($config, static::request()->getIPAddress()); + $driver->setLogger($logger); + + $session = new Session($driver, $config); + $session->setLogger($logger); + + if (session_status() === PHP_SESSION_NONE) + { + $session->start(); + } + + return $session; + } + + //-------------------------------------------------------------------- + + /** + * The Throttler class provides a simple method for implementing + * rate limiting in your applications. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Throttle\Throttler + */ + public static function throttler(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('throttler'); + } + + return new Throttler(static::cache()); + } + + //-------------------------------------------------------------------- + + /** + * The Timer class provides a simple way to Benchmark portions of your + * application. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Debug\Timer + */ + public static function timer(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('timer'); + } + + return new Timer(); + } + + //-------------------------------------------------------------------- + + /** + * Return the debug toolbar. + * + * @param \Config\Toolbar $config + * @param boolean $getShared + * + * @return \CodeIgniter\Debug\Toolbar + */ + public static function toolbar(\Config\Toolbar $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('toolbar', $config); + } + + if (! is_object($config)) + { + $config = config('Toolbar'); + } + + return new Toolbar($config); + } + + //-------------------------------------------------------------------- + + /** + * The URI class provides a way to model and manipulate URIs. + * + * @param string $uri + * @param boolean $getShared + * + * @return \CodeIgniter\HTTP\URI + */ + public static function uri(string $uri = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('uri', $uri); + } + + return new URI($uri); + } + + //-------------------------------------------------------------------- + + /** + * The Validation class provides tools for validating input data. + * + * @param \Config\Validation $config + * @param boolean $getShared + * + * @return \CodeIgniter\Validation\Validation + */ + public static function validation(\Config\Validation $config = null, bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('validation', $config); + } + + if (is_null($config)) + { + $config = config('Validation'); + } + + return new Validation($config, static::renderer()); + } + + //-------------------------------------------------------------------- + + /** + * View cells are intended to let you insert HTML into view + * that has been generated by any callable in the system. + * + * @param boolean $getShared + * + * @return \CodeIgniter\View\Cell + */ + public static function viewcell(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('viewcell'); + } + + return new Cell(static::cache()); + } + + //-------------------------------------------------------------------- + + /** + * The Typography class provides a way to format text in semantically relevant ways. + * + * @param boolean $getShared + * + * @return \CodeIgniter\Typography\Typography + */ + public static function typography(bool $getShared = true) + { + if ($getShared) + { + return static::getSharedInstance('typography'); + } + + return new Typography(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Config/View.php b/vendor/codeigniter4/framework/system/Config/View.php new file mode 100644 index 0000000..e9cafa6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Config/View.php @@ -0,0 +1,107 @@ + '\abs', + 'capitalize' => '\CodeIgniter\View\Filters::capitalize', + 'date' => '\CodeIgniter\View\Filters::date', + 'date_modify' => '\CodeIgniter\View\Filters::date_modify', + 'default' => '\CodeIgniter\View\Filters::default', + 'esc' => '\CodeIgniter\View\Filters::esc', + 'excerpt' => '\CodeIgniter\View\Filters::excerpt', + 'highlight' => '\CodeIgniter\View\Filters::highlight', + 'highlight_code' => '\CodeIgniter\View\Filters::highlight_code', + 'limit_words' => '\CodeIgniter\View\Filters::limit_words', + 'limit_chars' => '\CodeIgniter\View\Filters::limit_chars', + 'local_currency' => '\CodeIgniter\View\Filters::local_currency', + 'local_number' => '\CodeIgniter\View\Filters::local_number', + 'lower' => '\strtolower', + 'nl2br' => '\CodeIgniter\View\Filters::nl2br', + 'number_format' => '\number_format', + 'prose' => '\CodeIgniter\View\Filters::prose', + 'round' => '\CodeIgniter\View\Filters::round', + 'strip_tags' => '\strip_tags', + 'title' => '\CodeIgniter\View\Filters::title', + 'upper' => '\strtoupper', + ]; + + /** + * Built-in View plugins. + * + * @var type + */ + protected $corePlugins = [ + 'current_url' => '\CodeIgniter\View\Plugins::currentURL', + 'previous_url' => '\CodeIgniter\View\Plugins::previousURL', + 'mailto' => '\CodeIgniter\View\Plugins::mailto', + 'safe_mailto' => '\CodeIgniter\View\Plugins::safeMailto', + 'lang' => '\CodeIgniter\View\Plugins::lang', + 'validation_errors' => '\CodeIgniter\View\Plugins::validationErrors', + 'route' => '\CodeIgniter\View\Plugins::route', + 'siteURL' => '\CodeIgniter\View\Plugins::siteURL', + ]; + + /** + * Constructor. + * + * Merge the built-in and developer-configured filters and plugins, + * with preference to the developer ones. + */ + public function __construct() + { + $this->filters = array_merge($this->coreFilters, $this->filters); + $this->plugins = array_merge($this->corePlugins, $this->plugins); + + parent::__construct(); + } + +} diff --git a/vendor/codeigniter4/framework/system/Controller.php b/vendor/codeigniter4/framework/system/Controller.php new file mode 100644 index 0000000..985d828 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Controller.php @@ -0,0 +1,223 @@ +request = $request; + $this->response = $response; + $this->logger = $logger; + + if ($this->forceHTTPS > 0) + { + $this->forceHTTPS($this->forceHTTPS); + } + + $this->loadHelpers(); + } + + //-------------------------------------------------------------------- + + /** + * A convenience method to use when you need to ensure that a single + * method is reached only via HTTPS. If it isn't, then a redirect + * will happen back to this method and HSTS header will be sent + * to have modern browsers transform requests automatically. + * + * @param integer $duration The number of seconds this link should be + * considered secure for. Only with HSTS header. + * Default value is 1 year. + * + * @throws \CodeIgniter\HTTP\Exceptions\HTTPException + */ + protected function forceHTTPS(int $duration = 31536000) + { + force_https($duration, $this->request, $this->response); + } + + //-------------------------------------------------------------------- + + /** + * Provides a simple way to tie into the main CodeIgniter class + * and tell it how long to cache the current page for. + * + * @param integer $time + */ + protected function cachePage(int $time) + { + CodeIgniter::cache($time); + } + + //-------------------------------------------------------------------- + + /** + * Handles "auto-loading" helper files. + */ + protected function loadHelpers() + { + if (empty($this->helpers)) + { + return; + } + + foreach ($this->helpers as $helper) + { + helper($helper); + } + } + + //-------------------------------------------------------------------- + + /** + * A shortcut to performing validation on input data. If validation + * is not successful, a $errors property will be set on this class. + * + * @param array|string $rules + * @param array $messages An array of custom error messages + * + * @return boolean + */ + protected function validate($rules, array $messages = []): bool + { + $this->validator = Services::validation(); + + // If you replace the $rules array with the name of the group + if (is_string($rules)) + { + $validation = config('Validation'); + + // If the rule wasn't found in the \Config\Validation, we + // should throw an exception so the developer can find it. + if (! isset($validation->$rules)) + { + throw ValidationException::forRuleNotFound($rules); + } + + // If no error message is defined, use the error message in the Config\Validation file + if (! $messages) + { + $errorName = $rules . '_errors'; + $messages = $validation->$errorName ?? []; + } + + $rules = $validation->$rules; + } + + return $this->validator + ->withRequest($this->request) + ->setRules($rules, $messages) + ->run(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/BaseBuilder.php b/vendor/codeigniter4/framework/system/Database/BaseBuilder.php new file mode 100644 index 0000000..9e2f3eb --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/BaseBuilder.php @@ -0,0 +1,3492 @@ +db = $db; + + $this->from($tableName); + + if (! empty($options)) + { + foreach ($options as $key => $value) + { + if (property_exists($this, $key)) + { + $this->$key = $value; + } + } + } + } + + //-------------------------------------------------------------------- + + /** + * Sets a test mode status. + * + * @param boolean $mode Mode to set + * + * @return BaseBuilder + */ + public function testMode(bool $mode = true) + { + $this->testMode = $mode; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of bind values and their + * named parameters for binding in the Query object later. + * + * @return array + */ + public function getBinds(): array + { + return $this->binds; + } + + //-------------------------------------------------------------------- + + /** + * Ignore + * + * Set ignore Flag for next insert, + * update or delete query. + * + * @param boolean $ignore + * + * @return BaseBuilder + */ + public function ignore(bool $ignore = true) + { + $this->QBIgnore = $ignore; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Select + * + * Generates the SELECT portion of the query + * + * @param string|array $select + * @param boolean $escape + * + * @return BaseBuilder + */ + public function select($select = '*', bool $escape = null) + { + if (is_string($select)) + { + $select = explode(',', $select); + } + + // If the escape value was not set, we will base it on the global setting + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + foreach ($select as $val) + { + $val = trim($val); + + if ($val !== '') + { + $this->QBSelect[] = $val; + + /* + * When doing 'SELECT NULL as field_alias FROM table' + * null gets taken as a field, and therefore escaped + * with backticks. + * This prevents NULL being escaped + * @see https://github.com/codeigniter4/CodeIgniter4/issues/1169 + */ + if (mb_stripos(trim($val), 'NULL') === 0) + { + $escape = false; + } + + $this->QBNoEscape[] = $escape; + } + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Select Max + * + * Generates a SELECT MAX(field) portion of a query + * + * @param string $select The field + * @param string $alias An alias + * + * @return BaseBuilder + */ + public function selectMax(string $select = '', string $alias = '') + { + return $this->maxMinAvgSum($select, $alias); + } + + //-------------------------------------------------------------------- + + /** + * Select Min + * + * Generates a SELECT MIN(field) portion of a query + * + * @param string $select The field + * @param string $alias An alias + * + * @return BaseBuilder + */ + public function selectMin(string $select = '', string $alias = '') + { + return $this->maxMinAvgSum($select, $alias, 'MIN'); + } + + //-------------------------------------------------------------------- + + /** + * Select Average + * + * Generates a SELECT AVG(field) portion of a query + * + * @param string $select The field + * @param string $alias An alias + * + * @return BaseBuilder + */ + public function selectAvg(string $select = '', string $alias = '') + { + return $this->maxMinAvgSum($select, $alias, 'AVG'); + } + + //-------------------------------------------------------------------- + + /** + * Select Sum + * + * Generates a SELECT SUM(field) portion of a query + * + * @param string $select The field + * @param string $alias An alias + * + * @return BaseBuilder + */ + public function selectSum(string $select = '', string $alias = '') + { + return $this->maxMinAvgSum($select, $alias, 'SUM'); + } + + //-------------------------------------------------------------------- + + /** + * Select Count + * + * Generates a SELECT COUNT(field) portion of a query + * + * @param string $select The field + * @param string $alias An alias + * + * @return BaseBuilder + */ + public function selectCount(string $select = '', string $alias = '') + { + return $this->maxMinAvgSum($select, $alias, 'COUNT'); + } + + //-------------------------------------------------------------------- + + /** + * SELECT [MAX|MIN|AVG|SUM|COUNT]() + * + * @used-by selectMax() + * @used-by selectMin() + * @used-by selectAvg() + * @used-by selectSum() + * + * @param string $select Field name + * @param string $alias + * @param string $type + * + * @return BaseBuilder + * @throws \CodeIgniter\Database\Exceptions\DataException + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + protected function maxMinAvgSum(string $select = '', string $alias = '', string $type = 'MAX') + { + if ($select === '') + { + throw DataException::forEmptyInputGiven('Select'); + } + + if (strpos($select, ',') !== false) + { + throw DataException::forInvalidArgument('column name not separated by comma'); + } + + $type = strtoupper($type); + + if (! in_array($type, ['MAX', 'MIN', 'AVG', 'SUM', 'COUNT'])) + { + throw new DatabaseException('Invalid function type: ' . $type); + } + + if ($alias === '') + { + $alias = $this->createAliasFromTable(trim($select)); + } + + $sql = $type . '(' . $this->db->protectIdentifiers(trim($select)) . ') AS ' . $this->db->escapeIdentifiers(trim($alias)); + + $this->QBSelect[] = $sql; + $this->QBNoEscape[] = null; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Determines the alias name based on the table + * + * @param string $item + * + * @return string + */ + protected function createAliasFromTable(string $item): string + { + if (strpos($item, '.') !== false) + { + $item = explode('.', $item); + + return end($item); + } + + return $item; + } + + //-------------------------------------------------------------------- + + /** + * DISTINCT + * + * Sets a flag which tells the query string compiler to add DISTINCT + * + * @param boolean $val + * + * @return BaseBuilder + */ + public function distinct(bool $val = true) + { + $this->QBDistinct = $val; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * From + * + * Generates the FROM portion of the query + * + * @param mixed $from can be a string or array + * @param boolean $overwrite Should we remove the first table existing? + * + * @return BaseBuilder + */ + public function from($from, bool $overwrite = false) + { + if ($overwrite === true) + { + $this->QBFrom = []; + $this->db->setAliasedTables([]); + } + + foreach ((array) $from as $val) + { + if (strpos($val, ',') !== false) + { + foreach (explode(',', $val) as $v) + { + $v = trim($v); + $this->trackAliases($v); + + $this->QBFrom[] = $v = $this->db->protectIdentifiers($v, true, null, false); + } + } + else + { + $val = trim($val); + + // Extract any aliases that might exist. We use this information + // in the protectIdentifiers to know whether to add a table prefix + $this->trackAliases($val); + + $this->QBFrom[] = $this->db->protectIdentifiers($val, true, null, false); + } + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * JOIN + * + * Generates the JOIN portion of the query + * + * @param string $table + * @param string $cond The join condition + * @param string $type The type of join + * @param boolean $escape Whether not to try to escape identifiers + * + * @return BaseBuilder + */ + public function join(string $table, string $cond, string $type = '', bool $escape = null) + { + if ($type !== '') + { + $type = strtoupper(trim($type)); + + if (! in_array($type, $this->joinTypes, true)) + { + $type = ''; + } + else + { + $type .= ' '; + } + } + + // Extract any aliases that might exist. We use this information + // in the protectIdentifiers to know whether to add a table prefix + $this->trackAliases($table); + + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + if (! $this->hasOperator($cond)) + { + $cond = ' USING (' . ($escape ? $this->db->escapeIdentifiers($cond) : $cond) . ')'; + } + elseif ($escape === false) + { + $cond = ' ON ' . $cond; + } + else + { + // Split multiple conditions + if (preg_match_all('/\sAND\s|\sOR\s/i', $cond, $joints, PREG_OFFSET_CAPTURE)) + { + $conditions = []; + $joints = $joints[0]; + array_unshift($joints, ['', 0]); + + for ($i = count($joints) - 1, $pos = strlen($cond); $i >= 0; $i --) + { + $joints[$i][1] += strlen($joints[$i][0]); // offset + $conditions[$i] = substr($cond, $joints[$i][1], $pos - $joints[$i][1]); + $pos = $joints[$i][1] - strlen($joints[$i][0]); + $joints[$i] = $joints[$i][0]; + } + ksort($conditions); + } + else + { + $conditions = [$cond]; + $joints = ['']; + } + + $cond = ' ON '; + foreach ($conditions as $i => $condition) + { + $operator = $this->getOperator($condition); + $cond .= $joints[$i]; + $cond .= preg_match("/(\(*)?([\[\]\w\.'-]+)" . preg_quote($operator) . '(.*)/i', $condition, $match) ? $match[1] . $this->db->protectIdentifiers($match[2]) . $operator . $this->db->protectIdentifiers($match[3]) : $condition; + } + } + + // Do we want to escape the table name? + if ($escape === true) + { + $table = $this->db->protectIdentifiers($table, true, null, false); + } + + // Assemble the JOIN statement + $this->QBJoin[] = $join = $type . 'JOIN ' . $table . $cond; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * WHERE + * + * Generates the WHERE portion of the query. + * Separates multiple calls with 'AND'. + * + * @param mixed $key + * @param mixed $value + * @param boolean $escape + * + * @return BaseBuilder + */ + public function where($key, $value = null, bool $escape = null) + { + return $this->whereHaving('QBWhere', $key, $value, 'AND ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * OR WHERE + * + * Generates the WHERE portion of the query. + * Separates multiple calls with 'OR'. + * + * @param mixed $key + * @param mixed $value + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orWhere($key, $value = null, bool $escape = null) + { + return $this->whereHaving('QBWhere', $key, $value, 'OR ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * WHERE, HAVING + * + * @used-by where() + * @used-by orWhere() + * @used-by having() + * @used-by orHaving() + * + * @param string $qb_key 'QBWhere' or 'QBHaving' + * @param mixed $key + * @param mixed $value + * @param string $type + * @param boolean $escape + * + * @return BaseBuilder + */ + protected function whereHaving(string $qb_key, $key, $value = null, string $type = 'AND ', bool $escape = null) + { + if (! is_array($key)) + { + $key = [$key => $value]; + } + + // If the escape value was not set will base it on the global setting + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + foreach ($key as $k => $v) + { + $prefix = empty($this->$qb_key) ? $this->groupGetType('') : $this->groupGetType($type); + + if ($v !== null) + { + $op = $this->getOperator($k, true); + + if (! empty($op)) + { + $k = trim($k); + + end($op); + + $op = trim(current($op)); + + if (substr($k, -1 * strlen($op)) === $op) + { + $k = rtrim(strrev(preg_replace(strrev('/' . $op . '/'), strrev(''), strrev($k), 1))); + } + } + + $bind = $this->setBind($k, $v, $escape); + + if (empty($op)) + { + $k .= ' ='; + } + else + { + $k .= " $op"; + } + + if ($v instanceof Closure) + { + $builder = $this->cleanClone(); + $v = '(' . str_replace("\n", ' ', $v($builder)->getCompiledSelect()) . ')'; + } + else + { + $v = " :$bind:"; + } + } + elseif (! $this->hasOperator($k) && $qb_key !== 'QBHaving') + { + // value appears not to have been set, assign the test to IS NULL + $k .= ' IS NULL'; + } + elseif (preg_match('/\s*(!?=|<>|IS(?:\s+NOT)?)\s*$/i', $k, $match, PREG_OFFSET_CAPTURE)) + { + $k = substr($k, 0, $match[0][1]) . ($match[1][0] === '=' ? ' IS NULL' : ' IS NOT NULL'); + } + + $this->{$qb_key}[] = [ + 'condition' => $prefix . $k . $v, + 'escape' => $escape, + ]; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * WHERE IN + * + * Generates a WHERE field IN('item', 'item') SQL query, + * joined with 'AND' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function whereIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, false, 'AND ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * OR WHERE IN + * + * Generates a WHERE field IN('item', 'item') SQL query, + * joined with 'OR' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orWhereIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, false, 'OR ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * WHERE NOT IN + * + * Generates a WHERE field NOT IN('item', 'item') SQL query, + * joined with 'AND' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function whereNotIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, true, 'AND ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * OR WHERE NOT IN + * + * Generates a WHERE field NOT IN('item', 'item') SQL query, + * joined with 'OR' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orWhereNotIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, true, 'OR ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * HAVING IN + * + * Generates a HAVING field IN('item', 'item') SQL query, + * joined with 'AND' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function havingIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, false, 'AND ', $escape, 'QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * OR HAVING IN + * + * Generates a HAVING field IN('item', 'item') SQL query, + * joined with 'OR' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orHavingIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, false, 'OR ', $escape, 'QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * HAVING NOT IN + * + * Generates a HAVING field NOT IN('item', 'item') SQL query, + * joined with 'AND' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function havingNotIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, true, 'AND ', $escape, 'QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * OR HAVING NOT IN + * + * Generates a HAVING field NOT IN('item', 'item') SQL query, + * joined with 'OR' if appropriate. + * + * @param string $key The field to search + * @param array|string|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orHavingNotIn(string $key = null, $values = null, bool $escape = null) + { + return $this->_whereIn($key, $values, true, 'OR ', $escape, 'QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * Internal WHERE IN + * + * @used-by WhereIn() + * @used-by orWhereIn() + * @used-by whereNotIn() + * @used-by orWhereNotIn() + * + * @param string $key The field to search + * @param array|Closure $values The values searched on, or anonymous function with subquery + * @param boolean $not If the statement would be IN or NOT IN + * @param string $type + * @param boolean $escape + * @param string $clause (Internal use only) + * @throws InvalidArgumentException + * + * @return BaseBuilder + */ + protected function _whereIn(string $key = null, $values = null, bool $not = false, string $type = 'AND ', bool $escape = null, string $clause = 'QBWhere') + { + if (empty($key) || ! is_string($key)) + { + if (CI_DEBUG) + { + throw new \InvalidArgumentException(sprintf('%s() expects $key to be a non-empty string', debug_backtrace(0, 2)[1]['function'])); + } + // @codeCoverageIgnoreStart + return $this; + // @codeCoverageIgnoreEnd + } + + if ($values === null || (! is_array($values) && ! ($values instanceof Closure))) + { + if (CI_DEBUG) + { + throw new \InvalidArgumentException(sprintf('%s() expects $values to be of type array or closure', debug_backtrace(0, 2)[1]['function'])); + } + // @codeCoverageIgnoreStart + return $this; + // @codeCoverageIgnoreEnd + } + + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + $ok = $key; + + if ($escape === true) + { + $key = $this->db->protectIdentifiers($key); + } + + $not = ($not) ? ' NOT' : ''; + + if ($values instanceof Closure) + { + $builder = $this->cleanClone(); + $ok = str_replace("\n", ' ', $values($builder)->getCompiledSelect()); + } + else + { + $whereIn = is_array($values) ? array_values($values) : $values; + $ok = $this->setBind($ok, $whereIn, $escape); + } + + $prefix = empty($this->$clause) ? $this->groupGetType('') : $this->groupGetType($type); + + $whereIn = [ + 'condition' => $prefix . $key . $not . ($values instanceof Closure ? " IN ($ok)" : " IN :{$ok}:"), + 'escape' => false, + ]; + + $this->{$clause}[] = $whereIn; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * LIKE + * + * Generates a %LIKE% portion of the query. + * Separates multiple calls with 'AND'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * @param boolean $insensitiveSearch IF true, will force a case-insensitive search + * + * @return BaseBuilder + */ + public function like($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'AND ', $side, '', $escape, $insensitiveSearch); + } + + //-------------------------------------------------------------------- + + /** + * NOT LIKE + * + * Generates a NOT LIKE portion of the query. + * Separates multiple calls with 'AND'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * @param boolean $insensitiveSearch IF true, will force a case-insensitive search + * + * @return BaseBuilder + */ + public function notLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape, $insensitiveSearch); + } + + //-------------------------------------------------------------------- + + /** + * OR LIKE + * + * Generates a %LIKE% portion of the query. + * Separates multiple calls with 'OR'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * @param boolean $insensitiveSearch IF true, will force a case-insensitive search + * + * @return BaseBuilder + */ + public function orLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'OR ', $side, '', $escape, $insensitiveSearch); + } + + //-------------------------------------------------------------------- + + /** + * OR NOT LIKE + * + * Generates a NOT LIKE portion of the query. + * Separates multiple calls with 'OR'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * @param boolean $insensitiveSearch IF true, will force a case-insensitive search + * + * @return BaseBuilder + */ + public function orNotLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape, $insensitiveSearch); + } + + // -------------------------------------------------------------------- + + /** + * LIKE with HAVING clause + * + * Generates a %LIKE% portion of the query. + * Separates multiple calls with 'AND'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * + * @return BaseBuilder + */ + public function havingLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'AND ', $side, '', $escape, $insensitiveSearch, 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * NOT LIKE with HAVING clause + * + * Generates a NOT LIKE portion of the query. + * Separates multiple calls with 'AND'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * + * @return BaseBuilder + */ + public function notHavingLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'AND ', $side, 'NOT', $escape, $insensitiveSearch, 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * OR LIKE with HAVING clause + * + * Generates a %LIKE% portion of the query. + * Separates multiple calls with 'OR'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orHavingLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'OR ', $side, '', $escape, $insensitiveSearch, 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * OR NOT LIKE with HAVING clause + * + * Generates a NOT LIKE portion of the query. + * Separates multiple calls with 'OR'. + * + * @param mixed $field + * @param string $match + * @param string $side + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orNotHavingLike($field, string $match = '', string $side = 'both', bool $escape = null, bool $insensitiveSearch = false) + { + return $this->_like($field, $match, 'OR ', $side, 'NOT', $escape, $insensitiveSearch, 'QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * Internal LIKE + * + * @used-by like() + * @used-by orLike() + * @used-by notLike() + * @used-by orNotLike() + * @used-by havingLike() + * @used-by orHavingLike() + * @used-by notHavingLike() + * @used-by orNotHavingLike() + * + * @param mixed $field + * @param string $match + * @param string $type + * @param string $side + * @param string $not + * @param boolean $escape + * @param boolean $insensitiveSearch IF true, will force a case-insensitive search + * @param string $clause (Internal use only) + * + * @return BaseBuilder + */ + protected function _like($field, string $match = '', string $type = 'AND ', string $side = 'both', string $not = '', bool $escape = null, bool $insensitiveSearch = false, string $clause = 'QBWhere') + { + if (! is_array($field)) + { + $field = [$field => $match]; + } + + $escape = is_bool($escape) ? $escape : $this->db->protectIdentifiers; + + // lowercase $side in case somebody writes e.g. 'BEFORE' instead of 'before' (doh) + $side = strtolower($side); + + foreach ($field as $k => $v) + { + if ($insensitiveSearch === true) + { + $v = strtolower($v); + } + + $prefix = empty($this->$clause) ? $this->groupGetType('') : $this->groupGetType($type); + + if ($side === 'none') + { + $bind = $this->setBind($k, $v, $escape); + } + elseif ($side === 'before') + { + $bind = $this->setBind($k, "%$v", $escape); + } + elseif ($side === 'after') + { + $bind = $this->setBind($k, "$v%", $escape); + } + else + { + $bind = $this->setBind($k, "%$v%", $escape); + } + + $like_statement = $this->_like_statement($prefix, $k, $not, $bind, $insensitiveSearch); + + // some platforms require an escape sequence definition for LIKE wildcards + if ($escape === true && $this->db->likeEscapeStr !== '') + { + $like_statement .= sprintf($this->db->likeEscapeStr, $this->db->likeEscapeChar); + } + + $this->{$clause}[] = [ + 'condition' => $like_statement, + 'escape' => $escape, + ]; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Platform independent LIKE statement builder. + * + * @param string $prefix + * @param string $column + * @param string $not + * @param string $bind + * @param boolean $insensitiveSearch + * + * @return string $like_statement + */ + protected function _like_statement(string $prefix = null, string $column, string $not = null, string $bind, bool $insensitiveSearch = false): string + { + $like_statement = "{$prefix} {$column} {$not} LIKE :{$bind}:"; + + if ($insensitiveSearch === true) + { + $like_statement = "{$prefix} LOWER({$column}) {$not} LIKE :{$bind}:"; + } + + return $like_statement; + } + + //-------------------------------------------------------------------- + + /** + * Starts a query group. + * + * @return BaseBuilder + */ + public function groupStart() + { + return $this->groupStartPrepare(); + } + + //-------------------------------------------------------------------- + + /** + * Starts a query group, but ORs the group + * + * @return BaseBuilder + */ + public function orGroupStart() + { + return $this->groupStartPrepare('', 'OR '); + } + + //-------------------------------------------------------------------- + + /** + * Starts a query group, but NOTs the group + * + * @return BaseBuilder + */ + public function notGroupStart() + { + return $this->groupStartPrepare('NOT '); + } + + //-------------------------------------------------------------------- + + /** + * Starts a query group, but OR NOTs the group + * + * @return BaseBuilder + */ + public function orNotGroupStart() + { + return $this->groupStartPrepare('NOT ', 'OR '); + } + + //-------------------------------------------------------------------- + + /** + * Ends a query group + * + * @return BaseBuilder + */ + public function groupEnd() + { + return $this->groupEndPrepare(); + } + + // -------------------------------------------------------------------- + + /** + * Starts a query group for HAVING clause. + * + * @return BaseBuilder + */ + public function havingGroupStart() + { + return $this->groupStartPrepare('', 'AND ', 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * Starts a query group for HAVING clause, but ORs the group. + * + * @return BaseBuilder + */ + public function orHavingGroupStart() + { + return $this->groupStartPrepare('', 'OR ', 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * Starts a query group for HAVING clause, but NOTs the group. + * + * @return BaseBuilder + */ + public function notHavingGroupStart() + { + return $this->groupStartPrepare('NOT ', 'AND ', 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * Starts a query group for HAVING clause, but OR NOTs the group. + * + * @return BaseBuilder + */ + public function orNotHavingGroupStart() + { + return $this->groupStartPrepare('NOT ', 'OR ', 'QBHaving'); + } + + // -------------------------------------------------------------------- + + /** + * Ends a query group for HAVING clause. + * + * @return BaseBuilder + */ + public function havingGroupEnd() + { + return $this->groupEndPrepare('QBHaving'); + } + + //-------------------------------------------------------------------- + + /** + * Prepate a query group start. + * + * @param string $not + * @param string $type + * @param string $clause + * + * @return BaseBuilder + */ + protected function groupStartPrepare(string $not = '', string $type = 'AND ', string $clause = 'QBWhere') + { + $type = $this->groupGetType($type); + + $this->QBWhereGroupStarted = true; + $prefix = empty($this->$clause) ? '' : $type; + $where = [ + 'condition' => $prefix . $not . str_repeat(' ', ++ $this->QBWhereGroupCount) . ' (', + 'escape' => false, + ]; + + $this->{$clause}[] = $where; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Prepate a query group end. + * + * @param string $clause + * + * @return BaseBuilder + */ + protected function groupEndPrepare(string $clause = 'QBWhere') + { + $this->QBWhereGroupStarted = false; + $where = [ + 'condition' => str_repeat(' ', $this->QBWhereGroupCount -- ) . ')', + 'escape' => false, + ]; + + $this->{$clause}[] = $where; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Group_get_type + * + * @used-by groupStart() + * @used-by _like() + * @used-by whereHaving() + * @used-by _whereIn() + * @used-by havingGroupStart() + * + * @param string $type + * + * @return string + */ + protected function groupGetType(string $type): string + { + if ($this->QBWhereGroupStarted) + { + $type = ''; + $this->QBWhereGroupStarted = false; + } + + return $type; + } + + //-------------------------------------------------------------------- + + /** + * GROUP BY + * + * @param string|array $by + * @param boolean $escape + * + * @return BaseBuilder + */ + public function groupBy($by, bool $escape = null) + { + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + if (is_string($by)) + { + $by = ($escape === true) ? explode(',', $by) : [$by]; + } + + foreach ($by as $val) + { + $val = trim($val); + + if ($val !== '') + { + $val = [ + 'field' => $val, + 'escape' => $escape, + ]; + + $this->QBGroupBy[] = $val; + } + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * HAVING + * + * Separates multiple calls with 'AND'. + * + * @param string|array $key + * @param mixed $value + * @param boolean $escape + * + * @return BaseBuilder + */ + public function having($key, $value = null, bool $escape = null) + { + return $this->whereHaving('QBHaving', $key, $value, 'AND ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * OR HAVING + * + * Separates multiple calls with 'OR'. + * + * @param string|array $key + * @param mixed $value + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orHaving($key, $value = null, bool $escape = null) + { + return $this->whereHaving('QBHaving', $key, $value, 'OR ', $escape); + } + + //-------------------------------------------------------------------- + + /** + * ORDER BY + * + * @param string $orderBy + * @param string $direction ASC, DESC or RANDOM + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orderBy(string $orderBy, string $direction = '', bool $escape = null) + { + $direction = strtoupper(trim($direction)); + + if ($direction === 'RANDOM') + { + $direction = ''; + + // Do we have a seed value? + $orderBy = ctype_digit((string) $orderBy) ? sprintf($this->randomKeyword[1], $orderBy) : $this->randomKeyword[0]; + } + elseif (empty($orderBy)) + { + return $this; + } + elseif ($direction !== '') + { + $direction = in_array($direction, ['ASC', 'DESC'], true) ? ' ' . $direction : ''; + } + + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + if ($escape === false) + { + $qb_orderBy[] = [ + 'field' => $orderBy, + 'direction' => $direction, + 'escape' => false, + ]; + } + else + { + $qb_orderBy = []; + foreach (explode(',', $orderBy) as $field) + { + $qb_orderBy[] = ($direction === '' && preg_match('/\s+(ASC|DESC)$/i', rtrim($field), $match, PREG_OFFSET_CAPTURE)) + ? + [ + 'field' => ltrim(substr($field, 0, $match[0][1])), + 'direction' => ' ' . $match[1][0], + 'escape' => true, + ] + : + [ + 'field' => trim($field), + 'direction' => $direction, + 'escape' => true, + ]; + } + } + + $this->QBOrderBy = array_merge($this->QBOrderBy, $qb_orderBy); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * LIMIT + * + * @param integer $value LIMIT value + * @param integer $offset OFFSET value + * + * @return BaseBuilder + */ + public function limit(int $value = null, ?int $offset = 0) + { + if (! is_null($value)) + { + $this->QBLimit = $value; + } + + if (! empty($offset)) + { + $this->QBOffset = $offset; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the OFFSET value + * + * @param integer $offset OFFSET value + * + * @return BaseBuilder + */ + public function offset(int $offset) + { + if (! empty($offset)) + { + $this->QBOffset = (int) $offset; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * LIMIT string + * + * Generates a platform-specific LIMIT clause. + * + * @param string $sql SQL Query + * + * @return string + */ + protected function _limit(string $sql, bool $offsetIgnore = false): string + { + return $sql . ' LIMIT ' . (false === $offsetIgnore && $this->QBOffset ? $this->QBOffset . ', ' : '') . $this->QBLimit; + } + + //-------------------------------------------------------------------- + + /** + * The "set" function. + * + * Allows key/value pairs to be set for insert(), update() or replace(). + * + * @param string|array|object $key Field name, or an array of field/value pairs + * @param string $value Field value, if $key is a single field + * @param boolean $escape Whether to escape values and identifiers + * + * @return BaseBuilder + */ + public function set($key, ?string $value = '', bool $escape = null) + { + $key = $this->objectToArray($key); + + if (! is_array($key)) + { + $key = [$key => $value]; + } + + $escape = is_bool($escape) ? $escape : $this->db->protectIdentifiers; + + foreach ($key as $k => $v) + { + if ($escape) + { + $bind = $this->setBind($k, $v, $escape); + $this->QBSet[$this->db->protectIdentifiers($k, false, $escape)] = ":$bind:"; + } + else + { + $this->QBSet[$this->db->protectIdentifiers($k, false, $escape)] = $v; + } + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the previously set() data, alternatively resetting it + * if needed. + * + * @param boolean $clean + * + * @return array + */ + public function getSetData(bool $clean = false): array + { + $data = $this->QBSet; + + if ($clean) + { + $this->QBSet = []; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Get SELECT query string + * + * Compiles a SELECT query string and returns the sql. + * + * @param boolean $reset TRUE: resets QB values; FALSE: leave QB values alone + * + * @return string + */ + public function getCompiledSelect(bool $reset = true): string + { + $select = $this->compileSelect(); + + if ($reset === true) + { + $this->resetSelect(); + } + + return $this->compileFinalQuery($select); + } + + //-------------------------------------------------------------------- + + /** + * Returns a finalized, compiled query string with the bindings + * inserted and prefixes swapped out. + * + * @param string $sql + * + * @return string + */ + protected function compileFinalQuery(string $sql): string + { + $query = new Query($this->db); + $query->setQuery($sql, $this->binds, false); + + if (! empty($this->db->swapPre) && ! empty($this->db->DBPrefix)) + { + $query->swapPrefix($this->db->DBPrefix, $this->db->swapPre); + } + + return $query->getQuery(); + } + + /** + * Get + * + * Compiles the select statement based on the other functions called + * and runs the query + * + * @param integer $limit The limit clause + * @param integer $offset The offset clause + * @param boolean $reset Are we want to clear query builder values? + * + * @return ResultInterface + */ + public function get(int $limit = null, int $offset = 0, bool $reset = true) + { + if (! is_null($limit)) + { + $this->limit($limit, $offset); + } + + $result = $this->testMode + ? $this->getCompiledSelect($reset) + : $this->db->query($this->compileSelect(), $this->binds, false); + + if ($reset === true) + { + $this->resetSelect(); + + // Clear our binds so we don't eat up memory + $this->binds = []; + } + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * "Count All" query + * + * Generates a platform-specific query string that counts all records in + * the specified database + * + * @param boolean $reset Are we want to clear query builder values? + * + * @return integer|string when $test = true + */ + public function countAll(bool $reset = true) + { + $table = $this->QBFrom[0]; + + $sql = $this->countString . $this->db->escapeIdentifiers('numrows') . ' FROM ' . + $this->db->protectIdentifiers($table, true, null, false); + + if ($this->testMode) + { + return $sql; + } + + $query = $this->db->query($sql, null, false); + if (empty($query->getResult())) + { + return 0; + } + + $query = $query->getRow(); + + if ($reset === true) + { + $this->resetSelect(); + } + + return (int) $query->numrows; + } + + //-------------------------------------------------------------------- + + /** + * "Count All Results" query + * + * Generates a platform-specific query string that counts all records + * returned by an Query Builder query. + * + * @param boolean $reset + * + * @return integer|string when $test = true + */ + public function countAllResults(bool $reset = true) + { + // ORDER BY usage is often problematic here (most notably + // on Microsoft SQL Server) and ultimately unnecessary + // for selecting COUNT(*) ... + $orderBy = []; + if (! empty($this->QBOrderBy)) + { + $orderBy = $this->QBOrderBy; + $this->QBOrderBy = null; + } + + // We cannot use a LIMIT when getting the single row COUNT(*) result + $limit = $this->QBLimit; + $this->QBLimit = false; + + $sql = ($this->QBDistinct === true || ! empty($this->QBGroupBy)) + ? + $this->countString . $this->db->protectIdentifiers('numrows') . "\nFROM (\n" . $this->compileSelect() . "\n) CI_count_all_results" + : + $this->compileSelect($this->countString . $this->db->protectIdentifiers('numrows')); + + if ($this->testMode) + { + return $sql; + } + + $result = $this->db->query($sql, $this->binds, false); + + if ($reset === true) + { + $this->resetSelect(); + } + // If we've previously reset the QBOrderBy values, get them back + elseif (! isset($this->QBOrderBy)) + { + $this->QBOrderBy = $orderBy ?? []; + } + + // Restore the LIMIT setting + $this->QBLimit = $limit; + + $row = (! $result instanceof ResultInterface) + ? null + : $result->getRow(); + + if (empty($row)) + { + return 0; + } + + return (int) $row->numrows; + } + + //-------------------------------------------------------------------- + /** + * Get compiled 'where' condition string + * + * Compiles the set conditions and returns the sql statement + * + * @return string + */ + public function getCompiledQBWhere() + { + return $this->QBWhere; + } + //-------------------------------------------------------------------- + + /** + * Get_Where + * + * Allows the where clause, limit and offset to be added directly + * + * @param string|array $where Where condition + * @param integer $limit Limit value + * @param integer $offset Offset value + * @param boolean $reset Are we want to clear query builder values? + * + * @return ResultInterface + */ + public function getWhere($where = null, int $limit = null, ?int $offset = 0, bool $reset = true) + { + if ($where !== null) + { + $this->where($where); + } + + if (! empty($limit)) + { + $this->limit($limit, $offset); + } + + $result = $this->testMode + ? $this->getCompiledSelect($reset) + : $this->db->query($this->compileSelect(), $this->binds, false); + + if ($reset === true) + { + $this->resetSelect(); + + // Clear our binds so we don't eat up memory + $this->binds = []; + } + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Insert_Batch + * + * Compiles batch insert strings and runs the queries + * + * @param array $set An associative array of insert values + * @param boolean $escape Whether to escape values and identifiers + * @param integer $batchSize Batch size + * + * @return integer Number of rows inserted or FALSE on failure + * @throws DatabaseException + */ + public function insertBatch(array $set = null, bool $escape = null, int $batchSize = 100) + { + if ($set === null) + { + if (empty($this->QBSet)) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + } + else + { + if (empty($set)) + { + if (CI_DEBUG) + { + throw new DatabaseException('insertBatch() called with no data'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + $this->setInsertBatch($set, '', $escape); + } + + $table = $this->QBFrom[0]; + + // Batch this baby + $affected_rows = 0; + for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize) + { + $sql = $this->_insertBatch($this->db->protectIdentifiers($table, true, $escape, false), $this->QBKeys, array_slice($this->QBSet, $i, $batchSize)); + + if ($this->testMode) + { + ++ $affected_rows; + } + else + { + $this->db->query($sql, $this->binds, false); + $affected_rows += $this->db->affectedRows(); + } + } + + if (! $this->testMode) + { + $this->resetWrite(); + } + + return $affected_rows; + } + + //-------------------------------------------------------------------- + + /** + * Insert batch statement + * + * Generates a platform-specific insert string from the supplied data. + * + * @param string $table Table name + * @param array $keys INSERT keys + * @param array $values INSERT values + * + * @return string + */ + protected function _insertBatch(string $table, array $keys, array $values): string + { + return 'INSERT ' . $this->compileIgnore('insert') . 'INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES ' . implode(', ', $values); + } + + //-------------------------------------------------------------------- + + /** + * The "setInsertBatch" function. Allows key/value pairs to be set for batch inserts + * + * @param mixed $key + * @param string $value + * @param boolean $escape + * + * @return BaseBuilder|null + */ + public function setInsertBatch($key, string $value = '', bool $escape = null) + { + $key = $this->batchObjectToArray($key); + + if (! is_array($key)) + { + $key = [$key => $value]; + } + + $escape = is_bool($escape) ? $escape : $this->db->protectIdentifiers; + + $keys = array_keys($this->objectToArray(current($key))); + sort($keys); + + foreach ($key as $row) + { + $row = $this->objectToArray($row); + if (count(array_diff($keys, array_keys($row))) > 0 || count(array_diff(array_keys($row), $keys)) > 0) + { + // batch function above returns an error on an empty array + $this->QBSet[] = []; + + return null; + } + + ksort($row); // puts $row in the same order as our keys + + $clean = []; + foreach ($row as $k => $value) + { + $clean[] = ':' . $this->setBind($k, $value, $escape) . ':'; + } + + $row = $clean; + + $this->QBSet[] = '(' . implode(',', $row) . ')'; + } + + foreach ($keys as $k) + { + $this->QBKeys[] = $this->db->protectIdentifiers($k, false, $escape); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Get INSERT query string + * + * Compiles an insert query and returns the sql + * + * @param boolean $reset TRUE: reset QB values; FALSE: leave QB values alone + * + * @throws DatabaseException + * + * @return string + */ + public function getCompiledInsert(bool $reset = true): string + { + if ($this->validateInsert() === false) + { + return false; + } + + $sql = $this->_insert( + $this->db->protectIdentifiers( + $this->QBFrom[0], true, null, false + ), array_keys($this->QBSet), array_values($this->QBSet) + ); + + if ($reset === true) + { + $this->resetWrite(); + } + + return $this->compileFinalQuery($sql); + } + + //-------------------------------------------------------------------- + + /** + * Insert + * + * Compiles an insert string and runs the query + * + * @param array $set An associative array of insert values + * @param boolean $escape Whether to escape values and identifiers + * + * @throws DatabaseException + * + * @return BaseResult|Query|false + */ + public function insert(array $set = null, bool $escape = null) + { + if ($set !== null) + { + $this->set($set, '', $escape); + } + + if ($this->validateInsert() === false) + { + return false; + } + + $sql = $this->_insert( + $this->db->protectIdentifiers( + $this->QBFrom[0], true, $escape, false + ), array_keys($this->QBSet), array_values($this->QBSet) + ); + + if (! $this->testMode) + { + $this->resetWrite(); + + $result = $this->db->query($sql, $this->binds, false); + + // Clear our binds so we don't eat up memory + $this->binds = []; + + return $result; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Validate Insert + * + * This method is used by both insert() and getCompiledInsert() to + * validate that the there data is actually being set and that table + * has been chosen to be inserted into. + * + * @return boolean + * @throws DatabaseException + */ + protected function validateInsert(): bool + { + if (empty($this->QBSet)) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Insert statement + * + * Generates a platform-specific insert string from the supplied data + * + * @param string $table The table name + * @param array $keys The insert keys + * @param array $unescapedKeys The insert values + * + * @return string + */ + protected function _insert(string $table, array $keys, array $unescapedKeys): string + { + return 'INSERT ' . $this->compileIgnore('insert') . 'INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $unescapedKeys) . ')'; + } + + //-------------------------------------------------------------------- + + /** + * Replace + * + * Compiles an replace into string and runs the query + * + * @param array $set An associative array of insert values + * + * @return BaseResult|Query|string|false + * @throws DatabaseException + */ + public function replace(array $set = null) + { + if ($set !== null) + { + $this->set($set); + } + + if (empty($this->QBSet)) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + $table = $this->QBFrom[0]; + + $sql = $this->_replace($table, array_keys($this->QBSet), array_values($this->QBSet)); + + $this->resetWrite(); + + return $this->testMode ? $sql : $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Replace statement + * + * Generates a platform-specific replace string from the supplied data + * + * @param string $table The table name + * @param array $keys The insert keys + * @param array $values The insert values + * + * @return string + */ + protected function _replace(string $table, array $keys, array $values): string + { + return 'REPLACE INTO ' . $table . ' (' . implode(', ', $keys) . ') VALUES (' . implode(', ', $values) . ')'; + } + + //-------------------------------------------------------------------- + + /** + * FROM tables + * + * Groups tables in FROM clauses if needed, so there is no confusion + * about operator precedence. + * + * Note: This is only used (and overridden) by MySQL and CUBRID. + * + * @return string + */ + protected function _fromTables(): string + { + return implode(', ', $this->QBFrom); + } + + //-------------------------------------------------------------------- + + /** + * Get UPDATE query string + * + * Compiles an update query and returns the sql + * + * @param boolean $reset TRUE: reset QB values; FALSE: leave QB values alone + * + * @return string + */ + public function getCompiledUpdate(bool $reset = true): string + { + if ($this->validateUpdate() === false) + { + return false; + } + + $sql = $this->_update($this->QBFrom[0], $this->QBSet); + + if ($reset === true) + { + $this->resetWrite(); + } + + return $this->compileFinalQuery($sql); + } + + //-------------------------------------------------------------------- + + /** + * UPDATE + * + * Compiles an update string and runs the query. + * + * @param array $set An associative array of update values + * @param mixed $where + * @param integer $limit + * + * @throws DatabaseException + * + * @return boolean TRUE on success, FALSE on failure + */ + public function update(array $set = null, $where = null, int $limit = null): bool + { + if ($set !== null) + { + $this->set($set); + } + + if ($this->validateUpdate() === false) + { + return false; + } + + if ($where !== null) + { + $this->where($where); + } + + if (! empty($limit)) + { + if (! $this->canLimitWhereUpdates) + { + throw new DatabaseException('This driver does not allow LIMITs on UPDATE queries using WHERE.'); + } + + $this->limit($limit); + } + + $sql = $this->_update($this->QBFrom[0], $this->QBSet); + + if (! $this->testMode) + { + $this->resetWrite(); + + $result = $this->db->query($sql, $this->binds, false); + + if ($result->resultID !== false) + { + // Clear our binds so we don't eat up memory + $this->binds = []; + + return true; + } + + return false; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @param string $table the Table name + * @param array $values the Update data + * + * @return string + */ + protected function _update(string $table, array $values): string + { + $valStr = []; + + foreach ($values as $key => $val) + { + $valStr[] = $key . ' = ' . $val; + } + + return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . implode(', ', $valStr) + . $this->compileWhereHaving('QBWhere') + . $this->compileOrderBy() + . ($this->QBLimit ? $this->_limit(' ', true) : ''); + } + + //-------------------------------------------------------------------- + + /** + * Validate Update + * + * This method is used by both update() and getCompiledUpdate() to + * validate that data is actually being set and that a table has been + * chosen to be update. + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + protected function validateUpdate(): bool + { + if (empty($this->QBSet)) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Update_Batch + * + * Compiles an update string and runs the query + * + * @param array $set An associative array of update values + * @param string $index The where key + * @param integer $batchSize The size of the batch to run + * + * @return mixed Number of rows affected, SQL string, or FALSE on failure + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function updateBatch(array $set = null, string $index = null, int $batchSize = 100) + { + if ($index === null) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must specify an index to match on for batch updates.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + if ($set === null) + { + if (empty($this->QBSet)) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + } + else + { + if (empty($set)) + { + if (CI_DEBUG) + { + throw new DatabaseException('updateBatch() called with no data'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + $this->setUpdateBatch($set, $index); + } + + $table = $this->QBFrom[0]; + + // Batch this baby + $affected_rows = 0; + $savedSQL = []; + $savedQBWhere = $this->QBWhere; + for ($i = 0, $total = count($this->QBSet); $i < $total; $i += $batchSize) + { + $sql = $this->_updateBatch($table, array_slice($this->QBSet, $i, $batchSize), $this->db->protectIdentifiers($index) + ); + + if ($this->testMode) + { + $savedSQL[] = $sql; + } + else + { + $this->db->query($sql, $this->binds, false); + $affected_rows += $this->db->affectedRows(); + } + + $this->QBWhere = $savedQBWhere; + } + + $this->resetWrite(); + + return $this->testMode ? $savedSQL : $affected_rows; + } + + //-------------------------------------------------------------------- + + /** + * Update_Batch statement + * + * Generates a platform-specific batch update string from the supplied data + * + * @param string $table Table name + * @param array $values Update data + * @param string $index WHERE key + * + * @return string + */ + protected function _updateBatch(string $table, array $values, string $index): string + { + $ids = []; + $final = []; + + foreach ($values as $val) + { + $ids[] = $val[$index]; + + foreach (array_keys($val) as $field) + { + if ($field !== $index) + { + $final[$field][] = 'WHEN ' . $index . ' = ' . $val[$index] . ' THEN ' . $val[$field]; + } + } + } + + $cases = ''; + foreach ($final as $k => $v) + { + $cases .= $k . " = CASE \n" + . implode("\n", $v) . "\n" + . 'ELSE ' . $k . ' END, '; + } + + $this->where($index . ' IN(' . implode(',', $ids) . ')', null, false); + + return 'UPDATE ' . $this->compileIgnore('update') . $table . ' SET ' . substr($cases, 0, -2) . $this->compileWhereHaving('QBWhere'); + } + + //-------------------------------------------------------------------- + + /** + * The "setUpdateBatch" function. Allows key/value pairs to be set for batch updating + * + * @param array|object $key + * @param string $index + * @param boolean $escape + * + * @return BaseBuilder|null + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function setUpdateBatch($key, string $index = '', bool $escape = null) + { + $key = $this->batchObjectToArray($key); + + if (! is_array($key)) + { + return null; + } + + is_bool($escape) || $escape = $this->db->protectIdentifiers; + + foreach ($key as $v) + { + $index_set = false; + $clean = []; + foreach ($v as $k2 => $v2) + { + if ($k2 === $index) + { + $index_set = true; + } + + $bind = $this->setBind($k2, $v2, $escape); + + $clean[$this->db->protectIdentifiers($k2, false, $escape)] = ":$bind:"; + } + + if ($index_set === false) + { + throw new DatabaseException('One or more rows submitted for batch updating is missing the specified index.'); + } + + $this->QBSet[] = $clean; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Empty Table + * + * Compiles a delete string and runs "DELETE FROM table" + * + * @return boolean TRUE on success, FALSE on failure + */ + public function emptyTable() + { + $table = $this->QBFrom[0]; + + $sql = $this->_delete($table); + + if ($this->testMode) + { + return $sql; + } + + $this->resetWrite(); + + return $this->db->query($sql, null, false); + } + + //-------------------------------------------------------------------- + + /** + * Truncate + * + * Compiles a truncate string and runs the query + * If the database does not support the truncate() command + * This function maps to "DELETE FROM table" + * + * @return boolean TRUE on success, FALSE on failure + */ + public function truncate() + { + $table = $this->QBFrom[0]; + + $sql = $this->_truncate($table); + + if ($this->testMode) + { + return $sql; + } + + $this->resetWrite(); + + return $this->db->query($sql, null, false); + } + + //-------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * + * If the database does not support the truncate() command, + * then this method maps to 'DELETE FROM table' + * + * @param string $table The table name + * + * @return string + */ + protected function _truncate(string $table): string + { + return 'TRUNCATE ' . $table; + } + + //-------------------------------------------------------------------- + + /** + * Get DELETE query string + * + * Compiles a delete query string and returns the sql + * + * @param boolean $reset TRUE: reset QB values; FALSE: leave QB values alone + * + * @return string + */ + public function getCompiledDelete(bool $reset = true): string + { + $table = $this->QBFrom[0]; + + $sql = $this->delete($table, null, $reset, true); + + return $this->compileFinalQuery($sql); + } + + //-------------------------------------------------------------------- + + /** + * Delete + * + * Compiles a delete string and runs the query + * + * @param mixed $where The where clause + * @param integer $limit The limit clause + * @param boolean $reset_data + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function delete($where = '', int $limit = null, bool $reset_data = true) + { + $table = $this->db->protectIdentifiers($this->QBFrom[0], true, null, false); + + if ($where !== '') + { + $this->where($where); + } + + if (empty($this->QBWhere)) + { + if (CI_DEBUG) + { + throw new DatabaseException('Deletes are not allowed unless they contain a "where" or "like" clause.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + $sql = $this->_delete($table); + + if (! empty($limit)) + { + $this->QBLimit = $limit; + } + + if (! empty($this->QBLimit)) + { + if (! $this->canLimitDeletes) + { + throw new DatabaseException('SQLite3 does not allow LIMITs on DELETE queries.'); + } + + $sql = $this->_limit($sql, true); + } + + if ($reset_data) + { + $this->resetWrite(); + } + + return $this->testMode ? $sql : $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Increments a numeric column by the specified value. + * + * @param string $column + * @param integer $value + * + * @return boolean + */ + public function increment(string $column, int $value = 1) + { + $column = $this->db->protectIdentifiers($column); + + $sql = $this->_update($this->QBFrom[0], [$column => "{$column} + {$value}"]); + + return $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Decrements a numeric column by the specified value. + * + * @param string $column + * @param integer $value + * + * @return boolean + */ + public function decrement(string $column, int $value = 1) + { + $column = $this->db->protectIdentifiers($column); + + $sql = $this->_update($this->QBFrom[0], [$column => "{$column}-{$value}"]); + + return $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @param string $table The table name + * + * @return string + */ + protected function _delete(string $table): string + { + return 'DELETE ' . $this->compileIgnore('delete') . 'FROM ' . $table . $this->compileWhereHaving('QBWhere'); + } + + //-------------------------------------------------------------------- + + /** + * Track Aliases + * + * Used to track SQL statements written with aliased tables. + * + * @param string|array $table The table to inspect + * + * @return string|void + */ + protected function trackAliases($table) + { + if (is_array($table)) + { + foreach ($table as $t) + { + $this->trackAliases($t); + } + return; + } + + // Does the string contain a comma? If so, we need to separate + // the string into discreet statements + if (strpos($table, ',') !== false) + { + return $this->trackAliases(explode(',', $table)); + } + + // if a table alias is used we can recognize it by a space + if (strpos($table, ' ') !== false) + { + // if the alias is written with the AS keyword, remove it + $table = preg_replace('/\s+AS\s+/i', ' ', $table); + + // Grab the alias + $table = trim(strrchr($table, ' ')); + + // Store the alias, if it doesn't already exist + $this->db->addTableAlias($table); + } + } + + //-------------------------------------------------------------------- + + /** + * Compile the SELECT statement + * + * Generates a query string based on which functions were used. + * Should not be called directly. + * + * @param mixed $select_override + * + * @return string + */ + protected function compileSelect($select_override = false): string + { + // Write the "select" portion of the query + if ($select_override !== false) + { + $sql = $select_override; + } + else + { + $sql = ( ! $this->QBDistinct) ? 'SELECT ' : 'SELECT DISTINCT '; + + if (empty($this->QBSelect)) + { + $sql .= '*'; + } + else + { + // Cycle through the "select" portion of the query and prep each column name. + // The reason we protect identifiers here rather than in the select() function + // is because until the user calls the from() function we don't know if there are aliases + foreach ($this->QBSelect as $key => $val) + { + $no_escape = $this->QBNoEscape[$key] ?? null; + $this->QBSelect[$key] = $this->db->protectIdentifiers($val, false, $no_escape); + } + + $sql .= implode(', ', $this->QBSelect); + } + } + + // Write the "FROM" portion of the query + if (! empty($this->QBFrom)) + { + $sql .= "\nFROM " . $this->_fromTables(); + } + + // Write the "JOIN" portion of the query + if (! empty($this->QBJoin)) + { + $sql .= "\n" . implode("\n", $this->QBJoin); + } + + $sql .= $this->compileWhereHaving('QBWhere') + . $this->compileGroupBy() + . $this->compileWhereHaving('QBHaving') + . $this->compileOrderBy(); // ORDER BY + // LIMIT + if ($this->QBLimit) + { + return $this->_limit($sql . "\n"); + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Compile Ignore Statement + * + * Checks if the ignore option is supported by + * the Database Driver for the specific statement. + * + * @param string $statement + * + * @return string + */ + protected function compileIgnore(string $statement) + { + $sql = ''; + + if ($this->QBIgnore && + isset($this->supportedIgnoreStatements[$statement]) + ) + { + $sql = trim($this->supportedIgnoreStatements[$statement]) . ' '; + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Compile WHERE, HAVING statements + * + * Escapes identifiers in WHERE and HAVING statements at execution time. + * + * Required so that aliases are tracked properly, regardless of whether + * where(), orWhere(), having(), orHaving are called prior to from(), + * join() and prefixTable is added only if needed. + * + * @param string $qb_key 'QBWhere' or 'QBHaving' + * + * @return string SQL statement + */ + protected function compileWhereHaving(string $qb_key): string + { + if (! empty($this->$qb_key)) + { + foreach ($this->$qb_key as &$qbkey) + { + // Is this condition already compiled? + if (is_string($qbkey)) + { + continue; + } + elseif ($qbkey['escape'] === false) + { + $qbkey = $qbkey['condition']; + continue; + } + + // Split multiple conditions + $conditions = preg_split( + '/((?:^|\s+)AND\s+|(?:^|\s+)OR\s+)/i', $qbkey['condition'], -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY + ); + + foreach ($conditions as &$condition) + { + if (($op = $this->getOperator($condition)) === false + || ! preg_match('/^(\(?)(.*)(' . preg_quote($op, '/') . ')\s*(.*(? '(test <= foo)', /* the whole thing */ + // 1 => '(', /* optional */ + // 2 => 'test', /* the field name */ + // 3 => ' <= ', /* $op */ + // 4 => 'foo', /* optional, if $op is e.g. 'IS NULL' */ + // 5 => ')' /* optional */ + // ); + + if (! empty($matches[4])) + { + $protectIdentifiers = false; + if (strpos($matches[4], '.') !== false) + { + $protectIdentifiers = true; + } + + if (strpos($matches[4], ':') === false) + { + $matches[4] = $this->db->protectIdentifiers(trim($matches[4]), false, $protectIdentifiers); + } + + $matches[4] = ' ' . $matches[4]; + } + + $condition = $matches[1] . $this->db->protectIdentifiers(trim($matches[2])) + . ' ' . trim($matches[3]) . $matches[4] . $matches[5]; + } + + $qbkey = implode('', $conditions); + } + + return ($qb_key === 'QBHaving' ? "\nHAVING " : "\nWHERE ") + . implode("\n", $this->$qb_key); + } + + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Compile GROUP BY + * + * Escapes identifiers in GROUP BY statements at execution time. + * + * Required so that aliases are tracked properly, regardless of whether + * groupBy() is called prior to from(), join() and prefixTable is added + * only if needed. + * + * @return string SQL statement + */ + protected function compileGroupBy(): string + { + if (! empty($this->QBGroupBy)) + { + foreach ($this->QBGroupBy as &$groupBy) + { + // Is it already compiled? + if (is_string($groupBy)) + { + continue; + } + + $groupBy = ($groupBy['escape'] === false || + $this->isLiteral($groupBy['field'])) ? $groupBy['field'] : $this->db->protectIdentifiers($groupBy['field']); + } + + return "\nGROUP BY " . implode(', ', $this->QBGroupBy); + } + + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Compile ORDER BY + * + * Escapes identifiers in ORDER BY statements at execution time. + * + * Required so that aliases are tracked properly, regardless of whether + * orderBy() is called prior to from(), join() and prefixTable is added + * only if needed. + * + * @return string SQL statement + */ + protected function compileOrderBy(): string + { + if (is_array($this->QBOrderBy) && ! empty($this->QBOrderBy)) + { + foreach ($this->QBOrderBy as &$orderBy) + { + if ($orderBy['escape'] !== false && ! $this->isLiteral($orderBy['field'])) + { + $orderBy['field'] = $this->db->protectIdentifiers($orderBy['field']); + } + + $orderBy = $orderBy['field'] . $orderBy['direction']; + } + + return $this->QBOrderBy = "\nORDER BY " . implode(', ', $this->QBOrderBy); + } + elseif (is_string($this->QBOrderBy)) + { + return $this->QBOrderBy; + } + + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @param mixed $object + * + * @return mixed + */ + protected function objectToArray($object) + { + if (! is_object($object)) + { + return $object; + } + + $array = []; + foreach (get_object_vars($object) as $key => $val) + { + // There are some built in keys we need to ignore for this conversion + if (! is_object($val) && ! is_array($val) && $key !== '_parent_name') + { + $array[$key] = $val; + } + } + + return $array; + } + + //-------------------------------------------------------------------- + + /** + * Object to Array + * + * Takes an object as input and converts the class variables to array key/vals + * + * @param mixed $object + * + * @return mixed + */ + protected function batchObjectToArray($object) + { + if (! is_object($object)) + { + return $object; + } + + $array = []; + $out = get_object_vars($object); + $fields = array_keys($out); + + foreach ($fields as $val) + { + // There are some built in keys we need to ignore for this conversion + if ($val !== '_parent_name') + { + $i = 0; + foreach ($out[$val] as $data) + { + $array[$i ++][$val] = $data; + } + } + } + + return $array; + } + + //-------------------------------------------------------------------- + + /** + * Is literal + * + * Determines if a string represents a literal value or a field name + * + * @param string $str + * + * @return boolean + */ + protected function isLiteral(string $str): bool + { + $str = trim($str); + + if (empty($str) || ctype_digit($str) || (string) (float) $str === $str || + in_array(strtoupper($str), ['TRUE', 'FALSE'], true) + ) + { + return true; + } + + static $_str; + + if (empty($_str)) + { + $_str = ($this->db->escapeChar !== '"') ? ['"', "'"] : ["'"]; + } + + return in_array($str[0], $_str, true); + } + + //-------------------------------------------------------------------- + + /** + * Reset Query Builder values. + * + * Publicly-visible method to reset the QB values. + * + * @return BaseBuilder + */ + public function resetQuery() + { + $this->resetSelect(); + $this->resetWrite(); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Resets the query builder values. Called by the get() function + * + * @param array $qb_reset_items An array of fields to reset + * + * @return void + */ + protected function resetRun(array $qb_reset_items) + { + foreach ($qb_reset_items as $item => $default_value) + { + $this->$item = $default_value; + } + } + + //-------------------------------------------------------------------- + + /** + * Resets the query builder values. Called by the get() function + */ + protected function resetSelect() + { + $this->resetRun([ + 'QBSelect' => [], + 'QBJoin' => [], + 'QBWhere' => [], + 'QBGroupBy' => [], + 'QBHaving' => [], + 'QBOrderBy' => [], + 'QBNoEscape' => [], + 'QBDistinct' => false, + 'QBLimit' => false, + 'QBOffset' => false, + ]); + + if (! empty($this->db)) + { + $this->db->setAliasedTables([]); + } + + // Reset QBFrom part + if (! empty($this->QBFrom)) + { + $this->from(array_shift($this->QBFrom), true); + } + } + + //-------------------------------------------------------------------- + + /** + * Resets the query builder "write" values. + * + * Called by the insert() update() insertBatch() updateBatch() and delete() functions + */ + protected function resetWrite() + { + $this->resetRun([ + 'QBSet' => [], + 'QBJoin' => [], + 'QBWhere' => [], + 'QBOrderBy' => [], + 'QBKeys' => [], + 'QBLimit' => false, + 'QBIgnore' => false, + ]); + } + + //-------------------------------------------------------------------- + + /** + * Tests whether the string has an SQL operator + * + * @param string $str + * + * @return boolean + */ + protected function hasOperator(string $str): bool + { + return (bool) preg_match('/(<|>|!|=|\sIS NULL|\sIS NOT NULL|\sEXISTS|\sBETWEEN|\sLIKE|\sIN\s*\(|\s)/i', trim($str)); + } + + // -------------------------------------------------------------------- + + /** + * Returns the SQL string operator + * + * @param string $str + * @param boolean $list + * + * @return mixed + */ + protected function getOperator(string $str, bool $list = false) + { + static $_operators; + + if (empty($_operators)) + { + $_les = ($this->db->likeEscapeStr !== '') ? '\s+' . preg_quote(trim(sprintf($this->db->likeEscapeStr, $this->db->likeEscapeChar)), '/') : ''; + $_operators = [ + '\s*(?:<|>|!)?=\s*', // =, <=, >=, != + '\s*<>?\s*', // <, <> + '\s*>\s*', // > + '\s+IS NULL', // IS NULL + '\s+IS NOT NULL', // IS NOT NULL + '\s+EXISTS\s*\(.*\)', // EXISTS(sql) + '\s+NOT EXISTS\s*\(.*\)', // NOT EXISTS(sql) + '\s+BETWEEN\s+', // BETWEEN value AND value + '\s+IN\s*\(.*\)', // IN(list) + '\s+NOT IN\s*\(.*\)', // NOT IN (list) + '\s+LIKE\s+\S.*(' . $_les . ')?', // LIKE 'expr'[ ESCAPE '%s'] + '\s+NOT LIKE\s+\S.*(' . $_les . ')?', // NOT LIKE 'expr'[ ESCAPE '%s'] + ]; + } + + return preg_match_all('/' . implode('|', $_operators) . '/i', $str, $match) ? ($list ? $match[0] : $match[0][0]) : false; + } + + // -------------------------------------------------------------------- + + /** + * Stores a bind value after ensuring that it's unique. + * While it might be nicer to have named keys for our binds array + * with PHP 7+ we get a huge memory/performance gain with indexed + * arrays instead, so lets take advantage of that here. + * + * @param string $key + * @param mixed $value + * @param boolean $escape + * + * @return string + */ + protected function setBind(string $key, $value = null, bool $escape = true): string + { + if (! array_key_exists($key, $this->binds)) + { + $this->binds[$key] = [ + $value, + $escape, + ]; + + return $key; + } + + if (! array_key_exists($key, $this->bindsKeyCount)) + { + $this->bindsKeyCount[$key] = 0; + } + $count = $this->bindsKeyCount[$key]++; + + $this->binds[$key . $count] = [ + $value, + $escape, + ]; + + return $key . $count; + } + + //-------------------------------------------------------------------- + + /** + * Returns a clone of a Base Builder with reset query builder values. + * + * @return BaseBuilder + */ + protected function cleanClone() + { + return (clone $this)->from([], true)->resetQuery(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/BaseConnection.php b/vendor/codeigniter4/framework/system/Database/BaseConnection.php new file mode 100644 index 0000000..e1c4f7a --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/BaseConnection.php @@ -0,0 +1,1883 @@ + $value) + { + if (property_exists($this, $key)) + { + $this->$key = $value; + } + } + } + + //-------------------------------------------------------------------- + + /** + * Initializes the database connection/settings. + * + * @return mixed|void + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function initialize() + { + /* If an established connection is available, then there's + * no need to connect and select the database. + * + * Depending on the database driver, conn_id can be either + * boolean TRUE, a resource or an object. + */ + if ($this->connID) + { + return; + } + + //-------------------------------------------------------------------- + + $this->connectTime = microtime(true); + + try + { + // Connect to the database and set the connection ID + $this->connID = $this->connect($this->pConnect); + } + catch (\Throwable $e) + { + log_message('error', 'Error connecting to the database: ' . $e->getMessage()); + } + + // No connection resource? Check if there is a failover else throw an error + if (! $this->connID) + { + // Check if there is a failover set + if (! empty($this->failover) && is_array($this->failover)) + { + // Go over all the failovers + foreach ($this->failover as $failover) + { + // Replace the current settings with those of the failover + foreach ($failover as $key => $val) + { + if (property_exists($this, $key)) + { + $this->$key = $val; + } + } + + try + { + // Try to connect + $this->connID = $this->connect($this->pConnect); + } + catch (\Throwable $e) + { + log_message('error', 'Error connecting to the database: ' . $e->getMessage()); + } + + // If a connection is made break the foreach loop + if ($this->connID) + { + break; + } + } + } + + // We still don't have a connection? + if (! $this->connID) + { + throw new DatabaseException('Unable to connect to the database.'); + } + } + + $this->connectDuration = microtime(true) - $this->connectTime; + } + + //-------------------------------------------------------------------- + + /** + * Connect to the database. + * + * @param boolean $persistent + * @return mixed + */ + abstract public function connect(bool $persistent = false); + + //-------------------------------------------------------------------- + + /** + * Close the database connection. + * + * @return void + */ + public function close() + { + if ($this->connID) + { + $this->_close(); + $this->connID = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Platform dependent way method for closing the connection. + * + * @return mixed + */ + abstract protected function _close(); + + //-------------------------------------------------------------------- + + /** + * Create a persistent database connection. + * + * @return mixed + */ + public function persistentConnect() + { + return $this->connect(true); + } + + //-------------------------------------------------------------------- + + /** + * Keep or establish the connection if no queries have been sent for + * a length of time exceeding the server's idle timeout. + * + * @return mixed + */ + abstract public function reconnect(); + + //-------------------------------------------------------------------- + + /** + * Returns the actual connection object. If both a 'read' and 'write' + * connection has been specified, you can pass either term in to + * get that connection. If you pass either alias in and only a single + * connection is present, it must return the sole connection. + * + * @param string|null $alias + * + * @return mixed + */ + public function getConnection(string $alias = null) + { + //@todo work with read/write connections + return $this->connID; + } + + //-------------------------------------------------------------------- + + /** + * Select a specific database table to use. + * + * @param string $databaseName + * + * @return mixed + */ + abstract public function setDatabase(string $databaseName); + + //-------------------------------------------------------------------- + + /** + * Returns the name of the current database being used. + * + * @return string + */ + public function getDatabase(): string + { + return empty($this->database) ? '' : $this->database; + } + + //-------------------------------------------------------------------- + + /** + * Set DB Prefix + * + * Set's the DB Prefix to something new without needing to reconnect + * + * @param string $prefix The prefix + * + * @return string + */ + public function setPrefix(string $prefix = ''): string + { + return $this->DBPrefix = $prefix; + } + + //-------------------------------------------------------------------- + + /** + * Returns the database prefix. + * + * @return string + */ + public function getPrefix(): string + { + return $this->DBPrefix; + } + + //-------------------------------------------------------------------- + + /** + * The name of the platform in use (MySQLi, mssql, etc) + * + * @return string + */ + public function getPlatform(): string + { + return $this->DBDriver; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string containing the version of the database being used. + * + * @return string + */ + abstract public function getVersion(): string; + + //-------------------------------------------------------------------- + + /** + * Sets the Table Aliases to use. These are typically + * collected during use of the Builder, and set here + * so queries are built correctly. + * + * @param array $aliases + * + * @return $this + */ + public function setAliasedTables(array $aliases) + { + $this->aliasedTables = $aliases; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Add a table alias to our list. + * + * @param string $table + * + * @return $this + */ + public function addTableAlias(string $table) + { + if (! in_array($table, $this->aliasedTables)) + { + $this->aliasedTables[] = $table; + } + + return $this; + } + + /** + * Executes the query against the database. + * + * @param $sql + * + * @return mixed + */ + abstract protected function execute(string $sql); + + //-------------------------------------------------------------------- + + /** + * Orchestrates a query against the database. Queries must use + * Database\Statement objects to store the query and build it. + * This method works with the cache. + * + * Should automatically handle different connections for read/write + * queries if needed. + * + * @param string $sql + * @param mixed ...$binds + * @param boolean $setEscapeFlags + * @param string $queryClass + * + * @return BaseResult|Query|false + */ + public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = 'CodeIgniter\\Database\\Query') + { + if (empty($this->connID)) + { + $this->initialize(); + } + + $resultClass = str_replace('Connection', 'Result', get_class($this)); + /** + * @var Query $query + */ + $query = new $queryClass($this); + + $query->setQuery($sql, $binds, $setEscapeFlags); + + if (! empty($this->swapPre) && ! empty($this->DBPrefix)) + { + $query->swapPrefix($this->DBPrefix, $this->swapPre); + } + + $startTime = microtime(true); + + // Always save the last query so we can use + // the getLastQuery() method. + $this->lastQuery = $query; + + // Run the query for real + if (! $this->pretend && false === ($this->resultID = $this->simpleQuery($query->getQuery()))) + { + $query->setDuration($startTime, $startTime); + + // This will trigger a rollback if transactions are being used + if ($this->transDepth !== 0) + { + $this->transStatus = false; + } + + if ($this->DBDebug) + { + // We call this function in order to roll-back queries + // if transactions are enabled. If we don't call this here + // the error message will trigger an exit, causing the + // transactions to remain in limbo. + while ($this->transDepth !== 0) + { + $transDepth = $this->transDepth; + $this->transComplete(); + + if ($transDepth === $this->transDepth) + { + log_message('error', 'Database: Failure during an automated transaction commit/rollback!'); + break; + } + } + + return false; + } + + if (! $this->pretend) + { + // Let others do something with this query. + Events::trigger('DBQuery', $query); + } + + return new $resultClass($this->connID, $this->resultID); + } + + $query->setDuration($startTime); + + if (! $this->pretend) + { + // Let others do something with this query + Events::trigger('DBQuery', $query); + } + + // If $pretend is true, then we just want to return + // the actual query object here. There won't be + // any results to return. + return $this->pretend ? $query : new $resultClass($this->connID, $this->resultID); + } + + //-------------------------------------------------------------------- + + /** + * Performs a basic query against the database. No binding or caching + * is performed, nor are transactions handled. Simply takes a raw + * query string and returns the database-specific result id. + * + * @param string $sql + * + * @return mixed + */ + public function simpleQuery(string $sql) + { + if (empty($this->connID)) + { + $this->initialize(); + } + + return $this->execute($sql); + } + + //-------------------------------------------------------------------- + + /** + * Disable Transactions + * + * This permits transactions to be disabled at run-time. + * + * @return void + */ + public function transOff() + { + $this->transEnabled = false; + } + + //-------------------------------------------------------------------- + + /** + * Enable/disable Transaction Strict Mode + * + * When strict mode is enabled, if you are running multiple groups of + * transactions, if one group fails all subsequent groups will be + * rolled back. + * + * If strict mode is disabled, each group is treated autonomously, + * meaning a failure of one group will not affect any others + * + * @param boolean $mode = true + * + * @return $this + */ + public function transStrict(bool $mode = true) + { + $this->transStrict = $mode; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Start Transaction + * + * @param boolean $test_mode = FALSE + * @return boolean + */ + public function transStart(bool $test_mode = false): bool + { + if (! $this->transEnabled) + { + return false; + } + + return $this->transBegin($test_mode); + } + + //-------------------------------------------------------------------- + + /** + * Complete Transaction + * + * @return boolean + */ + public function transComplete(): bool + { + if (! $this->transEnabled) + { + return false; + } + + // The query() function will set this flag to FALSE in the event that a query failed + if ($this->transStatus === false || $this->transFailure === true) + { + $this->transRollback(); + + // If we are NOT running in strict mode, we will reset + // the _trans_status flag so that subsequent groups of + // transactions will be permitted. + if ($this->transStrict === false) + { + $this->transStatus = true; + } + + // log_message('debug', 'DB Transaction Failure'); + return false; + } + + return $this->transCommit(); + } + + //-------------------------------------------------------------------- + + /** + * Lets you retrieve the transaction flag to determine if it has failed + * + * @return boolean + */ + public function transStatus(): bool + { + return $this->transStatus; + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @param boolean $test_mode + * @return boolean + */ + public function transBegin(bool $test_mode = false): bool + { + if (! $this->transEnabled) + { + return false; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->transDepth > 0) + { + $this->transDepth ++; + return true; + } + + if (empty($this->connID)) + { + $this->initialize(); + } + + // Reset the transaction failure flag. + // If the $test_mode flag is set to TRUE transactions will be rolled back + // even if the queries produce a successful result. + $this->transFailure = ($test_mode === true); + + if ($this->_transBegin()) + { + $this->transDepth ++; + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + public function transCommit(): bool + { + if (! $this->transEnabled || $this->transDepth === 0) + { + return false; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->transDepth > 1 || $this->_transCommit()) + { + $this->transDepth --; + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + public function transRollback(): bool + { + if (! $this->transEnabled || $this->transDepth === 0) + { + return false; + } + // When transactions are nested we only begin/commit/rollback the outermost ones + elseif ($this->transDepth > 1 || $this->_transRollback()) + { + $this->transDepth --; + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return boolean + */ + abstract protected function _transBegin(): bool; + + //-------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + abstract protected function _transCommit(): bool; + + //-------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + abstract protected function _transRollback(): bool; + + //-------------------------------------------------------------------- + + /** + * Returns an instance of the query builder for this connection. + * + * @param string|array $tableName + * + * @return BaseBuilder + * @throws DatabaseException + */ + public function table($tableName) + { + if (empty($tableName)) + { + throw new DatabaseException('You must set the database table to be used with your query.'); + } + + $className = str_replace('Connection', 'Builder', get_class($this)); + + return new $className($tableName, $this); + } + + //-------------------------------------------------------------------- + + /** + * Creates a prepared statement with the database that can then + * be used to execute multiple statements against. Within the + * closure, you would build the query in any normal way, though + * the Query Builder is the expected manner. + * + * Example: + * $stmt = $db->prepare(function($db) + * { + * return $db->table('users') + * ->where('id', 1) + * ->get(); + * }) + * + * @param \Closure $func + * @param array $options Passed to the prepare() method + * + * @return BasePreparedQuery|null + */ + public function prepare(\Closure $func, array $options = []) + { + if (empty($this->connID)) + { + $this->initialize(); + } + + $this->pretend(); + + $sql = $func($this); + + $this->pretend(false); + + if ($sql instanceof QueryInterface) + { + $sql = $sql->getOriginalQuery(); + } + + $class = str_ireplace('Connection', 'PreparedQuery', get_class($this)); + /** + * @var BasePreparedQuery $class + */ + $class = new $class($this); + + return $class->prepare($sql, $options); + } + + //-------------------------------------------------------------------- + + /** + * Returns the last query's statement object. + * + * @return mixed + */ + public function getLastQuery() + { + return $this->lastQuery; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string representation of the last query's statement object. + * + * @return string + */ + public function showLastQuery(): string + { + return (string) $this->lastQuery; + } + + //-------------------------------------------------------------------- + + /** + * Returns the time we started to connect to this database in + * seconds with microseconds. + * + * Used by the Debug Toolbar's timeline. + * + * @return float|null + */ + public function getConnectStart(): ?float + { + return $this->connectTime; + } + + //-------------------------------------------------------------------- + + /** + * Returns the number of seconds with microseconds that it took + * to connect to the database. + * + * Used by the Debug Toolbar's timeline. + * + * @param integer $decimals + * + * @return string + */ + public function getConnectDuration(int $decimals = 6): string + { + return number_format($this->connectDuration, $decimals); + } + + //-------------------------------------------------------------------- + + /** + * Protect Identifiers + * + * This function is used extensively by the Query Builder class, and by + * a couple functions in this class. + * It takes a column or table name (optionally with an alias) and inserts + * the table prefix onto it. Some logic is necessary in order to deal with + * column names that include the path. Consider a query like this: + * + * SELECT hostname.database.table.column AS c FROM hostname.database.table + * + * Or a query with aliasing: + * + * SELECT m.member_id, m.member_name FROM members AS m + * + * Since the column name can include up to four segments (host, DB, table, column) + * or also have an alias prefix, we need to do a bit of work to figure this out and + * insert the table prefix (if it exists) in the proper position, and escape only + * the correct identifiers. + * + * @param string|array $item + * @param boolean $prefixSingle + * @param boolean $protectIdentifiers + * @param boolean $fieldExists + * + * @return string|array + */ + public function protectIdentifiers($item, bool $prefixSingle = false, bool $protectIdentifiers = null, bool $fieldExists = true) + { + if (! is_bool($protectIdentifiers)) + { + $protectIdentifiers = $this->protectIdentifiers; + } + + if (is_array($item)) + { + $escaped_array = []; + foreach ($item as $k => $v) + { + $escaped_array[$this->protectIdentifiers($k)] = $this->protectIdentifiers($v, $prefixSingle, $protectIdentifiers, $fieldExists); + } + + return $escaped_array; + } + + // This is basically a bug fix for queries that use MAX, MIN, etc. + // If a parenthesis is found we know that we do not need to + // escape the data or add a prefix. There's probably a more graceful + // way to deal with this, but I'm not thinking of it + // + // Added exception for single quotes as well, we don't want to alter + // literal strings. + if (strcspn($item, "()'") !== strlen($item)) + { + return $item; + } + + // Convert tabs or multiple spaces into single spaces + $item = preg_replace('/\s+/', ' ', trim($item)); + + // If the item has an alias declaration we remove it and set it aside. + // Note: strripos() is used in order to support spaces in table names + if ($offset = strripos($item, ' AS ')) + { + $alias = ($protectIdentifiers) ? substr($item, $offset, 4) . $this->escapeIdentifiers(substr($item, $offset + 4)) : substr($item, $offset); + $item = substr($item, 0, $offset); + } + elseif ($offset = strrpos($item, ' ')) + { + $alias = ($protectIdentifiers) ? ' ' . $this->escapeIdentifiers(substr($item, $offset + 1)) : substr($item, $offset); + $item = substr($item, 0, $offset); + } + else + { + $alias = ''; + } + + // Break the string apart if it contains periods, then insert the table prefix + // in the correct location, assuming the period doesn't indicate that we're dealing + // with an alias. While we're at it, we will escape the components + if (strpos($item, '.') !== false) + { + $parts = explode('.', $item); + + // Does the first segment of the exploded item match + // one of the aliases previously identified? If so, + // we have nothing more to do other than escape the item + // + // NOTE: The ! empty() condition prevents this method + // from breaking when QB isn't enabled. + if (! empty($this->aliasedTables) && in_array($parts[0], $this->aliasedTables)) + { + if ($protectIdentifiers === true) + { + foreach ($parts as $key => $val) + { + if (! in_array($val, $this->reservedIdentifiers)) + { + $parts[$key] = $this->escapeIdentifiers($val); + } + } + + $item = implode('.', $parts); + } + + return $item . $alias; + } + + // Is there a table prefix defined in the config file? If not, no need to do anything + if ($this->DBPrefix !== '') + { + // We now add the table prefix based on some logic. + // Do we have 4 segments (hostname.database.table.column)? + // If so, we add the table prefix to the column name in the 3rd segment. + if (isset($parts[3])) + { + $i = 2; + } + // Do we have 3 segments (database.table.column)? + // If so, we add the table prefix to the column name in 2nd position + elseif (isset($parts[2])) + { + $i = 1; + } + // Do we have 2 segments (table.column)? + // If so, we add the table prefix to the column name in 1st segment + else + { + $i = 0; + } + + // This flag is set when the supplied $item does not contain a field name. + // This can happen when this function is being called from a JOIN. + if ($fieldExists === false) + { + $i++; + } + + // Verify table prefix and replace if necessary + if ($this->swapPre !== '' && strpos($parts[$i], $this->swapPre) === 0) + { + $parts[$i] = preg_replace('/^' . $this->swapPre . '(\S+?)/', $this->DBPrefix . '\\1', $parts[$i]); + } + // We only add the table prefix if it does not already exist + elseif (strpos($parts[$i], $this->DBPrefix) !== 0) + { + $parts[$i] = $this->DBPrefix . $parts[$i]; + } + + // Put the parts back together + $item = implode('.', $parts); + } + + if ($protectIdentifiers === true) + { + $item = $this->escapeIdentifiers($item); + } + + return $item . $alias; + } + + // In some cases, especially 'from', we end up running through + // protect_identifiers twice. This algorithm won't work when + // it contains the escapeChar so strip it out. + $item = trim($item, $this->escapeChar); + + // Is there a table prefix? If not, no need to insert it + if ($this->DBPrefix !== '') + { + // Verify table prefix and replace if necessary + if ($this->swapPre !== '' && strpos($item, $this->swapPre) === 0) + { + $item = preg_replace('/^' . $this->swapPre . '(\S+?)/', $this->DBPrefix . '\\1', $item); + } + // Do we prefix an item with no segments? + elseif ($prefixSingle === true && strpos($item, $this->DBPrefix) !== 0) + { + $item = $this->DBPrefix . $item; + } + } + + if ($protectIdentifiers === true && ! in_array($item, $this->reservedIdentifiers)) + { + $item = $this->escapeIdentifiers($item); + } + + return $item . $alias; + } + + //-------------------------------------------------------------------- + + /** + * Escape the SQL Identifiers + * + * This function escapes column and table names + * + * @param mixed $item + * + * @return mixed + */ + public function escapeIdentifiers($item) + { + if ($this->escapeChar === '' || empty($item) || in_array($item, $this->reservedIdentifiers)) + { + return $item; + } + elseif (is_array($item)) + { + foreach ($item as $key => $value) + { + $item[$key] = $this->escapeIdentifiers($value); + } + + return $item; + } + // Avoid breaking functions and literal values inside queries + elseif (ctype_digit($item) || $item[0] === "'" || ( $this->escapeChar !== '"' && $item[0] === '"') || + strpos($item, '(') !== false + ) + { + return $item; + } + + static $preg_ec = []; + + if (empty($preg_ec)) + { + if (is_array($this->escapeChar)) + { + $preg_ec = [ + preg_quote($this->escapeChar[0], '/'), + preg_quote($this->escapeChar[1], '/'), + $this->escapeChar[0], + $this->escapeChar[1], + ]; + } + else + { + $preg_ec[0] = $preg_ec[1] = preg_quote($this->escapeChar, '/'); + $preg_ec[2] = $preg_ec[3] = $this->escapeChar; + } + } + + foreach ($this->reservedIdentifiers as $id) + { + if (strpos($item, '.' . $id) !== false) + { + return preg_replace('/' . $preg_ec[0] . '?([^' . $preg_ec[1] . '\.]+)' . $preg_ec[1] . '?\./i', $preg_ec[2] . '$1' . $preg_ec[3] . '.', $item); + } + } + + return preg_replace('/' . $preg_ec[0] . '?([^' . $preg_ec[1] . '\.]+)' . $preg_ec[1] . '?(\.)?/i', $preg_ec[2] . '$1' . $preg_ec[3] . '$2', $item); + } + + //-------------------------------------------------------------------- + + /** + * DB Prefix + * + * Prepends a database prefix if one exists in configuration + * + * @param string $table the table + * + * @return string + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function prefixTable(string $table = ''): string + { + if ($table === '') + { + throw new DatabaseException('A table name is required for that operation.'); + } + + return $this->DBPrefix . $table; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of rows affected by this query. + * + * @return mixed + */ + abstract public function affectedRows(): int; + + //-------------------------------------------------------------------- + + /** + * "Smart" Escape String + * + * Escapes data based on type. + * Sets boolean and null types + * + * @param mixed $str + * + * @return mixed + */ + public function escape($str) + { + if (is_array($str)) + { + return array_map([&$this, 'escape'], $str); + } + else if (is_string($str) || ( is_object($str) && method_exists($str, '__toString'))) + { + return "'" . $this->escapeString($str) . "'"; + } + else if (is_bool($str)) + { + return ($str === false) ? 0 : 1; + } + else if (is_numeric($str) && $str < 0) + { + return "'{$str}'"; + } + else if ($str === null) + { + return 'NULL'; + } + + return $str; + } + + //-------------------------------------------------------------------- + + /** + * Escape String + * + * @param string|string[] $str Input string + * @param boolean $like Whether or not the string will be used in a LIKE condition + * @return string|string[] + */ + public function escapeString($str, bool $like = false) + { + if (is_array($str)) + { + foreach ($str as $key => $val) + { + $str[$key] = $this->escapeString($val, $like); + } + + return $str; + } + + $str = $this->_escapeString($str); + + // escape LIKE condition wildcards + if ($like === true) + { + return str_replace([ + $this->likeEscapeChar, + '%', + '_', + ], [ + $this->likeEscapeChar . $this->likeEscapeChar, + $this->likeEscapeChar . '%', + $this->likeEscapeChar . '_', + ], $str + ); + } + + return $str; + } + + //-------------------------------------------------------------------- + + /** + * Escape LIKE String + * + * Calls the individual driver for platform + * specific escaping for LIKE conditions + * + * @param string|string[] + * @return string|string[] + */ + public function escapeLikeString($str) + { + return $this->escapeString($str, true); + } + + //-------------------------------------------------------------------- + + /** + * Platform independent string escape. + * + * Will likely be overridden in child classes. + * + * @param string $str + * + * @return string + */ + protected function _escapeString(string $str): string + { + return str_replace("'", "''", remove_invisible_characters($str, false)); + } + + //-------------------------------------------------------------------- + + /** + * This function enables you to call PHP database functions that are not natively included + * in CodeIgniter, in a platform independent manner. + * + * @param string $functionName + * @param array ...$params + * + * @return boolean + * @throws DatabaseException + */ + public function callFunction(string $functionName, ...$params): bool + { + $driver = ($this->DBDriver === 'postgre' ? 'pg' : strtolower($this->DBDriver)) . '_'; + + if (false === strpos($driver, $functionName)) + { + $functionName = $driver . $functionName; + } + + if (! function_exists($functionName)) + { + if ($this->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + return $functionName(...$params); + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // META Methods + //-------------------------------------------------------------------- + + /** + * Returns an array of table names + * + * @param boolean $constrainByPrefix = FALSE + * @return boolean|array + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function listTables(bool $constrainByPrefix = false) + { + // Is there a cached result? + if (isset($this->dataCache['table_names']) && $this->dataCache['table_names']) + { + return $constrainByPrefix ? + preg_grep("/^{$this->DBPrefix}/", $this->dataCache['table_names']) + : $this->dataCache['table_names']; + } + + if (false === ($sql = $this->_listTables($constrainByPrefix))) + { + if ($this->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + return false; + } + + $this->dataCache['table_names'] = []; + $query = $this->query($sql); + + foreach ($query->getResultArray() as $row) + { + // Do we know from which column to get the table name? + if (! isset($key)) + { + if (isset($row['table_name'])) + { + $key = 'table_name'; + } + elseif (isset($row['TABLE_NAME'])) + { + $key = 'TABLE_NAME'; + } + else + { + /* We have no other choice but to just get the first element's key. + * Due to array_shift() accepting its argument by reference, if + * E_STRICT is on, this would trigger a warning. So we'll have to + * assign it first. + */ + $key = array_keys($row); + $key = array_shift($key); + } + } + + $this->dataCache['table_names'][] = $row[$key]; + } + + return $this->dataCache['table_names']; + } + + //-------------------------------------------------------------------- + + /** + * Determine if a particular table exists + * + * @param string $tableName + * @return boolean + */ + public function tableExists(string $tableName): bool + { + return in_array($this->protectIdentifiers($tableName, true, false, false), $this->listTables()); + } + + //-------------------------------------------------------------------- + + /** + * Fetch Field Names + * + * @param string $table Table name + * + * @return array|false + * @throws DatabaseException + */ + public function getFieldNames(string $table) + { + // Is there a cached result? + if (isset($this->dataCache['field_names'][$table])) + { + return $this->dataCache['field_names'][$table]; + } + + if (empty($this->connID)) + { + $this->initialize(); + } + + if (false === ($sql = $this->_listColumns($table))) + { + if ($this->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + return false; + } + + $query = $this->query($sql); + $this->dataCache['field_names'][$table] = []; + + foreach ($query->getResultArray() as $row) + { + // Do we know from where to get the column's name? + if (! isset($key)) + { + if (isset($row['column_name'])) + { + $key = 'column_name'; + } + elseif (isset($row['COLUMN_NAME'])) + { + $key = 'COLUMN_NAME'; + } + else + { + // We have no other choice but to just get the first element's key. + $key = key($row); + } + } + + $this->dataCache['field_names'][$table][] = $row[$key]; + } + + return $this->dataCache['field_names'][$table]; + } + + //-------------------------------------------------------------------- + + /** + * Determine if a particular field exists + * + * @param string $fieldName + * @param string $tableName + * @return boolean + */ + public function fieldExists(string $fieldName, string $tableName): bool + { + return in_array($fieldName, $this->getFieldNames($tableName)); + } + + //-------------------------------------------------------------------- + + /** + * Returns an object with field data + * + * @param string $table the table name + * @return array|false + */ + public function getFieldData(string $table) + { + $fields = $this->_fieldData($this->protectIdentifiers($table, true, false, false)); + + return $fields ?? false; + } + + //-------------------------------------------------------------------- + + /** + * Returns an object with key data + * + * @param string $table the table name + * @return array|false + */ + public function getIndexData(string $table) + { + $fields = $this->_indexData($this->protectIdentifiers($table, true, false, false)); + + return $fields ?? false; + } + + //-------------------------------------------------------------------- + + /** + * Returns an object with foreign key data + * + * @param string $table the table name + * @return array|false + */ + public function getForeignKeyData(string $table) + { + $fields = $this->_foreignKeyData($this->protectIdentifiers($table, true, false, false)); + + return $fields ?? false; + } + + //-------------------------------------------------------------------- + + /** + * Disables foreign key checks temporarily. + */ + public function disableForeignKeyChecks() + { + $sql = $this->_disableForeignKeyChecks(); + + return $this->query($sql); + } + + //-------------------------------------------------------------------- + + /** + * Enables foreign key checks temporarily. + */ + public function enableForeignKeyChecks() + { + $sql = $this->_enableForeignKeyChecks(); + + return $this->query($sql); + } + + //-------------------------------------------------------------------- + + /** + * Allows the engine to be set into a mode where queries are not + * actually executed, but they are still generated, timed, etc. + * + * This is primarily used by the prepared query functionality. + * + * @param boolean $pretend + * + * @return $this + */ + public function pretend(bool $pretend = true) + { + $this->pretend = $pretend; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Empties our data cache. Especially helpful during testing. + * + * @return $this + */ + public function resetDataCache() + { + $this->dataCache = []; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last error code and message. + * + * Must return an array with keys 'code' and 'message': + * + * return ['code' => null, 'message' => null); + * + * @return array + */ + abstract public function error(): array; + + //-------------------------------------------------------------------- + + /** + * Insert ID + * + * @return integer + */ + abstract public function insertID(): int; + + //-------------------------------------------------------------------- + + /** + * Generates the SQL for listing tables in a platform-dependent manner. + * + * @param boolean $constrainByPrefix + * + * @return string + */ + abstract protected function _listTables(bool $constrainByPrefix = false): string; + + //-------------------------------------------------------------------- + + /** + * Generates a platform-specific query string so that the column names can be fetched. + * + * @param string $table + * + * @return string + */ + abstract protected function _listColumns(string $table = ''): string; + + //-------------------------------------------------------------------- + + /** + * Platform-specific field data information. + * + * @param string $table + * @see getFieldData() + * @return array + */ + abstract protected function _fieldData(string $table): array; + + //-------------------------------------------------------------------- + + /** + * Platform-specific index data. + * + * @param string $table + * @see getIndexData() + * @return array + */ + abstract protected function _indexData(string $table): array; + + //-------------------------------------------------------------------- + + /** + * Platform-specific foreign keys data. + * + * @param string $table + * @see getForeignKeyData() + * @return array + */ + abstract protected function _foreignKeyData(string $table): array; + + //-------------------------------------------------------------------- + + /** + * Accessor for properties if they exist. + * + * @param string $key + * + * @return mixed + */ + public function __get(string $key) + { + if (property_exists($this, $key)) + { + return $this->$key; + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Checker for properties existence. + * + * @param string $key + * + * @return boolean + */ + public function __isset(string $key): bool + { + return property_exists($this, $key); + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Database/BasePreparedQuery.php b/vendor/codeigniter4/framework/system/Database/BasePreparedQuery.php new file mode 100644 index 0000000..247d68c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/BasePreparedQuery.php @@ -0,0 +1,274 @@ +db = &$db; + } + + //-------------------------------------------------------------------- + + /** + * Prepares the query against the database, and saves the connection + * info necessary to execute the query later. + * + * NOTE: This version is based on SQL code. Child classes should + * override this method. + * + * @param string $sql + * @param array $options Passed to the connection's prepare statement. + * @param string $queryClass + * + * @return mixed + */ + public function prepare(string $sql, array $options = [], string $queryClass = 'CodeIgniter\\Database\\Query') + { + // We only supports positional placeholders (?) + // in order to work with the execute method below, so we + // need to replace our named placeholders (:name) + $sql = preg_replace('/:[^\s,)]+/', '?', $sql); + + /** + * @var \CodeIgniter\Database\Query $query + */ + $query = new $queryClass($this->db); + + $query->setQuery($sql); + + if (! empty($this->db->swapPre) && ! empty($this->db->DBPrefix)) + { + $query->swapPrefix($this->db->DBPrefix, $this->db->swapPre); + } + + $this->query = $query; + + return $this->_prepare($query->getOriginalQuery(), $options); + } + + //-------------------------------------------------------------------- + + /** + * The database-dependent portion of the prepare statement. + * + * @param string $sql + * @param array $options Passed to the connection's prepare statement. + * + * @return mixed + */ + abstract public function _prepare(string $sql, array $options = []); + + //-------------------------------------------------------------------- + + /** + * Takes a new set of data and runs it against the currently + * prepared query. Upon success, will return a Results object. + * + * @param array $data + * + * @return ResultInterface + */ + public function execute(...$data) + { + // Execute the Query. + $startTime = microtime(true); + + $result = $this->_execute($data); + + // Update our query object + $query = clone $this->query; + $query->setBinds($data); + + $query->setDuration($startTime); + + // Let others do something with this query + Events::trigger('DBQuery', $query); + + // Return a result object + $resultClass = str_replace('PreparedQuery', 'Result', get_class($this)); + + $resultID = $this->_getResult(); + + return new $resultClass($this->db->connID, $resultID); + } + + //-------------------------------------------------------------------- + + /** + * The database dependant version of the execute method. + * + * @param array $data + * + * @return boolean + */ + abstract public function _execute(array $data): bool; + + //-------------------------------------------------------------------- + + /** + * Returns the result object for the prepared query. + * + * @return mixed + */ + abstract public function _getResult(); + + //-------------------------------------------------------------------- + + /** + * Explicitly closes the statement. + * + * @return null|void + */ + public function close() + { + if (! is_object($this->statement)) + { + return; + } + + $this->statement->close(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the SQL that has been prepared. + * + * @return string + */ + public function getQueryString(): string + { + if (! $this->query instanceof QueryInterface) + { + throw new \BadMethodCallException('Cannot call getQueryString on a prepared query until after the query has been prepared.'); + } + + return $this->query->getQuery(); + } + + //-------------------------------------------------------------------- + + /** + * A helper to determine if any error exists. + * + * @return boolean + */ + public function hasError(): bool + { + return ! empty($this->errorString); + } + + //-------------------------------------------------------------------- + + /** + * Returns the error code created while executing this statement. + * + * @return integer + */ + public function getErrorCode(): int + { + return $this->errorCode; + } + + //-------------------------------------------------------------------- + + /** + * Returns the error message created while executing this statement. + * + * @return string + */ + public function getErrorMessage(): string + { + return $this->errorString; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/BaseResult.php b/vendor/codeigniter4/framework/system/Database/BaseResult.php new file mode 100644 index 0000000..5c6500e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/BaseResult.php @@ -0,0 +1,631 @@ +connID = $connID; + $this->resultID = $resultID; + } + + //-------------------------------------------------------------------- + + /** + * Retrieve the results of the query. Typically an array of + * individual data rows, which can be either an 'array', an + * 'object', or a custom class name. + * + * @param string $type The row type. Either 'array', 'object', or a class name to use + * + * @return array + */ + public function getResult(string $type = 'object'): array + { + if ($type === 'array') + { + return $this->getResultArray(); + } + elseif ($type === 'object') + { + return $this->getResultObject(); + } + + return $this->getCustomResultObject($type); + } + + //-------------------------------------------------------------------- + + /** + * Returns the results as an array of custom objects. + * + * @param string $className The name of the class to use. + * + * @return mixed + */ + public function getCustomResultObject(string $className) + { + if (isset($this->customResultObject[$className])) + { + return $this->customResultObject[$className]; + } + + if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0) + { + return []; + } + + // Don't fetch the result set again if we already have it + $_data = null; + if (($c = count($this->resultArray)) > 0) + { + $_data = 'resultArray'; + } + elseif (($c = count($this->resultObject)) > 0) + { + $_data = 'resultObject'; + } + + if ($_data !== null) + { + for ($i = 0; $i < $c; $i ++) + { + $this->customResultObject[$className][$i] = new $className(); + + foreach ($this->{$_data}[$i] as $key => $value) + { + $this->customResultObject[$className][$i]->$key = $value; + } + } + + return $this->customResultObject[$className]; + } + + is_null($this->rowData) || $this->dataSeek(); + $this->customResultObject[$className] = []; + + while ($row = $this->fetchObject($className)) + { + if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) + { + $row->syncOriginal(); + } + + $this->customResultObject[$className][] = $row; + } + + return $this->customResultObject[$className]; + } + + //-------------------------------------------------------------------- + + /** + * Returns the results as an array of arrays. + * + * If no results, an empty array is returned. + * + * @return array + */ + public function getResultArray(): array + { + if (! empty($this->resultArray)) + { + return $this->resultArray; + } + + // In the event that query caching is on, the result_id variable + // will not be a valid resource so we'll simply return an empty + // array. + if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0) + { + return []; + } + + if ($this->resultObject) + { + foreach ($this->resultObject as $row) + { + $this->resultArray[] = (array) $row; + } + + return $this->resultArray; + } + + is_null($this->rowData) || $this->dataSeek(); + while ($row = $this->fetchAssoc()) + { + $this->resultArray[] = $row; + } + + return $this->resultArray; + } + + //-------------------------------------------------------------------- + + /** + * Returns the results as an array of objects. + * + * If no results, an empty array is returned. + * + * @return array + */ + public function getResultObject(): array + { + if (! empty($this->resultObject)) + { + return $this->resultObject; + } + + // In the event that query caching is on, the result_id variable + // will not be a valid resource so we'll simply return an empty + // array. + if (is_bool($this->resultID) || ! $this->resultID || $this->numRows === 0) + { + return []; + } + + if ($this->resultArray) + { + foreach ($this->resultArray as $row) + { + $this->resultObject[] = (object) $row; + } + + return $this->resultObject; + } + + is_null($this->rowData) || $this->dataSeek(); + while ($row = $this->fetchObject()) + { + if (! is_subclass_of($row, Entity::class) && method_exists($row, 'syncOriginal')) + { + $row->syncOriginal(); + } + + $this->resultObject[] = $row; + } + + return $this->resultObject; + } + + //-------------------------------------------------------------------- + + /** + * Wrapper object to return a row as either an array, an object, or + * a custom class. + * + * If row doesn't exist, returns null. + * + * @param mixed $n The index of the results to return + * @param string $type The type of result object. 'array', 'object' or class name. + * + * @return mixed + */ + public function getRow($n = 0, string $type = 'object') + { + if (! is_numeric($n)) + { + // We cache the row data for subsequent uses + is_array($this->rowData) || $this->rowData = $this->getRowArray(); + + // array_key_exists() instead of isset() to allow for NULL values + if (empty($this->rowData) || ! array_key_exists($n, $this->rowData)) + { + return null; + } + + return $this->rowData[$n]; + } + + if ($type === 'object') + { + return $this->getRowObject($n); + } + elseif ($type === 'array') + { + return $this->getRowArray($n); + } + + return $this->getCustomRowObject($n, $type); + } + + //-------------------------------------------------------------------- + + /** + * Returns a row as a custom class instance. + * + * If row doesn't exists, returns null. + * + * @param integer $n + * @param string $className + * + * @return mixed + */ + public function getCustomRowObject(int $n, string $className) + { + isset($this->customResultObject[$className]) || $this->getCustomResultObject($className); + + if (empty($this->customResultObject[$className])) + { + return null; + } + + if ($n !== $this->currentRow && isset($this->customResultObject[$className][$n])) + { + $this->currentRow = $n; + } + + return $this->customResultObject[$className][$this->currentRow]; + } + + //-------------------------------------------------------------------- + + /** + * Returns a single row from the results as an array. + * + * If row doesn't exist, returns null. + * + * @param integer $n + * + * @return mixed + */ + public function getRowArray(int $n = 0) + { + $result = $this->getResultArray(); + if (empty($result)) + { + return null; + } + + if ($n !== $this->currentRow && isset($result[$n])) + { + $this->currentRow = $n; + } + + return $result[$this->currentRow]; + } + + //-------------------------------------------------------------------- + + /** + * Returns a single row from the results as an object. + * + * If row doesn't exist, returns null. + * + * @param integer $n + * + * @return mixed + */ + public function getRowObject(int $n = 0) + { + $result = $this->getResultObject(); + if (empty($result)) + { + return null; + } + + if ($n !== $this->customResultObject && isset($result[$n])) + { + $this->currentRow = $n; + } + + return $result[$this->currentRow]; + } + + //-------------------------------------------------------------------- + + /** + * Assigns an item into a particular column slot. + * + * @param mixed $key + * @param mixed $value + * + * @return mixed + */ + public function setRow($key, $value = null) + { + // We cache the row data for subsequent uses + if (! is_array($this->rowData)) + { + $this->rowData = $this->getRowArray(); + } + + if (is_array($key)) + { + foreach ($key as $k => $v) + { + $this->rowData[$k] = $v; + } + + return; + } + + if ($key !== '' && $value !== null) + { + $this->rowData[$key] = $value; + } + } + + //-------------------------------------------------------------------- + + /** + * Returns the "first" row of the current results. + * + * @param string $type + * + * @return mixed + */ + public function getFirstRow(string $type = 'object') + { + $result = $this->getResult($type); + + return (empty($result)) ? null : $result[0]; + } + + //-------------------------------------------------------------------- + + /** + * Returns the "last" row of the current results. + * + * @param string $type + * + * @return mixed + */ + public function getLastRow(string $type = 'object') + { + $result = $this->getResult($type); + + return (empty($result)) ? null : $result[count($result) - 1]; + } + + //-------------------------------------------------------------------- + + /** + * Returns the "next" row of the current results. + * + * @param string $type + * + * @return mixed + */ + public function getNextRow(string $type = 'object') + { + $result = $this->getResult($type); + if (empty($result)) + { + return null; + } + + return isset($result[$this->currentRow + 1]) ? $result[++ $this->currentRow] : null; + } + + //-------------------------------------------------------------------- + + /** + * Returns the "previous" row of the current results. + * + * @param string $type + * + * @return mixed + */ + public function getPreviousRow(string $type = 'object') + { + $result = $this->getResult($type); + if (empty($result)) + { + return null; + } + + if (isset($result[$this->currentRow - 1])) + { + -- $this->currentRow; + } + + return $result[$this->currentRow]; + } + + //-------------------------------------------------------------------- + + /** + * Returns an unbuffered row and move the pointer to the next row. + * + * @param string $type + * + * @return mixed + */ + public function getUnbufferedRow(string $type = 'object') + { + if ($type === 'array') + { + return $this->fetchAssoc(); + } + elseif ($type === 'object') + { + return $this->fetchObject(); + } + + return $this->fetchObject($type); + } + + //-------------------------------------------------------------------- + + /** + * Gets the number of fields in the result set. + * + * @return integer + */ + abstract public function getFieldCount(): int; + + //-------------------------------------------------------------------- + + /** + * Generates an array of column names in the result set. + * + * @return array + */ + abstract public function getFieldNames(): array; + + //-------------------------------------------------------------------- + + /** + * Generates an array of objects representing field meta-data. + * + * @return array + */ + abstract public function getFieldData(): array; + + //-------------------------------------------------------------------- + + /** + * Frees the current result. + * + * @return void + */ + abstract public function freeResult(); + + //-------------------------------------------------------------------- + + /** + * Moves the internal pointer to the desired offset. This is called + * internally before fetching results to make sure the result set + * starts at zero. + * + * @param integer $n + * + * @return mixed + */ + abstract public function dataSeek(int $n = 0); + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an array. + * + * Overridden by driver classes. + * + * @return mixed + */ + abstract protected function fetchAssoc(); + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an object. + * + * Overridden by child classes. + * + * @param string $className + * + * @return object + */ + abstract protected function fetchObject(string $className = 'stdClass'); + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/BaseUtils.php b/vendor/codeigniter4/framework/system/Database/BaseUtils.php new file mode 100644 index 0000000..e9a4dd6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/BaseUtils.php @@ -0,0 +1,423 @@ +db = & $db; + } + + //-------------------------------------------------------------------- + + /** + * List databases + * + * @return array|boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function listDatabases() + { + // Is there a cached result? + if (isset($this->db->dataCache['db_names'])) + { + return $this->db->dataCache['db_names']; + } + elseif ($this->listDatabases === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unsupported feature of the database platform you are using.'); + } + return false; + } + + $this->db->dataCache['db_names'] = []; + + $query = $this->db->query($this->listDatabases); + if ($query === false) + { + return $this->db->dataCache['db_names']; + } + + for ($i = 0, $query = $query->getResultArray(), $c = count($query); $i < $c; $i ++) + { + $this->db->dataCache['db_names'][] = current($query[$i]); + } + + return $this->db->dataCache['db_names']; + } + + //-------------------------------------------------------------------- + + /** + * Determine if a particular database exists + * + * @param string $database_name + * @return boolean + */ + public function databaseExists(string $database_name): bool + { + return in_array($database_name, $this->listDatabases()); + } + + //-------------------------------------------------------------------- + + /** + * Optimize Table + * + * @param string $table_name + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function optimizeTable(string $table_name) + { + if ($this->optimizeTable === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unsupported feature of the database platform you are using.'); + } + return false; + } + + $query = $this->db->query(sprintf($this->optimizeTable, $this->db->escapeIdentifiers($table_name))); + if ($query !== false) + { + $query = $query->getResultArray(); + return current($query); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Optimize Database + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function optimizeDatabase() + { + if ($this->optimizeTable === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unsupported feature of the database platform you are using.'); + } + return false; + } + + $result = []; + foreach ($this->db->listTables() as $table_name) + { + $res = $this->db->query(sprintf($this->optimizeTable, $this->db->escapeIdentifiers($table_name))); + if (is_bool($res)) + { + return $res; + } + + // Build the result array... + + $res = $res->getResultArray(); + + // Postgre & SQLite3 returns empty array + if (empty($res)) + { + $key = $table_name; + } + else + { + $res = current($res); + $key = str_replace($this->db->database . '.', '', current($res)); + $keys = array_keys($res); + unset($res[$keys[0]]); + } + + $result[$key] = $res; + } + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Repair Table + * + * @param string $table_name + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function repairTable(string $table_name) + { + if ($this->repairTable === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unsupported feature of the database platform you are using.'); + } + return false; + } + + $query = $this->db->query(sprintf($this->repairTable, $this->db->escapeIdentifiers($table_name))); + if (is_bool($query)) + { + return $query; + } + + $query = $query->getResultArray(); + return current($query); + } + + //-------------------------------------------------------------------- + + /** + * Generate CSV from a query result object + * + * @param ResultInterface $query Query result object + * @param string $delim Delimiter (default: ,) + * @param string $newline Newline character (default: \n) + * @param string $enclosure Enclosure (default: ") + * + * @return string + */ + public function getCSVFromResult(ResultInterface $query, string $delim = ',', string $newline = "\n", string $enclosure = '"') + { + $out = ''; + // First generate the headings from the table column names + foreach ($query->getFieldNames() as $name) + { + $out .= $enclosure . str_replace($enclosure, $enclosure . $enclosure, $name) . $enclosure . $delim; + } + + $out = substr($out, 0, -strlen($delim)) . $newline; + + // Next blast through the result array and build out the rows + while ($row = $query->getUnbufferedRow('array')) + { + $line = []; + foreach ($row as $item) + { + $line[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $item) . $enclosure; + } + $out .= implode($delim, $line) . $newline; + } + + return $out; + } + + //-------------------------------------------------------------------- + + /** + * Generate XML data from a query result object + * + * @param ResultInterface $query Query result object + * @param array $params Any preferences + * + * @return string + */ + public function getXMLFromResult(ResultInterface $query, array $params = []): string + { + // Set our default values + foreach (['root' => 'root', 'element' => 'element', 'newline' => "\n", 'tab' => "\t"] as $key => $val) + { + if (! isset($params[$key])) + { + $params[$key] = $val; + } + } + + // Create variables for convenience + extract($params); + + // Load the xml helper + helper('xml'); + // Generate the result + $xml = '<' . $root . '>' . $newline; + while ($row = $query->getUnbufferedRow()) + { + $xml .= $tab . '<' . $element . '>' . $newline; + foreach ($row as $key => $val) + { + $val = (! empty($val)) ? xml_convert($val) : ''; + $xml .= $tab . $tab . '<' . $key . '>' . $val . '' . $newline; + } + $xml .= $tab . '' . $newline; + } + + return $xml . '' . $newline; + } + + //-------------------------------------------------------------------- + + /** + * Database Backup + * + * @param array|string $params + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function backup($params = []) + { + // If the parameters have not been submitted as an + // array then we know that it is simply the table + // name, which is a valid short cut. + if (is_string($params)) + { + $params = ['tables' => $params]; + } + + // Set up our default preferences + $prefs = [ + 'tables' => [], + 'ignore' => [], + 'filename' => '', + 'format' => 'gzip', // gzip, txt + 'add_drop' => true, + 'add_insert' => true, + 'newline' => "\n", + 'foreign_key_checks' => true, + ]; + + // Did the user submit any preferences? If so set them.... + if (! empty($params)) + { + foreach ($prefs as $key => $val) + { + if (isset($params[$key])) + { + $prefs[$key] = $params[$key]; + } + } + } + + // Are we backing up a complete database or individual tables? + // If no table names were submitted we'll fetch the entire table list + if (empty($prefs['tables'])) + { + $prefs['tables'] = $this->db->listTables(); + } + + // Validate the format + if (! in_array($prefs['format'], ['gzip', 'txt'], true)) + { + $prefs['format'] = 'txt'; + } + + // Is the encoder supported? If not, we'll either issue an + // error or use plain text depending on the debug settings + if ($prefs['format'] === 'gzip' && ! function_exists('gzencode')) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('The file compression format you chose is not supported by your server.'); + } + + $prefs['format'] = 'txt'; + } + + if ($prefs['format'] === 'txt') // Was a text file requested? + { + return $this->_backup($prefs); + } + + return gzencode($this->_backup($prefs)); + } + + //-------------------------------------------------------------------- + + /** + * Platform dependent version of the backup function. + * + * @param array|null $prefs + * + * @return mixed + */ + abstract public function _backup(array $prefs = null); + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/Config.php b/vendor/codeigniter4/framework/system/Database/Config.php new file mode 100644 index 0000000..89dd495 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Config.php @@ -0,0 +1,199 @@ +defaultGroup; + } + + if (is_string($group) && ! isset($config->$group) && strpos($group, 'custom-') !== 0) + { + throw new \InvalidArgumentException($group . ' is not a valid database connection group.'); + } + + if ($getShared && isset(static::$instances[$group])) + { + return static::$instances[$group]; + } + + static::ensureFactory(); + + if (isset($config->$group)) + { + $config = $config->$group; + } + + $connection = static::$factory->load($config, $group); + + static::$instances[$group] = & $connection; + + return $connection; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of all db connections currently made. + * + * @return array + */ + public static function getConnections(): array + { + return static::$instances; + } + + //-------------------------------------------------------------------- + + /** + * Loads and returns an instance of the Forge for the specified + * database group, and loads the group if it hasn't been loaded yet. + * + * @param string|array|null $group + * + * @return Forge + */ + public static function forge($group = null) + { + $db = static::connect($group); + + return static::$factory->loadForge($db); + } + + //-------------------------------------------------------------------- + + /** + * Returns a new instance of the Database Utilities class. + * + * @param string|array|null $group + * + * @return BaseUtils + */ + public static function utils($group = null) + { + $db = static::connect($group); + + return static::$factory->loadUtils($db); + } + + //-------------------------------------------------------------------- + + /** + * Returns a new instance of the Database Seeder. + * + * @param string|null $group + * + * @return Seeder + */ + public static function seeder(string $group = null) + { + $config = config('Database'); + + return new Seeder($config, static::connect($group)); + } + + //-------------------------------------------------------------------- + + /** + * Ensures the database Connection Manager/Factory is loaded and ready to use. + */ + protected static function ensureFactory() + { + if (static::$factory instanceof Database) + { + return; + } + + static::$factory = new Database(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/ConnectionInterface.php b/vendor/codeigniter4/framework/system/Database/ConnectionInterface.php new file mode 100644 index 0000000..2df836e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/ConnectionInterface.php @@ -0,0 +1,225 @@ +connections[$alias] = $class; + + return $this->connections[$alias]; + } + + //-------------------------------------------------------------------- + + /** + * Creates a new Forge instance for the current database type. + * + * @param ConnectionInterface|BaseConnection $db + * + * @return mixed + */ + public function loadForge(ConnectionInterface $db) + { + $className = strpos($db->DBDriver, '\\') === false ? '\CodeIgniter\Database\\' . $db->DBDriver . '\\Forge' : $db->DBDriver . '\\Forge'; + + // Make sure a connection exists + if (! $db->connID) + { + $db->initialize(); + } + + return new $className($db); + } + + //-------------------------------------------------------------------- + + /** + * Loads the Database Utilities class. + * + * @param ConnectionInterface|BaseConnection $db + * + * @return mixed + */ + public function loadUtils(ConnectionInterface $db) + { + $className = strpos($db->DBDriver, '\\') === false ? '\CodeIgniter\Database\\' . $db->DBDriver . '\\Utils' : $db->DBDriver . '\\Utils'; + + // Make sure a connection exists + if (! $db->connID) + { + $db->initialize(); + } + + return new $className($db); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/Exceptions/DataException.php b/vendor/codeigniter4/framework/system/Database/Exceptions/DataException.php new file mode 100644 index 0000000..2af1793 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Exceptions/DataException.php @@ -0,0 +1,65 @@ +db = &$db; + } + + //-------------------------------------------------------------------- + + /** + * Provides access to the forge's current database connection. + * + * @return ConnectionInterface + */ + public function getConnection() + { + return $this->db; + } + + //-------------------------------------------------------------------- + + /** + * Create database + * + * @param string $dbName + * @param boolean $ifNotExists Whether to add IF NOT EXISTS condition + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function createDatabase(string $dbName, bool $ifNotExists = false): bool + { + if ($ifNotExists && $this->createDatabaseIfStr === null) + { + if ($this->databaseExists($dbName)) + { + return true; + } + $ifNotExists = false; + } + + if ($this->createDatabaseStr === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + elseif (! $this->db->query(sprintf($ifNotExists ? $this->createDatabaseIfStr : $this->createDatabaseStr, $dbName, $this->db->charset, $this->db->DBCollat)) + ) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unable to create the specified database.'); + } + + return false; + } + + if (! empty($this->db->dataCache['db_names'])) + { + $this->db->dataCache['db_names'][] = $dbName; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Determine if a database exists + * + * @param string $dbName + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + private function databaseExists(string $dbName): bool + { + if ($this->checkDatabaseExistStr === null) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + return $this->db->query($this->checkDatabaseExistStr, $dbName)->getRow() !== null; + } + + //-------------------------------------------------------------------- + + /** + * Drop database + * + * @param string $dbName + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropDatabase(string $dbName): bool + { + if ($this->dropDatabaseStr === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + elseif (! $this->db->query(sprintf($this->dropDatabaseStr, $dbName))) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unable to drop the specified database.'); + } + + return false; + } + + if (! empty($this->db->dataCache['db_names'])) + { + $key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true); + if ($key !== false) + { + unset($this->db->dataCache['db_names'][$key]); + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Add Key + * + * @param string|array $key + * @param boolean $primary + * @param boolean $unique + * + * @return Forge + */ + public function addKey($key, bool $primary = false, bool $unique = false) + { + if ($primary === true) + { + foreach ((array)$key as $one) + { + $this->primaryKeys[] = $one; + } + } + else + { + $this->keys[] = $key; + if ($unique === true) + { + $this->uniqueKeys[] = ($c = count($this->keys)) ? $c - 1 : 0; + } + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Add Primary Key + * + * @param string|array $key + * + * @return Forge + */ + public function addPrimaryKey($key) + { + return $this->addKey($key, true); + } + + //-------------------------------------------------------------------- + + /** + * Add Unique Key + * + * @param string|array $key + * + * @return Forge + */ + public function addUniqueKey($key) + { + return $this->addKey($key, false, true); + } + + //-------------------------------------------------------------------- + + /** + * Add Field + * + * @param array|string $field + * + * @return Forge + */ + public function addField($field) + { + if (is_string($field)) + { + if ($field === 'id') + { + $this->addField([ + 'id' => [ + 'type' => 'INT', + 'constraint' => 9, + 'auto_increment' => true, + ], + ]); + $this->addKey('id', true); + } + else + { + if (strpos($field, ' ') === false) + { + throw new \InvalidArgumentException('Field information is required for that operation.'); + } + + $this->fields[] = $field; + } + } + + if (is_array($field)) + { + $this->fields = array_merge($this->fields, $field); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Add Foreign Key + * + * @param string $fieldName + * @param string $tableName + * @param string $tableField + * @param string $onUpdate + * @param string $onDelete + * + * @return \CodeIgniter\Database\Forge + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function addForeignKey(string $fieldName = '', string $tableName = '', string $tableField = '', string $onUpdate = '', string $onDelete = '') + { + if (! isset($this->fields[$fieldName])) + { + throw new DatabaseException(lang('Database.fieldNotExists', [$fieldName])); + } + + $this->foreignKeys[$fieldName] = [ + 'table' => $tableName, + 'field' => $tableField, + 'onDelete' => strtoupper($onDelete), + 'onUpdate' => strtoupper($onUpdate), + ]; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Foreign Key Drop + * + * @param string $table Table name + * @param string $foreignName Foreign name + * + * @return boolean|\CodeIgniter\Database\BaseResult|\CodeIgniter\Database\Query|false|mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropForeignKey(string $table, string $foreignName) + { + $sql = sprintf($this->dropConstraintStr, $this->db->escapeIdentifiers($this->db->DBPrefix . $table), + $this->db->escapeIdentifiers($this->db->DBPrefix . $foreignName)); + + if ($sql === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + return $this->db->query($sql); + } + + //-------------------------------------------------------------------- + + /** + * Create Table + * + * @param string $table Table name + * @param boolean $if_not_exists Whether to add IF NOT EXISTS condition + * @param array $attributes Associative array of table attributes + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function createTable(string $table, bool $if_not_exists = false, array $attributes = []) + { + if ($table === '') + { + throw new \InvalidArgumentException('A table name is required for that operation.'); + } + + $table = $this->db->DBPrefix . $table; + + if (count($this->fields) === 0) + { + throw new \RuntimeException('Field information is required.'); + } + + $sql = $this->_createTable($table, $if_not_exists, $attributes); + + if (is_bool($sql)) + { + $this->reset(); + if ($sql === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + } + + if (($result = $this->db->query($sql)) !== false) + { + if (! isset($this->db->dataCache['table_names'][$table])) + { + $this->db->dataCache['table_names'][] = $table; + } + + // Most databases don't support creating indexes from within the CREATE TABLE statement + if (! empty($this->keys)) + { + for ($i = 0, $sqls = $this->_processIndexes($table), $c = count($sqls); $i < $c; $i++) + { + $this->db->query($sqls[$i]); + } + } + } + + $this->reset(); + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Create Table + * + * @param string $table Table name + * @param boolean $if_not_exists Whether to add 'IF NOT EXISTS' condition + * @param array $attributes Associative array of table attributes + * + * @return mixed + */ + protected function _createTable(string $table, bool $if_not_exists, array $attributes) + { + // For any platforms that don't support Create If Not Exists... + if ($if_not_exists === true && $this->createTableIfStr === false) + { + if ($this->db->tableExists($table)) + { + return true; + } + + $if_not_exists = false; + } + + $sql = ($if_not_exists) ? sprintf($this->createTableIfStr, $this->db->escapeIdentifiers($table)) + : 'CREATE TABLE'; + + $columns = $this->_processFields(true); + for ($i = 0, $c = count($columns); $i < $c; $i++) + { + $columns[$i] = ($columns[$i]['_literal'] !== false) ? "\n\t" . $columns[$i]['_literal'] + : "\n\t" . $this->_processColumn($columns[$i]); + } + + $columns = implode(',', $columns); + + $columns .= $this->_processPrimaryKeys($table); + $columns .= $this->_processForeignKeys($table); + + // Are indexes created from within the CREATE TABLE statement? (e.g. in MySQL) + if ($this->createTableKeys === true) + { + $columns .= $this->_processIndexes($table); + } + + // createTableStr will usually have the following format: "%s %s (%s\n)" + $sql = sprintf($this->createTableStr . '%s', $sql, $this->db->escapeIdentifiers($table), $columns, + $this->_createTableAttributes($attributes)); + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * CREATE TABLE attributes + * + * @param array $attributes Associative array of table attributes + * + * @return string + */ + protected function _createTableAttributes(array $attributes): string + { + $sql = ''; + + foreach (array_keys($attributes) as $key) + { + if (is_string($key)) + { + $sql .= ' ' . strtoupper($key) . ' ' . $this->db->escape($attributes[$key]); + } + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Drop Table + * + * @param string $tableName Table name + * @param boolean $ifExists Whether to add an IF EXISTS condition + * @param boolean $cascade Whether to add an CASCADE condition + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropTable(string $tableName, bool $ifExists = false, bool $cascade = false) + { + if ($tableName === '') + { + if ($this->db->DBDebug) + { + throw new DatabaseException('A table name is required for that operation.'); + } + + return false; + } + + // If the prefix is already starting the table name, remove it... + if ($this->db->DBPrefix && strpos($tableName, $this->db->DBPrefix) === 0) + { + $tableName = substr($tableName, strlen($this->db->DBPrefix)); + } + + if (($query = $this->_dropTable($this->db->DBPrefix . $tableName, $ifExists, $cascade)) === true) + { + return true; + } + + $this->db->disableForeignKeyChecks(); + + $query = $this->db->query($query); + + $this->db->enableForeignKeyChecks(); + + // Update table list cache + if ($query && ! empty($this->db->dataCache['table_names'])) + { + $key = array_search(strtolower($this->db->DBPrefix . $tableName), + array_map('strtolower', $this->db->dataCache['table_names']), true); + if ($key !== false) + { + unset($this->db->dataCache['table_names'][$key]); + } + } + + return $query; + } + + //-------------------------------------------------------------------- + + /** + * Drop Table + * + * Generates a platform-specific DROP TABLE string + * + * @param string $table Table name + * @param boolean $if_exists Whether to add an IF EXISTS condition + * @param boolean $cascade Whether to add an CASCADE condition + * + * @return string + */ + protected function _dropTable(string $table, bool $if_exists, bool $cascade): string + { + $sql = 'DROP TABLE'; + + if ($if_exists) + { + if ($this->dropTableIfStr === false) + { + if (! $this->db->tableExists($table)) + { + return true; + } + } + else + { + $sql = sprintf($this->dropTableIfStr, $this->db->escapeIdentifiers($table)); + } + } + + return $sql . ' ' . $this->db->escapeIdentifiers($table); + } + + //-------------------------------------------------------------------- + + /** + * Rename Table + * + * @param string $table_name Old table name + * @param string $new_table_name New table name + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function renameTable(string $table_name, string $new_table_name) + { + if ($table_name === '' || $new_table_name === '') + { + throw new \InvalidArgumentException('A table name is required for that operation.'); + } + elseif ($this->renameTableStr === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + $result = $this->db->query(sprintf($this->renameTableStr, + $this->db->escapeIdentifiers($this->db->DBPrefix . $table_name), + $this->db->escapeIdentifiers($this->db->DBPrefix . $new_table_name)) + ); + + if ($result && ! empty($this->db->dataCache['table_names'])) + { + $key = array_search(strtolower($this->db->DBPrefix . $table_name), + array_map('strtolower', $this->db->dataCache['table_names']), true); + if ($key !== false) + { + $this->db->dataCache['table_names'][$key] = $this->db->DBPrefix . $new_table_name; + } + } + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Column Add + * + * @param string $table Table name + * @param string|array $field Column definition + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function addColumn(string $table, $field): bool + { + // Work-around for literal column definitions + is_array($field) || $field = [$field]; + + foreach (array_keys($field) as $k) + { + $this->addField([$k => $field[$k]]); + } + + $sqls = $this->_alterTable('ADD', $this->db->DBPrefix . $table, $this->_processFields()); + $this->reset(); + if ($sqls === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + for ($i = 0, $c = count($sqls); $i < $c; $i++) + { + if ($this->db->query($sqls[$i]) === false) + { + return false; + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Column Drop + * + * @param string $table Table name + * @param string|array $column_name Column name Array or comma separated + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropColumn(string $table, $column_name) + { + $sql = $this->_alterTable('DROP', $this->db->DBPrefix . $table, $column_name); + if ($sql === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + return $this->db->query($sql); + } + + //-------------------------------------------------------------------- + + /** + * Column Modify + * + * @param string $table Table name + * @param string|array $field Column definition + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function modifyColumn(string $table, $field): bool + { + // Work-around for literal column definitions + is_array($field) || $field = [$field]; + + foreach (array_keys($field) as $k) + { + $this->addField([$k => $field[$k]]); + } + + if (count($this->fields) === 0) + { + throw new \RuntimeException('Field information is required'); + } + + $sqls = $this->_alterTable('CHANGE', $this->db->DBPrefix . $table, $this->_processFields()); + $this->reset(); + if ($sqls === false) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('This feature is not available for the database you are using.'); + } + + return false; + } + + if ($sqls !== null) + { + for ($i = 0, $c = count($sqls); $i < $c; $i++) + { + if ($this->db->query($sqls[$i]) === false) + { + return false; + } + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * ALTER TABLE + * + * @param string $alter_type ALTER type + * @param string $table Table name + * @param mixed $fields Column definition + * + * @return string|string[] + */ + protected function _alterTable(string $alter_type, string $table, $fields) + { + $sql = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table) . ' '; + + // DROP has everything it needs now. + if ($alter_type === 'DROP') + { + if (is_string($fields)) + { + $fields = explode(',', $fields); + } + + $fields = array_map(function ($field) { + return 'DROP COLUMN ' . $this->db->escapeIdentifiers(trim($field)); + }, $fields); + + return $sql . implode(', ', $fields); + } + + $sql .= ($alter_type === 'ADD') ? 'ADD ' : $alter_type . ' COLUMN '; + + $sqls = []; + foreach ($fields as $data) + { + $sqls[] = $sql + . ($data['_literal'] !== false ? $data['_literal'] : $this->_processColumn($data)); + } + + return $sqls; + } + + //-------------------------------------------------------------------- + + /** + * Process fields + * + * @param boolean $create_table + * + * @return array + */ + protected function _processFields(bool $create_table = false): array + { + $fields = []; + + foreach ($this->fields as $key => $attributes) + { + if (is_int($key) && ! is_array($attributes)) + { + $fields[] = ['_literal' => $attributes]; + continue; + } + + $attributes = array_change_key_case($attributes, CASE_UPPER); + + if ($create_table === true && empty($attributes['TYPE'])) + { + continue; + } + + isset($attributes['TYPE']) && $this->_attributeType($attributes); + + $field = [ + 'name' => $key, + 'new_name' => isset($attributes['NAME']) ? $attributes['NAME'] : null, + 'type' => isset($attributes['TYPE']) ? $attributes['TYPE'] : null, + 'length' => '', + 'unsigned' => '', + 'null' => '', + 'unique' => '', + 'default' => '', + 'auto_increment' => '', + '_literal' => false, + ]; + + isset($attributes['TYPE']) && $this->_attributeUnsigned($attributes, $field); + + if ($create_table === false) + { + if (isset($attributes['AFTER'])) + { + $field['after'] = $attributes['AFTER']; + } + elseif (isset($attributes['FIRST'])) + { + $field['first'] = (bool)$attributes['FIRST']; + } + } + + $this->_attributeDefault($attributes, $field); + + if (isset($attributes['NULL'])) + { + if ($attributes['NULL'] === true) + { + $field['null'] = empty($this->null) ? '' : ' ' . $this->null; + } + else + { + $field['null'] = ' NOT NULL'; + } + } + elseif ($create_table === true) + { + $field['null'] = ' NOT NULL'; + } + + $this->_attributeAutoIncrement($attributes, $field); + $this->_attributeUnique($attributes, $field); + + if (isset($attributes['COMMENT'])) + { + $field['comment'] = $this->db->escape($attributes['COMMENT']); + } + + if (isset($attributes['TYPE']) && ! empty($attributes['CONSTRAINT'])) + { + if (is_array($attributes['CONSTRAINT'])) + { + $attributes['CONSTRAINT'] = $this->db->escape($attributes['CONSTRAINT']); + $attributes['CONSTRAINT'] = implode(',', $attributes['CONSTRAINT']); + } + + $field['length'] = '(' . $attributes['CONSTRAINT'] . ')'; + } + + $fields[] = $field; + } + + return $fields; + } + + //-------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * + * @return string + */ + protected function _processColumn(array $field): string + { + return $this->db->escapeIdentifiers($field['name']) + . ' ' . $field['type'] . $field['length'] + . $field['unsigned'] + . $field['default'] + . $field['null'] + . $field['auto_increment'] + . $field['unique']; + } + + //-------------------------------------------------------------------- + + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * + * @return void + */ + protected function _attributeType(array &$attributes) + { + // Usually overridden by drivers + } + + //-------------------------------------------------------------------- + + /** + * Field attribute UNSIGNED + * + * Depending on the unsigned property value: + * + * - TRUE will always set $field['unsigned'] to 'UNSIGNED' + * - FALSE will always set $field['unsigned'] to '' + * - array(TYPE) will set $field['unsigned'] to 'UNSIGNED', + * if $attributes['TYPE'] is found in the array + * - array(TYPE => UTYPE) will change $field['type'], + * from TYPE to UTYPE in case of a match + * + * @param array &$attributes + * @param array &$field + * + * @return null|void + */ + protected function _attributeUnsigned(array &$attributes, array &$field) + { + if (empty($attributes['UNSIGNED']) || $attributes['UNSIGNED'] !== true) + { + return; + } + + // Reset the attribute in order to avoid issues if we do type conversion + $attributes['UNSIGNED'] = false; + + if (is_array($this->unsigned)) + { + foreach (array_keys($this->unsigned) as $key) + { + if (is_int($key) && strcasecmp($attributes['TYPE'], $this->unsigned[$key]) === 0) + { + $field['unsigned'] = ' UNSIGNED'; + + return; + } + elseif (is_string($key) && strcasecmp($attributes['TYPE'], $key) === 0) + { + $field['type'] = $key; + + return; + } + } + + return; + } + + $field['unsigned'] = ($this->unsigned === true) ? ' UNSIGNED' : ''; + } + + //-------------------------------------------------------------------- + + /** + * Field attribute DEFAULT + * + * @param array &$attributes + * @param array &$field + * + * @return null|void + */ + protected function _attributeDefault(array &$attributes, array &$field) + { + if ($this->default === false) + { + return; + } + + if (array_key_exists('DEFAULT', $attributes)) + { + if ($attributes['DEFAULT'] === null) + { + $field['default'] = empty($this->null) ? '' : $this->default . $this->null; + + // Override the NULL attribute if that's our default + $attributes['NULL'] = true; + $field['null'] = empty($this->null) ? '' : ' ' . $this->null; + } + else + { + $field['default'] = $this->default . $this->db->escape($attributes['DEFAULT']); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Field attribute UNIQUE + * + * @param array &$attributes + * @param array &$field + * + * @return void + */ + protected function _attributeUnique(array &$attributes, array &$field) + { + if (! empty($attributes['UNIQUE']) && $attributes['UNIQUE'] === true) + { + $field['unique'] = ' UNIQUE'; + } + } + + //-------------------------------------------------------------------- + + /** + * Field attribute AUTO_INCREMENT + * + * @param array &$attributes + * @param array &$field + * + * @return void + */ + protected function _attributeAutoIncrement(array &$attributes, array &$field) + { + if (! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === true + && stripos($field['type'], 'int') !== false + ) + { + $field['auto_increment'] = ' AUTO_INCREMENT'; + } + } + + //-------------------------------------------------------------------- + + /** + * Process primary keys + * + * @param string $table Table name + * + * @return string + */ + protected function _processPrimaryKeys(string $table): string + { + $sql = ''; + + for ($i = 0, $c = count($this->primaryKeys); $i < $c; $i++) + { + if (! isset($this->fields[$this->primaryKeys[$i]])) + { + unset($this->primaryKeys[$i]); + } + } + + if (count($this->primaryKeys) > 0) + { + $sql .= ",\n\tCONSTRAINT " . $this->db->escapeIdentifiers('pk_' . $table) + . ' PRIMARY KEY(' . implode(', ', $this->db->escapeIdentifiers($this->primaryKeys)) . ')'; + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Process indexes + * + * @param string $table + * + * @return array + */ + protected function _processIndexes(string $table) + { + $sqls = []; + + for ($i = 0, $c = count($this->keys); $i < $c; $i++) + { + $this->keys[$i] = (array)$this->keys[$i]; + + for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) + { + if (! isset($this->fields[$this->keys[$i][$i2]])) + { + unset($this->keys[$i][$i2]); + } + } + if (count($this->keys[$i]) <= 0) + { + continue; + } + + if (in_array($i, $this->uniqueKeys)) + { + $sqls[] = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table) + . ' ADD CONSTRAINT ' . $this->db->escapeIdentifiers($table . '_' . implode('_', $this->keys[$i])) + . ' UNIQUE (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ');'; + continue; + } + + $sqls[] = 'CREATE INDEX ' . $this->db->escapeIdentifiers($table . '_' . implode('_', $this->keys[$i])) + . ' ON ' . $this->db->escapeIdentifiers($table) + . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ');'; + } + + return $sqls; + } + + //-------------------------------------------------------------------- + + /** + * Process foreign keys + * + * @param string $table Table name + * + * @return string + */ + protected function _processForeignKeys(string $table): string + { + $sql = ''; + + $allowActions = [ + 'CASCADE', + 'SET NULL', + 'NO ACTION', + 'RESTRICT', + 'SET DEFAULT', + ]; + + if (count($this->foreignKeys) > 0) + { + foreach ($this->foreignKeys as $field => $fkey) + { + $name_index = $table . '_' . $field . '_foreign'; + + $sql .= ",\n\tCONSTRAINT " . $this->db->escapeIdentifiers($name_index) + . ' FOREIGN KEY(' . $this->db->escapeIdentifiers($field) . ') REFERENCES ' . $this->db->escapeIdentifiers($this->db->DBPrefix . $fkey['table']) . ' (' . $this->db->escapeIdentifiers($fkey['field']) . ')'; + + if ($fkey['onDelete'] !== false && in_array($fkey['onDelete'], $allowActions)) + { + $sql .= ' ON DELETE ' . $fkey['onDelete']; + } + + if ($fkey['onUpdate'] !== false && in_array($fkey['onUpdate'], $allowActions)) + { + $sql .= ' ON UPDATE ' . $fkey['onUpdate']; + } + } + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Reset + * + * Resets table creation vars + * + * @return void + */ + public function reset() + { + $this->fields = $this->keys = $this->uniqueKeys = $this->primaryKeys = $this->foreignKeys = []; + } + +} diff --git a/vendor/codeigniter4/framework/system/Database/Migration.php b/vendor/codeigniter4/framework/system/Database/Migration.php new file mode 100644 index 0000000..3af3229 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Migration.php @@ -0,0 +1,110 @@ +forge = ! is_null($forge) ? $forge : \Config\Database::forge($this->DBGroup ?? config('Database')->defaultGroup); + + $this->db = $this->forge->getConnection(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the database group name this migration uses. + * + * @return string + */ + public function getDBGroup(): ?string + { + return $this->DBGroup; + } + + //-------------------------------------------------------------------- + + /** + * Perform a migration step. + */ + abstract public function up(); + + //-------------------------------------------------------------------- + + /** + * Revert a migration step. + */ + abstract public function down(); + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/MigrationRunner.php b/vendor/codeigniter4/framework/system/Database/MigrationRunner.php new file mode 100644 index 0000000..55350c8 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MigrationRunner.php @@ -0,0 +1,1064 @@ +enabled = $config->enabled ?? false; + $this->table = $config->table ?? 'migrations'; + + // Default name space is the app namespace + $this->namespace = APP_NAMESPACE; + + // get default database group + $config = config('Database'); + $this->group = $config->defaultGroup; + unset($config); + + // If no db connection passed in, use + // default database group. + $this->db = db_connect($db); + } + + //-------------------------------------------------------------------- + + /** + * Locate and run all new migrations + * + * @param string|null $group + */ + public function latest(string $group = null) + { + if (! $this->enabled) + { + throw ConfigException::forDisabledMigrations(); + } + + $this->ensureTable(); + + // Set database group if not null + if (! is_null($group)) + { + $this->groupFilter = $group; + $this->setGroup($group); + } + + // Locate the migrations + $migrations = $this->findMigrations(); + + // If nothing was found then we're done + if (empty($migrations)) + { + return true; + } + + // Remove any migrations already in the history + foreach ($this->getHistory($this->group) as $history) + { + unset($migrations[$this->getObjectUid($history)]); + } + + // Start a new batch + $batch = $this->getLastBatch() + 1; + + // Run each migration + foreach ($migrations as $migration) + { + if ($this->migrate('up', $migration)) + { + if ($this->groupSkip === true) + { + $this->groupSkip = false; + continue; + } + + $this->addHistory($migration, $batch); + } + // If a migration failed then try to back out what was done + else + { + $this->regress(-1); + + $message = lang('Migrations.generalFault'); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Migrate down to a previous batch + * + * Calls each migration step required to get to the provided batch + * + * @param integer $targetBatch Target batch number, or negative for a relative batch, 0 for all + * @param string|null $group + * + * @return mixed Current batch number on success, FALSE on failure or no migrations are found + * @throws ConfigException + */ + public function regress(int $targetBatch = 0, string $group = null) + { + if (! $this->enabled) + { + throw ConfigException::forDisabledMigrations(); + } + + // Set database group if not null + if (! is_null($group)) + { + $this->setGroup($group); + } + + $this->ensureTable(); + + // Get all the batches + $batches = $this->getBatches(); + + // Convert a relative batch to its absolute + if ($targetBatch < 0) + { + $targetBatch = $batches[count($batches) - 1 + $targetBatch] ?? 0; + } + + // If the goal was rollback then check if it is done + if (empty($batches) && $targetBatch === 0) + { + return true; + } + + // Make sure $targetBatch is found + if ($targetBatch !== 0 && ! in_array($targetBatch, $batches)) + { + $message = lang('Migrations.batchNotFound') . $targetBatch; + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + // Save the namespace to restore it after loading migrations + $tmpNamespace = $this->namespace; + + // Get all migrations + $this->namespace = null; + $allMigrations = $this->findMigrations(); + + // Gather migrations down through each batch until reaching the target + $migrations = []; + while ($batch = array_pop($batches)) + { + // Check if reached target + if ($batch <= $targetBatch) + { + break; + } + + // Get the migrations from each history + foreach ($this->getBatchHistory($batch, 'desc') as $history) + { + // Create a UID from the history to match its migration + $uid = $this->getObjectUid($history); + + // Make sure the migration is still available + if (! isset($allMigrations[$uid])) + { + $message = lang('Migrations.gap') . ' ' . $history->version; + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + // Add the history and put it on the list + $migration = $allMigrations[$uid]; + $migration->history = $history; + $migrations[] = $migration; + } + } + + // Run each migration + foreach ($migrations as $migration) + { + if ($this->migrate('down', $migration)) + { + $this->removeHistory($migration->history); + } + // If a migration failed then quit so as not to ruin the whole batch + else + { + $message = lang('Migrations.generalFault'); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + } + + // Restore the namespace + $this->namespace = $tmpNamespace; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Migrate a single file regardless of order or batches. + * Method "up" or "down" determined by presence in history. + * NOTE: This is not recommended and provided mostly for testing. + * + * @param string $path Full path to a valid migration file + * @param string $path Namespace of the target migration + * @param string|null $group + */ + public function force(string $path, string $namespace, string $group = null) + { + if (! $this->enabled) + { + throw ConfigException::forDisabledMigrations(); + } + + $this->ensureTable(); + + // Set database group if not null + if (! is_null($group)) + { + $this->groupFilter = $group; + $this->setGroup($group); + } + + // Create and validate the migration + $migration = $this->migrationFromFile($path, $namespace); + if (empty($migration)) + { + $message = lang('Migrations.notFound'); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + // Check the history for a match + $method = 'up'; + $this->setNamespace($migration->namespace); + foreach ($this->getHistory($this->group) as $history) + { + if ($this->getObjectUid($history) === $migration->uid) + { + $method = 'down'; + $migration->history = $history; + break; + } + } + + // up + if ($method === 'up') + { + // Start a new batch + $batch = $this->getLastBatch() + 1; + + if ($this->migrate('up', $migration) && $this->groupSkip === false) + { + $this->addHistory($migration, $batch); + return true; + } + + $this->groupSkip = false; + } + + // down + elseif ($this->migrate('down', $migration)) + { + $this->removeHistory($migration->history); + return true; + } + + // If it came this far the migration failed + $message = lang('Migrations.generalFault'); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + //-------------------------------------------------------------------- + + /** + * Retrieves list of available migration scripts + * + * @return array List of all located migrations by their UID + */ + public function findMigrations(): array + { + // If a namespace is set then use it, otherwise load all namespaces from the autoloader + $namespaces = $this->namespace ? [$this->namespace] : array_keys(Services::autoloader()->getNamespace()); + + // Collect the migrations to run by their sortable UID + $migrations = []; + foreach ($namespaces as $namespace) + { + foreach ($this->findNamespaceMigrations($namespace) as $migration) + { + $migrations[$migration->uid] = $migration; + } + } + + // Sort migrations ascending by their UID (version) + ksort($migrations); + + return $migrations; + } + + //-------------------------------------------------------------------- + + /** + * Retrieves a list of available migration scripts for one namespace + * + * @param string $namespace The namespace to search for migrations + * + * @return array List of unsorted migrations from the namespace + */ + public function findNamespaceMigrations(string $namespace): array + { + $migrations = []; + $locator = Services::locator(true); + + // If $this->path contains a valid directory use it. + if (! empty($this->path)) + { + helper('filesystem'); + $dir = rtrim($this->path, DIRECTORY_SEPARATOR) . '/'; + $files = get_filenames($dir, true); + } + // Otherwise use FileLocator to search files in the subdirectory of the namespace + else + { + $files = $locator->listNamespaceFiles($namespace, '/Database/Migrations/'); + } + + // Load all *_*.php files in the migrations path + // We can't use glob if we want it to be testable.... + foreach ($files as $file) + { + // Clean up the file path + $file = empty($this->path) ? $file : $this->path . str_replace($this->path, '', $file); + + // Create the migration object from the file and save it + if ($migration = $this->migrationFromFile($file, $namespace)) + { + $migrations[] = $migration; + } + } + + return $migrations; + } + + //-------------------------------------------------------------------- + + /** + * Create a migration object from a file path. + * + * @param string $path The path to the file + * @param string $path The namespace of the target migration + * + * @return object|false Returns the migration object, or false on failure + */ + protected function migrationFromFile(string $path, string $namespace) + { + if (substr($path, -4) !== '.php') + { + return false; + } + + // Remove the extension + $name = basename($path, '.php'); + + // Filter out non-migration files + if (! preg_match($this->regex, $name)) + { + return false; + } + + $locator = Services::locator(true); + + // Create migration object using stdClass + $migration = new \stdClass(); + + // Get migration version number + $migration->version = $this->getMigrationNumber($name); + $migration->name = $this->getMigrationName($name); + $migration->path = $path; + $migration->class = $locator->getClassname($path); + $migration->namespace = $namespace; + $migration->uid = $this->getObjectUid($migration); + + return $migration; + } + + //-------------------------------------------------------------------- + + /** + * Set namespace. + * Allows other scripts to modify on the fly as needed. + * + * @param string $namespace or null for "all" + * + * @return MigrationRunner + */ + public function setNamespace(?string $namespace) + { + $this->namespace = $namespace; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Set database Group. + * Allows other scripts to modify on the fly as needed. + * + * @param string $group + * + * @return MigrationRunner + */ + public function setGroup(string $group) + { + $this->group = $group; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Set migration Name. + * + * @param string $name + * + * @return \CodeIgniter\Database\MigrationRunner + */ + public function setName(string $name) + { + $this->name = $name; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * If $silent == true, then will not throw exceptions and will + * attempt to continue gracefully. + * + * @param boolean $silent + * + * @return MigrationRunner + */ + public function setSilent(bool $silent) + { + $this->silent = $silent; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Extracts the migration number from a filename + * + * @param string $migration + * + * @return string Numeric portion of a migration filename + */ + protected function getMigrationNumber(string $migration): string + { + preg_match('/^\d{4}[_-]?\d{2}[_-]?\d{2}[_-]?\d{6}/', $migration, $matches); + + return count($matches) ? $matches[0] : '0'; + } + + //-------------------------------------------------------------------- + + /** + * Extracts the migration class name from a filename + * + * @param string $migration + * + * @return string text portion of a migration filename + */ + protected function getMigrationName(string $migration): string + { + $parts = explode('_', $migration); + array_shift($parts); + + return implode('_', $parts); + } + + //-------------------------------------------------------------------- + + /** + * Uses the non-repeatable portions of a migration or history + * to create a sortable unique key + * + * @param object $migration or $history + * + * @return string + */ + public function getObjectUid($object): string + { + return preg_replace('/[^0-9]/', '', $object->version) . $object->class; + } + + //-------------------------------------------------------------------- + + /** + * Retrieves messages formatted for CLI output + * + * @return array Current migration version + */ + public function getCliMessages(): array + { + return $this->cliMessages; + } + + //-------------------------------------------------------------------- + + /** + * Clears any CLI messages. + * + * @return MigrationRunner + */ + public function clearCliMessages() + { + $this->cliMessages = []; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Truncates the history table. + * + * @return boolean + */ + public function clearHistory() + { + if ($this->db->tableExists($this->table)) + { + $this->db->table($this->table) + ->truncate(); + } + } + + //-------------------------------------------------------------------- + + /** + * Add a history to the table. + * + * @param object $migration + * @param integer $batch + * + * @return void + */ + protected function addHistory($migration, int $batch) + { + $this->db->table($this->table) + ->insert([ + 'version' => $migration->version, + 'class' => $migration->class, + 'group' => $this->group, + 'namespace' => $migration->namespace, + 'time' => time(), + 'batch' => $batch, + ]); + + if (is_cli()) + { + $this->cliMessages[] = "\t" . CLI::color(lang('Migrations.added'), + 'yellow') . "($migration->namespace) " . $migration->version . '_' . $migration->class; + } + } + + //-------------------------------------------------------------------- + + /** + * Removes a single history + * + * @param string $version + * + * @return void + */ + protected function removeHistory($history) + { + $this->db->table($this->table)->where('id', $history->id)->delete(); + + if (is_cli()) + { + $this->cliMessages[] = "\t" . CLI::color(lang('Migrations.removed'), + 'yellow') . "($history->namespace) " . $history->version . '_' . $this->getMigrationName($history->class); + } + } + + //-------------------------------------------------------------------- + + /** + * Grabs the full migration history from the database for a group + * + * @param string $group + * + * @return array + */ + public function getHistory(string $group = 'default'): array + { + $this->ensureTable(); + + $criteria = ['group' => $group]; + + // If a namespace was specified then use it + if ($this->namespace) + { + $criteria['namespace'] = $this->namespace; + } + + $query = $this->db->table($this->table) + ->where($criteria) + ->orderBy('id', 'ASC') + ->get(); + + return $query ? $query->getResultObject() : []; + } + + //-------------------------------------------------------------------- + + /** + * Returns the migration history for a single batch. + * + * @param integer $batch + * + * @return array + */ + public function getBatchHistory(int $batch, $order = 'asc'): array + { + $this->ensureTable(); + + $query = $this->db->table($this->table) + ->where('batch', $batch) + ->orderBy('id', $order) + ->get(); + + return $query ? $query->getResultObject() : []; + } + + //-------------------------------------------------------------------- + + /** + * Returns all the batches from the database history in order + * + * @return array + */ + public function getBatches(): array + { + $this->ensureTable(); + + $batches = $this->db->table($this->table) + ->select('batch') + ->distinct() + ->orderBy('batch', 'asc') + ->get() + ->getResultArray(); + + return array_column($batches, 'batch'); + } + + //-------------------------------------------------------------------- + + /** + * Returns the value of the last batch in the database. + * + * @return integer + */ + public function getLastBatch(): int + { + $this->ensureTable(); + + $batch = $this->db->table($this->table) + ->selectMax('batch') + ->get() + ->getResultObject(); + + $batch = is_array($batch) && count($batch) + ? end($batch)->batch + : 0; + + return (int)$batch; + } + + //-------------------------------------------------------------------- + + /** + * Returns the version number of the first migration for a batch. + * Mostly just for tests. + * + * @param integer $batch + * + * @return string + */ + public function getBatchStart(int $batch): string + { + // Convert a relative batch to its absolute + if ($batch < 0) + { + $batches = $this->getBatches(); + $batch = $batches[count($batches) - 1 + $targetBatch] ?? 0; + } + + $migration = $this->db->table($this->table) + ->where('batch', $batch) + ->orderBy('id', 'asc') + ->limit(1) + ->get() + ->getResultObject(); + + return count($migration) ? $migration[0]->version : '0'; + } + + //-------------------------------------------------------------------- + + /** + * Returns the version number of the last migration for a batch. + * Mostly just for tests. + * + * @param integer $batch + * + * @return string + */ + public function getBatchEnd(int $batch): string + { + // Convert a relative batch to its absolute + if ($batch < 0) + { + $batches = $this->getBatches(); + $batch = $batches[count($batches) - 1 + $targetBatch] ?? 0; + } + + $migration = $this->db->table($this->table) + ->where('batch', $batch) + ->orderBy('id', 'desc') + ->limit(1) + ->get() + ->getResultObject(); + + return count($migration) ? $migration[0]->version : 0; + } + + //-------------------------------------------------------------------- + + /** + * Ensures that we have created our migrations table + * in the database. + */ + public function ensureTable() + { + if ($this->tableChecked || $this->db->tableExists($this->table)) + { + return; + } + + $forge = \Config\Database::forge($this->db); + + $forge->addField([ + 'id' => [ + 'type' => 'BIGINT', + 'constraint' => 20, + 'unsigned' => true, + 'auto_increment' => true, + ], + 'version' => [ + 'type' => 'VARCHAR', + 'constraint' => 255, + 'null' => false, + ], + 'class' => [ + 'type' => 'TEXT', + 'null' => false, + ], + 'group' => [ + 'type' => 'VARCHAR', + 'constraint' => 255, + 'null' => false, + ], + 'namespace' => [ + 'type' => 'VARCHAR', + 'constraint' => 255, + 'null' => false, + ], + 'time' => [ + 'type' => 'INT', + 'constraint' => 11, + 'null' => false, + ], + 'batch' => [ + 'type' => 'INT', + 'constraint' => 11, + 'unsigned' => true, + 'null' => false, + ], + ]); + + $forge->addPrimaryKey('id'); + $forge->createTable($this->table, true); + + $this->tableChecked = true; + } + + /** + * Handles the actual running of a migration. + * + * @param $direction "up" or "down" + * @param $migration The migration to run + * + * @return boolean + */ + protected function migrate($direction, $migration): bool + { + include_once $migration->path; + + $class = $migration->class; + $this->setName($migration->name); + + // Validate the migration file structure + if (! class_exists($class, false)) + { + $message = sprintf(lang('Migrations.classNotFound'), $class); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + // Initialize migration + $instance = new $class(); + // Determine DBGroup to use + $group = $instance->getDBGroup() ?? config('Database')->defaultGroup; + + // Skip tests db group when not running in testing environment + if (ENVIRONMENT !== 'testing' && $group === 'tests' && $this->groupFilter !== 'tests') + { + // @codeCoverageIgnoreStart + $this->groupSkip = true; + return true; + // @codeCoverageIgnoreEnd + } + + // Skip migration if group filtering was set + if ($direction === 'up' && ! is_null($this->groupFilter) && $this->groupFilter !== $group) + { + $this->groupSkip = true; + return true; + } + + $this->setGroup($group); + + if (! is_callable([$instance, $direction])) + { + $message = sprintf(lang('Migrations.missingMethod'), $direction); + + if ($this->silent) + { + $this->cliMessages[] = "\t" . CLI::color($message, 'red'); + return false; + } + throw new \RuntimeException($message); + } + + $instance->{$direction}(); + + return true; + } +} diff --git a/vendor/codeigniter4/framework/system/Database/ModelFactory.php b/vendor/codeigniter4/framework/system/Database/ModelFactory.php new file mode 100644 index 0000000..b2b4362 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/ModelFactory.php @@ -0,0 +1,111 @@ +locateFile($name, 'Models'); + + if (empty($file)) + { + // No file found - check if the class was namespaced + if (strpos($name, '\\') !== false) + { + // Class was namespaced and locateFile couldn't find it + return null; + } + + // Check all namespaces + $files = $locator->search('Models/' . $name); + if (empty($files)) + { + return null; + } + + // Get the first match (prioritizes user and framework) + $file = reset($files); + } + + $name = $locator->getClassname($file); + + if (empty($name)) + { + return null; + } + + return new $name($connection); + } +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/Builder.php b/vendor/codeigniter4/framework/system/Database/MySQLi/Builder.php new file mode 100644 index 0000000..d2eb6e6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/Builder.php @@ -0,0 +1,88 @@ + 'IGNORE', + 'insert' => 'IGNORE', + 'delete' => 'IGNORE', + ]; + + /** + * FROM tables + * + * Groups tables in FROM clauses if needed, so there is no confusion + * about operator precedence. + * + * Note: This is only used (and overridden) by MySQL. + * + * @return string + */ + protected function _fromTables(): string + { + if (! empty($this->QBJoin) && count($this->QBFrom) > 1) + { + return '(' . implode(', ', $this->QBFrom) . ')'; + } + + return implode(', ', $this->QBFrom); + } +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php b/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php new file mode 100644 index 0000000..206b9f0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/Connection.php @@ -0,0 +1,742 @@ +hostname[0] === '/') + { + $hostname = null; + $port = null; + $socket = $this->hostname; + } + else + { + $hostname = ($persistent === true) ? 'p:' . $this->hostname : $this->hostname; + $port = empty($this->port) ? null : $this->port; + $socket = ''; + } + + $client_flags = ($this->compress === true) ? MYSQLI_CLIENT_COMPRESS : 0; + $this->mysqli = mysqli_init(); + + mysqli_report(MYSQLI_REPORT_ALL & ~MYSQLI_REPORT_INDEX); + + $this->mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 10); + + if (isset($this->strictOn)) + { + if ($this->strictOn) + { + $this->mysqli->options(MYSQLI_INIT_COMMAND, + 'SET SESSION sql_mode = CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'); + } + else + { + $this->mysqli->options(MYSQLI_INIT_COMMAND, 'SET SESSION sql_mode = + REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( + @@sql_mode, + "STRICT_ALL_TABLES,", ""), + ",STRICT_ALL_TABLES", ""), + "STRICT_ALL_TABLES", ""), + "STRICT_TRANS_TABLES,", ""), + ",STRICT_TRANS_TABLES", ""), + "STRICT_TRANS_TABLES", "")' + ); + } + } + + if (is_array($this->encrypt)) + { + $ssl = []; + empty($this->encrypt['ssl_key']) || $ssl['key'] = $this->encrypt['ssl_key']; + empty($this->encrypt['ssl_cert']) || $ssl['cert'] = $this->encrypt['ssl_cert']; + empty($this->encrypt['ssl_ca']) || $ssl['ca'] = $this->encrypt['ssl_ca']; + empty($this->encrypt['ssl_capath']) || $ssl['capath'] = $this->encrypt['ssl_capath']; + empty($this->encrypt['ssl_cipher']) || $ssl['cipher'] = $this->encrypt['ssl_cipher']; + + if (! empty($ssl)) + { + if (isset($this->encrypt['ssl_verify'])) + { + if ($this->encrypt['ssl_verify']) + { + defined('MYSQLI_OPT_SSL_VERIFY_SERVER_CERT') && + $this->mysqli->options(MYSQLI_OPT_SSL_VERIFY_SERVER_CERT, true); + } + // Apparently (when it exists), setting MYSQLI_OPT_SSL_VERIFY_SERVER_CERT + // to FALSE didn't do anything, so PHP 5.6.16 introduced yet another + // constant ... + // + // https://secure.php.net/ChangeLog-5.php#5.6.16 + // https://bugs.php.net/bug.php?id=68344 + elseif (defined('MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT') && version_compare($this->mysqli->client_info, '5.6', '>=')) + { + $client_flags += MYSQLI_CLIENT_SSL_DONT_VERIFY_SERVER_CERT; + } + } + + $client_flags += MYSQLI_CLIENT_SSL; + $this->mysqli->ssl_set( + $ssl['key'] ?? null, $ssl['cert'] ?? null, $ssl['ca'] ?? null, + $ssl['capath'] ?? null, $ssl['cipher'] ?? null + ); + } + } + + try + { + if ($this->mysqli->real_connect($hostname, $this->username, $this->password, + $this->database, $port, $socket, $client_flags) + ) + { + // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails + if (($client_flags & MYSQLI_CLIENT_SSL) && version_compare($this->mysqli->client_info, '5.7.3', '<=') + && empty($this->mysqli->query("SHOW STATUS LIKE 'ssl_cipher'") + ->fetch_object()->Value) + ) + { + $this->mysqli->close(); + $message = 'MySQLi was configured for an SSL connection, but got an unencrypted connection instead!'; + log_message('error', $message); + + if ($this->DBDebug) + { + throw new DatabaseException($message); + } + + return false; + } + + if (! $this->mysqli->set_charset($this->charset)) + { + log_message('error', + "Database: Unable to set the configured connection charset ('{$this->charset}')."); + $this->mysqli->close(); + + if ($this->DBDebug) + { + throw new DatabaseException('Unable to set client connection character set: ' . $this->charset); + } + + return false; + } + + return $this->mysqli; + } + } + catch (\Throwable $e) + { + // Clean sensitive information from errors. + $msg = $e->getMessage(); + + $msg = str_replace($this->username, '****', $msg); + $msg = str_replace($this->password, '****', $msg); + + throw new \mysqli_sql_exception($msg, $e->getCode(), $e); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Keep or establish the connection if no queries have been sent for + * a length of time exceeding the server's idle timeout. + * + * @return void + */ + public function reconnect() + { + $this->close(); + $this->initialize(); + } + + //-------------------------------------------------------------------- + + /** + * Close the database connection. + * + * @return void + */ + protected function _close() + { + $this->connID->close(); + } + + //-------------------------------------------------------------------- + + /** + * Select a specific database table to use. + * + * @param string $databaseName + * + * @return boolean + */ + public function setDatabase(string $databaseName): bool + { + if ($databaseName === '') + { + $databaseName = $this->database; + } + + if (empty($this->connID)) + { + $this->initialize(); + } + + if ($this->connID->select_db($databaseName)) + { + $this->database = $databaseName; + + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string containing the version of the database being used. + * + * @return string + */ + public function getVersion(): string + { + if (isset($this->dataCache['version'])) + { + return $this->dataCache['version']; + } + + if (empty($this->mysqli)) + { + $this->initialize(); + } + + return $this->dataCache['version'] = $this->mysqli->server_info; + } + + //-------------------------------------------------------------------- + + /** + * Executes the query against the database. + * + * @param string $sql + * + * @return mixed + */ + public function execute(string $sql) + { + while ($this->connID->more_results()) + { + $this->connID->next_result(); + if ($res = $this->connID->store_result()) + { + $res->free(); + } + } + try + { + return $this->connID->query($this->prepQuery($sql)); + } + catch (\mysqli_sql_exception $e) + { + log_message('error', $e); + if ($this->DBDebug) + { + throw $e; + } + } + return false; + } + + //-------------------------------------------------------------------- + + /** + * Prep the query + * + * If needed, each database adapter can prep the query string + * + * @param string $sql an SQL query + * + * @return string + */ + protected function prepQuery(string $sql): string + { + // mysqli_affected_rows() returns 0 for "DELETE FROM TABLE" queries. This hack + // modifies the query so that it a proper number of affected rows is returned. + if ($this->deleteHack === true && preg_match('/^\s*DELETE\s+FROM\s+(\S+)\s*$/i', $sql)) + { + return trim($sql) . ' WHERE 1=1'; + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of rows affected by this query. + * + * @return integer + */ + public function affectedRows(): int + { + return $this->connID->affected_rows ?? 0; + } + + //-------------------------------------------------------------------- + + /** + * Platform-dependant string escape + * + * @param string $str + * @return string + */ + protected function _escapeString(string $str): string + { + if (is_bool($str)) + { + return $str; + } + + if (! $this->connID) + { + $this->initialize(); + } + + return $this->connID->real_escape_string($str); + } + + //-------------------------------------------------------------------- + + /** + * Escape Like String Direct + * There are a few instances where MySQLi queries cannot take the + * additional "ESCAPE x" parameter for specifying the escape character + * in "LIKE" strings, and this handles those directly with a backslash. + * + * @param string|string[] $str Input string + * @return string|string[] + */ + public function escapeLikeStringDirect($str) + { + if (is_array($str)) + { + foreach ($str as $key => $val) + { + $str[$key] = $this->escapeLikeStringDirect($val); + } + + return $str; + } + + $str = $this->_escapeString($str); + + // Escape LIKE condition wildcards + return str_replace([ + $this->likeEscapeChar, + '%', + '_', + ], [ + '\\' . $this->likeEscapeChar, + '\\' . '%', + '\\' . '_', + ], $str + ); + } + + //-------------------------------------------------------------------- + + /** + * Generates the SQL for listing tables in a platform-dependent manner. + * Uses escapeLikeStringDirect(). + * + * @param boolean $prefixLimit + * + * @return string + */ + protected function _listTables(bool $prefixLimit = false): string + { + $sql = 'SHOW TABLES FROM ' . $this->escapeIdentifiers($this->database); + + if ($prefixLimit !== false && $this->DBPrefix !== '') + { + return $sql . " LIKE '" . $this->escapeLikeStringDirect($this->DBPrefix) . "%'"; + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Generates a platform-specific query string so that the column names can be fetched. + * + * @param string $table + * + * @return string + */ + protected function _listColumns(string $table = ''): string + { + return 'SHOW COLUMNS FROM ' . $this->protectIdentifiers($table, true, null, false); + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with field data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _fieldData(string $table): array + { + $table = $this->protectIdentifiers($table, true, null, false); + + if (($query = $this->query('SHOW COLUMNS FROM ' . $table)) === false) + { + throw new DatabaseException(lang('Database.failGetFieldData')); + } + $query = $query->getResultObject(); + + $retVal = []; + for ($i = 0, $c = count($query); $i < $c; $i++) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = $query[$i]->Field; + + sscanf($query[$i]->Type, '%[a-z](%d)', $retVal[$i]->type, $retVal[$i]->max_length); + + $retVal[$i]->nullable = $query[$i]->Null === 'YES'; + $retVal[$i]->default = $query[$i]->Default; + $retVal[$i]->primary_key = (int)($query[$i]->Key === 'PRI'); + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with index data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + * @throws \LogicException + */ + public function _indexData(string $table): array + { + $table = $this->protectIdentifiers($table, true, null, false); + + if (($query = $this->query('SHOW INDEX FROM ' . $table)) === false) + { + throw new DatabaseException(lang('Database.failGetIndexData')); + } + + if (! $indexes = $query->getResultArray()) + { + return []; + } + + $keys = []; + + foreach ($indexes as $index) + { + if (empty($keys[$index['Key_name']])) + { + $keys[$index['Key_name']] = new \stdClass(); + $keys[$index['Key_name']]->name = $index['Key_name']; + + if ($index['Key_name'] === 'PRIMARY') + { + $type = 'PRIMARY'; + } + elseif ($index['Index_type'] === 'FULLTEXT') + { + $type = 'FULLTEXT'; + } + elseif ($index['Non_unique']) + { + if ($index['Index_type'] === 'SPATIAL') + { + $type = 'SPATIAL'; + } + else + { + $type = 'INDEX'; + } + } + else + { + $type = 'UNIQUE'; + } + + $keys[$index['Key_name']]->type = $type; + } + + $keys[$index['Key_name']]->fields[] = $index['Column_name']; + } + + return $keys; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with Foreign key data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _foreignKeyData(string $table): array + { + $sql = ' + SELECT + tc.CONSTRAINT_NAME, + tc.TABLE_NAME, + kcu.COLUMN_NAME, + rc.REFERENCED_TABLE_NAME, + kcu.REFERENCED_COLUMN_NAME + FROM information_schema.TABLE_CONSTRAINTS AS tc + INNER JOIN information_schema.REFERENTIAL_CONSTRAINTS AS rc + ON tc.CONSTRAINT_NAME = rc.CONSTRAINT_NAME + INNER JOIN information_schema.KEY_COLUMN_USAGE AS kcu + ON tc.CONSTRAINT_NAME = kcu.CONSTRAINT_NAME + WHERE + tc.CONSTRAINT_TYPE = ' . $this->escape('FOREIGN KEY') . ' AND + tc.TABLE_SCHEMA = ' . $this->escape($this->database) . ' AND + tc.TABLE_NAME = ' . $this->escape($table); + + if (($query = $this->query($sql)) === false) + { + throw new DatabaseException(lang('Database.failGetForeignKeyData')); + } + $query = $query->getResultObject(); + + $retVal = []; + foreach ($query as $row) + { + $obj = new \stdClass(); + $obj->constraint_name = $row->CONSTRAINT_NAME; + $obj->table_name = $row->TABLE_NAME; + $obj->column_name = $row->COLUMN_NAME; + $obj->foreign_table_name = $row->REFERENCED_TABLE_NAME; + $obj->foreign_column_name = $row->REFERENCED_COLUMN_NAME; + + $retVal[] = $obj; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to disable foreign key checks. + * + * @return string + */ + protected function _disableForeignKeyChecks() + { + return 'SET FOREIGN_KEY_CHECKS=0'; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to enable foreign key checks. + * + * @return string + */ + protected function _enableForeignKeyChecks() + { + return 'SET FOREIGN_KEY_CHECKS=1'; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last error code and message. + * + * Must return an array with keys 'code' and 'message': + * + * return ['code' => null, 'message' => null); + * + * @return array + */ + public function error(): array + { + if (! empty($this->mysqli->connect_errno)) + { + return [ + 'code' => $this->mysqli->connect_errno, + 'message' => $this->mysqli->connect_error, + ]; + } + + return [ + 'code' => $this->connID->errno, + 'message' => $this->connID->error, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Insert ID + * + * @return integer + */ + public function insertID(): int + { + return $this->connID->insert_id; + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return boolean + */ + protected function _transBegin(): bool + { + $this->connID->autocommit(false); + + return $this->connID->begin_transaction(); + } + + //-------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + protected function _transCommit(): bool + { + if ($this->connID->commit()) + { + $this->connID->autocommit(true); + + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + protected function _transRollback(): bool + { + if ($this->connID->rollback()) + { + $this->connID->autocommit(true); + + return true; + } + + return false; + } + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/Forge.php b/vendor/codeigniter4/framework/system/Database/MySQLi/Forge.php new file mode 100644 index 0000000..7e7e0a2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/Forge.php @@ -0,0 +1,279 @@ +_quoted_table_options)) + { + $sql .= $this->db->escape($attributes[$key]); + } + else + { + $sql .= $this->db->escapeString($attributes[$key]); + } + } + } + + if (! empty($this->db->charset) && ! strpos($sql, 'CHARACTER SET') && ! strpos($sql, 'CHARSET')) + { + $sql .= ' DEFAULT CHARACTER SET = ' . $this->db->escapeString($this->db->charset); + } + + if (! empty($this->db->DBCollat) && ! strpos($sql, 'COLLATE')) + { + $sql .= ' COLLATE = ' . $this->db->escapeString($this->db->DBCollat); + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * ALTER TABLE + * + * @param string $alter_type ALTER type + * @param string $table Table name + * @param mixed $field Column definition + * @return string|string[] + */ + protected function _alterTable(string $alter_type, string $table, $field) + { + if ($alter_type === 'DROP') + { + return parent::_alterTable($alter_type, $table, $field); + } + + $sql = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table); + foreach ($field as $i => $data) + { + if ($data['_literal'] !== false) + { + $field[$i] = ($alter_type === 'ADD') ? "\n\tADD " . $data['_literal'] : "\n\tMODIFY " . $data['_literal']; + } + else + { + if ($alter_type === 'ADD') + { + $field[$i]['_literal'] = "\n\tADD "; + } + else + { + $field[$i]['_literal'] = empty($data['new_name']) ? "\n\tMODIFY " : "\n\tCHANGE "; + } + + $field[$i] = $field[$i]['_literal'] . $this->_processColumn($field[$i]); + } + } + + return [$sql . implode(',', $field)]; + } + + //-------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * @return string + */ + protected function _processColumn(array $field): string + { + $extra_clause = isset($field['after']) ? ' AFTER ' . $this->db->escapeIdentifiers($field['after']) : ''; + + if (empty($extra_clause) && isset($field['first']) && $field['first'] === true) + { + $extra_clause = ' FIRST'; + } + + return $this->db->escapeIdentifiers($field['name']) + . (empty($field['new_name']) ? '' : ' ' . $this->db->escapeIdentifiers($field['new_name'])) + . ' ' . $field['type'] . $field['length'] + . $field['unsigned'] + . $field['null'] + . $field['default'] + . $field['auto_increment'] + . $field['unique'] + . (empty($field['comment']) ? '' : ' COMMENT ' . $field['comment']) + . $extra_clause; + } + + //-------------------------------------------------------------------- + + /** + * Process indexes + * + * @param string $table (ignored) + * @return string + */ + protected function _processIndexes(string $table): string + { + $sql = ''; + + for ($i = 0, $c = count($this->keys); $i < $c; $i ++) + { + if (is_array($this->keys[$i])) + { + for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2 ++) + { + if (! isset($this->fields[$this->keys[$i][$i2]])) + { + unset($this->keys[$i][$i2]); + continue; + } + } + } + elseif (! isset($this->fields[$this->keys[$i]])) + { + unset($this->keys[$i]); + continue; + } + + is_array($this->keys[$i]) || $this->keys[$i] = [$this->keys[$i]]; + + $unique = in_array($i, $this->uniqueKeys) ? 'UNIQUE ' : ''; + + $sql .= ",\n\t{$unique}KEY " . $this->db->escapeIdentifiers(implode('_', $this->keys[$i])) + . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ')'; + } + + $this->keys = []; + + return $sql; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/PreparedQuery.php b/vendor/codeigniter4/framework/system/Database/MySQLi/PreparedQuery.php new file mode 100644 index 0000000..3ef4104 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/PreparedQuery.php @@ -0,0 +1,135 @@ +statement = $this->db->mysqli->prepare($sql)) + { + $this->errorCode = $this->db->mysqli->errno; + $this->errorString = $this->db->mysqli->error; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Takes a new set of data and runs it against the currently + * prepared query. Upon success, will return a Results object. + * + * @param array $data + * + * @return boolean + */ + public function _execute(array $data): bool + { + if (is_null($this->statement)) + { + throw new \BadMethodCallException('You must call prepare before trying to execute a prepared statement.'); + } + + // First off -bind the parameters + $bindTypes = ''; + + // Determine the type string + foreach ($data as $item) + { + if (is_integer($item)) + { + $bindTypes .= 'i'; + } + elseif (is_numeric($item)) + { + $bindTypes .= 'd'; + } + else + { + $bindTypes .= 's'; + } + } + + // Bind it + $this->statement->bind_param($bindTypes, ...$data); + + return $this->statement->execute(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result object for the prepared query. + * + * @return mixed + */ + public function _getResult() + { + return $this->statement->get_result(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/Result.php b/vendor/codeigniter4/framework/system/Database/MySQLi/Result.php new file mode 100644 index 0000000..7a7c585 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/Result.php @@ -0,0 +1,211 @@ +resultID->field_count; + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of column names in the result set. + * + * @return array + */ + public function getFieldNames(): array + { + $fieldNames = []; + $this->resultID->field_seek(0); + while ($field = $this->resultID->fetch_field()) + { + $fieldNames[] = $field->name; + } + + return $fieldNames; + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of objects representing field meta-data. + * + * @return array + */ + public function getFieldData(): array + { + static $data_types = [ + MYSQLI_TYPE_DECIMAL => 'decimal', + MYSQLI_TYPE_NEWDECIMAL => 'newdecimal', + MYSQLI_TYPE_FLOAT => 'float', + MYSQLI_TYPE_DOUBLE => 'double', + + MYSQLI_TYPE_BIT => 'bit', + MYSQLI_TYPE_TINY => 'tiny', + MYSQLI_TYPE_SHORT => 'short', + MYSQLI_TYPE_LONG => 'long', + MYSQLI_TYPE_LONGLONG => 'longlong', + MYSQLI_TYPE_INT24 => 'int24', + + MYSQLI_TYPE_YEAR => 'year', + + MYSQLI_TYPE_TIMESTAMP => 'timestamp', + MYSQLI_TYPE_DATE => 'date', + MYSQLI_TYPE_TIME => 'time', + MYSQLI_TYPE_DATETIME => 'datetime', + MYSQLI_TYPE_NEWDATE => 'newdate', + + MYSQLI_TYPE_INTERVAL => 'interval', + MYSQLI_TYPE_SET => 'set', + MYSQLI_TYPE_ENUM => 'enum', + + MYSQLI_TYPE_VAR_STRING => 'var_string', + MYSQLI_TYPE_STRING => 'string', + MYSQLI_TYPE_CHAR => 'char', + + MYSQLI_TYPE_GEOMETRY => 'geometry', + MYSQLI_TYPE_TINY_BLOB => 'tiny_blob', + MYSQLI_TYPE_MEDIUM_BLOB => 'medium_blob', + MYSQLI_TYPE_LONG_BLOB => 'long_blob', + MYSQLI_TYPE_BLOB => 'blob', + ]; + + $retVal = []; + $fieldData = $this->resultID->fetch_fields(); + + foreach ($fieldData as $i => $data) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = $data->name; + $retVal[$i]->type = $data->type; + $retVal[$i]->type_name = isset($data_types[$data->type]) ? $data_types[$data->type] : null; + $retVal[$i]->max_length = $data->max_length; + $retVal[$i]->primary_key = (int) ($data->flags & 2); + $retVal[$i]->length = $data->length; + $retVal[$i]->default = $data->def; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Frees the current result. + * + * @return void + */ + public function freeResult() + { + if (is_object($this->resultID)) + { + $this->resultID->free(); + $this->resultID = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Moves the internal pointer to the desired offset. This is called + * internally before fetching results to make sure the result set + * starts at zero. + * + * @param integer $n + * + * @return mixed + */ + public function dataSeek(int $n = 0) + { + return $this->resultID->data_seek($n); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an array. + * + * Overridden by driver classes. + * + * @return mixed + */ + protected function fetchAssoc() + { + return $this->resultID->fetch_assoc(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an object. + * + * Overridden by child classes. + * + * @param string $className + * + * @return object|boolean|Entity + */ + protected function fetchObject(string $className = 'stdClass') + { + if (is_subclass_of($className, Entity::class)) + { + return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); + } + return $this->resultID->fetch_object($className); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/MySQLi/Utils.php b/vendor/codeigniter4/framework/system/Database/MySQLi/Utils.php new file mode 100644 index 0000000..e5056d1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/MySQLi/Utils.php @@ -0,0 +1,80 @@ + 'ON CONFLICT DO NOTHING', + ]; + + //-------------------------------------------------------------------- + + /** + * Compile Ignore Statement + * + * Checks if the ignore option is supported by + * the Database Driver for the specific statement. + * + * @param string $statement + * + * @return string + */ + protected function compileIgnore(string $statement) + { + $sql = parent::compileIgnore($statement); + + if (! empty($sql)) + { + $sql = ' ' . trim($sql); + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * ORDER BY + * + * @param string $orderBy + * @param string $direction ASC, DESC or RANDOM + * @param boolean $escape + * + * @return BaseBuilder + */ + public function orderBy(string $orderBy, string $direction = '', bool $escape = null) + { + $direction = strtoupper(trim($direction)); + if ($direction === 'RANDOM') + { + if (! is_float($orderBy) && ctype_digit((string) $orderBy)) + { + $orderBy = (float) ($orderBy > 1 ? "0.{$orderBy}" : $orderBy); + } + + if (is_float($orderBy)) + { + $this->db->simpleQuery("SET SEED {$orderBy}"); + } + + $orderBy = $this->randomKeyword[0]; + $direction = ''; + $escape = false; + } + + return parent::orderBy($orderBy, $direction, $escape); + } + + //-------------------------------------------------------------------- + + /** + * Increments a numeric column by the specified value. + * + * @param string $column + * @param integer $value + * + * @throws DatabaseException + * + * @return mixed + */ + public function increment(string $column, int $value = 1) + { + $column = $this->db->protectIdentifiers($column); + + $sql = $this->_update($this->QBFrom[0], [$column => "to_number({$column}, '9999999') + {$value}"]); + + return $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Decrements a numeric column by the specified value. + * + * @param string $column + * @param integer $value + * + * @throws DatabaseException + * + * @return mixed + */ + public function decrement(string $column, int $value = 1) + { + $column = $this->db->protectIdentifiers($column); + + $sql = $this->_update($this->QBFrom[0], [$column => "to_number({$column}, '9999999') - {$value}"]); + + return $this->db->query($sql, $this->binds, false); + } + + //-------------------------------------------------------------------- + + /** + * Replace + * + * Compiles an replace into string and runs the query. + * Because PostgreSQL doesn't support the replace into command, + * we simply do a DELETE and an INSERT on the first key/value + * combo, assuming that it's either the primary key or a unique key. + * + * @param array $set An associative array of insert values + * + * @return mixed + * @throws DatabaseException + * @internal param true $bool returns the generated SQL, false executes the query. + */ + public function replace(array $set = null) + { + if ($set !== null) + { + $this->set($set); + } + + if (! $this->QBSet) + { + if (CI_DEBUG) + { + throw new DatabaseException('You must use the "set" method to update an entry.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + + $table = $this->QBFrom[0]; + + $set = $this->binds; + + // We need to grab out the actual values from + // the way binds are stored with escape flag. + array_walk($set, function (&$item) { + $item = $item[0]; + }); + + $keys = array_keys($set); + $values = array_values($set); + + $builder = $this->db->table($table); + $exists = $builder->where("$keys[0] = $values[0]", null, false)->get()->getFirstRow(); + + if (empty($exists)) + { + $result = $builder->insert($set); + } + else + { + array_pop($set); + $result = $builder->update($set, "$keys[0] = $values[0]"); + } + + unset($builder); + $this->resetWrite(); + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Delete + * + * Compiles a delete string and runs the query + * + * @param mixed $where + * @param integer $limit + * @param boolean $reset_data + * + * @return mixed + * @throws DatabaseException + * @internal param the $mixed where clause + * @internal param the $mixed limit clause + * @internal param $bool + */ + public function delete($where = '', int $limit = null, bool $reset_data = true) + { + if (! empty($limit) || ! empty($this->QBLimit)) + { + throw new DatabaseException('PostgreSQL does not allow LIMITs on DELETE queries.'); + } + + return parent::delete($where, $limit, $reset_data); + } + + //-------------------------------------------------------------------- + + /** + * LIMIT string + * + * Generates a platform-specific LIMIT clause. + * + * @param string $sql SQL Query + * + * @return string + */ + protected function _limit(string $sql, bool $offsetIgnore = false): string + { + return $sql . ' LIMIT ' . $this->QBLimit . ($this->QBOffset ? " OFFSET {$this->QBOffset}" : ''); + } + + //-------------------------------------------------------------------- + + /** + * Update statement + * + * Generates a platform-specific update string from the supplied data + * + * @param string $table + * @param array $values + * + * @return string + * @throws DatabaseException + * @internal param the $string table name + * @internal param the $array update data + */ + protected function _update(string $table, array $values): string + { + if (! empty($this->QBLimit)) + { + throw new DatabaseException('Postgres does not support LIMITs with UPDATE queries.'); + } + + $this->QBOrderBy = []; + return parent::_update($table, $values); + } + + //-------------------------------------------------------------------- + + /** + * Update_Batch statement + * + * Generates a platform-specific batch update string from the supplied data + * + * @param string $table Table name + * @param array $values Update data + * @param string $index WHERE key + * + * @return string + */ + protected function _updateBatch(string $table, array $values, string $index): string + { + $ids = []; + foreach ($values as $val) + { + $ids[] = $val[$index]; + + foreach (array_keys($val) as $field) + { + if ($field !== $index) + { + $final[$field][] = "WHEN {$val[$index]} THEN {$val[$field]}"; + } + } + } + + $cases = ''; + foreach ($final as $k => $v) + { + $cases .= "{$k} = (CASE {$index}\n" + . implode("\n", $v) + . "\nELSE {$k} END), "; + } + + $this->where("{$index} IN(" . implode(',', $ids) . ')', null, false); + + return "UPDATE {$table} SET " . substr($cases, 0, -2) . $this->compileWhereHaving('QBWhere'); + } + + //-------------------------------------------------------------------- + + /** + * Delete statement + * + * Generates a platform-specific delete string from the supplied data + * + * @param string $table The table name + * + * @return string + */ + protected function _delete(string $table): string + { + $this->QBLimit = false; + return parent::_delete($table); + } + + //-------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * + * If the database does not support the truncate() command, + * then this method maps to 'DELETE FROM table' + * + * @param string $table The table name + * + * @return string + */ + protected function _truncate(string $table): string + { + return 'TRUNCATE ' . $table . ' RESTART IDENTITY'; + } + + //-------------------------------------------------------------------- + + /** + * Platform independent LIKE statement builder. + * + * In PostgreSQL, the ILIKE operator will perform case insensitive + * searches according to the current locale. + * + * @see https://www.postgresql.org/docs/9.2/static/functions-matching.html + * + * @param string $prefix + * @param string $column + * @param string $not + * @param string $bind + * @param boolean $insensitiveSearch + * + * @return string $like_statement + */ + public function _like_statement(string $prefix = null, string $column, string $not = null, string $bind, bool $insensitiveSearch = false): string + { + $op = $insensitiveSearch === true ? 'ILIKE' : 'LIKE'; + + return "{$prefix} {$column} {$not} {$op} :{$bind}:"; + } + + //-------------------------------------------------------------------- + + /** + * JOIN + * + * Generates the JOIN portion of the query + * + * @param string $table + * @param string $cond The join condition + * @param string $type The type of join + * @param boolean $escape Whether not to try to escape identifiers + * + * @return BaseBuilder + */ + public function join(string $table, string $cond, string $type = '', bool $escape = null) + { + if (! in_array('FULL OUTER', $this->joinTypes, true)) + { + $this->joinTypes = array_merge($this->joinTypes, ['FULL OUTER']); + } + + return parent::join($table, $cond, $type, $escape); + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Database/Postgre/Connection.php b/vendor/codeigniter4/framework/system/Database/Postgre/Connection.php new file mode 100644 index 0000000..c3d6db6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Postgre/Connection.php @@ -0,0 +1,626 @@ +DSN)) + { + $this->buildDSN(); + } + + // Strip pgsql if exists + if (mb_strpos($this->DSN, 'pgsql:') === 0) + { + $this->DSN = mb_substr($this->DSN, 6); + } + + // Convert semicolons to spaces. + $this->DSN = str_replace(';', ' ', $this->DSN); + + $this->connID = $persistent === true ? pg_pconnect($this->DSN) : pg_connect($this->DSN); + + if ($this->connID !== false) + { + if ($persistent === true && pg_connection_status($this->connID) === PGSQL_CONNECTION_BAD && pg_ping($this->connID) === false + ) + { + return false; + } + + empty($this->schema) || $this->simpleQuery("SET search_path TO {$this->schema},public"); + + if ($this->setClientEncoding($this->charset) === false) + { + return false; + } + } + + return $this->connID; + } + + //-------------------------------------------------------------------- + + /** + * Keep or establish the connection if no queries have been sent for + * a length of time exceeding the server's idle timeout. + * + * @return void + */ + public function reconnect() + { + if (pg_ping($this->connID) === false) + { + $this->connID = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Close the database connection. + * + * @return void + */ + protected function _close() + { + pg_close($this->connID); + } + + //-------------------------------------------------------------------- + + /** + * Select a specific database table to use. + * + * @param string $databaseName + * + * @return boolean + */ + public function setDatabase(string $databaseName): bool + { + return false; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string containing the version of the database being used. + * + * @return string + */ + public function getVersion(): string + { + if (isset($this->dataCache['version'])) + { + return $this->dataCache['version']; + } + + if (! $this->connID || ( $pgVersion = pg_version($this->connID)) === false) + { + $this->initialize(); + } + + return isset($pgVersion['server']) ? $this->dataCache['version'] = $pgVersion['server'] : false; + } + + //-------------------------------------------------------------------- + + /** + * Executes the query against the database. + * + * @param string $sql + * + * @return mixed + */ + public function execute(string $sql) + { + try + { + return pg_query($this->connID, $sql); + } + catch (\ErrorException $e) + { + log_message('error', $e); + if ($this->DBDebug) + { + throw $e; + } + } + return false; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of rows affected by this query. + * + * @return integer + */ + public function affectedRows(): int + { + return pg_affected_rows($this->resultID); + } + + //-------------------------------------------------------------------- + + /** + * "Smart" Escape String + * + * Escapes data based on type + * + * @param mixed $str + * @return mixed + */ + public function escape($str) + { + if (! $this->connID) + { + $this->initialize(); + } + + if (is_string($str) || ( is_object($str) && method_exists($str, '__toString'))) + { + return pg_escape_literal($this->connID, $str); + } + elseif (is_bool($str)) + { + return $str ? 'TRUE' : 'FALSE'; + } + + return parent::escape($str); + } + + //-------------------------------------------------------------------- + + /** + * Platform-dependant string escape + * + * @param string $str + * @return string + */ + protected function _escapeString(string $str): string + { + if (! $this->connID) + { + $this->initialize(); + } + + return pg_escape_string($this->connID, $str); + } + + //-------------------------------------------------------------------- + + /** + * Generates the SQL for listing tables in a platform-dependent manner. + * + * @param boolean $prefixLimit + * + * @return string + */ + protected function _listTables(bool $prefixLimit = false): string + { + $sql = 'SELECT "table_name" FROM "information_schema"."tables" WHERE "table_schema" = \'' . $this->schema . "'"; + + if ($prefixLimit !== false && $this->DBPrefix !== '') + { + return $sql . ' AND "table_name" LIKE \'' + . $this->escapeLikeString($this->DBPrefix) . "%' " + . sprintf($this->likeEscapeStr, $this->likeEscapeChar); + } + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Generates a platform-specific query string so that the column names can be fetched. + * + * @param string $table + * + * @return string + */ + protected function _listColumns(string $table = ''): string + { + return 'SELECT "column_name" + FROM "information_schema"."columns" + WHERE LOWER("table_name") = ' + . $this->escape($this->DBPrefix . strtolower($table)); + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with field data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _fieldData(string $table): array + { + $sql = 'SELECT "column_name", "data_type", "character_maximum_length", "numeric_precision", "column_default" + FROM "information_schema"."columns" + WHERE LOWER("table_name") = ' + . $this->escape(strtolower($table)); + + if (($query = $this->query($sql)) === false) + { + throw new DatabaseException(lang('Database.failGetFieldData')); + } + $query = $query->getResultObject(); + + $retVal = []; + for ($i = 0, $c = count($query); $i < $c; $i ++) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = $query[$i]->column_name; + $retVal[$i]->type = $query[$i]->data_type; + $retVal[$i]->default = $query[$i]->column_default; + $retVal[$i]->max_length = $query[$i]->character_maximum_length > 0 ? $query[$i]->character_maximum_length : $query[$i]->numeric_precision; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with index data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _indexData(string $table): array + { + $sql = 'SELECT "indexname", "indexdef" + FROM "pg_indexes" + WHERE LOWER("tablename") = ' . $this->escape(strtolower($table)) . ' + AND "schemaname" = ' . $this->escape('public'); + + if (($query = $this->query($sql)) === false) + { + throw new DatabaseException(lang('Database.failGetIndexData')); + } + $query = $query->getResultObject(); + + $retVal = []; + foreach ($query as $row) + { + $obj = new \stdClass(); + $obj->name = $row->indexname; + $_fields = explode(',', preg_replace('/^.*\((.+?)\)$/', '$1', trim($row->indexdef))); + $obj->fields = array_map(function ($v) { + return trim($v); + }, $_fields); + + if (strpos($row->indexdef, 'CREATE UNIQUE INDEX pk') === 0) + { + $obj->type = 'PRIMARY'; + } + else + { + $obj->type = (strpos($row->indexdef, 'CREATE UNIQUE') === 0) ? 'UNIQUE' : 'INDEX'; + } + + $retVal[$obj->name] = $obj; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with Foreign key data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _foreignKeyData(string $table): array + { + $sql = 'SELECT + tc.constraint_name, tc.table_name, kcu.column_name, + ccu.table_name AS foreign_table_name, + ccu.column_name AS foreign_column_name + FROM information_schema.table_constraints AS tc + JOIN information_schema.key_column_usage AS kcu + ON tc.constraint_name = kcu.constraint_name + JOIN information_schema.constraint_column_usage AS ccu + ON ccu.constraint_name = tc.constraint_name + WHERE constraint_type = ' . $this->escape('FOREIGN KEY') . ' AND + tc.table_name = ' . $this->escape($table); + + if (($query = $this->query($sql)) === false) + { + throw new DatabaseException(lang('Database.failGetForeignKeyData')); + } + $query = $query->getResultObject(); + + $retVal = []; + foreach ($query as $row) + { + $obj = new \stdClass(); + $obj->constraint_name = $row->constraint_name; + $obj->table_name = $row->table_name; + $obj->column_name = $row->column_name; + $obj->foreign_table_name = $row->foreign_table_name; + $obj->foreign_column_name = $row->foreign_column_name; + $retVal[] = $obj; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to disable foreign key checks. + * + * @return string + */ + protected function _disableForeignKeyChecks() + { + return 'SET CONSTRAINTS ALL DEFERRED'; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to enable foreign key checks. + * + * @return string + */ + protected function _enableForeignKeyChecks() + { + return 'SET CONSTRAINTS ALL IMMEDIATE;'; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last error code and message. + * + * Must return an array with keys 'code' and 'message': + * + * return ['code' => null, 'message' => null); + * + * @return array + */ + public function error(): array + { + return [ + 'code' => '', + 'message' => pg_last_error($this->connID), + ]; + } + + //-------------------------------------------------------------------- + + /** + * Insert ID + * + * @return integer + */ + public function insertID(): int + { + $v = pg_version($this->connID); + // 'server' key is only available since PostgreSQL 7.4 + $v = explode(' ', $v['server'])[0] ?? 0; + + $table = func_num_args() > 0 ? func_get_arg(0) : null; + $column = func_num_args() > 1 ? func_get_arg(1) : null; + + if ($table === null && $v >= '8.1') + { + $sql = 'SELECT LASTVAL() AS ins_id'; + } + elseif ($table !== null) + { + if ($column !== null && $v >= '8.0') + { + $sql = "SELECT pg_get_serial_sequence('{$table}', '{$column}') AS seq"; + $query = $this->query($sql); + $query = $query->getRow(); + $seq = $query->seq; + } + else + { + // seq_name passed in table parameter + $seq = $table; + } + + $sql = "SELECT CURRVAL('{$seq}') AS ins_id"; + } + else + { + return pg_last_oid($this->resultID); + } + + $query = $this->query($sql); + $query = $query->getRow(); + return (int) $query->ins_id; + } + + //-------------------------------------------------------------------- + + /** + * Build a DSN from the provided parameters + * + * @return void + */ + protected function buildDSN() + { + $this->DSN === '' || $this->DSN = ''; + + // If UNIX sockets are used, we shouldn't set a port + if (strpos($this->hostname, '/') !== false) + { + $this->port = ''; + } + + $this->hostname === '' || $this->DSN = "host={$this->hostname} "; + + if (! empty($this->port) && ctype_digit($this->port)) + { + $this->DSN .= "port={$this->port} "; + } + + if ($this->username !== '') + { + $this->DSN .= "user={$this->username} "; + + // An empty password is valid! + // password must be set to null to ignore it. + + $this->password === null || $this->DSN .= "password='{$this->password}' "; + } + + $this->database === '' || $this->DSN .= "dbname={$this->database} "; + + // We don't have these options as elements in our standard configuration + // array, but they might be set by parse_url() if the configuration was + // provided via string> Example: + // + // postgre://username:password@localhost:5432/database?connect_timeout=5&sslmode=1 + foreach (['connect_timeout', 'options', 'sslmode', 'service'] as $key) + { + if (isset($this->{$key}) && is_string($this->{$key}) && $this->{$key} !== '') + { + $this->DSN .= "{$key}='{$this->{$key}}' "; + } + } + + $this->DSN = rtrim($this->DSN); + } + + //-------------------------------------------------------------------- + + /** + * Set client encoding + * + * @param string $charset The client encoding to which the data will be converted. + * @return boolean + */ + protected function setClientEncoding(string $charset): bool + { + return pg_set_client_encoding($this->connID, $charset) === 0; + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return boolean + */ + protected function _transBegin(): bool + { + return (bool) pg_query($this->connID, 'BEGIN'); + } + + // -------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + protected function _transCommit(): bool + { + return (bool) pg_query($this->connID, 'COMMIT'); + } + + // -------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + protected function _transRollback(): bool + { + return (bool) pg_query($this->connID, 'ROLLBACK'); + } + + // -------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/Postgre/Forge.php b/vendor/codeigniter4/framework/system/Database/Postgre/Forge.php new file mode 100644 index 0000000..9b0bbdb --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Postgre/Forge.php @@ -0,0 +1,261 @@ + 'INTEGER', + 'SMALLINT' => 'INTEGER', + 'INT' => 'BIGINT', + 'INT4' => 'BIGINT', + 'INTEGER' => 'BIGINT', + 'INT8' => 'NUMERIC', + 'BIGINT' => 'NUMERIC', + 'REAL' => 'DOUBLE PRECISION', + 'FLOAT' => 'DOUBLE PRECISION', + ]; + + /** + * NULL value representation in CREATE/ALTER TABLE statements + * + * @var string + */ + protected $_null = 'NULL'; + + //-------------------------------------------------------------------- + + /** + * CREATE TABLE attributes + * + * @param array $attributes Associative array of table attributes + * @return string + */ + protected function _createTableAttributes(array $attributes): string + { + return ''; + } + + //-------------------------------------------------------------------- + + /** + * ALTER TABLE + * + * @param string $alter_type ALTER type + * @param string $table Table name + * @param mixed $field Column definition + * + * @return string|array + */ + protected function _alterTable(string $alter_type, string $table, $field) + { + if (in_array($alter_type, ['DROP', 'ADD'], true)) + { + return parent::_alterTable($alter_type, $table, $field); + } + + $sql = 'ALTER TABLE ' . $this->db->escapeIdentifiers($table); + $sqls = []; + foreach ($field as $data) + { + if ($data['_literal'] !== false) + { + return false; + } + + if (version_compare($this->db->getVersion(), '8', '>=') && isset($data['type'])) + { + $sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($data['name']) + . " TYPE {$data['type']}{$data['length']}"; + } + + if (! empty($data['default'])) + { + $sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($data['name']) + . " SET DEFAULT {$data['default']}"; + } + + if (isset($data['null'])) + { + $sqls[] = $sql . ' ALTER COLUMN ' . $this->db->escapeIdentifiers($data['name']) + . ($data['null'] === true ? ' DROP' : ' SET') . ' NOT NULL'; + } + + if (! empty($data['new_name'])) + { + $sqls[] = $sql . ' RENAME COLUMN ' . $this->db->escapeIdentifiers($data['name']) + . ' TO ' . $this->db->escapeIdentifiers($data['new_name']); + } + + if (! empty($data['comment'])) + { + $sqls[] = 'COMMENT ON COLUMN' . $this->db->escapeIdentifiers($table) + . '.' . $this->db->escapeIdentifiers($data['name']) + . " IS {$data['comment']}"; + } + } + + return $sqls; + } + + //-------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * @return string + */ + protected function _processColumn(array $field): string + { + return $this->db->escapeIdentifiers($field['name']) + . ' ' . $field['type'] . $field['length'] + . $field['default'] + . $field['null'] + . $field['auto_increment'] + . $field['unique']; + } + + //-------------------------------------------------------------------- + + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * + * @return void + */ + protected function _attributeType(array &$attributes) + { + // Reset field lengths for data types that don't support it + if (isset($attributes['CONSTRAINT']) && stripos($attributes['TYPE'], 'int') !== false) + { + $attributes['CONSTRAINT'] = null; + } + + switch (strtoupper($attributes['TYPE'])) + { + case 'TINYINT': + $attributes['TYPE'] = 'SMALLINT'; + $attributes['UNSIGNED'] = false; + break; + case 'MEDIUMINT': + $attributes['TYPE'] = 'INTEGER'; + $attributes['UNSIGNED'] = false; + break; + case 'DATETIME': + $attributes['TYPE'] = 'TIMESTAMP'; + break; + default: + break; + } + } + + //-------------------------------------------------------------------- + + /** + * Field attribute AUTO_INCREMENT + * + * @param array &$attributes + * @param array &$field + * + * @return void + */ + protected function _attributeAutoIncrement(array &$attributes, array &$field) + { + if (! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === true) + { + $field['type'] = $field['type'] === 'NUMERIC' || $field['type'] === 'BIGINT' ? 'BIGSERIAL' : 'SERIAL'; + } + } + + //-------------------------------------------------------------------- + + /** + * Drop Table + * + * Generates a platform-specific DROP TABLE string + * + * @param string $table Table name + * @param boolean $if_exists Whether to add an IF EXISTS condition + * @param boolean $cascade + * + * @return string + */ + protected function _dropTable(string $table, bool $if_exists, bool $cascade): string + { + $sql = parent::_dropTable($table, $if_exists, $cascade); + + if ($cascade === true) + { + $sql .= ' CASCADE'; + } + + return $sql; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Database/Postgre/PreparedQuery.php b/vendor/codeigniter4/framework/system/Database/Postgre/PreparedQuery.php new file mode 100644 index 0000000..27e3da2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Postgre/PreparedQuery.php @@ -0,0 +1,158 @@ +name = random_int(1, 10000000000000000); + + $sql = $this->parameterize($sql); + + // Update the query object since the parameters are slightly different + // than what was put in. + $this->query->setQuery($sql); + + if (! $this->statement = pg_prepare($this->db->connID, $this->name, $sql)) + { + $this->errorCode = 0; + $this->errorString = pg_last_error($this->db->connID); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Takes a new set of data and runs it against the currently + * prepared query. Upon success, will return a Results object. + * + * @param array $data + * + * @return boolean + */ + public function _execute(array $data): bool + { + if (is_null($this->statement)) + { + throw new \BadMethodCallException('You must call prepare before trying to execute a prepared statement.'); + } + + $this->result = pg_execute($this->db->connID, $this->name, $data); + + return (bool) $this->result; + } + + //-------------------------------------------------------------------- + + /** + * Returns the result object for the prepared query. + * + * @return mixed + */ + public function _getResult() + { + return $this->result; + } + + //-------------------------------------------------------------------- + + /** + * Replaces the ? placeholders with $1, $2, etc parameters for use + * within the prepared query. + * + * @param string $sql + * + * @return string + */ + public function parameterize(string $sql): string + { + // Track our current value + $count = 0; + + return preg_replace_callback('/\?/', function ($matches) use (&$count) { + $count ++; + return "\${$count}"; + }, $sql); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/Postgre/Result.php b/vendor/codeigniter4/framework/system/Database/Postgre/Result.php new file mode 100644 index 0000000..fcdd509 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Postgre/Result.php @@ -0,0 +1,173 @@ +resultID); + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of column names in the result set. + * + * @return array + */ + public function getFieldNames(): array + { + $fieldNames = []; + for ($i = 0, $c = $this->getFieldCount(); $i < $c; $i ++) + { + $fieldNames[] = pg_field_name($this->resultID, $i); + } + + return $fieldNames; + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of objects representing field meta-data. + * + * @return array + */ + public function getFieldData(): array + { + $retVal = []; + + for ($i = 0, $c = $this->getFieldCount(); $i < $c; $i ++) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = pg_field_name($this->resultID, $i); + $retVal[$i]->type = pg_field_type_oid($this->resultID, $i); + $retVal[$i]->type_name = pg_field_type($this->resultID, $i); + $retVal[$i]->max_length = pg_field_size($this->resultID, $i); + $retVal[$i]->length = $retVal[$i]->max_length; + // $retVal[$i]->primary_key = (int)($fieldData[$i]->flags & 2); + // $retVal[$i]->default = $fieldData[$i]->def; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Frees the current result. + * + * @return void + */ + public function freeResult() + { + if (is_resource($this->resultID)) + { + pg_free_result($this->resultID); + $this->resultID = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Moves the internal pointer to the desired offset. This is called + * internally before fetching results to make sure the result set + * starts at zero. + * + * @param integer $n + * + * @return mixed + */ + public function dataSeek(int $n = 0) + { + return pg_result_seek($this->resultID, $n); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an array. + * + * Overridden by driver classes. + * + * @return mixed + */ + protected function fetchAssoc() + { + return pg_fetch_assoc($this->resultID); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an object. + * + * Overridden by child classes. + * + * @param string $className + * + * @return object|boolean|Entity + */ + protected function fetchObject(string $className = 'stdClass') + { + if (is_subclass_of($className, Entity::class)) + { + return empty($data = $this->fetchAssoc()) ? false : (new $className())->setAttributes($data); + } + return pg_fetch_object($this->resultID, null, $className); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/Postgre/Utils.php b/vendor/codeigniter4/framework/system/Database/Postgre/Utils.php new file mode 100644 index 0000000..dd45de1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/Postgre/Utils.php @@ -0,0 +1,79 @@ +db = $db; + } + + //-------------------------------------------------------------------- + + /** + * Sets the raw query string to use for this statement. + * + * @param string $sql + * @param mixed $binds + * @param boolean $setEscape + * + * @return $this + */ + public function setQuery(string $sql, $binds = null, bool $setEscape = true) + { + $this->originalQueryString = $sql; + + if (! is_null($binds)) + { + if (! is_array($binds)) + { + $binds = [$binds]; + } + + if ($setEscape) + { + array_walk($binds, function (&$item) { + $item = [ + $item, + true, + ]; + }); + } + $this->binds = $binds; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Will store the variables to bind into the query later. + * + * @param array $binds + * + * @return $this + */ + public function setBinds(array $binds) + { + $this->binds = $binds; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the final, processed query string after binding, etal + * has been performed. + * + * @return string + */ + public function getQuery(): string + { + if (empty($this->finalQueryString)) + { + $this->finalQueryString = $this->originalQueryString; + } + + $this->compileBinds(); + + return $this->finalQueryString; + } + + //-------------------------------------------------------------------- + + /** + * Records the execution time of the statement using microtime(true) + * for it's start and end values. If no end value is present, will + * use the current time to determine total duration. + * + * @param float $start + * @param float $end + * + * @return $this + */ + public function setDuration(float $start, float $end = null) + { + $this->startTime = $start; + + if (is_null($end)) + { + $end = microtime(true); + } + + $this->endTime = $end; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the start time in seconds with microseconds. + * + * @param boolean $returnRaw + * @param integer $decimals + * + * @return string + */ + public function getStartTime(bool $returnRaw = false, int $decimals = 6): string + { + if ($returnRaw) + { + return $this->startTime; + } + + return number_format($this->startTime, $decimals); + } + + //-------------------------------------------------------------------- + /** + * Returns the duration of this query during execution, or null if + * the query has not been executed yet. + * + * @param integer $decimals The accuracy of the returned time. + * + * @return string + */ + public function getDuration(int $decimals = 6): string + { + return number_format(($this->endTime - $this->startTime), $decimals); + } + + //-------------------------------------------------------------------- + + /** + * Stores the error description that happened for this query. + * + * @param integer $code + * @param string $error + * + * @return $this + */ + public function setError(int $code, string $error) + { + $this->errorCode = $code; + $this->errorString = $error; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Reports whether this statement created an error not. + * + * @return boolean + */ + public function hasError(): bool + { + return ! empty($this->errorString); + } + + //-------------------------------------------------------------------- + + /** + * Returns the error code created while executing this statement. + * + * @return integer + */ + public function getErrorCode(): int + { + return $this->errorCode; + } + + //-------------------------------------------------------------------- + + /** + * Returns the error message created while executing this statement. + * + * @return string + */ + public function getErrorMessage(): string + { + return $this->errorString; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the statement is a write-type query or not. + * + * @return boolean + */ + public function isWriteType(): bool + { + return (bool) preg_match( + '/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', $this->originalQueryString); + } + + //-------------------------------------------------------------------- + + /** + * Swaps out one table prefix for a new one. + * + * @param string $orig + * @param string $swap + * + * @return $this + */ + public function swapPrefix(string $orig, string $swap) + { + $sql = empty($this->finalQueryString) ? $this->originalQueryString : $this->finalQueryString; + + $this->finalQueryString = preg_replace('/(\W)' . $orig . '(\S+?)/', '\\1' . $swap . '\\2', $sql); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the original SQL that was passed into the system. + * + * @return string + */ + public function getOriginalQuery(): string + { + return $this->originalQueryString; + } + + //-------------------------------------------------------------------- + + /** + * Escapes and inserts any binds into the finalQueryString object. + * + * @return null|void + */ + protected function compileBinds() + { + $sql = $this->finalQueryString; + + $hasNamedBinds = strpos($sql, ':') !== false && strpos($sql, ':=') === false; + + if (empty($this->binds) || empty($this->bindMarker) || + (strpos($sql, $this->bindMarker) === false && + $hasNamedBinds === false) + ) + { + return; + } + + if (! is_array($this->binds)) + { + $binds = [$this->binds]; + $bindCount = 1; + } + else + { + $binds = $this->binds; + $bindCount = count($binds); + } + + // Reverse the binds so that duplicate named binds + // will be processed prior to the original binds. + if (! is_numeric(key(array_slice($binds, 0, 1)))) + { + $binds = array_reverse($binds); + } + + // We'll need marker length later + $ml = strlen($this->bindMarker); + + if ($hasNamedBinds) + { + $sql = $this->matchNamedBinds($sql, $binds); + } + else + { + $sql = $this->matchSimpleBinds($sql, $binds, $bindCount, $ml); + } + + $this->finalQueryString = $sql; + } + + //-------------------------------------------------------------------- + + /** + * Match bindings + * + * @param string $sql + * @param array $binds + * @return string + */ + protected function matchNamedBinds(string $sql, array $binds): string + { + $replacers = []; + + foreach ($binds as $placeholder => $value) + { + // $value[1] contains the boolean whether should be escaped or not + $escapedValue = $value[1] ? $this->db->escape($value[0]) : $value[0]; + + // In order to correctly handle backlashes in saved strings + // we will need to preg_quote, so remove the wrapping escape characters + // otherwise it will get escaped. + if (is_array($value[0])) + { + $escapedValue = '(' . implode(',', $escapedValue) . ')'; + } + + $replacers[":{$placeholder}:"] = $escapedValue; + } + + return strtr($sql, $replacers); + } + + //-------------------------------------------------------------------- + + /** + * Match bindings + * + * @param string $sql + * @param array $binds + * @param integer $bindCount + * @param integer $ml + * @return string + */ + protected function matchSimpleBinds(string $sql, array $binds, int $bindCount, int $ml): string + { + // Make sure not to replace a chunk inside a string that happens to match the bind marker + if ($c = preg_match_all("/'[^']*'/i", $sql, $matches)) + { + $c = preg_match_all('/' . preg_quote($this->bindMarker, '/') . '/i', str_replace($matches[0], str_replace($this->bindMarker, str_repeat(' ', $ml), $matches[0]), $sql, $c), $matches, PREG_OFFSET_CAPTURE); + + // Bind values' count must match the count of markers in the query + if ($bindCount !== $c) + { + return $sql; + } + } + // Number of binds must match bindMarkers in the string. + else if (($c = preg_match_all('/' . preg_quote($this->bindMarker, '/') . '/i', $sql, $matches, PREG_OFFSET_CAPTURE)) !== $bindCount) + { + return $sql; + } + + do + { + $c--; + $escapedValue = $binds[$c][1] ? $this->db->escape($binds[$c][0]) : $binds[$c][0]; + if (is_array($escapedValue)) + { + $escapedValue = '(' . implode(',', $escapedValue) . ')'; + } + $sql = substr_replace($sql, $escapedValue, $matches[0][$c][1], $ml); + } + while ($c !== 0); + + return $sql; + } + + //-------------------------------------------------------------------- + + /** + * Return text representation of the query + * + * @return string + */ + public function __toString(): string + { + return $this->getQuery(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/QueryInterface.php b/vendor/codeigniter4/framework/system/Database/QueryInterface.php new file mode 100644 index 0000000..4a2781e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/QueryInterface.php @@ -0,0 +1,159 @@ + 'OR IGNORE', + ]; + + //-------------------------------------------------------------------- + + /** + * Replace statement + * + * Generates a platform-specific replace string from the supplied data + * + * @param string $table the table name + * @param array $keys the insert keys + * @param array $values the insert values + * + * @return string + */ + protected function _replace(string $table, array $keys, array $values): string + { + return 'INSERT OR ' . parent::_replace($table, $keys, $values); + } + + //-------------------------------------------------------------------- + + /** + * Truncate statement + * + * Generates a platform-specific truncate string from the supplied data + * + * If the database does not support the TRUNCATE statement, + * then this method maps to 'DELETE FROM table' + * + * @param string $table + * @return string + */ + protected function _truncate(string $table): string + { + return 'DELETE FROM ' . $table; + } + +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/Connection.php b/vendor/codeigniter4/framework/system/Database/SQLite3/Connection.php new file mode 100644 index 0000000..b9851e3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/Connection.php @@ -0,0 +1,566 @@ +db->DBDebug) + { + throw new DatabaseException('SQLite3 doesn\'t support persistent connections.'); + } + try + { + if ($this->database !== ':memory:' && strpos($this->database, DIRECTORY_SEPARATOR) === false) + { + $this->database = WRITEPATH . $this->database; + } + + return (! $this->password) + ? new \SQLite3($this->database) + : new \SQLite3($this->database, SQLITE3_OPEN_READWRITE | SQLITE3_OPEN_CREATE, $this->password); + } + catch (\Exception $e) + { + throw new DatabaseException('SQLite3 error: ' . $e->getMessage()); + } + } + + //-------------------------------------------------------------------- + + /** + * Keep or establish the connection if no queries have been sent for + * a length of time exceeding the server's idle timeout. + * + * @return void + */ + public function reconnect() + { + $this->close(); + $this->initialize(); + } + + //-------------------------------------------------------------------- + + /** + * Close the database connection. + * + * @return void + */ + protected function _close() + { + $this->connID->close(); + } + + //-------------------------------------------------------------------- + + /** + * Select a specific database table to use. + * + * @param string $databaseName + * + * @return boolean + */ + public function setDatabase(string $databaseName): bool + { + return false; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string containing the version of the database being used. + * + * @return string + */ + public function getVersion(): string + { + if (isset($this->dataCache['version'])) + { + return $this->dataCache['version']; + } + + $version = \SQLite3::version(); + + return $this->dataCache['version'] = $version['versionString']; + } + + //-------------------------------------------------------------------- + + /** + * Execute the query + * + * @param string $sql + * + * @return mixed \SQLite3Result object or bool + */ + public function execute(string $sql) + { + try + { + return $this->isWriteType($sql) + ? $this->connID->exec($sql) + : $this->connID->query($sql); + } + catch (\ErrorException $e) + { + log_message('error', $e); + if ($this->DBDebug) + { + throw $e; + } + } + return false; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of rows affected by this query. + * + * @return integer + */ + public function affectedRows(): int + { + return $this->connID->changes(); + } + + //-------------------------------------------------------------------- + + /** + * Platform-dependant string escape + * + * @param string $str + * + * @return string + */ + protected function _escapeString(string $str): string + { + return $this->connID->escapeString($str); + } + + //-------------------------------------------------------------------- + + /** + * Generates the SQL for listing tables in a platform-dependent manner. + * + * @param boolean $prefixLimit + * + * @return string + */ + protected function _listTables(bool $prefixLimit = false): string + { + return 'SELECT "NAME" FROM "SQLITE_MASTER" WHERE "TYPE" = \'table\'' + . ' AND "NAME" NOT LIKE \'sqlite!_%\' ESCAPE \'!\'' + . (($prefixLimit !== false && $this->DBPrefix !== '') + ? ' AND "NAME" LIKE \'' . $this->escapeLikeString($this->DBPrefix) . '%\' ' . sprintf($this->likeEscapeStr, + $this->likeEscapeChar) + : ''); + } + + //-------------------------------------------------------------------- + + /** + * Generates a platform-specific query string so that the column names can be fetched. + * + * @param string $table + * + * @return string + */ + protected function _listColumns(string $table = ''): string + { + return 'PRAGMA TABLE_INFO(' . $this->protectIdentifiers($table, true, null, false) . ')'; + } + + /** + * Fetch Field Names + * + * @param string $table Table name + * + * @return array|false + * @throws DatabaseException + */ + public function getFieldNames(string $table) + { + // Is there a cached result? + if (isset($this->dataCache['field_names'][$table])) + { + return $this->dataCache['field_names'][$table]; + } + + if (empty($this->connID)) + { + $this->initialize(); + } + + if (false === ($sql = $this->_listColumns($table))) + { + if ($this->DBDebug) + { + throw new DatabaseException(lang('Database.featureUnavailable')); + } + + return false; + } + + $query = $this->query($sql); + $this->dataCache['field_names'][$table] = []; + + foreach ($query->getResultArray() as $row) + { + // Do we know from where to get the column's name? + if (! isset($key)) + { + if (isset($row['column_name'])) + { + $key = 'column_name'; + } + elseif (isset($row['COLUMN_NAME'])) + { + $key = 'COLUMN_NAME'; + } + elseif (isset($row['name'])) + { + $key = 'name'; + } + else + { + // We have no other choice but to just get the first element's key. + $key = key($row); + } + } + + $this->dataCache['field_names'][$table][] = $row[$key]; + } + + return $this->dataCache['field_names'][$table]; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with field data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _fieldData(string $table): array + { + if (($query = $this->query('PRAGMA TABLE_INFO(' . $this->protectIdentifiers($table, true, null, + false) . ')')) === false) + { + throw new DatabaseException(lang('Database.failGetFieldData')); + } + $query = $query->getResultObject(); + + if (empty($query)) + { + return []; + } + $retVal = []; + for ($i = 0, $c = count($query); $i < $c; $i++) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = $query[$i]->name; + $retVal[$i]->type = $query[$i]->type; + $retVal[$i]->max_length = null; + $retVal[$i]->default = $query[$i]->dflt_value; + $retVal[$i]->primary_key = isset($query[$i]->pk) && (bool)$query[$i]->pk; + $retVal[$i]->nullable = isset($query[$i]->notnull) && ! (bool)$query[$i]->notnull; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with index data + * + * @param string $table + * @return \stdClass[] + * @throws DatabaseException + */ + public function _indexData(string $table): array + { + // Get indexes + // Don't use PRAGMA index_list, so we can preserve index order + $sql = "SELECT name FROM sqlite_master WHERE type='index' AND tbl_name=" . $this->escape(strtolower($table)); + if (($query = $this->query($sql)) === false) + { + throw new DatabaseException(lang('Database.failGetIndexData')); + } + $query = $query->getResultObject(); + + $retVal = []; + foreach ($query as $row) + { + $obj = new \stdClass(); + $obj->name = $row->name; + + // Get fields for index + $obj->fields = []; + if (($fields = $this->query('PRAGMA index_info(' . $this->escape(strtolower($row->name)) . ')')) === false) + { + throw new DatabaseException(lang('Database.failGetIndexData')); + } + $fields = $fields->getResultObject(); + + foreach ($fields as $field) + { + $obj->fields[] = $field->name; + } + + $retVal[$obj->name] = $obj; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of objects with Foreign key data + * + * @param string $table + * @return \stdClass[] + */ + public function _foreignKeyData(string $table): array + { + if ($this->supportsForeignKeys() !== true) + { + return []; + } + + $tables = $this->listTables(); + + if (empty($tables)) + { + return []; + } + + $retVal = []; + + foreach ($tables as $table) + { + $query = $this->query("PRAGMA foreign_key_list({$table})")->getResult(); + + foreach ($query as $row) + { + $obj = new \stdClass(); + $obj->constraint_name = $row->from . ' to ' . $row->table . '.' . $row->to; + $obj->table_name = $table; + $obj->foreign_table_name = $row->table; + $obj->sequence = $row->seq; + + $retVal[] = $obj; + } + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to disable foreign key checks. + * + * @return string + */ + protected function _disableForeignKeyChecks() + { + return 'PRAGMA foreign_keys = OFF'; + } + + //-------------------------------------------------------------------- + + /** + * Returns platform-specific SQL to enable foreign key checks. + * + * @return string + */ + protected function _enableForeignKeyChecks() + { + return 'PRAGMA foreign_keys = ON'; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last error code and message. + * + * Must return an array with keys 'code' and 'message': + * + * return ['code' => null, 'message' => null); + * + * @return array + */ + public function error(): array + { + return [ + 'code' => $this->connID->lastErrorCode(), + 'message' => $this->connID->lastErrorMsg(), + ]; + } + + //-------------------------------------------------------------------- + + /** + * Insert ID + * + * @return integer + */ + public function insertID(): int + { + return $this->connID->lastInsertRowID(); + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return boolean + */ + protected function _transBegin(): bool + { + return $this->connID->exec('BEGIN TRANSACTION'); + } + + //-------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + protected function _transCommit(): bool + { + return $this->connID->exec('END TRANSACTION'); + } + + //-------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + protected function _transRollback(): bool + { + return $this->connID->exec('ROLLBACK'); + } + + //-------------------------------------------------------------------- + + /** + * Determines if the statement is a write-type query or not. + * + * @return boolean + */ + public function isWriteType($sql): bool + { + return (bool)preg_match( + '/^\s*"?(SET|INSERT|UPDATE|DELETE|REPLACE|CREATE|DROP|TRUNCATE|LOAD|COPY|ALTER|RENAME|GRANT|REVOKE|LOCK|UNLOCK|REINDEX)\s/i', + $sql); + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if the current install supports Foreign Keys + * and has them enabled. + * + * @return boolean + */ + public function supportsForeignKeys(): bool + { + $result = $this->simpleQuery('PRAGMA foreign_keys'); + + return (bool)$result; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/Forge.php b/vendor/codeigniter4/framework/system/Database/SQLite3/Forge.php new file mode 100644 index 0000000..bb6f482 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/Forge.php @@ -0,0 +1,331 @@ +db->getVersion(), '3.3', '<')) + { + $this->createTableIfStr = false; + $this->dropTableIfStr = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Create database + * + * @param string $dbName + * @param boolean $ifNotExists Whether to add IF NOT EXISTS condition + * + * @return boolean + */ + public function createDatabase(string $dbName, bool $ifNotExists = false): bool + { + // In SQLite, a database is created when you connect to the database. + // We'll return TRUE so that an error isn't generated. + return true; + } + + //-------------------------------------------------------------------- + + /** + * Drop database + * + * @param string $dbName + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropDatabase(string $dbName): bool + { + // In SQLite, a database is dropped when we delete a file + if (! is_file($dbName)) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unable to drop the specified database.'); + } + + return false; + } + + // We need to close the pseudo-connection first + $this->db->close(); + if (! @unlink($dbName)) + { + if ($this->db->DBDebug) + { + throw new DatabaseException('Unable to drop the specified database.'); + } + + return false; + } + + if (! empty($this->db->dataCache['db_names'])) + { + $key = array_search(strtolower($dbName), array_map('strtolower', $this->db->dataCache['db_names']), true); + if ($key !== false) + { + unset($this->db->dataCache['db_names'][$key]); + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * ALTER TABLE + * + * @param string $alter_type ALTER type + * @param string $table Table name + * @param mixed $field Column definition + * + * @return string|array + */ + protected function _alterTable(string $alter_type, string $table, $field) + { + switch ($alter_type) + { + case 'DROP': + $sqlTable = new Table($this->db, $this); + + $sqlTable->fromTable($table) + ->dropColumn($field) + ->run(); + + return ''; + case 'CHANGE': + $sqlTable = new Table($this->db, $this); + + $sqlTable->fromTable($table) + ->modifyColumn($field) + ->run(); + + return null; + default: + return parent::_alterTable($alter_type, $table, $field); + } + } + + //-------------------------------------------------------------------- + + /** + * Process column + * + * @param array $field + * + * @return string + */ + protected function _processColumn(array $field): string + { + if ($field['type'] === 'TEXT' && strpos($field['length'], "('") === 0) + { + $field['type'] .= ' CHECK(' . $this->db->escapeIdentifiers($field['name']) + . ' IN ' . $field['length'] . ')'; + } + + return $this->db->escapeIdentifiers($field['name']) + . ' ' . $field['type'] + . $field['auto_increment'] + . $field['null'] + . $field['unique'] + . $field['default']; + } + + //-------------------------------------------------------------------- + + /** + * Process indexes + * + * @param string $table + * + * @return array + */ + protected function _processIndexes(string $table): array + { + $sqls = []; + + for ($i = 0, $c = count($this->keys); $i < $c; $i++) + { + $this->keys[$i] = (array)$this->keys[$i]; + + for ($i2 = 0, $c2 = count($this->keys[$i]); $i2 < $c2; $i2++) + { + if (! isset($this->fields[$this->keys[$i][$i2]])) + { + unset($this->keys[$i][$i2]); + } + } + if (count($this->keys[$i]) <= 0) + { + continue; + } + + if (in_array($i, $this->uniqueKeys)) + { + $sqls[] = 'CREATE UNIQUE INDEX ' . $this->db->escapeIdentifiers($table . '_' . implode('_', $this->keys[$i])) + . ' ON ' . $this->db->escapeIdentifiers($table) + . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ');'; + continue; + } + + $sqls[] = 'CREATE INDEX ' . $this->db->escapeIdentifiers($table . '_' . implode('_', $this->keys[$i])) + . ' ON ' . $this->db->escapeIdentifiers($table) + . ' (' . implode(', ', $this->db->escapeIdentifiers($this->keys[$i])) . ');'; + } + + return $sqls; + } + + //-------------------------------------------------------------------- + /** + * Field attribute TYPE + * + * Performs a data type mapping between different databases. + * + * @param array &$attributes + * + * @return void + */ + protected function _attributeType(array &$attributes) + { + switch (strtoupper($attributes['TYPE'])) + { + case 'ENUM': + case 'SET': + $attributes['TYPE'] = 'TEXT'; + break; + default: + break; + } + } + + //-------------------------------------------------------------------- + + /** + * Field attribute AUTO_INCREMENT + * + * @param array &$attributes + * @param array &$field + * + * @return void + */ + protected function _attributeAutoIncrement(array &$attributes, array &$field) + { + if (! empty($attributes['AUTO_INCREMENT']) && $attributes['AUTO_INCREMENT'] === true + && stripos($field['type'], 'int') !== false) + { + $field['type'] = 'INTEGER PRIMARY KEY'; + $field['default'] = ''; + $field['null'] = ''; + $field['unique'] = ''; + $field['auto_increment'] = ' AUTOINCREMENT'; + + $this->primaryKeys = []; + } + } + + //-------------------------------------------------------------------- + + /** + * Foreign Key Drop + * + * @param string $table Table name + * @param string $foreignName Foreign name + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dropForeignKey(string $table, string $foreignName): bool + { + // If this version of SQLite doesn't support it, we're done here + if ($this->db->supportsForeignKeys() !== true) + { + return true; + } + + // Otherwise we have to copy the table and recreate + // without the foreign key being involved now + $sqlTable = new Table($this->db, $this); + + return $sqlTable->fromTable($this->db->DBPrefix . $table) + ->dropForeignKey($foreignName) + ->run(); + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/PreparedQuery.php b/vendor/codeigniter4/framework/system/Database/SQLite3/PreparedQuery.php new file mode 100644 index 0000000..22202c3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/PreparedQuery.php @@ -0,0 +1,143 @@ +statement = $this->db->connID->prepare($sql))) + { + $this->errorCode = $this->db->connID->lastErrorCode(); + $this->errorString = $this->db->connID->lastErrorMsg(); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Takes a new set of data and runs it against the currently + * prepared query. Upon success, will return a Results object. + * + * @todo finalize() + * + * @param array $data + * + * @return boolean + */ + public function _execute(array $data): bool + { + if (is_null($this->statement)) + { + throw new \BadMethodCallException('You must call prepare before trying to execute a prepared statement.'); + } + + foreach ($data as $key => $item) + { + // Determine the type string + if (is_integer($item)) + { + $bindType = SQLITE3_INTEGER; + } + elseif (is_float($item)) + { + $bindType = SQLITE3_FLOAT; + } + else + { + $bindType = SQLITE3_TEXT; + } + + // Bind it + $this->statement->bindValue($key + 1, $item, $bindType); + } + + $this->result = $this->statement->execute(); + + return $this->result !== false; + } + + //-------------------------------------------------------------------- + + /** + * Returns the result object for the prepared query. + * + * @return mixed + */ + public function _getResult() + { + return $this->result; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/Result.php b/vendor/codeigniter4/framework/system/Database/SQLite3/Result.php new file mode 100644 index 0000000..ae293d6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/Result.php @@ -0,0 +1,207 @@ +resultID->numColumns(); + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of column names in the result set. + * + * @return array + */ + public function getFieldNames(): array + { + $fieldNames = []; + for ($i = 0, $c = $this->getFieldCount(); $i < $c; $i ++) + { + $fieldNames[] = $this->resultID->columnName($i); + } + + return $fieldNames; + } + + //-------------------------------------------------------------------- + + /** + * Generates an array of objects representing field meta-data. + * + * @return array + */ + public function getFieldData(): array + { + static $data_types = [ + SQLITE3_INTEGER => 'integer', + SQLITE3_FLOAT => 'float', + SQLITE3_TEXT => 'text', + SQLITE3_BLOB => 'blob', + SQLITE3_NULL => 'null', + ]; + + $retVal = []; + + for ($i = 0, $c = $this->getFieldCount(); $i < $c; $i ++) + { + $retVal[$i] = new \stdClass(); + $retVal[$i]->name = $this->resultID->columnName($i); + $type = $this->resultID->columnType($i); + $retVal[$i]->type = $type; + $retVal[$i]->type_name = isset($data_types[$type]) ? $data_types[$type] : null; + $retVal[$i]->max_length = null; + $retVal[$i]->length = null; + } + + return $retVal; + } + + //-------------------------------------------------------------------- + + /** + * Frees the current result. + * + * @return void + */ + public function freeResult() + { + if (is_object($this->resultID)) + { + $this->resultID->finalize(); + $this->resultID = false; + } + } + + //-------------------------------------------------------------------- + + /** + * Moves the internal pointer to the desired offset. This is called + * internally before fetching results to make sure the result set + * starts at zero. + * + * @param integer $n + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function dataSeek(int $n = 0) + { + if ($n !== 0) + { + throw new DatabaseException('SQLite3 doesn\'t support seeking to other offset.'); + } + + return $this->resultID->reset(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an array. + * + * Overridden by driver classes. + * + * @return mixed + */ + protected function fetchAssoc() + { + return $this->resultID->fetchArray(SQLITE3_ASSOC); + } + + //-------------------------------------------------------------------- + + /** + * Returns the result set as an object. + * + * Overridden by child classes. + * + * @param string $className + * + * @return object|boolean + */ + protected function fetchObject(string $className = 'stdClass') + { + // No native support for fetching rows as objects + if (($row = $this->fetchAssoc()) === false) + { + return false; + } + elseif ($className === 'stdClass') + { + return (object) $row; + } + + $classObj = new $className(); + + if (is_subclass_of($className, Entity::class)) + { + return $classObj->setAttributes($row); + } + + $classSet = \Closure::bind(function ($key, $value) { + $this->$key = $value; + }, $classObj, $className + ); + foreach (array_keys($row) as $key) + { + $classSet($key, $row[$key]); + } + return $classObj; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/Table.php b/vendor/codeigniter4/framework/system/Database/SQLite3/Table.php new file mode 100644 index 0000000..0845a35 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/Table.php @@ -0,0 +1,440 @@ +db = $db; + $this->forge = $forge; + } + + /** + * Reads an existing database table and + * collects all of the information needed to + * recreate this table. + * + * @param string $table + * + * @return \CodeIgniter\Database\SQLite3\Table + */ + public function fromTable(string $table) + { + $this->prefixedTableName = $table; + + // Remove the prefix, if any, since it's + // already been added by the time we get here... + $prefix = $this->db->DBPrefix; + if (! empty($prefix)) + { + if (strpos($table, $prefix) === 0) + { + $table = substr($table, strlen($prefix)); + } + } + + if (! $this->db->tableExists($this->prefixedTableName)) + { + throw DataException::forTableNotFound($this->prefixedTableName); + } + + $this->tableName = $table; + + $this->fields = $this->formatFields($this->db->getFieldData($table)); + + $this->keys = array_merge($this->keys, $this->formatKeys($this->db->getIndexData($table))); + + $this->foreignKeys = $this->db->getForeignKeyData($table); + + return $this; + } + + /** + * Called after `fromTable` and any actions, like `dropColumn`, etc, + * to finalize the action. It creates a temp table, creates the new + * table with modifications, and copies the data over to the new table. + * + * @return boolean + */ + public function run(): bool + { + $this->db->query('PRAGMA foreign_keys = OFF'); + + $this->db->transStart(); + + $this->forge->renameTable($this->tableName, "temp_{$this->tableName}"); + + $this->forge->reset(); + + $this->createTable(); + + $this->copyData(); + + $this->forge->dropTable("temp_{$this->tableName}"); + + $success = $this->db->transComplete(); + + $this->db->query('PRAGMA foreign_keys = ON'); + + return $success; + } + + /** + * Drops columns from the table. + * + * @param string|array $columns + * + * @return \CodeIgniter\Database\SQLite3\Table + */ + public function dropColumn($columns) + { + //unset($this->fields[$column]); + + if (is_string($columns)) + { + $columns = explode(',', $columns); + } + + foreach ($columns as $column) + { + $column = trim($column); + if (isset($this->fields[$column])) + { + unset($this->fields[$column]); + } + } + + return $this; + } + + /** + * Modifies a field, including changing data type, + * renaming, etc. + * + * @param array $field + * + * @return \CodeIgniter\Database\SQLite3\Table + */ + public function modifyColumn(array $field) + { + $field = $field[0]; + + $oldName = $field['name']; + unset($field['name']); + + $this->fields[$oldName] = $field; + + return $this; + } + + /** + * Drops a foreign key from this table so that + * it won't be recreated in the future. + * + * @param string $column + * + * @return \CodeIgniter\Database\SQLite3\Table + */ + public function dropForeignKey(string $column) + { + if (empty($this->foreignKeys)) + { + return $this; + } + + for ($i = 0; $i < count($this->foreignKeys); $i++) + { + if ($this->foreignKeys[$i]->table_name !== $this->tableName) + { + continue; + } + + // The column name should be the first thing in the constraint name + if (strpos($this->foreignKeys[$i]->constraint_name, $column) !== 0) + { + continue; + } + + unset($this->foreignKeys[$i]); + } + + return $this; + } + + /** + * Creates the new table based on our current fields. + * + * @return mixed + */ + protected function createTable() + { + $this->dropIndexes(); + $this->db->resetDataCache(); + + // Handle any modified columns. + $fields = []; + foreach ($this->fields as $name => $field) + { + if (isset($field['new_name'])) + { + $fields[$field['new_name']] = $field; + continue; + } + + $fields[$name] = $field; + } + + $this->forge->addField($fields); + + // Unique/Index keys + if (is_array($this->keys)) + { + foreach ($this->keys as $key) + { + switch ($key['type']) + { + case 'primary': + $this->forge->addPrimaryKey($key['fields']); + break; + case 'unique': + $this->forge->addUniqueKey($key['fields']); + break; + case 'index': + $this->forge->addKey($key['fields']); + break; + } + } + } + + // Foreign Keys + + return $this->forge->createTable($this->tableName); + } + + /** + * Copies data from our old table to the new one, + * taking care map data correctly based on any columns + * that have been renamed. + * + * @return void + */ + protected function copyData() + { + $exFields = []; + $newFields = []; + + foreach ($this->fields as $name => $details) + { + // Are we modifying the column? + if (isset($details['new_name'])) + { + $newFields[] = $details['new_name']; + } + else + { + $newFields[] = $name; + } + + $exFields[] = $name; + } + + $exFields = implode(', ', $exFields); + $newFields = implode(', ', $newFields); + + $this->db->query("INSERT INTO {$this->prefixedTableName}({$newFields}) SELECT {$exFields} FROM {$this->db->DBPrefix}temp_{$this->tableName}"); + } + + /** + * Converts fields retrieved from the database to + * the format needed for creating fields with Forge. + * + * @param array|boolean $fields + * + * @return mixed + */ + protected function formatFields($fields) + { + if (! is_array($fields)) + { + return $fields; + } + + $return = []; + + foreach ($fields as $field) + { + $return[$field->name] = [ + 'type' => $field->type, + 'default' => $field->default, + 'nullable' => $field->nullable, + ]; + + if ($field->primary_key) + { + $this->keys[$field->name] = [ + 'fields' => [$field->name], + 'type' => 'primary', + ]; + } + } + + return $return; + } + + /** + * Converts keys retrieved from the database to + * the format needed to create later. + * + * @param mixed $keys + * + * @return mixed + */ + protected function formatKeys($keys) + { + if (! is_array($keys)) + { + return $keys; + } + + $return = []; + + foreach ($keys as $name => $key) + { + $return[$name] = [ + 'fields' => $key->fields, + 'type' => 'index', + ]; + } + + return $return; + } + + /** + * Attempts to drop all indexes and constraints + * from the database for this table. + * + * @return null|void + */ + protected function dropIndexes() + { + if (! is_array($this->keys) || ! count($this->keys)) + { + return; + } + + foreach ($this->keys as $name => $key) + { + if ($key['type'] === 'primary' || $key['type'] === 'unique') + { + continue; + } + + $this->db->query("DROP INDEX IF EXISTS '{$name}'"); + } + } +} diff --git a/vendor/codeigniter4/framework/system/Database/SQLite3/Utils.php b/vendor/codeigniter4/framework/system/Database/SQLite3/Utils.php new file mode 100644 index 0000000..72f8d4b --- /dev/null +++ b/vendor/codeigniter4/framework/system/Database/SQLite3/Utils.php @@ -0,0 +1,73 @@ +seedPath = $config->filesPath ?? APPPATH . 'Database/'; + + if (empty($this->seedPath)) + { + throw new \InvalidArgumentException('Invalid filesPath set in the Config\Database.'); + } + + $this->seedPath = rtrim($this->seedPath, '/') . '/Seeds/'; + + if (! is_dir($this->seedPath)) + { + throw new \InvalidArgumentException('Unable to locate the seeds directory. Please check Config\Database::filesPath'); + } + + $this->config = & $config; + + if (is_null($db)) + { + $db = \Config\Database::connect($this->DBGroup); + } + + $this->db = & $db; + + $this->forge = \Config\Database::forge($this->DBGroup); + } + + //-------------------------------------------------------------------- + + /** + * Loads the specified seeder and runs it. + * + * @param string $class + * + * @throws \InvalidArgumentException + */ + public function call(string $class) + { + if (empty($class)) + { + throw new \InvalidArgumentException('No Seeder was specified.'); + } + + $path = str_replace('.php', '', $class) . '.php'; + + // If we have namespaced class, simply try to load it. + if (strpos($class, '\\') !== false) + { + $seeder = new $class($this->config); + } + // Otherwise, try to load the class manually. + else + { + $path = $this->seedPath . $path; + + if (! is_file($path)) + { + throw new \InvalidArgumentException('The specified Seeder is not a valid file: ' . $path); + } + + // Assume the class has the correct namespace + $class = APP_NAMESPACE . '\Database\Seeds\\' . $class; + + if (! class_exists($class, false)) + { + require_once $path; + } + + $seeder = new $class($this->config); + } + + $seeder->setSilent($this->silent); + $seeder->run(); + + unset($seeder); + + if (is_cli() && ! $this->silent) + { + CLI::write("Seeded: {$class}", 'green'); + } + } + + //-------------------------------------------------------------------- + + /** + * Sets the location of the directory that seed files can be located in. + * + * @param string $path + * + * @return Seeder + */ + public function setPath(string $path) + { + $this->seedPath = rtrim($path, '/') . '/'; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the silent treatment. + * + * @param boolean $silent + * + * @return Seeder + */ + public function setSilent(bool $silent) + { + $this->silent = $silent; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Run the database seeds. This is where the magic happens. + * + * Child classes must implement this method and take care + * of inserting their data here. + * + * @return mixed + */ + public function run() + { + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Debug/Exceptions.php b/vendor/codeigniter4/framework/system/Debug/Exceptions.php new file mode 100644 index 0000000..3b915e3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Exceptions.php @@ -0,0 +1,513 @@ +ob_level = ob_get_level(); + + $this->viewPath = rtrim($config->errorViewPath, '\\/ ') . DIRECTORY_SEPARATOR; + + $this->config = $config; + + $this->request = $request; + $this->response = $response; + } + + //-------------------------------------------------------------------- + + /** + * Responsible for registering the error, exception and shutdown + * handling of our application. + */ + public function initialize() + { + //Set the Exception Handler + set_exception_handler([$this, 'exceptionHandler']); + + // Set the Error Handler + set_error_handler([$this, 'errorHandler']); + + // Set the handler for shutdown to catch Parse errors + // Do we need this in PHP7? + register_shutdown_function([$this, 'shutdownHandler']); + } + + //-------------------------------------------------------------------- + + /** + * Catches any uncaught errors and exceptions, including most Fatal errors + * (Yay PHP7!). Will log the error, display it if display_errors is on, + * and fire an event that allows custom actions to be taken at this point. + * + * @param \Throwable $exception + * + * @codeCoverageIgnore + */ + public function exceptionHandler(Throwable $exception) + { + [ + $statusCode, + $exitCode, + ] = $this->determineCodes($exception); + + // Log it + if ($this->config->log === true && ! in_array($statusCode, $this->config->ignoreCodes)) + { + log_message('critical', $exception->getMessage() . "\n{trace}", [ + 'trace' => $exception->getTraceAsString(), + ]); + } + + if (! is_cli()) + { + $this->response->setStatusCode($statusCode); + $header = "HTTP/{$this->request->getProtocolVersion()} {$this->response->getStatusCode()} {$this->response->getReason()}"; + header($header, true, $statusCode); + + if (strpos($this->request->getHeaderLine('accept'), 'text/html') === false) + { + $this->respond(ENVIRONMENT === 'development' ? $this->collectVars($exception, $statusCode) : '', $statusCode)->send(); + + exit($exitCode); + } + } + + $this->render($exception, $statusCode); + + exit($exitCode); + } + + //-------------------------------------------------------------------- + + /** + * Even in PHP7, some errors make it through to the errorHandler, so + * convert these to Exceptions and let the exception handler log it and + * display it. + * + * This seems to be primarily when a user triggers it with trigger_error(). + * + * @param integer $severity + * @param string $message + * @param string|null $file + * @param integer|null $line + * + * @throws \ErrorException + */ + public function errorHandler(int $severity, string $message, string $file = null, int $line = null) + { + if (! (error_reporting() & $severity)) + { + return; + } + + // Convert it to an exception and pass it along. + throw new ErrorException($message, 0, $severity, $file, $line); + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if any errors have happened during shutdown that + * need to be caught and handle them. + */ + public function shutdownHandler() + { + $error = error_get_last(); + + // If we've got an error that hasn't been displayed, then convert + // it to an Exception and use the Exception handler to display it + // to the user. + if (! is_null($error)) + { + // Fatal Error? + if (in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE])) + { + $this->exceptionHandler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Determines the view to display based on the exception thrown, + * whether an HTTP or CLI request, etc. + * + * @param \Throwable $exception + * @param string $template_path + * + * @return string The path and filename of the view file to use + */ + protected function determineView(Throwable $exception, string $template_path): string + { + // Production environments should have a custom exception file. + $view = 'production.php'; + $template_path = rtrim($template_path, '\\/ ') . DIRECTORY_SEPARATOR; + + if (str_ireplace(['off', 'none', 'no', 'false', 'null'], '', ini_get('display_errors'))) + { + $view = 'error_exception.php'; + } + + // 404 Errors + if ($exception instanceof PageNotFoundException) + { + return 'error_404.php'; + } + + // Allow for custom views based upon the status code + if (is_file($template_path . 'error_' . $exception->getCode() . '.php')) + { + return 'error_' . $exception->getCode() . '.php'; + } + + return $view; + } + + //-------------------------------------------------------------------- + + /** + * Given an exception and status code will display the error to the client. + * + * @param \Throwable $exception + * @param integer $statusCode + */ + protected function render(Throwable $exception, int $statusCode) + { + // Determine possible directories of error views + $path = $this->viewPath; + $altPath = rtrim((new Paths())->viewDirectory, '\\/ ') . DIRECTORY_SEPARATOR . 'errors' . DIRECTORY_SEPARATOR; + + $path .= (is_cli() ? 'cli' : 'html') . DIRECTORY_SEPARATOR; + $altPath .= (is_cli() ? 'cli' : 'html') . DIRECTORY_SEPARATOR; + + // Determine the views + $view = $this->determineView($exception, $path); + $altView = $this->determineView($exception, $altPath); + + // Check if the view exists + if (is_file($path . $view)) + { + $viewFile = $path . $view; + } + elseif (is_file($altPath . $altView)) + { + $viewFile = $altPath . $altView; + } + + // Prepare the vars + $vars = $this->collectVars($exception, $statusCode); + extract($vars); + + // Render it + if (ob_get_level() > $this->ob_level + 1) + { + ob_end_clean(); + } + + ob_start(); + include $viewFile; + $buffer = ob_get_contents(); + ob_end_clean(); + echo $buffer; + } + + //-------------------------------------------------------------------- + + /** + * Gathers the variables that will be made available to the view. + * + * @param \Throwable $exception + * @param integer $statusCode + * + * @return array + */ + protected function collectVars(Throwable $exception, int $statusCode): array + { + return [ + 'title' => get_class($exception), + 'type' => get_class($exception), + 'code' => $statusCode, + 'message' => $exception->getMessage() ?? '(null)', + 'file' => $exception->getFile(), + 'line' => $exception->getLine(), + 'trace' => $exception->getTrace(), + ]; + } + + /** + * Determines the HTTP status code and the exit status code for this request. + * + * @param \Throwable $exception + * + * @return array + */ + protected function determineCodes(Throwable $exception): array + { + $statusCode = abs($exception->getCode()); + + if ($statusCode < 100 || $statusCode > 599) + { + $exitStatus = $statusCode + EXIT__AUTO_MIN; // 9 is EXIT__AUTO_MIN + if ($exitStatus > EXIT__AUTO_MAX) // 125 is EXIT__AUTO_MAX + { + $exitStatus = EXIT_ERROR; // EXIT_ERROR + } + $statusCode = 500; + } + else + { + $exitStatus = 1; // EXIT_ERROR + } + + return [ + $statusCode ?? 500, + $exitStatus, + ]; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Display Methods + //-------------------------------------------------------------------- + + /** + * Clean Path + * + * This makes nicer looking paths for the error output. + * + * @param string $file + * + * @return string + */ + public static function cleanPath(string $file): string + { + switch (true) + { + case strpos($file, APPPATH) === 0: + $file = 'APPPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(APPPATH)); + break; + case strpos($file, SYSTEMPATH) === 0: + $file = 'SYSTEMPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(SYSTEMPATH)); + break; + case strpos($file, FCPATH) === 0: + $file = 'FCPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(FCPATH)); + break; + case defined('VENDORPATH') && strpos($file, VENDORPATH) === 0: + $file = 'VENDORPATH' . DIRECTORY_SEPARATOR . substr($file, strlen(VENDORPATH)); + break; + } + + return $file; + } + + //-------------------------------------------------------------------- + + /** + * Describes memory usage in real-world units. Intended for use + * with memory_get_usage, etc. + * + * @param $bytes + * + * @return string + */ + public static function describeMemory(int $bytes): string + { + if ($bytes < 1024) + { + return $bytes . 'B'; + } + else if ($bytes < 1048576) + { + return round($bytes / 1024, 2) . 'KB'; + } + + return round($bytes / 1048576, 2) . 'MB'; + } + + //-------------------------------------------------------------------- + + /** + * Creates a syntax-highlighted version of a PHP file. + * + * @param string $file + * @param integer $lineNumber + * @param integer $lines + * + * @return boolean|string + */ + public static function highlightFile(string $file, int $lineNumber, int $lines = 15) + { + if (empty($file) || ! is_readable($file)) + { + return false; + } + + // Set our highlight colors: + if (function_exists('ini_set')) + { + ini_set('highlight.comment', '#767a7e; font-style: italic'); + ini_set('highlight.default', '#c7c7c7'); + ini_set('highlight.html', '#06B'); + ini_set('highlight.keyword', '#f1ce61;'); + ini_set('highlight.string', '#869d6a'); + } + + try + { + $source = file_get_contents($file); + } + catch (Throwable $e) + { + return false; + } + + $source = str_replace(["\r\n", "\r"], "\n", $source); + $source = explode("\n", highlight_string($source, true)); + $source = str_replace('
', "\n", $source[1]); + + $source = explode("\n", str_replace("\r\n", "\n", $source)); + + // Get just the part to show + $start = $lineNumber - (int) round($lines / 2); + $start = $start < 0 ? 0 : $start; + + // Get just the lines we need to display, while keeping line numbers... + $source = array_splice($source, $start, $lines, true); + + // Used to format the line number in the source + $format = '% ' . strlen(sprintf('%s', $start + $lines)) . 'd'; + + $out = ''; + // Because the highlighting may have an uneven number + // of open and close span tags on one line, we need + // to ensure we can close them all to get the lines + // showing correctly. + $spans = 1; + + foreach ($source as $n => $row) + { + $spans += substr_count($row, ']+>#', $row, $tags); + $out .= sprintf("{$format} %s\n%s", $n + $start + 1, strip_tags($row), implode('', $tags[0]) + ); + } + else + { + $out .= sprintf('' . $format . ' %s', $n + $start + 1, $row) . "\n"; + } + } + + if ($spans > 0) + { + $out .= str_repeat('', $spans); + } + + return '
' . $out . '
'; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Debug/Iterator.php b/vendor/codeigniter4/framework/system/Debug/Iterator.php new file mode 100644 index 0000000..c9101df --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Iterator.php @@ -0,0 +1,179 @@ +tests[$name] = $closure; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Runs through all of the tests that have been added, recording + * time to execute the desired number of iterations, and the approximate + * memory usage used during those iterations. + * + * @param integer $iterations + * @param boolean $output + * + * @return string|null + */ + public function run(int $iterations = 1000, bool $output = true) + { + foreach ($this->tests as $name => $test) + { + // clear memory before start + gc_collect_cycles(); + + $start = microtime(true); + $start_mem = $max_memory = memory_get_usage(true); + + for ($i = 0; $i < $iterations; $i ++) + { + $result = $test(); + + $max_memory = max($max_memory, memory_get_usage(true)); + + unset($result); + } + + $this->results[$name] = [ + 'time' => microtime(true) - $start, + 'memory' => $max_memory - $start_mem, + 'n' => $iterations, + ]; + } + + if ($output) + { + return $this->getReport(); + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Get results. + * + * @return string + */ + public function getReport(): string + { + if (empty($this->results)) + { + return 'No results to display.'; + } + + helper('number'); + + // Template + $tpl = ' + + + + + + + + + {rows} + +
TestTimeMemory
'; + + $rows = ''; + + foreach ($this->results as $name => $result) + { + $memory = number_to_size($result['memory'], 4); + + $rows .= " + {$name} + " . number_format($result['time'], 4) . " + {$memory} + "; + } + + $tpl = str_replace('{rows}', $rows, $tpl); + + return $tpl . '
'; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Debug/Timer.php b/vendor/codeigniter4/framework/system/Debug/Timer.php new file mode 100644 index 0000000..736f558 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Timer.php @@ -0,0 +1,181 @@ +timers[strtolower($name)] = [ + 'start' => ! empty($time) ? $time : microtime(true), + 'end' => null, + ]; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Stops a running timer. + * + * If the timer is not stopped before the timers() method is called, + * it will be automatically stopped at that point. + * + * @param string $name The name of this timer. + * + * @return Timer + */ + public function stop(string $name) + { + $name = strtolower($name); + + if (empty($this->timers[$name])) + { + throw new \RuntimeException('Cannot stop timer: invalid name given.'); + } + + $this->timers[$name]['end'] = microtime(true); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the duration of a recorded timer. + * + * @param string $name The name of the timer. + * @param integer $decimals Number of decimal places. + * + * @return null|float Returns null if timer exists by that name. + * Returns a float representing the number of + * seconds elapsed while that timer was running. + */ + public function getElapsedTime(string $name, int $decimals = 4) + { + $name = strtolower($name); + + if (empty($this->timers[$name])) + { + return null; + } + + $timer = $this->timers[$name]; + + if (empty($timer['end'])) + { + $timer['end'] = microtime(true); + } + + return (float) number_format($timer['end'] - $timer['start'], $decimals); + } + + //-------------------------------------------------------------------- + + /** + * Returns the array of timers, with the duration pre-calculated for you. + * + * @param integer $decimals Number of decimal places + * + * @return array + */ + public function getTimers(int $decimals = 4): array + { + $timers = $this->timers; + + foreach ($timers as &$timer) + { + if (empty($timer['end'])) + { + $timer['end'] = microtime(true); + } + + $timer['duration'] = (float) number_format($timer['end'] - $timer['start'], $decimals); + } + + return $timers; + } + + //-------------------------------------------------------------------- + + /** + * Checks whether or not a timer with the specified name exists. + * + * @param string $name + * + * @return boolean + */ + public function has(string $name): bool + { + return array_key_exists(strtolower($name), $this->timers); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar.php b/vendor/codeigniter4/framework/system/Debug/Toolbar.php new file mode 100644 index 0000000..ff2be35 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar.php @@ -0,0 +1,514 @@ +config = $config; + + foreach ($config->collectors as $collector) + { + if (! class_exists($collector)) + { + log_message('critical', 'Toolbar collector does not exists(' . $collector . ').' . + 'please check $collectors in the Config\Toolbar.php file.'); + continue; + } + + $this->collectors[] = new $collector(); + } + } + + //-------------------------------------------------------------------- + + /** + * Returns all the data required by Debug Bar + * + * @param float $startTime App start time + * @param float $totalTime + * @param \CodeIgniter\HTTP\RequestInterface $request + * @param \CodeIgniter\HTTP\ResponseInterface $response + * + * @return string JSON encoded data + */ + public function run(float $startTime, float $totalTime, RequestInterface $request, ResponseInterface $response): string + { + // Data items used within the view. + $data['url'] = current_url(); + $data['method'] = $request->getMethod(true); + $data['isAJAX'] = $request->isAJAX(); + $data['startTime'] = $startTime; + $data['totalTime'] = $totalTime * 1000; + $data['totalMemory'] = number_format((memory_get_peak_usage()) / 1024 / 1024, 3); + $data['segmentDuration'] = $this->roundTo($data['totalTime'] / 7); + $data['segmentCount'] = (int) ceil($data['totalTime'] / $data['segmentDuration']); + $data['CI_VERSION'] = \CodeIgniter\CodeIgniter::CI_VERSION; + $data['collectors'] = []; + + foreach ($this->collectors as $collector) + { + $data['collectors'][] = $collector->getAsArray(); + } + + foreach ($this->collectVarData() as $heading => $items) + { + $varData = []; + + if (is_array($items)) + { + foreach ($items as $key => $value) + { + $varData[esc($key)] = is_string($value) ? esc($value) : '
' . esc(print_r($value, true)) . '
'; + } + } + + $data['vars']['varData'][esc($heading)] = $varData; + } + + if (! empty($_SESSION)) + { + foreach ($_SESSION as $key => $value) + { + // Replace the binary data with string to avoid json_encode failure. + if (is_string($value) && preg_match('~[^\x20-\x7E\t\r\n]~', $value)) + { + $value = 'binary data'; + } + + $data['vars']['session'][esc($key)] = is_string($value) ? esc($value) : '
' . esc(print_r($value, true)) . '
'; + } + } + + foreach ($request->getGet() as $name => $value) + { + $data['vars']['get'][esc($name)] = is_array($value) ? '
' . esc(print_r($value, true)) . '
' : esc($value); + } + + foreach ($request->getPost() as $name => $value) + { + $data['vars']['post'][esc($name)] = is_array($value) ? '
' . esc(print_r($value, true)) . '
' : esc($value); + } + + foreach ($request->getHeaders() as $value) + { + if (empty($value)) + { + continue; + } + + if (! is_array($value)) + { + $value = [$value]; + } + + foreach ($value as $h) + { + $data['vars']['headers'][esc($h->getName())] = esc($h->getValueLine()); + } + } + + foreach ($request->getCookie() as $name => $value) + { + $data['vars']['cookies'][esc($name)] = esc($value); + } + + $data['vars']['request'] = ($request->isSecure() ? 'HTTPS' : 'HTTP') . '/' . $request->getProtocolVersion(); + + $data['vars']['response'] = [ + 'statusCode' => $response->getStatusCode(), + 'reason' => esc($response->getReason()), + 'contentType' => esc($response->getHeaderLine('content-type')), + ]; + + $data['config'] = \CodeIgniter\Debug\Toolbar\Collectors\Config::display(); + + if ($response->CSP !== null) + { + $response->CSP->addImageSrc('data:'); + } + + return json_encode($data); + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + + /** + * Called within the view to display the timeline itself. + * + * @param array $collectors + * @param float $startTime + * @param integer $segmentCount + * @param integer $segmentDuration + * @param array $styles + * + * @return string + */ + protected function renderTimeline(array $collectors, float $startTime, int $segmentCount, int $segmentDuration, array &$styles): string + { + $displayTime = $segmentCount * $segmentDuration; + $rows = $this->collectTimelineData($collectors); + $output = ''; + $styleCount = 0; + + foreach ($rows as $row) + { + $output .= ''; + $output .= "{$row['name']}"; + $output .= "{$row['component']}"; + $output .= "" . number_format($row['duration'] * 1000, 2) . ' ms'; + $output .= ""; + + $offset = ((((float) $row['start'] - $startTime) * 1000) / $displayTime) * 100; + $length = (((float) $row['duration'] * 1000) / $displayTime) * 100; + + $styles['debug-bar-timeline-' . $styleCount] = "left: {$offset}%; width: {$length}%;"; + $output .= ""; + $output .= ''; + $output .= ''; + + $styleCount ++; + } + + return $output; + } + + //-------------------------------------------------------------------- + + /** + * Returns a sorted array of timeline data arrays from the collectors. + * + * @param array $collectors + * + * @return array + */ + protected function collectTimelineData($collectors): array + { + $data = []; + + // Collect it + foreach ($collectors as $collector) + { + if (! $collector['hasTimelineData']) + { + continue; + } + + $data = array_merge($data, $collector['timelineData']); + } + + // Sort it + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of data from all of the modules + * that should be displayed in the 'Vars' tab. + * + * @return array + */ + protected function collectVarData(): array + { + $data = []; + + foreach ($this->collectors as $collector) + { + if (! $collector->hasVarData()) + { + continue; + } + + $data = array_merge($data, $collector->getVarData()); + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Rounds a number to the nearest incremental value. + * + * @param float $number + * @param integer $increments + * + * @return float + */ + protected function roundTo(float $number, int $increments = 5): float + { + $increments = 1 / $increments; + + return (ceil($number * $increments) / $increments); + } + + //-------------------------------------------------------------------- + + /** + * Prepare for debugging.. + * + * @param RequestInterface $request + * @param ResponseInterface $response + * @global type $app + * @return type + */ + public function prepare(RequestInterface $request = null, ResponseInterface $response = null) + { + if (CI_DEBUG && ! is_cli()) + { + global $app; + + $request = $request ?? Services::request(); + $response = $response ?? Services::response(); + + // Disable the toolbar for downloads + if ($response instanceof DownloadResponse) + { + return; + } + + $toolbar = Services::toolbar(config(Toolbar::class)); + $stats = $app->getPerformanceStats(); + $data = $toolbar->run( + $stats['startTime'], + $stats['totalTime'], + $request, + $response + ); + + helper('filesystem'); + + // Updated to time() so we can get history + $time = time(); + + if (! is_dir(WRITEPATH . 'debugbar')) + { + mkdir(WRITEPATH . 'debugbar', 0777); + } + + write_file(WRITEPATH . 'debugbar/' . 'debugbar_' . $time . '.json', $data, 'w+'); + + $format = $response->getHeaderLine('content-type'); + + // Non-HTML formats should not include the debugbar + // then we send headers saying where to find the debug data + // for this response + if ($request->isAJAX() || strpos($format, 'html') === false) + { + $response->setHeader('Debugbar-Time', "$time") + ->setHeader('Debugbar-Link', site_url("?debugbar_time={$time}")) + ->getBody(); + + return; + } + + $script = PHP_EOL + . '' + . '' + . '' + . PHP_EOL; + + if (strpos($response->getBody(), '') !== false) + { + $response->setBody( + str_replace('', '' . $script, $response->getBody()) + ); + + return; + } + + $response->appendBody($script); + } + } + + //-------------------------------------------------------------------- + + /** + * Inject debug toolbar into the response. + */ + public function respond() + { + if (ENVIRONMENT === 'testing') + { + return; + } + + // @codeCoverageIgnoreStart + $request = Services::request(); + + // If the request contains '?debugbar then we're + // simply returning the loading script + if ($request->getGet('debugbar') !== null) + { + // Let the browser know that we are sending javascript + header('Content-Type: application/javascript'); + + ob_start(); + include($this->config->viewsPath . 'toolbarloader.js.php'); + $output = ob_get_clean(); + + exit($output); + } + + // Otherwise, if it includes ?debugbar_time, then + // we should return the entire debugbar. + if ($request->getGet('debugbar_time')) + { + helper('security'); + + // Negotiate the content-type to format the output + $format = $request->negotiate('media', [ + 'text/html', + 'application/json', + 'application/xml', + ]); + $format = explode('/', $format)[1]; + + $file = sanitize_filename('debugbar_' . $request->getGet('debugbar_time')); + $filename = WRITEPATH . 'debugbar/' . $file . '.json'; + + // Show the toolbar + if (is_file($filename)) + { + $contents = $this->format(file_get_contents($filename), $format); + exit($contents); + } + + // File was not written or do not exists + http_response_code(404); + exit; // Exit here is needed to avoid load the index page + } + // @codeCoverageIgnoreEnd + } + + /** + * Format output + * + * @param string $data JSON encoded Toolbar data + * @param string $format html, json, xml + * + * @return string + */ + protected function format(string $data, string $format = 'html'): string + { + $data = json_decode($data, true); + + if ($this->config->maxHistory !== 0) + { + $history = new History(); + $history->setFiles( + Services::request()->getGet('debugbar_time'), + $this->config->maxHistory + ); + + $data['collectors'][] = $history->getAsArray(); + } + + $output = ''; + + switch ($format) + { + case 'html': + $data['styles'] = []; + extract($data); + $parser = Services::parser($this->config->viewsPath, null, false); + ob_start(); + include($this->config->viewsPath . 'toolbar.tpl.php'); + $output = ob_get_clean(); + break; + case 'json': + $formatter = new JSONFormatter(); + $output = $formatter->format($data); + break; + case 'xml': + $formatter = new XMLFormatter; + $output = $formatter->format($data); + break; + } + + return $output; + } + +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/BaseCollector.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/BaseCollector.php new file mode 100644 index 0000000..a403b4c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/BaseCollector.php @@ -0,0 +1,318 @@ +title)); + } + + return $this->title; + } + + //-------------------------------------------------------------------- + + /** + * Returns any information that should be shown next to the title. + * + * @return string + */ + public function getTitleDetails(): string + { + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Does this collector need it's own tab? + * + * @return boolean + */ + public function hasTabContent(): bool + { + return (bool) $this->hasTabContent; + } + + //-------------------------------------------------------------------- + + /** + * Does this collector have a label? + * + * @return boolean + */ + public function hasLabel(): bool + { + return (bool) $this->hasLabel; + } + + //-------------------------------------------------------------------- + + /** + * Does this collector have information for the timeline? + * + * @return boolean + */ + public function hasTimelineData(): bool + { + return (bool) $this->hasTimeline; + } + + //-------------------------------------------------------------------- + + /** + * Grabs the data for the timeline, properly formatted, + * or returns an empty array. + * + * @return array + */ + public function timelineData(): array + { + if (! $this->hasTimeline) + { + return []; + } + + return $this->formatTimelineData(); + } + + //-------------------------------------------------------------------- + + /** + * Does this Collector have data that should be shown in the + * 'Vars' tab? + * + * @return boolean + */ + public function hasVarData(): bool + { + return (bool) $this->hasVarData; + } + + //-------------------------------------------------------------------- + + /** + * Gets a collection of data that should be shown in the 'Vars' tab. + * The format is an array of sections, each with their own array + * of key/value pairs: + * + * $data = [ + * 'section 1' => [ + * 'foo' => 'bar, + * 'bar' => 'baz' + * ], + * 'section 2' => [ + * 'foo' => 'bar, + * 'bar' => 'baz' + * ], + * ]; + * + * @return null + */ + public function getVarData() + { + return null; + } + + //-------------------------------------------------------------------- + + /** + * Child classes should implement this to return the timeline data + * formatted for correct usage. + * + * Timeline data should be formatted into arrays that look like: + * + * [ + * 'name' => 'Database::Query', + * 'component' => 'Database', + * 'start' => 10 // milliseconds + * 'duration' => 15 // milliseconds + * ] + * + * @return array + */ + protected function formatTimelineData(): array + { + return []; + } + + //-------------------------------------------------------------------- + + /** + * Returns the data of this collector to be formatted in the toolbar + * + * @return array|string + */ + public function display() + { + return []; + } + + //-------------------------------------------------------------------- + + /** + * Clean Path + * + * This makes nicer looking paths for the error output. + * + * @param string $file + * + * @return string + */ + public function cleanPath(string $file): string + { + return Exceptions::cleanPath($file); + } + + /** + * Gets the "badge" value for the button. + * + * @return null + */ + public function getBadgeValue() + { + return null; + } + + /** + * Does this collector have any data collected? + * + * If not, then the toolbar button won't get shown. + * + * @return boolean + */ + public function isEmpty(): bool + { + return false; + } + + /** + * Returns the HTML to display the icon. Should either + * be SVG, or a base-64 encoded. + * + * Recommended dimensions are 24px x 24px + * + * @return string + */ + public function icon(): string + { + return ''; + } + + /** + * Return settings as an array. + * + * @return array + */ + public function getAsArray(): array + { + return [ + 'title' => $this->getTitle(), + 'titleSafe' => $this->getTitle(true), + 'titleDetails' => $this->getTitleDetails(), + 'display' => $this->display(), + 'badgeValue' => $this->getBadgeValue(), + 'isEmpty' => $this->isEmpty(), + 'hasTabContent' => $this->hasTabContent(), + 'hasLabel' => $this->hasLabel(), + 'icon' => $this->icon(), + 'hasTimelineData' => $this->hasTimelineData(), + 'timelineData' => $this->timelineData(), + ]; + } + +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Config.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Config.php new file mode 100644 index 0000000..82ef634 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Config.php @@ -0,0 +1,71 @@ + CodeIgniter::CI_VERSION, + 'phpVersion' => phpversion(), + 'phpSAPI' => php_sapi_name(), + 'environment' => ENVIRONMENT, + 'baseURL' => $config->baseURL, + 'timezone' => app_timezone(), + 'locale' => Services::request()->getLocale(), + 'cspEnabled' => $config->CSPEnabled, + ]; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Database.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Database.php new file mode 100644 index 0000000..00aa740 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Database.php @@ -0,0 +1,278 @@ +connections = \Config\Database::getConnections(); + } + + //-------------------------------------------------------------------- + + /** + * The static method used during Events to collect + * data. + * + * @param \CodeIgniter\Database\Query $query + * + * @internal param $ array \CodeIgniter\Database\Query + */ + public static function collect(Query $query) + { + $config = config('Toolbar'); + + // Provide default in case it's not set + $max = $config->maxQueries ?: 100; + + if (count(static::$queries) < $max) + { + static::$queries[] = $query; + } + } + + //-------------------------------------------------------------------- + + /** + * Returns timeline data formatted for the toolbar. + * + * @return array The formatted data or an empty array. + */ + protected function formatTimelineData(): array + { + $data = []; + + foreach ($this->connections as $alias => $connection) + { + // Connection Time + $data[] = [ + 'name' => 'Connecting to Database: "' . $alias . '"', + 'component' => 'Database', + 'start' => $connection->getConnectStart(), + 'duration' => $connection->getConnectDuration(), + ]; + } + + foreach (static::$queries as $query) + { + $data[] = [ + 'name' => 'Query', + 'component' => 'Database', + 'start' => $query->getStartTime(true), + 'duration' => $query->getDuration(), + ]; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Returns the data of this collector to be formatted in the toolbar + * + * @return array + */ + public function display(): array + { + // Key words we want bolded + $highlight = [ + 'SELECT', + 'DISTINCT', + 'FROM', + 'WHERE', + 'AND', + 'LEFT JOIN', + 'RIGHT JOIN', + 'JOIN', + 'ORDER BY', + 'GROUP BY', + 'LIMIT', + 'INSERT', + 'INTO', + 'VALUES', + 'UPDATE', + 'OR ', + 'HAVING', + 'OFFSET', + 'NOT IN', + 'IN', + 'LIKE', + 'NOT LIKE', + 'COUNT', + 'MAX', + 'MIN', + 'ON', + 'AS', + 'AVG', + 'SUM', + '(', + ')', + ]; + + $data = [ + 'queries' => [], + ]; + + foreach (static::$queries as $query) + { + $sql = $query->getQuery(); + + foreach ($highlight as $term) + { + $sql = str_replace($term, "{$term}", $sql); + } + + $data['queries'][] = [ + 'duration' => ($query->getDuration(5) * 1000) . ' ms', + 'sql' => $sql, + ]; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Gets the "badge" value for the button. + * + * @return integer + */ + public function getBadgeValue(): int + { + return count(static::$queries); + } + + //-------------------------------------------------------------------- + + /** + * Information to be displayed next to the title. + * + * @return string The number of queries (in parentheses) or an empty string. + */ + public function getTitleDetails(): string + { + return '(' . count(static::$queries) . ' Queries across ' . ($countConnection = count($this->connections)) . ' Connection' . + ($countConnection > 1 ? 's' : '') . ')'; + } + + //-------------------------------------------------------------------- + + /** + * Does this collector have any data collected? + * + * @return boolean + */ + public function isEmpty(): bool + { + return empty(static::$queries); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADMSURBVEhLY6A3YExLSwsA4nIycQDIDIhRWEBqamo/UNF/SjDQjF6ocZgAKPkRiFeEhoYyQ4WIBiA9QAuWAPEHqBAmgLqgHcolGQD1V4DMgHIxwbCxYD+QBqcKINseKo6eWrBioPrtQBq/BcgY5ht0cUIYbBg2AJKkRxCNWkDQgtFUNJwtABr+F6igE8olGQD114HMgHIxAVDyAhA/AlpSA8RYUwoeXAPVex5qHCbIyMgwBCkAuQJIY00huDBUz/mUlBQDqHGjgBjAwAAACexpph6oHSQAAAAASUVORK5CYII='; + } + +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Events.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Events.php new file mode 100644 index 0000000..41c9f00 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Events.php @@ -0,0 +1,187 @@ +viewer = Services::renderer(); + } + + //-------------------------------------------------------------------- + + /** + * Child classes should implement this to return the timeline data + * formatted for correct usage. + * + * @return array + */ + protected function formatTimelineData(): array + { + $data = []; + + $rows = $this->viewer->getPerformanceData(); + + foreach ($rows as $info) + { + $data[] = [ + 'name' => 'View: ' . $info['view'], + 'component' => 'Views', + 'start' => $info['start'], + 'duration' => $info['end'] - $info['start'], + ]; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Returns the data of this collector to be formatted in the toolbar + * + * @return array + */ + public function display(): array + { + $data = [ + 'events' => [], + ]; + + foreach (\CodeIgniter\Events\Events::getPerformanceLogs() as $row) + { + $key = $row['event']; + + if (! array_key_exists($key, $data['events'])) + { + $data['events'][$key] = [ + 'event' => $key, + 'duration' => number_format(($row['end'] - $row['start']) * 1000, 2), + 'count' => 1, + ]; + + continue; + } + + $data['events'][$key]['duration'] += number_format(($row['end'] - $row['start']) * 1000, 2); + $data['events'][$key]['count']++; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Gets the "badge" value for the button. + * + * @return integer + */ + public function getBadgeValue(): int + { + return count(\CodeIgniter\Events\Events::getPerformanceLogs()); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEASURBVEhL7ZXNDcIwDIVTsRBH1uDQDdquUA6IM1xgCA6MwJUN2hk6AQzAz0vl0ETUxC5VT3zSU5w81/mRMGZysixbFEVR0jSKNt8geQU9aRpFmp/keX6AbjZ5oB74vsaN5lSzA4tLSjpBFxsjeSuRy4d2mDdQTWU7YLbXTNN05mKyovj5KL6B7q3hoy3KwdZxBlT+Ipz+jPHrBqOIynZgcZonoukb/0ckiTHqNvDXtXEAaygRbaB9FvUTjRUHsIYS0QaSp+Dw6wT4hiTmYHOcYZsdLQ2CbXa4ftuuYR4x9vYZgdb4vsFYUdmABMYeukK9/SUme3KMFQ77+Yfzh8eYF8+orDuDWU5LAAAAAElFTkSuQmCC'; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Files.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Files.php new file mode 100644 index 0000000..36b0132 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Files.php @@ -0,0 +1,151 @@ +cleanPath($file); + + if (strpos($path, 'SYSTEMPATH') !== false) + { + $coreFiles[] = [ + 'name' => basename($file), + 'path' => $path, + ]; + } + else + { + $userFiles[] = [ + 'name' => basename($file), + 'path' => $path, + ]; + } + } + + sort($userFiles); + sort($coreFiles); + + return [ + 'coreFiles' => $coreFiles, + 'userFiles' => $userFiles, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Displays the number of included files as a badge in the tab button. + * + * @return integer + */ + public function getBadgeValue(): int + { + return count(get_included_files()); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGBSURBVEhL7ZQ9S8NQGIVTBQUncfMfCO4uLgoKbuKQOWg+OkXERRE1IAXrIHbVDrqIDuLiJgj+gro7S3dnpfq88b1FMTE3VZx64HBzzvvZWxKnj15QCcPwCD5HUfSWR+JtzgmtsUcQBEva5IIm9SwSu+95CAWbUuy67qBa32ByZEDpIaZYZSZMjjQuPcQUq8yEyYEb8FSerYeQVGbAFzJkX1PyQWLhgCz0BxTCekC1Wp0hsa6yokzhed4oje6Iz6rlJEkyIKfUEFtITVtQdAibn5rMyaYsMS+a5wTv8qeXMhcU16QZbKgl3hbs+L4/pnpdc87MElZgq10p5DxGdq8I7xrvUWUKvG3NbSK7ubngYzdJwSsF7TiOh9VOgfcEz1UayNe3JUPM1RWC5GXYgTfc75B4NBmXJnAtTfpABX0iPvEd9ezALwkplCFXcr9styiNOKc1RRZpaPM9tcqBwlWzGY1qPL9wjqRBgF5BH6j8HWh2S7MHlX8PrmbK+k/8PzjOOzx1D3i1pKTTAAAAAElFTkSuQmCC'; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/History.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/History.php new file mode 100644 index 0000000..3112e07 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/History.php @@ -0,0 +1,183 @@ += 0 && $counter > $limit) + { + unlink($filename); + continue; + } + + // Get the contents of this specific history request + $contents = file_get_contents($filename); + + $contents = @json_decode($contents); + if (json_last_error() === JSON_ERROR_NONE) + { + preg_match_all('/\d+/', $filename, $time); + $time = (int)end($time[0]); + + // Debugbar files shown in History Collector + $files[] = [ + 'time' => $time, + 'datetime' => date('Y-m-d H:i:s', $time), + 'active' => $time === $current, + 'status' => $contents->vars->response->statusCode, + 'method' => $contents->method, + 'url' => $contents->url, + 'isAJAX' => $contents->isAJAX ? 'Yes' : 'No', + 'contentType' => $contents->vars->response->contentType, + ]; + } + } + + $this->files = $files; + } + + //-------------------------------------------------------------------- + + /** + * Returns the data of this collector to be formatted in the toolbar + * + * @return array + */ + public function display(): array + { + return ['files' => $this->files]; + } + + //-------------------------------------------------------------------- + + /** + * Displays the number of included files as a badge in the tab button. + * + * @return integer + */ + public function getBadgeValue(): int + { + return count($this->files); + } + + /** + * Return true if there are no history files. + * + * @return boolean + */ + public function isEmpty(): bool + { + return empty($this->files); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAJySURBVEhL3ZU7aJNhGIVTpV6i4qCIgkIHxcXLErS4FBwUFNwiCKGhuTYJGaIgnRoo4qRu6iCiiIuIXXTTIkIpuqoFwaGgonUQlC5KafU5ycmNP0lTdPLA4fu+8573/a4/f6hXpFKpwUwmc9fDfweKbk+n07fgEv33TLSbtt/hvwNFT1PsG/zdTE0Gp+GFfD6/2fbVIxqNrqPIRbjg4t/hY8aztcngfDabHXbKyiiXy2vcrcPH8oDCry2FKDrA+Ar6L01E/ypyXzXaARjDGGcoeNxSDZXE0dHRA5VRE5LJ5CFy5jzJuOX2wHRHRnjbklZ6isQ3tIctBaAd4vlK3jLtkOVWqABBXd47jGHLmjTmSScttQV5J+SjfcUweFQEbsjAas5aqoCLXutJl7vtQsAzpRowYqkBinyCC8Vicb2lOih8zoldd0F8RD7qTFiqAnGrAy8stUAvi/hbqDM+YzkAFrLPdR5ZqoLXsd+Bh5YCIH7JniVdquUWxOPxDfboHhrI5XJ7HHhiqQXox+APe/Qk64+gGYVCYZs8cMpSFQj9JOoFzVqqo7k4HIvFYpscCoAjOmLffUsNUGRaQUwDlmofUa34ecsdgXdcXo4wbakBgiUFafXJV8A4DJ/2UrxUKm3E95H8RbjLcgOJRGILhnmCP+FBy5XvwN2uIPcy1AJvWgqC4xm2aU4Xb3lF4I+Tpyf8hRe5w3J7YLymSeA8Z3nSclv4WLRyFdfOjzrUFX0klJUEtZtntCNc+F69cz/FiDzEPtjzmcUMOr83kDQEX6pAJxJfpL3OX22n01YN7SZCoQnaSdoZ+Jz+PZihH3wt/xlCoT9M6nEtmRSPCQAAAABJRU5ErkJggg=='; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Logs.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Logs.php new file mode 100644 index 0000000..ed279c7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Logs.php @@ -0,0 +1,139 @@ + $this->collectLogs(), + ]; + } + + //-------------------------------------------------------------------- + + /** + * Does this collector actually have any data to display? + * + * @return boolean + */ + public function isEmpty(): bool + { + $this->collectLogs(); + + return empty($this->data); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACYSURBVEhLYxgFJIHU1FSjtLS0i0D8AYj7gEKMEBkqAaAFF4D4ERCvAFrwH4gDoFIMKSkpFkB+OTEYqgUTACXfA/GqjIwMQyD9H2hRHlQKJFcBEiMGQ7VgAqCBvUgK32dmZspCpagGGNPT0/1BLqeF4bQHQJePpiIwhmrBBEADR1MRfgB0+WgqAmOoFkwANHA0FY0CUgEDAwCQ0PUpNB3kqwAAAABJRU5ErkJggg=='; + } + + //-------------------------------------------------------------------- + + /** + * Ensures the data has been collected. + */ + protected function collectLogs() + { + if (! is_null($this->data)) + { + return $this->data; + } + + return $this->data = Services::logger(true)->logCache ?? []; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Routes.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Routes.php new file mode 100644 index 0000000..f75374d --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Routes.php @@ -0,0 +1,202 @@ +getMatchedRoute(); + + // Get our parameters + // Closure routes + if (is_callable($router->controllerName())) + { + $method = new \ReflectionFunction($router->controllerName()); + } + else + { + try + { + $method = new \ReflectionMethod($router->controllerName(), $router->methodName()); + } + catch (\ReflectionException $e) + { + // If we're here, the method doesn't exist + // and is likely calculated in _remap. + $method = new \ReflectionMethod($router->controllerName(), '_remap'); + } + } + + $rawParams = $method->getParameters(); + + $params = []; + foreach ($rawParams as $key => $param) + { + $params[] = [ + 'name' => $param->getName(), + 'value' => $router->params()[$key] ?? + '<empty> | default: ' . var_export($param->isDefaultValueAvailable() ? $param->getDefaultValue() : null, true), + ]; + } + + $matchedRoute = [ + [ + 'directory' => $router->directory(), + 'controller' => $router->controllerName(), + 'method' => $router->methodName(), + 'paramCount' => count($router->params()), + 'truePCount' => count($params), + 'params' => $params ?? [], + ], + ]; + + /* + * Defined Routes + */ + $routes = []; + $methods = [ + 'get', + 'head', + 'post', + 'patch', + 'put', + 'delete', + 'options', + 'trace', + 'connect', + 'cli', + ]; + + foreach ($methods as $method) + { + $raw = $rawRoutes->getRoutes($method); + + foreach ($raw as $route => $handler) + { + // filter for strings, as callbacks aren't displayable + if (is_string($handler)) + { + $routes[] = [ + 'method' => strtoupper($method), + 'route' => $route, + 'handler' => $handler, + ]; + } + } + } + + return [ + 'matchedRoute' => $matchedRoute, + 'routes' => $routes, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Returns a count of all the routes in the system. + * + * @return integer + */ + public function getBadgeValue(): int + { + $rawRoutes = Services::routes(true); + + return count($rawRoutes->getRoutes()); + } + + //-------------------------------------------------------------------- + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAFDSURBVEhL7ZRNSsNQFIUjVXSiOFEcuQIHDpzpxC0IGYeE/BEInbWlCHEDLsSiuANdhKDjgm6ggtSJ+l25ldrmmTwIgtgDh/t37r1J+16cX0dRFMtpmu5pWAkrvYjjOB7AETzStBFW+inxu3KUJMmhludQpoflS1zXban4LYqiO224h6VLTHr8Z+z8EpIHFF9gG78nDVmW7UgTHKjsCyY98QP+pcq+g8Ku2s8G8X3f3/I8b038WZTp+bO38zxfFd+I6YY6sNUvFlSDk9CRhiAI1jX1I9Cfw7GG1UB8LAuwbU0ZwQnbRDeEN5qqBxZMLtE1ti9LtbREnMIuOXnyIf5rGIb7Wq8HmlZgwYBH7ORTcKH5E4mpjeGt9fBZcHE2GCQ3Vt7oTNPNg+FXLHnSsHkw/FR+Gg2bB8Ptzrst/v6C/wrH+QB+duli6MYJdQAAAABJRU5ErkJggg=='; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Timers.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Timers.php new file mode 100644 index 0000000..d6168c6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Timers.php @@ -0,0 +1,107 @@ +getTimers(6); + + foreach ($rows as $name => $info) + { + if ($name === 'total_execution') + { + continue; + } + + $data[] = [ + 'name' => ucwords(str_replace('_', ' ', $name)), + 'component' => 'Timer', + 'start' => $info['start'], + 'duration' => $info['end'] - $info['start'], + ]; + } + + return $data; + } + +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Views.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Views.php new file mode 100644 index 0000000..bf0c110 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Collectors/Views.php @@ -0,0 +1,192 @@ +viewer = Services::renderer(); + } + + //-------------------------------------------------------------------- + + /** + * Child classes should implement this to return the timeline data + * formatted for correct usage. + * + * @return array + */ + protected function formatTimelineData(): array + { + $data = []; + + $rows = $this->viewer->getPerformanceData(); + + foreach ($rows as $info) + { + $data[] = [ + 'name' => 'View: ' . $info['view'], + 'component' => 'Views', + 'start' => $info['start'], + 'duration' => $info['end'] - $info['start'], + ]; + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * Gets a collection of data that should be shown in the 'Vars' tab. + * The format is an array of sections, each with their own array + * of key/value pairs: + * + * $data = [ + * 'section 1' => [ + * 'foo' => 'bar, + * 'bar' => 'baz' + * ], + * 'section 2' => [ + * 'foo' => 'bar, + * 'bar' => 'baz' + * ], + * ]; + * + * @return array + */ + public function getVarData(): array + { + return [ + 'View Data' => $this->viewer->getData(), + ]; + } + + //-------------------------------------------------------------------- + + /** + * Returns a count of all views. + * + * @return integer + */ + public function getBadgeValue(): int + { + return count($this->viewer->getPerformanceData()); + } + + /** + * Display the icon. + * + * Icon from https://icons8.com - 1em package + * + * @return string + */ + public function icon(): string + { + return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADeSURBVEhL7ZSxDcIwEEWNYA0YgGmgyAaJLTcUaaBzQQEVjMEabBQxAdw53zTHiThEovGTfnE/9rsoRUxhKLOmaa6Uh7X2+UvguLCzVxN1XW9x4EYHzik033Hp3X0LO+DaQG8MDQcuq6qao4qkHuMgQggLvkPLjqh00ZgFDBacMJYFkuwFlH1mshdkZ5JPJERA9JpI6xNCBESvibQ+IURA9JpI6xNCBESvibQ+IURA9DTsuHTOrVFFxixgB/eUFlU8uKJ0eDBFOu/9EvoeKnlJS2/08Tc8NOwQ8sIfMeYFjqKDjdU2sp4AAAAASUVORK5CYII='; + } +} diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_config.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_config.tpl new file mode 100644 index 0000000..4247e81 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_config.tpl @@ -0,0 +1,48 @@ +

+ Read the CodeIgniter docs... +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
CodeIgniter Version:{ ciVersion }
PHP Version:{ phpVersion }
PHP SAPI:{ phpSAPI }
Environment:{ environment }
Base URL: + { if $baseURL == '' } +
+ The $baseURL should always be set manually to prevent possible URL personification from external parties. +
+ { else } + { baseURL } + { endif } +
TimeZone:{ timezone }
Locale:{ locale }
Content Security Policy Enabled:{ if $cspEnabled } Yes { else } No { endif }
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_database.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_database.tpl new file mode 100644 index 0000000..b5cf1a4 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_database.tpl @@ -0,0 +1,16 @@ + + + + + + + + + {queries} + + + + + {/queries} + +
TimeQuery String
{duration}{! sql !}
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_events.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_events.tpl new file mode 100644 index 0000000..88d732f --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_events.tpl @@ -0,0 +1,18 @@ + + + + + + + + + + {events} + + + + + + {/events} + +
TimeEvent NameTimes Called
{ duration } ms{event}{count}
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_files.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_files.tpl new file mode 100644 index 0000000..9c992ab --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_files.tpl @@ -0,0 +1,16 @@ + + + {userFiles} + + + + + {/userFiles} + {coreFiles} + + + + + {/coreFiles} + +
{name}{path}
{name}{path}
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_history.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_history.tpl new file mode 100644 index 0000000..9db00ec --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_history.tpl @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + {files} + + + + + + + + + + {/files} + +
ActionDatetimeStatusMethodURLContent-TypeIs AJAX?
+ + {datetime}{status}{method}{url}{contentType}{isAJAX}
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_logs.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_logs.tpl new file mode 100644 index 0000000..7c80d84 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_logs.tpl @@ -0,0 +1,20 @@ +{ if $logs == [] } +

Nothing was logged. If you were expecting logged items, ensure that LoggerConfig file has the correct threshold set.

+{ else } + + + + + + + + + {logs} + + + + + {/logs} + +
SeverityMessage
{level}{msg}
+{ endif } diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_routes.tpl b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_routes.tpl new file mode 100644 index 0000000..e277046 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/_routes.tpl @@ -0,0 +1,52 @@ +

Matched Route

+ + + + {matchedRoute} + + + + + + + + + + + + + + + + + {params} + + + + + {/params} + {/matchedRoute} + +
Directory:{directory}
Controller:{controller}
Method:{method}
Params:{paramCount} / {truePCount}
{name}{value}
+ + +

Defined Routes

+ + + + + + + + + + + {routes} + + + + + + {/routes} + +
MethodRouteHandler
{method}{route}{handler}
diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.css b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.css new file mode 100644 index 0000000..e2abb4c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.css @@ -0,0 +1,609 @@ +/* CodeIgniter 4 - Debug bar + ============================================================================ */ +/* Forum: https://forum.codeigniter.com + * Github: https://github.com/codeigniter4/codeigniter4 + * Slack: https://codeigniterchat.slack.com + * Website: https://codeigniter.com + */ +#debug-icon { + bottom: 0; + position: fixed; + right: 0; + z-index: 10000; + height: 36px; + width: 36px; + margin: 0px; + padding: 0px; + clear: both; + text-align: center; } + #debug-icon a svg { + margin: 8px; + max-width: 20px; + max-height: 20px; } + #debug-icon.fixed-top { + bottom: auto; + top: 0; } + #debug-icon .debug-bar-ndisplay { + display: none; } + +#debug-bar { + bottom: 0; + left: 0; + position: fixed; + right: 0; + z-index: 10000; + height: 36px; + line-height: 36px; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; + font-size: 16px; + font-weight: 400; } + #debug-bar h1 { + bottom: 0; + display: inline-block; + font-size: 14px; + font-weight: normal; + margin: 0 16px 0 0; + padding: 0; + position: absolute; + right: 30px; + text-align: left; + top: 0; } + #debug-bar h2 { + font-size: 16px; + margin: 0; + padding: 5px 0 10px 0; } + #debug-bar h2 span { + font-size: 13px; } + #debug-bar h3 { + font-size: 12px; + font-weight: 200; + margin: 0 0 0 10px; + padding: 0; + text-transform: uppercase; } + #debug-bar p { + font-size: 12px; + margin: 0 0 0 15px; + padding: 0; } + #debug-bar a { + text-decoration: none; } + #debug-bar a:hover { + text-decoration: underline; } + #debug-bar button { + border: 1px solid; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + cursor: pointer; + line-height: 15px; } + #debug-bar button:hover { + text-decoration: underline; } + #debug-bar table { + border-collapse: collapse; + font-size: 14px; + line-height: normal; + margin: 5px 10px 15px 10px; + width: calc(100% - 10px); } + #debug-bar table strong { + font-weight: 500; } + #debug-bar table th { + display: table-cell; + font-weight: 600; + padding-bottom: 0.7em; + text-align: left; } + #debug-bar table tr { + border: none; } + #debug-bar table td { + border: none; + display: table-cell; + margin: 0; + text-align: left; } + #debug-bar table td:first-child { + max-width: 20%; } + #debug-bar table td:first-child.narrow { + width: 7em; } + #debug-bar .toolbar { + display: block; + overflow: hidden; + overflow-y: auto; + padding: 0 12px 0 12px; + /* give room for OS X scrollbar */ + white-space: nowrap; + z-index: 10000; } + #debug-bar.fixed-top { + bottom: auto; + top: 0; } + #debug-bar.fixed-top .tab { + bottom: auto; + top: 36px; } + #debug-bar #toolbar-position a, + #debug-bar #toolbar-theme a { + float: left; + padding: 0 6px; } + #debug-bar #toolbar-position a:hover, + #debug-bar #toolbar-theme a:hover { + text-decoration: none; } + #debug-bar #debug-bar-link { + bottom: 0; + display: inline-block; + font-size: 16px; + line-height: 36px; + padding: 6px; + position: absolute; + right: 10px; + top: 0; + width: 24px; } + #debug-bar .ci-label { + display: inline-block; + font-size: 14px; + vertical-align: baseline; } + #debug-bar .ci-label:hover { + cursor: pointer; } + #debug-bar .ci-label a { + color: inherit; + display: block; + letter-spacing: normal; + padding: 0 10px; + text-decoration: none; } + #debug-bar .ci-label img { + clear: left; + display: inline-block; + float: left; + margin: 6px 3px 6px 0; + width: 16px !important; + } + #debug-bar .ci-label .badge { + border-radius: 12px; + -moz-border-radius: 12px; + -webkit-border-radius: 12px; + display: inline-block; + font-size: 75%; + font-weight: bold; + line-height: 12px; + margin-left: 5px; + padding: 2px 5px; + text-align: center; + vertical-align: baseline; + white-space: nowrap; } + #debug-bar .tab { + bottom: 35px; + display: none; + left: 0; + max-height: 62%; + overflow: hidden; + overflow-y: auto; + padding: 1em 2em; + position: fixed; + right: 0; + z-index: 9999; } + #debug-bar .timeline { + margin-left: 0; + width: 100%; } + #debug-bar .timeline th { + border-left: 1px solid; + font-size: 12px; + font-weight: 200; + padding: 5px 5px 10px 5px; + position: relative; + text-align: left; } + #debug-bar .timeline th:first-child { + border-left: 0; } + #debug-bar .timeline td { + border-left: 1px solid; + padding: 5px; + position: relative; } + #debug-bar .timeline td:first-child { + border-left: 0; } + #debug-bar .timeline .timer { + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + display: inline-block; + padding: 5px; + position: absolute; + top: 30%; } + #debug-bar .route-params, + #debug-bar .route-params-item { + vertical-align: top; } + #debug-bar .route-params td:first-child, + #debug-bar .route-params-item td:first-child { + font-style: italic; + padding-left: 1em; + text-align: right; } + +.debug-view.show-view { + border: 1px solid; + margin: 4px; } + +.debug-view-path { + font-family: monospace; + font-size: 12px; + letter-spacing: normal; + min-height: 16px; + padding: 2px; + text-align: left; } + +.show-view .debug-view-path { + display: block !important; } + +@media screen and (max-width: 1024px) { + .hide-sm { + display: none !important; } } +#debug-icon { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #debug-icon a:active, #debug-icon a:link, #debug-icon a:visited { + color: #DD8615; } + +#debug-bar { + background-color: #FFFFFF; + color: #434343; } + #debug-bar h1, + #debug-bar h2, + #debug-bar h3, + #debug-bar p, + #debug-bar a, + #debug-bar button, + #debug-bar table, + #debug-bar thead, + #debug-bar tr, + #debug-bar td, + #debug-bar button, + #debug-bar .toolbar { + background-color: transparent; + color: #434343; } + #debug-bar button { + background-color: #FFFFFF; } + #debug-bar table strong { + color: #FDC894; } + #debug-bar table tbody tr:hover { + background-color: #DFDFDF; } + #debug-bar table tbody tr.current { + background-color: #FDC894; } + #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; } + #debug-bar .toolbar { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #debug-bar .toolbar img { + filter: brightness(0) invert(0.4); } + #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #DFDFDF; + -moz-box-shadow: 0 1px 4px #DFDFDF; + -webkit-box-shadow: 0 1px 4px #DFDFDF; } + #debug-bar .muted { + color: #434343; } + #debug-bar .muted td { + color: #DFDFDF; } + #debug-bar .muted:hover td { + color: #434343; } + #debug-bar #toolbar-position, + #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); } + #debug-bar .ci-label.active { + background-color: #DFDFDF; } + #debug-bar .ci-label:hover { + background-color: #DFDFDF; } + #debug-bar .ci-label .badge { + background-color: #5BC0DE; + color: #FFFFFF; } + #debug-bar .tab { + background-color: #FFFFFF; + box-shadow: 0 -1px 4px #DFDFDF; + -moz-box-shadow: 0 -1px 4px #DFDFDF; + -webkit-box-shadow: 0 -1px 4px #DFDFDF; } + #debug-bar .timeline th, + #debug-bar .timeline td { + border-color: #DFDFDF; } + #debug-bar .timeline .timer { + background-color: #DD8615; } + +.debug-view.show-view { + border-color: #DD8615; } + +.debug-view-path { + background-color: #FDC894; + color: #434343; } + +@media (prefers-color-scheme: dark) { + #debug-icon { + background-color: #252525; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #debug-icon a:active, #debug-icon a:link, #debug-icon a:visited { + color: #DD8615; } + + #debug-bar { + background-color: #252525; + color: #DFDFDF; } + #debug-bar h1, + #debug-bar h2, + #debug-bar h3, + #debug-bar p, + #debug-bar a, + #debug-bar button, + #debug-bar table, + #debug-bar thead, + #debug-bar tr, + #debug-bar td, + #debug-bar button, + #debug-bar .toolbar { + background-color: transparent; + color: #DFDFDF; } + #debug-bar button { + background-color: #252525; } + #debug-bar table strong { + color: #FDC894; } + #debug-bar table tbody tr:hover { + background-color: #434343; } + #debug-bar table tbody tr.current { + background-color: #FDC894; } + #debug-bar table tbody tr.current td { + color: #252525; } + #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; } + #debug-bar .toolbar { + background-color: #434343; + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; } + #debug-bar .toolbar img { + filter: brightness(0) invert(1); } + #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; } + #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #434343; + -moz-box-shadow: 0 1px 4px #434343; + -webkit-box-shadow: 0 1px 4px #434343; } + #debug-bar .muted { + color: #DFDFDF; } + #debug-bar .muted td { + color: #434343; } + #debug-bar .muted:hover td { + color: #DFDFDF; } + #debug-bar #toolbar-position, + #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); } + #debug-bar .ci-label.active { + background-color: #252525; } + #debug-bar .ci-label:hover { + background-color: #252525; } + #debug-bar .ci-label .badge { + background-color: #5BC0DE; + color: #DFDFDF; } + #debug-bar .tab { + background-color: #252525; + box-shadow: 0 -1px 4px #434343; + -moz-box-shadow: 0 -1px 4px #434343; + -webkit-box-shadow: 0 -1px 4px #434343; } + #debug-bar .timeline th, + #debug-bar .timeline td { + border-color: #434343; } + #debug-bar .timeline .timer { + background-color: #DD8615; } + + .debug-view.show-view { + border-color: #DD8615; } + + .debug-view-path { + background-color: #FDC894; + color: #434343; } } +#toolbarContainer.dark #debug-icon { + background-color: #252525; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #toolbarContainer.dark #debug-icon a:active, #toolbarContainer.dark #debug-icon a:link, #toolbarContainer.dark #debug-icon a:visited { + color: #DD8615; } +#toolbarContainer.dark #debug-bar { + background-color: #252525; + color: #DFDFDF; } + #toolbarContainer.dark #debug-bar h1, + #toolbarContainer.dark #debug-bar h2, + #toolbarContainer.dark #debug-bar h3, + #toolbarContainer.dark #debug-bar p, + #toolbarContainer.dark #debug-bar a, + #toolbarContainer.dark #debug-bar button, + #toolbarContainer.dark #debug-bar table, + #toolbarContainer.dark #debug-bar thead, + #toolbarContainer.dark #debug-bar tr, + #toolbarContainer.dark #debug-bar td, + #toolbarContainer.dark #debug-bar button, + #toolbarContainer.dark #debug-bar .toolbar { + background-color: transparent; + color: #DFDFDF; } + #toolbarContainer.dark #debug-bar button { + background-color: #252525; } + #toolbarContainer.dark #debug-bar table strong { + color: #FDC894; } + #toolbarContainer.dark #debug-bar table tbody tr:hover { + background-color: #434343; } + #toolbarContainer.dark #debug-bar table tbody tr.current { + background-color: #FDC894; } + #toolbarContainer.dark #debug-bar table tbody tr.current td { + color: #252525; } + #toolbarContainer.dark #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; } + #toolbarContainer.dark #debug-bar .toolbar { + background-color: #434343; + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; } + #toolbarContainer.dark #debug-bar .toolbar img { + filter: brightness(0) invert(1); } + #toolbarContainer.dark #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #434343; + -moz-box-shadow: 0 0 4px #434343; + -webkit-box-shadow: 0 0 4px #434343; } + #toolbarContainer.dark #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #434343; + -moz-box-shadow: 0 1px 4px #434343; + -webkit-box-shadow: 0 1px 4px #434343; } + #toolbarContainer.dark #debug-bar .muted { + color: #DFDFDF; } + #toolbarContainer.dark #debug-bar .muted td { + color: #434343; } + #toolbarContainer.dark #debug-bar .muted:hover td { + color: #DFDFDF; } + #toolbarContainer.dark #debug-bar #toolbar-position, + #toolbarContainer.dark #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); } + #toolbarContainer.dark #debug-bar .ci-label.active { + background-color: #252525; } + #toolbarContainer.dark #debug-bar .ci-label:hover { + background-color: #252525; } + #toolbarContainer.dark #debug-bar .ci-label .badge { + background-color: #5BC0DE; + color: #DFDFDF; } + #toolbarContainer.dark #debug-bar .tab { + background-color: #252525; + box-shadow: 0 -1px 4px #434343; + -moz-box-shadow: 0 -1px 4px #434343; + -webkit-box-shadow: 0 -1px 4px #434343; } + #toolbarContainer.dark #debug-bar .timeline th, + #toolbarContainer.dark #debug-bar .timeline td { + border-color: #434343; } + #toolbarContainer.dark #debug-bar .timeline .timer { + background-color: #DD8615; } +#toolbarContainer.dark .debug-view.show-view { + border-color: #DD8615; } +#toolbarContainer.dark .debug-view-path { + background-color: #FDC894; + color: #434343; } + +#toolbarContainer.light #debug-icon { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #toolbarContainer.light #debug-icon a:active, #toolbarContainer.light #debug-icon a:link, #toolbarContainer.light #debug-icon a:visited { + color: #DD8615; } +#toolbarContainer.light #debug-bar { + background-color: #FFFFFF; + color: #434343; } + #toolbarContainer.light #debug-bar h1, + #toolbarContainer.light #debug-bar h2, + #toolbarContainer.light #debug-bar h3, + #toolbarContainer.light #debug-bar p, + #toolbarContainer.light #debug-bar a, + #toolbarContainer.light #debug-bar button, + #toolbarContainer.light #debug-bar table, + #toolbarContainer.light #debug-bar thead, + #toolbarContainer.light #debug-bar tr, + #toolbarContainer.light #debug-bar td, + #toolbarContainer.light #debug-bar button, + #toolbarContainer.light #debug-bar .toolbar { + background-color: transparent; + color: #434343; } + #toolbarContainer.light #debug-bar button { + background-color: #FFFFFF; } + #toolbarContainer.light #debug-bar table strong { + color: #FDC894; } + #toolbarContainer.light #debug-bar table tbody tr:hover { + background-color: #DFDFDF; } + #toolbarContainer.light #debug-bar table tbody tr.current { + background-color: #FDC894; } + #toolbarContainer.light #debug-bar table tbody tr.current:hover td { + background-color: #DD4814; + color: #FFFFFF; } + #toolbarContainer.light #debug-bar .toolbar { + background-color: #FFFFFF; + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #toolbarContainer.light #debug-bar .toolbar img { + filter: brightness(0) invert(0.4); } + #toolbarContainer.light #debug-bar.fixed-top .toolbar { + box-shadow: 0 0 4px #DFDFDF; + -moz-box-shadow: 0 0 4px #DFDFDF; + -webkit-box-shadow: 0 0 4px #DFDFDF; } + #toolbarContainer.light #debug-bar.fixed-top .tab { + box-shadow: 0 1px 4px #DFDFDF; + -moz-box-shadow: 0 1px 4px #DFDFDF; + -webkit-box-shadow: 0 1px 4px #DFDFDF; } + #toolbarContainer.light #debug-bar .muted { + color: #434343; } + #toolbarContainer.light #debug-bar .muted td { + color: #DFDFDF; } + #toolbarContainer.light #debug-bar .muted:hover td { + color: #434343; } + #toolbarContainer.light #debug-bar #toolbar-position, + #toolbarContainer.light #debug-bar #toolbar-theme { + filter: brightness(0) invert(0.6); } + #toolbarContainer.light #debug-bar .ci-label.active { + background-color: #DFDFDF; } + #toolbarContainer.light #debug-bar .ci-label:hover { + background-color: #DFDFDF; } + #toolbarContainer.light #debug-bar .ci-label .badge { + background-color: #5BC0DE; + color: #FFFFFF; } + #toolbarContainer.light #debug-bar .tab { + background-color: #FFFFFF; + box-shadow: 0 -1px 4px #DFDFDF; + -moz-box-shadow: 0 -1px 4px #DFDFDF; + -webkit-box-shadow: 0 -1px 4px #DFDFDF; } + #toolbarContainer.light #debug-bar .timeline th, + #toolbarContainer.light #debug-bar .timeline td { + border-color: #DFDFDF; } + #toolbarContainer.light #debug-bar .timeline .timer { + background-color: #DD8615; } +#toolbarContainer.light .debug-view.show-view { + border-color: #DD8615; } +#toolbarContainer.light .debug-view-path { + background-color: #FDC894; + color: #434343; } + +.debug-bar-width30 { + width: 30%; } + +.debug-bar-width10 { + width: 10%; } + +.debug-bar-width70p { + width: 70px; } + +.debug-bar-width140p { + width: 140px; } + +.debug-bar-width20e { + width: 20em; } + +.debug-bar-width6r { + width: 6rem; } + +.debug-bar-ndisplay { + display: none; } + +.debug-bar-alignRight { + text-align: right; } + +.debug-bar-alignLeft { + text-align: left; } + +.debug-bar-noverflow { + overflow: hidden; } + +#debug-bar td[data-debugbar-route] form { + display: none; } +#debug-bar td[data-debugbar-route]:hover form { + display: block; } +#debug-bar td[data-debugbar-route]:hover > div { + display: none; } +#debug-bar td[data-debugbar-route] input[type=text] { + padding: 2px; } +#toolbarContainer.dark td[data-debugbar-route] input[type=text] { + background: #000; + color: #fff; } diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.js b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.js new file mode 100644 index 0000000..15fa668 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.js @@ -0,0 +1,661 @@ +/* + * Functionality for the CodeIgniter Debug Toolbar. + */ + +var ciDebugBar = { + + toolbarContainer : null, + toolbar : null, + icon : null, + + //-------------------------------------------------------------------- + + init : function () { + this.toolbarContainer = document.getElementById('toolbarContainer'); + this.toolbar = document.getElementById('debug-bar'); + this.icon = document.getElementById('debug-icon'); + + ciDebugBar.createListeners(); + ciDebugBar.setToolbarState(); + ciDebugBar.setToolbarPosition(); + ciDebugBar.setToolbarTheme(); + ciDebugBar.toggleViewsHints(); + ciDebugBar.routerLink(); + + document.getElementById('debug-bar-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + document.getElementById('debug-icon-link').addEventListener('click', ciDebugBar.toggleToolbar, true); + + // Allows to highlight the row of the current history request + var btn = document.querySelector('button[data-time="' + localStorage.getItem('debugbar-time') + '"]'); + ciDebugBar.addClass(btn.parentNode.parentNode, 'current'); + + historyLoad = document.getElementsByClassName('ci-history-load'); + + for (var i = 0; i < historyLoad.length; i++) + { + historyLoad[i].addEventListener('click', function () { + loadDoc(this.getAttribute('data-time')); + }, true); + } + + // Display the active Tab on page load + var tab = ciDebugBar.readCookie('debug-bar-tab'); + if (document.getElementById(tab)) + { + var el = document.getElementById(tab); + el.style.display = 'block'; + ciDebugBar.addClass(el, 'active'); + tab = document.querySelector('[data-tab=' + tab + ']'); + if (tab) + { + ciDebugBar.addClass(tab.parentNode, 'active'); + } + } + }, + + //-------------------------------------------------------------------- + + createListeners : function () { + var buttons = [].slice.call(document.querySelectorAll('#debug-bar .ci-label a')); + + for (var i = 0; i < buttons.length; i++) + { + buttons[i].addEventListener('click', ciDebugBar.showTab, true); + } + }, + + //-------------------------------------------------------------------- + + showTab: function () { + // Get the target tab, if any + var tab = document.getElementById(this.getAttribute('data-tab')); + + // If the label have not a tab stops here + if (! tab) + { + return; + } + + // Remove debug-bar-tab cookie + ciDebugBar.createCookie('debug-bar-tab', '', -1); + + // Check our current state. + var state = tab.style.display; + + // Hide all tabs + var tabs = document.querySelectorAll('#debug-bar .tab'); + + for (var i = 0; i < tabs.length; i++) + { + tabs[i].style.display = 'none'; + } + + // Mark all labels as inactive + var labels = document.querySelectorAll('#debug-bar .ci-label'); + + for (var i = 0; i < labels.length; i++) + { + ciDebugBar.removeClass(labels[i], 'active'); + } + + // Show/hide the selected tab + if (state != 'block') + { + tab.style.display = 'block'; + ciDebugBar.addClass(this.parentNode, 'active'); + // Create debug-bar-tab cookie to persistent state + ciDebugBar.createCookie('debug-bar-tab', this.getAttribute('data-tab'), 365); + } + }, + + //-------------------------------------------------------------------- + + addClass : function (el, className) { + if (el.classList) + { + el.classList.add(className); + } + else + { + el.className += ' ' + className; + } + }, + + //-------------------------------------------------------------------- + + removeClass : function (el, className) { + if (el.classList) + { + el.classList.remove(className); + } + else + { + el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } + }, + + //-------------------------------------------------------------------- + + /** + * Toggle display of a data table + * + * @param obj + */ + toggleDataTable : function (obj) { + if (typeof obj == 'string') + { + obj = document.getElementById(obj + '_table'); + } + + if (obj) + { + obj.style.display = obj.style.display == 'none' ? 'block' : 'none'; + } + }, + + //-------------------------------------------------------------------- + + /** + * Toggle tool bar from full to icon and icon to full + */ + toggleToolbar : function () { + var open = ciDebugBar.toolbar.style.display != 'none'; + + ciDebugBar.icon.style.display = open == true ? 'inline-block' : 'none'; + ciDebugBar.toolbar.style.display = open == false ? 'inline-block' : 'none'; + + // Remember it for other page loads on this site + ciDebugBar.createCookie('debug-bar-state', '', -1); + ciDebugBar.createCookie('debug-bar-state', open == true ? 'minimized' : 'open' , 365); + }, + + //-------------------------------------------------------------------- + + /** + * Sets the initial state of the toolbar (open or minimized) when + * the page is first loaded to allow it to remember the state between refreshes. + */ + setToolbarState: function () { + var open = ciDebugBar.readCookie('debug-bar-state'); + + ciDebugBar.icon.style.display = open != 'open' ? 'inline-block' : 'none'; + ciDebugBar.toolbar.style.display = open == 'open' ? 'inline-block' : 'none'; + }, + + //-------------------------------------------------------------------- + + toggleViewsHints: function () { + // Avoid toggle hints on history requests that are not the initial + if (localStorage.getItem('debugbar-time') != localStorage.getItem('debugbar-time-new')) + { + var a = document.querySelector('a[data-tab="ci-views"]'); + a.href = '#'; + return; + } + + var nodeList = []; // [ Element, NewElement( 1 )/OldElement( 0 ) ] + var sortedComments = []; + var comments = []; + + var getComments = function () { + var nodes = []; + var result = []; + var xpathResults = document.evaluate( "//comment()[starts-with(., ' DEBUG-VIEW')]", document, null, XPathResult.ANY_TYPE, null); + var nextNode = xpathResults.iterateNext(); + while ( nextNode ) + { + nodes.push( nextNode ); + nextNode = xpathResults.iterateNext(); + } + + // sort comment by opening and closing tags + for (var i = 0; i < nodes.length; ++i) + { + // get file path + name to use as key + var path = nodes[i].nodeValue.substring( 18, nodes[i].nodeValue.length - 1 ); + + if ( nodes[i].nodeValue[12] === 'S' ) // simple check for start comment + { + // create new entry + result[path] = [ nodes[i], null ]; + } + else if (result[path]) + { + // add to existing entry + result[path][1] = nodes[i]; + } + } + + return result; + }; + + // find node that has TargetNode as parentNode + var getParentNode = function ( node, targetNode ) { + if ( node.parentNode === null ) + { + return null; + } + + if ( node.parentNode !== targetNode ) + { + return getParentNode( node.parentNode, targetNode ); + } + + return node; + }; + + // define invalid & outer ( also invalid ) elements + const INVALID_ELEMENTS = [ 'NOSCRIPT', 'SCRIPT', 'STYLE' ]; + const OUTER_ELEMENTS = [ 'HTML', 'BODY', 'HEAD' ]; + + var getValidElementInner = function ( node, reverse ) { + // handle invalid tags + if ( OUTER_ELEMENTS.indexOf( node.nodeName ) !== -1 ) + { + for (var i = 0; i < document.body.children.length; ++i) + { + var index = reverse ? document.body.children.length - ( i + 1 ) : i; + var element = document.body.children[index]; + + // skip invalid tags + if ( INVALID_ELEMENTS.indexOf( element.nodeName ) !== -1 ) + { + continue; + } + + return [ element, reverse ]; + } + + return null; + } + + // get to next valid element + while ( node !== null && INVALID_ELEMENTS.indexOf( node.nodeName ) !== -1 ) + { + node = reverse ? node.previousElementSibling : node.nextElementSibling; + } + + // return non array if we couldnt find something + if ( node === null ) + { + return null; + } + + return [ node, reverse ]; + }; + + // get next valid element ( to be safe to add divs ) + // @return [ element, skip element ] or null if we couldnt find a valid place + var getValidElement = function ( nodeElement ) { + if (nodeElement) + { + if ( nodeElement.nextElementSibling !== null ) + { + return getValidElementInner( nodeElement.nextElementSibling, false ) + || getValidElementInner( nodeElement.previousElementSibling, true ); + } + if ( nodeElement.previousElementSibling !== null ) + { + return getValidElementInner( nodeElement.previousElementSibling, true ); + } + } + + // something went wrong! -> element is not in DOM + return null; + }; + + function showHints() + { + // Had AJAX? Reset view blocks + sortedComments = getComments(); + + for (var key in sortedComments) + { + var startElement = getValidElement( sortedComments[key][0] ); + var endElement = getValidElement( sortedComments[key][1] ); + + // skip if we couldnt get a valid element + if ( startElement === null || endElement === null ) + { + continue; + } + + // find element which has same parent as startelement + var jointParent = getParentNode( endElement[0], startElement[0].parentNode ); + if ( jointParent === null ) + { + // find element which has same parent as endelement + jointParent = getParentNode( startElement[0], endElement[0].parentNode ); + if ( jointParent === null ) + { + // both tries failed + continue; + } + else + { + startElement[0] = jointParent; + } + } + else + { + endElement[0] = jointParent; + } + + var debugDiv = document.createElement( 'div' ); // holder + var debugPath = document.createElement( 'div' ); // path + var childArray = startElement[0].parentNode.childNodes; // target child array + var parent = startElement[0].parentNode; + var start, end; + + // setup container + debugDiv.classList.add( 'debug-view' ); + debugDiv.classList.add( 'show-view' ); + debugPath.classList.add( 'debug-view-path' ); + debugPath.innerText = key; + debugDiv.appendChild( debugPath ); + + // calc distance between them + // start + for (var i = 0; i < childArray.length; ++i) + { + // check for comment ( start & end ) -> if its before valid start element + if ( childArray[i] === sortedComments[key][1] || + childArray[i] === sortedComments[key][0] || + childArray[i] === startElement[0] ) + { + start = i; + if ( childArray[i] === sortedComments[key][0] ) + { + start++; // increase to skip the start comment + } + break; + } + } + // adjust if we want to skip the start element + if ( startElement[1] ) + { + start++; + } + + // end + for (var i = start; i < childArray.length; ++i) + { + if ( childArray[i] === endElement[0] ) + { + end = i; + // dont break to check for end comment after end valid element + } + else if ( childArray[i] === sortedComments[key][1] ) + { + // if we found the end comment, we can break + end = i; + break; + } + } + + // move elements + var number = end - start; + if ( endElement[1] ) + { + number++; + } + for (var i = 0; i < number; ++i) + { + if ( INVALID_ELEMENTS.indexOf( childArray[start] ) !== -1 ) + { + // skip invalid childs that can cause problems if moved + start++; + continue; + } + debugDiv.appendChild( childArray[start] ); + } + + // add container to DOM + nodeList.push( parent.insertBefore( debugDiv, childArray[start] ) ); + } + + ciDebugBar.createCookie('debug-view', 'show', 365); + ciDebugBar.addClass(btn, 'active'); + } + + function hideHints() + { + for (var i = 0; i < nodeList.length; ++i) + { + var index; + + // find index + for (var j = 0; j < nodeList[i].parentNode.childNodes.length; ++j) + { + if ( nodeList[i].parentNode.childNodes[j] === nodeList[i] ) + { + index = j; + break; + } + } + + // move child back + while ( nodeList[i].childNodes.length !== 1 ) + { + nodeList[i].parentNode.insertBefore( nodeList[i].childNodes[1], nodeList[i].parentNode.childNodes[index].nextSibling ); + index++; + } + + nodeList[i].parentNode.removeChild( nodeList[i] ); + } + nodeList.length = 0; + + ciDebugBar.createCookie('debug-view', '', -1); + ciDebugBar.removeClass(btn, 'active'); + } + + var btn = document.querySelector('[data-tab=ci-views]'); + + // If the Views Collector is inactive stops here + if (! btn) + { + return; + } + + btn.parentNode.onclick = function () { + if (ciDebugBar.readCookie('debug-view')) + { + hideHints(); + } + else + { + showHints(); + } + }; + + // Determine Hints state on page load + if (ciDebugBar.readCookie('debug-view')) + { + showHints(); + } + }, + + //-------------------------------------------------------------------- + + setToolbarPosition: function () { + var btnPosition = document.getElementById('toolbar-position'); + + if (ciDebugBar.readCookie('debug-bar-position') === 'top') + { + ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); + } + + btnPosition.addEventListener('click', function () { + var position = ciDebugBar.readCookie('debug-bar-position'); + + ciDebugBar.createCookie('debug-bar-position', '', -1); + + if (!position || position === 'bottom') + { + ciDebugBar.createCookie('debug-bar-position', 'top', 365); + ciDebugBar.addClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.addClass(ciDebugBar.toolbar, 'fixed-top'); + } + else + { + ciDebugBar.createCookie('debug-bar-position', 'bottom', 365); + ciDebugBar.removeClass(ciDebugBar.icon, 'fixed-top'); + ciDebugBar.removeClass(ciDebugBar.toolbar, 'fixed-top'); + } + }, true); + }, + + //-------------------------------------------------------------------- + + setToolbarTheme: function () { + var btnTheme = document.getElementById('toolbar-theme'); + var isDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches; + var isLightMode = window.matchMedia("(prefers-color-scheme: light)").matches; + + // If a cookie is set with a value, we force the color scheme + if (ciDebugBar.readCookie('debug-bar-theme') === 'dark') + { + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); + } + else if (ciDebugBar.readCookie('debug-bar-theme') === 'light') + { + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + + btnTheme.addEventListener('click', function () { + var theme = ciDebugBar.readCookie('debug-bar-theme'); + + if (!theme && window.matchMedia("(prefers-color-scheme: dark)").matches) + { + // If there is no cookie, and "prefers-color-scheme" is set to "dark" + // It means that the user wants to switch to light mode + ciDebugBar.createCookie('debug-bar-theme', 'light', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + else + { + if (theme === 'dark') + { + ciDebugBar.createCookie('debug-bar-theme', 'light', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'dark'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'light'); + } + else + { + // In any other cases: if there is no cookie, or the cookie is set to + // "light", or the "prefers-color-scheme" is "light"... + ciDebugBar.createCookie('debug-bar-theme', 'dark', 365); + ciDebugBar.removeClass(ciDebugBar.toolbarContainer, 'light'); + ciDebugBar.addClass(ciDebugBar.toolbarContainer, 'dark'); + } + } + }, true); + }, + + //-------------------------------------------------------------------- + + /** + * Helper to create a cookie. + * + * @param name + * @param value + * @param days + */ + createCookie : function (name,value,days) { + if (days) + { + var date = new Date(); + + date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000)); + + var expires = "; expires=" + date.toGMTString(); + } + else + { + var expires = ""; + } + + document.cookie = name + "=" + value + expires + "; path=/"; + }, + + //-------------------------------------------------------------------- + + readCookie : function (name) { + var nameEQ = name + "="; + var ca = document.cookie.split(';'); + + for (var i = 0; i < ca.length; i++) + { + var c = ca[i]; + while (c.charAt(0) == ' ') + { + c = c.substring(1,c.length); + } + if (c.indexOf(nameEQ) == 0) + { + return c.substring(nameEQ.length,c.length); + } + } + return null; + }, + + //-------------------------------------------------------------------- + + trimSlash: function(text) { + return text.replace(/^\/|\/$/g, ''); + }, + + routerLink: function() { + var row, _location; + var rowGet = document.querySelectorAll('#debug-bar td[data-debugbar-route="GET"]'); + var patt = /\((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*\)/; + + for (var i = 0; i < rowGet.length; i++) { + row = rowGet[i]; + if (!/\/\(.+?\)/.test(rowGet[i].innerText)) { + row.style = 'cursor: pointer;'; + row.setAttribute('title', location.origin + '/' + ciDebugBar.trimSlash(row.innerText)); + row.addEventListener('click', function(ev) { + _location = location.origin + '/' + ciDebugBar.trimSlash(ev.target.innerText); + var redirectWindow = window.open(_location, '_blank'); + redirectWindow.location; + }); + } + else { + row.innerHTML = '
' + row.innerText + '
' + + '
' + + row.innerText.replace(patt, '') + + '' + + '
'; + } + } + + rowGet = document.querySelectorAll('#debug-bar td[data-debugbar-route="GET"] form'); + for (var i = 0; i < rowGet.length; i++) { + row = rowGet[i]; + + row.addEventListener('submit', function(event) { + event.preventDefault() + var inputArray = [], t = 0; + var input = event.target.querySelectorAll('input[type=text]'); + var tpl = event.target.getAttribute('data-debugbar-route-tpl'); + + for (var n = 0; n < input.length; n++) { + if (input[n].value.length > 0) inputArray.push(input[n].value); + } + + if (inputArray.length > 0) { + _location = location.origin + '/' + tpl.replace(/\?/g, function() {return inputArray[t++]}); + var redirectWindow = window.open(_location, '_blank'); + redirectWindow.location; + } + }) + } + + } + +}; diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.tpl.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.tpl.php new file mode 100644 index 0000000..5f5d7c4 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbar.tpl.php @@ -0,0 +1,307 @@ + + + + + +
+
+ + 🔅 + + + + ms   MB + + + + + + + + + + + + + + + + + + + + + + + Vars + + + +

+ + + + + + + + + + +

+ + + + + +
+ + +
+ + + + + + + + + + + + + renderTimeline($collectors, $startTime, $segmentCount, $segmentDuration, + $styles) ?> + +
NAMECOMPONENTDURATION ms
+
+ + + + + +
+

+ + setData($c['display'])->render("_{$c['titleSafe']}.tpl") ?> +
+ + + + + +
+ + + + $items) : ?> + + +

+
+ + + + + + $value) : ?> + + + + + + +
+ + +

No data to display.

+ + + + + + +

Session User Data

+
+ + + + + + $value) : ?> + + + + + + +
+ +

No data to display.

+ + +

Session doesn't seem to be active.

+ + +

Request ( )

+ + + +

$_GET

+
+ + + + $value) : ?> + + + + + + +
+ + + + +

$_POST

+
+ + + + $value) : ?> + + + + + + +
+ + + + +

Headers

+
+ + + + $value) : ?> + + + + + + +
+ + + + +

Cookies

+
+ + + + $value) : ?> + + + + + + + + + +

Response + ( ) +

+ + + +

Headers

+
+ + + + $value) : ?> + + + + + + +
+ +
+ + +
+

System Configuration

+ + setData($config)->render('_config.tpl') ?> +
+
+ diff --git a/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbarloader.js.php b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbarloader.js.php new file mode 100644 index 0000000..af69338 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Debug/Toolbar/Views/toolbarloader.js.php @@ -0,0 +1,90 @@ + +document.addEventListener('DOMContentLoaded', loadDoc, false); + +function loadDoc(time) { + if (isNaN(time)) { + time = document.getElementById("debugbar_loader").getAttribute("data-time"); + localStorage.setItem('debugbar-time', time); + } + + localStorage.setItem('debugbar-time-new', time); + + var url = ""; + + var xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function() { + if (this.readyState === 4 && this.status === 200) { + var toolbar = document.getElementById("toolbarContainer"); + if (!toolbar) { + toolbar = document.createElement('div'); + toolbar.setAttribute('id', 'toolbarContainer'); + document.body.appendChild(toolbar); + } + + // copy for easier manipulation + let responseText = this.responseText; + + // get csp blocked parts + // the style block is the first and starts at 0 + { + let PosBeg = responseText.indexOf( '>', responseText.indexOf( '', PosBeg ); + document.getElementById( 'debugbar_dynamic_style' ).innerHTML = responseText.substr( PosBeg, PosEnd - PosBeg ); + responseText = responseText.substr( PosEnd + 8 ); + } + // the script block starts right after style blocks ended + { + let PosBeg = responseText.indexOf( '>', responseText.indexOf( '' ); + document.getElementById( 'debugbar_dynamic_script' ).innerHTML = responseText.substr( PosBeg, PosEnd - PosBeg ); + responseText = responseText.substr( PosEnd + 9 ); + } + // check for last style block + { + let PosBeg = responseText.indexOf( '>', responseText.lastIndexOf( '', PosBeg ); + document.getElementById( 'debugbar_dynamic_style' ).innerHTML += responseText.substr( PosBeg, PosEnd - PosBeg ); + responseText = responseText.substr( 0, PosBeg + 8 ); + } + + toolbar.innerHTML = responseText; + if (typeof ciDebugBar === 'object') { + ciDebugBar.init(); + } + } else if (this.readyState === 4 && this.status === 404) { + console.log('CodeIgniter DebugBar: File "WRITEPATH/debugbar/debugbar_' + time + '" not found.'); + } + }; + + xhttp.open("GET", url + "?debugbar_time=" + time, true); + xhttp.send(); +} + +// Track all AJAX requests +if (window.ActiveXObject) { + var oldXHR = new ActiveXObject('Microsoft.XMLHTTP'); +} else { + var oldXHR = window.XMLHttpRequest; +} + +function newXHR() { + var realXHR = new oldXHR(); + realXHR.addEventListener("readystatechange", function() { + // Only success responses and URLs that do not contains "debugbar_time" are tracked + if (realXHR.readyState === 4 && realXHR.status.toString()[0] === '2' && realXHR.responseURL.indexOf('debugbar_time') === -1) { + var debugbarTime = realXHR.getResponseHeader('Debugbar-Time'); + if (debugbarTime) { + var h2 = document.querySelector('#ci-history > h2'); + if(h2) { + h2.innerHTML = 'History You have new debug data. '; + var badge = document.querySelector('a[data-tab="ci-history"] > span > .badge'); + badge.className += ' active'; + } + } + } + }, false); + return realXHR; +} + +window.XMLHttpRequest = newXHR; + diff --git a/vendor/codeigniter4/framework/system/Email/Email.php b/vendor/codeigniter4/framework/system/Email/Email.php new file mode 100644 index 0000000..b3a3dcd --- /dev/null +++ b/vendor/codeigniter4/framework/system/Email/Email.php @@ -0,0 +1,2188 @@ + '1 (Highest)', + 2 => '2 (High)', + 3 => '3 (Normal)', + 4 => '4 (Low)', + 5 => '5 (Lowest)', + ]; + /** + * mbstring.func_overload flag + * + * @var boolean + */ + protected static $func_overload; + //-------------------------------------------------------------------- + /** + * Constructor - Sets Email Preferences + * + * The constructor can be passed an array of config values + * + * @param array|null $config + */ + public function __construct($config = null) + { + $this->initialize($config); + isset(static::$func_overload) || static::$func_overload = (extension_loaded('mbstring') && ini_get('mbstring.func_overload')); + } + //-------------------------------------------------------------------- + /** + * Initialize preferences + * + * @param array|\Config\Email $config + * + * @return Email + */ + public function initialize($config) + { + $this->clear(); + if ($config instanceof \Config\Email) + { + $config = get_object_vars($config); + } + foreach (get_class_vars(get_class($this)) as $key => $value) + { + if (property_exists($this, $key) && isset($config[$key])) + { + $method = 'set' . ucfirst($key); + if (method_exists($this, $method)) + { + $this->$method($config[$key]); + } + else + { + $this->$key = $config[$key]; + } + } + } + $this->charset = strtoupper($this->charset); + $this->SMTPAuth = isset($this->SMTPUser[0], $this->SMTPPass[0]); + return $this; + } + //-------------------------------------------------------------------- + /** + * Initialize the Email Data + * + * @param boolean $clearAttachments + * + * @return Email + */ + public function clear($clearAttachments = false) + { + $this->subject = ''; + $this->body = ''; + $this->finalBody = ''; + $this->headerStr = ''; + $this->replyToFlag = false; + $this->recipients = []; + $this->CCArray = []; + $this->BCCArray = []; + $this->headers = []; + $this->debugMessage = []; + $this->setHeader('Date', $this->setDate()); + if ($clearAttachments !== false) + { + $this->attachments = []; + } + return $this; + } + //-------------------------------------------------------------------- + /** + * Set FROM + * + * @param string $from + * @param string $name + * @param string|null $returnPath Return-Path + * + * @return Email + */ + public function setFrom($from, $name = '', $returnPath = null) + { + if (preg_match('/\<(.*)\>/', $from, $match)) + { + $from = $match[1]; + } + if ($this->validate) + { + $this->validateEmail($this->stringToArray($from)); + if ($returnPath) + { + $this->validateEmail($this->stringToArray($returnPath)); + } + } + + // Store the plain text values + $this->tmpArchive['fromEmail'] = $from; + $this->tmpArchive['fromName'] = $name; + + // prepare the display name + if ($name !== '') + { + // only use Q encoding if there are characters that would require it + if (! preg_match('/[\200-\377]/', $name)) + { + // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes + $name = '"' . addcslashes($name, "\0..\37\177'\"\\") . '"'; + } + else + { + $name = $this->prepQEncoding($name); + } + } + $this->setHeader('From', $name . ' <' . $from . '>'); + isset($returnPath) || $returnPath = $from; + $this->setHeader('Return-Path', '<' . $returnPath . '>'); + $this->tmpArchive['returnPath'] = $returnPath; + + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Reply-to + * + * @param string $replyto + * @param string $name + * + * @return Email + */ + public function setReplyTo($replyto, $name = '') + { + if (preg_match('/\<(.*)\>/', $replyto, $match)) + { + $replyto = $match[1]; + } + if ($this->validate) + { + $this->validateEmail($this->stringToArray($replyto)); + } + if ($name !== '') + { + $this->tmpArchive['replyName'] = $name; + + // only use Q encoding if there are characters that would require it + if (! preg_match('/[\200-\377]/', $name)) + { + // add slashes for non-printing characters, slashes, and double quotes, and surround it in double quotes + $name = '"' . addcslashes($name, "\0..\37\177'\"\\") . '"'; + } + else + { + $name = $this->prepQEncoding($name); + } + } + $this->setHeader('Reply-To', $name . ' <' . $replyto . '>'); + $this->replyToFlag = true; + $this->tmpArchive['replyTo'] = $replyto; + + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Recipients + * + * @param string|array $to + * + * @return Email + */ + public function setTo($to) + { + $to = $this->stringToArray($to); + $to = $this->cleanEmail($to); + if ($this->validate) + { + $this->validateEmail($to); + } + if ($this->getProtocol() !== 'mail') + { + $this->setHeader('To', implode(', ', $to)); + } + $this->recipients = $to; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set CC + * + * @param string $cc + * + * @return Email + */ + public function setCC($cc) + { + $cc = $this->cleanEmail($this->stringToArray($cc)); + if ($this->validate) + { + $this->validateEmail($cc); + } + $this->setHeader('Cc', implode(', ', $cc)); + if ($this->getProtocol() === 'smtp') + { + $this->CCArray = $cc; + } + $this->tmpArchive['CCArray'] = $cc; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set BCC + * + * @param string $bcc + * @param string $limit + * + * @return Email + */ + public function setBCC($bcc, $limit = '') + { + if ($limit !== '' && is_numeric($limit)) + { + $this->BCCBatchMode = true; + $this->BCCBatchSize = $limit; + } + $bcc = $this->cleanEmail($this->stringToArray($bcc)); + if ($this->validate) + { + $this->validateEmail($bcc); + } + if ($this->getProtocol() === 'smtp' || ($this->BCCBatchMode && count($bcc) > $this->BCCBatchSize)) + { + $this->BCCArray = $bcc; + } + else + { + $this->setHeader('Bcc', implode(', ', $bcc)); + $this->tmpArchive['BCCArray'] = $bcc; + } + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Email Subject + * + * @param string $subject + * + * @return Email + */ + public function setSubject($subject) + { + $this->tmpArchive['subject'] = $subject; + + $subject = $this->prepQEncoding($subject); + $this->setHeader('Subject', $subject); + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Body + * + * @param string $body + * + * @return Email + */ + public function setMessage($body) + { + $this->body = rtrim(str_replace("\r", '', $body)); + return $this; + } + //-------------------------------------------------------------------- + /** + * Assign file attachments + * + * @param string $file Can be local path, URL or buffered content + * @param string $disposition 'attachment' + * @param string|null $newname + * @param string $mime + * + * @return Email + */ + public function attach($file, $disposition = '', $newname = null, $mime = '') + { + if ($mime === '') + { + if (strpos($file, '://') === false && ! is_file($file)) + { + $this->setErrorMessage(lang('Email.attachmentMissing', [$file])); + return false; + } + if (! $fp = @fopen($file, 'rb')) + { + $this->setErrorMessage(lang('Email.attachmentUnreadable', [$file])); + return false; + } + $fileContent = stream_get_contents($fp); + $mime = $this->mimeTypes(pathinfo($file, PATHINFO_EXTENSION)); + fclose($fp); + } + else + { + $fileContent = & $file; // buffered file + } + // declare names on their own, to make phpcbf happy + $namesAttached = [ + $file, + $newname, + ]; + $this->attachments[] = [ + 'name' => $namesAttached, + 'disposition' => empty($disposition) ? 'attachment' : $disposition, + // Can also be 'inline' Not sure if it matters + 'type' => $mime, + 'content' => chunk_split(base64_encode($fileContent)), + 'multipart' => 'mixed', + ]; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set and return attachment Content-ID + * + * Useful for attached inline pictures + * + * @param string $filename + * + * @return string + */ + public function setAttachmentCID($filename) + { + for ($i = 0, $c = count($this->attachments); $i < $c; $i ++) + { + if ($this->attachments[$i]['name'][0] === $filename) + { + $this->attachments[$i]['multipart'] = 'related'; + $this->attachments[$i]['cid'] = uniqid(basename($this->attachments[$i]['name'][0]) . '@', true); + return $this->attachments[$i]['cid']; + } + } + return false; + } + //-------------------------------------------------------------------- + /** + * Add a Header Item + * + * @param string $header + * @param string $value + * + * @return Email + */ + public function setHeader($header, $value) + { + $this->headers[$header] = str_replace(["\n", "\r"], '', $value); + return $this; + } + //-------------------------------------------------------------------- + /** + * Convert a String to an Array + * + * @param string $email + * + * @return array + */ + protected function stringToArray($email) + { + if (! is_array($email)) + { + return (strpos($email, ',') !== false) ? preg_split('/[\s,]/', $email, -1, PREG_SPLIT_NO_EMPTY) : (array) trim($email); + } + return $email; + } + //-------------------------------------------------------------------- + /** + * Set Multipart Value + * + * @param string $str + * + * @return Email + */ + public function setAltMessage($str) + { + $this->altMessage = (string) $str; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Mailtype + * + * @param string $type + * + * @return Email + */ + public function setMailType($type = 'text') + { + $this->mailType = ($type === 'html') ? 'html' : 'text'; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Wordwrap + * + * @param boolean $wordWrap + * + * @return Email + */ + public function setWordWrap($wordWrap = true) + { + $this->wordWrap = (bool) $wordWrap; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Protocol + * + * @param string $protocol + * + * @return Email + */ + public function setProtocol($protocol = 'mail') + { + $this->protocol = in_array($protocol, $this->protocols, true) ? strtolower($protocol) : 'mail'; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Priority + * + * @param integer $n + * + * @return Email + */ + public function setPriority($n = 3) + { + $this->priority = preg_match('/^[1-5]$/', $n) ? (int) $n : 3; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set Newline Character + * + * @param string $newline + * + * @return Email + */ + public function setNewline($newline = "\n") + { + $this->newline = in_array($newline, ["\n", "\r\n", "\r"]) ? $newline : "\n"; + return $this; + } + //-------------------------------------------------------------------- + /** + * Set CRLF + * + * @param string $CRLF + * + * @return Email + */ + public function setCRLF($CRLF = "\n") + { + $this->CRLF = ($CRLF !== "\n" && $CRLF !== "\r\n" && $CRLF !== "\r") ? "\n" : $CRLF; + return $this; + } + //-------------------------------------------------------------------- + /** + * Get the Message ID + * + * @return string + */ + protected function getMessageID() + { + $from = str_replace(['>', '<'], '', $this->headers['Return-Path']); + return '<' . uniqid('', true) . strstr($from, '@') . '>'; + } + //-------------------------------------------------------------------- + /** + * Get Mail Protocol + * + * @return string + */ + protected function getProtocol() + { + $this->protocol = strtolower($this->protocol); + in_array($this->protocol, $this->protocols, true) || $this->protocol = 'mail'; + return $this->protocol; + } + //-------------------------------------------------------------------- + /** + * Get Mail Encoding + * + * @return string + */ + protected function getEncoding() + { + in_array($this->encoding, $this->bitDepths) || $this->encoding = '8bit'; + foreach ($this->baseCharsets as $charset) + { + if (strpos($this->charset, $charset) === 0) + { + $this->encoding = '7bit'; + break; + } + } + return $this->encoding; + } + //-------------------------------------------------------------------- + /** + * Get content type (text/html/attachment) + * + * @return string + */ + protected function getContentType() + { + if ($this->mailType === 'html') + { + return empty($this->attachments) ? 'html' : 'html-attach'; + } + elseif ($this->mailType === 'text' && ! empty($this->attachments)) + { + return 'plain-attach'; + } + else + { + return 'plain'; + } + } + //-------------------------------------------------------------------- + /** + * Set RFC 822 Date + * + * @return string + */ + protected function setDate() + { + $timezone = date('Z'); + $operator = ($timezone[0] === '-') ? '-' : '+'; + $timezone = abs($timezone); + $timezone = floor($timezone / 3600) * 100 + ($timezone % 3600) / 60; + return sprintf('%s %s%04d', date('D, j M Y H:i:s'), $operator, $timezone); + } + //-------------------------------------------------------------------- + /** + * Mime message + * + * @return string + */ + protected function getMimeMessage() + { + return 'This is a multi-part message in MIME format.' . $this->newline . 'Your email application may not support this format.'; + } + //-------------------------------------------------------------------- + /** + * Validate Email Address + * + * @param string|array $email + * + * @return boolean + */ + public function validateEmail($email) + { + if (! is_array($email)) + { + $this->setErrorMessage(lang('Email.mustBeArray')); + return false; + } + foreach ($email as $val) + { + if (! $this->isValidEmail($val)) + { + $this->setErrorMessage(lang('Email.invalidAddress', [$val])); + return false; + } + } + return true; + } + //-------------------------------------------------------------------- + /** + * Email Validation + * + * @param string $email + * + * @return boolean + */ + public function isValidEmail($email) + { + if (function_exists('idn_to_ascii') && defined('INTL_IDNA_VARIANT_UTS46') && $atpos = strpos($email, '@')) + { + $email = static::substr($email, 0, ++ $atpos) . idn_to_ascii( + static::substr($email, $atpos), 0, INTL_IDNA_VARIANT_UTS46 + ); + } + return (bool) filter_var($email, FILTER_VALIDATE_EMAIL); + } + //-------------------------------------------------------------------- + /** + * Clean Extended Email Address: Joe Smith + * + * @param string $email + * + * @return string + */ + public function cleanEmail($email) + { + if (! is_array($email)) + { + return preg_match('/\<(.*)\>/', $email, $match) ? $match[1] : $email; + } + $cleanEmail = []; + foreach ($email as $addy) + { + $cleanEmail[] = preg_match('/\<(.*)\>/', $addy, $match) ? $match[1] : $addy; + } + return $cleanEmail; + } + //-------------------------------------------------------------------- + /** + * Build alternative plain text message + * + * Provides the raw message for use in plain-text headers of + * HTML-formatted emails. + * If the user hasn't specified his own alternative message + * it creates one by stripping the HTML + * + * @return string + */ + protected function getAltMessage() + { + if (! empty($this->altMessage)) + { + return ($this->wordWrap) ? $this->wordWrap($this->altMessage, 76) : $this->altMessage; + } + $body = preg_match('/\(.*)\<\/body\>/si', $this->body, $match) ? $match[1] : $this->body; + $body = str_replace("\t", '', preg_replace('# ' . $message . "\n"; + + flock($fp, LOCK_EX); + + for ($written = 0, $length = strlen($msg); $written < $length; $written += $result) + { + if (($result = fwrite($fp, substr($msg, $written))) === false) + { + // if we get this far, we'll never see this during travis-ci + // @codeCoverageIgnoreStart + break; + // @codeCoverageIgnoreEnd + } + } + + flock($fp, LOCK_UN); + fclose($fp); + + if (isset($newfile) && $newfile === true) + { + chmod($filepath, $this->filePermissions); + } + + return is_int($result); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Log/Handlers/HandlerInterface.php b/vendor/codeigniter4/framework/system/Log/Handlers/HandlerInterface.php new file mode 100644 index 0000000..6778a46 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Log/Handlers/HandlerInterface.php @@ -0,0 +1,85 @@ + 1, + 'alert' => 2, + 'critical' => 3, + 'error' => 4, + 'warning' => 5, + 'notice' => 6, + 'info' => 7, + 'debug' => 8, + ]; + + /** + * Array of levels to be logged. + * The rest will be ignored. + * Set in Config/logger.php + * + * @var array + */ + protected $loggableLevels = []; + + /** + * File permissions + * + * @var integer + */ + protected $filePermissions = 0644; + + /** + * Format of the timestamp for log files. + * + * @var string + */ + protected $dateFormat = 'Y-m-d H:i:s'; + + /** + * Filename Extension + * + * @var string + */ + protected $fileExt; + + /** + * Caches instances of the handlers. + * + * @var array + */ + protected $handlers = []; + + /** + * Holds the configuration for each handler. + * The key is the handler's class name. The + * value is an associative array of configuration + * items. + * + * @var array + */ + protected $handlerConfig = []; + + /** + * Caches logging calls for debugbar. + * + * @var array + */ + public $logCache; + + /** + * Should we cache our logged items? + * + * @var boolean + */ + protected $cacheLogs = false; + + //-------------------------------------------------------------------- + + /** + * Constructor. + * + * @param \Config\Logger $config + * @param boolean $debug + * @throws \RuntimeException + */ + public function __construct($config, bool $debug = CI_DEBUG) + { + $this->loggableLevels = is_array($config->threshold) ? $config->threshold : range(1, (int) $config->threshold); + + // Now convert loggable levels to strings. + // We only use numbers to make the threshold setting convenient for users. + if ($this->loggableLevels) + { + $temp = []; + foreach ($this->loggableLevels as $level) + { + $temp[] = array_search((int) $level, $this->logLevels); + } + + $this->loggableLevels = $temp; + unset($temp); + } + + $this->dateFormat = $config->dateFormat ?? $this->dateFormat; + + if (! is_array($config->handlers) || empty($config->handlers)) + { + throw LogException::forNoHandlers('LoggerConfig'); + } + + // Save the handler configuration for later. + // Instances will be created on demand. + $this->handlerConfig = $config->handlers; + + $this->cacheLogs = $debug; + if ($this->cacheLogs) + { + $this->logCache = []; + } + } + + //-------------------------------------------------------------------- + + /** + * System is unusable. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function emergency($message, array $context = []): bool + { + return $this->log('emergency', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function alert($message, array $context = []): bool + { + return $this->log('alert', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function critical($message, array $context = []): bool + { + return $this->log('critical', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function error($message, array $context = []): bool + { + return $this->log('error', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function warning($message, array $context = []): bool + { + return $this->log('warning', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function notice($message, array $context = []): bool + { + return $this->log('notice', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function info($message, array $context = []): bool + { + return $this->log('info', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * + * @return boolean + */ + public function debug($message, array $context = []): bool + { + return $this->log('debug', $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * + * @return boolean + */ + public function log($level, $message, array $context = []): bool + { + if (is_numeric($level)) + { + $level = array_search((int) $level, $this->logLevels); + } + + // Is the level a valid level? + if (! array_key_exists($level, $this->logLevels)) + { + throw LogException::forInvalidLogLevel($level); + } + + // Does the app want to log this right now? + if (! in_array($level, $this->loggableLevels)) + { + return false; + } + + // Parse our placeholders + $message = $this->interpolate($message, $context); + + if (! is_string($message)) + { + $message = print_r($message, true); + } + + if ($this->cacheLogs) + { + $this->logCache[] = [ + 'level' => $level, + 'msg' => $message, + ]; + } + + foreach ($this->handlerConfig as $className => $config) + { + if (! array_key_exists($className, $this->handlers)) + { + $this->handlers[$className] = new $className($config); + } + + /** + * @var \CodeIgniter\Log\Handlers\HandlerInterface + */ + $handler = $this->handlers[$className]; + + if (! $handler->canHandle($level)) + { + continue; + } + + // If the handler returns false, then we + // don't execute any other handlers. + if (! $handler->setDateFormat($this->dateFormat)->handle($level, $message)) + { + break; + } + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Replaces any placeholders in the message with variables + * from the context, as well as a few special items like: + * + * {session_vars} + * {post_vars} + * {get_vars} + * {env} + * {env:foo} + * {file} + * {line} + * + * @param mixed $message + * @param array $context + * + * @return mixed + */ + protected function interpolate($message, array $context = []) + { + if (! is_string($message)) + { + return $message; + } + + // build a replacement array with braces around the context keys + $replace = []; + + foreach ($context as $key => $val) + { + // Verify that the 'exception' key is actually an exception + // or error, both of which implement the 'Throwable' interface. + if ($key === 'exception' && $val instanceof \Throwable) + { + $val = $val->getMessage() . ' ' . $this->cleanFileNames($val->getFile()) . ':' . $val->getLine(); + } + + // todo - sanitize input before writing to file? + $replace['{' . $key . '}'] = $val; + } + + // Add special placeholders + $replace['{post_vars}'] = '$_POST: ' . print_r($_POST, true); + $replace['{get_vars}'] = '$_GET: ' . print_r($_GET, true); + $replace['{env}'] = ENVIRONMENT; + + // Allow us to log the file/line that we are logging from + if (strpos($message, '{file}') !== false) + { + list($file, $line) = $this->determineFile(); + + $replace['{file}'] = $file; + $replace['{line}'] = $line; + } + + // Match up environment variables in {env:foo} tags. + if (strpos($message, 'env:') !== false) + { + preg_match('/env:[^}]+/', $message, $matches); + + if ($matches) + { + foreach ($matches as $str) + { + $key = str_replace('env:', '', $str); + $replace["{{$str}}"] = $_ENV[$key] ?? 'n/a'; + } + } + } + + if (isset($_SESSION)) + { + $replace['{session_vars}'] = '$_SESSION: ' . print_r($_SESSION, true); + } + + // interpolate replacement values into the message and return + return strtr($message, $replace); + } + + /** + * Determines the file and line that the logging call + * was made from by analyzing the backtrace. + * Find the earliest stack frame that is part of our logging system. + * + * @return array + */ + public function determineFile(): array + { + $logFunctions = [ + 'log_message', + 'log', + 'error', + 'debug', + 'info', + 'warning', + 'critical', + 'emergency', + 'alert', + 'notice', + ]; + + // Generate Backtrace info + $trace = \debug_backtrace(false); + + // So we search from the bottom (earliest) of the stack frames + $stackFrames = \array_reverse($trace); + + // Find the first reference to a Logger class method + foreach ($stackFrames as $frame) + { + if (\in_array($frame['function'], $logFunctions)) + { + $file = isset($frame['file']) ? $this->cleanFileNames($frame['file']) : 'unknown'; + $line = $frame['line'] ?? 'unknown'; + return [ + $file, + $line, + ]; + } + } + + return [ + 'unknown', + 'unknown', + ]; + } + + //-------------------------------------------------------------------- + + /** + * Cleans the paths of filenames by replacing APPPATH, SYSTEMPATH, FCPATH + * with the actual var. i.e. + * + * /var/www/site/app/Controllers/Home.php + * becomes: + * APPPATH/Controllers/Home.php + * + * @param $file + * + * @return string + */ + protected function cleanFileNames(string $file): string + { + $file = str_replace(APPPATH, 'APPPATH/', $file); + $file = str_replace(SYSTEMPATH, 'SYSTEMPATH/', $file); + + return str_replace(FCPATH, 'FCPATH/', $file); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Model.php b/vendor/codeigniter4/framework/system/Model.php new file mode 100644 index 0000000..8245fba --- /dev/null +++ b/vendor/codeigniter4/framework/system/Model.php @@ -0,0 +1,1842 @@ +paginate() + * + * @var Pager + */ + public $pager; + + /** + * Name of database table + * + * @var string + */ + protected $table; + + /** + * The table's primary key. + * + * @var string + */ + protected $primaryKey = 'id'; + + /** + * Last insert ID + * + * @var integer + */ + protected $insertID = 0; + + /** + * The Database connection group that + * should be instantiated. + * + * @var string + */ + protected $DBGroup; + + /** + * The format that the results should be returned as. + * Will be overridden if the as* methods are used. + * + * @var string + */ + protected $returnType = 'array'; + + /** + * If this model should use "softDeletes" and + * simply set a date when rows are deleted, or + * do hard deletes. + * + * @var boolean + */ + protected $useSoftDeletes = false; + + /** + * An array of field names that are allowed + * to be set by the user in inserts/updates. + * + * @var array + */ + protected $allowedFields = []; + + /** + * If true, will set created_at, and updated_at + * values during insert and update routines. + * + * @var boolean + */ + protected $useTimestamps = false; + + /** + * The type of column that created_at and updated_at + * are expected to. + * + * Allowed: 'datetime', 'date', 'int' + * + * @var string + */ + protected $dateFormat = 'datetime'; + + //-------------------------------------------------------------------- + + /** + * The column used for insert timestamps + * + * @var string + */ + protected $createdField = 'created_at'; + + /** + * The column used for update timestamps + * + * @var string + */ + protected $updatedField = 'updated_at'; + + /** + * Used by withDeleted to override the + * model's softDelete setting. + * + * @var boolean + */ + protected $tempUseSoftDeletes; + + /** + * The column used to save soft delete state + * + * @var string + */ + protected $deletedField = 'deleted_at'; + + /** + * Used by asArray and asObject to provide + * temporary overrides of model default. + * + * @var string + */ + protected $tempReturnType; + + /** + * Whether we should limit fields in inserts + * and updates to those available in $allowedFields or not. + * + * @var boolean + */ + protected $protectFields = true; + + /** + * Database Connection + * + * @var ConnectionInterface + */ + protected $db; + + /** + * Query Builder object + * + * @var BaseBuilder + */ + protected $builder; + + /** + * Rules used to validate data in insert, update, and save methods. + * The array must match the format of data passed to the Validation + * library. + * + * @var array + */ + protected $validationRules = []; + + /** + * Contains any custom error messages to be + * used during data validation. + * + * @var array + */ + protected $validationMessages = []; + + /** + * Skip the model's validation. Used in conjunction with skipValidation() + * to skip data validation for any future calls. + * + * @var boolean + */ + protected $skipValidation = false; + + /** + * Whether rules should be removed that do not exist + * in the passed in data. Used between inserts/updates. + * + * @var boolean + */ + protected $cleanValidationRules = true; + + /** + * Our validator instance. + * + * @var \CodeIgniter\Validation\Validation + */ + protected $validation; + + /* + * Callbacks. Each array should contain the method + * names (within the model) that should be called + * when those events are triggered. With the exception + * of 'afterFind', all methods are passed the same + * items that are given to the update/insert method. + * 'afterFind' will also include the results that were found. + */ + + /** + * Whether to trigger the defined callbacks + * + * @var boolean + */ + protected $allowCallbacks = true; + + /** + * Used by allowCallbacks() to override the + * model's allowCallbacks setting. + * + * @var boolean + */ + protected $tempAllowCallbacks; + + /** + * Callbacks for beforeInsert + * + * @var array + */ + protected $beforeInsert = []; + /** + * Callbacks for afterInsert + * + * @var array + */ + protected $afterInsert = []; + /** + * Callbacks for beforeUpdate + * + * @var array + */ + protected $beforeUpdate = []; + /** + * Callbacks for afterUpdate + * + * @var array + */ + protected $afterUpdate = []; + /** + * Callbacks for afterFind + * + * @var array + */ + protected $afterFind = []; + /** + * Callbacks for beforeDelete + * + * @var array + */ + protected $beforeDelete = []; + /** + * Callbacks for afterDelete + * + * @var array + */ + protected $afterDelete = []; + + /** + * Holds information passed in via 'set' + * so that we can capture it (not the builder) + * and ensure it gets validated first. + * + * @var array + */ + protected $tempData = []; + + //-------------------------------------------------------------------- + + /** + * Model constructor. + * + * @param ConnectionInterface $db + * @param ValidationInterface $validation + */ + public function __construct(ConnectionInterface &$db = null, ValidationInterface $validation = null) + { + if ($db instanceof ConnectionInterface) + { + $this->db = & $db; + } + else + { + $this->db = Database::connect($this->DBGroup); + } + + $this->tempReturnType = $this->returnType; + $this->tempUseSoftDeletes = $this->useSoftDeletes; + $this->tempAllowCallbacks = $this->allowCallbacks; + + if (is_null($validation)) + { + $validation = \Config\Services::validation(null, false); + } + + $this->validation = $validation; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // CRUD & FINDERS + //-------------------------------------------------------------------- + + /** + * Fetches the row of database from $this->table with a primary key + * matching $id. + * + * @param mixed|array|null $id One primary key or an array of primary keys + * + * @return array|object|null The resulting row of data, or null. + */ + public function find($id = null) + { + $builder = $this->builder(); + + if ($this->tempUseSoftDeletes === true) + { + $builder->where($this->table . '.' . $this->deletedField, null); + } + + if (is_array($id)) + { + $row = $builder->whereIn($this->table . '.' . $this->primaryKey, $id) + ->get(); + $row = $row->getResult($this->tempReturnType); + } + elseif (is_numeric($id) || is_string($id)) + { + $row = $builder->where($this->table . '.' . $this->primaryKey, $id) + ->get(); + + $row = $row->getFirstRow($this->tempReturnType); + } + else + { + $row = $builder->get(); + + $row = $row->getResult($this->tempReturnType); + } + + $eventData = $this->trigger('afterFind', ['id' => $id, 'data' => $row]); + + $this->tempReturnType = $this->returnType; + $this->tempUseSoftDeletes = $this->useSoftDeletes; + + return $eventData['data']; + } + + //-------------------------------------------------------------------- + + /** + * Fetches the column of database from $this->table + * + * @param string $columnName + * + * @return array|null The resulting row of data, or null if no data found. + * @throws \CodeIgniter\Database\Exceptions\DataException + */ + public function findColumn(string $columnName) + { + if (strpos($columnName, ',') !== false) + { + throw DataException::forFindColumnHaveMultipleColumns(); + } + + $resultSet = $this->select($columnName) + ->asArray() + ->find(); + + return (! empty($resultSet)) ? array_column($resultSet, $columnName) : null; + } + + //-------------------------------------------------------------------- + + /** + * Works with the current Query Builder instance to return + * all results, while optionally limiting them. + * + * @param integer $limit + * @param integer $offset + * + * @return array + */ + public function findAll(int $limit = 0, int $offset = 0) + { + $builder = $this->builder(); + + if ($this->tempUseSoftDeletes === true) + { + $builder->where($this->table . '.' . $this->deletedField, null); + } + + $row = $builder->limit($limit, $offset) + ->get(); + + $row = $row->getResult($this->tempReturnType); + + $eventData = $this->trigger('afterFind', ['data' => $row, 'limit' => $limit, 'offset' => $offset]); + + $this->tempReturnType = $this->returnType; + $this->tempUseSoftDeletes = $this->useSoftDeletes; + + return $eventData['data']; + } + + //-------------------------------------------------------------------- + + /** + * Returns the first row of the result set. Will take any previous + * Query Builder calls into account when determining the result set. + * + * @return array|object|null + */ + public function first() + { + $builder = $this->builder(); + + if ($this->tempUseSoftDeletes === true) + { + $builder->where($this->table . '.' . $this->deletedField, null); + } + else + { + if ($this->useSoftDeletes === true && empty($builder->QBGroupBy) && ! empty($this->primaryKey)) + { + $builder->groupBy($this->table . '.' . $this->primaryKey); + } + } + + // Some databases, like PostgreSQL, need order + // information to consistently return correct results. + if (! empty($builder->QBGroupBy) && empty($builder->QBOrderBy) && ! empty($this->primaryKey)) + { + $builder->orderBy($this->table . '.' . $this->primaryKey, 'asc'); + } + + $row = $builder->limit(1, 0) + ->get(); + + $row = $row->getFirstRow($this->tempReturnType); + + $eventData = $this->trigger('afterFind', ['data' => $row]); + + $this->tempReturnType = $this->returnType; + $this->tempUseSoftDeletes = $this->useSoftDeletes; + + return $eventData['data']; + } + + //-------------------------------------------------------------------- + + /** + * Captures the builder's set() method so that we can validate the + * data here. This allows it to be used with any of the other + * builder methods and still get validated data, like replace. + * + * @param mixed $key Field name, or an array of field/value pairs + * @param string $value Field value, if $key is a single field + * @param boolean $escape Whether to escape values and identifiers + * + * @return $this + */ + public function set($key, ?string $value = '', bool $escape = null) + { + $data = is_array($key) + ? $key + : [$key => $value]; + + $this->tempData['escape'] = $escape; + $this->tempData['data'] = array_merge($this->tempData['data'] ?? [], $data); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * A convenience method that will attempt to determine whether the + * data should be inserted or updated. Will work with either + * an array or object. When using with custom class objects, + * you must ensure that the class will provide access to the class + * variables, even if through a magic method. + * + * @param array|object $data + * + * @return boolean + * @throws \ReflectionException + */ + public function save($data): bool + { + if (empty($data)) + { + return true; + } + + if (is_object($data) && isset($data->{$this->primaryKey})) + { + $response = $this->update($data->{$this->primaryKey}, $data); + } + elseif (is_array($data) && ! empty($data[$this->primaryKey])) + { + $response = $this->update($data[$this->primaryKey], $data); + } + else + { + $response = $this->insert($data, false); + + if ($response instanceof BaseResult) + { + $response = $response->resultID !== false; + } + elseif ($response !== false) + { + $response = true; + } + } + + return $response; + } + + /** + * Takes a class an returns an array of it's public and protected + * properties as an array suitable for use in creates and updates. + * + * @param string|object $data + * @param string|null $primaryKey + * @param string $dateFormat + * @param boolean $onlyChanged + * + * @return array + * @throws \ReflectionException + */ + public static function classToArray($data, $primaryKey = null, string $dateFormat = 'datetime', bool $onlyChanged = true): array + { + if (method_exists($data, 'toRawArray')) + { + $properties = $data->toRawArray($onlyChanged); + + // Always grab the primary key otherwise updates will fail. + if (! empty($properties) && ! empty($primaryKey) && ! in_array($primaryKey, $properties) && ! empty($data->{$primaryKey})) + { + $properties[$primaryKey] = $data->{$primaryKey}; + } + } + else + { + $mirror = new ReflectionClass($data); + $props = $mirror->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED); + + $properties = []; + + // Loop over each property, + // saving the name/value in a new array we can return. + foreach ($props as $prop) + { + // Must make protected values accessible. + $prop->setAccessible(true); + $propName = $prop->getName(); + $properties[$propName] = $prop->getValue($data); + } + } + + // Convert any Time instances to appropriate $dateFormat + if ($properties) + { + foreach ($properties as $key => $value) + { + if ($value instanceof Time) + { + switch ($dateFormat) + { + case 'datetime': + $converted = $value->format('Y-m-d H:i:s'); + break; + case 'date': + $converted = $value->format('Y-m-d'); + break; + case 'int': + $converted = $value->getTimestamp(); + break; + default: + $converted = (string)$value; + } + + $properties[$key] = $converted; + } + } + } + + return $properties; + } + + //-------------------------------------------------------------------- + + /** + * Returns last insert ID or 0. + * + * @return integer + */ + public function getInsertID(): int + { + return $this->insertID; + } + + //-------------------------------------------------------------------- + + /** + * Inserts data into the current table. If an object is provided, + * it will attempt to convert it to an array. + * + * @param array|object $data + * @param boolean $returnID Whether insert ID should be returned or not. + * + * @return BaseResult|integer|string|false + * @throws \ReflectionException + */ + public function insert($data = null, bool $returnID = true) + { + $escape = null; + + $this->insertID = 0; + + if (empty($data)) + { + $data = $this->tempData['data'] ?? null; + $escape = $this->tempData['escape'] ?? null; + $this->tempData = []; + } + + if (empty($data)) + { + throw DataException::forEmptyDataset('insert'); + } + + // If $data is using a custom class with public or protected + // properties representing the table elements, we need to grab + // them as an array. + if (is_object($data) && ! $data instanceof stdClass) + { + $data = static::classToArray($data, $this->primaryKey, $this->dateFormat, false); + } + + // If it's still a stdClass, go ahead and convert to + // an array so doProtectFields and other model methods + // don't have to do special checks. + if (is_object($data)) + { + $data = (array) $data; + } + + if (empty($data)) + { + throw DataException::forEmptyDataset('insert'); + } + + // Validate data before saving. + if ($this->skipValidation === false) + { + if ($this->cleanRules()->validate($data) === false) + { + return false; + } + } + + // Must be called first so we don't + // strip out created_at values. + $data = $this->doProtectFields($data); + + // Set created_at and updated_at with same time + $date = $this->setDate(); + + if ($this->useTimestamps && ! empty($this->createdField) && ! array_key_exists($this->createdField, $data)) + { + $data[$this->createdField] = $date; + } + + if ($this->useTimestamps && ! empty($this->updatedField) && ! array_key_exists($this->updatedField, $data)) + { + $data[$this->updatedField] = $date; + } + + $eventData = $this->trigger('beforeInsert', ['data' => $data]); + + // Must use the set() method to ensure objects get converted to arrays + $result = $this->builder() + ->set($eventData['data'], '', $escape) + ->insert(); + + // If insertion succeeded then save the insert ID + if ($result->resultID) + { + $this->insertID = $this->db->insertID(); + } + + // Trigger afterInsert events with the inserted data and new ID + $this->trigger('afterInsert', ['id' => $this->insertID, 'data' => $eventData['data'], 'result' => $result]); + + // If insertion failed, get out of here + if (! $result) + { + return $result; + } + + // otherwise return the insertID, if requested. + return $returnID ? $this->insertID : $result; + } + + //-------------------------------------------------------------------- + + /** + * Compiles batch insert strings and runs the queries, validating each row prior. + * + * @param array $set An associative array of insert values + * @param boolean $escape Whether to escape values and identifiers + * @param integer $batchSize The size of the batch to run + * @param boolean $testing True means only number of records is returned, false will execute the query + * + * @return integer|boolean Number of rows inserted or FALSE on failure + */ + public function insertBatch(array $set = null, bool $escape = null, int $batchSize = 100, bool $testing = false) + { + if (is_array($set) && $this->skipValidation === false) + { + foreach ($set as $row) + { + if ($this->cleanRules()->validate($row) === false) + { + return false; + } + } + } + + return $this->builder()->testMode($testing)->insertBatch($set, $escape, $batchSize); + } + + //-------------------------------------------------------------------- + + /** + * Updates a single record in $this->table. If an object is provided, + * it will attempt to convert it into an array. + * + * @param integer|array|string $id + * @param array|object $data + * + * @return boolean + * @throws \ReflectionException + */ + public function update($id = null, $data = null): bool + { + $escape = null; + + if (is_numeric($id) || is_string($id)) + { + $id = [$id]; + } + + if (empty($data)) + { + $data = $this->tempData['data'] ?? null; + $escape = $this->tempData['escape'] ?? null; + $this->tempData = []; + } + + if (empty($data)) + { + throw DataException::forEmptyDataset('update'); + } + + // If $data is using a custom class with public or protected + // properties representing the table elements, we need to grab + // them as an array. + if (is_object($data) && ! $data instanceof stdClass) + { + $data = static::classToArray($data, $this->primaryKey, $this->dateFormat); + } + + // If it's still a stdClass, go ahead and convert to + // an array so doProtectFields and other model methods + // don't have to do special checks. + if (is_object($data)) + { + $data = (array) $data; + } + + // If it's still empty here, means $data is no change or is empty object + if (empty($data)) + { + throw DataException::forEmptyDataset('update'); + } + + // Validate data before saving. + if ($this->skipValidation === false) + { + if ($this->cleanRules(true)->validate($data) === false) + { + return false; + } + } + + // Must be called first so we don't + // strip out updated_at values. + $data = $this->doProtectFields($data); + + if ($this->useTimestamps && ! empty($this->updatedField) && ! array_key_exists($this->updatedField, $data)) + { + $data[$this->updatedField] = $this->setDate(); + } + + $eventData = $this->trigger('beforeUpdate', ['id' => $id, 'data' => $data]); + + $builder = $this->builder(); + + if ($id) + { + $builder = $builder->whereIn($this->table . '.' . $this->primaryKey, $id); + } + + // Must use the set() method to ensure objects get converted to arrays + $result = $builder + ->set($eventData['data'], '', $escape) + ->update(); + + $this->trigger('afterUpdate', ['id' => $id, 'data' => $eventData['data'], 'result' => $result]); + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Update_Batch + * + * Compiles an update string and runs the query + * + * @param array $set An associative array of update values + * @param string $index The where key + * @param integer $batchSize The size of the batch to run + * @param boolean $returnSQL True means SQL is returned, false will execute the query + * + * @return mixed Number of rows affected or FALSE on failure + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function updateBatch(array $set = null, string $index = null, int $batchSize = 100, bool $returnSQL = false) + { + if (is_array($set) && $this->skipValidation === false) + { + foreach ($set as $row) + { + if ($this->cleanRules(true)->validate($row) === false) + { + return false; + } + } + } + + return $this->builder()->testMode($returnSQL)->updateBatch($set, $index, $batchSize); + } + + //-------------------------------------------------------------------- + + /** + * Deletes a single record from $this->table where $id matches + * the table's primaryKey + * + * @param integer|string|array|null $id The rows primary key(s) + * @param boolean $purge Allows overriding the soft deletes setting. + * + * @return BaseResult|boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function delete($id = null, bool $purge = false) + { + if (! empty($id) && (is_numeric($id) || is_string($id))) + { + $id = [$id]; + } + + $builder = $this->builder(); + if (! empty($id)) + { + $builder = $builder->whereIn($this->primaryKey, $id); + } + + $this->trigger('beforeDelete', ['id' => $id, 'purge' => $purge]); + + if ($this->useSoftDeletes && ! $purge) + { + if (empty($builder->getCompiledQBWhere())) + { + if (CI_DEBUG) + { + throw new DatabaseException('Deletes are not allowed unless they contain a "where" or "like" clause.'); + } + // @codeCoverageIgnoreStart + return false; + // @codeCoverageIgnoreEnd + } + $set[$this->deletedField] = $this->setDate(); + + if ($this->useTimestamps && ! empty($this->updatedField)) + { + $set[$this->updatedField] = $this->setDate(); + } + + $result = $builder->update($set); + } + else + { + $result = $builder->delete(); + } + + $this->trigger('afterDelete', ['id' => $id, 'purge' => $purge, 'result' => $result, 'data' => null]); + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Permanently deletes all rows that have been marked as deleted + * through soft deletes (deleted = 1) + * + * @return boolean|mixed + */ + public function purgeDeleted() + { + if (! $this->useSoftDeletes) + { + return true; + } + + return $this->builder() + ->where($this->table . '.' . $this->deletedField . ' IS NOT NULL') + ->delete(); + } + + //-------------------------------------------------------------------- + + /** + * Sets $useSoftDeletes value so that we can temporarily override + * the softdeletes settings. Can be used for all find* methods. + * + * @param boolean $val + * + * @return Model + */ + public function withDeleted($val = true) + { + $this->tempUseSoftDeletes = ! $val; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Works with the find* methods to return only the rows that + * have been deleted. + * + * @return Model + */ + public function onlyDeleted() + { + $this->tempUseSoftDeletes = false; + + $this->builder() + ->where($this->table . '.' . $this->deletedField . ' IS NOT NULL'); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Replace + * + * Compiles an replace into string and runs the query + * + * @param null $data + * @param boolean $returnSQL + * + * @return mixed + */ + public function replace($data = null, bool $returnSQL = false) + { + // Validate data before saving. + if (! empty($data) && $this->skipValidation === false) + { + if ($this->cleanRules(true)->validate($data) === false) + { + return false; + } + } + + return $this->builder()->replace($data, $returnSQL); + } + + //-------------------------------------------------------------------- + // Utility + //-------------------------------------------------------------------- + + /** + * Sets the return type of the results to be as an associative array. + * + * @return Model + */ + public function asArray() + { + $this->tempReturnType = 'array'; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the return type to be of the specified type of object. + * Defaults to a simple object, but can be any class that has + * class vars with the same name as the table columns, or at least + * allows them to be created. + * + * @param string $class + * + * @return Model + */ + public function asObject(string $class = 'object') + { + $this->tempReturnType = $class; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Loops over records in batches, allowing you to operate on them. + * Works with $this->builder to get the Compiled select to + * determine the rows to operate on. + * + * @param integer $size + * @param \Closure $userFunc + * + * @throws \CodeIgniter\Database\Exceptions\DataException + */ + public function chunk(int $size, Closure $userFunc) + { + $total = $this->builder() + ->countAllResults(false); + + $offset = 0; + + while ($offset <= $total) + { + $builder = clone($this->builder()); + + $rows = $builder->get($size, $offset); + + if ($rows === false) + { + throw DataException::forEmptyDataset('chunk'); + } + + $rows = $rows->getResult($this->tempReturnType); + + $offset += $size; + + if (empty($rows)) + { + continue; + } + + foreach ($rows as $row) + { + if ($userFunc($row) === false) + { + return; + } + } + } + } + + //-------------------------------------------------------------------- + + /** + * Works with $this->builder to get the Compiled Select to operate on. + * Expects a GET variable (?page=2) that specifies the page of results + * to display. + * + * @param integer $perPage + * @param string $group Will be used by the pagination library + * to identify a unique pagination set. + * @param integer $page Optional page number (useful when the page number is provided in different way) + * @param integer $segment Optional URI segment number (if page number is provided by URI segment) + * + * @return array|null + */ + public function paginate(int $perPage = null, string $group = 'default', int $page = null, int $segment = 0) + { + $pager = \Config\Services::pager(null, null, false); + + if ($segment) + { + $pager->setSegment($segment); + } + + $page = $page >= 1 ? $page : $pager->getCurrentPage($group); + + $total = $this->countAllResults(false); + + // Store it in the Pager library so it can be + // paginated in the views. + $this->pager = $pager->store($group, $page, $perPage, $total, $segment); + $perPage = $this->pager->getPerPage($group); + $offset = ($page - 1) * $perPage; + + return $this->findAll($perPage, $offset); + } + + //-------------------------------------------------------------------- + + /** + * Sets whether or not we should whitelist data set during + * updates or inserts against $this->availableFields. + * + * @param boolean $protect + * + * @return Model + */ + public function protect(bool $protect = true) + { + $this->protectFields = $protect; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Provides a shared instance of the Query Builder. + * + * @param string $table + * + * @return BaseBuilder + * @throws \CodeIgniter\Exceptions\ModelException; + */ + protected function builder(string $table = null) + { + if ($this->builder instanceof BaseBuilder) + { + return $this->builder; + } + + // We're going to force a primary key to exist + // so we don't have overly convoluted code, + // and future features are likely to require them. + if (empty($this->primaryKey)) + { + throw ModelException::forNoPrimaryKey(get_class($this)); + } + + $table = empty($table) ? $this->table : $table; + + // Ensure we have a good db connection + if (! $this->db instanceof BaseConnection) + { + $this->db = Database::connect($this->DBGroup); + } + + $this->builder = $this->db->table($table); + + return $this->builder; + } + + //-------------------------------------------------------------------- + + /** + * Ensures that only the fields that are allowed to be updated + * are in the data array. + * + * Used by insert() and update() to protect against mass assignment + * vulnerabilities. + * + * @param array $data + * + * @return array + * @throws \CodeIgniter\Database\Exceptions\DataException + */ + protected function doProtectFields(array $data): array + { + if ($this->protectFields === false) + { + return $data; + } + + if (empty($this->allowedFields)) + { + throw DataException::forInvalidAllowedFields(get_class($this)); + } + + if (is_array($data) && count($data)) + { + foreach ($data as $key => $val) + { + if (! in_array($key, $this->allowedFields)) + { + unset($data[$key]); + } + } + } + + return $data; + } + + //-------------------------------------------------------------------- + + /** + * A utility function to allow child models to use the type of + * date/time format that they prefer. This is primarily used for + * setting created_at, updated_at and deleted_at values, but can be + * used by inheriting classes. + * + * The available time formats are: + * - 'int' - Stores the date as an integer timestamp + * - 'datetime' - Stores the data in the SQL datetime format + * - 'date' - Stores the date (only) in the SQL date format. + * + * @param integer $userData An optional PHP timestamp to be converted. + * + * @return mixed + * @throws \CodeIgniter\Exceptions\ModelException; + */ + protected function setDate(int $userData = null) + { + $currentDate = is_numeric($userData) ? (int) $userData : time(); + + switch ($this->dateFormat) + { + case 'int': + return $currentDate; + case 'datetime': + return date('Y-m-d H:i:s', $currentDate); + case 'date': + return date('Y-m-d', $currentDate); + default: + throw ModelException::forNoDateFormat(get_class($this)); + } + } + + //-------------------------------------------------------------------- + + /** + * Specify the table associated with a model + * + * @param string $table + * + * @return Model + */ + public function setTable(string $table) + { + $this->table = $table; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Grabs the last error(s) that occurred. If data was validated, + * it will first check for errors there, otherwise will try to + * grab the last error from the Database connection. + * + * @param boolean $forceDB Always grab the db error, not validation + * + * @return array|null + */ + public function errors(bool $forceDB = false) + { + // Do we have validation errors? + if ($forceDB === false && $this->skipValidation === false) + { + $errors = $this->validation->getErrors(); + + if (! empty($errors)) + { + return $errors; + } + } + + // Still here? Grab the database-specific error, if any. + $error = $this->db->error(); + + return $error['message'] ?? null; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Validation + //-------------------------------------------------------------------- + + /** + * Set the value of the skipValidation flag. + * + * @param boolean $skip + * + * @return Model + */ + public function skipValidation(bool $skip = true) + { + $this->skipValidation = $skip; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Allows to set validation messages. + * It could be used when you have to change default or override current validate messages. + * + * @param array $validationMessages + * + * @return void + */ + public function setValidationMessages(array $validationMessages) + { + $this->validationMessages = $validationMessages; + } + //-------------------------------------------------------------------- + + /** + * Allows to set field wise validation message. + * It could be used when you have to change default or override current validate messages. + * + * @param string $field + * @param array $fieldMessages + * + * @return void + */ + public function setValidationMessage(string $field, array $fieldMessages) + { + $this->validationMessages[$field] = $fieldMessages; + } + + //-------------------------------------------------------------------- + + /** + * Allows to set validation rules. + * It could be used when you have to change default or override current validate rules. + * + * @param array $validationRules + * + * @return void + */ + public function setValidationRules(array $validationRules) + { + $this->validationRules = $validationRules; + } + + //-------------------------------------------------------------------- + + /** + * Allows to set field wise validation rules. + * It could be used when you have to change default or override current validate rules. + * + * @param string $field + * @param string|array $fieldRules + * + * @return void + */ + public function setValidationRule(string $field, $fieldRules) + { + $this->validationRules[$field] = $fieldRules; + } + + //-------------------------------------------------------------------- + + /** + * Should validation rules be removed before saving? + * Most handy when doing updates. + * + * @param boolean $choice + * + * @return $this + */ + public function cleanRules(bool $choice = false) + { + $this->cleanValidationRules = $choice; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Validate the data against the validation rules (or the validation group) + * specified in the class property, $validationRules. + * + * @param array|object $data + * + * @return boolean + */ + public function validate($data): bool + { + $rules = $this->getValidationRules(); + + if ($this->skipValidation === true || empty($rules) || empty($data)) + { + return true; + } + + // Query Builder works with objects as well as arrays, + // but validation requires array, so cast away. + if (is_object($data)) + { + $data = (array) $data; + } + + // ValidationRules can be either a string, which is the group name, + // or an array of rules. + if (is_string($rules)) + { + $rules = $this->validation->loadRuleGroup($rules); + } + + $rules = $this->cleanValidationRules + ? $this->cleanValidationRules($rules, $data) + : $rules; + + // If no data existed that needs validation + // our job is done here. + if (empty($rules)) + { + return true; + } + + $this->validation->setRules($rules, $this->validationMessages); + $valid = $this->validation->run($data, null, $this->DBGroup); + + return (bool) $valid; + } + + //-------------------------------------------------------------------- + + /** + * Removes any rules that apply to fields that have not been set + * currently so that rules don't block updating when only updating + * a partial row. + * + * @param array $rules + * + * @param array|null $data + * + * @return array + */ + protected function cleanValidationRules(array $rules, array $data = null): array + { + if (empty($data)) + { + return []; + } + + foreach ($rules as $field => $rule) + { + if (! array_key_exists($field, $data)) + { + unset($rules[$field]); + } + } + + return $rules; + } + + /** + * Replace any placeholders within the rules with the values that + * match the 'key' of any properties being set. For example, if + * we had the following $data array: + * + * [ 'id' => 13 ] + * + * and the following rule: + * + * 'required|is_unique[users,email,id,{id}]' + * + * The value of {id} would be replaced with the actual id in the form data: + * + * 'required|is_unique[users,email,id,13]' + * + * @codeCoverageIgnore + * + * @deprecated use fillPlaceholders($rules, $data) from Validation instead + * + * @param array $rules + * @param array $data + * + * @return array + */ + protected function fillPlaceholders(array $rules, array $data): array + { + $replacements = []; + + foreach ($data as $key => $value) + { + $replacements["{{$key}}"] = $value; + } + + if (! empty($replacements)) + { + foreach ($rules as &$rule) + { + if (is_array($rule)) + { + foreach ($rule as &$row) + { + // Should only be an `errors` array + // which doesn't take placeholders. + if (is_array($row)) + { + continue; + } + + $row = strtr($row, $replacements); + } + continue; + } + + $rule = strtr($rule, $replacements); + } + } + + return $rules; + } + + //-------------------------------------------------------------------- + + /** + * Returns the model's defined validation rules so that they + * can be used elsewhere, if needed. + * + * @param array $options + * + * @return array + */ + public function getValidationRules(array $options = []): array + { + $rules = $this->validationRules; + + // ValidationRules can be either a string, which is the group name, + // or an array of rules. + if (is_string($rules)) + { + $rules = $this->validation->loadRuleGroup($rules); + } + + if (isset($options['except'])) + { + $rules = array_diff_key($rules, array_flip($options['except'])); + } + elseif (isset($options['only'])) + { + $rules = array_intersect_key($rules, array_flip($options['only'])); + } + + return $rules; + } + + //-------------------------------------------------------------------- + + /** + * Returns the model's define validation messages so they + * can be used elsewhere, if needed. + * + * @return array + */ + public function getValidationMessages(): array + { + return $this->validationMessages; + } + + //-------------------------------------------------------------------- + + /** + * Override countAllResults to account for soft deleted accounts. + * + * @param boolean $reset + * @param boolean $test + * + * @return mixed + */ + public function countAllResults(bool $reset = true, bool $test = false) + { + if ($this->tempUseSoftDeletes === true) + { + $this->builder()->where($this->table . '.' . $this->deletedField, null); + } + + // When $reset === false, the $tempUseSoftDeletes will be + // dependant on $useSoftDeletes value because we don't + // want to add the same "where" condition for the second time + $this->tempUseSoftDeletes = ($reset === true) + ? $this->useSoftDeletes + : ($this->useSoftDeletes === true + ? false + : $this->useSoftDeletes); + + return $this->builder()->testMode($test)->countAllResults($reset); + } + + /** + * Sets $tempAllowCallbacks value so that we can temporarily override + * the setting. Resets after the next trigger. + * + * @param boolean $val + * + * @return Model + */ + public function allowCallbacks(bool $val = true) + { + $this->tempAllowCallbacks = $val; + + return $this; + } + + /** + * A simple event trigger for Model Events that allows additional + * data manipulation within the model. Specifically intended for + * usage by child models this can be used to format data, + * save/load related classes, etc. + * + * It is the responsibility of the callback methods to return + * the data itself. + * + * Each $eventData array MUST have a 'data' key with the relevant + * data for callback methods (like an array of key/value pairs to insert + * or update, an array of results, etc) + * + * If callbacks are not allowed then returns $eventData immediately. + * + * @param string $event + * @param array $eventData + * + * @return mixed + * @throws \CodeIgniter\Database\Exceptions\DataException + */ + protected function trigger(string $event, array $eventData) + { + $allowed = $this->tempAllowCallbacks; + $this->tempAllowCallbacks = $this->allowCallbacks; + + if (! $allowed) + { + return $eventData; + } + + // Ensure it's a valid event + if (! isset($this->{$event}) || empty($this->{$event})) + { + return $eventData; + } + + foreach ($this->{$event} as $callback) + { + if (! method_exists($this, $callback)) + { + throw DataException::forInvalidMethodTriggered($callback); + } + + $eventData = $this->{$callback}($eventData); + } + + return $eventData; + } + + //-------------------------------------------------------------------- + + //-------------------------------------------------------------------- + // Magic + //-------------------------------------------------------------------- + + /** + * Provides/instantiates the builder/db connection and model's table/primary key names and return type. + * + * @param string $name + * + * @return mixed + */ + public function __get(string $name) + { + if (property_exists($this, $name)) + { + return $this->{$name}; + } + elseif (isset($this->db->$name)) + { + return $this->db->$name; + } + elseif (isset($this->builder()->$name)) + { + return $this->builder()->$name; + } + + return null; + } + + /** + * Checks for the existence of properties across this model, builder, and db connection. + * + * @param string $name + * + * @return boolean + */ + public function __isset(string $name): bool + { + if (property_exists($this, $name)) + { + return true; + } + elseif (isset($this->db->$name)) + { + return true; + } + elseif (isset($this->builder()->$name)) + { + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Provides direct access to method in the builder (if available) + * and the database connection. + * + * @param string $name + * @param array $params + * + * @return Model|null + */ + public function __call(string $name, array $params) + { + $result = null; + + if (method_exists($this->db, $name)) + { + $result = $this->db->$name(...$params); + } + elseif (method_exists($builder = $this->builder(), $name)) + { + $result = $builder->$name(...$params); + } + + // Don't return the builder object unless specifically requested + //, since that will interrupt the usability flow + // and break intermingling of model and builder methods. + if ($name !== 'builder' && empty($result)) + { + if (! method_exists($this->builder(), $name)) + { + $className = get_class($this); + throw new \BadMethodCallException("Call to undefined method $className::$name"); + } + return $result; + } + if ($name !== 'builder' && ! $result instanceof BaseBuilder) + { + return $result; + } + + return $this; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Modules/Modules.php b/vendor/codeigniter4/framework/system/Modules/Modules.php new file mode 100644 index 0000000..73d6835 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Modules/Modules.php @@ -0,0 +1,88 @@ +enabled) + { + return false; + } + + return in_array(strtolower($alias), $this->aliases); + } +} diff --git a/vendor/codeigniter4/framework/system/Pager/Exceptions/PagerException.php b/vendor/codeigniter4/framework/system/Pager/Exceptions/PagerException.php new file mode 100644 index 0000000..fe2b62c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Pager/Exceptions/PagerException.php @@ -0,0 +1,17 @@ +config = $config; + $this->view = $view; + } + + //-------------------------------------------------------------------- + + /** + * Handles creating and displaying the + * + * @param string $group + * @param string $template The output template alias to render. + * + * @return string + */ + public function links(string $group = 'default', string $template = 'default_full'): string + { + $this->ensureGroup($group); + + return $this->displayLinks($group, $template); + } + + //-------------------------------------------------------------------- + + /** + * Creates simple Next/Previous links, instead of full pagination. + * + * @param string $group + * @param string $template + * + * @return string + */ + public function simpleLinks(string $group = 'default', string $template = 'default_simple'): string + { + $this->ensureGroup($group); + + return $this->displayLinks($group, $template); + } + + //-------------------------------------------------------------------- + + /** + * Allows for a simple, manual, form of pagination where all of the data + * is provided by the user. The URL is the current URI. + * + * @param integer $page + * @param integer $perPage + * @param integer $total + * @param string $template The output template alias to render. + * @param integer $segment (if page number is provided by URI segment) + * + * @param string $group optional group (i.e. if we'd like to define custom path) + * @return string + */ + public function makeLinks(int $page, int $perPage = null, int $total, string $template = 'default_full', int $segment = 0, ?string $group = 'default'): string + { + $group = $group === '' ? 'default' : $group; + + $this->store($group, $page, $perPage ?? $this->config->perPage, $total, $segment); + + return $this->displayLinks($group, $template); + } + + //-------------------------------------------------------------------- + + /** + * Does the actual work of displaying the view file. Used internally + * by links(), simpleLinks(), and makeLinks(). + * + * @param string $group + * @param string $template + * + * @return string + */ + protected function displayLinks(string $group, string $template): string + { + $pager = new PagerRenderer($this->getDetails($group)); + + if (! array_key_exists($template, $this->config->templates)) + { + throw PagerException::forInvalidTemplate($template); + } + + return $this->view->setVar('pager', $pager) + ->render($this->config->templates[$template]); + } + + //-------------------------------------------------------------------- + + /** + * Stores a set of pagination data for later display. Most commonly used + * by the model to automate the process. + * + * @param string $group + * @param integer $page + * @param integer $perPage + * @param integer $total + * @param integer $segment + * + * @return $this + */ + public function store(string $group, int $page, int $perPage = null, int $total, int $segment = 0) + { + if ($segment) + { + $this->setSegment($segment, $group); + } + + $this->ensureGroup($group, $perPage); + + if ($segment > 0 && $this->groups[$group]['currentPage'] > 0) + { + $page = $this->groups[$group]['currentPage']; + } + + $perPage = $perPage ?? $this->config->perPage; + $pageCount = (int)ceil($total / $perPage); + $this->groups[$group]['currentPage'] = $page > $pageCount ? $pageCount : $page; + $this->groups[$group]['perPage'] = $perPage; + $this->groups[$group]['total'] = $total; + $this->groups[$group]['pageCount'] = $pageCount; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets segment for a group. + * + * @param integer $number + * @param string $group + * + * @return mixed + */ + public function setSegment(int $number, string $group = 'default') + { + $this->segment[$group] = $number; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the path that an aliased group of links will use. + * + * @param string $path + * @param string $group + * + * @return mixed + */ + public function setPath(string $path, string $group = 'default') + { + $this->ensureGroup($group); + + $this->groups[$group]['uri']->setPath($path); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of pages. + * + * @param string|null $group + * + * @return integer + */ + public function getPageCount(string $group = 'default'): int + { + $this->ensureGroup($group); + + return $this->groups[$group]['pageCount']; + } + + //-------------------------------------------------------------------- + + /** + * Returns the number of the current page of results. + * + * @param string|null $group + * + * @return integer + */ + public function getCurrentPage(string $group = 'default'): int + { + $this->ensureGroup($group); + + return $this->groups[$group]['currentPage'] ?: 1; + } + + //-------------------------------------------------------------------- + + /** + * Tells whether this group of results has any more pages of results. + * + * @param string|null $group + * + * @return boolean + */ + public function hasMore(string $group = 'default'): bool + { + $this->ensureGroup($group); + + return ($this->groups[$group]['currentPage'] * $this->groups[$group]['perPage']) < $this->groups[$group]['total']; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last page, if we have a total that we can calculate with. + * + * @param string $group + * + * @return integer|null + */ + public function getLastPage(string $group = 'default') + { + $this->ensureGroup($group); + + if (! is_numeric($this->groups[$group]['total']) || ! is_numeric($this->groups[$group]['perPage'])) + { + return null; + } + + return (int)ceil($this->groups[$group]['total'] / $this->groups[$group]['perPage']); + } + + //-------------------------------------------------------------------- + + /** + * Determines the first page # that should be shown. + * + * @param string $group + * + * @return integer + */ + public function getFirstPage(string $group = 'default'): int + { + $this->ensureGroup($group); + + // @todo determine based on a 'surroundCount' value + return 1; + } + + //-------------------------------------------------------------------- + + /** + * Returns the URI for a specific page for the specified group. + * + * @param integer|null $page + * @param string $group + * @param boolean $returnObject + * + * @return string|\CodeIgniter\HTTP\URI + */ + public function getPageURI(int $page = null, string $group = 'default', bool $returnObject = false) + { + $this->ensureGroup($group); + + /** + * @var \CodeIgniter\HTTP\URI $uri + */ + $uri = $this->groups[$group]['uri']; + + $segment = $this->segment[$group] ?? 0; + + if ($segment) + { + $uri->setSegment($segment, $page); + } + else + { + $uri->addQuery($this->groups[$group]['pageSelector'], $page); + } + + if ($this->only) + { + $query = array_intersect_key($_GET, array_flip($this->only)); + + if (! $segment) + { + $query[$this->groups[$group]['pageSelector']] = $page; + } + + $uri->setQueryArray($query); + } + + return $returnObject === true ? $uri : (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Returns the full URI to the next page of results, or null. + * + * @param string $group + * @param boolean $returnObject + * + * @return string|null + */ + public function getNextPageURI(string $group = 'default', bool $returnObject = false) + { + $this->ensureGroup($group); + + $last = $this->getLastPage($group); + $curr = $this->getCurrentPage($group); + $page = null; + + if (! empty($last) && ! empty($curr) && $last === $curr) + { + return null; + } + + if ($last > $curr) + { + $page = $curr + 1; + } + + return $this->getPageURI($page, $group, $returnObject); + } + + //-------------------------------------------------------------------- + + /** + * Returns the full URL to the previous page of results, or null. + * + * @param string $group + * @param boolean $returnObject + * + * @return string|null + */ + public function getPreviousPageURI(string $group = 'default', bool $returnObject = false) + { + $this->ensureGroup($group); + + $first = $this->getFirstPage($group); + $curr = $this->getCurrentPage($group); + $page = null; + + if (! empty($first) && ! empty($curr) && $first === $curr) + { + return null; + } + + if ($first < $curr) + { + $page = $curr - 1; + } + + return $this->getPageURI($page, $group, $returnObject); + } + + //-------------------------------------------------------------------- + + /** + * Returns the number of results per page that should be shown. + * + * @param string $group + * + * @return integer + */ + public function getPerPage(string $group = 'default'): int + { + $this->ensureGroup($group); + + return (int) $this->groups[$group]['perPage']; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array with details about the results, including + * total, per_page, current_page, last_page, next_url, prev_url, from, to. + * Does not include the actual data. This data is suitable for adding + * a 'data' object to with the result set and converting to JSON. + * + * @param string $group + * + * @return array + */ + public function getDetails(string $group = 'default'): array + { + if (! array_key_exists($group, $this->groups)) + { + throw PagerException::forInvalidPaginationGroup($group); + } + + $newGroup = $this->groups[$group]; + + $newGroup['next'] = $this->getNextPageURI($group); + $newGroup['previous'] = $this->getPreviousPageURI($group); + $newGroup['segment'] = $this->segment[$group] ?? 0; + + return $newGroup; + } + + //-------------------------------------------------------------------- + + /** + * Sets only allowed queries on pagination links. + * + * @param array $queries + * + * @return Pager + */ + public function only(array $queries):Pager + { + $this->only = $queries; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Ensures that an array exists for the group specified. + * + * @param string $group + * @param integer $perPage + */ + protected function ensureGroup(string $group, int $perPage = null) + { + if (array_key_exists($group, $this->groups)) + { + return; + } + + $this->groups[$group] = [ + 'uri' => clone current_url(true), + 'hasMore' => false, + 'total' => null, + 'perPage' => $perPage ?? $this->config->perPage, + 'pageCount' => 1, + 'pageSelector' => $group === 'default' ? 'page' : 'page_' . $group, + ]; + + $this->calculateCurrentPage($group); + + if ($_GET) + { + $this->groups[$group]['uri'] = $this->groups[$group]['uri']->setQueryArray($_GET); + } + } + + //-------------------------------------------------------------------- + + /** + * Calculating the current page + * + * @param string $group + */ + protected function calculateCurrentPage(string $group) + { + if (array_key_exists($group, $this->segment)) + { + try + { + $this->groups[$group]['currentPage'] = (int) $this->groups[$group]['uri']->setSilent(false)->getSegment($this->segment[$group]); + } + catch (\CodeIgniter\HTTP\Exceptions\HTTPException $e) + { + $this->groups[$group]['currentPage'] = 1; + } + } + else + { + $pageSelector = $this->groups[$group]['pageSelector']; + + $page = (int) ($_GET[$pageSelector] ?? 1); + + $this->groups[$group]['currentPage'] = $page < 1 ? 1 : $page; + } + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Pager/PagerInterface.php b/vendor/codeigniter4/framework/system/Pager/PagerInterface.php new file mode 100644 index 0000000..9f975b5 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Pager/PagerInterface.php @@ -0,0 +1,228 @@ +first = 1; + $this->last = $details['pageCount']; + $this->current = $details['currentPage']; + $this->total = $details['total']; + $this->uri = $details['uri']; + $this->pageCount = $details['pageCount']; + $this->segment = $details['segment'] ?? 0; + $this->pageSelector = $details['pageSelector'] ?? 'page'; + } + + //-------------------------------------------------------------------- + + /** + * Sets the total number of links that should appear on either + * side of the current page. Adjusts the first and last counts + * to reflect it. + * + * @param integer|null $count + * + * @return PagerRenderer + */ + public function setSurroundCount(int $count = null) + { + $this->updatePages($count); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if there is a "previous" page before our "first" page. + * + * @return boolean + */ + public function hasPrevious(): bool + { + return $this->first > 1; + } + + //-------------------------------------------------------------------- + + /** + * Returns a URL to the "previous" page. The previous page is NOT the + * page before the current page, but is the page just before the + * "first" page. + * + * You MUST call hasPrevious() first, or this value may be invalid. + * + * @return string|null + */ + public function getPrevious() + { + if (! $this->hasPrevious()) + { + return null; + } + + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->first - 1); + } + else + { + $uri->setSegment($this->segment, $this->first - 1); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if there is a "next" page after our "last" page. + * + * @return boolean + */ + public function hasNext(): bool + { + return $this->pageCount > $this->last; + } + + //-------------------------------------------------------------------- + + /** + * Returns a URL to the "next" page. The next page is NOT, the + * page after the current page, but is the page that follows the + * "last" page. + * + * You MUST call hasNext() first, or this value may be invalid. + * + * @return string|null + */ + public function getNext() + { + if (! $this->hasNext()) + { + return null; + } + + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->last + 1); + } + else + { + $uri->setSegment($this->segment, $this->last + 1); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Returns the URI of the first page. + * + * @return string + */ + public function getFirst(): string + { + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, 1); + } + else + { + $uri->setSegment($this->segment, 1); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Returns the URI of the last page. + * + * @return string + */ + public function getLast(): string + { + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->pageCount); + } + else + { + $uri->setSegment($this->segment, $this->pageCount); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Returns the URI of the current page. + * + * @return string + */ + public function getCurrent(): string + { + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->current); + } + else + { + $uri->setSegment($this->segment, $this->current); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Returns an array of links that should be displayed. Each link + * is represented by another array containing of the URI the link + * should go to, the title (number) of the link, and a boolean + * value representing whether this link is active or not. + * + * @return array + */ + public function links(): array + { + $links = []; + + $uri = clone $this->uri; + + for ($i = $this->first; $i <= $this->last; $i ++) + { + $links[] = [ + 'uri' => (string) ($this->segment === 0 ? $uri->addQuery($this->pageSelector, $i) : $uri->setSegment($this->segment, $i)), + 'title' => (int) $i, + 'active' => ($i === $this->current), + ]; + } + + return $links; + } + + //-------------------------------------------------------------------- + + /** + * Updates the first and last pages based on $surroundCount, + * which is the number of links surrounding the active page + * to show. + * + * @param integer|null $count The new "surroundCount" + */ + protected function updatePages(int $count = null) + { + if (is_null($count)) + { + return; + } + + $this->first = $this->current - $count > 0 ? (int) ($this->current - $count) : 1; + $this->last = $this->current + $count <= $this->pageCount ? (int) ($this->current + $count) : (int) $this->pageCount; + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if there is a "previous" page before our "first" page. + * + * @return boolean + */ + public function hasPreviousPage(): bool + { + return $this->current > 1; + } + + //-------------------------------------------------------------------- + + /** + * Returns a URL to the "previous" page. + * + * You MUST call hasPreviousPage() first, or this value may be invalid. + * + * @return string|null + */ + public function getPreviousPage() + { + if (! $this->hasPreviousPage()) + { + return null; + } + + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->current - 1); + } + else + { + $uri->setSegment($this->segment, $this->current - 1); + } + + return (string) $uri; + } + + //-------------------------------------------------------------------- + + /** + * Checks to see if there is a "next" page after our "last" page. + * + * @return boolean + */ + public function hasNextPage(): bool + { + return $this->current < $this->last; + } + + //-------------------------------------------------------------------- + + /** + * Returns a URL to the "next" page. + * + * You MUST call hasNextPage() first, or this value may be invalid. + * + * @return string|null + */ + public function getNextPage() + { + if (! $this->hasNextPage()) + { + return null; + } + + $uri = clone $this->uri; + + if ($this->segment === 0) + { + $uri->addQuery($this->pageSelector, $this->current + 1); + } + else + { + $uri->setSegment($this->segment, $this->current + 1); + } + + return (string) $uri; + } +} diff --git a/vendor/codeigniter4/framework/system/Pager/Views/default_full.php b/vendor/codeigniter4/framework/system/Pager/Views/default_full.php new file mode 100644 index 0000000..ef446e9 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Pager/Views/default_full.php @@ -0,0 +1,46 @@ +setSurroundCount(2); +?> + + diff --git a/vendor/codeigniter4/framework/system/Pager/Views/default_head.php b/vendor/codeigniter4/framework/system/Pager/Views/default_head.php new file mode 100644 index 0000000..8f9dc69 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Pager/Views/default_head.php @@ -0,0 +1,18 @@ +setSurroundCount(0); + +if ($pager->hasPrevious()) +{ + echo '' . PHP_EOL; +} + +echo '' . PHP_EOL; + +if ($pager->hasNext()) +{ + echo '' . PHP_EOL; +} diff --git a/vendor/codeigniter4/framework/system/Pager/Views/default_simple.php b/vendor/codeigniter4/framework/system/Pager/Views/default_simple.php new file mode 100644 index 0000000..3bfa8d9 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Pager/Views/default_simple.php @@ -0,0 +1,21 @@ +setSurroundCount(0); +?> + diff --git a/vendor/codeigniter4/framework/system/RESTful/ResourceController.php b/vendor/codeigniter4/framework/system/RESTful/ResourceController.php new file mode 100644 index 0000000..d13218c --- /dev/null +++ b/vendor/codeigniter4/framework/system/RESTful/ResourceController.php @@ -0,0 +1,203 @@ +setModel($this->modelName); + } + + //-------------------------------------------------------------------- + + /** + * Return an array of resource objects, themselves in array format + * + * @return array an array + */ + public function index() + { + return $this->fail(lang('RESTful.notImplemented', ['index']), 501); + } + + /** + * Return the properties of a resource object + * + * @return array an array + */ + public function show($id = null) + { + return $this->fail(lang('RESTful.notImplemented', ['show']), 501); + } + + /** + * Return a new resource object, with default properties + * + * @return array an array + */ + public function new() + { + return $this->fail(lang('RESTful.notImplemented', ['new']), 501); + } + + /** + * Create a new resource object, from "posted" parameters + * + * @return array an array + */ + public function create() + { + return $this->fail(lang('RESTful.notImplemented', ['create']), 501); + } + + /** + * Return the editable properties of a resource object + * + * @return array an array + */ + public function edit($id = null) + { + return $this->fail(lang('RESTful.notImplemented', ['edit']), 501); + } + + /** + * Add or update a model resource, from "posted" properties + * + * @return array an array + */ + public function update($id = null) + { + return $this->fail(lang('RESTful.notImplemented', ['update']), 501); + } + + /** + * Delete the designated resource object from the model + * + * @return array an array + */ + public function delete($id = null) + { + return $this->fail(lang('RESTful.notImplemented', ['delete']), 501); + } + + //-------------------------------------------------------------------- + + /** + * Set or change the model this controller is bound to. + * Given either the name or the object, determine the other. + * + * @param string|object $which + */ + public function setModel($which = null) + { + // save what we have been given + if (! empty($which)) + { + if (is_object($which)) + { + $this->model = $which; + } + else + { + $this->modelName = $which; + } + } + + // make a model object if needed + if (empty($this->model) && ! empty($this->modelName)) + { + if (class_exists($this->modelName)) + { + $this->model = model($this->modelName); + } + } + + // determine model name if needed + if (empty($this->modelName) && ! empty($this->model)) + { + $this->modelName = get_class($this->model); + } + } + + /** + * Set/change the expected response representation for returned objects + * + * @param string $format + */ + public function setFormat(string $format = 'json') + { + if (in_array($format, ['json', 'xml'])) + { + $this->format = $format; + } + } + +} diff --git a/vendor/codeigniter4/framework/system/RESTful/ResourcePresenter.php b/vendor/codeigniter4/framework/system/RESTful/ResourcePresenter.php new file mode 100644 index 0000000..91fdeb0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/RESTful/ResourcePresenter.php @@ -0,0 +1,206 @@ +setModel($this->modelName); + } + + //-------------------------------------------------------------------- + + /** + * Present a view of resource objects + * + * @return string + */ + public function index() + { + return lang('RESTful.notImplemented', ['index']); + } + + /** + * Present a view to present a specific resource object + * + * @param type $id + * @return string + */ + public function show($id = null) + { + return lang('RESTful.notImplemented', ['show']); + } + + /** + * Present a view to present a new single resource object + * + * @return string + */ + public function new() + { + return lang('RESTful.notImplemented', ['new']); + } + + /** + * Process the creation/insertion of a new resource object. + * This should be a POST. + * + * @return string + */ + public function create() + { + return lang('RESTful.notImplemented', ['create']); + } + + /** + * Present a view to confirm the deletion of a specific resource object + * + * @param type $id + * @return string + */ + public function remove($id = null) + { + return lang('RESTful.notImplemented', ['remove']); + } + + /** + * Process the deletion of a specific resource object + * + * @param type $id + * @return string + */ + public function delete($id = null) + { + return lang('RESTful.notImplemented', ['delete']); + } + + /** + * Present a view to edit the properties of a specific resource object + * + * @param type $id + * @return string + */ + public function edit($id = null) + { + return lang('RESTful.notImplemented', ['edit']); + } + + /** + * Process the updating, full or partial, of a specific resource object. + * This should be a POST. + * + * @param type $id + * @return string + */ + public function update($id = null) + { + return lang('RESTful.notImplemented', ['update']); + } + + //-------------------------------------------------------------------- + + /** + * Set or change the model this controller is bound to. + * Given either the name or the object, determine the other. + * + * @param string|object $which + */ + public function setModel($which = null) + { + // save what we have been given + if (! empty($which)) + { + if (is_object($which)) + { + $this->model = $which; + $this->modelName = null; + } + else + { + $this->model = null; + $this->modelName = $which; + } + } + + // make a model object if needed + if (empty($this->model) && ! empty($this->modelName)) + { + if (class_exists($this->modelName)) + { + $this->model = model($this->modelName); + } + } + + // determine model name if needed + if (empty($this->modelName) && ! empty($this->model)) + { + $this->modelName = get_class($this->model); + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Router/Exceptions/RedirectException.php b/vendor/codeigniter4/framework/system/Router/Exceptions/RedirectException.php new file mode 100644 index 0000000..6114207 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Router/Exceptions/RedirectException.php @@ -0,0 +1,53 @@ + '.*', + 'segment' => '[^/]+', + 'alphanum' => '[a-zA-Z0-9]+', + 'num' => '[0-9]+', + 'alpha' => '[a-zA-Z]+', + 'hash' => '[^/]+', + ]; + + /** + * An array of all routes and their mappings. + * + * @var array + */ + protected $routes = [ + '*' => [], + 'options' => [], + 'get' => [], + 'head' => [], + 'post' => [], + 'put' => [], + 'delete' => [], + 'trace' => [], + 'connect' => [], + 'cli' => [], + ]; + + /** + * Array of routes options + * + * @var array + */ + protected $routesOptions = []; + + /** + * The current method that the script is being called by. + * + * @var string + */ + protected $HTTPVerb; + + /** + * The default list of HTTP methods (and CLI for command line usage) + * that is allowed if no other method is provided. + * + * @var array + */ + protected $defaultHTTPMethods = [ + 'options', + 'get', + 'head', + 'post', + 'put', + 'delete', + 'trace', + 'connect', + 'cli', + ]; + + /** + * The name of the current group, if any. + * + * @var string + */ + protected $group; + + /** + * The current subdomain. + * + * @var string + */ + protected $currentSubdomain; + + /** + * Stores copy of current options being + * applied during creation. + * + * @var null + */ + protected $currentOptions; + + /** + * A little performance booster. + * + * @var boolean + */ + protected $didDiscover = false; + + /** + * Handle to the file locator to use. + * + * @var \CodeIgniter\Autoloader\FileLocator + */ + protected $fileLocator; + + /** + * Handle to the modules config. + * + * @var \Config\Modules + */ + protected $moduleConfig; + + //-------------------------------------------------------------------- + + /** + * Constructor + * + * @param \CodeIgniter\Autoloader\FileLocator $locator + * @param \Config\Modules $moduleConfig + */ + public function __construct(FileLocator $locator, $moduleConfig) + { + $this->fileLocator = $locator; + $this->moduleConfig = $moduleConfig; + } + + //-------------------------------------------------------------------- + + /** + * Registers a new constraint with the system. Constraints are used + * by the routes as placeholders for regular expressions to make defining + * the routes more human-friendly. + * + * You can pass an associative array as $placeholder, and have + * multiple placeholders added at once. + * + * @param string|array $placeholder + * @param string $pattern + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function addPlaceholder($placeholder, string $pattern = null): RouteCollectionInterface + { + if (! is_array($placeholder)) + { + $placeholder = [$placeholder => $pattern]; + } + + $this->placeholders = array_merge($this->placeholders, $placeholder); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the default namespace to use for Controllers when no other + * namespace has been specified. + * + * @param string $value + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function setDefaultNamespace(string $value): RouteCollectionInterface + { + $this->defaultNamespace = filter_var($value, FILTER_SANITIZE_STRING); + $this->defaultNamespace = rtrim($this->defaultNamespace, '\\') . '\\'; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the default controller to use when no other controller has been + * specified. + * + * @param string $value + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function setDefaultController(string $value): RouteCollectionInterface + { + $this->defaultController = filter_var($value, FILTER_SANITIZE_STRING); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the default method to call on the controller when no other + * method has been set in the route. + * + * @param string $value + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function setDefaultMethod(string $value): RouteCollectionInterface + { + $this->defaultMethod = filter_var($value, FILTER_SANITIZE_STRING); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Tells the system whether to convert dashes in URI strings into + * underscores. In some search engines, including Google, dashes + * create more meaning and make it easier for the search engine to + * find words and meaning in the URI for better SEO. But it + * doesn't work well with PHP method names.... + * + * @param boolean $value + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function setTranslateURIDashes(bool $value): RouteCollectionInterface + { + $this->translateURIDashes = $value; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * If TRUE, the system will attempt to match the URI against + * Controllers by matching each segment against folders/files + * in APPPATH/Controllers, when a match wasn't found against + * defined routes. + * + * If FALSE, will stop searching and do NO automatic routing. + * + * @param boolean $value + * + * @return RouteCollectionInterface + */ + public function setAutoRoute(bool $value): RouteCollectionInterface + { + $this->autoRoute = $value; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets the class/method that should be called if routing doesn't + * find a match. It can be either a closure or the controller/method + * name exactly like a route is defined: Users::index + * + * This setting is passed to the Router class and handled there. + * + * @param callable|null $callable + * + * @return RouteCollectionInterface + */ + public function set404Override($callable = null): RouteCollectionInterface + { + $this->override404 = $callable; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the 404 Override setting, which can be null, a closure + * or the controller/string. + * + * @return string|\Closure|null + */ + public function get404Override() + { + return $this->override404; + } + + //-------------------------------------------------------------------- + + /** + * Will attempt to discover any additional routes, either through + * the local PSR4 namespaces, or through selected Composer packages. + */ + protected function discoverRoutes() + { + if ($this->didDiscover) + { + return; + } + + // We need this var in local scope + // so route files can access it. + $routes = $this; + + if ($this->moduleConfig->shouldDiscover('routes')) + { + $files = $this->fileLocator->search('Config/Routes.php'); + + foreach ($files as $file) + { + // Don't include our main file again... + if ($file === APPPATH . 'Config/Routes.php') + { + continue; + } + + include $file; + } + } + + $this->didDiscover = true; + } + + //-------------------------------------------------------------------- + + /** + * Sets the default constraint to be used in the system. Typically + * for use with the 'resource' method. + * + * @param string $placeholder + * + * @return RouteCollectionInterface + */ + public function setDefaultConstraint(string $placeholder): RouteCollectionInterface + { + if (array_key_exists($placeholder, $this->placeholders)) + { + $this->defaultPlaceholder = $placeholder; + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the name of the default controller. With Namespace. + * + * @return string + */ + public function getDefaultController(): string + { + return $this->defaultController; + } + + //-------------------------------------------------------------------- + + /** + * Returns the name of the default method to use within the controller. + * + * @return string + */ + public function getDefaultMethod(): string + { + return $this->defaultMethod; + } + + //-------------------------------------------------------------------- + + /** + * Returns the default namespace as set in the Routes config file. + * + * @return string + */ + public function getDefaultNamespace(): string + { + return $this->defaultNamespace; + } + + //-------------------------------------------------------------------- + + /** + * Returns the current value of the translateURIDashes setting. + * + * @return boolean + */ + public function shouldTranslateURIDashes(): bool + { + return $this->translateURIDashes; + } + + //-------------------------------------------------------------------- + + /** + * Returns the flag that tells whether to autoRoute URI against Controllers. + * + * @return boolean + */ + public function shouldAutoRoute(): bool + { + return $this->autoRoute; + } + + //-------------------------------------------------------------------- + + /** + * Returns the raw array of available routes. + * + * @param mixed $verb + * + * @return array + */ + public function getRoutes($verb = null): array + { + if (empty($verb)) + { + $verb = $this->getHTTPVerb(); + } + + // Since this is the entry point for the Router, + // take a moment to do any route discovery + // we might need to do. + $this->discoverRoutes(); + + $routes = []; + + if (isset($this->routes[$verb])) + { + // Keep current verb's routes at the beginning so they're matched + // before any of the generic, "add" routes. + if (isset($this->routes['*'])) + { + $extraRules = array_diff_key($this->routes['*'], $this->routes[$verb]); + $collection = array_merge($this->routes[$verb], $extraRules); + } + foreach ($collection as $r) + { + $key = key($r['route']); + $routes[$key] = $r['route'][$key]; + } + } + + return $routes; + } + + //-------------------------------------------------------------------- + + /** + * Returns one or all routes options + * + * @param string $from + * + * @return array + */ + public function getRoutesOptions(string $from = null): array + { + return $from ? $this->routesOptions[$from] ?? [] : $this->routesOptions; + } + + //-------------------------------------------------------------------- + + /** + * Returns the current HTTP Verb being used. + * + * @return string + */ + public function getHTTPVerb(): string + { + return $this->HTTPVerb; + } + + //-------------------------------------------------------------------- + + /** + * Sets the current HTTP verb. + * Used primarily for testing. + * + * @param string $verb + * + * @return $this + */ + public function setHTTPVerb(string $verb) + { + $this->HTTPVerb = $verb; + + return $this; + } + + /** + * A shortcut method to add a number of routes at a single time. + * It does not allow any options to be set on the route, or to + * define the method used. + * + * @param array $routes + * @param array $options + * + * @return RouteCollectionInterface + */ + public function map(array $routes = [], array $options = null): RouteCollectionInterface + { + foreach ($routes as $from => $to) + { + $this->add($from, $to, $options); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Adds a single route to the collection. + * + * Example: + * $routes->add('news', 'Posts::index'); + * + * @param string $from + * @param array|string $to + * @param array|null $options + * + * @return RouteCollectionInterface + */ + public function add(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('*', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Adds a temporary redirect from one route to another. Used for + * redirecting traffic from old, non-existing routes to the new + * moved routes. + * + * @param string $from The pattern to match against + * @param string $to Either a route name or a URI to redirect to + * @param integer $status The HTTP status code that should be returned with this redirect + * + * @return RouteCollection + */ + public function addRedirect(string $from, string $to, int $status = 302) + { + // Use the named route's pattern if this is a named route. + if (array_key_exists($to, $this->routes['*'])) + { + $to = $this->routes['*'][$to]['route']; + } + elseif (array_key_exists($to, $this->routes['get'])) + { + $to = $this->routes['get'][$to]['route']; + } + + $this->create('*', $from, $to, ['redirect' => $status]); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the route is a redirecting route. + * + * @param string $from + * + * @return boolean + */ + public function isRedirect(string $from): bool + { + foreach ($this->routes['*'] as $name => $route) + { + // Named route? + if ($name === $from || key($route['route']) === $from) + { + return isset($route['redirect']) && is_numeric($route['redirect']); + } + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Grabs the HTTP status code from a redirecting Route. + * + * @param string $from + * + * @return integer + */ + public function getRedirectCode(string $from): int + { + foreach ($this->routes['*'] as $name => $route) + { + // Named route? + if ($name === $from || key($route['route']) === $from) + { + return $route['redirect'] ?? 0; + } + } + + return 0; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Grouping Routes + //-------------------------------------------------------------------- + + /** + * Group a series of routes under a single URL segment. This is handy + * for grouping items into an admin area, like: + * + * Example: + * // Creates route: admin/users + * $route->group('admin', function() { + * $route->resource('users'); + * }); + * + * @param string $name The name to group/prefix the routes with. + * @param array ...$params + * + * @return void + */ + public function group(string $name, ...$params) + { + $oldGroup = $this->group; + $oldOptions = $this->currentOptions; + + // To register a route, we'll set a flag so that our router + // so it will see the group name. + $this->group = ltrim($oldGroup . '/' . $name, '/'); + + $callback = array_pop($params); + + if ($params && is_array($params[0])) + { + $this->currentOptions = array_shift($params); + } + + if (is_callable($callback)) + { + $callback($this); + } + + $this->group = $oldGroup; + $this->currentOptions = $oldOptions; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // HTTP Verb-based routing + //-------------------------------------------------------------------- + // Routing works here because, as the routes Config file is read in, + // the various HTTP verb-based routes will only be added to the in-memory + // routes if it is a call that should respond to that verb. + // + // The options array is typically used to pass in an 'as' or var, but may + // be expanded in the future. See the docblock for 'add' method above for + // current list of globally available options. + // + + /** + * Creates a collections of HTTP-verb based routes for a controller. + * + * Possible Options: + * 'controller' - Customize the name of the controller used in the 'to' route + * 'placeholder' - The regex used by the Router. Defaults to '(:any)' + * 'websafe' - - '1' if only GET and POST HTTP verbs are supported + * + * Example: + * + * $route->resource('photos'); + * + * // Generates the following routes: + * HTTP Verb | Path | Action | Used for... + * ----------+-------------+---------------+----------------- + * GET /photos index an array of photo objects + * GET /photos/new new an empty photo object, with default properties + * GET /photos/{id}/edit edit a specific photo object, editable properties + * GET /photos/{id} show a specific photo object, all properties + * POST /photos create a new photo object, to add to the resource + * DELETE /photos/{id} delete deletes the specified photo object + * PUT/PATCH /photos/{id} update replacement properties for existing photo + * + * If 'websafe' option is present, the following paths are also available: + * + * POST /photos/{id}/delete delete + * POST /photos/{id} update + * + * @param string $name The name of the resource/controller to route to. + * @param array|null $options An list of possible ways to customize the routing. + * + * @return RouteCollectionInterface + */ + public function resource(string $name, array $options = null): RouteCollectionInterface + { + // In order to allow customization of the route the + // resources are sent to, we need to have a new name + // to store the values in. + $new_name = ucfirst($name); + + // If a new controller is specified, then we replace the + // $name value with the name of the new controller. + if (isset($options['controller'])) + { + $new_name = ucfirst(filter_var($options['controller'], FILTER_SANITIZE_STRING)); + } + + // In order to allow customization of allowed id values + // we need someplace to store them. + $id = $this->placeholders[$this->defaultPlaceholder] ?? '(:segment)'; + + if (isset($options['placeholder'])) + { + $id = $options['placeholder']; + } + + // Make sure we capture back-references + $id = '(' . trim($id, '()') . ')'; + + $methods = isset($options['only']) ? (is_string($options['only']) ? explode(',', $options['only']) : $options['only']) : ['index', 'show', 'create', 'update', 'delete', 'new', 'edit']; + + if (isset($options['except'])) + { + $options['except'] = is_array($options['except']) ? $options['except'] : explode(',', $options['except']); + foreach ($methods as $i => $method) + { + if (in_array($method, $options['except'])) + { + unset($methods[$i]); + } + } + } + + if (in_array('index', $methods)) + { + $this->get($name, $new_name . '::index', $options); + } + if (in_array('new', $methods)) + { + $this->get($name . '/new', $new_name . '::new', $options); + } + if (in_array('edit', $methods)) + { + $this->get($name . '/' . $id . '/edit', $new_name . '::edit/$1', $options); + } + if (in_array('show', $methods)) + { + $this->get($name . '/' . $id, $new_name . '::show/$1', $options); + } + if (in_array('create', $methods)) + { + $this->post($name, $new_name . '::create', $options); + } + if (in_array('update', $methods)) + { + $this->put($name . '/' . $id, $new_name . '::update/$1', $options); + $this->patch($name . '/' . $id, $new_name . '::update/$1', $options); + } + if (in_array('delete', $methods)) + { + $this->delete($name . '/' . $id, $new_name . '::delete/$1', $options); + } + + // Web Safe? delete needs checking before update because of method name + if (isset($options['websafe'])) + { + if (in_array('delete', $methods)) + { + $this->post($name . '/' . $id . '/delete', $new_name . '::delete/$1', $options); + } + if (in_array('update', $methods)) + { + $this->post($name . '/' . $id, $new_name . '::update/$1', $options); + } + } + + return $this; + } + + /** + * Creates a collections of HTTP-verb based routes for a presenter controller. + * + * Possible Options: + * 'controller' - Customize the name of the controller used in the 'to' route + * 'placeholder' - The regex used by the Router. Defaults to '(:any)' + * + * Example: + * + * $route->presenter('photos'); + * + * // Generates the following routes: + * HTTP Verb | Path | Action | Used for... + * ----------+-------------+---------------+----------------- + * GET /photos index showing all array of photo objects + * GET /photos/show/{id} show showing a specific photo object, all properties + * GET /photos/new new showing a form for an empty photo object, with default properties + * POST /photos/create create processing the form for a new photo + * GET /photos/edit/{id} edit show an editing form for a specific photo object, editable properties + * POST /photos/update/{id} update process the editing form data + * GET /photos/remove/{id} remove show a form to confirm deletion of a specific photo object + * POST /photos/delete/{id} delete deleting the specified photo object + * + * @param string $name The name of the controller to route to. + * @param array|null $options An list of possible ways to customize the routing. + * + * @return RouteCollectionInterface + */ + public function presenter(string $name, array $options = null): RouteCollectionInterface + { + // In order to allow customization of the route the + // resources are sent to, we need to have a new name + // to store the values in. + $newName = ucfirst($name); + + // If a new controller is specified, then we replace the + // $name value with the name of the new controller. + if (isset($options['controller'])) + { + $newName = ucfirst(filter_var($options['controller'], FILTER_SANITIZE_STRING)); + } + + // In order to allow customization of allowed id values + // we need someplace to store them. + $id = $this->placeholders[$this->defaultPlaceholder] ?? '(:segment)'; + + if (isset($options['placeholder'])) + { + $id = $options['placeholder']; + } + + // Make sure we capture back-references + $id = '(' . trim($id, '()') . ')'; + + $methods = isset($options['only']) ? (is_string($options['only']) ? explode(',', $options['only']) : $options['only']) : ['index', 'show', 'new', 'create', 'edit', 'update', 'remove', 'delete']; + + if (isset($options['except'])) + { + $options['except'] = is_array($options['except']) ? $options['except'] : explode(',', $options['except']); + foreach ($methods as $i => $method) + { + if (in_array($method, $options['except'])) + { + unset($methods[$i]); + } + } + } + + if (in_array('index', $methods)) + { + $this->get($name, $newName . '::index', $options); + } + if (in_array('show', $methods)) + { + $this->get($name . '/show/' . $id, $newName . '::show/$1', $options); + } + if (in_array('new', $methods)) + { + $this->get($name . '/new', $newName . '::new', $options); + } + if (in_array('create', $methods)) + { + $this->post($name . '/create', $newName . '::create', $options); + } + if (in_array('edit', $methods)) + { + $this->get($name . '/edit/' . $id, $newName . '::edit/$1', $options); + } + if (in_array('update', $methods)) + { + $this->post($name . '/update/' . $id, $newName . '::update/$1', $options); + } + if (in_array('remove', $methods)) + { + $this->get($name . '/remove/' . $id, $newName . '::remove/$1', $options); + } + if (in_array('delete', $methods)) + { + $this->post($name . '/delete/' . $id, $newName . '::delete/$1', $options); + } + if (in_array('show', $methods)) + { + $this->get($name . '/' . $id, $newName . '::show/$1', $options); + } + if (in_array('create', $methods)) + { + $this->post($name, $newName . '::create', $options); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a single route to match for multiple HTTP Verbs. + * + * Example: + * $route->match( ['get', 'post'], 'users/(:num)', 'users/$1); + * + * @param array $verbs + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function match(array $verbs = [], string $from, $to, array $options = null): RouteCollectionInterface + { + foreach ($verbs as $verb) + { + $verb = strtolower($verb); + + $this->{$verb}($from, $to, $options); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to GET requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function get(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('get', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to POST requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function post(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('post', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to PUT requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function put(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('put', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to DELETE requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function delete(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('delete', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to HEAD requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function head(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('head', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to PATCH requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function patch(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('patch', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to OPTIONS requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function options(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('options', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Specifies a route that is only available to command-line requests. + * + * @param string $from + * @param string|array $to + * @param array|null $options + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function cli(string $from, $to, array $options = null): RouteCollectionInterface + { + $this->create('cli', $from, $to, $options); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Limits the routes to a specified ENVIRONMENT or they won't run. + * + * @param string $env + * @param \Closure $callback + * + * @return \CodeIgniter\Router\RouteCollectionInterface + */ + public function environment(string $env, \Closure $callback): RouteCollectionInterface + { + if (ENVIRONMENT === $env) + { + $callback($this); + } + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to look up a route based on its destination. + * + * If a route exists: + * + * 'path/(:any)/(:any)' => 'Controller::method/$1/$2' + * + * This method allows you to know the Controller and method + * and get the route that leads to it. + * + * // Equals 'path/$param1/$param2' + * reverseRoute('Controller::method', $param1, $param2); + * + * @param string $search + * @param array ...$params + * + * @return string|false + */ + public function reverseRoute(string $search, ...$params) + { + // Named routes get higher priority. + foreach ($this->routes as $collection) + { + if (array_key_exists($search, $collection)) + { + $route = $this->fillRouteParams(key($collection[$search]['route']), $params); + return $this->localizeRoute($route); + } + } + + // If it's not a named route, then loop over + // all routes to find a match. + foreach ($this->routes as $collection) + { + foreach ($collection as $route) + { + $from = key($route['route']); + $to = $route['route'][$from]; + + // ignore closures + if (! is_string($to)) + { + continue; + } + + // Lose any namespace slash at beginning of strings + // to ensure more consistent match. + $to = ltrim($to, '\\'); + $search = ltrim($search, '\\'); + + // If there's any chance of a match, then it will + // be with $search at the beginning of the $to string. + if (strpos($to, $search) !== 0) + { + continue; + } + + // Ensure that the number of $params given here + // matches the number of back-references in the route + if (substr_count($to, '$') !== count($params)) + { + continue; + } + + $route = $this->fillRouteParams($from, $params); + return $this->localizeRoute($route); + } + } + + // If we're still here, then we did not find a match. + return false; + } + + //-------------------------------------------------------------------- + + /** + * Replaces the {locale} tag with the current application locale + * + * @param string $route + * + * @return string + */ + protected function localizeRoute(string $route) :string + { + return strtr($route, ['{locale}' => Services::request()->getLocale()]); + } + + //-------------------------------------------------------------------- + + /** + * Checks a route (using the "from") to see if it's filtered or not. + * + * @param string $search + * + * @return boolean + */ + public function isFiltered(string $search): bool + { + return isset($this->routesOptions[$search]['filter']); + } + + //-------------------------------------------------------------------- + + /** + * Returns the filter that should be applied for a single route, along + * with any parameters it might have. Parameters are found by splitting + * the parameter name on a colon to separate the filter name from the parameter list, + * and the splitting the result on commas. So: + * + * 'role:admin,manager' + * + * has a filter of "role", with parameters of ['admin', 'manager']. + * + * @param string $search + * + * @return string + */ + public function getFilterForRoute(string $search): string + { + if (! $this->isFiltered($search)) + { + return ''; + } + + return $this->routesOptions[$search]['filter']; + } + + //-------------------------------------------------------------------- + + /** + * Given a + * + * @param string $from + * @param array|null $params + * + * @return string + * @throws \CodeIgniter\Router\Exceptions\RouterException + */ + protected function fillRouteParams(string $from, array $params = null): string + { + // Find all of our back-references in the original route + preg_match_all('/\(([^)]+)\)/', $from, $matches); + + if (empty($matches[0])) + { + return '/' . ltrim($from, '/'); + } + + // Build our resulting string, inserting the $params in + // the appropriate places. + foreach ($matches[0] as $index => $pattern) + { + // Ensure that the param we're inserting matches + // the expected param type. + $pos = strpos($from, $pattern); + + if (preg_match('#^' . $pattern . '$#u', $params[$index])) + { + $from = substr_replace($from, $params[$index], $pos, strlen($pattern)); + } + else + { + throw RouterException::forInvalidParameterType(); + } + } + + return '/' . ltrim($from, '/'); + } + + //-------------------------------------------------------------------- + + /** + * Does the heavy lifting of creating an actual route. You must specify + * the request method(s) that this route will work for. They can be separated + * by a pipe character "|" if there is more than one. + * + * @param string $verb + * @param string $from + * @param string|array $to + * @param array|null $options + */ + protected function create(string $verb, string $from, $to, array $options = null) + { + $overwrite = false; + $prefix = is_null($this->group) ? '' : $this->group . '/'; + + $from = filter_var($prefix . $from, FILTER_SANITIZE_STRING); + + // While we want to add a route within a group of '/', + // it doesn't work with matching, so remove them... + if ($from !== '/') + { + $from = trim($from, '/'); + } + + $options = array_merge((array) $this->currentOptions, (array) $options); + + // Hostname limiting? + if (! empty($options['hostname'])) + { + // @todo determine if there's a way to whitelist hosts? + if (isset($_SERVER['HTTP_HOST']) && strtolower($_SERVER['HTTP_HOST']) !== strtolower($options['hostname'])) + { + return; + } + + $overwrite = true; + } + + // Limiting to subdomains? + else if (! empty($options['subdomain'])) + { + // If we don't match the current subdomain, then + // we don't need to add the route. + if (! $this->checkSubdomains($options['subdomain'])) + { + return; + } + + $overwrite = true; + } + + // Are we offsetting the binds? + // If so, take care of them here in one + // fell swoop. + if (isset($options['offset']) && is_string($to)) + { + // Get a constant string to work with. + $to = preg_replace('/(\$\d+)/', '$X', $to); + + for ($i = (int) $options['offset'] + 1; $i < (int) $options['offset'] + 7; $i ++) + { + $to = preg_replace_callback( + '/\$X/', function ($m) use ($i) { + return '$' . $i; + }, $to, 1 + ); + } + } + + // Replace our regex pattern placeholders with the actual thing + // so that the Router doesn't need to know about any of this. + foreach ($this->placeholders as $tag => $pattern) + { + $from = str_ireplace(':' . $tag, $pattern, $from); + } + + //If is redirect, No processing + if (! isset($options['redirect'])) + { + // If no namespace found, add the default namespace + if (is_string($to) && (strpos($to, '\\') === false || strpos($to, '\\') > 0)) + { + $namespace = $options['namespace'] ?? $this->defaultNamespace; + $to = trim($namespace, '\\') . '\\' . $to; + } + + // Always ensure that we escape our namespace so we're not pointing to + // \CodeIgniter\Routes\Controller::method. + if (is_string($to)) + { + $to = '\\' . ltrim($to, '\\'); + } + } + + $name = $options['as'] ?? $from; + + // Don't overwrite any existing 'froms' so that auto-discovered routes + // do not overwrite any app/Config/Routes settings. The app + // routes should always be the "source of truth". + // this works only because discovered routes are added just prior + // to attempting to route the request. + if (isset($this->routes[$verb][$name]) && ! $overwrite) + { + return; + } + + $this->routes[$verb][$name] = [ + 'route' => [$from => $to], + ]; + + $this->routesOptions[$from] = $options; + + // Is this a redirect? + if (isset($options['redirect']) && is_numeric($options['redirect'])) + { + $this->routes['*'][$name]['redirect'] = $options['redirect']; + } + } + + //-------------------------------------------------------------------- + + /** + * Compares the subdomain(s) passed in against the current subdomain + * on this page request. + * + * @param mixed $subdomains + * + * @return boolean + */ + private function checkSubdomains($subdomains): bool + { + // CLI calls can't be on subdomain. + if (! isset($_SERVER['HTTP_HOST'])) + { + return false; + } + + if (is_null($this->currentSubdomain)) + { + $this->currentSubdomain = $this->determineCurrentSubdomain(); + } + + if (! is_array($subdomains)) + { + $subdomains = [$subdomains]; + } + + // Routes can be limited to any sub-domain. In that case, though, + // it does require a sub-domain to be present. + if (! empty($this->currentSubdomain) && in_array('*', $subdomains)) + { + return true; + } + + return in_array($this->currentSubdomain, $subdomains, true); + } + + //-------------------------------------------------------------------- + + /** + * Examines the HTTP_HOST to get a best match for the subdomain. It + * won't be perfect, but should work for our needs. + * + * It's especially not perfect since it's possible to register a domain + * with a period (.) as part of the domain name. + * + * @return mixed + */ + private function determineCurrentSubdomain() + { + // We have to ensure that a scheme exists + // on the URL else parse_url will mis-interpret + // 'host' as the 'path'. + $url = $_SERVER['HTTP_HOST']; + if (strpos($url, 'http') !== 0) + { + $url = 'http://' . $url; + } + + $parsedUrl = parse_url($url); + + $host = explode('.', $parsedUrl['host']); + + if ($host[0] === 'www') + { + unset($host[0]); + } + + // Get rid of any domains, which will be the last + unset($host[count($host)]); + + // Account for .co.uk, .co.nz, etc. domains + if (end($host) === 'co') + { + $host = array_slice($host, 0, -1); + } + + // If we only have 1 part left, then we don't have a sub-domain. + if (count($host) === 1) + { + // Set it to false so we don't make it back here again. + return false; + } + + return array_shift($host); + } + + //-------------------------------------------------------------------- + + /** + * Reset the routes, so that a FeatureTestCase can provide the + * explicit ones needed for it. + */ + public function resetRoutes() + { + $this->routes = ['*' => []]; + foreach ($this->defaultHTTPMethods as $verb) + { + $this->routes[$verb] = []; + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Router/RouteCollectionInterface.php b/vendor/codeigniter4/framework/system/Router/RouteCollectionInterface.php new file mode 100644 index 0000000..b25e93d --- /dev/null +++ b/vendor/codeigniter4/framework/system/Router/RouteCollectionInterface.php @@ -0,0 +1,276 @@ + 'Controller::method/$1/$2' + * + * This method allows you to know the Controller and method + * and get the route that leads to it. + * + * // Equals 'path/$param1/$param2' + * reverseRoute('Controller::method', $param1, $param2); + * + * @param string $search + * @param array ...$params + * + * @return string|false + */ + public function reverseRoute(string $search, ...$params); + + //-------------------------------------------------------------------- + + /** + * Determines if the route is a redirecting route. + * + * @param string $from + * + * @return boolean + */ + public function isRedirect(string $from): bool; + + //-------------------------------------------------------------------- + + /** + * Grabs the HTTP status code from a redirecting Route. + * + * @param string $from + * + * @return integer + */ + public function getRedirectCode(string $from): int; + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Router/Router.php b/vendor/codeigniter4/framework/system/Router/Router.php new file mode 100644 index 0000000..3ef9150 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Router/Router.php @@ -0,0 +1,725 @@ +collection = $routes; + + $this->controller = $this->collection->getDefaultController(); + $this->method = $this->collection->getDefaultMethod(); + + $this->collection->setHTTPVerb($request->getMethod() ?? strtolower($_SERVER['REQUEST_METHOD'])); + } + + //-------------------------------------------------------------------- + + /** + * @param string|null $uri + * + * @return mixed|string + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \CodeIgniter\Exceptions\PageNotFoundException + */ + public function handle(string $uri = null) + { + $this->translateURIDashes = $this->collection->shouldTranslateURIDashes(); + + // If we cannot find a URI to match against, then + // everything runs off of it's default settings. + if ($uri === null || $uri === '') + { + return strpos($this->controller, '\\') === false + ? $this->collection->getDefaultNamespace() . $this->controller + : $this->controller; + } + + // Decode URL-encoded string + $uri = urldecode($uri); + + if ($this->checkRoutes($uri)) + { + if ($this->collection->isFiltered($this->matchedRoute[0])) + { + $this->filterInfo = $this->collection->getFilterForRoute($this->matchedRoute[0]); + } + + return $this->controller; + } + + // Still here? Then we can try to match the URI against + // Controllers/directories, but the application may not + // want this, like in the case of API's. + if (! $this->collection->shouldAutoRoute()) + { + throw new PageNotFoundException("Can't find a route for '{$uri}'."); + } + + $this->autoRoute($uri); + + return $this->controllerName(); + } + + //-------------------------------------------------------------------- + + /** + * Returns the filter info for the matched route, if any. + * + * @return string + */ + public function getFilter() + { + return $this->filterInfo; + } + + //-------------------------------------------------------------------- + + /** + * Returns the name of the matched controller. + * + * @return mixed + */ + public function controllerName() + { + return $this->translateURIDashes + ? str_replace('-', '_', $this->controller) + : $this->controller; + } + + //-------------------------------------------------------------------- + + /** + * Returns the name of the method to run in the + * chosen container. + * + * @return mixed + */ + public function methodName(): string + { + return $this->translateURIDashes + ? str_replace('-', '_', $this->method) + : $this->method; + } + + //-------------------------------------------------------------------- + + /** + * Returns the 404 Override settings from the Collection. + * If the override is a string, will split to controller/index array. + */ + public function get404Override() + { + $route = $this->collection->get404Override(); + + if (is_string($route)) + { + $routeArray = explode('::', $route); + + return [ + $routeArray[0], // Controller + $routeArray[1] ?? 'index', // Method + ]; + } + + if (is_callable($route)) + { + return $route; + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Returns the binds that have been matched and collected + * during the parsing process as an array, ready to send to + * instance->method(...$params). + * + * @return mixed + */ + public function params(): array + { + return $this->params; + } + + //-------------------------------------------------------------------- + + /** + * Returns the name of the sub-directory the controller is in, + * if any. Relative to APPPATH.'Controllers'. + * + * Only used when auto-routing is turned on. + * + * @return string + */ + public function directory(): string + { + return ! empty($this->directory) ? $this->directory : ''; + } + + //-------------------------------------------------------------------- + + /** + * Returns the routing information that was matched for this + * request, if a route was defined. + * + * @return array|null + */ + public function getMatchedRoute() + { + return $this->matchedRoute; + } + + //-------------------------------------------------------------------- + + /** + * Returns all options set for the matched route + * + * @return array|null + */ + public function getMatchedRouteOptions() + { + return $this->matchedRouteOptions; + } + + //-------------------------------------------------------------------- + + /** + * Sets the value that should be used to match the index.php file. Defaults + * to index.php but this allows you to modify it in case your are using + * something like mod_rewrite to remove the page. This allows you to set + * it a blank. + * + * @param $page + * + * @return mixed + */ + public function setIndexPage($page): self + { + $this->indexPage = $page; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Tells the system whether we should translate URI dashes or not + * in the URI from a dash to an underscore. + * + * @param boolean|false $val + * + * @return $this + */ + public function setTranslateURIDashes(bool $val = false): self + { + $this->translateURIDashes = $val; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns true/false based on whether the current route contained + * a {locale} placeholder. + * + * @return boolean + */ + public function hasLocale() + { + return (bool) $this->detectedLocale; + } + + //-------------------------------------------------------------------- + + /** + * Returns the detected locale, if any, or null. + * + * @return string + */ + public function getLocale() + { + return $this->detectedLocale; + } + + //-------------------------------------------------------------------- + + /** + * Compares the uri string against the routes that the + * RouteCollection class defined for us, attempting to find a match. + * This method will modify $this->controller, etal as needed. + * + * @param string $uri The URI path to compare against the routes + * + * @return boolean Whether the route was matched or not. + * @throws \CodeIgniter\Router\Exceptions\RedirectException + */ + protected function checkRoutes(string $uri): bool + { + $routes = $this->collection->getRoutes($this->collection->getHTTPVerb()); + + $uri = $uri === '/' + ? $uri + : ltrim($uri, '/ '); + + // Don't waste any time + if (empty($routes)) + { + return false; + } + + // Loop through the route array looking for wildcards + foreach ($routes as $key => $val) + { + $key = $key === '/' + ? $key + : ltrim($key, '/ '); + + $matchedKey = $key; + + // Are we dealing with a locale? + if (strpos($key, '{locale}') !== false) + { + $localeSegment = array_search('{locale}', preg_split('/[\/]*((^[a-zA-Z0-9])|\(([^()]*)\))*[\/]+/m', $key)); + + // Replace it with a regex so it + // will actually match. + $key = str_replace('/', '\/', $key); + $key = str_replace('{locale}', '[^\/]+', $key); + } + + // Does the RegEx match? + if (preg_match('#^' . $key . '$#u', $uri, $matches)) + { + // Is this route supposed to redirect to another? + if ($this->collection->isRedirect($key)) + { + throw new RedirectException(is_array($val) ? key($val) : $val, $this->collection->getRedirectCode($key)); + } + // Store our locale so CodeIgniter object can + // assign it to the Request. + if (isset($localeSegment)) + { + // The following may be inefficient, but doesn't upset NetBeans :-/ + $temp = (explode('/', $uri)); + $this->detectedLocale = $temp[$localeSegment]; + unset($localeSegment); + } + + // Are we using Closures? If so, then we need + // to collect the params into an array + // so it can be passed to the controller method later. + if (! is_string($val) && is_callable($val)) + { + $this->controller = $val; + + // Remove the original string from the matches array + array_shift($matches); + + $this->params = $matches; + + $this->matchedRoute = [ + $matchedKey, + $val, + ]; + + $this->matchedRouteOptions = $this->collection->getRoutesOptions($matchedKey); + + return true; + } + // Are we using the default method for back-references? + + // Support resource route when function with subdirectory + // ex: $routes->resource('Admin/Admins'); + if (strpos($val, '$') !== false && strpos($key, '(') !== false && strpos($key, '/') !== false) + { + $replacekey = str_replace('/(.*)', '', $key); + $val = preg_replace('#^' . $key . '$#u', $val, $uri); + $val = str_replace($replacekey, str_replace('/', '\\', $replacekey), $val); + } + elseif (strpos($val, '$') !== false && strpos($key, '(') !== false) + { + $val = preg_replace('#^' . $key . '$#u', $val, $uri); + } + elseif (strpos($val, '/') !== false) + { + [ + $controller, + $method, + ] = explode( '::', $val ); + + // Only replace slashes in the controller, not in the method. + $controller = str_replace('/', '\\', $controller); + + $val = $controller . '::' . $method; + } + + $this->setRequest(explode('/', $val)); + + $this->matchedRoute = [ + $matchedKey, + $val, + ]; + + $this->matchedRouteOptions = $this->collection->getRoutesOptions($matchedKey); + + return true; + } + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Attempts to match a URI path against Controllers and directories + * found in APPPATH/Controllers, to find a matching route. + * + * @param string $uri + */ + public function autoRoute(string $uri) + { + $segments = explode('/', $uri); + + $segments = $this->validateRequest($segments); + + // If we don't have any segments left - try the default controller; + // WARNING: Directories get shifted out of the segments array. + if (empty($segments)) + { + $this->setDefaultController(); + } + // If not empty, then the first segment should be the controller + else + { + $this->controller = ucfirst(array_shift($segments)); + } + + // Use the method name if it exists. + // If it doesn't, no biggie - the default method name + // has already been set. + if (! empty($segments)) + { + $this->method = array_shift($segments) ?: $this->method; + } + + if (! empty($segments)) + { + $this->params = $segments; + } + + $defaultNamespace = $this->collection->getDefaultNamespace(); + $controllerName = $this->controllerName(); + if ($this->collection->getHTTPVerb() !== 'cli') + { + $controller = '\\' . $defaultNamespace; + $controller .= $this->directory ? str_replace('/', '\\', $this->directory) : ''; + $controller .= $controllerName; + $controller = strtolower($controller); + $methodName = strtolower($this->methodName()); + + foreach ($this->collection->getRoutes('cli') as $route) + { + if (is_string($route)) + { + $route = strtolower($route); + if (strpos($route, $controller . '::' . $methodName) === 0) + { + throw new PageNotFoundException(); + } + + if ($route === $controller) + { + throw new PageNotFoundException(); + } + } + } + } + + // Load the file so that it's available for CodeIgniter. + $file = APPPATH . 'Controllers/' . $this->directory . $controllerName . '.php'; + if (is_file($file)) + { + include_once $file; + } + + // Ensure the controller stores the fully-qualified class name + // We have to check for a length over 1, since by default it will be '\' + if (strpos($this->controller, '\\') === false && strlen($defaultNamespace) > 1) + { + $this->controller = '\\' . ltrim(str_replace('/', '\\', $defaultNamespace . $this->directory . $controllerName), '\\'); + } + } + + //-------------------------------------------------------------------- + + /** + * Attempts to validate the URI request and determine the controller path. + * + * @param array $segments URI segments + * + * @return array URI segments + */ + protected function validateRequest(array $segments): array + { + $segments = array_filter($segments, function ($segment) { + return ! empty($segment) || ($segment !== '0' || $segment !== 0); + }); + $segments = array_values($segments); + + $c = count($segments); + $directory_override = isset($this->directory); + + // Loop through our segments and return as soon as a controller + // is found or when such a directory doesn't exist + while ($c-- > 0) + { + $test = $this->directory . ucfirst($this->translateURIDashes === true ? str_replace('-', '_', $segments[0]) : $segments[0]); + + if (! is_file(APPPATH . 'Controllers/' . $test . '.php') && $directory_override === false && is_dir(APPPATH . 'Controllers/' . $this->directory . ucfirst($segments[0]))) + { + $this->setDirectory(array_shift($segments), true); + continue; + } + + return $segments; + } + + // This means that all segments were actually directories + return $segments; + } + + //-------------------------------------------------------------------- + + /** + * Sets the sub-directory that the controller is in. + * + * @param string|null $dir + * @param boolean|false $append + */ + public function setDirectory(string $dir = null, bool $append = false) + { + if (empty($dir)) + { + $this->directory = null; + return; + } + + $dir = ucfirst($dir); + + if ($append !== true || empty($this->directory)) + { + $this->directory = str_replace('.', '', trim($dir, '/')) . '/'; + } + else + { + $this->directory .= str_replace('.', '', trim($dir, '/')) . '/'; + } + } + + //-------------------------------------------------------------------- + + /** + * Set request route + * + * Takes an array of URI segments as input and sets the class/method + * to be called. + * + * @param array $segments URI segments + */ + protected function setRequest(array $segments = []) + { + // If we don't have any segments - try the default controller; + if (empty($segments)) + { + $this->setDefaultController(); + + return; + } + + list($controller, $method) = array_pad(explode('::', $segments[0]), 2, null); + + $this->controller = $controller; + + // $this->method already contains the default method name, + // so don't overwrite it with emptiness. + if (! empty($method)) + { + $this->method = $method; + } + + array_shift($segments); + + $this->params = $segments; + } + + //-------------------------------------------------------------------- + + /** + * Sets the default controller based on the info set in the RouteCollection. + */ + protected function setDefaultController() + { + if (empty($this->controller)) + { + throw RouterException::forMissingDefaultRoute(); + } + + // Is the method being specified? + if (sscanf($this->controller, '%[^/]/%s', $class, $this->method) !== 2) + { + $this->method = 'index'; + } + + if (! is_file(APPPATH . 'Controllers/' . $this->directory . ucfirst($class) . '.php')) + { + return; + } + + $this->controller = ucfirst($class); + + log_message('info', 'Used the default controller.'); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Router/RouterInterface.php b/vendor/codeigniter4/framework/system/Router/RouterInterface.php new file mode 100644 index 0000000..46cb285 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Router/RouterInterface.php @@ -0,0 +1,115 @@ +method(...$params). + * + * @return mixed + */ + public function params(); + + //-------------------------------------------------------------------- + + /** + * Sets the value that should be used to match the index.php file. Defaults + * to index.php but this allows you to modify it in case your are using + * something like mod_rewrite to remove the page. This allows you to set + * it a blank. + * + * @param $page + * + * @return mixed + */ + public function setIndexPage($page); + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Security/Exceptions/SecurityException.php b/vendor/codeigniter4/framework/system/Security/Exceptions/SecurityException.php new file mode 100644 index 0000000..dda6a9d --- /dev/null +++ b/vendor/codeigniter4/framework/system/Security/Exceptions/SecurityException.php @@ -0,0 +1,12 @@ +', + '<', + '>', + "'", + '"', + '&', + '$', + '#', + '{', + '}', + '[', + ']', + '=', + ';', + '?', + '%20', + '%22', + '%3c', // < + '%253c', // < + '%3e', // > + '%0e', // > + '%28', // ( + '%29', // ) + '%2528', // ( + '%26', // & + '%24', // $ + '%3f', // ? + '%3b', // ; + '%3d', // = + ]; + + //-------------------------------------------------------------------- + + /** + * Security constructor. + * + * Stores our configuration and fires off the init() method to + * setup initial state. + * + * @param \Config\App $config + * + * @throws \Exception + */ + public function __construct($config) + { + // Store our CSRF-related settings + $this->CSRFExpire = $config->CSRFExpire; + $this->CSRFTokenName = $config->CSRFTokenName; + $this->CSRFHeaderName = $config->CSRFHeaderName; + $this->CSRFCookieName = $config->CSRFCookieName; + $this->CSRFRegenerate = $config->CSRFRegenerate; + + if (isset($config->cookiePrefix)) + { + $this->CSRFCookieName = $config->cookiePrefix . $this->CSRFCookieName; + } + + // Store cookie-related settings + $this->cookiePath = $config->cookiePath; + $this->cookieDomain = $config->cookieDomain; + $this->cookieSecure = $config->cookieSecure; + + $this->CSRFSetHash(); + + unset($config); + } + + //-------------------------------------------------------------------- + + /** + * CSRF Verify + * + * @param RequestInterface $request + * + * @return $this|false + * @throws \Exception + */ + public function CSRFVerify(RequestInterface $request) + { + // If it's not a POST request we will set the CSRF cookie + if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST') + { + return $this->CSRFSetCookie($request); + } + + // Do the tokens exist in _POST, HEADER or optionally php:://input - json data + $CSRFTokenValue = $_POST[$this->CSRFTokenName] ?? + (! is_null($request->getHeader($this->CSRFHeaderName)) && ! empty($request->getHeader($this->CSRFHeaderName)->getValue()) ? + $request->getHeader($this->CSRFHeaderName)->getValue() : + (! empty($request->getBody()) && ! empty($json = json_decode($request->getBody())) && json_last_error() === JSON_ERROR_NONE ? + ($json->{$this->CSRFTokenName} ?? null) : + null)); + + // Do the tokens exist in both the _POST/POSTed JSON and _COOKIE arrays? + if (! isset($CSRFTokenValue, $_COOKIE[$this->CSRFCookieName]) || $CSRFTokenValue !== $_COOKIE[$this->CSRFCookieName] + ) // Do the tokens match? + { + throw SecurityException::forDisallowedAction(); + } + + // We kill this since we're done and we don't want to pollute the _POST array + if (isset($_POST[$this->CSRFTokenName])) + { + unset($_POST[$this->CSRFTokenName]); + $request->setGlobal('post', $_POST); + } + // We kill this since we're done and we don't want to pollute the JSON data + elseif (isset($json->{$this->CSRFTokenName})) + { + unset($json->{$this->CSRFTokenName}); + $request->setBody(json_encode($json)); + } + + // Regenerate on every submission? + if ($this->CSRFRegenerate) + { + // Nothing should last forever + $this->CSRFHash = null; + unset($_COOKIE[$this->CSRFCookieName]); + } + + $this->CSRFSetHash(); + $this->CSRFSetCookie($request); + + log_message('info', 'CSRF token verified'); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * CSRF Set Cookie + * + * @codeCoverageIgnore + * + * @param RequestInterface|\CodeIgniter\HTTP\IncomingRequest $request + * + * @return Security|false + */ + public function CSRFSetCookie(RequestInterface $request) + { + $expire = time() + $this->CSRFExpire; + $secure_cookie = (bool) $this->cookieSecure; + + if ($secure_cookie && ! $request->isSecure()) + { + return false; + } + + setcookie( + $this->CSRFCookieName, $this->CSRFHash, $expire, $this->cookiePath, $this->cookieDomain, $secure_cookie, true // Enforce HTTP only cookie for security + ); + + log_message('info', 'CSRF cookie sent'); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the current CSRF Hash. + * + * @return string + */ + public function getCSRFHash(): string + { + return $this->CSRFHash; + } + + //-------------------------------------------------------------------- + + /** + * Returns the CSRF Token Name. + * + * @return string + */ + public function getCSRFTokenName(): string + { + return $this->CSRFTokenName; + } + + //-------------------------------------------------------------------- + + /** + * Sets the CSRF Hash and cookie. + * + * @return string + * @throws \Exception + */ + protected function CSRFSetHash(): string + { + if ($this->CSRFHash === null) + { + // If the cookie exists we will use its value. + // We don't necessarily want to regenerate it with + // each page load since a page could contain embedded + // sub-pages causing this feature to fail + if (isset($_COOKIE[$this->CSRFCookieName]) && is_string($_COOKIE[$this->CSRFCookieName]) && preg_match('#^[0-9a-f]{32}$#iS', $_COOKIE[$this->CSRFCookieName]) === 1 + ) + { + return $this->CSRFHash = $_COOKIE[$this->CSRFCookieName]; + } + + $rand = random_bytes(16); + $this->CSRFHash = bin2hex($rand); + } + + return $this->CSRFHash; + } + + //-------------------------------------------------------------------- + + /** + * Sanitize Filename + * + * Tries to sanitize filenames in order to prevent directory traversal attempts + * and other security threats, which is particularly useful for files that + * were supplied via user input. + * + * If it is acceptable for the user input to include relative paths, + * e.g. file/in/some/approved/folder.txt, you can set the second optional + * parameter, $relative_path to TRUE. + * + * @param string $str Input file name + * @param boolean $relative_path Whether to preserve paths + * + * @return string + */ + public function sanitizeFilename(string $str, bool $relative_path = false): string + { + $bad = $this->filenameBadChars; + + if (! $relative_path) + { + $bad[] = './'; + $bad[] = '/'; + } + + $str = remove_invisible_characters($str, false); + + do + { + $old = $str; + $str = str_replace($bad, '', $str); + } + while ($old !== $str); + + return stripslashes($str); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Session/Exceptions/SessionException.php b/vendor/codeigniter4/framework/system/Session/Exceptions/SessionException.php new file mode 100644 index 0000000..f4733c0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Exceptions/SessionException.php @@ -0,0 +1,32 @@ +cookiePrefix = $config->cookiePrefix; + $this->cookieDomain = $config->cookieDomain; + $this->cookiePath = $config->cookiePath; + $this->cookieSecure = $config->cookieSecure; + $this->cookieName = $config->sessionCookieName; + $this->matchIP = $config->sessionMatchIP; + $this->savePath = $config->sessionSavePath; + $this->ipAddress = $ipAddress; + } + + //-------------------------------------------------------------------- + + /** + * Internal method to force removal of a cookie by the client + * when session_destroy() is called. + * + * @return boolean + */ + protected function destroyCookie(): bool + { + return setcookie( + $this->cookieName, null, 1, $this->cookiePath, $this->cookieDomain, $this->cookieSecure, true + ); + } + + //-------------------------------------------------------------------- + + /** + * A dummy method allowing drivers with no locking functionality + * (databases other than PostgreSQL and MySQL) to act as if they + * do acquire a lock. + * + * @param string $sessionID + * + * @return boolean + */ + protected function lockSession(string $sessionID): bool + { + $this->lock = true; + return true; + } + + //-------------------------------------------------------------------- + + /** + * Releases the lock, if any. + * + * @return boolean + */ + protected function releaseLock(): bool + { + $this->lock = false; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Fail + * + * Drivers other than the 'files' one don't (need to) use the + * session.save_path INI setting, but that leads to confusing + * error messages emitted by PHP when open() or write() fail, + * as the message contains session.save_path ... + * To work around the problem, the drivers will call this method + * so that the INI is set just in time for the error message to + * be properly generated. + * + * @return boolean + */ + protected function fail(): bool + { + ini_set('session.save_path', $this->savePath); + + return false; + } +} diff --git a/vendor/codeigniter4/framework/system/Session/Handlers/DatabaseHandler.php b/vendor/codeigniter4/framework/system/Session/Handlers/DatabaseHandler.php new file mode 100644 index 0000000..71ecbde --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Handlers/DatabaseHandler.php @@ -0,0 +1,430 @@ +table = $config->sessionSavePath; + + if (empty($this->table)) + { + throw SessionException::forMissingDatabaseTable(); + } + + // Get DB Connection + $this->DBGroup = $config->sessionDBGroup ?? config(Database::class)->defaultGroup; + + $this->db = Database::connect($this->DBGroup); + + // Determine Database type + $driver = strtolower(get_class($this->db)); + if (strpos($driver, 'mysql') !== false) + { + $this->platform = 'mysql'; + } + elseif (strpos($driver, 'postgre') !== false) + { + $this->platform = 'postgre'; + } + } + + //-------------------------------------------------------------------- + + /** + * Open + * + * Ensures we have an initialized database connection. + * + * @param string $savePath Path to session files' directory + * @param string $name Session cookie name + * + * @return boolean + * @throws \Exception + */ + public function open($savePath, $name): bool + { + if (empty($this->db->connID)) + { + $this->db->initialize(); + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $sessionID Session ID + * + * @return string Serialized session data + */ + public function read($sessionID): string + { + if ($this->lockSession($sessionID) === false) + { + $this->fingerprint = md5(''); + return ''; + } + + // Needed by write() to detect session_regenerate_id() calls + if (is_null($this->sessionID)) + { + $this->sessionID = $sessionID; + } + + $builder = $this->db->table($this->table) + ->select('data') + ->where('id', $sessionID); + + if ($this->matchIP) + { + $builder = $builder->where('ip_address', $this->ipAddress); + } + + $result = $builder->get()->getRow(); + + if ($result === null) + { + // PHP7 will reuse the same SessionHandler object after + // ID regeneration, so we need to explicitly set this to + // FALSE instead of relying on the default ... + $this->rowExists = false; + $this->fingerprint = md5(''); + + return ''; + } + + // PostgreSQL's variant of a BLOB datatype is Bytea, which is a + // PITA to work with, so we use base64-encoded data in a TEXT + // field instead. + if (is_bool($result)) + { + $result = ''; + } + else + { + $result = ($this->platform === 'postgre') ? base64_decode(rtrim($result->data)) : $result->data; + } + + $this->fingerprint = md5($result); + $this->rowExists = true; + + return $result; + } + + //-------------------------------------------------------------------- + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $sessionID Session ID + * @param string $sessionData Serialized session data + * + * @return boolean + */ + public function write($sessionID, $sessionData): bool + { + if ($this->lock === false) + { + return $this->fail(); + } + + // Was the ID regenerated? + elseif ($sessionID !== $this->sessionID) + { + $this->rowExists = false; + $this->sessionID = $sessionID; + } + + if ($this->rowExists === false) + { + $insertData = [ + 'id' => $sessionID, + 'ip_address' => $this->ipAddress, + 'timestamp' => time(), + 'data' => $this->platform === 'postgre' ? base64_encode($sessionData) : $sessionData, + ]; + + if (! $this->db->table($this->table)->insert($insertData)) + { + return $this->fail(); + } + + $this->fingerprint = md5($sessionData); + $this->rowExists = true; + + return true; + } + + $builder = $this->db->table($this->table)->where('id', $sessionID); + + if ($this->matchIP) + { + $builder = $builder->where('ip_address', $this->ipAddress); + } + + $updateData = [ + 'timestamp' => time(), + ]; + + if ($this->fingerprint !== md5($sessionData)) + { + $updateData['data'] = ($this->platform === 'postgre') ? base64_encode($sessionData) : $sessionData; + } + + if (! $builder->update($updateData)) + { + return $this->fail(); + } + + $this->fingerprint = md5($sessionData); + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Close + * + * Releases locks and closes file descriptor. + * + * @return boolean + */ + public function close(): bool + { + return ($this->lock && ! $this->releaseLock()) ? $this->fail() : true; + } + + //-------------------------------------------------------------------- + + /** + * Destroy + * + * Destroys the current session. + * + * @param string $sessionID + * + * @return boolean + */ + public function destroy($sessionID): bool + { + if ($this->lock) + { + $builder = $this->db->table($this->table)->where('id', $sessionID); + + if ($this->matchIP) + { + $builder = $builder->where('ip_address', $this->ipAddress); + } + + if (! $builder->delete()) + { + return $this->fail(); + } + } + + if ($this->close()) + { + $this->destroyCookie(); + + return true; + } + + return $this->fail(); + } + + //-------------------------------------------------------------------- + + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param integer $maxlifetime Maximum lifetime of sessions + * + * @return boolean + */ + public function gc($maxlifetime): bool + { + return ($this->db->table($this->table)->delete('timestamp < ' . (time() - $maxlifetime))) ? true : $this->fail(); + } + + //-------------------------------------------------------------------- + + /** + * Lock the session. + * + * @param string $sessionID + * @return boolean + */ + protected function lockSession(string $sessionID): bool + { + if ($this->platform === 'mysql') + { + $arg = md5($sessionID . ($this->matchIP ? '_' . $this->ipAddress : '')); + if ($this->db->query("SELECT GET_LOCK('{$arg}', 300) AS ci_session_lock")->getRow()->ci_session_lock) + { + $this->lock = $arg; + return true; + } + + return $this->fail(); + } + elseif ($this->platform === 'postgre') + { + $arg = "hashtext('{$sessionID}')" . ($this->matchIP ? ", hashtext('{$this->ipAddress}')" : ''); + if ($this->db->simpleQuery("SELECT pg_advisory_lock({$arg})")) + { + $this->lock = $arg; + return true; + } + + return $this->fail(); + } + + // Unsupported DB? Let the parent handle the simplified version. + return parent::lockSession($sessionID); + } + + //-------------------------------------------------------------------- + + /** + * Releases the lock, if any. + * + * @return boolean + */ + protected function releaseLock(): bool + { + if (! $this->lock) + { + return true; + } + + if ($this->platform === 'mysql') + { + if ($this->db->query("SELECT RELEASE_LOCK('{$this->lock}') AS ci_session_lock")->getRow()->ci_session_lock) + { + $this->lock = false; + return true; + } + + return $this->fail(); + } + elseif ($this->platform === 'postgre') + { + if ($this->db->simpleQuery("SELECT pg_advisory_unlock({$this->lock})")) + { + $this->lock = false; + return true; + } + + return $this->fail(); + } + + // Unsupported DB? Let the parent handle the simple version. + return parent::releaseLock(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Session/Handlers/FileHandler.php b/vendor/codeigniter4/framework/system/Session/Handlers/FileHandler.php new file mode 100644 index 0000000..19fc57f --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Handlers/FileHandler.php @@ -0,0 +1,422 @@ +sessionSavePath)) + { + $this->savePath = rtrim($config->sessionSavePath, '/\\'); + ini_set('session.save_path', $config->sessionSavePath); + } + else + { + $sessionPath = rtrim(ini_get('session.save_path'), '/\\'); + + if (! $sessionPath) + { + $sessionPath = WRITEPATH . 'session'; + } + + $this->savePath = $sessionPath; + } + + $this->matchIP = $config->sessionMatchIP; + + $this->configureSessionIDRegex(); + } + + //-------------------------------------------------------------------- + + /** + * Open + * + * Sanitizes the save_path directory. + * + * @param string $savePath Path to session files' directory + * @param string $name Session cookie name + * + * @return boolean + * @throws \Exception + */ + public function open($savePath, $name): bool + { + if (! is_dir($savePath)) + { + if (! mkdir($savePath, 0700, true)) + { + throw SessionException::forInvalidSavePath($this->savePath); + } + } + elseif (! is_writable($savePath)) + { + throw SessionException::forWriteProtectedSavePath($this->savePath); + } + + $this->savePath = $savePath; + $this->filePath = $this->savePath . '/' + . $name // we'll use the session cookie name as a prefix to avoid collisions + . ($this->matchIP ? md5($this->ipAddress) : ''); + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $sessionID Session ID + * + * @return string Serialized session data + */ + public function read($sessionID): string + { + // This might seem weird, but PHP 5.6 introduced session_reset(), + // which re-reads session data + if ($this->fileHandle === null) + { + $this->fileNew = ! is_file($this->filePath . $sessionID); + + if (($this->fileHandle = fopen($this->filePath . $sessionID, 'c+b')) === false) + { + $this->logger->error("Session: Unable to open file '" . $this->filePath . $sessionID . "'."); + + return false; + } + + if (flock($this->fileHandle, LOCK_EX) === false) + { + $this->logger->error("Session: Unable to obtain lock for file '" . $this->filePath . $sessionID . "'."); + fclose($this->fileHandle); + $this->fileHandle = null; + + return false; + } + + // Needed by write() to detect session_regenerate_id() calls + if (is_null($this->sessionID)) + { + $this->sessionID = $sessionID; + } + + if ($this->fileNew) + { + chmod($this->filePath . $sessionID, 0600); + $this->fingerprint = md5(''); + + return ''; + } + } + else + { + rewind($this->fileHandle); + } + + $session_data = ''; + clearstatcache(); // Address https://github.com/codeigniter4/CodeIgniter4/issues/2056 + for ($read = 0, $length = filesize($this->filePath . $sessionID); $read < $length; $read += strlen($buffer)) + { + if (($buffer = fread($this->fileHandle, $length - $read)) === false) + { + break; + } + + $session_data .= $buffer; + } + + $this->fingerprint = md5($session_data); + + return $session_data; + } + + //-------------------------------------------------------------------- + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $sessionID Session ID + * @param string $sessionData Serialized session data + * + * @return boolean + */ + public function write($sessionID, $sessionData): bool + { + // If the two IDs don't match, we have a session_regenerate_id() call + if ($sessionID !== $this->sessionID) + { + $this->sessionID = $sessionID; + } + + if (! is_resource($this->fileHandle)) + { + return false; + } + elseif ($this->fingerprint === md5($sessionData)) + { + return ($this->fileNew) ? true : touch($this->filePath . $sessionID); + } + + if (! $this->fileNew) + { + ftruncate($this->fileHandle, 0); + rewind($this->fileHandle); + } + + if (($length = strlen($sessionData)) > 0) + { + for ($written = 0; $written < $length; $written += $result) + { + if (($result = fwrite($this->fileHandle, substr($sessionData, $written))) === false) + { + break; + } + } + + if (! is_int($result)) + { + $this->fingerprint = md5(substr($sessionData, 0, $written)); + $this->logger->error('Session: Unable to write data.'); + + return false; + } + } + + $this->fingerprint = md5($sessionData); + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Close + * + * Releases locks and closes file descriptor. + * + * @return boolean + */ + public function close(): bool + { + if (is_resource($this->fileHandle)) + { + flock($this->fileHandle, LOCK_UN); + fclose($this->fileHandle); + + $this->fileHandle = $this->fileNew = null; + + return true; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * + * @return boolean + */ + public function destroy($session_id): bool + { + if ($this->close()) + { + return is_file($this->filePath . $session_id) + ? (unlink($this->filePath . $session_id) && $this->destroyCookie()) : true; + } + elseif ($this->filePath !== null) + { + clearstatcache(); + + return is_file($this->filePath . $session_id) + ? (unlink($this->filePath . $session_id) && $this->destroyCookie()) : true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param integer $maxlifetime Maximum lifetime of sessions + * + * @return boolean + */ + public function gc($maxlifetime): bool + { + if (! is_dir($this->savePath) || ($directory = opendir($this->savePath)) === false) + { + $this->logger->debug("Session: Garbage collector couldn't list files under directory '" . $this->savePath . "'."); + + return false; + } + + $ts = time() - $maxlifetime; + + $pattern = $this->matchIP === true + ? '[0-9a-f]{32}' + : ''; + + $pattern = sprintf( + '#\A%s' . $pattern . $this->sessionIDRegex . '\z#', + preg_quote($this->cookieName) + ); + + while (($file = readdir($directory)) !== false) + { + // If the filename doesn't match this pattern, it's either not a session file or is not ours + if (! preg_match($pattern, $file) + || ! is_file($this->savePath . DIRECTORY_SEPARATOR . $file) + || ($mtime = filemtime($this->savePath . DIRECTORY_SEPARATOR . $file)) === false + || $mtime > $ts + ) + { + continue; + } + + unlink($this->savePath . DIRECTORY_SEPARATOR . $file); + } + + closedir($directory); + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Configure Session ID regular expression + */ + protected function configureSessionIDRegex() + { + $bitsPerCharacter = (int)ini_get('session.sid_bits_per_character'); + $SIDLength = (int)ini_get('session.sid_length'); + + if (($bits = $SIDLength * $bitsPerCharacter) < 160) + { + // Add as many more characters as necessary to reach at least 160 bits + $SIDLength += (int)ceil((160 % $bits) / $bitsPerCharacter); + ini_set('session.sid_length', $SIDLength); + } + + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 + switch ($bitsPerCharacter) + { + case 4: + $this->sessionIDRegex = '[0-9a-f]'; + break; + case 5: + $this->sessionIDRegex = '[0-9a-v]'; + break; + case 6: + $this->sessionIDRegex = '[0-9a-zA-Z,-]'; + break; + } + + $this->sessionIDRegex .= '{' . $SIDLength . '}'; + } +} diff --git a/vendor/codeigniter4/framework/system/Session/Handlers/MemcachedHandler.php b/vendor/codeigniter4/framework/system/Session/Handlers/MemcachedHandler.php new file mode 100644 index 0000000..f35405e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Handlers/MemcachedHandler.php @@ -0,0 +1,405 @@ +savePath)) + { + throw SessionException::forEmptySavepath(); + } + + if ($this->matchIP === true) + { + $this->keyPrefix .= $this->ipAddress . ':'; + } + + if (! empty($this->keyPrefix)) + { + ini_set('memcached.sess_prefix', $this->keyPrefix); + } + + $this->sessionExpiration = $config->sessionExpiration; + } + + //-------------------------------------------------------------------- + + /** + * Open + * + * Sanitizes save_path and initializes connections. + * + * @param string $save_path Server path(s) + * @param string $name Session cookie name, unused + * + * @return boolean + */ + public function open($save_path, $name): bool + { + $this->memcached = new \Memcached(); + $this->memcached->setOption(\Memcached::OPT_BINARY_PROTOCOL, true); // required for touch() usage + + $server_list = []; + + foreach ($this->memcached->getServerList() as $server) + { + $server_list[] = $server['host'] . ':' . $server['port']; + } + + if (! preg_match_all('#,?([^,:]+)\:(\d{1,5})(?:\:(\d+))?#', $this->savePath, $matches, PREG_SET_ORDER) + ) + { + $this->memcached = null; + $this->logger->error('Session: Invalid Memcached save path format: ' . $this->savePath); + + return false; + } + + foreach ($matches as $match) + { + // If Memcached already has this server (or if the port is invalid), skip it + if (in_array($match[1] . ':' . $match[2], $server_list, true)) + { + $this->logger->debug('Session: Memcached server pool already has ' . $match[1] . ':' . $match[2]); + continue; + } + + if (! $this->memcached->addServer($match[1], $match[2], $match[3] ?? 0)) + { + $this->logger->error('Could not add ' . $match[1] . ':' . $match[2] . ' to Memcached server pool.'); + } + else + { + $server_list[] = $match[1] . ':' . $match[2]; + } + } + + if (empty($server_list)) + { + $this->logger->error('Session: Memcached server pool is empty.'); + + return false; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $sessionID Session ID + * + * @return string Serialized session data + */ + public function read($sessionID): string + { + if (isset($this->memcached) && $this->lockSession($sessionID)) + { + // Needed by write() to detect session_regenerate_id() calls + if (is_null($this->sessionID)) + { + $this->sessionID = $sessionID; + } + + $session_data = (string) $this->memcached->get($this->keyPrefix . $sessionID); + $this->fingerprint = md5($session_data); + + return $session_data; + } + + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $sessionID Session ID + * @param string $sessionData Serialized session data + * + * @return boolean + */ + public function write($sessionID, $sessionData): bool + { + if (! isset($this->memcached)) + { + return false; + } + // Was the ID regenerated? + elseif ($sessionID !== $this->sessionID) + { + if (! $this->releaseLock() || ! $this->lockSession($sessionID)) + { + return false; + } + + $this->fingerprint = md5(''); + $this->sessionID = $sessionID; + } + + if (isset($this->lockKey)) + { + $this->memcached->replace($this->lockKey, time(), 300); + + if ($this->fingerprint !== ($fingerprint = md5($sessionData))) + { + if ($this->memcached->set($this->keyPrefix . $sessionID, $sessionData, $this->sessionExpiration)) + { + $this->fingerprint = $fingerprint; + + return true; + } + + return false; + } + + return $this->memcached->touch($this->keyPrefix . $sessionID, $this->sessionExpiration); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Close + * + * Releases locks and closes connection. + * + * @return boolean + */ + public function close(): bool + { + if (isset($this->memcached)) + { + isset($this->lockKey) && $this->memcached->delete($this->lockKey); + + if (! $this->memcached->quit()) + { + return false; + } + + $this->memcached = null; + + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Destroy + * + * Destroys the current session. + * + * @param string $session_id Session ID + * + * @return boolean + */ + public function destroy($session_id): bool + { + if (isset($this->memcached, $this->lockKey)) + { + $this->memcached->delete($this->keyPrefix . $session_id); + + return $this->destroyCookie(); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param integer $maxlifetime Maximum lifetime of sessions + * + * @return boolean + */ + public function gc($maxlifetime): bool + { + // Not necessary, Memcached takes care of that. + return true; + } + + //-------------------------------------------------------------------- + + /** + * Get lock + * + * Acquires an (emulated) lock. + * + * @param string $sessionID Session ID + * + * @return boolean + */ + protected function lockSession(string $sessionID): bool + { + if (isset($this->lockKey)) + { + return $this->memcached->replace($this->lockKey, time(), 300); + } + + // 30 attempts to obtain a lock, in case another request already has it + $lock_key = $this->keyPrefix . $sessionID . ':lock'; + $attempt = 0; + + do + { + if ($this->memcached->get($lock_key)) + { + sleep(1); + continue; + } + + if (! $this->memcached->set($lock_key, time(), 300)) + { + $this->logger->error('Session: Error while trying to obtain lock for ' . $this->keyPrefix . $sessionID); + + return false; + } + + $this->lockKey = $lock_key; + break; + } + while (++ $attempt < 30); + + if ($attempt === 30) + { + $this->logger->error('Session: Unable to obtain lock for ' . $this->keyPrefix . $sessionID . ' after 30 attempts, aborting.'); + + return false; + } + + $this->lock = true; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Release lock + * + * Releases a previously acquired lock + * + * @return boolean + */ + protected function releaseLock(): bool + { + if (isset($this->memcached, $this->lockKey) && $this->lock) + { + if (! $this->memcached->delete($this->lockKey) && + $this->memcached->getResultCode() !== \Memcached::RES_NOTFOUND + ) + { + $this->logger->error('Session: Error while trying to free lock for ' . $this->lockKey); + + return false; + } + + $this->lockKey = null; + $this->lock = false; + } + + return true; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Session/Handlers/RedisHandler.php b/vendor/codeigniter4/framework/system/Session/Handlers/RedisHandler.php new file mode 100644 index 0000000..a6fcb33 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Handlers/RedisHandler.php @@ -0,0 +1,424 @@ +savePath)) + { + throw SessionException::forEmptySavepath(); + } + elseif (preg_match('#(?:tcp://)?([^:?]+)(?:\:(\d+))?(\?.+)?#', $this->savePath, $matches)) + { + isset($matches[3]) || $matches[3] = ''; // Just to avoid undefined index notices below + + $this->savePath = [ + 'host' => $matches[1], + 'port' => empty($matches[2]) ? null : $matches[2], + 'password' => preg_match('#auth=([^\s&]+)#', $matches[3], $match) ? $match[1] : null, + 'database' => preg_match('#database=(\d+)#', $matches[3], $match) ? (int) $match[1] : null, + 'timeout' => preg_match('#timeout=(\d+\.\d+)#', $matches[3], $match) ? (float) $match[1] : null, + ]; + + preg_match('#prefix=([^\s&]+)#', $matches[3], $match) && $this->keyPrefix = $match[1]; + } + else + { + throw SessionException::forInvalidSavePathFormat($this->savePath); + } + + if ($this->matchIP === true) + { + $this->keyPrefix .= $this->ipAddress . ':'; + } + + $this->sessionExpiration = empty($config->sessionExpiration) + ? (int) ini_get('session.gc_maxlifetime') + : (int) $config->sessionExpiration; + } + + //-------------------------------------------------------------------- + + /** + * Open + * + * Sanitizes save_path and initializes connection. + * + * @param string $save_path Server path + * @param string $name Session cookie name, unused + * @return boolean + */ + public function open($save_path, $name): bool + { + if (empty($this->savePath)) + { + return false; + } + + $redis = new \Redis(); + + if (! $redis->connect($this->savePath['host'], $this->savePath['port'], $this->savePath['timeout'])) + { + $this->logger->error('Session: Unable to connect to Redis with the configured settings.'); + } + elseif (isset($this->savePath['password']) && ! $redis->auth($this->savePath['password'])) + { + $this->logger->error('Session: Unable to authenticate to Redis instance.'); + } + elseif (isset($this->savePath['database']) && ! $redis->select($this->savePath['database'])) + { + $this->logger->error('Session: Unable to select Redis database with index ' . $this->savePath['database']); + } + else + { + $this->redis = $redis; + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Read + * + * Reads session data and acquires a lock + * + * @param string $sessionID Session ID + * + * @return string|false Serialized session data + */ + public function read($sessionID): string + { + if (isset($this->redis) && $this->lockSession($sessionID)) + { + // Needed by write() to detect session_regenerate_id() calls + if (is_null($this->sessionID)) + { + $this->sessionID = $sessionID; + } + + $session_data = $this->redis->get($this->keyPrefix . $sessionID); + is_string($session_data) ? $this->keyExists = true : $session_data = ''; + + $this->fingerprint = md5($session_data); + + return $session_data; + } + + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Write + * + * Writes (create / update) session data + * + * @param string $sessionID Session ID + * @param string $sessionData Serialized session data + * + * @return boolean + */ + public function write($sessionID, $sessionData): bool + { + if (! isset($this->redis)) + { + return false; + } + // Was the ID regenerated? + elseif ($sessionID !== $this->sessionID) + { + if (! $this->releaseLock() || ! $this->lockSession($sessionID)) + { + return false; + } + + $this->keyExists = false; + $this->sessionID = $sessionID; + } + + if (isset($this->lockKey)) + { + $this->redis->expire($this->lockKey, 300); + + if ($this->fingerprint !== ($fingerprint = md5($sessionData)) || $this->keyExists === false) + { + if ($this->redis->set($this->keyPrefix . $sessionID, $sessionData, $this->sessionExpiration)) + { + $this->fingerprint = $fingerprint; + $this->keyExists = true; + return true; + } + + return false; + } + + return $this->redis->expire($this->keyPrefix . $sessionID, $this->sessionExpiration); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Close + * + * Releases locks and closes connection. + * + * @return boolean + */ + public function close(): bool + { + if (isset($this->redis)) + { + try + { + $ping_reply = $this->redis->ping(); + if (($ping_reply === true) || ($ping_reply === '+PONG')) + { + isset($this->lockKey) && $this->redis->del($this->lockKey); + + if (! $this->redis->close()) + { + return false; + } + } + } + catch (\RedisException $e) + { + $this->logger->error('Session: Got RedisException on close(): ' . $e->getMessage()); + } + + $this->redis = null; + + return true; + } + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Destroy + * + * Destroys the current session. + * + * @param string $sessionID + * + * @return boolean + */ + public function destroy($sessionID): bool + { + if (isset($this->redis, $this->lockKey)) + { + if (($result = $this->redis->del($this->keyPrefix . $sessionID)) !== 1) + { + $this->logger->debug('Session: Redis::del() expected to return 1, got ' . var_export($result, true) . ' instead.'); + } + + return $this->destroyCookie(); + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Garbage Collector + * + * Deletes expired sessions + * + * @param integer $maxlifetime Maximum lifetime of sessions + * @return boolean + */ + public function gc($maxlifetime): bool + { + // Not necessary, Redis takes care of that. + return true; + } + + //-------------------------------------------------------------------- + + /** + * Get lock + * + * Acquires an (emulated) lock. + * + * @param string $sessionID Session ID + * + * @return boolean + */ + protected function lockSession(string $sessionID): bool + { + // PHP 7 reuses the SessionHandler object on regeneration, + // so we need to check here if the lock key is for the + // correct session ID. + if ($this->lockKey === $this->keyPrefix . $sessionID . ':lock') + { + return $this->redis->expire($this->lockKey, 300); + } + + // 30 attempts to obtain a lock, in case another request already has it + $lock_key = $this->keyPrefix . $sessionID . ':lock'; + $attempt = 0; + + do + { + if (($ttl = $this->redis->ttl($lock_key)) > 0) + { + sleep(1); + continue; + } + + if (! $this->redis->setex($lock_key, 300, time())) + { + $this->logger->error('Session: Error while trying to obtain lock for ' . $this->keyPrefix . $sessionID); + return false; + } + + $this->lockKey = $lock_key; + break; + } + while (++ $attempt < 30); + + if ($attempt === 30) + { + log_message('error', 'Session: Unable to obtain lock for ' . $this->keyPrefix . $sessionID . ' after 30 attempts, aborting.'); + return false; + } + elseif ($ttl === -1) + { + log_message('debug', 'Session: Lock for ' . $this->keyPrefix . $sessionID . ' had no TTL, overriding.'); + } + + $this->lock = true; + return true; + } + + //-------------------------------------------------------------------- + + /** + * Release lock + * + * Releases a previously acquired lock + * + * @return boolean + */ + protected function releaseLock(): bool + { + if (isset($this->redis, $this->lockKey) && $this->lock) + { + if (! $this->redis->del($this->lockKey)) + { + $this->logger->error('Session: Error while trying to free lock for ' . $this->lockKey); + return false; + } + + $this->lockKey = null; + $this->lock = false; + } + + return true; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Session/Session.php b/vendor/codeigniter4/framework/system/Session/Session.php new file mode 100644 index 0000000..d925bd7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/Session.php @@ -0,0 +1,1023 @@ +driver = $driver; + + $this->sessionDriverName = $config->sessionDriver; + $this->sessionCookieName = $config->sessionCookieName; + $this->sessionExpiration = $config->sessionExpiration; + $this->sessionSavePath = $config->sessionSavePath; + $this->sessionMatchIP = $config->sessionMatchIP; + $this->sessionTimeToUpdate = $config->sessionTimeToUpdate; + $this->sessionRegenerateDestroy = $config->sessionRegenerateDestroy; + + $this->cookieDomain = $config->cookieDomain; + $this->cookiePath = $config->cookiePath; + $this->cookieSecure = $config->cookieSecure; + + helper('array'); + } + + //-------------------------------------------------------------------- + + /** + * Initialize the session container and starts up the session. + * + * @return mixed + */ + public function start() + { + if (is_cli() && ENVIRONMENT !== 'testing') + { + // @codeCoverageIgnoreStart + $this->logger->debug('Session: Initialization under CLI aborted.'); + + return; + // @codeCoverageIgnoreEnd + } + elseif ((bool) ini_get('session.auto_start')) + { + $this->logger->error('Session: session.auto_start is enabled in php.ini. Aborting.'); + + return; + } + elseif (session_status() === PHP_SESSION_ACTIVE) + { + $this->logger->warning('Session: Sessions is enabled, and one exists.Please don\'t $session->start();'); + + return; + } + + if (! $this->driver instanceof \SessionHandlerInterface) + { + $this->logger->error("Session: Handler '" . $this->driver . + "' doesn't implement SessionHandlerInterface. Aborting."); + } + + $this->configure(); + + $this->setSaveHandler(); + + // Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers + if (isset($_COOKIE[$this->sessionCookieName]) && ( + ! is_string($_COOKIE[$this->sessionCookieName]) || ! preg_match('#\A' . $this->sidRegexp . '\z#', $_COOKIE[$this->sessionCookieName]) + ) + ) + { + unset($_COOKIE[$this->sessionCookieName]); + } + + $this->startSession(); + + // Is session ID auto-regeneration configured? (ignoring ajax requests) + if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) || + strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest') && ($regenerate_time = $this->sessionTimeToUpdate) > 0 + ) + { + if (! isset($_SESSION['__ci_last_regenerate'])) + { + $_SESSION['__ci_last_regenerate'] = time(); + } + elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time)) + { + $this->regenerate((bool) $this->sessionRegenerateDestroy); + } + } + // Another work-around ... PHP doesn't seem to send the session cookie + // unless it is being currently created or regenerated + elseif (isset($_COOKIE[$this->sessionCookieName]) && $_COOKIE[$this->sessionCookieName] === session_id()) + { + $this->setCookie(); + } + + $this->initVars(); + + $this->logger->info("Session: Class initialized using '" . $this->sessionDriverName . "' driver."); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Does a full stop of the session: + * + * - destroys the session + * - unsets the session id + * - destroys the session cookie + */ + public function stop() + { + setcookie( + $this->sessionCookieName, session_id(), 1, $this->cookiePath, $this->cookieDomain, $this->cookieSecure, true + ); + + session_regenerate_id(true); + } + + //-------------------------------------------------------------------- + + /** + * Configuration. + * + * Handle input binds and configuration defaults. + */ + protected function configure() + { + if (empty($this->sessionCookieName)) + { + $this->sessionCookieName = ini_get('session.name'); + } + else + { + ini_set('session.name', $this->sessionCookieName); + } + + session_set_cookie_params( + $this->sessionExpiration, $this->cookiePath, $this->cookieDomain, $this->cookieSecure, true // HTTP only; Yes, this is intentional and not configurable for security reasons. + ); + + //if (empty($this->sessionExpiration)) + if (! isset($this->sessionExpiration)) + { + $this->sessionExpiration = (int) ini_get('session.gc_maxlifetime'); + } + else + { + ini_set('session.gc_maxlifetime', (int) $this->sessionExpiration); + } + + if (! empty($this->sessionSavePath)) + { + ini_set('session.save_path', $this->sessionSavePath); + } + + // Security is king + ini_set('session.use_trans_sid', 0); + ini_set('session.use_strict_mode', 1); + ini_set('session.use_cookies', 1); + ini_set('session.use_only_cookies', 1); + + $this->configureSidLength(); + } + + // ------------------------------------------------------------------------ + + /** + * Configure session ID length + * + * To make life easier, we used to force SHA-1 and 4 bits per + * character on everyone. And of course, someone was unhappy. + * + * Then PHP 7.1 broke backwards-compatibility because ext/session + * is such a mess that nobody wants to touch it with a pole stick, + * and the one guy who does, nobody has the energy to argue with. + * + * So we were forced to make changes, and OF COURSE something was + * going to break and now we have this pile of shit. -- Narf + * + * @return void + */ + protected function configureSidLength() + { + $bits_per_character = (int) (ini_get('session.sid_bits_per_character') !== false + ? ini_get('session.sid_bits_per_character') + : 4); + $sid_length = (int) (ini_get('session.sid_length') !== false + ? ini_get('session.sid_length') + : 40); + if (($sid_length * $bits_per_character) < 160) + { + $bits = ($sid_length * $bits_per_character); + // Add as many more characters as necessary to reach at least 160 bits + $sid_length += (int) ceil((160 % $bits) / $bits_per_character); + ini_set('session.sid_length', $sid_length); + } + + // Yes, 4,5,6 are the only known possible values as of 2016-10-27 + switch ($bits_per_character) + { + case 4: + $this->sidRegexp = '[0-9a-f]'; + break; + case 5: + $this->sidRegexp = '[0-9a-v]'; + break; + case 6: + $this->sidRegexp = '[0-9a-zA-Z,-]'; + break; + } + + $this->sidRegexp .= '{' . $sid_length . '}'; + } + + //-------------------------------------------------------------------- + + /** + * Handle temporary variables + * + * Clears old "flash" data, marks the new one for deletion and handles + * "temp" data deletion. + */ + protected function initVars() + { + if (empty($_SESSION['__ci_vars'])) + { + return; + } + + $current_time = time(); + + foreach ($_SESSION['__ci_vars'] as $key => &$value) + { + if ($value === 'new') + { + $_SESSION['__ci_vars'][$key] = 'old'; + } + // Hacky, but 'old' will (implicitly) always be less than time() ;) + // DO NOT move this above the 'new' check! + elseif ($value < $current_time) + { + unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]); + } + } + + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Session Utility Methods + //-------------------------------------------------------------------- + + /** + * Regenerates the session ID. + * + * @param boolean $destroy Should old session data be destroyed? + */ + public function regenerate(bool $destroy = false) + { + $_SESSION['__ci_last_regenerate'] = time(); + session_regenerate_id($destroy); + } + + //-------------------------------------------------------------------- + + /** + * Destroys the current session. + */ + public function destroy() + { + session_destroy(); + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Basic Setters and Getters + //-------------------------------------------------------------------- + + /** + * Sets user data into the session. + * + * If $data is a string, then it is interpreted as a session property + * key, and $value is expected to be non-null. + * + * If $data is an array, it is expected to be an array of key/value pairs + * to be set as session properties. + * + * @param string|array $data Property name or associative array of properties + * @param string|array $value Property value if single key provided + */ + public function set($data, $value = null) + { + if (is_array($data)) + { + foreach ($data as $key => &$value) + { + if (is_int($key)) + { + $_SESSION[$value] = null; + } + else + { + $_SESSION[$key] = $value; + } + } + + return; + } + + $_SESSION[$data] = $value; + } + + //-------------------------------------------------------------------- + + /** + * Get user data that has been set in the session. + * + * If the property exists as "normal", returns it. + * Otherwise, returns an array of any temp or flash data values with the + * property key. + * + * Replaces the legacy method $session->userdata(); + * + * @param string $key Identifier of the session property to retrieve + * @return array|null The property value(s) + */ + public function get(string $key = null) + { + if (! empty($key) && (! is_null($value = isset($_SESSION[$key]) ? $_SESSION[$key] : null) || ! is_null($value = dot_array_search($key, $_SESSION ?? [])))) + { + return $value; + } + elseif (empty($_SESSION)) + { + return $key === null ? [] : null; + } + + if (! empty($key)) + { + return null; + } + + $userdata = []; + $_exclude = array_merge( + ['__ci_vars'], $this->getFlashKeys(), $this->getTempKeys() + ); + + $keys = array_keys($_SESSION); + foreach ($keys as $key) + { + if (! in_array($key, $_exclude, true)) + { + $userdata[$key] = $_SESSION[$key]; + } + } + + return $userdata; + } + + //-------------------------------------------------------------------- + + /** + * Returns whether an index exists in the session array. + * + * @param string $key Identifier of the session property we are interested in. + * + * @return boolean + */ + public function has(string $key): bool + { + return isset($_SESSION[$key]); + } + + //-------------------------------------------------------------------- + + /** + * Push new value onto session value that is array. + * + * @param string $key Identifier of the session property we are interested in. + * @param array $data value to be pushed to existing session key. + * + * @return void + */ + public function push(string $key, array $data) + { + if ($this->has($key) && is_array($value = $this->get($key))) + { + $this->set($key, array_merge($value, $data)); + } + } + + //-------------------------------------------------------------------- + + /** + * Remove one or more session properties. + * + * If $key is an array, it is interpreted as an array of string property + * identifiers to remove. Otherwise, it is interpreted as the identifier + * of a specific session property to remove. + * + * @param string|array $key Identifier of the session property or properties to remove. + */ + public function remove($key) + { + if (is_array($key)) + { + foreach ($key as $k) + { + unset($_SESSION[$k]); + } + + return; + } + + unset($_SESSION[$key]); + } + + //-------------------------------------------------------------------- + + /** + * Magic method to set variables in the session by simply calling + * $session->foo = bar; + * + * @param string $key Identifier of the session property to set. + * @param string|array $value + */ + public function __set(string $key, $value) + { + $_SESSION[$key] = $value; + } + + //-------------------------------------------------------------------- + + /** + * Magic method to get session variables by simply calling + * $foo = $session->foo; + * + * @param string $key Identifier of the session property to remove. + * + * @return null|string + */ + public function __get(string $key) + { + // Note: Keep this order the same, just in case somebody wants to + // use 'session_id' as a session data key, for whatever reason + if (isset($_SESSION[$key])) + { + return $_SESSION[$key]; + } + elseif ($key === 'session_id') + { + return session_id(); + } + + return null; + } + + //-------------------------------------------------------------------- + + /** + * Magic method to check for session variables. + * Different from has() in that it will validate 'session_id' as well. + * Mostly used by internal PHP functions, users should stick to has() + * + * @param string $key Identifier of the session property to remove. + * + * @return boolean + */ + public function __isset(string $key): bool + { + return isset($_SESSION[$key]) || ($key === 'session_id'); + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Flash Data Methods + //-------------------------------------------------------------------- + + /** + * Sets data into the session that will only last for a single request. + * Perfect for use with single-use status update messages. + * + * If $data is an array, it is interpreted as an associative array of + * key/value pairs for flashdata properties. + * Otherwise, it is interpreted as the identifier of a specific + * flashdata property, with $value containing the property value. + * + * @param array|string $data Property identifier or associative array of properties + * @param string|array $value Property value if $data is a scalar + */ + public function setFlashdata($data, $value = null) + { + $this->set($data, $value); + $this->markAsFlashdata(is_array($data) ? array_keys($data) : $data); + } + + //-------------------------------------------------------------------- + + /** + * Retrieve one or more items of flash data from the session. + * + * If the item key is null, return all flashdata. + * + * @param string $key Property identifier + * @return array|null The requested property value, or an associative array of them + */ + public function getFlashdata(string $key = null) + { + if (isset($key)) + { + return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && + ! is_int($_SESSION['__ci_vars'][$key])) ? $_SESSION[$key] : null; + } + + $flashdata = []; + + if (! empty($_SESSION['__ci_vars'])) + { + foreach ($_SESSION['__ci_vars'] as $key => &$value) + { + is_int($value) || $flashdata[$key] = $_SESSION[$key]; + } + } + + return $flashdata; + } + + //-------------------------------------------------------------------- + + /** + * Keeps a single piece of flash data alive for one more request. + * + * @param array|string $key Property identifier or array of them + */ + public function keepFlashdata($key) + { + $this->markAsFlashdata($key); + } + + //-------------------------------------------------------------------- + + /** + * Mark a session property or properties as flashdata. + * + * @param array|string $key Property identifier or array of them + * + * @return boolean False if any of the properties are not already set + */ + public function markAsFlashdata($key): bool + { + if (is_array($key)) + { + foreach ($key as $sessionKey) + { + if (! isset($_SESSION[$sessionKey])) + { + return false; + } + } + + $new = array_fill_keys($key, 'new'); + + $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) ? array_merge($_SESSION['__ci_vars'], $new) : $new; + + return true; + } + + if (! isset($_SESSION[$key])) + { + return false; + } + + $_SESSION['__ci_vars'][$key] = 'new'; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Unmark data in the session as flashdata. + * + * @param mixed $key Property identifier or array of them + */ + public function unmarkFlashdata($key) + { + if (empty($_SESSION['__ci_vars'])) + { + return; + } + + is_array($key) || $key = [$key]; + + foreach ($key as $k) + { + if (isset($_SESSION['__ci_vars'][$k]) && ! is_int($_SESSION['__ci_vars'][$k])) + { + unset($_SESSION['__ci_vars'][$k]); + } + } + + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } + } + + //-------------------------------------------------------------------- + + /** + * Retrieve all of the keys for session data marked as flashdata. + * + * @return array The property names of all flashdata + */ + public function getFlashKeys(): array + { + if (! isset($_SESSION['__ci_vars'])) + { + return []; + } + + $keys = []; + foreach (array_keys($_SESSION['__ci_vars']) as $key) + { + is_int($_SESSION['__ci_vars'][$key]) || $keys[] = $key; + } + + return $keys; + } + + //-------------------------------------------------------------------- + //-------------------------------------------------------------------- + // Temp Data Methods + //-------------------------------------------------------------------- + + /** + * Sets new data into the session, and marks it as temporary data + * with a set lifespan. + * + * @param string|array $data Session data key or associative array of items + * @param null $value Value to store + * @param integer $ttl Time-to-live in seconds + */ + public function setTempdata($data, $value = null, int $ttl = 300) + { + $this->set($data, $value); + $this->markAsTempdata($data, $ttl); + } + + //-------------------------------------------------------------------- + + /** + * Returns either a single piece of tempdata, or all temp data currently + * in the session. + * + * @param string $key Session data key + * @return mixed Session data value or null if not found. + */ + public function getTempdata(string $key = null) + { + if (isset($key)) + { + return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && + is_int($_SESSION['__ci_vars'][$key])) ? $_SESSION[$key] : null; + } + + $tempdata = []; + + if (! empty($_SESSION['__ci_vars'])) + { + foreach ($_SESSION['__ci_vars'] as $key => &$value) + { + is_int($value) && $tempdata[$key] = $_SESSION[$key]; + } + } + + return $tempdata; + } + + //-------------------------------------------------------------------- + + /** + * Removes a single piece of temporary data from the session. + * + * @param string $key Session data key + */ + public function removeTempdata(string $key) + { + $this->unmarkTempdata($key); + unset($_SESSION[$key]); + } + + //-------------------------------------------------------------------- + + /** + * Mark one of more pieces of data as being temporary, meaning that + * it has a set lifespan within the session. + * + * @param string|array $key Property identifier or array of them + * @param integer $ttl Time to live, in seconds + * + * @return boolean False if any of the properties were not set + */ + public function markAsTempdata($key, int $ttl = 300): bool + { + $ttl += time(); + + if (is_array($key)) + { + $temp = []; + + foreach ($key as $k => $v) + { + // Do we have a key => ttl pair, or just a key? + if (is_int($k)) + { + $k = $v; + $v = $ttl; + } + elseif (is_string($v)) + { + $v = time() + $ttl; + } + else + { + $v += time(); + } + + if (! array_key_exists($k, $_SESSION)) + { + return false; + } + + $temp[$k] = $v; + } + + $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars']) ? array_merge($_SESSION['__ci_vars'], $temp) : $temp; + + return true; + } + + if (! isset($_SESSION[$key])) + { + return false; + } + + $_SESSION['__ci_vars'][$key] = $ttl; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Unmarks temporary data in the session, effectively removing its + * lifespan and allowing it to live as long as the session does. + * + * @param string|array $key Property identifier or array of them + */ + public function unmarkTempdata($key) + { + if (empty($_SESSION['__ci_vars'])) + { + return; + } + + is_array($key) || $key = [$key]; + + foreach ($key as $k) + { + if (isset($_SESSION['__ci_vars'][$k]) && is_int($_SESSION['__ci_vars'][$k])) + { + unset($_SESSION['__ci_vars'][$k]); + } + } + + if (empty($_SESSION['__ci_vars'])) + { + unset($_SESSION['__ci_vars']); + } + } + + //-------------------------------------------------------------------- + + /** + * Retrieve the keys of all session data that have been marked as temporary data. + * + * @return array + */ + public function getTempKeys(): array + { + if (! isset($_SESSION['__ci_vars'])) + { + return []; + } + + $keys = []; + foreach (array_keys($_SESSION['__ci_vars']) as $key) + { + is_int($_SESSION['__ci_vars'][$key]) && $keys[] = $key; + } + + return $keys; + } + + //-------------------------------------------------------------------- + + /** + * Sets the driver as the session handler in PHP. + * Extracted for easier testing. + */ + protected function setSaveHandler() + { + session_set_save_handler($this->driver, true); + } + + //-------------------------------------------------------------------- + + /** + * Starts the session. + * Extracted for testing reasons. + */ + protected function startSession() + { + if (ENVIRONMENT === 'testing') + { + $_SESSION = []; + return; + } + + // @codeCoverageIgnoreStart + session_start(); + // @codeCoverageIgnoreEnd + } + + //-------------------------------------------------------------------- + + /** + * Takes care of setting the cookie on the client side. + * Extracted for testing reasons. + */ + protected function setCookie() + { + setcookie( + $this->sessionCookieName, session_id(), (empty($this->sessionExpiration) ? 0 : time() + $this->sessionExpiration), $this->cookiePath, $this->cookieDomain, $this->cookieSecure, true + ); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Session/SessionInterface.php b/vendor/codeigniter4/framework/system/Session/SessionInterface.php new file mode 100644 index 0000000..e098514 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Session/SessionInterface.php @@ -0,0 +1,251 @@ +userdata(); + * + * @param string $key Identifier of the session property to retrieve + * + * @return array|null The property value(s) + */ + public function get(string $key = null); + + //-------------------------------------------------------------------- + + /** + * Returns whether an index exists in the session array. + * + * @param string $key Identifier of the session property we are interested in. + * + * @return boolean + */ + public function has(string $key): bool; + + //-------------------------------------------------------------------- + + /** + * Remove one or more session properties. + * + * If $key is an array, it is interpreted as an array of string property + * identifiers to remove. Otherwise, it is interpreted as the identifier + * of a specific session property to remove. + * + * @param string|array $key Identifier of the session property or properties to remove. + */ + public function remove($key); + + //-------------------------------------------------------------------- + + /** + * Sets data into the session that will only last for a single request. + * Perfect for use with single-use status update messages. + * + * If $data is an array, it is interpreted as an associative array of + * key/value pairs for flashdata properties. + * Otherwise, it is interpreted as the identifier of a specific + * flashdata property, with $value containing the property value. + * + * @param string|array $data Property identifier or associative array of properties + * @param string|array $value Property value if $data is a scalar + */ + public function setFlashdata($data, $value = null); + + //-------------------------------------------------------------------- + + /** + * Retrieve one or more items of flash data from the session. + * + * If the item key is null, return all flashdata. + * + * @param string $key Property identifier + * @return array|null The requested property value, or an associative + * array of them + */ + public function getFlashdata(string $key = null); + + //-------------------------------------------------------------------- + + /** + * Keeps a single piece of flash data alive for one more request. + * + * @param array|string $key Property identifier or array of them + */ + public function keepFlashdata($key); + + //-------------------------------------------------------------------- + + /** + * Mark a session property or properties as flashdata. + * + * @param string|array $key Property identifier or array of them + * + * @return False if any of the properties are not already set + */ + public function markAsFlashdata($key); + + //-------------------------------------------------------------------- + + /** + * Unmark data in the session as flashdata. + * + * @param string|array $key Property identifier or array of them + */ + public function unmarkFlashdata($key); + + //-------------------------------------------------------------------- + + /** + * Retrieve all of the keys for session data marked as flashdata. + * + * @return array The property names of all flashdata + */ + public function getFlashKeys(): array; + + //-------------------------------------------------------------------- + + /** + * Sets new data into the session, and marks it as temporary data + * with a set lifespan. + * + * @param string|array $data Session data key or associative array of items + * @param mixed $value Value to store + * @param integer $ttl Time-to-live in seconds + */ + public function setTempdata($data, $value = null, int $ttl = 300); + + //-------------------------------------------------------------------- + + /** + * Returns either a single piece of tempdata, or all temp data currently + * in the session. + * + * @param string $key Session data key + * @return mixed Session data value or null if not found. + */ + public function getTempdata(string $key = null); + + //-------------------------------------------------------------------- + + /** + * Removes a single piece of temporary data from the session. + * + * @param string $key Session data key + */ + public function removeTempdata(string $key); + + //-------------------------------------------------------------------- + + /** + * Mark one of more pieces of data as being temporary, meaning that + * it has a set lifespan within the session. + * + * @param string|array $key Property identifier or array of them + * @param integer $ttl Time to live, in seconds + * + * @return boolean False if any of the properties were not set + */ + public function markAsTempdata($key, int $ttl = 300); + + //-------------------------------------------------------------------- + + /** + * Unmarks temporary data in the session, effectively removing its + * lifespan and allowing it to live as long as the session does. + * + * @param string|array $key Property identifier or array of them + */ + public function unmarkTempdata($key); + + //-------------------------------------------------------------------- + + /** + * Retrieve the keys of all session data that have been marked as temporary data. + * + * @return array + */ + public function getTempKeys(): array; + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Test/CIDatabaseTestCase.php b/vendor/codeigniter4/framework/system/Test/CIDatabaseTestCase.php new file mode 100644 index 0000000..3d11ce3 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/CIDatabaseTestCase.php @@ -0,0 +1,388 @@ +hasInDatabase(); + * + * @var array + */ + protected $insertCache = []; + + //-------------------------------------------------------------------- + + /** + * Load any database test dependencies. + */ + public function loadDependencies() + { + if ($this->db === null) + { + $this->db = Database::connect($this->DBGroup); + $this->db->initialize(); + } + + if ($this->migrations === null) + { + // Ensure that we can run migrations + $config = new Migrations(); + $config->enabled = true; + + $this->migrations = Services::migrations($config, $this->db); + $this->migrations->setSilent(false); + } + + if ($this->seeder === null) + { + $this->seeder = Database::seeder($this->DBGroup); + $this->seeder->setSilent(true); + } + } + + //-------------------------------------------------------------------- + + /** + * Ensures that the database is cleaned up to a known state + * before each test runs. + * + * @throws ConfigException + */ + protected function setUp(): void + { + parent::setUp(); + + $this->loadDependencies(); + + if ($this->refresh === true) + { + $this->regressDatabase(); + + // Reset counts on faked items + Fabricator::resetCounts(); + } + + $this->migrateDatabase(); + + if (! empty($this->seed)) + { + if (! empty($this->basePath)) + { + $this->seeder->setPath(rtrim($this->basePath, '/') . '/Seeds'); + } + + $seeds = is_array($this->seed) ? $this->seed : [$this->seed]; + foreach ($seeds as $seed) + { + $this->seed($seed); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Takes care of any required cleanup after the test, like + * removing any rows inserted via $this->hasInDatabase() + */ + protected function tearDown(): void + { + parent::tearDown(); + + if (! empty($this->insertCache)) + { + foreach ($this->insertCache as $row) + { + $this->db->table($row[0]) + ->where($row[1]) + ->delete(); + } + } + } + + //-------------------------------------------------------------------- + + /** + * Regress migrations as defined by the class + */ + protected function regressDatabase() + { + // If no namespace was specified then rollback all + if (empty($this->namespace)) + { + $this->migrations->setNamespace(null); + $this->migrations->regress(0, 'tests'); + } + + // Regress each specified namespace + else + { + $namespaces = is_array($this->namespace) ? $this->namespace : [$this->namespace]; + + foreach ($namespaces as $namespace) + { + $this->migrations->setNamespace($namespace); + $this->migrations->regress(0, 'tests'); + } + } + } + + /** + * Run migrations as defined by the class + */ + protected function migrateDatabase() + { + // If no namespace was specified then migrate all + if (empty($this->namespace)) + { + $this->migrations->setNamespace(null); + $this->migrations->latest('tests'); + } + // Run migrations for each specified namespace + else + { + $namespaces = is_array($this->namespace) ? $this->namespace : [$this->namespace]; + + foreach ($namespaces as $namespace) + { + $this->migrations->setNamespace($namespace); + $this->migrations->latest('tests'); + } + } + } + + /** + * Seeds that database with a specific seeder. + * + * @param string $name + */ + public function seed(string $name) + { + return $this->seeder->call($name); + } + + //-------------------------------------------------------------------- + // Database Test Helpers + //-------------------------------------------------------------------- + + /** + * Asserts that records that match the conditions in $where do + * not exist in the database. + * + * @param string $table + * @param array $where + * + * @return boolean + */ + public function dontSeeInDatabase(string $table, array $where) + { + $count = $this->db->table($table) + ->where($where) + ->countAllResults(); + + $this->assertTrue($count === 0, 'Row was found in database'); + } + + //-------------------------------------------------------------------- + + /** + * Asserts that records that match the conditions in $where DO + * exist in the database. + * + * @param string $table + * @param array $where + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function seeInDatabase(string $table, array $where) + { + $count = $this->db->table($table) + ->where($where) + ->countAllResults(); + + $this->assertTrue($count > 0, 'Row not found in database: ' . $this->db->showLastQuery()); + } + + //-------------------------------------------------------------------- + + /** + * Fetches a single column from a database row with criteria + * matching $where. + * + * @param string $table + * @param string $column + * @param array $where + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function grabFromDatabase(string $table, string $column, array $where) + { + $query = $this->db->table($table) + ->select($column) + ->where($where) + ->get(); + + $query = $query->getRow(); + + return $query->$column ?? false; + } + + //-------------------------------------------------------------------- + + /** + * Inserts a row into to the database. This row will be removed + * after the test has run. + * + * @param string $table + * @param array $data + * + * @return boolean + */ + public function hasInDatabase(string $table, array $data) + { + $this->insertCache[] = [ + $table, + $data, + ]; + + return $this->db->table($table) + ->insert($data); + } + + //-------------------------------------------------------------------- + + /** + * Asserts that the number of rows in the database that match $where + * is equal to $expected. + * + * @param integer $expected + * @param string $table + * @param array $where + * + * @return boolean + * @throws \CodeIgniter\Database\Exceptions\DatabaseException + */ + public function seeNumRecords(int $expected, string $table, array $where) + { + $count = $this->db->table($table) + ->where($where) + ->countAllResults(); + + $this->assertEquals($expected, $count, 'Wrong number of matching rows in database.'); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Test/CIUnitTestCase.php b/vendor/codeigniter4/framework/system/Test/CIUnitTestCase.php new file mode 100644 index 0000000..d90b2e0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/CIUnitTestCase.php @@ -0,0 +1,361 @@ +app) + { + $this->app = $this->createApplication(); + } + + foreach ($this->setUpMethods as $method) + { + $this->$method(); + } + } + + protected function tearDown(): void + { + parent::tearDown(); + + foreach ($this->tearDownMethods as $method) + { + $this->$method(); + } + } + + //-------------------------------------------------------------------- + // Mocking + //-------------------------------------------------------------------- + + /** + * Injects the mock session driver into Services + */ + protected function mockSession() + { + $_SESSION = []; + + $config = config('App'); + $session = new MockSession(new ArrayHandler($config, '0.0.0.0'), $config); + + Services::injectMock('session', $session); + } + + /** + * Injects the mock email driver so no emails really send + */ + protected function mockEmail() + { + Services::injectMock('email', new MockEmail(config('Email'))); + } + + //-------------------------------------------------------------------- + // Assertions + //-------------------------------------------------------------------- + + /** + * Custom function to hook into CodeIgniter's Logging mechanism + * to check if certain messages were logged during code execution. + * + * @param string $level + * @param null $expectedMessage + * + * @return boolean + * @throws \Exception + */ + public function assertLogged(string $level, $expectedMessage = null) + { + $result = TestLogger::didLog($level, $expectedMessage); + + $this->assertTrue($result); + return $result; + } + + /** + * Hooks into CodeIgniter's Events system to check if a specific + * event was triggered or not. + * + * @param string $eventName + * + * @return boolean + * @throws \Exception + */ + public function assertEventTriggered(string $eventName): bool + { + $found = false; + $eventName = strtolower($eventName); + + foreach (Events::getPerformanceLogs() as $log) + { + if ($log['event'] !== $eventName) + { + continue; + } + + $found = true; + break; + } + + $this->assertTrue($found); + return $found; + } + + /** + * Hooks into xdebug's headers capture, looking for a specific header + * emitted + * + * @param string $header The leading portion of the header we are looking for + * @param boolean $ignoreCase + * + * @throws \Exception + */ + public function assertHeaderEmitted(string $header, bool $ignoreCase = false): void + { + $found = false; + + if (! function_exists('xdebug_get_headers')) + { + $this->markTestSkipped('XDebug not found.'); + } + + foreach (xdebug_get_headers() as $emitted) + { + $found = $ignoreCase ? + (stripos($emitted, $header) === 0) : + (strpos($emitted, $header) === 0); + if ($found) + { + break; + } + } + + $this->assertTrue($found, "Didn't find header for {$header}"); + } + + /** + * Hooks into xdebug's headers capture, looking for a specific header + * emitted + * + * @param string $header The leading portion of the header we don't want to find + * @param boolean $ignoreCase + * + * @throws \Exception + */ + public function assertHeaderNotEmitted(string $header, bool $ignoreCase = false): void + { + $found = false; + + if (! function_exists('xdebug_get_headers')) + { + $this->markTestSkipped('XDebug not found.'); + } + + foreach (xdebug_get_headers() as $emitted) + { + $found = $ignoreCase ? + (stripos($emitted, $header) === 0) : + (strpos($emitted, $header) === 0); + if ($found) + { + break; + } + } + + $success = ! $found; + $this->assertTrue($success, "Found header for {$header}"); + } + + /** + * Custom function to test that two values are "close enough". + * This is intended for extended execution time testing, + * where the result is close but not exactly equal to the + * expected time, for reasons beyond our control. + * + * @param integer $expected + * @param mixed $actual + * @param string $message + * @param integer $tolerance + * + * @throws \Exception + */ + public function assertCloseEnough(int $expected, $actual, string $message = '', int $tolerance = 1) + { + $difference = abs($expected - (int) floor($actual)); + + $this->assertLessThanOrEqual($tolerance, $difference, $message); + } + + /** + * Custom function to test that two values are "close enough". + * This is intended for extended execution time testing, + * where the result is close but not exactly equal to the + * expected time, for reasons beyond our control. + * + * @param mixed $expected + * @param mixed $actual + * @param string $message + * @param integer $tolerance + * + * @return boolean + * @throws \Exception + */ + public function assertCloseEnoughString($expected, $actual, string $message = '', int $tolerance = 1) + { + $expected = (string) $expected; + $actual = (string) $actual; + if (strlen($expected) !== strlen($actual)) + { + return false; + } + + try + { + $expected = (int) substr($expected, -2); + $actual = (int) substr($actual, -2); + $difference = abs($expected - $actual); + + $this->assertLessThanOrEqual($tolerance, $difference, $message); + } + catch (\Exception $e) + { + return false; + } + } + + //-------------------------------------------------------------------- + // Utility + //-------------------------------------------------------------------- + + /** + * Loads up an instance of CodeIgniter + * and gets the environment setup. + * + * @return \CodeIgniter\CodeIgniter + */ + protected function createApplication() + { + return require realpath(__DIR__ . '/../') . '/bootstrap.php'; + } + + /** + * Return first matching emitted header. + * + * @param string $header Identifier of the header of interest + * @param boolean $ignoreCase + * + * @return string|null The value of the header found, null if not found + */ + protected function getHeaderEmitted(string $header, bool $ignoreCase = false): ?string + { + $found = false; + + if (! function_exists('xdebug_get_headers')) + { + $this->markTestSkipped('XDebug not found.'); + } + + foreach (xdebug_get_headers() as $emitted) + { + $found = $ignoreCase ? + (stripos($emitted, $header) === 0) : + (strpos($emitted, $header) === 0); + if ($found) + { + return $emitted; + } + } + + return null; + } +} diff --git a/vendor/codeigniter4/framework/system/Test/ControllerResponse.php b/vendor/codeigniter4/framework/system/Test/ControllerResponse.php new file mode 100644 index 0000000..a187ce7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/ControllerResponse.php @@ -0,0 +1,227 @@ +dom = new DOMParser(); + } + + //-------------------------------------------------------------------- + // Getters / Setters + //-------------------------------------------------------------------- + + /** + * Set the body & DOM. + * + * @param string $body + * + * @return $this + */ + public function setBody(string $body) + { + $this->body = $body; + + if (! empty($body)) + { + $this->dom = $this->dom->withString($body); + } + + return $this; + } + + /** + * Retrieve the body. + * + * @return string + */ + public function getBody() + { + return $this->body; + } + + /** + * Set the request. + * + * @param \CodeIgniter\HTTP\RequestInterface $request + * + * @return $this + */ + public function setRequest(RequestInterface $request) + { + $this->request = $request; + + return $this; + } + + /** + * Set the response. + * + * @param \CodeIgniter\HTTP\ResponseInterface $response + * + * @return $this + */ + public function setResponse(ResponseInterface $response) + { + $this->response = $response; + + $this->setBody($response->getBody() ?? ''); + + return $this; + } + + /** + * Request accessor. + * + * @return \CodeIgniter\HTTP\IncomingRequest + */ + public function request() + { + return $this->request; + } + + /** + * Response accessor. + * + * @return \CodeIgniter\HTTP\Response + */ + public function response() + { + return $this->response; + } + + //-------------------------------------------------------------------- + // Simple Response Checks + //-------------------------------------------------------------------- + + /** + * Boils down the possible responses into a boolean valid/not-valid + * response type. + * + * @return boolean + */ + public function isOK(): bool + { + // Only 200 and 300 range status codes + // are considered valid. + if ($this->response->getStatusCode() >= 400 || $this->response->getStatusCode() < 200) + { + return false; + } + + // Empty bodies are not considered valid. + if (empty($this->response->getBody())) + { + return false; + } + + return true; + } + + /** + * Returns whether or not the Response was a redirect response + * + * @return boolean + */ + public function isRedirect(): bool + { + return $this->response instanceof RedirectResponse; + } + + //-------------------------------------------------------------------- + // Utility + //-------------------------------------------------------------------- + + /** + * Forward any unrecognized method calls to our DOMParser instance. + * + * @param string $function Method name + * @param mixed $params Any method parameters + * @return mixed + */ + public function __call($function, $params) + { + if (method_exists($this->dom, $function)) + { + return $this->dom->{$function}(...$params); + } + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/ControllerTester.php b/vendor/codeigniter4/framework/system/Test/ControllerTester.php new file mode 100644 index 0000000..89d4431 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/ControllerTester.php @@ -0,0 +1,316 @@ +withRequest($request) + * ->withResponse($response) + * ->withURI($uri) + * ->withBody($body) + * ->controller('App\Controllers\Home') + * ->run('methodName'); + */ +trait ControllerTester +{ + + /** + * Controller configuration. + * + * @var BaseConfig + */ + protected $appConfig; + + /** + * Request. + * + * @var Request + */ + protected $request; + /** + * Response. + * + * @var Response + */ + protected $response; + /** + * Message logger. + * + * @var LoggerInterface + */ + protected $logger; + /** + * Initialized controller. + * + * @var Controller + */ + protected $controller; + /** + * URI of this request. + * + * @var string + */ + protected $uri = 'http://example.com'; + /** + * Request or response body. + * + * @var string + */ + protected $body; + + /** + * Loads the specified controller, and generates any needed dependencies. + * + * @param string $name + * + * @return mixed + */ + public function controller(string $name) + { + if (! class_exists($name)) + { + throw new InvalidArgumentException('Invalid Controller: ' . $name); + } + + if (empty($this->appConfig)) + { + $this->appConfig = new App(); + } + + if (! $this->uri instanceof URI) + { + $this->uri = new URI($this->appConfig->baseURL ?? 'http://example.com'); + } + + if (empty($this->request)) + { + $this->request = new IncomingRequest($this->appConfig, $this->uri, $this->body, new UserAgent()); + } + + if (empty($this->response)) + { + $this->response = new Response($this->appConfig); + } + + if (empty($this->logger)) + { + $this->logger = Services::logger(); + } + + $this->controller = new $name(); + $this->controller->initController($this->request, $this->response, $this->logger); + + return $this; + } + + /** + * Runs the specified method on the controller and returns the results. + * + * @param string $method + * @param array $params + * + * @return \CodeIgniter\Test\ControllerResponse|\InvalidArgumentException + */ + public function execute(string $method, ...$params) + { + if (! method_exists($this->controller, $method) || ! is_callable([$this->controller, $method])) + { + throw new InvalidArgumentException('Method does not exist or is not callable in controller: ' . $method); + } + + // The URL helper is always loaded by the system + // so ensure it's available. + helper('url'); + + $result = (new ControllerResponse()) + ->setRequest($this->request) + ->setResponse($this->response); + + $response = null; + try + { + ob_start(); + + $response = $this->controller->{$method}(...$params); + } + catch (Throwable $e) + { + $result->response() + ->setStatusCode($e->getCode()); + } + finally + { + $output = ob_get_clean(); + + // If the controller returned a response, use it + if (isset($response) && $response instanceof Response) + { + $result->setResponse($response); + } + + // check if controller returned a view rather than echoing it + if (is_string($response)) + { + $output = $response; + $result->response()->setBody($output); + $result->setBody($output); + } + elseif (! empty($response) && ! empty($response->getBody())) + { + $result->setBody($response->getBody()); + } + else + { + $result->setBody(''); + } + } + + // If not response code has been sent, assume a success + if (empty($result->response()->getStatusCode())) + { + $result->response()->setStatusCode(200); + } + + return $result; + } + + /** + * Set controller's config, with method chaining. + * + * @param mixed $appConfig + * + * @return mixed + */ + public function withConfig($appConfig) + { + $this->appConfig = $appConfig; + + return $this; + } + + /** + * Set controller's request, with method chaining. + * + * @param mixed $request + * + * @return mixed + */ + public function withRequest($request) + { + $this->request = $request; + + // Make sure it's available for other classes + Services::injectMock('request', $request); + + return $this; + } + + /** + * Set controller's response, with method chaining. + * + * @param mixed $response + * + * @return mixed + */ + public function withResponse($response) + { + $this->response = $response; + + return $this; + } + + /** + * Set controller's logger, with method chaining. + * + * @param mixed $logger + * + * @return mixed + */ + public function withLogger($logger) + { + $this->logger = $logger; + + return $this; + } + + /** + * Set the controller's URI, with method chaining. + * + * @param string $uri + * + * @return mixed + */ + public function withUri(string $uri) + { + $this->uri = new URI($uri); + + return $this; + } + + /** + * Set the method's body, with method chaining. + * + * @param mixed $body + * + * @return mixed + */ + public function withBody($body) + { + $this->body = $body; + + return $this; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/DOMParser.php b/vendor/codeigniter4/framework/system/Test/DOMParser.php new file mode 100644 index 0000000..95b8896 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/DOMParser.php @@ -0,0 +1,359 @@ +dom = new \DOMDocument('1.0', 'utf-8'); + } + + /** + * Returns the body of the current document. + * + * @return string + */ + public function getBody(): string + { + return $this->dom->saveHTML(); + } + + /** + * Sets a string as the body that we want to work with. + * + * @param string $content + * + * @return $this + */ + public function withString(string $content) + { + // converts all special characters to utf-8 + $content = mb_convert_encoding($content, 'HTML-ENTITIES', 'UTF-8'); + + //turning off some errors + libxml_use_internal_errors(true); + + if (! $this->dom->loadHTML($content)) + { + // unclear how we would get here, given that we are trapping libxml errors + // @codeCoverageIgnoreStart + libxml_clear_errors(); + throw new \BadMethodCallException('Invalid HTML'); + // @codeCoverageIgnoreEnd + } + + // ignore the whitespace. + $this->dom->preserveWhiteSpace = false; + + return $this; + } + + /** + * Loads the contents of a file as a string + * so that we can work with it. + * + * @param string $path + * + * @return \CodeIgniter\Test\DOMParser + */ + public function withFile(string $path) + { + if (! is_file($path)) + { + throw new \InvalidArgumentException(basename($path) . ' is not a valid file.'); + } + + $content = file_get_contents($path); + + return $this->withString($content); + } + + /** + * Checks to see if the text is found within the result. + * + * @param string $search + * @param string $element + * + * @return boolean + */ + public function see(string $search = null, string $element = null): bool + { + // If Element is null, we're just scanning for text + if (is_null($element)) + { + $content = $this->dom->saveHTML($this->dom->documentElement); + return mb_strpos($content, $search) !== false; + } + + $result = $this->doXPath($search, $element); + + return (bool)$result->length; + } + + /** + * Checks to see if the text is NOT found within the result. + * + * @param string $search + * @param string|null $element + * + * @return boolean + */ + public function dontSee(string $search = null, string $element = null): bool + { + return ! $this->see($search, $element); + } + + /** + * Checks to see if an element with the matching CSS specifier + * is found within the current DOM. + * + * @param string $element + * + * @return boolean + */ + public function seeElement(string $element): bool + { + return $this->see(null, $element); + } + + /** + * Checks to see if the element is available within the result. + * + * @param string $element + * + * @return boolean + */ + public function dontSeeElement(string $element): bool + { + return $this->dontSee(null, $element); + } + + /** + * Determines if a link with the specified text is found + * within the results. + * + * @param string $text + * @param string|null $details + * + * @return boolean + */ + public function seeLink(string $text, string $details = null): bool + { + return $this->see($text, 'a' . $details); + } + + /** + * Checks for an input named $field with a value of $value. + * + * @param string $field + * @param string $value + * + * @return boolean + */ + public function seeInField(string $field, string $value): bool + { + $result = $this->doXPath(null, 'input', ["[@value=\"{$value}\"][@name=\"{$field}\"]"]); + + return (bool)$result->length; + } + + /** + * Checks for checkboxes that are currently checked. + * + * @param string $element + * + * @return boolean + */ + public function seeCheckboxIsChecked(string $element): bool + { + $result = $this->doXPath(null, 'input' . $element, [ + '[@type="checkbox"]', + '[@checked="checked"]', + ]); + + return (bool)$result->length; + } + + //-------------------------------------------------------------------- + /** + * Search the DOM using an XPath expression. + * + * @param string $search + * @param string $element + * @param array $paths + * @return type + */ + + protected function doXPath(string $search = null, string $element, array $paths = []) + { + // Otherwise, grab any elements that match + // the selector + $selector = $this->parseSelector($element); + + $path = ''; + + // By ID + if (! empty($selector['id'])) + { + $path = empty($selector['tag']) + ? "id(\"{$selector['id']}\")" + : "//body//{$selector['tag']}[@id=\"{$selector['id']}\"]"; + } + // By Class + else if (! empty($selector['class'])) + { + $path = empty($selector['tag']) + ? "//*[@class=\"{$selector['class']}\"]" + : "//body//{$selector['tag']}[@class=\"{$selector['class']}\"]"; + } + // By tag only + else if (! empty($selector['tag'])) + { + $path = "//body//{$selector['tag']}"; + } + + if (! empty($selector['attr'])) + { + foreach ($selector['attr'] as $key => $value) + { + $path .= "[@{$key}=\"{$value}\"]"; + } + } + + // $paths might contain a number of different + // ready to go xpath portions to tack on. + if (! empty($paths) && is_array($paths)) + { + foreach ($paths as $extra) + { + $path .= $extra; + } + } + + if (! is_null($search)) + { + $path .= "[contains(., \"{$search}\")]"; + } + + $xpath = new \DOMXPath($this->dom); + + return $xpath->query($path); + } + + /** + * Look for the a selector in the passed text. + * + * @param string $selector + * @return type + */ + public function parseSelector(string $selector) + { + $tag = null; + $id = null; + $class = null; + $attr = null; + + // ID? + if ($pos = strpos($selector, '#') !== false) + { + list($tag, $id) = explode('#', $selector); + } + // Attribute + elseif (strpos($selector, '[') !== false && strpos($selector, ']') !== false) + { + $open = strpos($selector, '['); + $close = strpos($selector, ']'); + + $tag = substr($selector, 0, $open); + $text = substr($selector, $open + 1, $close - 2); + + // We only support a single attribute currently + $text = explode(',', $text); + $text = trim(array_shift($text)); + + list($name, $value) = explode('=', $text); + $name = trim($name); + $value = trim($value); + $attr = [$name => trim($value, '] ')]; + } + // Class? + elseif ($pos = strpos($selector, '.') !== false) + { + list($tag, $class) = explode('.', $selector); + } + // Otherwise, assume the entire string is our tag + else + { + $tag = $selector; + } + + return [ + 'tag' => $tag, + 'id' => $id, + 'class' => $class, + 'attr' => $attr, + ]; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Fabricator.php b/vendor/codeigniter4/framework/system/Test/Fabricator.php new file mode 100644 index 0000000..3791a37 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Fabricator.php @@ -0,0 +1,648 @@ + formatter + * @param string|null $locale Locale for Faker provider + * + * @throws \InvalidArgumentException + */ + public function __construct($model, array $formatters = null, string $locale = null) + { + if (is_string($model)) + { + // Create a new model instance + $model = model($model, false); + } + + if (! is_object($model)) + { + throw new \InvalidArgumentException(lang('Fabricator.invalidModel')); + } + + $this->model = $model; + + // If no locale was specified then use the App default + if (is_null($locale)) + { + $locale = config('App')->defaultLocale; + } + + // There is no easy way to retrieve the locale from Faker so we will store it + $this->locale = $locale; + + // Create the locale-specific Generator + $this->faker = Factory::create($this->locale); + + // Determine eligible date fields + foreach (['createdField', 'updatedField', 'deletedField'] as $field) + { + if (! empty($this->model->$field)) + { + $this->dateFields[] = $this->model->$field; + } + } + + // Set the formatters + $this->setFormatters($formatters); + } + + //-------------------------------------------------------------------- + + /** + * Reset internal counts + */ + public static function resetCounts() + { + self::$tableCounts = []; + } + + /** + * Get the count for a specific table + * + * @param string $table Name of the target table + * + * @return integer + */ + public static function getCount(string $table): int + { + return empty(self::$tableCounts[$table]) ? 0 : self::$tableCounts[$table]; + } + + /** + * Set the count for a specific table + * + * @param string $table Name of the target table + * @param integer $count Count value + * + * @return integer The new count value + */ + public static function setCount(string $table, int $count): int + { + self::$tableCounts[$table] = $count; + return $count; + } + + /** + * Increment the count for a table + * + * @param string $table Name of the target table + * + * @return integer The new count value + */ + public static function upCount(string $table): int + { + return self::setCount($table, self::getCount($table) + 1); + } + + /** + * Decrement the count for a table + * + * @param string $table Name of the target table + * + * @return integer The new count value + */ + public static function downCount(string $table): int + { + return self::setCount($table, self::getCount($table) - 1); + } + + //-------------------------------------------------------------------- + + /** + * Returns the model instance + * + * @return object Framework or compatible model + */ + public function getModel() + { + return $this->model; + } + + /** + * Returns the locale + * + * @return string + */ + public function getLocale(): string + { + return $this->locale; + } + + /** + * Returns the Faker generator + * + * @return Faker\Generator + */ + public function getFaker(): Generator + { + return $this->faker; + } + + //-------------------------------------------------------------------- + + /** + * Return and reset tempOverrides + * + * @return array + */ + public function getOverrides(): array + { + $overrides = $this->tempOverrides ?? $this->overrides; + + $this->tempOverrides = $this->overrides; + + return $overrides; + } + + /** + * Set the overrides, once or persistent + * + * @param array $overrides Array of [field => value] + * @param boolean $persist Whether these overrides should persist through the next operation + * + * @return $this + */ + public function setOverrides(array $overrides = [], $persist = true): self + { + if ($persist) + { + $this->overrides = $overrides; + } + + $this->tempOverrides = $overrides; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the current formatters + * + * @return array|null + */ + public function getFormatters(): ?array + { + return $this->formatters; + } + + /** + * Set the formatters to use. Will attempt to autodetect if none are available. + * + * @param array|null $formatters Array of [field => formatter], or null to detect + * + * @return $this + */ + public function setFormatters(array $formatters = null): self + { + if (! is_null($formatters)) + { + $this->formatters = $formatters; + } + elseif (method_exists($this->model, 'fake')) + { + $this->formatters = null; + } + else + { + $formatters = $this->detectFormatters(); + } + + return $this; + } + + /** + * Try to identify the appropriate Faker formatter for each field. + * + * @return $this + */ + protected function detectFormatters(): self + { + $this->formatters = []; + + if (! empty($this->model->allowedFields)) + { + foreach ($this->model->allowedFields as $field) + { + $this->formatters[$field] = $this->guessFormatter($field); + } + } + + return $this; + } + + /** + * Guess at the correct formatter to match a field name. + * + * @param $field Name of the field + * + * @return string Name of the formatter + */ + protected function guessFormatter($field): string + { + // First check for a Faker formatter of the same name - covers things like "email" + try + { + $this->faker->getFormatter($field); + return $field; + } + catch (\InvalidArgumentException $e) + { + // No match, keep going + } + + // Next look for known model fields + if (in_array($field, $this->dateFields)) + { + switch ($this->model->dateFormat) + { + case 'datetime': + return 'date'; + break; + + case 'date': + return 'date'; + break; + + case 'int': + return 'unixTime'; + break; + } + } + elseif ($field === $this->model->primaryKey) + { + return 'numberBetween'; + } + + // Check some common partials + foreach (['email', 'name', 'title', 'text', 'date', 'url'] as $term) + { + if (stripos($field, $term) !== false) + { + return $term; + } + } + + if (stripos($field, 'phone') !== false) + { + return 'phoneNumber'; + } + + // Nothing left, use the default + return $this->defaultFormatter; + } + + //-------------------------------------------------------------------- + + /** + * Generate new entities with faked data + * + * @param integer|null $count Optional number to create a collection + * + * @return array|object An array or object (based on returnType), or an array of returnTypes + */ + public function make(int $count = null) + { + // If a singleton was requested then go straight to it + if (is_null($count)) + { + return $this->model->returnType === 'array' + ? $this->makeArray() + : $this->makeObject(); + } + + $return = []; + + for ($i = 0; $i < $count; $i++) + { + $return[] = $this->model->returnType === 'array' + ? $this->makeArray() + : $this->makeObject(); + } + + return $return; + } + + /** + * Generate an array of faked data + * + * @return array An array of faked data + * + * @throws \RuntimeException + */ + public function makeArray() + { + if (! is_null($this->formatters)) + { + $result = []; + + foreach ($this->formatters as $field => $formatter) + { + $result[$field] = $this->faker->{$formatter}; + } + } + + // If no formatters were defined then look for a model fake() method + elseif (method_exists($this->model, 'fake')) + { + $result = $this->model->fake($this->faker); + + // This should cover entities + if (method_exists($result, 'toArray')) + { + $result = $result->toArray(); + } + // Try to cast it + else + { + $result = (array) $result; + } + } + + // Nothing left to do but give up + else + { + throw new \RuntimeException(lang('Fabricator.missingFormatters')); + } + + // Replace overridden fields + return array_merge($result, $this->getOverrides()); + } + + /** + * Generate an object of faked data + * + * @param string|null $className Class name of the object to create; null to use model default + * + * @return object An instance of the class with faked data + * + * @throws \RuntimeException + */ + public function makeObject(string $className = null): object + { + if (is_null($className)) + { + if ($this->model->returnType === 'object' || $this->model->returnType === 'array') + { + $className = 'stdClass'; + } + else + { + $className = $this->model->returnType; + } + } + + // If using the model's fake() method then check it for the correct return type + if (is_null($this->formatters) && method_exists($this->model, 'fake')) + { + $result = $this->model->fake($this->faker); + + if ($result instanceof $className) + { + // Set overrides manually + foreach ($this->getOverrides() as $key => $value) + { + $result->{$key} = $value; + } + + return $result; + } + } + + // Get the array values and apply them to the object + $array = $this->makeArray(); + $object = new $className(); + + // Check for the entity method + if (method_exists($object, 'fill')) + { + $object->fill($array); + } + else + { + foreach ($array as $key => $value) + { + $object->{$key} = $value; + } + } + + return $object; + } + + //-------------------------------------------------------------------- + + /** + * Generate new entities from the database + * + * @param integer|null $count Optional number to create a collection + * @param array $override Array of data to add/override + * @param boolean $mock Whether to execute or mock the insertion + * + * @return array|object An array or object (based on returnType), or an array of returnTypes + */ + public function create(int $count = null, bool $mock = false) + { + // Intercept mock requests + if ($mock) + { + return $this->createMock($count); + } + + $ids = []; + + // Iterate over new entities and insert each one, storing insert IDs + foreach ($this->make($count ?? 1) as $result) + { + if ($id = $this->model->insert($result, true)) + { + $ids[] = $id; + self::upCount($this->model->table); + } + } + + // If the model defines a "withDeleted" method for handling soft deletes then use it + if (method_exists($this->model, 'withDeleted')) + { + $this->model->withDeleted(); + } + + return $this->model->find(is_null($count) ? reset($ids) : $ids); + } + + /** + * Generate new database entities without actually inserting them + * + * @param integer|null $count Optional number to create a collection + * + * @return array|object An array or object (based on returnType), or an array of returnTypes + */ + protected function createMock(int $count = null) + { + switch ($this->model->dateFormat) + { + case 'datetime': + $datetime = date('Y-m-d H:i:s'); + case 'date': + $datetime = date('Y-m-d'); + default: + $datetime = time(); + } + + // Determine which fields we will need + $fields = []; + + if (! empty($this->model->useTimestamps)) + { + $fields[$this->model->createdField] = $datetime; + $fields[$this->model->updatedField] = $datetime; + } + + if (! empty($this->model->useSoftDeletes)) + { + $fields[$this->model->deletedField] = null; + } + + // Iterate over new entities and add the necessary fields + $return = []; + foreach ($this->make($count ?? 1) as $i => $result) + { + // Set the ID + $fields[$this->model->primaryKey] = $i; + + // Merge fields + if (is_array($result)) + { + $result = array_merge($result, $fields); + } + else + { + foreach ($fields as $key => $value) + { + $result->{$key} = $value; + } + } + + $return[] = $result; + } + + return is_null($count) ? reset($return) : $return; + } +} diff --git a/vendor/codeigniter4/framework/system/Test/FeatureResponse.php b/vendor/codeigniter4/framework/system/Test/FeatureResponse.php new file mode 100644 index 0000000..6c919b7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/FeatureResponse.php @@ -0,0 +1,439 @@ +response = $response; + + $body = $response->getBody(); + if (! empty($body) && is_string($body)) + { + $this->domParser = (new DOMParser())->withString($body); + } + } + + //-------------------------------------------------------------------- + // Simple Response Checks + //-------------------------------------------------------------------- + + /** + * Boils down the possible responses into a bolean valid/not-valid + * response type. + * + * @return boolean + */ + public function isOK(): bool + { + $status = $this->response->getStatusCode(); + + // Only 200 and 300 range status codes + // are considered valid. + if ($status >= 400 || $status < 200) + { + return false; + } + + // Empty bodies are not considered valid, unless in redirects + if ($status < 300 && empty($this->response->getBody())) + { + return false; + } + + return true; + } + + /** + * Returns whether or not the Response was a redirect response + * + * @return boolean + */ + public function isRedirect(): bool + { + return $this->response instanceof RedirectResponse; + } + + /** + * Assert that the given response was a redirect. + * + * @throws \Exception + */ + public function assertRedirect() + { + $this->assertTrue($this->isRedirect(), 'Response is not a RedirectResponse.'); + } + + /** + * Returns the URL set for redirection. + * + * @return string|null + */ + public function getRedirectUrl(): ?string + { + if (! $this->isRedirect()) + { + return null; + } + + if ($this->response->hasHeader('Location')) + { + return $this->response->getHeaderLine('Location'); + } + elseif ($this->response->hasHeader('Refresh')) + { + return str_replace('0;url=', '', $this->response->getHeaderLine('Refresh')); + } + + return null; + } + + /** + * Asserts that the status is a specific value. + * + * @param integer $code + * + * @throws \Exception + */ + public function assertStatus(int $code) + { + $this->assertEquals($code, (int) $this->response->getStatusCode()); + } + + /** + * Asserts that the Response is considered OK. + * + * @throws \Exception + */ + public function assertOK() + { + $this->assertTrue($this->isOK(), "{$this->response->getStatusCode()} is not a successful status code, or the Response has an empty body."); + } + + //-------------------------------------------------------------------- + // Session Assertions + //-------------------------------------------------------------------- + + /** + * Asserts that an SESSION key has been set and, optionally, test it's value. + * + * @param string $key + * @param null $value + * + * @throws \Exception + */ + public function assertSessionHas(string $key, $value = null) + { + $this->assertTrue(array_key_exists($key, $_SESSION), "'{$key}' is not in the current \$_SESSION"); + + if ($value !== null) + { + $this->assertEquals($value, $_SESSION[$key], "The value of '{$key}' ({$value}) does not match expected value."); + } + } + + /** + * Asserts the session is missing $key. + * + * @param string $key + * + * @throws \Exception + */ + public function assertSessionMissing(string $key) + { + $this->assertFalse(array_key_exists($key, $_SESSION), "'{$key}' should not be present in \$_SESSION."); + } + + //-------------------------------------------------------------------- + // Header Assertions + //-------------------------------------------------------------------- + + /** + * Asserts that the Response contains a specific header. + * + * @param string $key + * @param null $value + * + * @throws \Exception + */ + public function assertHeader(string $key, $value = null) + { + $this->assertTrue($this->response->hasHeader($key), "'{$key}' is not a valid Response header."); + + if ($value !== null) + { + $this->assertEquals($value, $this->response->getHeaderLine($key), "The value of '{$key}' header ({$this->response->getHeaderLine($key)}) does not match expected value."); + } + } + + /** + * Asserts the Response headers does not contain the specified header. + * + * @param string $key + * + * @throws \Exception + */ + public function assertHeaderMissing(string $key) + { + $this->assertFalse($this->response->hasHeader($key), "'{$key}' should not be in the Response headers."); + } + + //-------------------------------------------------------------------- + // Cookie Assertions + //-------------------------------------------------------------------- + + /** + * Asserts that the response has the specified cookie. + * + * @param string $key + * @param null $value + * @param string|null $prefix + * + * @throws \Exception + */ + public function assertCookie(string $key, $value = null, string $prefix = '') + { + $this->assertTrue($this->response->hasCookie($key, $value, $prefix), "No cookie found named '{$key}'."); + } + + /** + * Assert the Response does not have the specified cookie set. + * + * @param string $key + */ + public function assertCookieMissing(string $key) + { + $this->assertFalse($this->response->hasCookie($key), "Cookie named '{$key}' should not be set."); + } + + /** + * Asserts that a cookie exists and has an expired time. + * + * @param string $key + * @param string $prefix + * + * @throws \Exception + */ + public function assertCookieExpired(string $key, string $prefix = '') + { + $this->assertTrue($this->response->hasCookie($key, null, $prefix)); + $this->assertGreaterThan(time(), $this->response->getCookie($key, $prefix)['expires']); + } + + //-------------------------------------------------------------------- + // DomParser Assertions + //-------------------------------------------------------------------- + + /** + * Assert that the desired text can be found in the result body. + * + * @param string|null $search + * @param string|null $element + * + * @throws \Exception + */ + public function assertSee(string $search = null, string $element = null) + { + $this->assertTrue($this->domParser->see($search, $element), "Do not see '{$search}' in response."); + } + + /** + * Asserts that we do not see the specified text. + * + * @param string|null $search + * @param string|null $element + * + * @throws \Exception + */ + public function assertDontSee(string $search = null, string $element = null) + { + $this->assertTrue($this->domParser->dontSee($search, $element), "I should not see '{$search}' in response."); + } + + /** + * Assert that we see an element selected via a CSS selector. + * + * @param string $search + * + * @throws \Exception + */ + public function assertSeeElement(string $search) + { + $this->assertTrue($this->domParser->seeElement($search), "Do not see element with selector '{$search} in response.'"); + } + + /** + * Assert that we do not see an element selected via a CSS selector. + * + * @param string $search + * + * @throws \Exception + */ + public function assertDontSeeElement(string $search) + { + $this->assertTrue($this->domParser->dontSeeElement($search), "I should not see an element with selector '{$search}' in response.'"); + } + + /** + * Assert that we see a link with the matching text and/or class. + * + * @param string $text + * @param string|null $details + * + * @throws \Exception + */ + public function assertSeeLink(string $text, string $details = null) + { + $this->assertTrue($this->domParser->seeLink($text, $details), "Do no see anchor tag with the text {$text} in response."); + } + + /** + * Assert that we see an input with name/value. + * + * @param string $field + * @param string|null $value + * + * @throws \Exception + */ + public function assertSeeInField(string $field, string $value = null) + { + $this->assertTrue($this->domParser->seeInField($field, $value), "Do no see input named {$field} with value {$value} in response."); + } + + //-------------------------------------------------------------------- + // JSON Methods + //-------------------------------------------------------------------- + + /** + * Returns the response's body as JSON + * + * @return mixed|false + */ + public function getJSON() + { + $response = $this->response->getJSON(); + + if (is_null($response)) + { + return false; + } + + return $response; + } + + /** + * Test that the response contains a matching JSON fragment. + * + * @param array $fragment + * + * @throws \Exception + */ + public function assertJSONFragment(array $fragment) + { + $json = json_decode($this->getJSON(), true); + + $this->assertArraySubset($fragment, $json, false, 'Response does not contain a matching JSON fragment.'); + } + + /** + * Asserts that the JSON exactly matches the passed in data. + * If the value being passed in is a string, it must be a json_encoded string. + * + * @param string|array $test + * + * @throws \Exception + */ + public function assertJSONExact($test) + { + $json = $this->getJSON(); + + if (is_array($test)) + { + $config = new Format(); + $formatter = $config->getFormatter('application/json'); + $test = $formatter->format($test); + } + + $this->assertJsonStringEqualsJsonString($test, $json, 'Response does not contain matching JSON.'); + } + + //-------------------------------------------------------------------- + // XML Methods + //-------------------------------------------------------------------- + + /** + * Returns the response' body as XML + * + * @return mixed|string + */ + public function getXML() + { + return $this->response->getXML(); + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/FeatureTestCase.php b/vendor/codeigniter4/framework/system/Test/FeatureTestCase.php new file mode 100644 index 0000000..ee70910 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/FeatureTestCase.php @@ -0,0 +1,75 @@ +resetRoutes(); + foreach ($routes as $route) + { + $collection->{$route[0]}($route[1], $route[2]); + } + } + + $this->routes = $collection; + + return $this; + } + + /** + * Sets any values that should exist during this session. + * + * @param array|null Array of values, or null to use the current $_SESSION + * + * @return $this + */ + public function withSession(array $values = null) + { + $this->session = is_null($values) ? $_SESSION : $values; + + return $this; + } + + /** + * Don't run any events while running this test. + * + * @return $this + */ + public function skipEvents() + { + Events::simulate(true); + + return $this; + } + + /** + * Calls a single URI, executes it, and returns a FeatureResponse + * instance that can be used to run many assertions against. + * + * @param string $method + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function call(string $method, string $path, array $params = null) + { + $buffer = \ob_get_level(); + + // Clean up any open output buffers + // not relevant to unit testing + // @codeCoverageIgnoreStart + if (\ob_get_level() > 0 && (! isset($this->clean) || $this->clean === true)) + { + \ob_end_clean(); + } + // @codeCoverageIgnoreEnd + + // Simulate having a blank session + $_SESSION = []; + $_SERVER['REQUEST_METHOD'] = $method; + + $request = $this->setupRequest($method, $path); + $request = $this->populateGlobals($method, $request, $params); + + // Make sure the RouteCollection knows what method we're using... + $routes = $this->routes ?: Services::routes(); + $routes->setHTTPVerb($method); + + // Make sure any other classes that might call the request + // instance get the right one. + Services::injectMock('request', $request); + + // Make sure filters are reset between tests + Services::injectMock('filters', Services::filters(null, false)); + + $response = $this->app + ->setRequest($request) + ->run($routes, true); + + $output = \ob_get_contents(); + if (empty($response->getBody()) && ! empty($output)) + { + $response->setBody($output); + } + + // Reset directory if it has been set + Services::router()->setDirectory(null); + + // Ensure the output buffer is identical so no tests are risky + // @codeCoverageIgnoreStart + while (\ob_get_level() > $buffer) + { + \ob_end_clean(); + } + while (\ob_get_level() < $buffer) + { + \ob_start(); + } + // @codeCoverageIgnoreEnd + + return new FeatureResponse($response); + } + + /** + * Performs a GET request. + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function get(string $path, array $params = null) + { + return $this->call('get', $path, $params); + } + + /** + * Performs a POST request. + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function post(string $path, array $params = null) + { + return $this->call('post', $path, $params); + } + + /** + * Performs a PUT request + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function put(string $path, array $params = null) + { + return $this->call('put', $path, $params); + } + + /** + * Performss a PATCH request + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function patch(string $path, array $params = null) + { + return $this->call('patch', $path, $params); + } + + /** + * Performs a DELETE request. + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function delete(string $path, array $params = null) + { + return $this->call('delete', $path, $params); + } + + /** + * Performs an OPTIONS request. + * + * @param string $path + * @param array|null $params + * + * @return \CodeIgniter\Test\FeatureResponse + * @throws \CodeIgniter\Router\Exceptions\RedirectException + * @throws \Exception + */ + public function options(string $path, array $params = null) + { + return $this->call('options', $path, $params); + } + + /** + * Setup a Request object to use so that CodeIgniter + * won't try to auto-populate some of the items. + * + * @param string $method + * @param string|null $path + * + * @return \CodeIgniter\HTTP\IncomingRequest + */ + protected function setupRequest(string $method, string $path = null): IncomingRequest + { + $config = config(App::class); + $uri = new URI(rtrim($config->baseURL, '/') . '/' . trim($path, '/ ')); + + $request = new IncomingRequest($config, clone($uri), null, new UserAgent()); + $request->uri = $uri; + + $request->setMethod($method); + $request->setProtocolVersion('1.1'); + + if ($config->forceGlobalSecureRequests) + { + $_SERVER['HTTPS'] = 'test'; + } + + return $request; + } + + /** + * Populates the data of our Request with "global" data + * relevant to the request, like $_POST data. + * + * Always populate the GET vars based on the URI. + * + * @param string $method + * @param \CodeIgniter\HTTP\Request $request + * @param array|null $params + * + * @return \CodeIgniter\HTTP\Request + * @throws \ReflectionException + */ + protected function populateGlobals(string $method, Request $request, array $params = null) + { + // $params should set the query vars if present, + // otherwise set it from the URL. + $get = ! empty($params) && $method === 'get' + ? $params + : $this->getPrivateProperty($request->uri, 'query'); + + $request->setGlobal('get', $get); + if ($method !== 'get') + { + $request->setGlobal($method, $params); + } + + $request->setGlobal('request', $params); + + $_SESSION = $this->session ?? []; + + return $request; + } +} diff --git a/vendor/codeigniter4/framework/system/Test/Filters/CITestStreamFilter.php b/vendor/codeigniter4/framework/system/Test/Filters/CITestStreamFilter.php new file mode 100644 index 0000000..4310a7f --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Filters/CITestStreamFilter.php @@ -0,0 +1,81 @@ +data; + $consumed += $bucket->datalen; + } + return PSFS_PASS_ON; + } + +} + +// @codeCoverageIgnoreStart +stream_filter_register('CITestStreamFilter', 'CodeIgniter\Test\Filters\CITestStreamFilter'); +// @codeCoverageIgnoreEnd diff --git a/vendor/codeigniter4/framework/system/Test/Interfaces/FabricatorModel.php b/vendor/codeigniter4/framework/system/Test/Interfaces/FabricatorModel.php new file mode 100644 index 0000000..fdf7500 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Interfaces/FabricatorModel.php @@ -0,0 +1,109 @@ +table with a primary key + * matching $id. + * + * @param mixed|array|null $id One primary key or an array of primary keys + * + * @return array|object|null The resulting row of data, or null. + */ + public function find($id = null); + + /** + * Inserts data into the current table. If an object is provided, + * it will attempt to convert it to an array. + * + * @param array|object $data + * @param boolean $returnID Whether insert ID should be returned or not. + * + * @return integer|string|boolean + * @throws \ReflectionException + */ + public function insert($data = null, bool $returnID = true); + + /** + * The following properties and methods are optional, but if present should + * adhere to their definitions. + * + * @property array $allowedFields + * @property string $useSoftDeletes + * @property string $useTimestamps + * @property string $createdField + * @property string $updatedField + * @property string $deletedField + */ + + /* + * Sets $useSoftDeletes value so that we can temporarily override + * the softdeletes settings. Can be used for all find* methods. + * + * @param boolean $val + * + * @return Model + */ + // public function withDeleted($val = true); + + /** + * Faked data for Fabricator. + * + * @param Generator $faker + * + * @return array|object + */ + // public function fake(Generator &$faker); +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockAppConfig.php b/vendor/codeigniter4/framework/system/Test/Mock/MockAppConfig.php new file mode 100644 index 0000000..fba7b76 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockAppConfig.php @@ -0,0 +1,34 @@ +output = $output; + + return $this; + } + + //-------------------------------------------------------------------- + + protected function sendRequest(array $curl_options = []): string + { + // Save so we can access later. + $this->curl_options = $curl_options; + + return $this->output; + } + + //-------------------------------------------------------------------- + // for testing purposes only + public function getBaseURI() + { + return $this->baseURI; + } + + // for testing purposes only + public function getDelay() + { + return $this->delay; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockCache.php b/vendor/codeigniter4/framework/system/Test/Mock/MockCache.php new file mode 100644 index 0000000..855cb7b --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockCache.php @@ -0,0 +1,198 @@ +prefix . $key; + + return array_key_exists($key, $this->cache) + ? $this->cache[$key] + : null; + } + + //-------------------------------------------------------------------- + + /** + * Saves an item to the cache store. + * + * The $raw parameter is only utilized by Mamcache in order to + * allow usage of increment() and decrement(). + * + * @param string $key Cache item name + * @param $value the data to save + * @param null $ttl Time To Live, in seconds (default 60) + * @param boolean $raw Whether to store the raw value. + * + * @return mixed + */ + public function save(string $key, $value, int $ttl = 60, bool $raw = false) + { + $key = $this->prefix . $key; + + $this->cache[$key] = $value; + + return true; + } + + //-------------------------------------------------------------------- + + /** + * Deletes a specific item from the cache store. + * + * @param string $key Cache item name + * + * @return mixed + */ + public function delete(string $key) + { + unset($this->cache[$key]); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic incrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function increment(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $data = $this->cache[$key] ?: null; + + if (empty($data)) + { + $data = 0; + } + elseif (! is_int($data)) + { + return false; + } + + return $this->save($key, $data + $offset); + } + + //-------------------------------------------------------------------- + + /** + * Performs atomic decrementation of a raw stored value. + * + * @param string $key Cache ID + * @param integer $offset Step/value to increase by + * + * @return mixed + */ + public function decrement(string $key, int $offset = 1) + { + $key = $this->prefix . $key; + + $data = $this->cache[$key] ?: null; + + if (empty($data)) + { + $data = 0; + } + elseif (! is_int($data)) + { + return false; + } + + return $this->save($key, $data - $offset); + } + + //-------------------------------------------------------------------- + + /** + * Will delete all items in the entire cache. + * + * @return mixed + */ + public function clean() + { + $this->cache = []; + } + + //-------------------------------------------------------------------- + + /** + * Returns information on the entire cache. + * + * The information returned and the structure of the data + * varies depending on the handler. + * + * @return mixed + */ + public function getCacheInfo() + { + return []; + } + + //-------------------------------------------------------------------- + + /** + * Returns detailed information about the specific item in the cache. + * + * @param string $key Cache item name. + * + * @return mixed + */ + public function getMetaData(string $key) + { + return false; + } + + //-------------------------------------------------------------------- + + /** + * Determines if the driver is supported on this system. + * + * @return boolean + */ + public function isSupported(): bool + { + return true; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockCodeIgniter.php b/vendor/codeigniter4/framework/system/Test/Mock/MockCodeIgniter.php new file mode 100644 index 0000000..5580fd1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockCodeIgniter.php @@ -0,0 +1,11 @@ +returnValues[$method] = $return; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Orchestrates a query against the database. Queries must use + * Database\Statement objects to store the query and build it. + * This method works with the cache. + * + * Should automatically handle different connections for read/write + * queries if needed. + * + * @param string $sql + * @param mixed ...$binds + * @param boolean $setEscapeFlags + * @param string $queryClass + * + * @return \CodeIgniter\Database\BaseResult|\CodeIgniter\Database\Query|false + */ + + public function query(string $sql, $binds = null, bool $setEscapeFlags = true, string $queryClass = 'CodeIgniter\\Database\\Query') + { + $queryClass = str_replace('Connection', 'Query', get_class($this)); + + $query = new $queryClass($this); + + $query->setQuery($sql, $binds, $setEscapeFlags); + + if (! empty($this->swapPre) && ! empty($this->DBPrefix)) + { + $query->swapPrefix($this->DBPrefix, $this->swapPre); + } + + $startTime = microtime(true); + + $this->lastQuery = $query; + + // Run the query + if (false === ($this->resultID = $this->simpleQuery($query->getQuery()))) + { + $query->setDuration($startTime, $startTime); + + // @todo deal with errors + + return false; + } + + $query->setDuration($startTime); + + $resultClass = str_replace('Connection', 'Result', get_class($this)); + + return new $resultClass($this->connID, $this->resultID); + } + + //-------------------------------------------------------------------- + + /** + * Connect to the database. + * + * @param boolean $persistent + * + * @return mixed + */ + public function connect(bool $persistent = false) + { + $return = $this->returnValues['connect'] ?? true; + + if (is_array($return)) + { + // By removing the top item here, we can + // get a different value for, say, testing failover connections. + $return = array_shift($this->returnValues['connect']); + } + + return $return; + } + + //-------------------------------------------------------------------- + + /** + * Keep or establish the connection if no queries have been sent for + * a length of time exceeding the server's idle timeout. + * + * @return boolean + */ + public function reconnect(): bool + { + return true; + } + + //-------------------------------------------------------------------- + + /** + * Select a specific database table to use. + * + * @param string $databaseName + * + * @return mixed + */ + public function setDatabase(string $databaseName) + { + $this->database = $databaseName; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns a string containing the version of the database being used. + * + * @return string + */ + public function getVersion(): string + { + return CodeIgniter::CI_VERSION; + } + + //-------------------------------------------------------------------- + + /** + * Executes the query against the database. + * + * @param string $sql + * + * @return mixed + */ + protected function execute(string $sql) + { + return $this->returnValues['execute']; + } + + //-------------------------------------------------------------------- + + /** + * Returns the total number of rows affected by this query. + * + * @return integer + */ + public function affectedRows(): int + { + return 1; + } + + //-------------------------------------------------------------------- + + /** + * Returns the last error code and message. + * + * Must return an array with keys 'code' and 'message': + * + * return ['code' => null, 'message' => null); + * + * @return array + */ + public function error(): array + { + return [ + 'code' => null, + 'message' => null, + ]; + } + + //-------------------------------------------------------------------- + + /** + * Insert ID + * + * @return integer + */ + public function insertID(): int + { + return $this->connID->insert_id; + } + + //-------------------------------------------------------------------- + + /** + * Generates the SQL for listing tables in a platform-dependent manner. + * + * @param boolean $constrainByPrefix + * + * @return string + */ + protected function _listTables(bool $constrainByPrefix = false): string + { + return ''; + } + + //-------------------------------------------------------------------- + + /** + * Generates a platform-specific query string so that the column names can be fetched. + * + * @param string $table + * + * @return string + */ + protected function _listColumns(string $table = ''): string + { + return ''; + } + + /** + * @param string $table + * @return array + */ + protected function _fieldData(string $table): array + { + return []; + } + + /** + * @param string $table + * @return array + */ + protected function _indexData(string $table): array + { + return []; + } + + /** + * @param string $table + * @return array + */ + protected function _foreignKeyData(string $table): array + { + return []; + } + + //-------------------------------------------------------------------- + + /** + * Close the connection. + */ + protected function _close() + { + } + + //-------------------------------------------------------------------- + + /** + * Begin Transaction + * + * @return boolean + */ + protected function _transBegin(): bool + { + return true; + } + + //-------------------------------------------------------------------- + + /** + * Commit Transaction + * + * @return boolean + */ + protected function _transCommit(): bool + { + return true; + } + + //-------------------------------------------------------------------- + + /** + * Rollback Transaction + * + * @return boolean + */ + protected function _transRollback(): bool + { + return true; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockEmail.php b/vendor/codeigniter4/framework/system/Test/Mock/MockEmail.php new file mode 100644 index 0000000..ab62a77 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockEmail.php @@ -0,0 +1,31 @@ +returnValue) + { + $this->setArchiveValues(); + + if ($autoClear) + { + $this->clear(); + } + + Events::trigger('email', $this->archive); + } + + return $this->returnValue; + } +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockEvents.php b/vendor/codeigniter4/framework/system/Test/Mock/MockEvents.php new file mode 100644 index 0000000..e8b3f43 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockEvents.php @@ -0,0 +1,66 @@ +handles = $config['handles'] ?? []; + $this->destination = $this->path . 'log-' . date('Y-m-d') . '.' . $this->fileExtension; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockIncomingRequest.php b/vendor/codeigniter4/framework/system/Test/Mock/MockIncomingRequest.php new file mode 100644 index 0000000..64d7b2e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockIncomingRequest.php @@ -0,0 +1,17 @@ +language[$locale ?? $this->locale][$file] = $data; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Provides an override that allows us to set custom + * data to be returned easily during testing. + * + * @param string $path + * + * @return array|mixed + */ + protected function requireFile(string $path): array + { + return $this->data ?? []; + } + + //-------------------------------------------------------------------- + + /** + * Arbitrarily turnoff internationalization support for testing + */ + public function disableIntlSupport() + { + $this->intlSupport = false; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockLogger.php b/vendor/codeigniter4/framework/system/Test/Mock/MockLogger.php new file mode 100644 index 0000000..239dab5 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockLogger.php @@ -0,0 +1,98 @@ + [ + /* + * The log levels that this handler will handle. + */ + 'handles' => [ + 'critical', + 'alert', + 'emergency', + 'debug', + 'error', + 'info', + 'notice', + 'warning', + ], + + /* + * Logging Directory Path + */ + 'path' => '', + ], + ]; + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockQuery.php b/vendor/codeigniter4/framework/system/Test/Mock/MockQuery.php new file mode 100644 index 0000000..851ad3e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockQuery.php @@ -0,0 +1,8 @@ +model; + } + + public function getModelName() + { + return $this->modelName; + } + + public function getFormat() + { + return $this->format; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockResourcePresenter.php b/vendor/codeigniter4/framework/system/Test/Mock/MockResourcePresenter.php new file mode 100644 index 0000000..84f831c --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockResourcePresenter.php @@ -0,0 +1,23 @@ +model; + } + + public function getModelName() + { + return $this->modelName; + } + + public function getFormat() + { + return $this->format; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockResponse.php b/vendor/codeigniter4/framework/system/Test/Mock/MockResponse.php new file mode 100644 index 0000000..67f1a7d --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockResponse.php @@ -0,0 +1,30 @@ +pretend; + } + + // artificial error for testing + public function misbehave() + { + $this->statusCode = 0; + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockResult.php b/vendor/codeigniter4/framework/system/Test/Mock/MockResult.php new file mode 100644 index 0000000..a76e9dd --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockResult.php @@ -0,0 +1,93 @@ +CSRFHash; + + return $this; + } + + //-------------------------------------------------------------------- + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockServices.php b/vendor/codeigniter4/framework/system/Test/Mock/MockServices.php new file mode 100644 index 0000000..5d9e736 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockServices.php @@ -0,0 +1,27 @@ + TESTPATH . '_support/', + ]; + public $classmap = []; + + //-------------------------------------------------------------------- + + public function __construct() + { + // Don't call the parent since we don't want the default mappings. + // parent::__construct(); + } + + //-------------------------------------------------------------------- + public static function locator(bool $getShared = true) + { + return new \CodeIgniter\Autoloader\FileLocator(static::autoloader()); + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockSession.php b/vendor/codeigniter4/framework/system/Test/Mock/MockSession.php new file mode 100644 index 0000000..e69183e --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockSession.php @@ -0,0 +1,72 @@ +driver, true); + } + + //-------------------------------------------------------------------- + + /** + * Starts the session. + * Extracted for testing reasons. + */ + protected function startSession() + { + // session_start(); + } + + //-------------------------------------------------------------------- + + /** + * Takes care of setting the cookie on the client side. + * Extracted for testing reasons. + */ + protected function setCookie() + { + $this->cookies[] = [ + $this->sessionCookieName, + session_id(), + (empty($this->sessionExpiration) ? 0 : time() + $this->sessionExpiration), + $this->cookiePath, + $this->cookieDomain, + $this->cookieSecure, + true, + ]; + } + + //-------------------------------------------------------------------- + + public function regenerate(bool $destroy = false) + { + $this->didRegenerate = true; + $_SESSION['__ci_last_regenerate'] = time(); + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/Test/Mock/MockTable.php b/vendor/codeigniter4/framework/system/Test/Mock/MockTable.php new file mode 100644 index 0000000..3e5758b --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/Mock/MockTable.php @@ -0,0 +1,16 @@ +setAccessible(true); + $obj = (gettype($obj) === 'object') ? $obj : null; + + return function () use ($obj, $ref_method) { + $args = func_get_args(); + return $ref_method->invokeArgs($obj, $args); + }; + } + + /** + * Find an accessible property. + * + * @param object $obj + * @param string $property + * + * @return \ReflectionProperty + * @throws \ReflectionException + */ + private static function getAccessibleRefProperty($obj, $property) + { + if (is_object($obj)) + { + $ref_class = new ReflectionObject($obj); + } + else + { + $ref_class = new ReflectionClass($obj); + } + + $ref_property = $ref_class->getProperty($property); + $ref_property->setAccessible(true); + + return $ref_property; + } + + /** + * Set a private property. + * + * @param object|string $obj object or class name + * @param string $property property name + * @param mixed $value value + * + * @throws \ReflectionException + */ + public static function setPrivateProperty($obj, $property, $value) + { + $ref_property = self::getAccessibleRefProperty($obj, $property); + $ref_property->setValue($obj, $value); + } + + /** + * Retrieve a private property. + * + * @param object|string $obj object or class name + * @param string $property property name + * + * @return mixed value + * @throws \ReflectionException + */ + public static function getPrivateProperty($obj, $property) + { + $ref_property = self::getAccessibleRefProperty($obj, $property); + return $ref_property->getValue($obj); + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/TestLogger.php b/vendor/codeigniter4/framework/system/Test/TestLogger.php new file mode 100644 index 0000000..f0c1c94 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/TestLogger.php @@ -0,0 +1,82 @@ +assertLogged() methods. + * + * @param string $level + * @param string $message + * @param array $context + * + * @return boolean + */ + public function log($level, $message, array $context = []): bool + { + // While this requires duplicate work, we want to ensure + // we have the final message to test against. + $log_message = $this->interpolate($message, $context); + + // Determine the file and line by finding the first + // backtrace that is not part of our logging system. + $trace = debug_backtrace(); + $file = null; + + foreach ($trace as $row) + { + if (! in_array($row['function'], ['log', 'log_message'])) + { + $file = basename($row['file'] ?? ''); + break; + } + } + + self::$op_logs[] = [ + 'level' => $level, + 'message' => $log_message, + 'file' => $file, + ]; + + // Let the parent do it's thing. + return parent::log($level, $message, $context); + } + + //-------------------------------------------------------------------- + + /** + * Used by CIUnitTestCase class to provide ->assertLogged() methods. + * + * @param string $level + * @param string $message + * + * @return boolean + */ + public static function didLog(string $level, $message) + { + foreach (self::$op_logs as $log) + { + if (strtolower($log['level']) === strtolower($level) && $message === $log['message']) + { + return true; + } + } + + return false; + } + + //-------------------------------------------------------------------- + // Expose cleanFileNames() + public function cleanup($file) + { + return $this->cleanFileNames($file); + } + +} diff --git a/vendor/codeigniter4/framework/system/Test/bootstrap.php b/vendor/codeigniter4/framework/system/Test/bootstrap.php new file mode 100644 index 0000000..89bdc7b --- /dev/null +++ b/vendor/codeigniter4/framework/system/Test/bootstrap.php @@ -0,0 +1,67 @@ +appDirectory) . DIRECTORY_SEPARATOR); +defined('WRITEPATH') || define('WRITEPATH', realpath($paths->writableDirectory) . DIRECTORY_SEPARATOR); +defined('SYSTEMPATH') || define('SYSTEMPATH', realpath($paths->systemDirectory) . DIRECTORY_SEPARATOR); +defined('ROOTPATH') || define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR); +defined('CIPATH') || define('CIPATH', realpath(SYSTEMPATH . '../') . DIRECTORY_SEPARATOR); +defined('FCPATH') || define('FCPATH', realpath(PUBLICPATH) . DIRECTORY_SEPARATOR); +defined('TESTPATH') || define('TESTPATH', realpath(HOMEPATH . 'tests/') . DIRECTORY_SEPARATOR); +defined('SUPPORTPATH') || define('SUPPORTPATH', realpath(TESTPATH . '_support/') . DIRECTORY_SEPARATOR); +defined('COMPOSER_PATH') || define('COMPOSER_PATH', realpath(HOMEPATH . 'vendor/autoload.php')); +defined('VENDORPATH') || define('VENDORPATH', realpath(HOMEPATH . 'vendor') . DIRECTORY_SEPARATOR); + +// Load Common.php from App then System +if (file_exists(APPPATH . 'Common.php')) +{ + require_once APPPATH . 'Common.php'; +} + +require_once SYSTEMPATH . 'Common.php'; + +// Set environment values that would otherwise stop the framework from functioning during tests. +if (! isset($_SERVER['app.baseURL'])) +{ + $_SERVER['app.baseURL'] = 'http://example.com'; +} + +// Load necessary components +require_once SYSTEMPATH . 'Config/AutoloadConfig.php'; +require_once APPPATH . 'Config/Autoload.php'; +require_once APPPATH . 'Config/Constants.php'; +require_once SYSTEMPATH . 'Modules/Modules.php'; +require_once APPPATH . 'Config/Modules.php'; + +require_once SYSTEMPATH . 'Autoloader/Autoloader.php'; +require_once SYSTEMPATH . 'Config/BaseService.php'; +require_once SYSTEMPATH . 'Config/Services.php'; +require_once APPPATH . 'Config/Services.php'; + +// Use Config\Services as CodeIgniter\Services +if (! class_exists('CodeIgniter\Services', false)) +{ + class_alias('Config\Services', 'CodeIgniter\Services'); +} + +// Launch the autoloader to gather namespaces (includes composer.json's "autoload-dev") +$loader = \CodeIgniter\Services::autoloader(); +$loader->initialize(new Config\Autoload(), new Config\Modules()); + +// Register the loader with the SPL autoloader stack. +$loader->register(); + +require_once APPPATH . 'Config/Routes.php'; +$routes->getRoutes('*'); diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Escaper.php b/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Escaper.php new file mode 100644 index 0000000..9f903a5 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Escaper.php @@ -0,0 +1,391 @@ + 'quot', // quotation mark + 38 => 'amp', // ampersand + 60 => 'lt', // less-than sign + 62 => 'gt', // greater-than sign + ]; + + /** + * Current encoding for escaping. If not UTF-8, we convert strings from this encoding + * pre-escaping and back to this encoding post-escaping. + * + * @var string + */ + protected $encoding = 'utf-8'; + + /** + * Holds the value of the special flags passed as second parameter to + * htmlspecialchars(). + * + * @var int + */ + protected $htmlSpecialCharsFlags; + + /** + * Static Matcher which escapes characters for HTML Attribute contexts + * + * @var callable + */ + protected $htmlAttrMatcher; + + /** + * Static Matcher which escapes characters for Javascript contexts + * + * @var callable + */ + protected $jsMatcher; + + /** + * Static Matcher which escapes characters for CSS Attribute contexts + * + * @var callable + */ + protected $cssMatcher; + + /** + * List of all encoding supported by this class + * + * @var array + */ + protected $supportedEncodings = [ + 'iso-8859-1', 'iso8859-1', 'iso-8859-5', 'iso8859-5', + 'iso-8859-15', 'iso8859-15', 'utf-8', 'cp866', + 'ibm866', '866', 'cp1251', 'windows-1251', + 'win-1251', '1251', 'cp1252', 'windows-1252', + '1252', 'koi8-r', 'koi8-ru', 'koi8r', + 'big5', '950', 'gb2312', '936', + 'big5-hkscs', 'shift_jis', 'sjis', 'sjis-win', + 'cp932', '932', 'euc-jp', 'eucjp', + 'eucjp-win', 'macroman' + ]; + + /** + * Constructor: Single parameter allows setting of global encoding for use by + * the current object. + * + * @param string $encoding + * @throws Exception\InvalidArgumentException + */ + public function __construct($encoding = null) + { + if ($encoding !== null) { + if (! is_string($encoding)) { + throw new Exception\InvalidArgumentException( + get_class($this) . ' constructor parameter must be a string, received ' . gettype($encoding) + ); + } + if ($encoding === '') { + throw new Exception\InvalidArgumentException( + get_class($this) . ' constructor parameter does not allow a blank value' + ); + } + + $encoding = strtolower($encoding); + if (! in_array($encoding, $this->supportedEncodings)) { + throw new Exception\InvalidArgumentException( + 'Value of \'' . $encoding . '\' passed to ' . get_class($this) + . ' constructor parameter is invalid. Provide an encoding supported by htmlspecialchars()' + ); + } + + $this->encoding = $encoding; + } + + // We take advantage of ENT_SUBSTITUTE flag to correctly deal with invalid UTF-8 sequences. + $this->htmlSpecialCharsFlags = ENT_QUOTES | ENT_SUBSTITUTE; + + // set matcher callbacks + $this->htmlAttrMatcher = [$this, 'htmlAttrMatcher']; + $this->jsMatcher = [$this, 'jsMatcher']; + $this->cssMatcher = [$this, 'cssMatcher']; + } + + /** + * Return the encoding that all output/input is expected to be encoded in. + * + * @return string + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Escape a string for the HTML Body context where there are very few characters + * of special meaning. Internally this will use htmlspecialchars(). + * + * @param string $string + * @return string + */ + public function escapeHtml($string) + { + return htmlspecialchars($string, $this->htmlSpecialCharsFlags, $this->encoding); + } + + /** + * Escape a string for the HTML Attribute context. We use an extended set of characters + * to escape that are not covered by htmlspecialchars() to cover cases where an attribute + * might be unquoted or quoted illegally (e.g. backticks are valid quotes for IE). + * + * @param string $string + * @return string + */ + public function escapeHtmlAttr($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9,\.\-_]/iSu', $this->htmlAttrMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Escape a string for the Javascript context. This does not use json_encode(). An extended + * set of characters are escaped beyond ECMAScript's rules for Javascript literal string + * escaping in order to prevent misinterpretation of Javascript as HTML leading to the + * injection of special characters and entities. The escaping used should be tolerant + * of cases where HTML escaping was not applied on top of Javascript escaping correctly. + * Backslash escaping is not used as it still leaves the escaped character as-is and so + * is not useful in a HTML context. + * + * @param string $string + * @return string + */ + public function escapeJs($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9,\._]/iSu', $this->jsMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Escape a string for the URI or Parameter contexts. This should not be used to escape + * an entire URI - only a subcomponent being inserted. The function is a simple proxy + * to rawurlencode() which now implements RFC 3986 since PHP 5.3 completely. + * + * @param string $string + * @return string + */ + public function escapeUrl($string) + { + return rawurlencode($string); + } + + /** + * Escape a string for the CSS context. CSS escaping can be applied to any string being + * inserted into CSS and escapes everything except alphanumerics. + * + * @param string $string + * @return string + */ + public function escapeCss($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9]/iSu', $this->cssMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Callback function for preg_replace_callback that applies HTML Attribute + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function htmlAttrMatcher($matches) + { + $chr = $matches[0]; + $ord = ord($chr); + + /** + * The following replaces characters undefined in HTML with the + * hex entity for the Unicode replacement character. + */ + if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") + || ($ord >= 0x7f && $ord <= 0x9f) + ) { + return '�'; + } + + /** + * Check if the current character to escape has a name entity we should + * replace it with while grabbing the integer value of the character. + */ + if (strlen($chr) > 1) { + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); + } + + $hex = bin2hex($chr); + $ord = hexdec($hex); + if (isset(static::$htmlNamedEntityMap[$ord])) { + return '&' . static::$htmlNamedEntityMap[$ord] . ';'; + } + + /** + * Per OWASP recommendations, we'll use upper hex entities + * for any other characters where a named entity does not exist. + */ + if ($ord > 255) { + return sprintf('&#x%04X;', $ord); + } + return sprintf('&#x%02X;', $ord); + } + + /** + * Callback function for preg_replace_callback that applies Javascript + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function jsMatcher($matches) + { + $chr = $matches[0]; + if (strlen($chr) == 1) { + return sprintf('\\x%02X', ord($chr)); + } + $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); + $hex = strtoupper(bin2hex($chr)); + if (strlen($hex) <= 4) { + return sprintf('\\u%04s', $hex); + } + $highSurrogate = substr($hex, 0, 4); + $lowSurrogate = substr($hex, 4, 4); + return sprintf('\\u%04s\\u%04s', $highSurrogate, $lowSurrogate); + } + + /** + * Callback function for preg_replace_callback that applies CSS + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function cssMatcher($matches) + { + $chr = $matches[0]; + if (strlen($chr) == 1) { + $ord = ord($chr); + } else { + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); + $ord = hexdec(bin2hex($chr)); + } + return sprintf('\\%X ', $ord); + } + + /** + * Converts a string to UTF-8 from the base encoding. The base encoding is set via this + * class' constructor. + * + * @param string $string + * @throws Exception\RuntimeException + * @return string + */ + protected function toUtf8($string) + { + if ($this->getEncoding() === 'utf-8') { + $result = $string; + } else { + $result = $this->convertEncoding($string, 'UTF-8', $this->getEncoding()); + } + + if (! $this->isUtf8($result)) { + throw new Exception\RuntimeException( + sprintf('String to be escaped was not valid UTF-8 or could not be converted: %s', $result) + ); + } + + return $result; + } + + /** + * Converts a string from UTF-8 to the base encoding. The base encoding is set via this + * class' constructor. + * @param string $string + * @return string + */ + protected function fromUtf8($string) + { + if ($this->getEncoding() === 'utf-8') { + return $string; + } + + return $this->convertEncoding($string, $this->getEncoding(), 'UTF-8'); + } + + /** + * Checks if a given string appears to be valid UTF-8 or not. + * + * @param string $string + * @return bool + */ + protected function isUtf8($string) + { + return ($string === '' || preg_match('/^./su', $string)); + } + + /** + * Encoding conversion helper which wraps iconv and mbstring where they exist or throws + * and exception where neither is available. + * + * @param string $string + * @param string $to + * @param array|string $from + * @throws Exception\RuntimeException + * @return string + */ + protected function convertEncoding($string, $to, $from) + { + if (function_exists('iconv')) { + $result = iconv($from, $to, $string); + } elseif (function_exists('mb_convert_encoding')) { + $result = mb_convert_encoding($string, $to, $from); + } else { + throw new Exception\RuntimeException( + get_class($this) + . ' requires either the iconv or mbstring extension to be installed' + . ' when escaping for non UTF-8 strings.' + ); + } + + if ($result === false) { + return ''; // return non-fatal blank string on encoding errors from users + } + return $result; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/ExceptionInterface.php b/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/ExceptionInterface.php new file mode 100644 index 0000000..7ebe04e --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Escaper/Exception/ExceptionInterface.php @@ -0,0 +1,13 @@ + true, + T_COMMENT => true, + T_DOC_COMMENT => true, + T_INLINE_HTML => true, + T_OPEN_TAG => true, + T_OPEN_TAG_WITH_ECHO => true, + T_WHITESPACE => true, + ); + + /** + * Things we need to do specially for operator tokens: + * - Refuse to strip spaces around them + * - Wrap the access path in parentheses if there + * are any of these in the final short parameter. + */ + private static $operator = array( + T_AND_EQUAL => true, + T_BOOLEAN_AND => true, + T_BOOLEAN_OR => true, + T_ARRAY_CAST => true, + T_BOOL_CAST => true, + T_CLONE => true, + T_CONCAT_EQUAL => true, + T_DEC => true, + T_DIV_EQUAL => true, + T_DOUBLE_CAST => true, + T_INC => true, + T_INCLUDE => true, + T_INCLUDE_ONCE => true, + T_INSTANCEOF => true, + T_INT_CAST => true, + T_IS_EQUAL => true, + T_IS_GREATER_OR_EQUAL => true, + T_IS_IDENTICAL => true, + T_IS_NOT_EQUAL => true, + T_IS_NOT_IDENTICAL => true, + T_IS_SMALLER_OR_EQUAL => true, + T_LOGICAL_AND => true, + T_LOGICAL_OR => true, + T_LOGICAL_XOR => true, + T_MINUS_EQUAL => true, + T_MOD_EQUAL => true, + T_MUL_EQUAL => true, + T_NEW => true, + T_OBJECT_CAST => true, + T_OR_EQUAL => true, + T_PLUS_EQUAL => true, + T_REQUIRE => true, + T_REQUIRE_ONCE => true, + T_SL => true, + T_SL_EQUAL => true, + T_SR => true, + T_SR_EQUAL => true, + T_STRING_CAST => true, + T_UNSET_CAST => true, + T_XOR_EQUAL => true, + '!' => true, + '%' => true, + '&' => true, + '*' => true, + '+' => true, + '-' => true, + '.' => true, + '/' => true, + ':' => true, + '<' => true, + '=' => true, + '>' => true, + '?' => true, + '^' => true, + '|' => true, + '~' => true, + ); + + private static $strip = array( + '(' => true, + ')' => true, + '[' => true, + ']' => true, + '{' => true, + '}' => true, + T_OBJECT_OPERATOR => true, + T_DOUBLE_COLON => true, + T_NS_SEPARATOR => true, + ); + + public static function getFunctionCalls($source, $line, $function) + { + static $up = array( + '(' => true, + '[' => true, + '{' => true, + T_CURLY_OPEN => true, + T_DOLLAR_OPEN_CURLY_BRACES => true, + ); + static $down = array( + ')' => true, + ']' => true, + '}' => true, + ); + static $modifiers = array( + '!' => true, + '@' => true, + '~' => true, + '+' => true, + '-' => true, + ); + static $identifier = array( + T_DOUBLE_COLON => true, + T_STRING => true, + T_NS_SEPARATOR => true, + ); + + if (KINT_PHP56) { + self::$operator[T_POW] = true; + self::$operator[T_POW_EQUAL] = true; + } + + if (KINT_PHP70) { + self::$operator[T_SPACESHIP] = true; + } + + if (KINT_PHP74) { + self::$operator[T_COALESCE_EQUAL] = true; + } + + $tokens = \token_get_all($source); + $cursor = 1; + $function_calls = array(); + /** @var array Performance optimization preventing backwards loops */ + $prev_tokens = array(null, null, null); + + if (\is_array($function)) { + $class = \explode('\\', $function[0]); + $class = \strtolower(\end($class)); + $function = \strtolower($function[1]); + } else { + $class = null; + $function = \strtolower($function); + } + + // Loop through tokens + foreach ($tokens as $index => $token) { + if (!\is_array($token)) { + continue; + } + + // Count newlines for line number instead of using $token[2] + // since certain situations (String tokens after whitespace) may + // not have the correct line number unless you do this manually + $cursor += \substr_count($token[1], "\n"); + if ($cursor > $line) { + break; + } + + // Store the last real tokens for later + if (isset(self::$ignore[$token[0]])) { + continue; + } + + $prev_tokens = array($prev_tokens[1], $prev_tokens[2], $token); + + // Check if it's the right type to be the function we're looking for + if (T_STRING !== $token[0] || \strtolower($token[1]) !== $function) { + continue; + } + + // Check if it's a function call + $nextReal = self::realTokenIndex($tokens, $index); + if (!isset($nextReal, $tokens[$nextReal]) || '(' !== $tokens[$nextReal]) { + continue; + } + + // Check if it matches the signature + if (null === $class) { + if ($prev_tokens[1] && \in_array($prev_tokens[1][0], array(T_DOUBLE_COLON, T_OBJECT_OPERATOR), true)) { + continue; + } + } else { + if (!$prev_tokens[1] || T_DOUBLE_COLON !== $prev_tokens[1][0]) { + continue; + } + + if (!$prev_tokens[0] || T_STRING !== $prev_tokens[0][0] || \strtolower($prev_tokens[0][1]) !== $class) { + continue; + } + } + + $inner_cursor = $cursor; + $depth = 1; // The depth respective to the function call + $offset = $nextReal + 1; // The start of the function call + $instring = false; // Whether we're in a string or not + $realtokens = false; // Whether the current scope contains anything meaningful or not + $paramrealtokens = false; // Whether the current parameter contains anything meaningful + $params = array(); // All our collected parameters + $shortparam = array(); // The short version of the parameter + $param_start = $offset; // The distance to the start of the parameter + + // Loop through the following tokens until the function call ends + while (isset($tokens[$offset])) { + $token = $tokens[$offset]; + + // Ensure that the $inner_cursor is correct and + // that $token is either a T_ constant or a string + if (\is_array($token)) { + $inner_cursor += \substr_count($token[1], "\n"); + } + + if (!isset(self::$ignore[$token[0]]) && !isset($down[$token[0]])) { + $paramrealtokens = $realtokens = true; + } + + // If it's a token that makes us to up a level, increase the depth + if (isset($up[$token[0]])) { + if (1 === $depth) { + $shortparam[] = $token; + $realtokens = false; + } + + ++$depth; + } elseif (isset($down[$token[0]])) { + --$depth; + + // If this brings us down to the parameter level, and we've had + // real tokens since going up, fill the $shortparam with an ellipsis + if (1 === $depth) { + if ($realtokens) { + $shortparam[] = '...'; + } + $shortparam[] = $token; + } + } elseif ('"' === $token[0]) { + // Strings use the same symbol for up and down, but we can + // only ever be inside one string, so just use a bool for that + if ($instring) { + --$depth; + if (1 === $depth) { + $shortparam[] = '...'; + } + } else { + ++$depth; + } + + $instring = !$instring; + + $shortparam[] = '"'; + } elseif (1 === $depth) { + if (',' === $token[0]) { + $params[] = array( + 'full' => \array_slice($tokens, $param_start, $offset - $param_start), + 'short' => $shortparam, + ); + $shortparam = array(); + $paramrealtokens = false; + $param_start = $offset + 1; + } elseif (T_CONSTANT_ENCAPSED_STRING === $token[0] && \strlen($token[1]) > 2) { + $shortparam[] = $token[1][0].'...'.$token[1][0]; + } else { + $shortparam[] = $token; + } + } + + // Depth has dropped to 0 (So we've hit the closing paren) + if ($depth <= 0) { + if ($paramrealtokens) { + $params[] = array( + 'full' => \array_slice($tokens, $param_start, $offset - $param_start), + 'short' => $shortparam, + ); + } + + break; + } + + ++$offset; + } + + // If we're not passed (or at) the line at the end + // of the function call, we're too early so skip it + if ($inner_cursor < $line) { + continue; + } + + // Format the final output parameters + foreach ($params as &$param) { + $name = self::tokensFormatted($param['short']); + $expression = false; + foreach ($name as $token) { + if (self::tokenIsOperator($token)) { + $expression = true; + break; + } + } + + $param = array( + 'name' => self::tokensToString($name), + 'path' => self::tokensToString(self::tokensTrim($param['full'])), + 'expression' => $expression, + ); + } + + // Get the modifiers + --$index; + + while (isset($tokens[$index])) { + if (!isset(self::$ignore[$tokens[$index][0]]) && !isset($identifier[$tokens[$index][0]])) { + break; + } + + --$index; + } + + $mods = array(); + + while (isset($tokens[$index])) { + if (isset(self::$ignore[$tokens[$index][0]])) { + --$index; + continue; + } + + if (isset($modifiers[$tokens[$index][0]])) { + $mods[] = $tokens[$index]; + --$index; + continue; + } + + break; + } + + $function_calls[] = array( + 'parameters' => $params, + 'modifiers' => $mods, + ); + } + + return $function_calls; + } + + private static function realTokenIndex(array $tokens, $index) + { + ++$index; + + while (isset($tokens[$index])) { + if (!isset(self::$ignore[$tokens[$index][0]])) { + return $index; + } + + ++$index; + } + + return null; + } + + /** + * We need a separate method to check if tokens are operators because we + * occasionally add "..." to short parameter versions. If we simply check + * for `$token[0]` then "..." will incorrectly match the "." operator. + * + * @param array|string $token The token to check + * + * @return bool + */ + private static function tokenIsOperator($token) + { + return '...' !== $token && isset(self::$operator[$token[0]]); + } + + private static function tokensToString(array $tokens) + { + $out = ''; + + foreach ($tokens as $token) { + if (\is_string($token)) { + $out .= $token; + } elseif (\is_array($token)) { + $out .= $token[1]; + } + } + + return $out; + } + + private static function tokensTrim(array $tokens) + { + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + unset($tokens[$index]); + } else { + break; + } + } + + $tokens = \array_reverse($tokens); + + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + unset($tokens[$index]); + } else { + break; + } + } + + return \array_reverse($tokens); + } + + private static function tokensFormatted(array $tokens) + { + $space = false; + + $tokens = self::tokensTrim($tokens); + + $output = array(); + $last = null; + + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + if ($space) { + continue; + } + + $next = $tokens[self::realTokenIndex($tokens, $index)]; + + if (isset(self::$strip[$last[0]]) && !self::tokenIsOperator($next)) { + continue; + } + + if (isset(self::$strip[$next[0]]) && $last && !self::tokenIsOperator($last)) { + continue; + } + + $token = ' '; + $space = true; + } else { + $space = false; + $last = $token; + } + + $output[] = $token; + } + + return $output; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Kint.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Kint.php new file mode 100644 index 0000000..e0ce963 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Kint.php @@ -0,0 +1,756 @@ + '', + * app_path() => '', + * config_path() => '', + * database_path() => '', + * public_path() => '', + * resource_path() => '', + * storage_path() => '', + * ]; + * + * Defaults to [$_SERVER['DOCUMENT_ROOT'] => ''] + */ + public static $app_root_dirs = array(); + + /** + * @var int max array/object levels to go deep, if zero no limits are applied + */ + public static $max_depth = 6; + + /** + * @var bool expand all trees by default for rich view + */ + public static $expanded = false; + + /** + * @var bool enable detection when Kint is command line. + * + * Formats output with whitespace only; does not HTML-escape it + */ + public static $cli_detection = true; + + /** + * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces + */ + public static $aliases = array( + array('Kint\\Kint', 'dump'), + array('Kint\\Kint', 'trace'), + array('Kint\\Kint', 'dumpArray'), + ); + + /** + * @var array Array of modes to renderer class names + */ + public static $renderers = array( + self::MODE_RICH => 'Kint\\Renderer\\RichRenderer', + self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer', + self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer', + self::MODE_CLI => 'Kint\\Renderer\\CliRenderer', + ); + + public static $plugins = array( + 'Kint\\Parser\\ArrayObjectPlugin', + 'Kint\\Parser\\Base64Plugin', + 'Kint\\Parser\\BlacklistPlugin', + 'Kint\\Parser\\ClassMethodsPlugin', + 'Kint\\Parser\\ClassStaticsPlugin', + 'Kint\\Parser\\ClosurePlugin', + 'Kint\\Parser\\ColorPlugin', + 'Kint\\Parser\\DateTimePlugin', + 'Kint\\Parser\\FsPathPlugin', + 'Kint\\Parser\\IteratorPlugin', + 'Kint\\Parser\\JsonPlugin', + 'Kint\\Parser\\MicrotimePlugin', + 'Kint\\Parser\\SimpleXMLElementPlugin', + 'Kint\\Parser\\SplFileInfoPlugin', + 'Kint\\Parser\\SplObjectStoragePlugin', + 'Kint\\Parser\\StreamPlugin', + 'Kint\\Parser\\TablePlugin', + 'Kint\\Parser\\ThrowablePlugin', + 'Kint\\Parser\\TimestampPlugin', + 'Kint\\Parser\\TracePlugin', + 'Kint\\Parser\\XmlPlugin', + ); + + protected static $plugin_pool = array(); + + protected $parser; + protected $renderer; + + public function __construct(Parser $p, Renderer $r) + { + $this->parser = $p; + $this->renderer = $r; + } + + public function setParser(Parser $p) + { + $this->parser = $p; + } + + public function getParser() + { + return $this->parser; + } + + public function setRenderer(Renderer $r) + { + $this->renderer = $r; + } + + public function getRenderer() + { + return $this->renderer; + } + + public function setStatesFromStatics(array $statics) + { + $this->renderer->setStatics($statics); + + $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false); + $this->parser->clearPlugins(); + + if (!isset($statics['plugins'])) { + return; + } + + $plugins = array(); + + foreach ($statics['plugins'] as $plugin) { + if ($plugin instanceof Plugin) { + $plugins[] = $plugin; + } elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) { + if (!isset(self::$plugin_pool[$plugin])) { + $p = new $plugin(); + self::$plugin_pool[$plugin] = $p; + } + $plugins[] = self::$plugin_pool[$plugin]; + } + } + + $plugins = $this->renderer->filterParserPlugins($plugins); + + foreach ($plugins as $plugin) { + $this->parser->addPlugin($plugin); + } + } + + public function setStatesFromCallInfo(array $info) + { + $this->renderer->setCallInfo($info); + + if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) { + $this->parser->setDepthLimit(false); + } + + $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null); + } + + /** + * Renders a list of vars including the pre and post renders. + * + * @param array $vars Data to dump + * @param BasicObject[] $base Base objects + * + * @return string + */ + public function dumpAll(array $vars, array $base) + { + if (\array_keys($vars) !== \array_keys($base)) { + throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments'); + } + + $output = $this->renderer->preRender(); + + if ($vars === array()) { + $output .= $this->renderer->renderNothing(); + } + + foreach ($vars as $key => $arg) { + if (!$base[$key] instanceof BasicObject) { + throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances'); + } + $output .= $this->dumpVar($arg, $base[$key]); + } + + $output .= $this->renderer->postRender(); + + return $output; + } + + /** + * Dumps and renders a var. + * + * @param mixed $var Data to dump + * @param BasicObject $base Base object + * + * @return string + */ + public function dumpVar(&$var, BasicObject $base) + { + return $this->renderer->render( + $this->parser->parse($var, $base) + ); + } + + /** + * Gets all static settings at once. + * + * @return array Current static settings + */ + public static function getStatics() + { + return array( + 'aliases' => self::$aliases, + 'app_root_dirs' => self::$app_root_dirs, + 'cli_detection' => self::$cli_detection, + 'display_called_from' => self::$display_called_from, + 'enabled_mode' => self::$enabled_mode, + 'expanded' => self::$expanded, + 'file_link_format' => self::$file_link_format, + 'max_depth' => self::$max_depth, + 'mode_default' => self::$mode_default, + 'mode_default_cli' => self::$mode_default_cli, + 'plugins' => self::$plugins, + 'renderers' => self::$renderers, + 'return' => self::$return, + ); + } + + /** + * Creates a Kint instances based on static settings. + * + * Also calls setStatesFromStatics for you + * + * @param array $statics array of statics as returned by getStatics + * + * @return null|\Kint\Kint + */ + public static function createFromStatics(array $statics) + { + $mode = false; + + if (isset($statics['enabled_mode'])) { + $mode = $statics['enabled_mode']; + + if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) { + $mode = $statics['mode_default']; + + if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) { + $mode = $statics['mode_default_cli']; + } + } + } + + if (!$mode) { + return null; + } + + if (!isset($statics['renderers'][$mode])) { + $renderer = new TextRenderer(); + } else { + /** @var Renderer */ + $renderer = new $statics['renderers'][$mode](); + } + + return new self(new Parser(), $renderer); + } + + /** + * Creates base objects given parameter info. + * + * @param array $params Parameters as returned from getCallInfo + * @param int $argc Number of arguments the helper was called with + * + * @return BasicObject[] Base objects for the arguments + */ + public static function getBasesFromParamInfo(array $params, $argc) + { + static $blacklist = array( + 'null', + 'true', + 'false', + 'array(...)', + 'array()', + '[...]', + '[]', + '(...)', + '()', + '"..."', + 'b"..."', + "'...'", + "b'...'", + ); + + $params = \array_values($params); + $bases = array(); + + for ($i = 0; $i < $argc; ++$i) { + if (isset($params[$i])) { + $param = $params[$i]; + } else { + $param = null; + } + + if (!isset($param['name']) || \is_numeric($param['name'])) { + $name = null; + } elseif (\in_array(\strtolower($param['name']), $blacklist, true)) { + $name = null; + } else { + $name = $param['name']; + } + + if (isset($param['path'])) { + $access_path = $param['path']; + + if (!empty($param['expression'])) { + $access_path = '('.$access_path.')'; + } + } else { + $access_path = '$'.$i; + } + + $bases[] = BasicObject::blank($name, $access_path); + } + + return $bases; + } + + /** + * Gets call info from the backtrace, alias, and argument count. + * + * Aliases must be normalized beforehand (Utils::normalizeAliases) + * + * @param array $aliases Call aliases as found in Kint::$aliases + * @param array[] $trace Backtrace + * @param int $argc Number of arguments + * + * @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info + */ + public static function getCallInfo(array $aliases, array $trace, $argc) + { + $found = false; + $callee = null; + $caller = null; + $miniTrace = array(); + + foreach ($trace as $index => $frame) { + if (Utils::traceFrameIsListed($frame, $aliases)) { + $found = true; + $miniTrace = array(); + } + + if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) { + $miniTrace[] = $frame; + } + } + + if ($found) { + $callee = \reset($miniTrace) ?: null; + + /** @var null|array Psalm bug workaround */ + $caller = \next($miniTrace) ?: null; + } + + foreach ($miniTrace as $index => $frame) { + if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) { + unset($frame['object'], $frame['args']); + $miniTrace[$index] = $frame; + } else { + unset($miniTrace[$index]); + } + } + + $miniTrace = \array_values($miniTrace); + + $call = self::getSingleCall($callee ?: array(), $argc); + + $ret = array( + 'params' => null, + 'modifiers' => array(), + 'callee' => $callee, + 'caller' => $caller, + 'trace' => $miniTrace, + ); + + if ($call) { + $ret['params'] = $call['parameters']; + $ret['modifiers'] = $call['modifiers']; + } + + return $ret; + } + + /** + * Dumps a backtrace. + * + * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true)) + * + * @return int|string + */ + public static function trace() + { + if (!self::$enabled_mode) { + return 0; + } + + Utils::normalizeAliases(self::$aliases); + + $args = \func_get_args(); + + $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); + + $statics = self::getStatics(); + + if (\in_array('~', $call_info['modifiers'], true)) { + $statics['enabled_mode'] = self::MODE_TEXT; + } + + $kintstance = self::createFromStatics($statics); + if (!$kintstance) { + // Should never happen + return 0; // @codeCoverageIgnore + } + + if (\in_array('-', $call_info['modifiers'], true)) { + while (\ob_get_level()) { + \ob_end_clean(); + } + } + + $kintstance->setStatesFromStatics($statics); + $kintstance->setStatesFromCallInfo($call_info); + + $trimmed_trace = array(); + $trace = \debug_backtrace(true); + + foreach ($trace as $frame) { + if (Utils::traceFrameIsListed($frame, self::$aliases)) { + $trimmed_trace = array(); + } + + $trimmed_trace[] = $frame; + } + + $output = $kintstance->dumpAll( + array($trimmed_trace), + array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)')) + ); + + if (self::$return || \in_array('@', $call_info['modifiers'], true)) { + return $output; + } + + echo $output; + + if (\in_array('-', $call_info['modifiers'], true)) { + \flush(); // @codeCoverageIgnore + } + + return 0; + } + + /** + * Dumps some data. + * + * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true)) + * + * @return int|string + */ + public static function dump() + { + if (!self::$enabled_mode) { + return 0; + } + + Utils::normalizeAliases(self::$aliases); + + $args = \func_get_args(); + + $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); + + $statics = self::getStatics(); + + if (\in_array('~', $call_info['modifiers'], true)) { + $statics['enabled_mode'] = self::MODE_TEXT; + } + + $kintstance = self::createFromStatics($statics); + if (!$kintstance) { + // Should never happen + return 0; // @codeCoverageIgnore + } + + if (\in_array('-', $call_info['modifiers'], true)) { + while (\ob_get_level()) { + \ob_end_clean(); + } + } + + $kintstance->setStatesFromStatics($statics); + $kintstance->setStatesFromCallInfo($call_info); + + // If the call is Kint::dump(1) then dump a backtrace instead + if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) { + $args = \debug_backtrace(true); + $trace = array(); + + foreach ($args as $index => $frame) { + if (Utils::traceFrameIsListed($frame, self::$aliases)) { + $trace = array(); + } + + $trace[] = $frame; + } + + if (isset($call_info['callee']['function'])) { + $tracename = $call_info['callee']['function'].'(1)'; + if (isset($call_info['callee']['class'], $call_info['callee']['type'])) { + $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename; + } + } else { + $tracename = 'Kint\\Kint::dump(1)'; + } + + $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)'); + + $output = $kintstance->dumpAll(array($trace), array($tracebase)); + } else { + $bases = self::getBasesFromParamInfo( + isset($call_info['params']) ? $call_info['params'] : array(), + \count($args) + ); + $output = $kintstance->dumpAll($args, $bases); + } + + if (self::$return || \in_array('@', $call_info['modifiers'], true)) { + return $output; + } + + echo $output; + + if (\in_array('-', $call_info['modifiers'], true)) { + \flush(); // @codeCoverageIgnore + } + + return 0; + } + + /** + * generic path display callback, can be configured in app_root_dirs; purpose is + * to show relevant path info and hide as much of the path as possible. + * + * @param string $file + * + * @return string + */ + public static function shortenPath($file) + { + $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen')); + + $longest_match = 0; + $match = '/'; + + foreach (self::$app_root_dirs as $path => $alias) { + if (empty($path)) { + continue; + } + + $path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen')); + + if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) { + $longest_match = \count($path); + $match = $alias; + } + } + + if ($longest_match) { + $file = \array_merge(array($match), \array_slice($file, $longest_match)); + + return \implode('/', $file); + } + + // fallback to find common path with Kint dir + $kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen')); + + foreach ($file as $i => $part) { + if (!isset($kint[$i]) || $kint[$i] !== $part) { + return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i)); + } + } + + return '/'.\implode('/', $file); + } + + public static function getIdeLink($file, $line) + { + return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format); + } + + /** + * Returns specific function call info from a stack trace frame, or null if no match could be found. + * + * @param array $frame The stack trace frame in question + * @param int $argc The amount of arguments received + * + * @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined + */ + protected static function getSingleCall(array $frame, $argc) + { + if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) { + return null; + } + + if (empty($frame['class'])) { + $callfunc = $frame['function']; + } else { + $callfunc = array($frame['class'], $frame['function']); + } + + $calls = CallFinder::getFunctionCalls( + \file_get_contents($frame['file']), + $frame['line'], + $callfunc + ); + + $return = null; + + foreach ($calls as $call) { + $is_unpack = false; + + // Handle argument unpacking as a last resort + if (KINT_PHP56) { + foreach ($call['parameters'] as $i => &$param) { + if (0 === \strpos($param['name'], '...')) { + if ($i < $argc && $i === \count($call['parameters']) - 1) { + for ($j = 1; $j + $i < $argc; ++$j) { + $call['parameters'][] = array( + 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', + 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', + 'expression' => false, + ); + } + + $param['name'] = 'reset('.\substr($param['name'], 3).')'; + $param['path'] = 'reset('.\substr($param['path'], 3).')'; + $param['expression'] = false; + } else { + $call['parameters'] = \array_slice($call['parameters'], 0, $i); + } + + $is_unpack = true; + break; + } + + if ($i >= $argc) { + continue 2; + } + } + } + + if ($is_unpack || \count($call['parameters']) === $argc) { + if (null === $return) { + $return = $call; + } else { + // If we have multiple calls on the same line with the same amount of arguments, + // we can't be sure which it is so just return null and let them figure it out + return null; + } + } + } + + return $return; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BasicObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BasicObject.php new file mode 100644 index 0000000..d69347e --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BasicObject.php @@ -0,0 +1,248 @@ +representations[$rep->getName()])) { + return false; + } + + if (null === $pos) { + $this->representations[$rep->getName()] = $rep; + } else { + $this->representations = \array_merge( + \array_slice($this->representations, 0, $pos), + array($rep->getName() => $rep), + \array_slice($this->representations, $pos) + ); + } + + return true; + } + + public function replaceRepresentation(Representation $rep, $pos = null) + { + if (null === $pos) { + $this->representations[$rep->getName()] = $rep; + } else { + $this->removeRepresentation($rep); + $this->addRepresentation($rep, $pos); + } + } + + public function removeRepresentation($rep) + { + if ($rep instanceof Representation) { + unset($this->representations[$rep->getName()]); + } elseif (\is_string($rep)) { + unset($this->representations[$rep]); + } + } + + public function getRepresentation($name) + { + if (isset($this->representations[$name])) { + return $this->representations[$name]; + } + } + + public function getRepresentations() + { + return $this->representations; + } + + public function clearRepresentations() + { + $this->representations = array(); + } + + public function getType() + { + return $this->type; + } + + public function getModifiers() + { + $out = $this->getAccess(); + + if ($this->const) { + $out .= ' const'; + } + + if ($this->static) { + $out .= ' static'; + } + + if (\strlen($out)) { + return \ltrim($out); + } + } + + public function getAccess() + { + switch ($this->access) { + case self::ACCESS_PRIVATE: + return 'private'; + case self::ACCESS_PROTECTED: + return 'protected'; + case self::ACCESS_PUBLIC: + return 'public'; + } + } + + public function getName() + { + return $this->name; + } + + public function getOperator() + { + switch ($this->operator) { + case self::OPERATOR_ARRAY: + return '=>'; + case self::OPERATOR_OBJECT: + return '->'; + case self::OPERATOR_STATIC: + return '::'; + } + } + + public function getSize() + { + return $this->size; + } + + public function getValueShort() + { + if ($rep = $this->value) { + if ('boolean' === $this->type) { + return $rep->contents ? 'true' : 'false'; + } + + if ('integer' === $this->type || 'double' === $this->type) { + return $rep->contents; + } + } + } + + public function getAccessPath() + { + return $this->access_path; + } + + public function transplant(BasicObject $old) + { + $this->name = $old->name; + $this->size = $old->size; + $this->access_path = $old->access_path; + $this->access = $old->access; + $this->static = $old->static; + $this->const = $old->const; + $this->type = $old->type; + $this->depth = $old->depth; + $this->owner_class = $old->owner_class; + $this->operator = $old->operator; + $this->reference = $old->reference; + $this->value = $old->value; + $this->representations += $old->representations; + $this->hints = \array_merge($this->hints, $old->hints); + } + + /** + * Creates a new basic object with a name and access path. + * + * @param null|string $name + * @param null|string $access_path + * + * @return \Kint\Object\BasicObject + */ + public static function blank($name = null, $access_path = null) + { + $o = new self(); + $o->name = $name; + $o->access_path = $access_path; + + return $o; + } + + public static function sortByAccess(BasicObject $a, BasicObject $b) + { + static $sorts = array( + self::ACCESS_PUBLIC => 1, + self::ACCESS_PROTECTED => 2, + self::ACCESS_PRIVATE => 3, + self::ACCESS_NONE => 4, + ); + + return $sorts[$a->access] - $sorts[$b->access]; + } + + public static function sortByName(BasicObject $a, BasicObject $b) + { + $ret = \strnatcasecmp($a->name, $b->name); + + if (0 === $ret) { + return (int) \is_int($b->name) - (int) \is_int($a->name); + } + + return $ret; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BlobObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BlobObject.php new file mode 100644 index 0000000..66d508f --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/BlobObject.php @@ -0,0 +1,177 @@ +encoding) { + return 'binary '.$this->type; + } + + if ('ASCII' === $this->encoding) { + return $this->type; + } + + return $this->encoding.' '.$this->type; + } + + public function getValueShort() + { + if ($rep = $this->value) { + return '"'.$rep->contents.'"'; + } + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->encoding = $old->encoding; + } + } + + public static function strlen($string, $encoding = false) + { + if (\function_exists('mb_strlen')) { + if (false === $encoding) { + $encoding = self::detectEncoding($string); + } + + if ($encoding && 'ASCII' !== $encoding) { + return \mb_strlen($string, $encoding); + } + } + + return \strlen($string); + } + + public static function substr($string, $start, $length = null, $encoding = false) + { + if (\function_exists('mb_substr')) { + if (false === $encoding) { + $encoding = self::detectEncoding($string); + } + + if ($encoding && 'ASCII' !== $encoding) { + return \mb_substr($string, $start, $length, $encoding); + } + } + + // Special case for substr/mb_substr discrepancy + if ('' === $string) { + return ''; + } + + return \substr($string, $start, isset($length) ? $length : PHP_INT_MAX); + } + + public static function detectEncoding($string) + { + if (\function_exists('mb_detect_encoding')) { + if ($ret = \mb_detect_encoding($string, self::$char_encodings, true)) { + return $ret; + } + } + + // Pretty much every character encoding uses first 32 bytes as control + // characters. If it's not a multi-byte format it's safe to say matching + // any control character besides tab, nl, and cr means it's binary. + if (\preg_match('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', $string)) { + return false; + } + + if (\function_exists('iconv')) { + foreach (self::$legacy_encodings as $encoding) { + if (@\iconv($encoding, $encoding, $string) === $string) { + return $encoding; + } + } + } elseif (!\function_exists('mb_detect_encoding')) { // @codeCoverageIgnore + // If a user has neither mb_detect_encoding, nor iconv, nor the + // polyfills, there's not much we can do about it... + // Pretend it's ASCII and pray the browser renders it properly. + return 'ASCII'; // @codeCoverageIgnore + } + + return false; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ClosureObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ClosureObject.php new file mode 100644 index 0000000..344eceb --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ClosureObject.php @@ -0,0 +1,68 @@ +access_path) { + return parent::getAccessPath().'('.$this->getParams().')'; + } + } + + public function getSize() + { + } + + public function getParams() + { + if (null !== $this->paramcache) { + return $this->paramcache; + } + + $out = array(); + + foreach ($this->parameters as $p) { + $type = $p->getType(); + + $ref = $p->reference ? '&' : ''; + + if ($type) { + $out[] = $type.' '.$ref.$p->getName(); + } else { + $out[] = $ref.$p->getName(); + } + } + + return $this->paramcache = \implode(', ', $out); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/DateTimeObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/DateTimeObject.php new file mode 100644 index 0000000..f8b1b3f --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/DateTimeObject.php @@ -0,0 +1,53 @@ +dt = clone $dt; + } + + public function getValueShort() + { + $stamp = $this->dt->format('Y-m-d H:i:s'); + if ((int) ($micro = $this->dt->format('u'))) { + $stamp .= '.'.$micro; + } + $stamp .= $this->dt->format('P T'); + + return $stamp; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/InstanceObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/InstanceObject.php new file mode 100644 index 0000000..943b33d --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/InstanceObject.php @@ -0,0 +1,78 @@ +classname; + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->classname = $old->classname; + $this->hash = $old->hash; + $this->filename = $old->filename; + $this->startline = $old->startline; + } + } + + public static function sortByHierarchy($a, $b) + { + if (\is_string($a) && \is_string($b)) { + $aclass = $a; + $bclass = $b; + } elseif (!($a instanceof BasicObject) || !($b instanceof BasicObject)) { + return 0; + } elseif ($a instanceof self && $b instanceof self) { + $aclass = $a->classname; + $bclass = $b->classname; + } else { + return 0; + } + + if (\is_subclass_of($aclass, $bclass)) { + return -1; + } + + if (\is_subclass_of($bclass, $aclass)) { + return 1; + } + + return 0; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/MethodObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/MethodObject.php new file mode 100644 index 0000000..78d49de --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/MethodObject.php @@ -0,0 +1,253 @@ +name = $method->getName(); + $this->filename = $method->getFileName(); + $this->startline = $method->getStartLine(); + $this->endline = $method->getEndLine(); + $this->internal = $method->isInternal(); + $this->docstring = $method->getDocComment(); + $this->return_reference = $method->returnsReference(); + + foreach ($method->getParameters() as $param) { + $this->parameters[] = new ParameterObject($param); + } + + if (KINT_PHP70) { + $this->returntype = $method->getReturnType(); + if ($this->returntype) { + $this->returntype = Utils::getTypeString($this->returntype); + } + } + + if ($method instanceof ReflectionMethod) { + $this->static = $method->isStatic(); + $this->operator = $this->static ? BasicObject::OPERATOR_STATIC : BasicObject::OPERATOR_OBJECT; + $this->abstract = $method->isAbstract(); + $this->final = $method->isFinal(); + $this->owner_class = $method->getDeclaringClass()->name; + $this->access = BasicObject::ACCESS_PUBLIC; + if ($method->isProtected()) { + $this->access = BasicObject::ACCESS_PROTECTED; + } elseif ($method->isPrivate()) { + $this->access = BasicObject::ACCESS_PRIVATE; + } + } + + if ($this->internal) { + return; + } + + $docstring = new DocstringRepresentation( + $this->docstring, + $this->filename, + $this->startline + ); + + $docstring->implicit_label = true; + $this->addRepresentation($docstring); + $this->value = $docstring; + } + + public function setAccessPathFrom(InstanceObject $parent) + { + static $magic = array( + '__call' => true, + '__callstatic' => true, + '__clone' => true, + '__construct' => true, + '__debuginfo' => true, + '__destruct' => true, + '__get' => true, + '__invoke' => true, + '__isset' => true, + '__set' => true, + '__set_state' => true, + '__sleep' => true, + '__tostring' => true, + '__unset' => true, + '__wakeup' => true, + ); + + $name = \strtolower($this->name); + + if ('__construct' === $name) { + $this->access_path = 'new \\'.$parent->getType(); + } elseif ('__invoke' === $name) { + $this->access_path = $parent->access_path; + } elseif ('__clone' === $name) { + $this->access_path = 'clone '.$parent->access_path; + $this->showparams = false; + } elseif ('__tostring' === $name) { + $this->access_path = '(string) '.$parent->access_path; + $this->showparams = false; + } elseif (isset($magic[$name])) { + $this->access_path = null; + } elseif ($this->static) { + $this->access_path = '\\'.$this->owner_class.'::'.$this->name; + } else { + $this->access_path = $parent->access_path.'->'.$this->name; + } + } + + public function getValueShort() + { + if (!$this->value || !($this->value instanceof DocstringRepresentation)) { + return parent::getValueShort(); + } + + $ds = $this->value->getDocstringWithoutComments(); + + if (!$ds) { + return null; + } + + $ds = \explode("\n", $ds); + + $out = ''; + + foreach ($ds as $line) { + if (0 === \strlen(\trim($line)) || '@' === $line[0]) { + break; + } + + $out .= $line.' '; + } + + if (\strlen($out)) { + return \rtrim($out); + } + } + + public function getModifiers() + { + $mods = array( + $this->abstract ? 'abstract' : null, + $this->final ? 'final' : null, + $this->getAccess(), + $this->static ? 'static' : null, + ); + + $out = ''; + + foreach ($mods as $word) { + if (null !== $word) { + $out .= $word.' '; + } + } + + if (\strlen($out)) { + return \rtrim($out); + } + } + + public function getAccessPath() + { + if (null !== $this->access_path) { + if ($this->showparams) { + return parent::getAccessPath().'('.$this->getParams().')'; + } + + return parent::getAccessPath(); + } + } + + public function getParams() + { + if (null !== $this->paramcache) { + return $this->paramcache; + } + + $out = array(); + + foreach ($this->parameters as $p) { + $type = $p->getType(); + if ($type) { + $type .= ' '; + } + + $default = $p->getDefault(); + if ($default) { + $default = ' = '.$default; + } + + $ref = $p->reference ? '&' : ''; + + $out[] = $type.$ref.$p->getName().$default; + } + + return $this->paramcache = \implode(', ', $out); + } + + public function getPhpDocUrl() + { + if (!$this->internal) { + return null; + } + + if ($this->owner_class) { + $class = \strtolower($this->owner_class); + } else { + $class = 'function'; + } + + $funcname = \str_replace('_', '-', \strtolower($this->name)); + + if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) { + $funcname = \substr($funcname, 2); + } + + return 'https://secure.php.net/'.$class.'.'.$funcname; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ParameterObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ParameterObject.php new file mode 100644 index 0000000..4bed551 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ParameterObject.php @@ -0,0 +1,100 @@ +getType()) { + $this->type_hint = Utils::getTypeString($type); + } + } else { + if ($param->isArray()) { + $this->type_hint = 'array'; + } else { + try { + if ($this->type_hint = $param->getClass()) { + $this->type_hint = $this->type_hint->name; + } + } catch (ReflectionException $e) { + \preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/s', $param->__toString(), $matches); + $this->type_hint = isset($matches[1]) ? $matches[1] : ''; + } + } + } + + $this->reference = $param->isPassedByReference(); + $this->name = $param->getName(); + $this->position = $param->getPosition(); + + if ($param->isDefaultValueAvailable()) { + /** @var mixed Psalm bug workaround */ + $default = $param->getDefaultValue(); + switch (\gettype($default)) { + case 'NULL': + $this->default = 'null'; + break; + case 'boolean': + $this->default = $default ? 'true' : 'false'; + break; + case 'array': + $this->default = \count($default) ? 'array(...)' : 'array()'; + break; + default: + $this->default = \var_export($default, true); + break; + } + } + } + + public function getType() + { + return $this->type_hint; + } + + public function getName() + { + return '$'.$this->name; + } + + public function getDefault() + { + return $this->default; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/ColorRepresentation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/ColorRepresentation.php new file mode 100644 index 0000000..d6a072f --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/ColorRepresentation.php @@ -0,0 +1,576 @@ + 'f0f8ff', + 'antiquewhite' => 'faebd7', + 'aqua' => '00ffff', + 'aquamarine' => '7fffd4', + 'azure' => 'f0ffff', + 'beige' => 'f5f5dc', + 'bisque' => 'ffe4c4', + 'black' => '000000', + 'blanchedalmond' => 'ffebcd', + 'blue' => '0000ff', + 'blueviolet' => '8a2be2', + 'brown' => 'a52a2a', + 'burlywood' => 'deb887', + 'cadetblue' => '5f9ea0', + 'chartreuse' => '7fff00', + 'chocolate' => 'd2691e', + 'coral' => 'ff7f50', + 'cornflowerblue' => '6495ed', + 'cornsilk' => 'fff8dc', + 'crimson' => 'dc143c', + 'cyan' => '00ffff', + 'darkblue' => '00008b', + 'darkcyan' => '008b8b', + 'darkgoldenrod' => 'b8860b', + 'darkgray' => 'a9a9a9', + 'darkgreen' => '006400', + 'darkgrey' => 'a9a9a9', + 'darkkhaki' => 'bdb76b', + 'darkmagenta' => '8b008b', + 'darkolivegreen' => '556b2f', + 'darkorange' => 'ff8c00', + 'darkorchid' => '9932cc', + 'darkred' => '8b0000', + 'darksalmon' => 'e9967a', + 'darkseagreen' => '8fbc8f', + 'darkslateblue' => '483d8b', + 'darkslategray' => '2f4f4f', + 'darkslategrey' => '2f4f4f', + 'darkturquoise' => '00ced1', + 'darkviolet' => '9400d3', + 'deeppink' => 'ff1493', + 'deepskyblue' => '00bfff', + 'dimgray' => '696969', + 'dimgrey' => '696969', + 'dodgerblue' => '1e90ff', + 'firebrick' => 'b22222', + 'floralwhite' => 'fffaf0', + 'forestgreen' => '228b22', + 'fuchsia' => 'ff00ff', + 'gainsboro' => 'dcdcdc', + 'ghostwhite' => 'f8f8ff', + 'gold' => 'ffd700', + 'goldenrod' => 'daa520', + 'gray' => '808080', + 'green' => '008000', + 'greenyellow' => 'adff2f', + 'grey' => '808080', + 'honeydew' => 'f0fff0', + 'hotpink' => 'ff69b4', + 'indianred' => 'cd5c5c', + 'indigo' => '4b0082', + 'ivory' => 'fffff0', + 'khaki' => 'f0e68c', + 'lavender' => 'e6e6fa', + 'lavenderblush' => 'fff0f5', + 'lawngreen' => '7cfc00', + 'lemonchiffon' => 'fffacd', + 'lightblue' => 'add8e6', + 'lightcoral' => 'f08080', + 'lightcyan' => 'e0ffff', + 'lightgoldenrodyellow' => 'fafad2', + 'lightgray' => 'd3d3d3', + 'lightgreen' => '90ee90', + 'lightgrey' => 'd3d3d3', + 'lightpink' => 'ffb6c1', + 'lightsalmon' => 'ffa07a', + 'lightseagreen' => '20b2aa', + 'lightskyblue' => '87cefa', + 'lightslategray' => '778899', + 'lightslategrey' => '778899', + 'lightsteelblue' => 'b0c4de', + 'lightyellow' => 'ffffe0', + 'lime' => '00ff00', + 'limegreen' => '32cd32', + 'linen' => 'faf0e6', + 'magenta' => 'ff00ff', + 'maroon' => '800000', + 'mediumaquamarine' => '66cdaa', + 'mediumblue' => '0000cd', + 'mediumorchid' => 'ba55d3', + 'mediumpurple' => '9370db', + 'mediumseagreen' => '3cb371', + 'mediumslateblue' => '7b68ee', + 'mediumspringgreen' => '00fa9a', + 'mediumturquoise' => '48d1cc', + 'mediumvioletred' => 'c71585', + 'midnightblue' => '191970', + 'mintcream' => 'f5fffa', + 'mistyrose' => 'ffe4e1', + 'moccasin' => 'ffe4b5', + 'navajowhite' => 'ffdead', + 'navy' => '000080', + 'oldlace' => 'fdf5e6', + 'olive' => '808000', + 'olivedrab' => '6b8e23', + 'orange' => 'ffa500', + 'orangered' => 'ff4500', + 'orchid' => 'da70d6', + 'palegoldenrod' => 'eee8aa', + 'palegreen' => '98fb98', + 'paleturquoise' => 'afeeee', + 'palevioletred' => 'db7093', + 'papayawhip' => 'ffefd5', + 'peachpuff' => 'ffdab9', + 'peru' => 'cd853f', + 'pink' => 'ffc0cb', + 'plum' => 'dda0dd', + 'powderblue' => 'b0e0e6', + 'purple' => '800080', + 'rebeccapurple' => '663399', + 'red' => 'ff0000', + 'rosybrown' => 'bc8f8f', + 'royalblue' => '4169e1', + 'saddlebrown' => '8b4513', + 'salmon' => 'fa8072', + 'sandybrown' => 'f4a460', + 'seagreen' => '2e8b57', + 'seashell' => 'fff5ee', + 'sienna' => 'a0522d', + 'silver' => 'c0c0c0', + 'skyblue' => '87ceeb', + 'slateblue' => '6a5acd', + 'slategray' => '708090', + 'slategrey' => '708090', + 'snow' => 'fffafa', + 'springgreen' => '00ff7f', + 'steelblue' => '4682b4', + 'tan' => 'd2b48c', + 'teal' => '008080', + 'thistle' => 'd8bfd8', + 'tomato' => 'ff6347', + // To quote MDN: + // "Technically, transparent is a shortcut for rgba(0,0,0,0)." + 'transparent' => '00000000', + 'turquoise' => '40e0d0', + 'violet' => 'ee82ee', + 'wheat' => 'f5deb3', + 'white' => 'ffffff', + 'whitesmoke' => 'f5f5f5', + 'yellow' => 'ffff00', + 'yellowgreen' => '9acd32', + ); + + public $r = 0; + public $g = 0; + public $b = 0; + public $a = 1.0; + public $variant; + public $implicit_label = true; + public $hints = array('color'); + + public function __construct($value) + { + parent::__construct('Color'); + + $this->contents = $value; + $this->setValues($value); + } + + public function getColor($variant = null) + { + if (!$variant) { + $variant = $this->variant; + } + + switch ($variant) { + case self::COLOR_NAME: + $hex = \sprintf('%02x%02x%02x', $this->r, $this->g, $this->b); + $hex_alpha = \sprintf('%02x%02x%02x%02x', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); + + return \array_search($hex, self::$color_map, true) ?: \array_search($hex_alpha, self::$color_map, true); + case self::COLOR_HEX_3: + if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11) { + return \sprintf( + '#%1X%1X%1X', + \round($this->r / 0x11), + \round($this->g / 0x11), + \round($this->b / 0x11) + ); + } + + return false; + case self::COLOR_HEX_6: + return \sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b); + case self::COLOR_RGB: + if (1.0 === $this->a) { + return \sprintf('rgb(%d, %d, %d)', $this->r, $this->g, $this->b); + } + + return \sprintf('rgb(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4)); + case self::COLOR_RGBA: + return \sprintf('rgba(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4)); + case self::COLOR_HSL: + $val = self::rgbToHsl($this->r, $this->g, $this->b); + if (1.0 === $this->a) { + return \vsprintf('hsl(%d, %d%%, %d%%)', $val); + } + + return \sprintf('hsl(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4)); + case self::COLOR_HSLA: + $val = self::rgbToHsl($this->r, $this->g, $this->b); + + return \sprintf('hsla(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4)); + case self::COLOR_HEX_4: + if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11 && 0 === ($this->a * 255) % 0x11) { + return \sprintf( + '#%1X%1X%1X%1X', + \round($this->r / 0x11), + \round($this->g / 0x11), + \round($this->b / 0x11), + \round($this->a * 0xF) + ); + } + + return false; + + case self::COLOR_HEX_8: + return \sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); + } + + return false; + } + + public function hasAlpha($variant = null) + { + if (null === $variant) { + $variant = $this->variant; + } + + switch ($variant) { + case self::COLOR_NAME: + case self::COLOR_RGB: + case self::COLOR_HSL: + return \abs($this->a - 1) >= 0.0001; + case self::COLOR_RGBA: + case self::COLOR_HSLA: + case self::COLOR_HEX_4: + case self::COLOR_HEX_8: + return true; + default: + return false; + } + } + + protected function setValues($value) + { + $value = \strtolower(\trim($value)); + // Find out which variant of color input it is + if (isset(self::$color_map[$value])) { + if (!$this->setValuesFromHex(self::$color_map[$value])) { + return; + } + + $variant = self::COLOR_NAME; + } elseif ('#' === $value[0]) { + $variant = $this->setValuesFromHex(\substr($value, 1)); + + if (!$variant) { + return; + } + } else { + $variant = $this->setValuesFromFunction($value); + + if (!$variant) { + return; + } + } + + // If something has gone horribly wrong + if ($this->r > 0xFF || $this->g > 0xFF || $this->b > 0xFF || $this->a > 1) { + $this->variant = null; // @codeCoverageIgnore + } else { + $this->variant = $variant; + $this->r = (int) $this->r; + $this->g = (int) $this->g; + $this->b = (int) $this->b; + $this->a = (float) $this->a; + } + } + + protected function setValuesFromHex($hex) + { + if (!\ctype_xdigit($hex)) { + return null; + } + + switch (\strlen($hex)) { + case 3: + $variant = self::COLOR_HEX_3; + break; + case 6: + $variant = self::COLOR_HEX_6; + break; + case 4: + $variant = self::COLOR_HEX_4; + break; + case 8: + $variant = self::COLOR_HEX_8; + break; + default: + return null; + } + + switch ($variant) { + case self::COLOR_HEX_4: + $this->a = \hexdec($hex[3]) / 0xF; + // no break + case self::COLOR_HEX_3: + $this->r = \hexdec($hex[0]) * 0x11; + $this->g = \hexdec($hex[1]) * 0x11; + $this->b = \hexdec($hex[2]) * 0x11; + break; + case self::COLOR_HEX_8: + $this->a = \hexdec(\substr($hex, 6, 2)) / 0xFF; + // no break + case self::COLOR_HEX_6: + $hex = \str_split($hex, 2); + $this->r = \hexdec($hex[0]); + $this->g = \hexdec($hex[1]); + $this->b = \hexdec($hex[2]); + break; + } + + return $variant; + } + + protected function setValuesFromFunction($value) + { + if (!\preg_match('/^((?:rgb|hsl)a?)\\s*\\(([0-9\\.%,\\s\\/\\-]+)\\)$/i', $value, $match)) { + return null; + } + + switch (\strtolower($match[1])) { + case 'rgb': + $variant = self::COLOR_RGB; + break; + case 'rgba': + $variant = self::COLOR_RGBA; + break; + case 'hsl': + $variant = self::COLOR_HSL; + break; + case 'hsla': + $variant = self::COLOR_HSLA; + break; + default: + return null; // @codeCoverageIgnore + } + + $params = \preg_replace('/[,\\s\\/]+/', ',', \trim($match[2])); + $params = \explode(',', $params); + $params = \array_map('trim', $params); + + if (\count($params) < 3 || \count($params) > 4) { + return null; + } + + foreach ($params as $i => &$color) { + if (false !== \strpos($color, '%')) { + $color = (float) \str_replace('%', '', $color); + + if (3 === $i) { + $color = $color / 100; + } elseif (\in_array($variant, array(self::COLOR_RGB, self::COLOR_RGBA), true)) { + $color = \round($color / 100 * 0xFF); + } + } + + $color = (float) $color; + + if (0 === $i && \in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA), true)) { + $color = ($color % 360 + 360) % 360; + } + } + + /** @var float[] Psalm bug workaround */ + $params = \array_map('floatval', $params); + + switch ($variant) { + case self::COLOR_RGBA: + case self::COLOR_RGB: + if (\min($params) < 0 || \max($params) > 0xFF) { + return null; + } + break; + case self::COLOR_HSLA: + case self::COLOR_HSL: + if (\min($params) < 0 || $params[0] > 360 || \max($params[1], $params[2]) > 100) { + return null; + } + break; + } + + if (4 === \count($params)) { + if ($params[3] > 1) { + return null; + } + + $this->a = $params[3]; + } + + if (self::COLOR_HSLA === $variant || self::COLOR_HSL === $variant) { + $params = self::hslToRgb($params[0], $params[1], $params[2]); + } + + list($this->r, $this->g, $this->b) = $params; + + return $variant; + } + + /** + * Turns HSL color to RGB. Black magic. + * + * @param float $h Hue + * @param float $s Saturation + * @param float $l Lightness + * + * @return int[] RGB array + */ + public static function hslToRgb($h, $s, $l) + { + if (\min($h, $s, $l) < 0) { + throw new InvalidArgumentException('The parameters for hslToRgb should be no less than 0'); + } + + if ($h > 360 || \max($s, $l) > 100) { + throw new InvalidArgumentException('The parameters for hslToRgb should be no more than 360, 100, and 100 respectively'); + } + + $h /= 360; + $s /= 100; + $l /= 100; + + $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l * $s; + $m1 = $l * 2 - $m2; + + return array( + (int) \round(self::hueToRgb($m1, $m2, $h + 1 / 3) * 0xFF), + (int) \round(self::hueToRgb($m1, $m2, $h) * 0xFF), + (int) \round(self::hueToRgb($m1, $m2, $h - 1 / 3) * 0xFF), + ); + } + + /** + * Converts RGB to HSL. Color inversion of previous black magic is white magic? + * + * @param float|int $red Red + * @param float|int $green Green + * @param float|int $blue Blue + * + * @return float[] HSL array + */ + public static function rgbToHsl($red, $green, $blue) + { + if (\min($red, $green, $blue) < 0) { + throw new InvalidArgumentException('The parameters for rgbToHsl should be no less than 0'); + } + + if (\max($red, $green, $blue) > 0xFF) { + throw new InvalidArgumentException('The parameters for rgbToHsl should be no more than 255'); + } + + $clrMin = \min($red, $green, $blue); + $clrMax = \max($red, $green, $blue); + $deltaMax = $clrMax - $clrMin; + + $L = ($clrMax + $clrMin) / 510; + + if (0 == $deltaMax) { + $H = 0; + $S = 0; + } else { + if (0.5 > $L) { + $S = $deltaMax / ($clrMax + $clrMin); + } else { + $S = $deltaMax / (510 - $clrMax - $clrMin); + } + + if ($clrMax === $red) { + $H = ($green - $blue) / (6.0 * $deltaMax); + + if (0 > $H) { + $H += 1.0; + } + } elseif ($clrMax === $green) { + $H = 1 / 3 + ($blue - $red) / (6.0 * $deltaMax); + } else { + $H = 2 / 3 + ($red - $green) / (6.0 * $deltaMax); + } + } + + return array( + (float) ($H * 360 % 360), + (float) ($S * 100), + (float) ($L * 100), + ); + } + + /** + * Helper function for hslToRgb. Even blacker magic. + * + * + * @param float $m1 + * @param float $m2 + * @param float $hue + * + * @return float Color value + */ + private static function hueToRgb($m1, $m2, $hue) + { + $hue = ($hue < 0) ? $hue + 1 : (($hue > 1) ? $hue - 1 : $hue); + if ($hue * 6 < 1) { + return $m1 + ($m2 - $m1) * $hue * 6; + } + if ($hue * 2 < 1) { + return $m2; + } + if ($hue * 3 < 2) { + return $m1 + ($m2 - $m1) * (2 / 3 - $hue) * 6; + } + + return $m1; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/DocstringRepresentation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/DocstringRepresentation.php new file mode 100644 index 0000000..488d8d6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/DocstringRepresentation.php @@ -0,0 +1,73 @@ +file = $file; + $this->line = $line; + $this->class = $class; + $this->contents = $docstring; + } + + /** + * Returns the representation's docstring without surrounding comments. + * + * Note that this will not work flawlessly. + * + * On comments with whitespace after the stars the lines will begin with + * whitespace, since we can't accurately guess how much of an indentation + * is required. + * + * And on lines without stars on the left this may eat bullet points. + * + * Long story short: If you want the docstring read the contents. If you + * absolutely must have it without comments (ie renderValueShort) this will + * probably do. + * + * @return null|string Docstring with comments stripped + */ + public function getDocstringWithoutComments() + { + if (!$this->contents) { + return null; + } + + $string = \substr($this->contents, 3, -2); + $string = \preg_replace('/^\\s*\\*\\s*?(\\S|$)/m', '\\1', $string); + + return \trim($string); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/MicrotimeRepresentation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/MicrotimeRepresentation.php new file mode 100644 index 0000000..b9f4dac --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/MicrotimeRepresentation.php @@ -0,0 +1,71 @@ +seconds = (int) $seconds; + $this->microseconds = (int) $microseconds; + + $this->group = $group; + $this->lap = $lap; + $this->total = $total; + $this->i = $i; + + if ($i) { + $this->avg = $total / $i; + } + + $this->mem = \memory_get_usage(); + $this->mem_real = \memory_get_usage(true); + $this->mem_peak = \memory_get_peak_usage(); + $this->mem_peak_real = \memory_get_peak_usage(true); + } + + public function getDateTime() + { + return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad($this->microseconds, 6, '0', STR_PAD_LEFT)); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/Representation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/Representation.php new file mode 100644 index 0000000..0c911a4 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/Representation.php @@ -0,0 +1,71 @@ +label = $label; + + if (null === $name) { + $name = $label; + } + + $this->setName($name); + } + + public function getLabel() + { + if (\is_array($this->contents) && \count($this->contents) > 1) { + return $this->label.' ('.\count($this->contents).')'; + } + + return $this->label; + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name)); + } + + public function labelIsImplicit() + { + return $this->implicit_label; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SourceRepresentation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SourceRepresentation.php new file mode 100644 index 0000000..c2cf120 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SourceRepresentation.php @@ -0,0 +1,72 @@ +filename = $filename; + $this->line = $line; + + $start_line = \max($line - $padding, 1); + $length = $line + $padding + 1 - $start_line; + $this->source = self::getSource($filename, $start_line, $length); + if (null !== $this->source) { + $this->contents = \implode("\n", $this->source); + } + } + + /** + * Gets section of source code. + * + * @param string $filename Full path to file + * @param int $start_line The first line to display (1 based) + * @param null|int $length Amount of lines to show + * + * @return null|array + */ + public static function getSource($filename, $start_line = 1, $length = null) + { + if (!$filename || !\file_exists($filename) || !\is_readable($filename)) { + return null; + } + + $source = \preg_split("/\r\n|\n|\r/", \file_get_contents($filename)); + $source = \array_combine(\range(1, \count($source)), $source); + $source = \array_slice($source, $start_line - 1, $length, true); + + return $source; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SplFileInfoRepresentation.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SplFileInfoRepresentation.php new file mode 100644 index 0000000..3df50e6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/Representation/SplFileInfoRepresentation.php @@ -0,0 +1,177 @@ +getRealPath()) { + $this->realpath = $fileInfo->getRealPath(); + $this->perms = $fileInfo->getPerms(); + $this->size = $fileInfo->getSize(); + $this->owner = $fileInfo->getOwner(); + $this->group = $fileInfo->getGroup(); + $this->ctime = $fileInfo->getCTime(); + $this->mtime = $fileInfo->getMTime(); + } + + $this->path = $fileInfo->getPathname(); + + $this->is_dir = $fileInfo->isDir(); + $this->is_file = $fileInfo->isFile(); + $this->is_link = $fileInfo->isLink(); + + if ($this->is_link) { + $this->linktarget = $fileInfo->getLinkTarget(); + } + + switch ($this->perms & 0xF000) { + case 0xC000: + $this->typename = 'Socket'; + $this->typeflag = 's'; + break; + case 0x6000: + $this->typename = 'Block device'; + $this->typeflag = 'b'; + break; + case 0x2000: + $this->typename = 'Character device'; + $this->typeflag = 'c'; + break; + case 0x1000: + $this->typename = 'Named pipe'; + $this->typeflag = 'p'; + break; + default: + if ($this->is_file) { + if ($this->is_link) { + $this->typename = 'File symlink'; + $this->typeflag = 'l'; + } else { + $this->typename = 'File'; + $this->typeflag = '-'; + } + } elseif ($this->is_dir) { + if ($this->is_link) { + $this->typename = 'Directory symlink'; + $this->typeflag = 'l'; + } else { + $this->typename = 'Directory'; + $this->typeflag = 'd'; + } + } + break; + } + + $this->flags = array($this->typeflag); + + // User + $this->flags[] = (($this->perms & 0400) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0200) ? 'w' : '-'); + if ($this->perms & 0100) { + $this->flags[] = ($this->perms & 04000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 04000) ? 'S' : '-'; + } + + // Group + $this->flags[] = (($this->perms & 0040) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0020) ? 'w' : '-'); + if ($this->perms & 0010) { + $this->flags[] = ($this->perms & 02000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 02000) ? 'S' : '-'; + } + + // Other + $this->flags[] = (($this->perms & 0004) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0002) ? 'w' : '-'); + if ($this->perms & 0001) { + $this->flags[] = ($this->perms & 01000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 01000) ? 'S' : '-'; + } + + $this->contents = \implode($this->flags).' '.$this->owner.' '.$this->group; + $this->contents .= ' '.$this->getSize().' '.$this->getMTime().' '; + + if ($this->is_link && $this->linktarget) { + $this->contents .= $this->path.' -> '.$this->linktarget; + } elseif (null !== $this->realpath && \strlen($this->realpath) < \strlen($this->path)) { + $this->contents .= $this->realpath; + } else { + $this->contents .= $this->path; + } + } + + public function getLabel() + { + return $this->typename.' ('.$this->getSize().')'; + } + + public function getSize() + { + if ($this->size) { + $size = Utils::getHumanReadableBytes($this->size); + + return \round($size['value'], 2).$size['unit']; + } + } + + public function getMTime() + { + $year = \date('Y', $this->mtime); + + if ($year !== \date('Y')) { + return \date('M d Y', $this->mtime); + } + + return \date('M d H:i', $this->mtime); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ResourceObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ResourceObject.php new file mode 100644 index 0000000..a43f85d --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ResourceObject.php @@ -0,0 +1,49 @@ +resource_type) { + return $this->resource_type.' resource'; + } + + return 'resource'; + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->resource_type = $old->resource_type; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/StreamObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/StreamObject.php new file mode 100644 index 0000000..358f274 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/StreamObject.php @@ -0,0 +1,54 @@ +stream_meta = $meta; + } + + public function getValueShort() + { + if (empty($this->stream_meta['uri'])) { + return; + } + + $uri = $this->stream_meta['uri']; + + if (\stream_is_local($uri)) { + return Kint::shortenPath($uri); + } + + return $uri; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ThrowableObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ThrowableObject.php new file mode 100644 index 0000000..2a86d57 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/ThrowableObject.php @@ -0,0 +1,54 @@ +message = $throw->getMessage(); + } + + public function getValueShort() + { + if (\strlen($this->message)) { + return '"'.$this->message.'"'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceFrameObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceFrameObject.php new file mode 100644 index 0000000..4259aee --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceFrameObject.php @@ -0,0 +1,100 @@ +transplant($base); + + $this->trace = array( + 'function' => isset($raw_frame['function']) ? $raw_frame['function'] : null, + 'line' => isset($raw_frame['line']) ? $raw_frame['line'] : null, + 'file' => isset($raw_frame['file']) ? $raw_frame['file'] : null, + 'class' => isset($raw_frame['class']) ? $raw_frame['class'] : null, + 'type' => isset($raw_frame['type']) ? $raw_frame['type'] : null, + 'object' => null, + 'args' => null, + ); + + if ($this->trace['class'] && \method_exists($this->trace['class'], $this->trace['function'])) { + $func = new ReflectionMethod($this->trace['class'], $this->trace['function']); + $this->trace['function'] = new MethodObject($func); + } elseif (!$this->trace['class'] && \function_exists($this->trace['function'])) { + $func = new ReflectionFunction($this->trace['function']); + $this->trace['function'] = new MethodObject($func); + } + + foreach ($this->value->contents as $frame_prop) { + if ('object' === $frame_prop->name) { + $this->trace['object'] = $frame_prop; + $this->trace['object']->name = null; + $this->trace['object']->operator = BasicObject::OPERATOR_NONE; + } + if ('args' === $frame_prop->name) { + $this->trace['args'] = $frame_prop->value->contents; + + if ($this->trace['function'] instanceof MethodObject) { + foreach (\array_values($this->trace['function']->parameters) as $param) { + if (isset($this->trace['args'][$param->position])) { + $this->trace['args'][$param->position]->name = $param->getName(); + } + } + } + } + } + + $this->clearRepresentations(); + + if (isset($this->trace['file'], $this->trace['line']) && \is_readable($this->trace['file'])) { + $this->addRepresentation(new SourceRepresentation($this->trace['file'], $this->trace['line'])); + } + + if ($this->trace['args']) { + $args = new Representation('Arguments'); + $args->contents = $this->trace['args']; + $this->addRepresentation($args); + } + + if ($this->trace['object']) { + $callee = new Representation('object'); + $callee->label = 'Callee object ['.$this->trace['object']->classname.']'; + $callee->contents[] = $this->trace['object']; + $this->addRepresentation($callee); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceObject.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceObject.php new file mode 100644 index 0000000..a780b08 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Object/TraceObject.php @@ -0,0 +1,45 @@ +size) { + return 'empty'; + } + + return parent::getSize(); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php new file mode 100644 index 0000000..286d255 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ArrayObjectPlugin.php @@ -0,0 +1,63 @@ +getFlags(); + + if (ArrayObject::STD_PROP_LIST === $flags) { + return; + } + + $var->setFlags(ArrayObject::STD_PROP_LIST); + + $o = $this->parser->parse($var, $o); + + $var->setFlags($flags); + + $this->parser->haltParse(); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Base64Plugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Base64Plugin.php new file mode 100644 index 0000000..3d7d6bc --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Base64Plugin.php @@ -0,0 +1,95 @@ +depth = $o->depth + 1; + $base_obj->name = 'base64_decode('.$o->name.')'; + + if ($o->access_path) { + $base_obj->access_path = 'base64_decode('.$o->access_path.')'; + } + + $r = new Representation('Base64'); + $r->contents = $this->parser->parse($data, $base_obj); + + if (\strlen($var) > self::$min_length_soft) { + $o->addRepresentation($r, 0); + } else { + $o->addRepresentation($r); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BinaryPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BinaryPlugin.php new file mode 100644 index 0000000..327c297 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BinaryPlugin.php @@ -0,0 +1,49 @@ +encoding, array('ASCII', 'UTF-8'), true)) { + $o->value->hints[] = 'binary'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BlacklistPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BlacklistPlugin.php new file mode 100644 index 0000000..b37e45f --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/BlacklistPlugin.php @@ -0,0 +1,143 @@ +parseObject($var, $o); + } + if (\is_array($var)) { + return $this->parseArray($var, $o); + } + } + + protected function parseObject(&$var, BasicObject &$o) + { + foreach (self::$blacklist as $class) { + if ($var instanceof $class) { + return $this->blacklistObject($var, $o); + } + } + + if ($o->depth <= 0) { + return; + } + + foreach (self::$shallow_blacklist as $class) { + if ($var instanceof $class) { + return $this->blacklistObject($var, $o); + } + } + } + + protected function blacklistObject(&$var, BasicObject &$o) + { + $object = new InstanceObject(); + $object->transplant($o); + $object->classname = \get_class($var); + $object->hash = \spl_object_hash($var); + $object->clearRepresentations(); + $object->value = null; + $object->size = null; + $object->hints[] = 'blacklist'; + + $o = $object; + + $this->parser->haltParse(); + } + + protected function parseArray(array &$var, BasicObject &$o) + { + if (\count($var) > self::$array_limit) { + return $this->blacklistArray($var, $o); + } + + if ($o->depth <= 0) { + return; + } + + if (\count($var) > self::$shallow_array_limit) { + return $this->blacklistArray($var, $o); + } + } + + protected function blacklistArray(array &$var, BasicObject &$o) + { + $object = new BasicObject(); + $object->transplant($o); + $object->value = null; + $object->size = \count($var); + $object->hints[] = 'blacklist'; + + $o = $object; + + $this->parser->haltParse(); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php new file mode 100644 index 0000000..e4c2371 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassMethodsPlugin.php @@ -0,0 +1,113 @@ +getMethods() as $method) { + $methods[] = new MethodObject($method); + } + + \usort($methods, array('Kint\\Parser\\ClassMethodsPlugin', 'sort')); + + self::$cache[$class] = $methods; + } + + if (!empty(self::$cache[$class])) { + $rep = new Representation('Available methods', 'methods'); + + // Can't cache access paths + foreach (self::$cache[$class] as $m) { + $method = clone $m; + $method->depth = $o->depth + 1; + + if (!$this->parser->childHasPath($o, $method)) { + $method->access_path = null; + } else { + $method->setAccessPathFrom($o); + } + + if ($method->owner_class !== $class && $ds = $method->getRepresentation('docstring')) { + $ds = clone $ds; + $ds->class = $method->owner_class; + $method->replaceRepresentation($ds); + } + + $rep->contents[] = $method; + } + + $o->addRepresentation($rep); + } + } + + private static function sort(MethodObject $a, MethodObject $b) + { + $sort = ((int) $a->static) - ((int) $b->static); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + $sort = InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + if ($sort) { + return $sort; + } + + return $a->startline - $b->startline; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php new file mode 100644 index 0000000..0ba58ca --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClassStaticsPlugin.php @@ -0,0 +1,122 @@ +getConstants() as $name => $val) { + $const = BasicObject::blank($name, '\\'.$class.'::'.$name); + $const->const = true; + $const->depth = $o->depth + 1; + $const->owner_class = $class; + $const->operator = BasicObject::OPERATOR_STATIC; + $const = $this->parser->parse($val, $const); + + $consts[] = $const; + } + + self::$cache[$class] = $consts; + } + + $statics = new Representation('Static class properties', 'statics'); + $statics->contents = self::$cache[$class]; + + foreach ($reflection->getProperties(ReflectionProperty::IS_STATIC) as $static) { + $prop = new BasicObject(); + $prop->name = '$'.$static->getName(); + $prop->depth = $o->depth + 1; + $prop->static = true; + $prop->operator = BasicObject::OPERATOR_STATIC; + $prop->owner_class = $static->getDeclaringClass()->name; + + $prop->access = BasicObject::ACCESS_PUBLIC; + if ($static->isProtected()) { + $prop->access = BasicObject::ACCESS_PROTECTED; + } elseif ($static->isPrivate()) { + $prop->access = BasicObject::ACCESS_PRIVATE; + } + + if ($this->parser->childHasPath($o, $prop)) { + $prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name; + } + + $static->setAccessible(true); + $static = $static->getValue(); + $statics->contents[] = $this->parser->parse($static, $prop); + } + + if (empty($statics->contents)) { + return; + } + + \usort($statics->contents, array('Kint\\Parser\\ClassStaticsPlugin', 'sort')); + + $o->addRepresentation($statics); + } + + private static function sort(BasicObject $a, BasicObject $b) + { + $sort = ((int) $a->const) - ((int) $b->const); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClosurePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClosurePlugin.php new file mode 100644 index 0000000..73e367b --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ClosurePlugin.php @@ -0,0 +1,94 @@ +transplant($o); + $o = $object; + $object->removeRepresentation('properties'); + + $closure = new ReflectionFunction($var); + + $o->filename = $closure->getFileName(); + $o->startline = $closure->getStartLine(); + + foreach ($closure->getParameters() as $param) { + $o->parameters[] = new ParameterObject($param); + } + + $p = new Representation('Parameters'); + $p->contents = &$o->parameters; + $o->addRepresentation($p, 0); + + $statics = array(); + + if (\method_exists($closure, 'getClosureThis') && $v = $closure->getClosureThis()) { + $statics = array('this' => $v); + } + + if (\count($statics = $statics + $closure->getStaticVariables())) { + $statics_parsed = array(); + + foreach ($statics as $name => &$static) { + $obj = BasicObject::blank('$'.$name); + $obj->depth = $o->depth + 1; + $statics_parsed[$name] = $this->parser->parse($static, $obj); + if (null === $statics_parsed[$name]->value) { + $statics_parsed[$name]->access_path = null; + } + } + + $r = new Representation('Uses'); + $r->contents = $statics_parsed; + $o->addRepresentation($r, 0); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ColorPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ColorPlugin.php new file mode 100644 index 0000000..0d748f2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ColorPlugin.php @@ -0,0 +1,63 @@ + 32) { + return; + } + + $trimmed = \strtolower(\trim($var)); + + if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)[^\\)]{6,}\\)|#[0-9a-fA-F]{3,8})$/', $trimmed)) { + return; + } + + $rep = new ColorRepresentation($var); + + if ($rep->variant) { + $o->removeRepresentation($o->value); + $o->addRepresentation($rep, 0); + $o->hints[] = 'color'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DOMDocumentPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DOMDocumentPlugin.php new file mode 100644 index 0000000..ec08d31 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DOMDocumentPlugin.php @@ -0,0 +1,328 @@ + 'DOMNode', + 'firstChild' => 'DOMNode', + 'lastChild' => 'DOMNode', + 'previousSibling' => 'DOMNode', + 'nextSibling' => 'DOMNode', + 'ownerDocument' => 'DOMDocument', + ); + + /** + * Show all properties and methods. + * + * @var bool + */ + public static $verbose = false; + + public function getTypes() + { + return array('object'); + } + + public function getTriggers() + { + return Parser::TRIGGER_SUCCESS; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + if (!$o instanceof InstanceObject) { + return; + } + + if ($var instanceof DOMNamedNodeMap || $var instanceof DOMNodeList) { + return $this->parseList($var, $o, $trigger); + } + + if ($var instanceof DOMNode) { + return $this->parseNode($var, $o); + } + } + + protected function parseList(&$var, InstanceObject &$o, $trigger) + { + // Recursion should never happen, should always be stopped at the parent + // DOMNode. Depth limit on the other hand we're going to skip since + // that would show an empty iterator and rather useless. Let the depth + // limit hit the children (DOMNodeList only has DOMNode as children) + if ($trigger & Parser::TRIGGER_RECURSION) { + return; + } + + $o->size = $var->length; + if (0 === $o->size) { + $o->replaceRepresentation(new Representation('Iterator')); + $o->size = null; + + return; + } + + // Depth limit + // Make empty iterator representation since we need it in DOMNode to point out depth limits + if ($this->parser->getDepthLimit() && $o->depth + 1 >= $this->parser->getDepthLimit()) { + $b = new BasicObject(); + $b->name = $o->classname.' Iterator Contents'; + $b->access_path = 'iterator_to_array('.$o->access_path.')'; + $b->depth = $o->depth + 1; + $b->hints[] = 'depth_limit'; + + $r = new Representation('Iterator'); + $r->contents = array($b); + $o->replaceRepresentation($r, 0); + + return; + } + + $data = \iterator_to_array($var); + + $r = new Representation('Iterator'); + $o->replaceRepresentation($r, 0); + + foreach ($data as $key => $item) { + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $item->nodeName; + + if ($o->access_path) { + if ($var instanceof DOMNamedNodeMap) { + $base_obj->access_path = $o->access_path.'->getNamedItem('.\var_export($key, true).')'; + } elseif ($var instanceof DOMNodeList) { + $base_obj->access_path = $o->access_path.'->item('.\var_export($key, true).')'; + } else { + $base_obj->access_path = 'iterator_to_array('.$o->access_path.')'; + } + } + + $r->contents[] = $this->parser->parse($item, $base_obj); + } + } + + protected function parseNode(&$var, InstanceObject &$o) + { + // Fill the properties + // They can't be enumerated through reflection or casting, + // so we have to trust the docs and try them one at a time + $known_properties = array( + 'nodeValue', + 'childNodes', + 'attributes', + ); + + if (self::$verbose) { + $known_properties = array( + 'nodeName', + 'nodeValue', + 'nodeType', + 'parentNode', + 'childNodes', + 'firstChild', + 'lastChild', + 'previousSibling', + 'nextSibling', + 'attributes', + 'ownerDocument', + 'namespaceURI', + 'prefix', + 'localName', + 'baseURI', + 'textContent', + ); + } + + $childNodes = array(); + $attributes = array(); + + $rep = $o->value; + + foreach ($known_properties as $prop) { + $prop_obj = $this->parseProperty($o, $prop, $var); + $rep->contents[] = $prop_obj; + + if ('childNodes' === $prop) { + $childNodes = $prop_obj->getRepresentation('iterator'); + } elseif ('attributes' === $prop) { + $attributes = $prop_obj->getRepresentation('iterator'); + } + } + + if (!self::$verbose) { + $o->removeRepresentation('methods'); + $o->removeRepresentation('properties'); + } + + // Attributes and comments and text nodes don't + // need children or attributes of their own + if (\in_array($o->classname, array('DOMAttr', 'DOMText', 'DOMComment'), true)) { + return; + } + + // Set the attributes + if ($attributes) { + $a = new Representation('Attributes'); + foreach ($attributes->contents as $attribute) { + $a->contents[] = self::textualNodeToString($attribute); + } + $o->addRepresentation($a, 0); + } + + // Set the children + if ($childNodes) { + $c = new Representation('Children'); + + if (1 === \count($childNodes->contents) && ($node = \reset($childNodes->contents)) && \in_array('depth_limit', $node->hints, true)) { + $n = new InstanceObject(); + $n->transplant($node); + $n->name = 'childNodes'; + $n->classname = 'DOMNodeList'; + $c->contents = array($n); + } else { + foreach ($childNodes->contents as $index => $node) { + // Shortcircuit text nodes to plain strings + if ('DOMText' === $node->classname || 'DOMComment' === $node->classname) { + $node = self::textualNodeToString($node); + + // And remove them if they're empty + if (\ctype_space($node->value->contents) || '' === $node->value->contents) { + continue; + } + } + + $c->contents[] = $node; + } + } + + $o->addRepresentation($c, 0); + } + + if (isset($c) && \count($c->contents)) { + $o->size = \count($c->contents); + } + + if (!$o->size) { + $o->size = null; + } + } + + protected function parseProperty(InstanceObject $o, $prop, &$var) + { + // Duplicating (And slightly optimizing) the Parser::parseObject() code here + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->owner_class = $o->classname; + $base_obj->name = $prop; + $base_obj->operator = BasicObject::OPERATOR_OBJECT; + $base_obj->access = BasicObject::ACCESS_PUBLIC; + + if (null !== $o->access_path) { + $base_obj->access_path = $o->access_path; + + if (\preg_match('/^[A-Za-z0-9_]+$/', $base_obj->name)) { + $base_obj->access_path .= '->'.$base_obj->name; + } else { + $base_obj->access_path .= '->{'.\var_export($base_obj->name, true).'}'; + } + } + + if (!isset($var->{$prop})) { + $base_obj->type = 'null'; + } elseif (isset(self::$blacklist[$prop])) { + $b = new InstanceObject(); + $b->transplant($base_obj); + $base_obj = $b; + + $base_obj->hints[] = 'blacklist'; + $base_obj->classname = self::$blacklist[$prop]; + } elseif ('attributes' === $prop) { + $base_obj = $this->parser->parseDeep($var->{$prop}, $base_obj); + } else { + $base_obj = $this->parser->parse($var->{$prop}, $base_obj); + } + + return $base_obj; + } + + protected static function textualNodeToString(InstanceObject $o) + { + if (empty($o->value) || empty($o->value->contents) || empty($o->classname)) { + return; + } + + if (!\in_array($o->classname, array('DOMText', 'DOMAttr', 'DOMComment'), true)) { + return; + } + + foreach ($o->value->contents as $property) { + if ('nodeValue' === $property->name) { + $ret = clone $property; + $ret->name = $o->name; + + return $ret; + } + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DateTimePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DateTimePlugin.php new file mode 100644 index 0000000..f2cebb6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/DateTimePlugin.php @@ -0,0 +1,55 @@ +transplant($o); + + $o = $object; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/FsPathPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/FsPathPlugin.php new file mode 100644 index 0000000..3a8d1e0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/FsPathPlugin.php @@ -0,0 +1,72 @@ + 2048) { + return; + } + + if (!\preg_match('/[\\/\\'.DIRECTORY_SEPARATOR.']/', $var)) { + return; + } + + if (\preg_match('/[?<>"*|]/', $var)) { + return; + } + + if (!@\file_exists($var)) { + return; + } + + if (\in_array($var, self::$blacklist, true)) { + return; + } + + $r = new SplFileInfoRepresentation(new SplFileInfo($var)); + $r->hints[] = 'fspath'; + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/IteratorPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/IteratorPlugin.php new file mode 100644 index 0000000..0487a38 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/IteratorPlugin.php @@ -0,0 +1,110 @@ +name = $class.' Iterator Contents'; + $b->access_path = 'iterator_to_array('.$o->access_path.', true)'; + $b->depth = $o->depth + 1; + $b->hints[] = 'blacklist'; + + $r = new Representation('Iterator'); + $r->contents = array($b); + + $o->addRepresentation($r); + + return; + } + } + + /** @var array|false */ + $data = \iterator_to_array($var); + + if (false === $data) { + return; + } + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'iterator_to_array('.$o->access_path.')'; + } + + $r = new Representation('Iterator'); + $r->contents = $this->parser->parse($data, $base_obj); + $r->contents = $r->contents->value->contents; + + $primary = $o->getRepresentations(); + $primary = \reset($primary); + if ($primary && $primary === $o->value && $primary->contents === array()) { + $o->addRepresentation($r, 0); + } else { + $o->addRepresentation($r); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/JsonPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/JsonPlugin.php new file mode 100644 index 0000000..84b2519 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/JsonPlugin.php @@ -0,0 +1,73 @@ +depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'json_decode('.$o->access_path.', true)'; + } + + $r = new Representation('Json'); + $r->contents = $this->parser->parse($json, $base_obj); + + if (!\in_array('depth_limit', $r->contents->hints, true)) { + $r->contents = $r->contents->value->contents; + } + + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MicrotimePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MicrotimePlugin.php new file mode 100644 index 0000000..5062b59 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MicrotimePlugin.php @@ -0,0 +1,105 @@ +depth) { + return; + } + + if (\is_string($var)) { + if ('microtime()' !== $o->name || !\preg_match('/^0\\.[0-9]{8} [0-9]{10}$/', $var)) { + return; + } + + $usec = (int) \substr($var, 2, 6); + $sec = (int) \substr($var, 11, 10); + } else { + if ('microtime(...)' !== $o->name) { + return; + } + + $sec = \floor($var); + $usec = $var - $sec; + $usec = \floor($usec * 1000000); + } + + $time = $sec + ($usec / 1000000); + + if (null !== self::$last) { + $last_time = self::$last[0] + (self::$last[1] / 1000000); + $lap = $time - $last_time; + ++self::$times; + } else { + $lap = null; + self::$start = $time; + } + + self::$last = array($sec, $usec); + + if (null !== $lap) { + $total = $time - self::$start; + $r = new MicrotimeRepresentation($sec, $usec, self::$group, $lap, $total, self::$times); + } else { + $r = new MicrotimeRepresentation($sec, $usec, self::$group); + } + $r->contents = $var; + $r->implicit_label = true; + + $o->removeRepresentation($o->value); + $o->addRepresentation($r); + $o->hints[] = 'microtime'; + } + + public static function clean() + { + self::$last = null; + self::$start = null; + self::$times = 0; + ++self::$group; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MysqliPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MysqliPlugin.php new file mode 100644 index 0000000..265299b --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/MysqliPlugin.php @@ -0,0 +1,129 @@ + true, + 'connect_errno' => true, + 'connect_error' => true, + ); + + // These are readable on empty mysqli objects, but not on failed connections + protected $empty_readable = array( + 'client_info' => true, + 'errno' => true, + 'error' => true, + ); + + // These are only readable on connected mysqli objects + protected $connected_readable = array( + 'affected_rows' => true, + 'error_list' => true, + 'field_count' => true, + 'host_info' => true, + 'info' => true, + 'insert_id' => true, + 'server_info' => true, + 'server_version' => true, + 'stat' => true, + 'sqlstate' => true, + 'protocol_version' => true, + 'thread_id' => true, + 'warning_count' => true, + ); + + public function getTypes() + { + return array('object'); + } + + public function getTriggers() + { + return Parser::TRIGGER_COMPLETE; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + if (!$var instanceof Mysqli) { + return; + } + + $connected = false; + $empty = false; + + if (\is_string(@$var->sqlstate)) { + $connected = true; + } elseif (\is_string(@$var->client_info)) { + $empty = true; + } + + foreach ($o->value->contents as $key => $obj) { + if (isset($this->connected_readable[$obj->name])) { + if (!$connected) { + continue; + } + } elseif (isset($this->empty_readable[$obj->name])) { + if (!$connected && !$empty) { + continue; + } + } elseif (!isset($this->always_readable[$obj->name])) { + continue; + } + + if ('null' !== $obj->type) { + continue; + } + + $param = $var->{$obj->name}; + + if (null === $param) { + continue; + } + + $base = BasicObject::blank($obj->name, $obj->access_path); + + $base->depth = $obj->depth; + $base->owner_class = $obj->owner_class; + $base->operator = $obj->operator; + $base->access = $obj->access; + $base->reference = $obj->reference; + + $o->value->contents[$key] = $this->parser->parse($param, $base); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Parser.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Parser.php new file mode 100644 index 0000000..b7f81c6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Parser.php @@ -0,0 +1,604 @@ +marker = \uniqid("kint\0", true); + + $this->caller_class = $caller; + + if ($depth_limit) { + $this->depth_limit = $depth_limit; + } + } + + /** + * Set the caller class. + * + * @param null|string $caller Caller class name + */ + public function setCallerClass($caller = null) + { + $this->noRecurseCall(); + + $this->caller_class = $caller; + } + + public function getCallerClass() + { + return $this->caller_class; + } + + /** + * Set the depth limit. + * + * @param false|int $depth_limit Maximum depth to parse data + */ + public function setDepthLimit($depth_limit = false) + { + $this->noRecurseCall(); + + $this->depth_limit = $depth_limit; + } + + public function getDepthLimit() + { + return $this->depth_limit; + } + + /** + * Disables the depth limit and parses a variable. + * + * This should not be used unless you know what you're doing! + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + public function parseDeep(&$var, BasicObject $o) + { + $depth_limit = $this->depth_limit; + $this->depth_limit = false; + + $out = $this->parse($var, $o); + + $this->depth_limit = $depth_limit; + + return $out; + } + + /** + * Parses a variable into a Kint object structure. + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + public function parse(&$var, BasicObject $o) + { + $o->type = \strtolower(\gettype($var)); + + if (!$this->applyPlugins($var, $o, self::TRIGGER_BEGIN)) { + return $o; + } + + switch ($o->type) { + case 'array': + return $this->parseArray($var, $o); + case 'boolean': + case 'double': + case 'integer': + case 'null': + return $this->parseGeneric($var, $o); + case 'object': + return $this->parseObject($var, $o); + case 'resource': + return $this->parseResource($var, $o); + case 'string': + return $this->parseString($var, $o); + default: + return $this->parseUnknown($var, $o); + } + } + + public function addPlugin(Plugin $p) + { + if (!$types = $p->getTypes()) { + return false; + } + + if (!$triggers = $p->getTriggers()) { + return false; + } + + $p->setParser($this); + + foreach ($types as $type) { + if (!isset($this->plugins[$type])) { + $this->plugins[$type] = array( + self::TRIGGER_BEGIN => array(), + self::TRIGGER_SUCCESS => array(), + self::TRIGGER_RECURSION => array(), + self::TRIGGER_DEPTH_LIMIT => array(), + ); + } + + foreach ($this->plugins[$type] as $trigger => &$pool) { + if ($triggers & $trigger) { + $pool[] = $p; + } + } + } + + return true; + } + + public function clearPlugins() + { + $this->plugins = array(); + } + + public function haltParse() + { + $this->parse_break = true; + } + + public function childHasPath(InstanceObject $parent, BasicObject $child) + { + if ('object' === $parent->type && (null !== $parent->access_path || $child->static || $child->const)) { + if (BasicObject::ACCESS_PUBLIC === $child->access) { + return true; + } + + if (BasicObject::ACCESS_PRIVATE === $child->access && $this->caller_class) { + if ($this->caller_class === $child->owner_class) { + return true; + } + } elseif (BasicObject::ACCESS_PROTECTED === $child->access && $this->caller_class) { + if ($this->caller_class === $child->owner_class) { + return true; + } + + if (\is_subclass_of($this->caller_class, $child->owner_class)) { + return true; + } + + if (\is_subclass_of($child->owner_class, $this->caller_class)) { + return true; + } + } + } + + return false; + } + + /** + * Returns an array without the recursion marker in it. + * + * DO NOT pass an array that has had it's marker removed back + * into the parser, it will result in an extra recursion + * + * @param array $array Array potentially containing a recursion marker + * + * @return array Array with recursion marker removed + */ + public function getCleanArray(array $array) + { + unset($array[$this->marker]); + + return $array; + } + + protected function noRecurseCall() + { + $bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS); + + $caller_frame = array( + 'function' => __FUNCTION__, + ); + + while (isset($bt[0]['object']) && $bt[0]['object'] === $this) { + $caller_frame = \array_shift($bt); + } + + foreach ($bt as $frame) { + if (isset($frame['object']) && $frame['object'] === $this) { + throw new DomainException(__CLASS__.'::'.$caller_frame['function'].' cannot be called from inside a parse'); + } + } + } + + private function parseGeneric(&$var, BasicObject $o) + { + $rep = new Representation('Contents'); + $rep->contents = $var; + $rep->implicit_label = true; + $o->addRepresentation($rep); + $o->value = $rep; + + $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS); + + return $o; + } + + /** + * Parses a string into a Kint BlobObject structure. + * + * @param string $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseString(&$var, BasicObject $o) + { + $string = new BlobObject(); + $string->transplant($o); + $string->encoding = BlobObject::detectEncoding($var); + $string->size = BlobObject::strlen($var, $string->encoding); + + $rep = new Representation('Contents'); + $rep->contents = $var; + $rep->implicit_label = true; + + $string->addRepresentation($rep); + $string->value = $rep; + + $this->applyPlugins($var, $string, self::TRIGGER_SUCCESS); + + return $string; + } + + /** + * Parses an array into a Kint object structure. + * + * @param array $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseArray(array &$var, BasicObject $o) + { + $array = new BasicObject(); + $array->transplant($o); + $array->size = \count($var); + + if (isset($var[$this->marker])) { + --$array->size; + $array->hints[] = 'recursion'; + + $this->applyPlugins($var, $array, self::TRIGGER_RECURSION); + + return $array; + } + + $rep = new Representation('Contents'); + $rep->implicit_label = true; + $array->addRepresentation($rep); + $array->value = $rep; + + if (!$array->size) { + $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS); + + return $array; + } + + if ($this->depth_limit && $o->depth >= $this->depth_limit) { + $array->hints[] = 'depth_limit'; + + $this->applyPlugins($var, $array, self::TRIGGER_DEPTH_LIMIT); + + return $array; + } + + $copy = \array_values($var); + + // It's really really hard to access numeric string keys in arrays, + // and it's really really hard to access integer properties in + // objects, so we just use array_values and index by counter to get + // at it reliably for reference testing. This also affects access + // paths since it's pretty much impossible to access these things + // without complicated stuff you should never need to do. + $i = 0; + + // Set the marker for recursion + $var[$this->marker] = $array->depth; + + $refmarker = new stdClass(); + + foreach ($var as $key => &$val) { + if ($key === $this->marker) { + continue; + } + + $child = new BasicObject(); + $child->name = $key; + $child->depth = $array->depth + 1; + $child->access = BasicObject::ACCESS_NONE; + $child->operator = BasicObject::OPERATOR_ARRAY; + + if (null !== $array->access_path) { + if (\is_string($key) && (string) (int) $key === $key) { + $child->access_path = 'array_values('.$array->access_path.')['.$i.']'; // @codeCoverageIgnore + } else { + $child->access_path = $array->access_path.'['.\var_export($key, true).']'; + } + } + + $stash = $val; + $copy[$i] = $refmarker; + if ($val === $refmarker) { + $child->reference = true; + $val = $stash; + } + + $rep->contents[] = $this->parse($val, $child); + ++$i; + } + + $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS); + unset($var[$this->marker]); + + return $array; + } + + /** + * Parses an object into a Kint InstanceObject structure. + * + * @param object $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseObject(&$var, BasicObject $o) + { + $hash = \spl_object_hash($var); + $values = (array) $var; + + $object = new InstanceObject(); + $object->transplant($o); + $object->classname = \get_class($var); + $object->hash = $hash; + $object->size = \count($values); + + if (isset($this->object_hashes[$hash])) { + $object->hints[] = 'recursion'; + + $this->applyPlugins($var, $object, self::TRIGGER_RECURSION); + + return $object; + } + + $this->object_hashes[$hash] = $object; + + if ($this->depth_limit && $o->depth >= $this->depth_limit) { + $object->hints[] = 'depth_limit'; + + $this->applyPlugins($var, $object, self::TRIGGER_DEPTH_LIMIT); + unset($this->object_hashes[$hash]); + + return $object; + } + + $reflector = new ReflectionObject($var); + + if ($reflector->isUserDefined()) { + $object->filename = $reflector->getFileName(); + $object->startline = $reflector->getStartLine(); + } + + $rep = new Representation('Properties'); + + $copy = \array_values($values); + $refmarker = new stdClass(); + $i = 0; + + // Reflection will not show parent classes private properties, and if a + // property was unset it will happly trigger a notice looking for it. + foreach ($values as $key => &$val) { + // Casting object to array: + // private properties show in the form "\0$owner_class_name\0$property_name"; + // protected properties show in the form "\0*\0$property_name"; + // public properties show in the form "$property_name"; + // http://www.php.net/manual/en/language.types.array.php#language.types.array.casting + + $child = new BasicObject(); + $child->depth = $object->depth + 1; + $child->owner_class = $object->classname; + $child->operator = BasicObject::OPERATOR_OBJECT; + $child->access = BasicObject::ACCESS_PUBLIC; + + $split_key = \explode("\0", $key, 3); + + if (3 === \count($split_key) && '' === $split_key[0]) { + $child->name = $split_key[2]; + if ('*' === $split_key[1]) { + $child->access = BasicObject::ACCESS_PROTECTED; + } else { + $child->access = BasicObject::ACCESS_PRIVATE; + $child->owner_class = $split_key[1]; + } + } elseif (KINT_PHP72) { + $child->name = (string) $key; + } else { + $child->name = $key; // @codeCoverageIgnore + } + + if ($this->childHasPath($object, $child)) { + $child->access_path = $object->access_path; + + if (!KINT_PHP72 && \is_int($child->name)) { + $child->access_path = 'array_values((array) '.$child->access_path.')['.$i.']'; // @codeCoverageIgnore + } elseif (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $child->name)) { + $child->access_path .= '->'.$child->name; + } else { + $child->access_path .= '->{'.\var_export((string) $child->name, true).'}'; + } + } + + $stash = $val; + $copy[$i] = $refmarker; + if ($val === $refmarker) { + $child->reference = true; + $val = $stash; + } + + $rep->contents[] = $this->parse($val, $child); + ++$i; + } + + $object->addRepresentation($rep); + $object->value = $rep; + $this->applyPlugins($var, $object, self::TRIGGER_SUCCESS); + unset($this->object_hashes[$hash]); + + return $object; + } + + /** + * Parses a resource into a Kint ResourceObject structure. + * + * @param resource $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseResource(&$var, BasicObject $o) + { + $resource = new ResourceObject(); + $resource->transplant($o); + $resource->resource_type = \get_resource_type($var); + + $this->applyPlugins($var, $resource, self::TRIGGER_SUCCESS); + + return $resource; + } + + /** + * Parses an unknown into a Kint object structure. + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseUnknown(&$var, BasicObject $o) + { + $o->type = 'unknown'; + $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS); + + return $o; + } + + /** + * Applies plugins for an object type. + * + * @param mixed $var variable + * @param BasicObject $o Kint object parsed so far + * @param int $trigger The trigger to check for the plugins + * + * @return bool Continue parsing + */ + private function applyPlugins(&$var, BasicObject &$o, $trigger) + { + $break_stash = $this->parse_break; + + /** @var bool Psalm bug workaround */ + $this->parse_break = false; + + $plugins = array(); + + if (isset($this->plugins[$o->type][$trigger])) { + $plugins = $this->plugins[$o->type][$trigger]; + } + + foreach ($plugins as $plugin) { + try { + $plugin->parse($var, $o, $trigger); + } catch (Exception $e) { + \trigger_error( + 'An exception ('.\get_class($e).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing Kint Parser Plugin "'.\get_class($plugin).'". Error message: '.$e->getMessage(), + E_USER_WARNING + ); + } + + if ($this->parse_break) { + $this->parse_break = $break_stash; + + return false; + } + } + + $this->parse_break = $break_stash; + + return true; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Plugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Plugin.php new file mode 100644 index 0000000..51d5f0b --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/Plugin.php @@ -0,0 +1,55 @@ +parser = $p; + } + + /** + * An array of types (As returned by gettype) for all data this plugin can operate on. + * + * @return array List of types + */ + public function getTypes() + { + return array(); + } + + public function getTriggers() + { + return Parser::TRIGGER_NONE; + } + + abstract public function parse(&$variable, BasicObject &$o, $trigger); +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ProxyPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ProxyPlugin.php new file mode 100644 index 0000000..3376d3a --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ProxyPlugin.php @@ -0,0 +1,66 @@ +types = $types; + $this->triggers = $triggers; + $this->callback = $callback; + } + + public function getTypes() + { + return $this->types; + } + + public function getTriggers() + { + return $this->triggers; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + return \call_user_func_array($this->callback, array(&$var, &$o, $trigger, $this->parser)); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SerializePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SerializePlugin.php new file mode 100644 index 0000000..c5dadb8 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SerializePlugin.php @@ -0,0 +1,108 @@ + Unserialization can result in code being loaded and executed due to + * > object instantiation and autoloading, and a malicious user may be able + * > to exploit this. + * + * The natural way to stop that from happening is to just refuse to unserialize + * stuff by default. Which is what we're doing for anything that's not scalar. + * + * @var bool + */ + public static $safe_mode = true; + public static $options = array(true); + + public function getTypes() + { + return array('string'); + } + + public function getTriggers() + { + return Parser::TRIGGER_SUCCESS; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + $trimmed = \rtrim($var); + + if ('N;' !== $trimmed && !\preg_match('/^(?:[COabis]:\\d+[:;]|d:\\d+(?:\\.\\d+);)/', $trimmed)) { + return; + } + + if (!self::$safe_mode || !\in_array($trimmed[0], array('C', 'O', 'a'), true)) { + // Second parameter only supported on PHP 7 + if (KINT_PHP70) { + // Suppress warnings on unserializeable variable + $data = @\unserialize($trimmed, self::$options); + } else { + $data = @\unserialize($trimmed); + } + + if (false === $data && 'b:0;' !== \substr($trimmed, 0, 4)) { + return; + } + } + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = 'unserialize('.$o->name.')'; + + if ($o->access_path) { + $base_obj->access_path = 'unserialize('.$o->access_path; + if (!KINT_PHP70 || self::$options === array(true)) { + $base_obj->access_path .= ')'; + } elseif (self::$options === array(false)) { + $base_obj->access_path .= ', false)'; + } else { + $base_obj->access_path .= ', Serialize::$options)'; + } + } + + $r = new Representation('Serialized'); + + if (isset($data)) { + $r->contents = $this->parser->parse($data, $base_obj); + } else { + $base_obj->hints[] = 'blacklist'; + $r->contents = $base_obj; + } + + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php new file mode 100644 index 0000000..b90c863 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SimpleXMLElementPlugin.php @@ -0,0 +1,154 @@ +hints[] = 'simplexml_element'; + + if (!self::$verbose) { + $o->removeRepresentation('properties'); + $o->removeRepresentation('iterator'); + $o->removeRepresentation('methods'); + } + + // Attributes + $a = new Representation('Attributes'); + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = '(string) '.$o->access_path; + } + + if ($attribs = $var->attributes()) { + $attribs = \iterator_to_array($attribs); + $attribs = \array_map('strval', $attribs); + } else { + $attribs = array(); + } + + // XML attributes are by definition strings and don't have children, + // so up the depth limit in case we're just below the limit since + // there won't be any recursive stuff anyway. + $a->contents = $this->parser->parseDeep($attribs, $base_obj)->value->contents; + + $o->addRepresentation($a, 0); + + // Children + // We need to check children() separately from the values we already parsed because + // text contents won't show up in children() but they will show up in properties. + // + // Why do we still need to check for attributes if we already have an attributes() + // method? Hell if I know! + $children = $var->children(); + + if ($o->value) { + $c = new Representation('Children'); + + foreach ($o->value->contents as $value) { + if ('@attributes' === $value->name) { + continue; + } + + if (isset($children->{$value->name})) { + $i = 0; + + while (isset($children->{$value->name}[$i])) { + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $value->name; + if ($value->access_path) { + $base_obj->access_path = $value->access_path.'['.$i.']'; + } + + $value = $this->parser->parse($children->{$value->name}[$i], $base_obj); + + if ($value->access_path && 'string' === $value->type) { + $value->access_path = '(string) '.$value->access_path; + } + + $c->contents[] = $value; + + ++$i; + } + } + } + + $o->size = \count($c->contents); + + if (!$o->size) { + $o->size = null; + + if (\strlen((string) $var)) { + $base_obj = new BlobObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $o->name; + if ($o->access_path) { + $base_obj->access_path = '(string) '.$o->access_path; + } + + $value = (string) $var; + + $c = new Representation('Contents'); + $c->implicit_label = true; + $c->contents = array($this->parser->parseDeep($value, $base_obj)); + } + } + + $o->addRepresentation($c, 0); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php new file mode 100644 index 0000000..8b72193 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplFileInfoPlugin.php @@ -0,0 +1,55 @@ +addRepresentation($r, 0); + $o->size = $r->getSize(); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplObjectStoragePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplObjectStoragePlugin.php new file mode 100644 index 0000000..03ff301 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/SplObjectStoragePlugin.php @@ -0,0 +1,54 @@ +getRepresentation('iterator'))) { + return; + } + + $r = $o->getRepresentation('iterator'); + if ($r) { + $o->size = !\is_array($r->contents) ? null : \count($r->contents); + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/StreamPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/StreamPlugin.php new file mode 100644 index 0000000..464a3ff --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/StreamPlugin.php @@ -0,0 +1,78 @@ +resource_type) { + return; + } + + if (!$meta = \stream_get_meta_data($var)) { + return; + } + + $rep = new Representation('Stream'); + $rep->implicit_label = true; + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'stream_get_meta_data('.$o->access_path.')'; + } + + $rep->contents = $this->parser->parse($meta, $base_obj); + + if (!\in_array('depth_limit', $rep->contents->hints, true)) { + $rep->contents = $rep->contents->value->contents; + } + + $o->addRepresentation($rep, 0); + $o->value = $rep; + + $stream = new StreamObject($meta); + $stream->transplant($o); + $o = $stream; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TablePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TablePlugin.php new file mode 100644 index 0000000..510c4ff --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TablePlugin.php @@ -0,0 +1,87 @@ +value->contents)) { + return; + } + + $array = $this->parser->getCleanArray($var); + + if (\count($array) < 2) { + return; + } + + // Ensure this is an array of arrays and that all child arrays have the + // same keys. We don't care about their children - if there's another + // "table" inside we'll just make another one down the value tab + $keys = null; + foreach ($array as $elem) { + if (!\is_array($elem) || \count($elem) < 2) { + return; + } + + if (null === $keys) { + $keys = \array_keys($elem); + } elseif (\array_keys($elem) !== $keys) { + return; + } + } + + // Ensure none of the child arrays are recursion or depth limit. We + // don't care if their children are since they are the table cells + foreach ($o->value->contents as $childarray) { + if (empty($childarray->value->contents)) { + return; + } + } + + // Objects by reference for the win! We can do a copy-paste of the value + // representation contents and just slap a new hint on there and hey + // presto we have our table representation with no extra memory used! + $table = new Representation('Table'); + $table->contents = $o->value->contents; + $table->hints[] = 'table'; + $o->addRepresentation($table, 0); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ThrowablePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ThrowablePlugin.php new file mode 100644 index 0000000..8490d1d --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ThrowablePlugin.php @@ -0,0 +1,60 @@ +transplant($o); + $r = new SourceRepresentation($var->getFile(), $var->getLine()); + $r->showfilename = true; + $throw->addRepresentation($r, 0); + + $o = $throw; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TimestampPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TimestampPlugin.php new file mode 100644 index 0000000..72958d6 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TimestampPlugin.php @@ -0,0 +1,71 @@ +value->label = 'Timestamp'; + $o->value->hints[] = 'timestamp'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ToStringPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ToStringPlugin.php new file mode 100644 index 0000000..8b7a65f --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/ToStringPlugin.php @@ -0,0 +1,67 @@ +hasMethod('__toString')) { + return; + } + + foreach (self::$blacklist as $class) { + if ($var instanceof $class) { + return; + } + } + + $r = new Representation('toString'); + $r->contents = (string) $var; + + $o->addRepresentation($r); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TracePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TracePlugin.php new file mode 100644 index 0000000..3554993 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/TracePlugin.php @@ -0,0 +1,92 @@ +value) { + return; + } + + $trace = $this->parser->getCleanArray($var); + + if (\count($trace) !== \count($o->value->contents) || !Utils::isTrace($trace)) { + return; + } + + $traceobj = new TraceObject(); + $traceobj->transplant($o); + $rep = $traceobj->value; + + $old_trace = $rep->contents; + + Utils::normalizeAliases(self::$blacklist); + + $rep->contents = array(); + + foreach ($old_trace as $frame) { + $index = $frame->name; + + if (!isset($trace[$index]['function'])) { + // Something's very very wrong here, but it's probably a plugin's fault + continue; + } + + if (Utils::traceFrameIsListed($trace[$index], self::$blacklist)) { + continue; + } + + $rep->contents[$index] = new TraceFrameObject($frame, $trace[$index]); + } + + \ksort($rep->contents); + $rep->contents = \array_values($rep->contents); + + $traceobj->clearRepresentations(); + $traceobj->addRepresentation($rep); + $traceobj->size = \count($rep->contents); + $o = $traceobj; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/XmlPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/XmlPlugin.php new file mode 100644 index 0000000..0947e9a --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Parser/XmlPlugin.php @@ -0,0 +1,150 @@ +access_path); + + if (empty($xml)) { + return; + } + + list($xml, $access_path, $name) = $xml; + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $name; + $base_obj->access_path = $access_path; + + $r = new Representation('XML'); + $r->contents = $this->parser->parse($xml, $base_obj); + + $o->addRepresentation($r, 0); + } + + protected static function xmlToSimpleXML($var, $parent_path) + { + try { + $errors = \libxml_use_internal_errors(true); + $xml = \simplexml_load_string($var); + \libxml_use_internal_errors($errors); + } catch (Exception $e) { + if (isset($errors)) { + \libxml_use_internal_errors($errors); + } + + return; + } + + if (!$xml) { + return; + } + + if (null === $parent_path) { + $access_path = null; + } else { + $access_path = 'simplexml_load_string('.$parent_path.')'; + } + + $name = $xml->getName(); + + return array($xml, $access_path, $name); + } + + /** + * Get the DOMDocument info. + * + * The documentation of DOMDocument::loadXML() states that while you can + * call it statically, it will give an E_STRICT warning. On my system it + * actually gives an E_DEPRECATED warning, but it works so we'll just add + * an error-silencing '@' to the access path. + * + * If it errors loading then we wouldn't have gotten this far in the first place. + * + * @param string $var The XML string + * @param null|string $parent_path The path to the parent, in this case the XML string + * + * @return null|array The root element DOMNode, the access path, and the root element name + */ + protected static function xmlToDOMDocument($var, $parent_path) + { + // There's no way to check validity in DOMDocument without making errors. For shame! + if (!self::xmlToSimpleXML($var, $parent_path)) { + return null; + } + + $xml = new DOMDocument(); + $xml->loadXML($var); + $xml = $xml->firstChild; + + if (null === $parent_path) { + $access_path = null; + } else { + $access_path = '@\\DOMDocument::loadXML('.$parent_path.')->firstChild'; + } + + $name = $xml->nodeName; + + return array($xml, $access_path, $name); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/CliRenderer.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/CliRenderer.php new file mode 100644 index 0000000..0d0846a --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/CliRenderer.php @@ -0,0 +1,152 @@ +windows_output = KINT_WIN; + } + + if (!self::$terminal_width) { + if (!KINT_WIN && self::$detect_width) { + self::$terminal_width = \exec('tput cols'); + } + + if (self::$terminal_width < self::$min_terminal_width) { + self::$terminal_width = self::$default_width; + } + } + + $this->colors = $this->windows_output ? false : self::$cli_colors; + + $this->header_width = self::$terminal_width; + } + + public function colorValue($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[32m".\str_replace("\n", "\x1b[0m\n\x1b[32m", $string)."\x1b[0m"; + } + + public function colorType($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[35;1m".\str_replace("\n", "\x1b[0m\n\x1b[35;1m", $string)."\x1b[0m"; + } + + public function colorTitle($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[36m".\str_replace("\n", "\x1b[0m\n\x1b[36m", $string)."\x1b[0m"; + } + + public function renderTitle(BasicObject $o) + { + if ($this->windows_output) { + return $this->utf8ToWindows(parent::renderTitle($o)); + } + + return parent::renderTitle($o); + } + + public function preRender() + { + return PHP_EOL; + } + + public function postRender() + { + if ($this->windows_output) { + return $this->utf8ToWindows(parent::postRender()); + } + + return parent::postRender(); + } + + public function escape($string, $encoding = false) + { + return \str_replace("\x1b", '\\x1b', $string); + } + + protected function utf8ToWindows($string) + { + return \str_replace( + array('┌', 'â•', 'â”', '│', 'â””', '─', '┘'), + array("\xda", "\xdc", "\xbf", "\xb3", "\xc0", "\xc4", "\xd9"), + $string + ); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/PlainRenderer.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/PlainRenderer.php new file mode 100644 index 0000000..493a774 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/PlainRenderer.php @@ -0,0 +1,237 @@ + array( + array('Kint\\Renderer\\PlainRenderer', 'renderJs'), + array('Kint\\Renderer\\Text\\MicrotimePlugin', 'renderJs'), + ), + 'style' => array( + array('Kint\\Renderer\\PlainRenderer', 'renderCss'), + ), + 'raw' => array(), + ); + + /** + * Path to the CSS file to load by default. + * + * @var string + */ + public static $theme = 'plain.css'; + + /** + * Output htmlentities instead of utf8. + * + * @var bool + */ + public static $disable_utf8 = false; + + public static $needs_pre_render = true; + + public static $always_pre_render = false; + + protected $force_pre_render = false; + protected $pre_render; + + public function __construct() + { + parent::__construct(); + + $this->pre_render = self::$needs_pre_render; + + if (self::$always_pre_render) { + $this->setPreRender(true); + } + } + + public function setCallInfo(array $info) + { + parent::setCallInfo($info); + + if (\in_array('@', $this->call_info['modifiers'], true)) { + $this->setPreRender(true); + } + } + + public function setStatics(array $statics) + { + parent::setStatics($statics); + + if (!empty($statics['return'])) { + $this->setPreRender(true); + } + } + + public function setPreRender($pre_render) + { + $this->pre_render = $pre_render; + $this->force_pre_render = true; + } + + public function getPreRender() + { + return $this->pre_render; + } + + public function colorValue($string) + { + return ''.$string.''; + } + + public function colorType($string) + { + return ''.$string.''; + } + + public function colorTitle($string) + { + return ''.$string.''; + } + + public function renderTitle(BasicObject $o) + { + if (self::$disable_utf8) { + return $this->utf8ToHtmlentity(parent::renderTitle($o)); + } + + return parent::renderTitle($o); + } + + public function preRender() + { + $output = ''; + + if ($this->pre_render) { + foreach (self::$pre_render_sources as $type => $values) { + $contents = ''; + foreach ($values as $v) { + $contents .= \call_user_func($v, $this); + } + + if (!\strlen($contents)) { + continue; + } + + switch ($type) { + case 'script': + $output .= ''; + break; + case 'style': + $output .= ''; + break; + default: + $output .= $contents; + } + } + + // Don't pre-render on every dump + if (!$this->force_pre_render) { + self::$needs_pre_render = false; + } + } + + return $output.'
'; + } + + public function postRender() + { + if (self::$disable_utf8) { + return $this->utf8ToHtmlentity(parent::postRender()).'
'; + } + + return parent::postRender().'
'; + } + + public function ideLink($file, $line) + { + $path = $this->escape(Kint::shortenPath($file)).':'.$line; + $ideLink = Kint::getIdeLink($file, $line); + + if (!$ideLink) { + return $path; + } + + $class = ''; + + if (\preg_match('/https?:\\/\\//i', $ideLink)) { + $class = 'class="kint-ide-link" '; + } + + return ''.$path.''; + } + + public function escape($string, $encoding = false) + { + if (false === $encoding) { + $encoding = BlobObject::detectEncoding($string); + } + + $original_encoding = $encoding; + + if (false === $encoding || 'ASCII' === $encoding) { + $encoding = 'UTF-8'; + } + + $string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding); + + // this call converts all non-ASCII characters into numeirc htmlentities + if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) { + $string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding); + } + + return $string; + } + + protected function utf8ToHtmlentity($string) + { + return \str_replace( + array('┌', 'â•', 'â”', '│', 'â””', '─', '┘'), + array('┌', '═', '┐', '│', '└', '─', '┘'), + $string + ); + } + + protected static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/plain.js'); + } + + protected static function renderCss() + { + if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { + return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); + } + + return \file_get_contents(self::$theme); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Renderer.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Renderer.php new file mode 100644 index 0000000..cf8b0a7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Renderer.php @@ -0,0 +1,185 @@ +call_info = array( + 'params' => $info['params'], + 'modifiers' => $info['modifiers'], + 'callee' => $info['callee'], + 'caller' => $info['caller'], + 'trace' => $info['trace'], + ); + } + + public function getCallInfo() + { + return $this->call_info; + } + + public function setStatics(array $statics) + { + $this->statics = $statics; + $this->setShowTrace(!empty($statics['display_called_from'])); + } + + public function getStatics() + { + return $this->statics; + } + + public function setShowTrace($show_trace) + { + $this->show_trace = $show_trace; + } + + public function getShowTrace() + { + return $this->show_trace; + } + + /** + * Returns the first compatible plugin available. + * + * @param array $plugins Array of hints to class strings + * @param array $hints Array of object hints + * + * @return array Array of hints to class strings filtered and sorted by object hints + */ + public function matchPlugins(array $plugins, array $hints) + { + $out = array(); + + foreach ($hints as $key) { + if (isset($plugins[$key])) { + $out[$key] = $plugins[$key]; + } + } + + return $out; + } + + public function filterParserPlugins(array $plugins) + { + return $plugins; + } + + public function preRender() + { + return ''; + } + + public function postRender() + { + return ''; + } + + public static function sortPropertiesFull(BasicObject $a, BasicObject $b) + { + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByName($a, $b); + if ($sort) { + return $sort; + } + + return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + } + + /** + * Sorts an array of BasicObject. + * + * @param BasicObject[] $contents Object properties to sort + * @param int $sort + * + * @return BasicObject[] + */ + public static function sortProperties(array $contents, $sort) + { + switch ($sort) { + case self::SORT_VISIBILITY: + /** @var array Containers to quickly stable sort by type */ + $containers = array( + BasicObject::ACCESS_PUBLIC => array(), + BasicObject::ACCESS_PROTECTED => array(), + BasicObject::ACCESS_PRIVATE => array(), + BasicObject::ACCESS_NONE => array(), + ); + + foreach ($contents as $item) { + $containers[$item->access][] = $item; + } + + return \call_user_func_array('array_merge', $containers); + case self::SORT_FULL: + \usort($contents, array('Kint\\Renderer\\Renderer', 'sortPropertiesFull')); + // no break + default: + return $contents; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php new file mode 100644 index 0000000..5b4d613 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BinaryPlugin.php @@ -0,0 +1,51 @@ +'; + + $chunks = \str_split($r->contents, self::$line_length); + + foreach ($chunks as $index => $chunk) { + $out .= \sprintf('%08X', $index * self::$line_length).":\t"; + $out .= \implode(' ', \str_split(\str_pad(\bin2hex($chunk), 2 * self::$line_length, ' '), self::$chunk_length)); + $out .= "\t".\preg_replace('/[^\\x20-\\x7E]/', '.', $chunk)."\n"; + } + + $out .= ''; + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php new file mode 100644 index 0000000..fcfedc1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/BlacklistPlugin.php @@ -0,0 +1,36 @@ +'.$this->renderLockedHeader($o, 'Blacklisted').''; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php new file mode 100644 index 0000000..5834017 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/CallablePlugin.php @@ -0,0 +1,174 @@ +renderMethod($o); + } + + if ($o instanceof ClosureObject) { + return $this->renderClosure($o); + } + + return $this->renderCallable($o); + } + + protected function renderClosure(ClosureObject $o) + { + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')'; + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; + } + + protected function renderCallable(BasicObject $o) + { + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).''; + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; + } + + protected function renderMethod(MethodObject $o) + { + if (!empty(self::$method_cache[$o->owner_class][$o->name])) { + $children = self::$method_cache[$o->owner_class][$o->name]['children']; + + $header = $this->renderer->renderHeaderWrapper( + $o, + (bool) \strlen($children), + self::$method_cache[$o->owner_class][$o->name]['header'] + ); + + return '
'.$header.$children.'
'; + } + + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers()) || $o->return_reference) { + $header .= ''.$s; + + if ($o->return_reference) { + if ($s) { + $header .= ' '; + } + $header .= $this->renderer->escape('&'); + } + + $header .= ' '; + } + + if (null !== ($s = $o->getName())) { + $function = $this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')'; + + if (null !== ($url = $o->getPhpDocUrl())) { + $function = ''.$function.''; + } + + $header .= ''.$function.''; + } + + if (!empty($o->returntype)) { + $header .= ': '; + + if ($o->return_reference) { + $header .= $this->renderer->escape('&'); + } + + $header .= $this->renderer->escape($o->returntype).''; + } elseif ($o->docstring) { + if (\preg_match('/@return\\s+(.*)\\r?\\n/m', $o->docstring, $matches)) { + if (\trim($matches[1])) { + $header .= ': '.$this->renderer->escape(\trim($matches[1])).''; + } + } + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + if (\strlen($o->owner_class) && \strlen($o->name)) { + self::$method_cache[$o->owner_class][$o->name] = array( + 'header' => $header, + 'children' => $children, + ); + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php new file mode 100644 index 0000000..79a9926 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ClosurePlugin.php @@ -0,0 +1,59 @@ +renderer->renderChildren($o); + + if (!($o instanceof ClosureObject)) { + $header = $this->renderer->renderHeader($o); + } else { + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).') '; + } + + $header .= 'Closure '; + $header .= $this->renderer->escape(Kint::shortenPath($o->filename)).':'.(int) $o->startline; + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php new file mode 100644 index 0000000..241a815 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ColorPlugin.php @@ -0,0 +1,100 @@ +getRepresentation('color'); + + if (!$r instanceof ColorRepresentation) { + return; + } + + $children = $this->renderer->renderChildren($o); + + $header = $this->renderer->renderHeader($o); + $header .= '
'; + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } + + public function renderTab(Representation $r) + { + if (!$r instanceof ColorRepresentation) { + return; + } + + $out = ''; + + if ($color = $r->getColor(ColorRepresentation::COLOR_NAME)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_3)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_6)) { + $out .= ''.$color."\n"; + } + + if ($r->hasAlpha()) { + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_4)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_8)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_RGBA)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HSLA)) { + $out .= ''.$color."\n"; + } + } else { + if ($color = $r->getColor(ColorRepresentation::COLOR_RGB)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HSL)) { + $out .= ''.$color."\n"; + } + } + + if (!\strlen($out)) { + return false; + } + + return '
'.$out.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php new file mode 100644 index 0000000..cd92b41 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DepthLimitPlugin.php @@ -0,0 +1,36 @@ +'.$this->renderLockedHeader($o, 'Depth Limit').''; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php new file mode 100644 index 0000000..19c5309 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/DocstringPlugin.php @@ -0,0 +1,70 @@ +contents) as $line) { + $docstring[] = \trim($line); + } + + $docstring = \implode("\n", $docstring); + + $location = array(); + + if ($r->class) { + $location[] = 'Inherited from '.$this->renderer->escape($r->class); + } + if ($r->file && $r->line) { + $location[] = 'Defined in '.$this->renderer->escape(Kint::shortenPath($r->file)).':'.((int) $r->line); + } + + $location = \implode("\n", $location); + + if ($location) { + if (\strlen($docstring)) { + $docstring .= "\n\n"; + } + + $location = ''.$location.''; + } elseif (0 === \strlen($docstring)) { + return ''; + } + + return '
'.$this->renderer->escape($docstring).$location.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php new file mode 100644 index 0000000..a56bb23 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/MicrotimePlugin.php @@ -0,0 +1,68 @@ +getDateTime()->format('Y-m-d H:i:s.u'); + if (null !== $r->lap) { + $out .= '
SINCE LAST CALL: '.\round($r->lap, 4).'s.'; + } + if (null !== $r->total) { + $out .= '
SINCE START: '.\round($r->total, 4).'s.'; + } + if (null !== $r->avg) { + $out .= '
AVERAGE DURATION: '.\round($r->avg, 4).'s.'; + } + + $bytes = Utils::getHumanReadableBytes($r->mem); + $out .= '
MEMORY USAGE: '.$r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_real); + $out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $bytes = Utils::getHumanReadableBytes($r->mem_peak); + $out .= '
PEAK MEMORY USAGE: '.$r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_peak_real); + $out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + return '
'.$out.'
'; + } + + public static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js'); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ObjectPluginInterface.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ObjectPluginInterface.php new file mode 100644 index 0000000..f46aa29 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/ObjectPluginInterface.php @@ -0,0 +1,33 @@ +renderer = $r; + } + + /** + * Renders a locked header. + * + * @param BasicObject $o + * @param string $content + */ + public function renderLockedHeader(BasicObject $o, $content) + { + $header = '
'; + + if (RichRenderer::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) { + $header .= ''; + } + + $header .= ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).' '; + + if ($s = $o->getOperator()) { + $header .= $this->renderer->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + $s = $this->renderer->escape($s); + + if ($o->reference) { + $s = '&'.$s; + } + + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getSize())) { + $header .= '('.$this->renderer->escape($s).') '; + } + + $header .= $content; + + if (!empty($ap)) { + $header .= '
'.$this->renderer->escape($ap).'
'; + } + + return $header.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php new file mode 100644 index 0000000..79828e7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/PluginInterface.php @@ -0,0 +1,33 @@ +'.$this->renderLockedHeader($o, 'Recursion').''; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php new file mode 100644 index 0000000..6c18931 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SimpleXMLElementPlugin.php @@ -0,0 +1,81 @@ +renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).' '; + + if ($s = $o->getOperator()) { + $header .= $this->renderer->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + $s = $this->renderer->escape($s); + + if ($o->reference) { + $s = '&'.$s; + } + + $header .= ''.$this->renderer->escape($s).' '; + } + + if (null !== ($s = $o->getSize())) { + $header .= '('.$this->renderer->escape($s).') '; + } + + if (null === $s && $c = $o->getRepresentation('contents')) { + $c = \reset($c->contents); + + if ($c && null !== ($s = $c->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= $this->renderer->escape($s); + } + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php new file mode 100644 index 0000000..5443dbf --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/SourcePlugin.php @@ -0,0 +1,79 @@ +source)) { + return false; + } + + $source = $r->source; + + // Trim empty lines from the start and end of the source + foreach ($source as $linenum => $line) { + if (\strlen(\trim($line)) || $linenum === $r->line) { + break; + } + + unset($source[$linenum]); + } + + foreach (\array_reverse($source, true) as $linenum => $line) { + if (\strlen(\trim($line)) || $linenum === $r->line) { + break; + } + + unset($source[$linenum]); + } + + $output = ''; + + foreach ($source as $linenum => $line) { + if ($linenum === $r->line) { + $output .= '
'.$this->renderer->escape($line)."\n".'
'; + } else { + $output .= '
'.$this->renderer->escape($line)."\n".'
'; + } + } + + if ($output) { + \reset($source); + + $data = ''; + if ($r->showfilename) { + $data = ' data-kint-filename="'.$this->renderer->escape($r->filename).'"'; + } + + return '
'.$output.'
'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php new file mode 100644 index 0000000..7cdbde7 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TabPluginInterface.php @@ -0,0 +1,33 @@ +'; + + $firstrow = \reset($r->contents); + + foreach ($firstrow->value->contents as $field) { + $out .= ''; + } + + $out .= ''; + + foreach ($r->contents as $row) { + $out .= ''; + + foreach ($row->value->contents as $field) { + $out .= 'getType())) { + $type = $this->renderer->escape($s); + + if ($field->reference) { + $ref = '&'; + $type = $ref.$type; + } + + if (null !== ($s = $field->getSize())) { + $size .= ' ('.$this->renderer->escape($s).')'; + } + } + + if ($type) { + $out .= ' title="'.$type.$size.'"'; + } + + $out .= '>'; + + switch ($field->type) { + case 'boolean': + $out .= $field->value->contents ? ''.$ref.'true' : ''.$ref.'false'; + break; + case 'integer': + case 'double': + $out .= (string) $field->value->contents; + break; + case 'null': + $out .= ''.$ref.'null'; + break; + case 'string': + if ($field->encoding) { + $val = $field->value->contents; + if (RichRenderer::$strlen_max && self::$respect_str_length && BlobObject::strlen($val) > RichRenderer::$strlen_max) { + $val = \substr($val, 0, RichRenderer::$strlen_max).'...'; + } + + $out .= $this->renderer->escape($val); + } else { + $out .= ''.$type.''; + } + break; + case 'array': + $out .= ''.$ref.'array'.$size; + break; + case 'object': + $out .= ''.$ref.$this->renderer->escape($field->classname).''.$size; + break; + case 'resource': + $out .= ''.$ref.'resource'; + break; + default: + $out .= ''.$ref.'unknown'; + break; + } + + if (\in_array('blacklist', $field->hints, true)) { + $out .= ' Blacklisted'; + } elseif (\in_array('recursion', $field->hints, true)) { + $out .= ' Recursion'; + } elseif (\in_array('depth_limit', $field->hints, true)) { + $out .= ' Depth Limit'; + } + + $out .= ''; + } + + $out .= ''; + } + + $out .= '
'.$this->renderer->escape($field->name).'
'; + $out .= $this->renderer->escape($row->name); + $out .= '
'; + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php new file mode 100644 index 0000000..6e3a2f8 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TimestampPlugin.php @@ -0,0 +1,42 @@ +contents); + + if ($dt) { + return '
'.$dt->setTimeZone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s T').'
'; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php new file mode 100644 index 0000000..6ca19bb --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Rich/TraceFramePlugin.php @@ -0,0 +1,68 @@ +trace['file']) && !empty($o->trace['line'])) { + $header = ''.$this->renderer->ideLink($o->trace['file'], (int) $o->trace['line']).' '; + } else { + $header = 'PHP internal call '; + } + + if ($o->trace['class']) { + $header .= $this->renderer->escape($o->trace['class'].$o->trace['type']); + } + + if (\is_string($o->trace['function'])) { + $function = $this->renderer->escape($o->trace['function'].'()'); + } else { + $function = $this->renderer->escape( + $o->trace['function']->getName().'('.$o->trace['function']->getParams().')' + ); + + if (null !== ($url = $o->trace['function']->getPhpDocUrl())) { + $function = ''.$function.''; + } + } + + $header .= ''.$function.''; + + $children = $this->renderer->renderChildren($o); + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/RichRenderer.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/RichRenderer.php new file mode 100644 index 0000000..dcd39ee --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/RichRenderer.php @@ -0,0 +1,612 @@ + 'Kint\\Renderer\\Rich\\BlacklistPlugin', + 'callable' => 'Kint\\Renderer\\Rich\\CallablePlugin', + 'closure' => 'Kint\\Renderer\\Rich\\ClosurePlugin', + 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', + 'depth_limit' => 'Kint\\Renderer\\Rich\\DepthLimitPlugin', + 'recursion' => 'Kint\\Renderer\\Rich\\RecursionPlugin', + 'simplexml_element' => 'Kint\\Renderer\\Rich\\SimpleXMLElementPlugin', + 'trace_frame' => 'Kint\\Renderer\\Rich\\TraceFramePlugin', + ); + + /** + * RichRenderer tab plugins should implement Kint\Renderer\Rich\TabPluginInterface. + */ + public static $tab_plugins = array( + 'binary' => 'Kint\\Renderer\\Rich\\BinaryPlugin', + 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', + 'docstring' => 'Kint\\Renderer\\Rich\\DocstringPlugin', + 'microtime' => 'Kint\\Renderer\\Rich\\MicrotimePlugin', + 'source' => 'Kint\\Renderer\\Rich\\SourcePlugin', + 'table' => 'Kint\\Renderer\\Rich\\TablePlugin', + 'timestamp' => 'Kint\\Renderer\\Rich\\TimestampPlugin', + ); + + public static $pre_render_sources = array( + 'script' => array( + array('Kint\\Renderer\\RichRenderer', 'renderJs'), + array('Kint\\Renderer\\Rich\\MicrotimePlugin', 'renderJs'), + ), + 'style' => array( + array('Kint\\Renderer\\RichRenderer', 'renderCss'), + ), + 'raw' => array(), + ); + + /** + * Whether or not to render access paths. + * + * Access paths can become incredibly heavy with very deep and wide + * structures. Given mostly public variables it will typically make + * up one quarter of the output HTML size. + * + * If this is an unacceptably large amount and your browser is groaning + * under the weight of the access paths - your first order of buisiness + * should be to get a new browser. Failing that, use this to turn them off. + * + * @var bool + */ + public static $access_paths = true; + + /** + * The maximum length of a string before it is truncated. + * + * Falsey to disable + * + * @var int + */ + public static $strlen_max = 80; + + /** + * Path to the CSS file to load by default. + * + * @var string + */ + public static $theme = 'original.css'; + + /** + * Assume types and sizes don't need to be escaped. + * + * Turn this off if you use anything but ascii in your class names, + * but it'll cause a slowdown of around 10% + * + * @var bool + */ + public static $escape_types = false; + + /** + * Move all dumps to a folder at the bottom of the body. + * + * @var bool + */ + public static $folder = true; + + /** + * Sort mode for object properties. + * + * @var int + */ + public static $sort = self::SORT_NONE; + + public static $needs_pre_render = true; + public static $needs_folder_render = true; + + public static $always_pre_render = false; + + protected $plugin_objs = array(); + protected $expand = false; + protected $force_pre_render = false; + protected $pre_render; + protected $use_folder; + + public function __construct() + { + $this->pre_render = self::$needs_pre_render; + $this->use_folder = self::$folder; + + if (self::$always_pre_render) { + $this->setForcePreRender(); + } + } + + public function setCallInfo(array $info) + { + parent::setCallInfo($info); + + if (\in_array('!', $this->call_info['modifiers'], true)) { + $this->setExpand(true); + $this->use_folder = false; + } + + if (\in_array('@', $this->call_info['modifiers'], true)) { + $this->setForcePreRender(); + } + } + + public function setStatics(array $statics) + { + parent::setStatics($statics); + + if (!empty($statics['expanded'])) { + $this->setExpand(true); + } + + if (!empty($statics['return'])) { + $this->setForcePreRender(); + } + } + + public function setExpand($expand) + { + $this->expand = $expand; + } + + public function getExpand() + { + return $this->expand; + } + + public function setForcePreRender() + { + $this->force_pre_render = true; + $this->pre_render = true; + } + + public function setPreRender($pre_render) + { + $this->setForcePreRender(); // TODO: Remove line in next major version + $this->pre_render = $pre_render; + } + + public function getPreRender() + { + return $this->pre_render; + } + + public function setUseFolder($use_folder) + { + $this->use_folder = $use_folder; + } + + public function getUseFolder() + { + return $this->use_folder; + } + + public function render(BasicObject $o) + { + if ($plugin = $this->getPlugin(self::$object_plugins, $o->hints)) { + if (\strlen($output = $plugin->renderObject($o))) { + return $output; + } + } + + $children = $this->renderChildren($o); + $header = $this->renderHeaderWrapper($o, (bool) \strlen($children), $this->renderHeader($o)); + + return '
'.$header.$children.'
'; + } + + public function renderNothing() + { + return '
No argument
'; + } + + public function renderHeaderWrapper(BasicObject $o, $has_children, $contents) + { + $out = 'expand) { + $out .= ' kint-show'; + } + + $out .= '"'; + } + + $out .= '>'; + + if (self::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) { + $out .= ''; + } + + if ($has_children) { + $out .= ''; + + if (0 === $o->depth) { + $out .= ''; + $out .= ''; + } + + $out .= ''; + } + + $out .= $contents; + + if (!empty($ap)) { + $out .= '
'.$this->escape($ap).'
'; + } + + return $out.''; + } + + public function renderHeader(BasicObject $o) + { + $output = ''; + + if (null !== ($s = $o->getModifiers())) { + $output .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $output .= ''.$this->escape($s).' '; + + if ($s = $o->getOperator()) { + $output .= $this->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + if (self::$escape_types) { + $s = $this->escape($s); + } + + if ($o->reference) { + $s = '&'.$s; + } + + $output .= ''.$s.' '; + } + + if (null !== ($s = $o->getSize())) { + if (self::$escape_types) { + $s = $this->escape($s); + } + $output .= '('.$s.') '; + } + + if (null !== ($s = $o->getValueShort())) { + $s = \preg_replace('/\\s+/', ' ', $s); + + if (self::$strlen_max) { + $s = Utils::truncateString($s, self::$strlen_max); + } + + $output .= $this->escape($s); + } + + return \trim($output); + } + + public function renderChildren(BasicObject $o) + { + $contents = array(); + $tabs = array(); + + foreach ($o->getRepresentations() as $rep) { + $result = $this->renderTab($o, $rep); + if (\strlen($result)) { + $contents[] = $result; + $tabs[] = $rep; + } + } + + if (empty($tabs)) { + return ''; + } + + $output = '
'; + + if (1 === \count($tabs) && $tabs[0]->labelIsImplicit()) { + $output .= \reset($contents); + } else { + $output .= '
    '; + + foreach ($tabs as $i => $tab) { + if (0 === $i) { + $output .= '
  • '; + } else { + $output .= '
  • '; + } + + $output .= $this->escape($tab->getLabel()).'
  • '; + } + + $output .= '
    '; + + foreach ($contents as $tab) { + $output .= '
  • '.$tab.'
  • '; + } + + $output .= '
'; + } + + return $output.'
'; + } + + public function preRender() + { + $output = ''; + + if ($this->pre_render) { + foreach (self::$pre_render_sources as $type => $values) { + $contents = ''; + foreach ($values as $v) { + $contents .= \call_user_func($v, $this); + } + + if (!\strlen($contents)) { + continue; + } + + switch ($type) { + case 'script': + $output .= ''; + break; + case 'style': + $output .= ''; + break; + default: + $output .= $contents; + } + } + + // Don't pre-render on every dump + if (!$this->force_pre_render) { + self::$needs_pre_render = false; + } + } + + $output .= '
'; + + return $output; + } + + public function postRender() + { + if (!$this->show_trace) { + return '
'; + } + + $output = '
'; + $output .= ' '; + + if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) { + $output .= ''; + } + + if (isset($this->call_info['callee']['file'])) { + $output .= 'Called from '.$this->ideLink( + $this->call_info['callee']['file'], + $this->call_info['callee']['line'] + ); + } + + if (isset($this->call_info['callee']['function']) && ( + !empty($this->call_info['callee']['class']) || + !\in_array( + $this->call_info['callee']['function'], + array('include', 'include_once', 'require', 'require_once'), + true + ) + ) + ) { + $output .= ' ['; + if (isset($this->call_info['callee']['class'])) { + $output .= $this->call_info['callee']['class']; + } + if (isset($this->call_info['callee']['type'])) { + $output .= $this->call_info['callee']['type']; + } + $output .= $this->call_info['callee']['function'].'()]'; + } + + if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) { + $output .= '
    '; + foreach ($this->call_info['trace'] as $index => $step) { + if (!$index) { + continue; + } + + $output .= '
  1. '.$this->ideLink($step['file'], $step['line']); // closing tag not required + if (isset($step['function']) + && !\in_array($step['function'], array('include', 'include_once', 'require', 'require_once'), true) + ) { + $output .= ' ['; + if (isset($step['class'])) { + $output .= $step['class']; + } + if (isset($step['type'])) { + $output .= $step['type']; + } + $output .= $step['function'].'()]'; + } + } + $output .= '
'; + } + + $output .= '
'; + + return $output; + } + + public function escape($string, $encoding = false) + { + if (false === $encoding) { + $encoding = BlobObject::detectEncoding($string); + } + + $original_encoding = $encoding; + + if (false === $encoding || 'ASCII' === $encoding) { + $encoding = 'UTF-8'; + } + + $string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding); + + // this call converts all non-ASCII characters into numeirc htmlentities + if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) { + $string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding); + } + + return $string; + } + + public function ideLink($file, $line) + { + $path = $this->escape(Kint::shortenPath($file)).':'.$line; + $ideLink = Kint::getIdeLink($file, $line); + + if (!$ideLink) { + return $path; + } + + $class = ''; + + if (\preg_match('/https?:\\/\\//i', $ideLink)) { + $class = 'class="kint-ide-link" '; + } + + return ''.$path.''; + } + + protected function renderTab(BasicObject $o, Representation $rep) + { + if ($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) { + if (\strlen($output = $plugin->renderTab($rep))) { + return $output; + } + } + + if (\is_array($rep->contents)) { + $output = ''; + + if ($o instanceof InstanceObject && 'properties' === $rep->getName()) { + foreach (self::sortProperties($rep->contents, self::$sort) as $obj) { + $output .= $this->render($obj); + } + } else { + foreach ($rep->contents as $obj) { + $output .= $this->render($obj); + } + } + + return $output; + } + + if (\is_string($rep->contents)) { + $show_contents = false; + + // If it is the value representation of a string and its whitespace + // was truncated in the header, always display the full string + if ('string' !== $o->type || $o->value !== $rep) { + $show_contents = true; + } else { + if (\preg_match('/(:?[\\r\\n\\t\\f\\v]| {2})/', $rep->contents)) { + $show_contents = true; + } elseif (self::$strlen_max && BlobObject::strlen($o->getValueShort()) > self::$strlen_max) { + $show_contents = true; + } + + if (empty($o->encoding)) { + $show_contents = false; + } + } + + if ($show_contents) { + return '
'.$this->escape($rep->contents)."\n
"; + } + } + + if ($rep->contents instanceof BasicObject) { + return $this->render($rep->contents); + } + } + + protected function getPlugin(array $plugins, array $hints) + { + if ($plugins = $this->matchPlugins($plugins, $hints)) { + $plugin = \end($plugins); + + if (!isset($this->plugin_objs[$plugin])) { + $this->plugin_objs[$plugin] = new $plugin($this); + } + + return $this->plugin_objs[$plugin]; + } + } + + protected static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/rich.js'); + } + + protected static function renderCss() + { + if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { + return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); + } + + return \file_get_contents(self::$theme); + } + + protected static function renderFolder() + { + return '
Kint
'; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php new file mode 100644 index 0000000..127d32a --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/BlacklistPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('BLACKLISTED').PHP_EOL; + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php new file mode 100644 index 0000000..310b87e --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/DepthLimitPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('DEPTH LIMIT').PHP_EOL; + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php new file mode 100644 index 0000000..9128032 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/MicrotimePlugin.php @@ -0,0 +1,128 @@ +renderer instanceof PlainRenderer) { + $this->useJs = true; + } + } + + public function render(BasicObject $o) + { + $r = $o->getRepresentation('microtime'); + + if (!$r instanceof MicrotimeRepresentation) { + return false; + } + + $out = ''; + + if (0 == $o->depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o); + $out .= $this->renderer->renderChildren($o).PHP_EOL; + + $indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width); + + if ($this->useJs) { + $out .= ''; + } + + $out .= $indent.$this->renderer->colorType('TIME:').' '; + $out .= $this->renderer->colorValue($r->getDateTime()->format('Y-m-d H:i:s.u')).PHP_EOL; + + if (null !== $r->lap) { + $out .= $indent.$this->renderer->colorType('SINCE LAST CALL:').' '; + + $lap = \round($r->lap, 4); + + if ($this->useJs) { + $lap = ''.$lap.''; + } + + $out .= $this->renderer->colorValue($lap.'s').'.'.PHP_EOL; + } + if (null !== $r->total) { + $out .= $indent.$this->renderer->colorType('SINCE START:').' '; + $out .= $this->renderer->colorValue(\round($r->total, 4).'s').'.'.PHP_EOL; + } + if (null !== $r->avg) { + $out .= $indent.$this->renderer->colorType('AVERAGE DURATION:').' '; + + $avg = \round($r->avg, 4); + + if ($this->useJs) { + $avg = ''.$avg.''; + } + + $out .= $this->renderer->colorValue($avg.'s').'.'.PHP_EOL; + } + + $bytes = Utils::getHumanReadableBytes($r->mem); + $mem = $r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_real); + $mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $out .= $indent.$this->renderer->colorType('MEMORY USAGE:').' '; + $out .= $this->renderer->colorValue($mem).'.'.PHP_EOL; + + $bytes = Utils::getHumanReadableBytes($r->mem_peak); + $mem = $r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_peak_real); + $mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $out .= $indent.$this->renderer->colorType('PEAK MEMORY USAGE:').' '; + $out .= $this->renderer->colorValue($mem).'.'.PHP_EOL; + + if ($this->useJs) { + $out .= ''; + } + + return $out; + } + + public static function renderJs() + { + return RichPlugin::renderJs(); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/Plugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/Plugin.php new file mode 100644 index 0000000..9de25c1 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/Plugin.php @@ -0,0 +1,41 @@ +renderer = $r; + } + + abstract public function render(BasicObject $o); +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php new file mode 100644 index 0000000..72c2257 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/RecursionPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('RECURSION').PHP_EOL; + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php new file mode 100644 index 0000000..5833840 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/Text/TracePlugin.php @@ -0,0 +1,111 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).':'.PHP_EOL; + + $indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width); + + $i = 1; + foreach ($o->value->contents as $frame) { + $framedesc = $indent.\str_pad($i.': ', 4, ' '); + + if ($frame->trace['file']) { + $framedesc .= $this->renderer->ideLink($frame->trace['file'], $frame->trace['line']).PHP_EOL; + } else { + $framedesc .= 'PHP internal call'.PHP_EOL; + } + + $framedesc .= $indent.' '; + + if ($frame->trace['class']) { + $framedesc .= $this->renderer->escape($frame->trace['class']); + + if ($frame->trace['object']) { + $framedesc .= $this->renderer->escape('->'); + } else { + $framedesc .= '::'; + } + } + + if (\is_string($frame->trace['function'])) { + $framedesc .= $this->renderer->escape($frame->trace['function']).'(...)'; + } elseif ($frame->trace['function'] instanceof MethodObject) { + $framedesc .= $this->renderer->escape($frame->trace['function']->getName()); + $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; + } + + $out .= $this->renderer->colorType($framedesc).PHP_EOL.PHP_EOL; + + if ($source = $frame->getRepresentation('source')) { + $line_wanted = $source->line; + $source = $source->source; + + // Trim empty lines from the start and end of the source + foreach ($source as $linenum => $line) { + if (\trim($line) || $linenum === $line_wanted) { + break; + } + + unset($source[$linenum]); + } + + foreach (\array_reverse($source, true) as $linenum => $line) { + if (\trim($line) || $linenum === $line_wanted) { + break; + } + + unset($source[$linenum]); + } + + foreach ($source as $lineno => $line) { + if ($lineno == $line_wanted) { + $out .= $indent.$this->renderer->colorValue($this->renderer->escape($line)).PHP_EOL; + } else { + $out .= $indent.$this->renderer->escape($line).PHP_EOL; + } + } + } + + ++$i; + } + + return $out; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/TextRenderer.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/TextRenderer.php new file mode 100644 index 0000000..43b6c40 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Renderer/TextRenderer.php @@ -0,0 +1,346 @@ + 'Kint\\Renderer\\Text\\BlacklistPlugin', + 'depth_limit' => 'Kint\\Renderer\\Text\\DepthLimitPlugin', + 'microtime' => 'Kint\\Renderer\\Text\\MicrotimePlugin', + 'recursion' => 'Kint\\Renderer\\Text\\RecursionPlugin', + 'trace' => 'Kint\\Renderer\\Text\\TracePlugin', + ); + + /** + * Parser plugins must be instanceof one of these or + * it will be removed for performance reasons. + */ + public static $parser_plugin_whitelist = array( + 'Kint\\Parser\\BlacklistPlugin', + 'Kint\\Parser\\MicrotimePlugin', + 'Kint\\Parser\\StreamPlugin', + 'Kint\\Parser\\TracePlugin', + ); + + /** + * The maximum length of a string before it is truncated. + * + * Falsey to disable + * + * @var int + */ + public static $strlen_max = 0; + + /** + * The default width of the terminal for headers. + * + * @var int + */ + public static $default_width = 80; + + /** + * Indentation width. + * + * @var int + */ + public static $default_indent = 4; + + /** + * Decorate the header and footer. + * + * @var bool + */ + public static $decorations = true; + + /** + * Sort mode for object properties. + * + * @var int + */ + public static $sort = self::SORT_NONE; + + public $header_width = 80; + public $indent_width = 4; + + protected $plugin_objs = array(); + + public function __construct() + { + $this->header_width = self::$default_width; + $this->indent_width = self::$default_indent; + } + + public function render(BasicObject $o) + { + if ($plugin = $this->getPlugin(self::$plugins, $o->hints)) { + if (\strlen($output = $plugin->render($o))) { + return $output; + } + } + + $out = ''; + + if (0 == $o->depth) { + $out .= $this->colorTitle($this->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderHeader($o); + $out .= $this->renderChildren($o).PHP_EOL; + + return $out; + } + + public function renderNothing() + { + if (self::$decorations) { + return $this->colorTitle( + $this->boxText('No argument', $this->header_width) + ).PHP_EOL; + } + + return $this->colorTitle('No argument').PHP_EOL; + } + + public function boxText($text, $width) + { + $out = '┌'.\str_repeat('─', $width - 2).'â”'.PHP_EOL; + + if (\strlen($text)) { + $text = Utils::truncateString($text, $width - 4); + $text = \str_pad($text, $width - 4); + + $out .= '│ '.$this->escape($text).' │'.PHP_EOL; + } + + $out .= 'â””'.\str_repeat('─', $width - 2).'┘'; + + return $out; + } + + public function renderTitle(BasicObject $o) + { + $name = (string) $o->getName(); + + if (self::$decorations) { + return $this->boxText($name, $this->header_width); + } + + return Utils::truncateString($name, $this->header_width); + } + + public function renderHeader(BasicObject $o) + { + $output = array(); + + if ($o->depth) { + if (null !== ($s = $o->getModifiers())) { + $output[] = $s; + } + + if (null !== $o->name) { + $output[] = $this->escape(\var_export($o->name, true)); + + if (null !== ($s = $o->getOperator())) { + $output[] = $this->escape($s); + } + } + } + + if (null !== ($s = $o->getType())) { + if ($o->reference) { + $s = '&'.$s; + } + + $output[] = $this->colorType($this->escape($s)); + } + + if (null !== ($s = $o->getSize())) { + $output[] = '('.$this->escape($s).')'; + } + + if (null !== ($s = $o->getValueShort())) { + if (self::$strlen_max) { + $s = Utils::truncateString($s, self::$strlen_max); + } + $output[] = $this->colorValue($this->escape($s)); + } + + return \str_repeat(' ', $o->depth * $this->indent_width).\implode(' ', $output); + } + + public function renderChildren(BasicObject $o) + { + if ('array' === $o->type) { + $output = ' ['; + } elseif ('object' === $o->type) { + $output = ' ('; + } else { + return ''; + } + + $children = ''; + + if ($o->value && \is_array($o->value->contents)) { + if ($o instanceof InstanceObject && 'properties' === $o->value->getName()) { + foreach (self::sortProperties($o->value->contents, self::$sort) as $obj) { + $children .= $this->render($obj); + } + } else { + foreach ($o->value->contents as $child) { + $children .= $this->render($child); + } + } + } + + if ($children) { + $output .= PHP_EOL.$children; + $output .= \str_repeat(' ', $o->depth * $this->indent_width); + } + + if ('array' === $o->type) { + $output .= ']'; + } else { + $output .= ')'; + } + + return $output; + } + + public function colorValue($string) + { + return $string; + } + + public function colorType($string) + { + return $string; + } + + public function colorTitle($string) + { + return $string; + } + + public function postRender() + { + if (self::$decorations) { + $output = \str_repeat('â•', $this->header_width); + } else { + $output = ''; + } + + if (!$this->show_trace) { + return $this->colorTitle($output); + } + + if ($output) { + $output .= PHP_EOL; + } + + return $this->colorTitle($output.$this->calledFrom().PHP_EOL); + } + + public function filterParserPlugins(array $plugins) + { + $return = array(); + + foreach ($plugins as $index => $plugin) { + foreach (self::$parser_plugin_whitelist as $whitelist) { + if ($plugin instanceof $whitelist) { + $return[] = $plugin; + continue 2; + } + } + } + + return $return; + } + + public function ideLink($file, $line) + { + return $this->escape(Kint::shortenPath($file)).':'.$line; + } + + public function escape($string, $encoding = false) + { + return $string; + } + + protected function calledFrom() + { + $output = ''; + + if (isset($this->call_info['callee']['file'])) { + $output .= 'Called from '.$this->ideLink( + $this->call_info['callee']['file'], + $this->call_info['callee']['line'] + ); + } + + if (isset($this->call_info['callee']['function']) && ( + !empty($this->call_info['callee']['class']) || + !\in_array( + $this->call_info['callee']['function'], + array('include', 'include_once', 'require', 'require_once'), + true + ) + ) + ) { + $output .= ' ['; + if (isset($this->call_info['callee']['class'])) { + $output .= $this->call_info['callee']['class']; + } + if (isset($this->call_info['callee']['type'])) { + $output .= $this->call_info['callee']['type']; + } + $output .= $this->call_info['callee']['function'].'()]'; + } + + return $output; + } + + protected function getPlugin(array $plugins, array $hints) + { + if ($plugins = $this->matchPlugins($plugins, $hints)) { + $plugin = \end($plugins); + + if (!isset($this->plugin_objs[$plugin])) { + $this->plugin_objs[$plugin] = new $plugin($this); + } + + return $this->plugin_objs[$plugin]; + } + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/Utils.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Utils.php new file mode 100644 index 0000000..27a2491 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/Utils.php @@ -0,0 +1,240 @@ + (float) ($value / \pow(1024, $i)), + 'unit' => $unit[$i], + ); + } + + public static function isSequential(array $array) + { + return \array_keys($array) === \range(0, \count($array) - 1); + } + + public static function composerGetExtras($key = 'kint') + { + $extras = array(); + + if (0 === \strpos(KINT_DIR, 'phar://')) { + // Only run inside phar file, so skip for code coverage + return $extras; // @codeCoverageIgnore + } + + $folder = KINT_DIR.'/vendor'; + + for ($i = 0; $i < 4; ++$i) { + $installed = $folder.'/composer/installed.json'; + + if (\file_exists($installed) && \is_readable($installed)) { + $packages = \json_decode(\file_get_contents($installed), true); + + foreach ($packages as $package) { + if (isset($package['extra'][$key]) && \is_array($package['extra'][$key])) { + $extras = \array_replace($extras, $package['extra'][$key]); + } + } + + $folder = \dirname($folder); + + if (\file_exists($folder.'/composer.json') && \is_readable($folder.'/composer.json')) { + $composer = \json_decode(\file_get_contents($folder.'/composer.json'), true); + + if (isset($composer['extra'][$key]) && \is_array($composer['extra'][$key])) { + $extras = \array_replace($extras, $composer['extra'][$key]); + } + } + + break; + } + + $folder = \dirname($folder); + } + + return $extras; + } + + /** + * @codeCoverageIgnore + */ + public static function composerSkipFlags() + { + $extras = self::composerGetExtras(); + + if (!empty($extras['disable-facade']) && !\defined('KINT_SKIP_FACADE')) { + \define('KINT_SKIP_FACADE', true); + } + + if (!empty($extras['disable-helpers']) && !\defined('KINT_SKIP_HELPERS')) { + \define('KINT_SKIP_HELPERS', true); + } + } + + public static function isTrace(array $trace) + { + if (!self::isSequential($trace)) { + return false; + } + + static $bt_structure = array( + 'function' => 'string', + 'line' => 'integer', + 'file' => 'string', + 'class' => 'string', + 'object' => 'object', + 'type' => 'string', + 'args' => 'array', + ); + + $file_found = false; + + foreach ($trace as $frame) { + if (!\is_array($frame) || !isset($frame['function'])) { + return false; + } + + foreach ($frame as $key => $val) { + if (!isset($bt_structure[$key])) { + return false; + } + + if (\gettype($val) !== $bt_structure[$key]) { + return false; + } + + if ('file' === $key) { + $file_found = true; + } + } + } + + return $file_found; + } + + public static function traceFrameIsListed(array $frame, array $matches) + { + if (isset($frame['class'])) { + $called = array(\strtolower($frame['class']), \strtolower($frame['function'])); + } else { + $called = \strtolower($frame['function']); + } + + return \in_array($called, $matches, true); + } + + public static function normalizeAliases(array &$aliases) + { + static $name_regex = '[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*'; + + foreach ($aliases as $index => &$alias) { + if (\is_array($alias) && 2 === \count($alias)) { + $alias = \array_values(\array_filter($alias, 'is_string')); + + if (2 === \count($alias) && + \preg_match('/^'.$name_regex.'$/', $alias[1]) && + \preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias[0]) + ) { + $alias = array( + \strtolower(\ltrim($alias[0], '\\')), + \strtolower($alias[1]), + ); + } else { + unset($aliases[$index]); + continue; + } + } elseif (\is_string($alias)) { + if (\preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias)) { + $alias = \explode('\\', \strtolower($alias)); + $alias = \end($alias); + } else { + unset($aliases[$index]); + continue; + } + } else { + unset($aliases[$index]); + } + } + + $aliases = \array_values($aliases); + } + + public static function truncateString($input, $length = PHP_INT_MAX, $end = '...', $encoding = false) + { + $length = (int) $length; + $endlength = BlobObject::strlen($end); + + if ($endlength >= $length) { + throw new InvalidArgumentException('Can\'t truncate a string to '.$length.' characters if ending with string '.$endlength.' characters long'); + } + + if (BlobObject::strlen($input, $encoding) > $length) { + return BlobObject::substr($input, 0, $length - $endlength, $encoding).$end; + } + + return $input; + } + + public static function getTypeString(ReflectionType $type) + { + if ($type instanceof ReflectionNamedType) { + return $type->getName(); + } + + return (string) $type; // @codeCoverageIgnore + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/init.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/init.php new file mode 100644 index 0000000..952e041 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/init.php @@ -0,0 +1,62 @@ += 0)); +\define('KINT_PHP70', (\version_compare(PHP_VERSION, '7.0') >= 0)); +\define('KINT_PHP72', (\version_compare(PHP_VERSION, '7.2') >= 0)); +\define('KINT_PHP73', (\version_compare(PHP_VERSION, '7.3') >= 0)); +\define('KINT_PHP74', (\version_compare(PHP_VERSION, '7.4') >= 0)); + +// Dynamic default settings +Kint::$file_link_format = \ini_get('xdebug.file_link_format'); +if (isset($_SERVER['DOCUMENT_ROOT'])) { + Kint::$app_root_dirs = array( + $_SERVER['DOCUMENT_ROOT'] => '', + \realpath($_SERVER['DOCUMENT_ROOT']) => '', + ); +} + +Utils::composerSkipFlags(); + +if ((!\defined('KINT_SKIP_FACADE') || !KINT_SKIP_FACADE) && !\class_exists('Kint')) { + \class_alias('Kint\\Kint', 'Kint'); +} + +if (!\defined('KINT_SKIP_HELPERS') || !KINT_SKIP_HELPERS) { + require_once __DIR__.'/init_helpers.php'; +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/init_helpers.php b/vendor/codeigniter4/framework/system/ThirdParty/Kint/init_helpers.php new file mode 100644 index 0000000..b961d67 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/init_helpers.php @@ -0,0 +1,84 @@ +dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #d7d7d7}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#06f;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:red}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #d7d7d7;background:#f8f8f8;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#f8f8f8;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#f8f8f8}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #d7d7d7;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#f8f8f8;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#f8f8f8;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f8f8f8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#f8f8f8;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #d7d7d7}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#f8f8f8;border:1px solid #d7d7d7;border-top:0}.kint-rich ul.kint-tabs>li{background:#f8f8f8;border:1px solid #d7d7d7;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#aaa;color:red}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#f8f8f8;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#aaa;color:red}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #d7d7d7;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#aaa}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #d7d7d7;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#f8f8f8;color:#1d1e1e}.kint-rich table td{background:#f8f8f8;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #aaa inset}.kint-rich table tr:hover var{color:red}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #f8f8f8}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #aaa;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#f8f8f8}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #aaa,0 1px #aaa,1px 0 #aaa,0 -1px #aaa;color:#f8f8f8;font-weight:bold}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:#f8f8f8}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:#f8f8f8;border:1px solid #d7d7d7;border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:25px}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:1px solid #d7d7d7;background:#fff;font-weight:bold;padding-top:0;border-bottom:1px solid #fff !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid #fff}.kint-rich ul>li>pre{border:1px solid #d7d7d7}.kint-rich dt:hover+dd>ul{border-color:#aaa}.kint-rich pre{background:#fff;margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:#cfc}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:#fff}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:#fff}.kint-rich table tr:hover>td{box-shadow:none;background:#cfc} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/microtime.js b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/microtime.js new file mode 100644 index 0000000..20e3445 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/microtime.js @@ -0,0 +1 @@ +void 0===window.kintMicrotimeInitialized&&(window.kintMicrotimeInitialized=1,window.addEventListener("load",function(){"use strict";var c={},i=Array.prototype.slice.call(document.querySelectorAll("[data-kint-microtime-group]"),0);i.forEach(function(i){if(i.querySelector(".kint-microtime-lap")){var t=i.getAttribute("data-kint-microtime-group"),e=parseFloat(i.querySelector(".kint-microtime-lap").innerHTML),r=parseFloat(i.querySelector(".kint-microtime-avg").innerHTML);void 0===c[t]&&(c[t]={}),(void 0===c[t].min||c[t].min>e)&&(c[t].min=e),(void 0===c[t].max||c[t].maxdl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxnIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iI0ZGRiI+PHBhdGggZD0iTTEgMWgyOHYyOEgxem01IDE0aDE4bS05IDlWNk0xIDYxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzM3OSIvPjxwYXRoIGQ9Ik0xIDMxaDI4djI4SDF6bTUgMTRoMThtLTkgOVYzNk0xIDkxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzVBMyIvPjxwYXRoIGQ9Ik0xIDEyMWgyOHYyOEgxem01IDVsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZT0iI0NDQyIvPjwvZz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #b6cedb}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#0092db;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#5cb730}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #b6cedb;background:#e0eaef;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#e0eaef;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#e0eaef}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #b6cedb;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#c1d4df;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#d0d0d0;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#e8e8e8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#c1d4df;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #b6cedb}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#e0eaef;border:1px solid #b6cedb;border-top:0}.kint-rich ul.kint-tabs>li{background:#c1d4df;border:1px solid #b6cedb;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#0092db;color:#5cb730}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#e0eaef;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#0092db;color:#5cb730}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #b6cedb;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#0092db}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #b6cedb;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#c1d4df;color:#1d1e1e}.kint-rich table td{background:#e0eaef;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #0092db inset}.kint-rich table tr:hover var{color:#5cb730}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #c1d4df}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #0092db;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#c1d4df}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #0092db,0 1px #0092db,1px 0 #0092db,0 -1px #0092db;color:#e0eaef;font-weight:bold}.kint-rich>dl>dt{background:linear-gradient(to bottom, #e3ecf0 0, #c0d4df 100%)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, #9dbed0 0px, #b2ccda 100%)}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li{background:#e0eaef}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li.kint-active-tab{background:#c1d4df}.kint-rich>dl.kint-trace>dt{background:linear-gradient(to bottom, #c0d4df 0px, #e3ecf0 100%)}.kint-rich .kint-source .kint-highlight{background:#f0eb96} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.css b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.css new file mode 100644 index 0000000..ba1eba0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.css @@ -0,0 +1 @@ +.kint-plain{background:rgba(255,255,255,0.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-lap{font-weight:bold;text-shadow:1px 0 #fff, 0 1px #fff, -1px 0 #fff, 0 -1px #fff} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.js b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.js new file mode 100644 index 0000000..9791fc9 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/plain.js @@ -0,0 +1 @@ +void 0===window.kintPlain&&(window.kintPlain=function(){"use strict";var i={initLoad:function(){i.style=window.kintShared.dedupe("style.kint-plain-style",i.style),i.script=window.kintShared.dedupe("script.kint-plain-script",i.script)},style:null,script:null};return i}()),window.kintShared.runOnce(window.kintPlain.initLoad); diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/rich.js b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/rich.js new file mode 100644 index 0000000..18fb072 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/rich.js @@ -0,0 +1 @@ +void 0===window.kintRich&&(window.kintRich=function(){"use strict";var n={selectText:function(e){var t=window.getSelection(),a=document.createRange();a.selectNodeContents(e),t.removeAllRanges(),t.addRange(a)},each:function(e,t){Array.prototype.slice.call(document.querySelectorAll(e),0).forEach(t)},hasClass:function(e,t){return!!e.classList&&(void 0===t&&(t="kint-show"),e.classList.contains(t))},addClass:function(e,t){void 0===t&&(t="kint-show"),e.classList.add(t)},removeClass:function(e,t){return void 0===t&&(t="kint-show"),e.classList.remove(t),e},toggle:function(e,t){var a=n.getChildren(e);a&&(void 0===t&&(t=n.hasClass(e)),t?n.removeClass(e):n.addClass(e),1===a.childNodes.length&&(a=a.childNodes[0].childNodes[0])&&n.hasClass(a,"kint-parent")&&n.toggle(a,t))},toggleChildren:function(e,t){var a=n.getChildren(e);if(a){var r=a.getElementsByClassName("kint-parent"),o=r.length;for(void 0===t&&(t=!n.hasClass(e));o--;)n.toggle(r[o],t)}},toggleAll:function(e){for(var t=document.getElementsByClassName("kint-parent"),a=t.length,r=!n.hasClass(e.parentNode);a--;)n.toggle(t[a],r)},switchTab:function(e){var t,a=e.previousSibling,r=0;for(n.removeClass(e.parentNode.getElementsByClassName("kint-active-tab")[0],"kint-active-tab"),n.addClass(e,"kint-active-tab");a;)1===a.nodeType&&r++,a=a.previousSibling;t=e.parentNode.nextSibling.childNodes;for(var o=0;o"},openInNewWindow:function(e){var t=window.open();t&&(t.document.open(),t.document.write(n.mktag("html")+n.mktag("head")+n.mktag("title")+"Kint ("+(new Date).toISOString()+")"+n.mktag("/title")+n.mktag('meta charset="utf-8"')+document.getElementsByClassName("kint-rich-script")[0].outerHTML+document.getElementsByClassName("kint-rich-style")[0].outerHTML+n.mktag("/head")+n.mktag("body")+'
'+e.parentNode.outerHTML+"
"+n.mktag("/body")),t.document.close())},sortTable:function(e,a){var t=e.tBodies[0];[].slice.call(e.tBodies[0].rows).sort(function(e,t){if(e=e.cells[a].textContent.trim().toLocaleLowerCase(),t=t.cells[a].textContent.trim().toLocaleLowerCase(),isNaN(e)||isNaN(t)){if(isNaN(e)&&!isNaN(t))return 1;if(isNaN(t)&&!isNaN(e))return-1}else e=parseFloat(e),t=parseFloat(t);return eli:not(.kint-active-tab)",function(e){0===e.offsetWidth&&0===e.offsetHeight||n.keyboardNav.targets.push(e)})},sync:function(e){var t=document.querySelector(".kint-focused");if(t&&n.removeClass(t,"kint-focused"),n.keyboardNav.active){var a=n.keyboardNav.targets[n.keyboardNav.target];n.addClass(a,"kint-focused"),e||n.keyboardNav.scroll(a)}},scroll:function(e){var t=function(e){return e.offsetTop+(e.offsetParent?t(e.offsetParent):0)},a=t(e);if(n.folder){var r=n.folder.querySelector("dd.kint-folder");r.scrollTo(0,a-r.clientHeight/2)}else window.scrollTo(0,a-window.innerHeight/2)},moveCursor:function(e){for(n.keyboardNav.target+=e;n.keyboardNav.target<0;)n.keyboardNav.target+=n.keyboardNav.targets.length;for(;n.keyboardNav.target>=n.keyboardNav.targets.length;)n.keyboardNav.target-=n.keyboardNav.targets.length;n.keyboardNav.sync()},setCursor:function(e){n.keyboardNav.fetchTargets();for(var t=0;tdl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}body{background:#073642;color:#fff}.kint-rich{box-shadow:0 0 5px 3px #073642}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/solarized.css b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/solarized.css new file mode 100644 index 0000000..db5da0d --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/Kint/resources/compiled/solarized.css @@ -0,0 +1 @@ +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,0.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:none}.kint-rich.kint-folder.kint-show{display:block}.kint-rich.kint-folder dd.kint-folder{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#657b83}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/AbstractLogger.php b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/AbstractLogger.php new file mode 100644 index 0000000..d5106da --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/AbstractLogger.php @@ -0,0 +1,120 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = []) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = []) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = []) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = []) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = []) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = []) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = []) + { + $this->log(LogLevel::DEBUG, $message, $context); + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/InvalidArgumentException.php b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/InvalidArgumentException.php new file mode 100644 index 0000000..67f852d --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/InvalidArgumentException.php @@ -0,0 +1,7 @@ +logger = $logger; + } +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerInterface.php b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerInterface.php new file mode 100644 index 0000000..20c7ff0 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/LoggerInterface.php @@ -0,0 +1,112 @@ +log(LogLevel::EMERGENCY, $message, $context); + } + + /** + * Action must be taken immediately. + * + * Example: Entire website down, database unavailable, etc. This should + * trigger the SMS alerts and wake you up. + * + * @param string $message + * @param array $context + * @return null + */ + public function alert($message, array $context = []) + { + $this->log(LogLevel::ALERT, $message, $context); + } + + /** + * Critical conditions. + * + * Example: Application component unavailable, unexpected exception. + * + * @param string $message + * @param array $context + * @return null + */ + public function critical($message, array $context = []) + { + $this->log(LogLevel::CRITICAL, $message, $context); + } + + /** + * Runtime errors that do not require immediate action but should typically + * be logged and monitored. + * + * @param string $message + * @param array $context + * @return null + */ + public function error($message, array $context = []) + { + $this->log(LogLevel::ERROR, $message, $context); + } + + /** + * Exceptional occurrences that are not errors. + * + * Example: Use of deprecated APIs, poor use of an API, undesirable things + * that are not necessarily wrong. + * + * @param string $message + * @param array $context + * @return null + */ + public function warning($message, array $context = []) + { + $this->log(LogLevel::WARNING, $message, $context); + } + + /** + * Normal but significant events. + * + * @param string $message + * @param array $context + * @return null + */ + public function notice($message, array $context = []) + { + $this->log(LogLevel::NOTICE, $message, $context); + } + + /** + * Interesting events. + * + * Example: User logs in, SQL logs. + * + * @param string $message + * @param array $context + * @return null + */ + public function info($message, array $context = []) + { + $this->log(LogLevel::INFO, $message, $context); + } + + /** + * Detailed debug information. + * + * @param string $message + * @param array $context + * @return null + */ + public function debug($message, array $context = []) + { + $this->log(LogLevel::DEBUG, $message, $context); + } + + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + abstract public function log($level, $message, array $context = []); +} diff --git a/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/NullLogger.php b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/NullLogger.php new file mode 100644 index 0000000..e47d4b9 --- /dev/null +++ b/vendor/codeigniter4/framework/system/ThirdParty/PSR/Log/NullLogger.php @@ -0,0 +1,27 @@ +logger) { }` + * blocks. + */ +class NullLogger extends AbstractLogger +{ + /** + * Logs with an arbitrary level. + * + * @param mixed $level + * @param string $message + * @param array $context + * @return null + */ + public function log($level, $message, array $context = []) + { + // noop + } +} diff --git a/vendor/codeigniter4/framework/system/Throttle/Throttler.php b/vendor/codeigniter4/framework/system/Throttle/Throttler.php new file mode 100644 index 0000000..c843434 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Throttle/Throttler.php @@ -0,0 +1,212 @@ +cache = $cache; + } + + //-------------------------------------------------------------------- + + /** + * Returns the number of seconds until the next available token will + * be released for usage. + * + * @return integer + */ + public function getTokenTime(): int + { + return $this->tokenTime; + } + + //-------------------------------------------------------------------- + + /** + * Restricts the number of requests made by a single IP address within + * a set number of seconds. + * + * Example: + * + * if (! $throttler->check($request->ipAddress(), 60, MINUTE)) + * { + * die('You submitted over 60 requests within a minute.'); + * } + * + * @param string $key The name to use as the "bucket" name. + * @param integer $capacity The number of requests the "bucket" can hold + * @param integer $seconds The time it takes the "bucket" to completely refill + * @param integer $cost The number of tokens this action uses. + * + * @return boolean + * @internal param int $maxRequests + */ + public function check(string $key, int $capacity, int $seconds, int $cost = 1): bool + { + $tokenName = $this->prefix . $key; + + // Check to see if the bucket has even been created yet. + if (($tokens = $this->cache->get($tokenName)) === null) + { + // If it hasn't been created, then we'll set it to the maximum + // capacity - 1, and save it to the cache. + $this->cache->save($tokenName, $capacity - $cost, $seconds); + $this->cache->save($tokenName . 'Time', time(), $seconds); + + return true; + } + + // If $tokens > 0, then we need to replenish the bucket + // based on how long it's been since the last update. + $throttleTime = $this->cache->get($tokenName . 'Time'); + $elapsed = $this->time() - $throttleTime; + + // Number of tokens to add back per second + $rate = $capacity / $seconds; + + // How many seconds till a new token is available. + // We must have a minimum wait of 1 second for a new token. + // Primarily stored to allow devs to report back to users. + $newTokenAvailable = (1 / $rate) - $elapsed; + $this->tokenTime = max(1, $newTokenAvailable); + + // Add tokens based up on number per second that + // should be refilled, then checked against capacity + // to be sure the bucket didn't overflow. + $tokens += $rate * $elapsed; + $tokens = $tokens > $capacity ? $capacity : $tokens; + + // If $tokens >= 1, then we are safe to perform the action, but + // we need to decrement the number of available tokens. + if ($tokens >= 1) + { + $this->cache->save($tokenName, $tokens - $cost, $seconds); + $this->cache->save($tokenName . 'Time', time(), $seconds); + + return true; + } + + return false; + } + + //-------------------------------------------------------------------- + + /** + * Used during testing to set the current timestamp to use. + * + * @param integer $time + * + * @return $this + */ + public function setTestTime(int $time) + { + $this->testTime = $time; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Return the test time, defaulting to current. + * + * @return integer + */ + public function time(): int + { + return $this->testTime ?? time(); + } +} diff --git a/vendor/codeigniter4/framework/system/Throttle/ThrottlerInterface.php b/vendor/codeigniter4/framework/system/Throttle/ThrottlerInterface.php new file mode 100644 index 0000000..ef7d787 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Throttle/ThrottlerInterface.php @@ -0,0 +1,76 @@ +checkIPAddress($request->ipAddress(), 60, MINUTE)) + * { + * die('You submitted over 60 requests within a minute.'); + * } + * + * @param string $key The name to use as the "bucket" name. + * @param integer $capacity The number of requests the "bucket" can hold + * @param integer $seconds The time it takes the "bucket" to completely refill + * @param integer $cost The number of tokens this action uses. + * + * @return boolean + */ + public function check(string $key, int $capacity, int $seconds, int $cost); + + //-------------------------------------------------------------------- + + /** + * Returns the number of seconds until the next available token will + * be released for usage. + * + * @return integer + */ + public function getTokenTime(): int; +} diff --git a/vendor/codeigniter4/framework/system/Typography/Typography.php b/vendor/codeigniter4/framework/system/Typography/Typography.php new file mode 100644 index 0000000..4e632d2 --- /dev/null +++ b/vendor/codeigniter4/framework/system/Typography/Typography.php @@ -0,0 +1,408 @@ + tags + * + * @var string + */ + public $blockElements = 'address|blockquote|div|dl|fieldset|form|h\d|hr|noscript|object|ol|p|pre|script|table|ul'; + + /** + * Elements that should not have

and
tags within them. + * + * @var string + */ + public $skipElements = 'p|pre|ol|ul|dl|object|table|h\d'; + + /** + * Tags we want the parser to completely ignore when splitting the string. + * + * @var string + */ + public $inlineElements = 'a|abbr|acronym|b|bdo|big|br|button|cite|code|del|dfn|em|i|img|ins|input|label|map|kbd|q|samp|select|small|span|strong|sub|sup|textarea|tt|var'; + + /** + * array of block level elements that require inner content to be within another block level element + * + * @var array + */ + public $innerBlockRequired = ['blockquote']; + + /** + * the last block element parsed + * + * @var string + */ + public $lastBlockElement = ''; + + /** + * whether or not to protect quotes within { curly braces } + * + * @var boolean + */ + public $protectBracedQuotes = false; + + /** + * Auto Typography + * + * This function converts text, making it typographically correct: + * - Converts double spaces into paragraphs. + * - Converts single line breaks into
tags + * - Converts single and double quotes into correctly facing curly quote entities. + * - Converts three dots into ellipsis. + * - Converts double dashes into em-dashes. + * - Converts two spaces into entities + * + * @param string $str + * @param boolean $reduce_linebreaks whether to reduce more then two consecutive newlines to two + * + * @return string + */ + public function autoTypography(string $str, bool $reduce_linebreaks = false): string + { + if ($str === '') + { + return ''; + } + + // Standardize Newlines to make matching easier + if (strpos($str, "\r") !== false) + { + $str = str_replace(["\r\n", "\r"], "\n", $str); + } + + // Reduce line breaks. If there are more than two consecutive linebreaks + // we'll compress them down to a maximum of two since there's no benefit to more. + if ($reduce_linebreaks === false) + { + $str = preg_replace("/\n\n+/", "\n\n", $str); + } + + // HTML comment tags don't conform to patterns of normal tags, so pull them out separately, only if needed + $html_comments = []; + if (strpos($str, '' . PHP_EOL + . $output . PHP_EOL + . '' . PHP_EOL; + } + } + + // Should we cache? + if (isset($this->renderVars['options']['cache'])) + { + cache()->save($this->renderVars['cacheName'], $output, (int) $this->renderVars['options']['cache']); + } + + $this->tempData = null; + + return $output; + } + + //-------------------------------------------------------------------- + + /** + * Builds the output based upon a string and any + * data that has already been set. + * Cache does not apply, because there is no "key". + * + * @param string $view The view contents + * @param array $options Reserved for 3rd-party uses since + * it might be needed to pass additional info + * to other template engines. + * @param boolean $saveData If true, will save data for use with any other calls, + * if false, will clean the data after displaying the view, + * if not specified, use the config setting. + * + * @return string + */ + public function renderString(string $view, array $options = null, bool $saveData = null): string + { + $start = microtime(true); + + if (is_null($saveData)) + { + $saveData = $this->saveData; + } + + if (is_null($this->tempData)) + { + $this->tempData = $this->data; + } + + extract($this->tempData); + + if ($saveData) + { + $this->data = $this->tempData; + } + + ob_start(); + $incoming = '?>' . $view; + eval($incoming); + $output = ob_get_contents(); + @ob_end_clean(); + + $this->logPerformance($start, microtime(true), $this->excerpt($view)); + + $this->tempData = null; + + return $output; + } + + //-------------------------------------------------------------------- + + /** + * Extract first bit of a long string and add ellipsis + * + * @param string $string + * @param integer $length + * @return string + */ + public function excerpt(string $string, int $length = 20): string + { + return (strlen($string) > $length) ? substr($string, 0, $length - 3) . '...' : $string; + } + + //-------------------------------------------------------------------- + + /** + * Sets several pieces of view data at once. + * + * @param array $data + * @param string $context The context to escape it for: html, css, js, url + * If null, no escaping will happen + * + * @return RendererInterface + */ + public function setData(array $data = [], string $context = null): RendererInterface + { + if (! empty($context)) + { + $data = \esc($data, $context); + } + + $this->tempData = $this->tempData ?? $this->data; + $this->tempData = array_merge($this->tempData, $data); + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Sets a single piece of view data. + * + * @param string $name + * @param mixed $value + * @param string $context The context to escape it for: html, css, js, url + * If null, no escaping will happen + * + * @return RendererInterface + */ + public function setVar(string $name, $value = null, string $context = null): RendererInterface + { + if (! empty($context)) + { + $value = \esc($value, $context); + } + + $this->tempData = $this->tempData ?? $this->data; + $this->tempData[$name] = $value; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Removes all of the view data from the system. + * + * @return RendererInterface + */ + public function resetData(): RendererInterface + { + $this->data = []; + + return $this; + } + + //-------------------------------------------------------------------- + + /** + * Returns the current data that will be displayed in the view. + * + * @return array + */ + public function getData(): array + { + return is_null($this->tempData) ? $this->data : $this->tempData; + } + + //-------------------------------------------------------------------- + + /** + * Specifies that the current view should extend an existing layout. + * + * @param string $layout + * + * @return void + */ + public function extend(string $layout) + { + $this->layout = $layout; + } + + //-------------------------------------------------------------------- + + /** + * Starts holds content for a section within the layout. + * + * @param string $name + */ + public function section(string $name) + { + $this->currentSection = $name; + + ob_start(); + } + + //-------------------------------------------------------------------- + + /** + * + * + * @throws \Laminas\Escaper\Exception\RuntimeException + */ + public function endSection() + { + $contents = ob_get_clean(); + + if (empty($this->currentSection)) + { + throw new \RuntimeException('View themes, no current section.'); + } + + // Ensure an array exists so we can store multiple entries for this. + if (! array_key_exists($this->currentSection, $this->sections)) + { + $this->sections[$this->currentSection] = []; + } + $this->sections[$this->currentSection][] = $contents; + + $this->currentSection = null; + } + + //-------------------------------------------------------------------- + + /** + * Renders a section's contents. + * + * @param string $sectionName + */ + public function renderSection(string $sectionName) + { + if (! isset($this->sections[$sectionName])) + { + echo ''; + + return; + } + + foreach ($this->sections[$sectionName] as $key => $contents) + { + echo $contents; + unset($this->sections[$sectionName][$key]); + } + } + + //-------------------------------------------------------------------- + + /** + * Used within layout views to include additional views. + * + * @param string $view + * @param array|null $options + * @param null $saveData + * + * @return string + */ + public function include(string $view, array $options = null, $saveData = true): string + { + return $this->render($view, $options, $saveData); + } + + //-------------------------------------------------------------------- + + /** + * Returns the performance data that might have been collected + * during the execution. Used primarily in the Debug Toolbar. + * + * @return array + */ + public function getPerformanceData(): array + { + return $this->performanceData; + } + + //-------------------------------------------------------------------- + + /** + * Logs performance data for rendering a view. + * + * @param float $start + * @param float $end + * @param string $view + */ + protected function logPerformance(float $start, float $end, string $view) + { + if (! $this->debug) + { + return; + } + + $this->performanceData[] = [ + 'start' => $start, + 'end' => $end, + 'view' => $view, + ]; + } + + //-------------------------------------------------------------------- +} diff --git a/vendor/codeigniter4/framework/system/bootstrap.php b/vendor/codeigniter4/framework/system/bootstrap.php new file mode 100644 index 0000000..9298baf --- /dev/null +++ b/vendor/codeigniter4/framework/system/bootstrap.php @@ -0,0 +1,183 @@ +appDirectory) . DIRECTORY_SEPARATOR); +} + +/** + * The path to the project root directory. Just above APPPATH. + */ +if (! defined('ROOTPATH')) +{ + define('ROOTPATH', realpath(APPPATH . '../') . DIRECTORY_SEPARATOR); +} + +/** + * The path to the system directory. + */ +if (! defined('SYSTEMPATH')) +{ + define('SYSTEMPATH', realpath($paths->systemDirectory) . DIRECTORY_SEPARATOR); +} + +/** + * The path to the writable directory. + */ +if (! defined('WRITEPATH')) +{ + define('WRITEPATH', realpath($paths->writableDirectory) . DIRECTORY_SEPARATOR); +} + +/** + * The path to the tests directory + */ +if (! defined('TESTPATH')) +{ + define('TESTPATH', realpath($paths->testsDirectory) . DIRECTORY_SEPARATOR); +} + +/* + * --------------------------------------------------------------- + * GRAB OUR CONSTANTS & COMMON + * --------------------------------------------------------------- + */ +if (! defined('APP_NAMESPACE')) +{ + require_once APPPATH . 'Config/Constants.php'; +} + +// Let's see if an app/Common.php file exists +if (file_exists(APPPATH . 'Common.php')) +{ + require_once APPPATH . 'Common.php'; +} + +// Require system/Common.php +require_once SYSTEMPATH . 'Common.php'; + +/* + * --------------------------------------------------------------- + * LOAD OUR AUTOLOADER + * --------------------------------------------------------------- + * + * The autoloader allows all of the pieces to work together + * in the framework. We have to load it here, though, so + * that the config files can use the path constants. + */ + +if (! class_exists(Config\Autoload::class, false)) +{ + require_once SYSTEMPATH . 'Config/AutoloadConfig.php'; + require_once APPPATH . 'Config/Autoload.php'; + require_once SYSTEMPATH . 'Modules/Modules.php'; + require_once APPPATH . 'Config/Modules.php'; +} + +require_once SYSTEMPATH . 'Autoloader/Autoloader.php'; +require_once SYSTEMPATH . 'Config/BaseService.php'; +require_once SYSTEMPATH . 'Config/Services.php'; +require_once APPPATH . 'Config/Services.php'; + +// Use Config\Services as CodeIgniter\Services +if (! class_exists('CodeIgniter\Services', false)) +{ + class_alias('Config\Services', 'CodeIgniter\Services'); +} + +$loader = CodeIgniter\Services::autoloader(); +$loader->initialize(new Config\Autoload(), new Config\Modules()); +$loader->register(); // Register the loader with the SPL autoloader stack. + +// Now load Composer's if it's available +if (is_file(COMPOSER_PATH)) +{ + /** + * The path to the vendor directory. + * + * We do not want to enforce this, so set the constant if Composer was used. + */ + if (! defined('VENDORPATH')) + { + define('VENDORPATH', realpath(ROOTPATH . 'vendor') . DIRECTORY_SEPARATOR); + } + + require_once COMPOSER_PATH; +} + +// Load environment settings from .env files +// into $_SERVER and $_ENV +require_once SYSTEMPATH . 'Config/DotEnv.php'; + +$env = new \CodeIgniter\Config\DotEnv(ROOTPATH); +$env->load(); + +// Always load the URL helper - +// it should be used in 90% of apps. +helper('url'); + +/* + * --------------------------------------------------------------- + * GRAB OUR CODEIGNITER INSTANCE + * --------------------------------------------------------------- + * + * The CodeIgniter class contains the core functionality to make + * the application run, and does all of the dirty work to get + * the pieces all working together. + */ + +$appConfig = config(\Config\App::class); +$app = new \CodeIgniter\CodeIgniter($appConfig); +$app->initialize(); + +return $app; diff --git a/vendor/codeigniter4/framework/system/index.html b/vendor/codeigniter4/framework/system/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/system/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/codeigniter4/framework/writable/.htaccess b/vendor/codeigniter4/framework/writable/.htaccess new file mode 100644 index 0000000..f24db0a --- /dev/null +++ b/vendor/codeigniter4/framework/writable/.htaccess @@ -0,0 +1,6 @@ + + Require all denied + + + Deny from all + diff --git a/vendor/codeigniter4/framework/writable/cache/index.html b/vendor/codeigniter4/framework/writable/cache/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/writable/cache/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/codeigniter4/framework/writable/logs/index.html b/vendor/codeigniter4/framework/writable/logs/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/writable/logs/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/codeigniter4/framework/writable/session/index.html b/vendor/codeigniter4/framework/writable/session/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/writable/session/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/codeigniter4/framework/writable/uploads/index.html b/vendor/codeigniter4/framework/writable/uploads/index.html new file mode 100644 index 0000000..b702fbc --- /dev/null +++ b/vendor/codeigniter4/framework/writable/uploads/index.html @@ -0,0 +1,11 @@ + + + + 403 Forbidden + + + +

Directory access is forbidden.

+ + + diff --git a/vendor/composer/ClassLoader.php b/vendor/composer/ClassLoader.php new file mode 100644 index 0000000..03b9bb9 --- /dev/null +++ b/vendor/composer/ClassLoader.php @@ -0,0 +1,445 @@ + + * 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 http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + 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 array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $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 array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $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] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $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 array|string $paths The PSR-0 base directories + */ + 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 array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + 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 + */ + 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 + */ + 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 + */ + 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 + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * 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; + } + + 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; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE new file mode 100644 index 0000000..f27399a --- /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 0000000..2d7a735 --- /dev/null +++ b/vendor/composer/autoload_classmap.php @@ -0,0 +1,594 @@ + $vendorDir . '/dompdf/dompdf/lib/Cpdf.php', + 'HTML5_Data' => $vendorDir . '/dompdf/dompdf/lib/html5lib/Data.php', + 'HTML5_InputStream' => $vendorDir . '/dompdf/dompdf/lib/html5lib/InputStream.php', + 'HTML5_Parser' => $vendorDir . '/dompdf/dompdf/lib/html5lib/Parser.php', + 'HTML5_Tokenizer' => $vendorDir . '/dompdf/dompdf/lib/html5lib/Tokenizer.php', + 'HTML5_TreeBuilder' => $vendorDir . '/dompdf/dompdf/lib/html5lib/TreeBuilder.php', + 'PHPUnit\\Exception' => $vendorDir . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => $vendorDir . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php', + 'PHPUnit\\Framework\\CodeCoverageException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => $vendorDir . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => $vendorDir . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidArgumentException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\InvalidDataProviderException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php', + 'PHPUnit\\Framework\\InvalidParameterGroupException' => $vendorDir . '/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\Api' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Api/Api.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php', + 'PHPUnit\\Framework\\MockObject\\ConfigurableMethodsAlreadyInitializedException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Generator.php', + 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Method' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Api/Method.php', + 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockClass' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockClass.php', + 'PHPUnit\\Framework\\MockObject\\MockMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php', + 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\MockTrait' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockTrait.php', + 'PHPUnit\\Framework\\MockObject\\MockType' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/MockType.php', + 'PHPUnit\\Framework\\MockObject\\MockedCloneMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ConsecutiveParameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtIndex' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php', + 'PHPUnit\\Framework\\MockObject\\UnmockedCloneMethod' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => $vendorDir . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php', + 'PHPUnit\\Framework\\NoChildTestSuiteException' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php', + 'PHPUnit\\Framework\\OutputError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/OutputError.php', + 'PHPUnit\\Framework\\PHPTAssertionFailedError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php', + 'PHPUnit\\Framework\\RiskyTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => $vendorDir . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/SyntheticError.php', + 'PHPUnit\\Framework\\SyntheticSkippedError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php', + 'PHPUnit\\Framework\\Test' => $vendorDir . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestBuilder' => $vendorDir . '/phpunit/phpunit/src/Framework/TestBuilder.php', + 'PHPUnit\\Framework\\TestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => $vendorDir . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => $vendorDir . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => $vendorDir . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => $vendorDir . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => $vendorDir . '/phpunit/phpunit/src/Framework/Exception/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => $vendorDir . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\AfterIncompleteTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php', + 'PHPUnit\\Runner\\AfterLastTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php', + 'PHPUnit\\Runner\\AfterRiskyTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php', + 'PHPUnit\\Runner\\AfterSkippedTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php', + 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php', + 'PHPUnit\\Runner\\AfterTestErrorHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php', + 'PHPUnit\\Runner\\AfterTestFailureHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php', + 'PHPUnit\\Runner\\AfterTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php', + 'PHPUnit\\Runner\\AfterTestWarningHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php', + 'PHPUnit\\Runner\\BaseTestRunner' => $vendorDir . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\BeforeFirstTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php', + 'PHPUnit\\Runner\\BeforeTestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php', + 'PHPUnit\\Runner\\DefaultTestResultCache' => $vendorDir . '/phpunit/phpunit/src/Runner/DefaultTestResultCache.php', + 'PHPUnit\\Runner\\Exception' => $vendorDir . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => $vendorDir . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\Hook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/Hook.php', + 'PHPUnit\\Runner\\NullTestResultCache' => $vendorDir . '/phpunit/phpunit/src/Runner/NullTestResultCache.php', + 'PHPUnit\\Runner\\PhptTestCase' => $vendorDir . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\ResultCacheExtension' => $vendorDir . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestHook' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestHook.php', + 'PHPUnit\\Runner\\TestListenerAdapter' => $vendorDir . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php', + 'PHPUnit\\Runner\\TestResultCache' => $vendorDir . '/phpunit/phpunit/src/Runner/TestResultCache.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteSorter' => $vendorDir . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php', + 'PHPUnit\\Runner\\Version' => $vendorDir . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => $vendorDir . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\Exception' => $vendorDir . '/phpunit/phpunit/src/TextUI/Exception.php', + 'PHPUnit\\TextUI\\Help' => $vendorDir . '/phpunit/phpunit/src/TextUI/Help.php', + 'PHPUnit\\TextUI\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => $vendorDir . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Annotation\\DocBlock' => $vendorDir . '/phpunit/phpunit/src/Util/Annotation/DocBlock.php', + 'PHPUnit\\Util\\Annotation\\Registry' => $vendorDir . '/phpunit/phpunit/src/Util/Annotation/Registry.php', + 'PHPUnit\\Util\\Blacklist' => $vendorDir . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Color' => $vendorDir . '/phpunit/phpunit/src/Util/Color.php', + 'PHPUnit\\Util\\Configuration' => $vendorDir . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => $vendorDir . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Exception' => $vendorDir . '/phpunit/phpunit/src/Util/Exception.php', + 'PHPUnit\\Util\\FileLoader' => $vendorDir . '/phpunit/phpunit/src/Util/FileLoader.php', + 'PHPUnit\\Util\\Filesystem' => $vendorDir . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => $vendorDir . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => $vendorDir . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => $vendorDir . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidDataSetException' => $vendorDir . '/phpunit/phpunit/src/Util/InvalidDataSetException.php', + 'PHPUnit\\Util\\Json' => $vendorDir . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => $vendorDir . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => $vendorDir . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => $vendorDir . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => $vendorDir . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => $vendorDir . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => $vendorDir . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TestDoxPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TestDoxPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => $vendorDir . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => $vendorDir . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\VersionComparisonOperator' => $vendorDir . '/phpunit/phpunit/src/Util/VersionComparisonOperator.php', + 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => $vendorDir . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php', + 'PHPUnit\\Util\\Xml' => $vendorDir . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => $vendorDir . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHP_Token' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => $vendorDir . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Util' => $vendorDir . '/phpunit/php-token-stream/src/Token/Util.php', + 'PHP_Token_VAR' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => $vendorDir . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => $vendorDir . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => $vendorDir . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => $vendorDir . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => $vendorDir . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => $vendorDir . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => $vendorDir . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => $vendorDir . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => $vendorDir . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => $vendorDir . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => $vendorDir . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => $vendorDir . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => $vendorDir . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => $vendorDir . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => $vendorDir . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => $vendorDir . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => $vendorDir . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => $vendorDir . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => $vendorDir . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => $vendorDir . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => $vendorDir . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => $vendorDir . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => $vendorDir . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => $vendorDir . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => $vendorDir . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => $vendorDir . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => $vendorDir . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => $vendorDir . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => $vendorDir . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => $vendorDir . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => $vendorDir . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => $vendorDir . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => $vendorDir . '/phar-io/version/src/exceptions/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidPreReleaseSuffixException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', + 'PharIo\\Version\\InvalidVersionException' => $vendorDir . '/phar-io/version/src/exceptions/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => $vendorDir . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => $vendorDir . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => $vendorDir . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => $vendorDir . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => $vendorDir . '/phar-io/version/src/constraints/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => $vendorDir . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => $vendorDir . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => $vendorDir . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => $vendorDir . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PCOV' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PCOV.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => $vendorDir . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => $vendorDir . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => $vendorDir . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => $vendorDir . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => $vendorDir . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => $vendorDir . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => $vendorDir . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => $vendorDir . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => $vendorDir . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => $vendorDir . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => $vendorDir . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => $vendorDir . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => $vendorDir . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => $vendorDir . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => $vendorDir . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => $vendorDir . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => $vendorDir . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => $vendorDir . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => $vendorDir . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => $vendorDir . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => $vendorDir . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => $vendorDir . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => $vendorDir . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => $vendorDir . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => $vendorDir . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => $vendorDir . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\ConfigurationException' => $vendorDir . '/sebastian/diff/src/Exception/ConfigurationException.php', + 'SebastianBergmann\\Diff\\Diff' => $vendorDir . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => $vendorDir . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => $vendorDir . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => $vendorDir . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => $vendorDir . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => $vendorDir . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => $vendorDir . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => $vendorDir . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => $vendorDir . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => $vendorDir . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => $vendorDir . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => $vendorDir . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => $vendorDir . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\FileIterator\\Facade' => $vendorDir . '/phpunit/php-file-iterator/src/Facade.php', + 'SebastianBergmann\\FileIterator\\Factory' => $vendorDir . '/phpunit/php-file-iterator/src/Factory.php', + 'SebastianBergmann\\FileIterator\\Iterator' => $vendorDir . '/phpunit/php-file-iterator/src/Iterator.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => $vendorDir . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => $vendorDir . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => $vendorDir . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => $vendorDir . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => $vendorDir . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => $vendorDir . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => $vendorDir . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => $vendorDir . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => $vendorDir . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => $vendorDir . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => $vendorDir . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => $vendorDir . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => $vendorDir . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => $vendorDir . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => $vendorDir . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => $vendorDir . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Timer\\Exception' => $vendorDir . '/phpunit/php-timer/src/Exception.php', + 'SebastianBergmann\\Timer\\RuntimeException' => $vendorDir . '/phpunit/php-timer/src/RuntimeException.php', + 'SebastianBergmann\\Timer\\Timer' => $vendorDir . '/phpunit/php-timer/src/Timer.php', + 'SebastianBergmann\\Type\\CallableType' => $vendorDir . '/sebastian/type/src/CallableType.php', + 'SebastianBergmann\\Type\\Exception' => $vendorDir . '/sebastian/type/src/exception/Exception.php', + 'SebastianBergmann\\Type\\GenericObjectType' => $vendorDir . '/sebastian/type/src/GenericObjectType.php', + 'SebastianBergmann\\Type\\IterableType' => $vendorDir . '/sebastian/type/src/IterableType.php', + 'SebastianBergmann\\Type\\NullType' => $vendorDir . '/sebastian/type/src/NullType.php', + 'SebastianBergmann\\Type\\ObjectType' => $vendorDir . '/sebastian/type/src/ObjectType.php', + 'SebastianBergmann\\Type\\RuntimeException' => $vendorDir . '/sebastian/type/src/exception/RuntimeException.php', + 'SebastianBergmann\\Type\\SimpleType' => $vendorDir . '/sebastian/type/src/SimpleType.php', + 'SebastianBergmann\\Type\\Type' => $vendorDir . '/sebastian/type/src/Type.php', + 'SebastianBergmann\\Type\\TypeName' => $vendorDir . '/sebastian/type/src/TypeName.php', + 'SebastianBergmann\\Type\\UnknownType' => $vendorDir . '/sebastian/type/src/UnknownType.php', + 'SebastianBergmann\\Type\\VoidType' => $vendorDir . '/sebastian/type/src/VoidType.php', + 'SebastianBergmann\\Version' => $vendorDir . '/sebastian/version/src/Version.php', + 'Text_Template' => $vendorDir . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => $vendorDir . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => $vendorDir . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => $vendorDir . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => $vendorDir . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => $vendorDir . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => $vendorDir . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => $vendorDir . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => $vendorDir . '/theseer/tokenizer/src/XMLSerializer.php', +); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php new file mode 100644 index 0000000..6133a06 --- /dev/null +++ b/vendor/composer/autoload_files.php @@ -0,0 +1,13 @@ + $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '7e9bd612cc444b3eed788ebbe46263a0' => $vendorDir . '/laminas/laminas-zendframework-bridge/src/autoload.php', + '3917c79c5052b270641b5a200963dbc2' => $vendorDir . '/kint-php/kint/init.php', + '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', +); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..484189f --- /dev/null +++ b/vendor/composer/autoload_namespaces.php @@ -0,0 +1,11 @@ + array($vendorDir . '/mikey179/vfsstream/src/main/php'), + 'Sabberworm\\CSS' => array($vendorDir . '/sabberworm/php-css-parser/lib'), +); diff --git a/vendor/composer/autoload_psr4.php b/vendor/composer/autoload_psr4.php new file mode 100644 index 0000000..6361ae4 --- /dev/null +++ b/vendor/composer/autoload_psr4.php @@ -0,0 +1,25 @@ + array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'), + 'Webmozart\\Assert\\' => array($vendorDir . '/webmozart/assert/src'), + 'Tests\\Support\\' => array($baseDir . '/tests/_support'), + 'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'), + 'Svg\\' => array($vendorDir . '/phenx/php-svg-lib/src/Svg'), + 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), + 'Prophecy\\' => array($vendorDir . '/phpspec/prophecy/src/Prophecy'), + 'Laminas\\ZendFrameworkBridge\\' => array($vendorDir . '/laminas/laminas-zendframework-bridge/src'), + 'Laminas\\Escaper\\' => array($vendorDir . '/laminas/laminas-escaper/src'), + 'Kint\\' => array($vendorDir . '/kint-php/kint/src'), + 'FontLib\\' => array($vendorDir . '/phenx/php-font-lib/src/FontLib'), + 'Faker\\' => array($vendorDir . '/fzaninotto/faker/src/Faker'), + 'Dompdf\\' => array($vendorDir . '/dompdf/dompdf/src'), + 'Doctrine\\Instantiator\\' => array($vendorDir . '/doctrine/instantiator/src/Doctrine/Instantiator'), + 'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'), + 'CodeIgniter\\' => array($vendorDir . '/codeigniter4/framework/system'), +); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php new file mode 100644 index 0000000..66b9c17 --- /dev/null +++ b/vendor/composer/autoload_real.php @@ -0,0 +1,73 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequirebbfefea263758c542cf1b7e1de76aa47($fileIdentifier, $file); + } + + return $loader; + } +} + +function composerRequirebbfefea263758c542cf1b7e1de76aa47($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php new file mode 100644 index 0000000..de9cca8 --- /dev/null +++ b/vendor/composer/autoload_static.php @@ -0,0 +1,749 @@ + __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '7e9bd612cc444b3eed788ebbe46263a0' => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src/autoload.php', + '3917c79c5052b270641b5a200963dbc2' => __DIR__ . '/..' . '/kint-php/kint/init.php', + '6124b4c8570aa390c21fafd04a26c69f' => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', + ); + + public static $prefixLengthsPsr4 = array ( + 'p' => + array ( + 'phpDocumentor\\Reflection\\' => 25, + ), + 'W' => + array ( + 'Webmozart\\Assert\\' => 17, + ), + 'T' => + array ( + 'Tests\\Support\\' => 14, + ), + 'S' => + array ( + 'Symfony\\Polyfill\\Ctype\\' => 23, + 'Svg\\' => 4, + ), + 'P' => + array ( + 'Psr\\Log\\' => 8, + 'Prophecy\\' => 9, + ), + 'L' => + array ( + 'Laminas\\ZendFrameworkBridge\\' => 28, + 'Laminas\\Escaper\\' => 16, + ), + 'K' => + array ( + 'Kint\\' => 5, + ), + 'F' => + array ( + 'FontLib\\' => 8, + 'Faker\\' => 6, + ), + 'D' => + array ( + 'Dompdf\\' => 7, + 'Doctrine\\Instantiator\\' => 22, + 'DeepCopy\\' => 9, + ), + 'C' => + array ( + 'CodeIgniter\\' => 12, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'phpDocumentor\\Reflection\\' => + array ( + 0 => __DIR__ . '/..' . '/phpdocumentor/reflection-common/src', + 1 => __DIR__ . '/..' . '/phpdocumentor/reflection-docblock/src', + 2 => __DIR__ . '/..' . '/phpdocumentor/type-resolver/src', + ), + 'Webmozart\\Assert\\' => + array ( + 0 => __DIR__ . '/..' . '/webmozart/assert/src', + ), + 'Tests\\Support\\' => + array ( + 0 => __DIR__ . '/../..' . '/tests/_support', + ), + 'Symfony\\Polyfill\\Ctype\\' => + array ( + 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', + ), + 'Svg\\' => + array ( + 0 => __DIR__ . '/..' . '/phenx/php-svg-lib/src/Svg', + ), + 'Psr\\Log\\' => + array ( + 0 => __DIR__ . '/..' . '/psr/log/Psr/Log', + ), + 'Prophecy\\' => + array ( + 0 => __DIR__ . '/..' . '/phpspec/prophecy/src/Prophecy', + ), + 'Laminas\\ZendFrameworkBridge\\' => + array ( + 0 => __DIR__ . '/..' . '/laminas/laminas-zendframework-bridge/src', + ), + 'Laminas\\Escaper\\' => + array ( + 0 => __DIR__ . '/..' . '/laminas/laminas-escaper/src', + ), + 'Kint\\' => + array ( + 0 => __DIR__ . '/..' . '/kint-php/kint/src', + ), + 'FontLib\\' => + array ( + 0 => __DIR__ . '/..' . '/phenx/php-font-lib/src/FontLib', + ), + 'Faker\\' => + array ( + 0 => __DIR__ . '/..' . '/fzaninotto/faker/src/Faker', + ), + 'Dompdf\\' => + array ( + 0 => __DIR__ . '/..' . '/dompdf/dompdf/src', + ), + 'Doctrine\\Instantiator\\' => + array ( + 0 => __DIR__ . '/..' . '/doctrine/instantiator/src/Doctrine/Instantiator', + ), + 'DeepCopy\\' => + array ( + 0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy', + ), + 'CodeIgniter\\' => + array ( + 0 => __DIR__ . '/..' . '/codeigniter4/framework/system', + ), + ); + + public static $prefixesPsr0 = array ( + 'o' => + array ( + 'org\\bovigo\\vfs\\' => + array ( + 0 => __DIR__ . '/..' . '/mikey179/vfsstream/src/main/php', + ), + ), + 'S' => + array ( + 'Sabberworm\\CSS' => + array ( + 0 => __DIR__ . '/..' . '/sabberworm/php-css-parser/lib', + ), + ), + ); + + public static $classMap = array ( + 'Dompdf\\Cpdf' => __DIR__ . '/..' . '/dompdf/dompdf/lib/Cpdf.php', + 'HTML5_Data' => __DIR__ . '/..' . '/dompdf/dompdf/lib/html5lib/Data.php', + 'HTML5_InputStream' => __DIR__ . '/..' . '/dompdf/dompdf/lib/html5lib/InputStream.php', + 'HTML5_Parser' => __DIR__ . '/..' . '/dompdf/dompdf/lib/html5lib/Parser.php', + 'HTML5_Tokenizer' => __DIR__ . '/..' . '/dompdf/dompdf/lib/html5lib/Tokenizer.php', + 'HTML5_TreeBuilder' => __DIR__ . '/..' . '/dompdf/dompdf/lib/html5lib/TreeBuilder.php', + 'PHPUnit\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Exception.php', + 'PHPUnit\\Framework\\Assert' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Assert.php', + 'PHPUnit\\Framework\\AssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php', + 'PHPUnit\\Framework\\CodeCoverageException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php', + 'PHPUnit\\Framework\\Constraint\\ArrayHasKey' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php', + 'PHPUnit\\Framework\\Constraint\\ArraySubset' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php', + 'PHPUnit\\Framework\\Constraint\\Attribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Attribute.php', + 'PHPUnit\\Framework\\Constraint\\Callback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Callback.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\ClassHasStaticAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php', + 'PHPUnit\\Framework\\Constraint\\Composite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Composite.php', + 'PHPUnit\\Framework\\Constraint\\Constraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Constraint.php', + 'PHPUnit\\Framework\\Constraint\\Count' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Count.php', + 'PHPUnit\\Framework\\Constraint\\DirectoryExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php', + 'PHPUnit\\Framework\\Constraint\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/Exception.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionCode' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessage' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php', + 'PHPUnit\\Framework\\Constraint\\ExceptionMessageRegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\FileExists' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/FileExists.php', + 'PHPUnit\\Framework\\Constraint\\GreaterThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php', + 'PHPUnit\\Framework\\Constraint\\IsAnything' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsAnything.php', + 'PHPUnit\\Framework\\Constraint\\IsEmpty' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php', + 'PHPUnit\\Framework\\Constraint\\IsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsEqual.php', + 'PHPUnit\\Framework\\Constraint\\IsFalse' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFalse.php', + 'PHPUnit\\Framework\\Constraint\\IsFinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsFinite.php', + 'PHPUnit\\Framework\\Constraint\\IsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\IsInfinite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php', + 'PHPUnit\\Framework\\Constraint\\IsInstanceOf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php', + 'PHPUnit\\Framework\\Constraint\\IsJson' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsJson.php', + 'PHPUnit\\Framework\\Constraint\\IsNan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNan.php', + 'PHPUnit\\Framework\\Constraint\\IsNull' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsNull.php', + 'PHPUnit\\Framework\\Constraint\\IsReadable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsReadable.php', + 'PHPUnit\\Framework\\Constraint\\IsTrue' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsTrue.php', + 'PHPUnit\\Framework\\Constraint\\IsType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsType.php', + 'PHPUnit\\Framework\\Constraint\\IsWritable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/IsWritable.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatches' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php', + 'PHPUnit\\Framework\\Constraint\\JsonMatchesErrorMessageProvider' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php', + 'PHPUnit\\Framework\\Constraint\\LessThan' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LessThan.php', + 'PHPUnit\\Framework\\Constraint\\LogicalAnd' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php', + 'PHPUnit\\Framework\\Constraint\\LogicalNot' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php', + 'PHPUnit\\Framework\\Constraint\\LogicalOr' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php', + 'PHPUnit\\Framework\\Constraint\\LogicalXor' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php', + 'PHPUnit\\Framework\\Constraint\\ObjectHasAttribute' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php', + 'PHPUnit\\Framework\\Constraint\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php', + 'PHPUnit\\Framework\\Constraint\\SameSize' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/SameSize.php', + 'PHPUnit\\Framework\\Constraint\\StringContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringContains.php', + 'PHPUnit\\Framework\\Constraint\\StringEndsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php', + 'PHPUnit\\Framework\\Constraint\\StringMatchesFormatDescription' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php', + 'PHPUnit\\Framework\\Constraint\\StringStartsWith' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContains' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsEqual' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsIdentical' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php', + 'PHPUnit\\Framework\\Constraint\\TraversableContainsOnly' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php', + 'PHPUnit\\Framework\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php', + 'PHPUnit\\Framework\\DataProviderTestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/DataProviderTestSuite.php', + 'PHPUnit\\Framework\\Error\\Deprecated' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Deprecated.php', + 'PHPUnit\\Framework\\Error\\Error' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Error.php', + 'PHPUnit\\Framework\\Error\\Notice' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Notice.php', + 'PHPUnit\\Framework\\Error\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Error/Warning.php', + 'PHPUnit\\Framework\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/Exception.php', + 'PHPUnit\\Framework\\ExceptionWrapper' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/ExceptionWrapper.php', + 'PHPUnit\\Framework\\ExpectationFailedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php', + 'PHPUnit\\Framework\\IncompleteTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTest.php', + 'PHPUnit\\Framework\\IncompleteTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/IncompleteTestCase.php', + 'PHPUnit\\Framework\\IncompleteTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php', + 'PHPUnit\\Framework\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php', + 'PHPUnit\\Framework\\InvalidCoversTargetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php', + 'PHPUnit\\Framework\\InvalidDataProviderException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php', + 'PHPUnit\\Framework\\InvalidParameterGroupException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php', + 'PHPUnit\\Framework\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php', + 'PHPUnit\\Framework\\MockObject\\Api' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Api/Api.php', + 'PHPUnit\\Framework\\MockObject\\BadMethodCallException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Identity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationMocker' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\InvocationStubber' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Match' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\MethodNameMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\ParametersMatch' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php', + 'PHPUnit\\Framework\\MockObject\\Builder\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php', + 'PHPUnit\\Framework\\MockObject\\ConfigurableMethod' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php', + 'PHPUnit\\Framework\\MockObject\\ConfigurableMethodsAlreadyInitializedException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php', + 'PHPUnit\\Framework\\MockObject\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Generator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Generator.php', + 'PHPUnit\\Framework\\MockObject\\IncompatibleReturnValueException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php', + 'PHPUnit\\Framework\\MockObject\\Invocation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Invocation.php', + 'PHPUnit\\Framework\\MockObject\\InvocationHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php', + 'PHPUnit\\Framework\\MockObject\\Matcher' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Matcher.php', + 'PHPUnit\\Framework\\MockObject\\Method' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Api/Method.php', + 'PHPUnit\\Framework\\MockObject\\MethodNameConstraint' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php', + 'PHPUnit\\Framework\\MockObject\\MockBuilder' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php', + 'PHPUnit\\Framework\\MockObject\\MockClass' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockClass.php', + 'PHPUnit\\Framework\\MockObject\\MockMethod' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockMethod.php', + 'PHPUnit\\Framework\\MockObject\\MockMethodSet' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php', + 'PHPUnit\\Framework\\MockObject\\MockObject' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockObject.php', + 'PHPUnit\\Framework\\MockObject\\MockTrait' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockTrait.php', + 'PHPUnit\\Framework\\MockObject\\MockType' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/MockType.php', + 'PHPUnit\\Framework\\MockObject\\MockedCloneMethod' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyInvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\AnyParameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ConsecutiveParameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvocationOrder' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtIndex' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtLeastOnce' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedAtMostCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\InvokedCount' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\MethodName' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\Parameters' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php', + 'PHPUnit\\Framework\\MockObject\\Rule\\ParametersRule' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php', + 'PHPUnit\\Framework\\MockObject\\RuntimeException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php', + 'PHPUnit\\Framework\\MockObject\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ConsecutiveCalls' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnArgument' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnCallback' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnReference' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnSelf' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnStub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\ReturnValueMap' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php', + 'PHPUnit\\Framework\\MockObject\\Stub\\Stub' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php', + 'PHPUnit\\Framework\\MockObject\\UnmockedCloneMethod' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php', + 'PHPUnit\\Framework\\MockObject\\Verifiable' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/MockObject/Verifiable.php', + 'PHPUnit\\Framework\\NoChildTestSuiteException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php', + 'PHPUnit\\Framework\\OutputError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/OutputError.php', + 'PHPUnit\\Framework\\PHPTAssertionFailedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php', + 'PHPUnit\\Framework\\RiskyTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php', + 'PHPUnit\\Framework\\SelfDescribing' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SelfDescribing.php', + 'PHPUnit\\Framework\\SkippedTest' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTest.php', + 'PHPUnit\\Framework\\SkippedTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/SkippedTestCase.php', + 'PHPUnit\\Framework\\SkippedTestError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php', + 'PHPUnit\\Framework\\SkippedTestSuiteError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php', + 'PHPUnit\\Framework\\SyntheticError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/SyntheticError.php', + 'PHPUnit\\Framework\\SyntheticSkippedError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php', + 'PHPUnit\\Framework\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Test.php', + 'PHPUnit\\Framework\\TestBuilder' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestBuilder.php', + 'PHPUnit\\Framework\\TestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestCase.php', + 'PHPUnit\\Framework\\TestFailure' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestFailure.php', + 'PHPUnit\\Framework\\TestListener' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListener.php', + 'PHPUnit\\Framework\\TestListenerDefaultImplementation' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php', + 'PHPUnit\\Framework\\TestResult' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestResult.php', + 'PHPUnit\\Framework\\TestSuite' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuite.php', + 'PHPUnit\\Framework\\TestSuiteIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/TestSuiteIterator.php', + 'PHPUnit\\Framework\\UnintentionallyCoveredCodeError' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php', + 'PHPUnit\\Framework\\Warning' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/Exception/Warning.php', + 'PHPUnit\\Framework\\WarningTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Framework/WarningTestCase.php', + 'PHPUnit\\Runner\\AfterIncompleteTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php', + 'PHPUnit\\Runner\\AfterLastTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php', + 'PHPUnit\\Runner\\AfterRiskyTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php', + 'PHPUnit\\Runner\\AfterSkippedTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php', + 'PHPUnit\\Runner\\AfterSuccessfulTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php', + 'PHPUnit\\Runner\\AfterTestErrorHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php', + 'PHPUnit\\Runner\\AfterTestFailureHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php', + 'PHPUnit\\Runner\\AfterTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php', + 'PHPUnit\\Runner\\AfterTestWarningHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php', + 'PHPUnit\\Runner\\BaseTestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/BaseTestRunner.php', + 'PHPUnit\\Runner\\BeforeFirstTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php', + 'PHPUnit\\Runner\\BeforeTestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php', + 'PHPUnit\\Runner\\DefaultTestResultCache' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/DefaultTestResultCache.php', + 'PHPUnit\\Runner\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Exception.php', + 'PHPUnit\\Runner\\Filter\\ExcludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\Factory' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/Factory.php', + 'PHPUnit\\Runner\\Filter\\GroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\IncludeGroupFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php', + 'PHPUnit\\Runner\\Filter\\NameFilterIterator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php', + 'PHPUnit\\Runner\\Hook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/Hook.php', + 'PHPUnit\\Runner\\NullTestResultCache' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/NullTestResultCache.php', + 'PHPUnit\\Runner\\PhptTestCase' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/PhptTestCase.php', + 'PHPUnit\\Runner\\ResultCacheExtension' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/ResultCacheExtension.php', + 'PHPUnit\\Runner\\StandardTestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php', + 'PHPUnit\\Runner\\TestHook' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/TestHook.php', + 'PHPUnit\\Runner\\TestListenerAdapter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php', + 'PHPUnit\\Runner\\TestResultCache' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestResultCache.php', + 'PHPUnit\\Runner\\TestSuiteLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteLoader.php', + 'PHPUnit\\Runner\\TestSuiteSorter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/TestSuiteSorter.php', + 'PHPUnit\\Runner\\Version' => __DIR__ . '/..' . '/phpunit/phpunit/src/Runner/Version.php', + 'PHPUnit\\TextUI\\Command' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Command.php', + 'PHPUnit\\TextUI\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Exception.php', + 'PHPUnit\\TextUI\\Help' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/Help.php', + 'PHPUnit\\TextUI\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/ResultPrinter.php', + 'PHPUnit\\TextUI\\TestRunner' => __DIR__ . '/..' . '/phpunit/phpunit/src/TextUI/TestRunner.php', + 'PHPUnit\\Util\\Annotation\\DocBlock' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Annotation/DocBlock.php', + 'PHPUnit\\Util\\Annotation\\Registry' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Annotation/Registry.php', + 'PHPUnit\\Util\\Blacklist' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Blacklist.php', + 'PHPUnit\\Util\\Color' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Color.php', + 'PHPUnit\\Util\\Configuration' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Configuration.php', + 'PHPUnit\\Util\\ConfigurationGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ConfigurationGenerator.php', + 'PHPUnit\\Util\\ErrorHandler' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/ErrorHandler.php', + 'PHPUnit\\Util\\Exception' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Exception.php', + 'PHPUnit\\Util\\FileLoader' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/FileLoader.php', + 'PHPUnit\\Util\\Filesystem' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filesystem.php', + 'PHPUnit\\Util\\Filter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Filter.php', + 'PHPUnit\\Util\\Getopt' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Getopt.php', + 'PHPUnit\\Util\\GlobalState' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/GlobalState.php', + 'PHPUnit\\Util\\InvalidDataSetException' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/InvalidDataSetException.php', + 'PHPUnit\\Util\\Json' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Json.php', + 'PHPUnit\\Util\\Log\\JUnit' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/JUnit.php', + 'PHPUnit\\Util\\Log\\TeamCity' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Log/TeamCity.php', + 'PHPUnit\\Util\\PHP\\AbstractPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php', + 'PHPUnit\\Util\\PHP\\DefaultPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php', + 'PHPUnit\\Util\\PHP\\WindowsPhpProcess' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php', + 'PHPUnit\\Util\\Printer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Printer.php', + 'PHPUnit\\Util\\RegularExpression' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/RegularExpression.php', + 'PHPUnit\\Util\\Test' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Test.php', + 'PHPUnit\\Util\\TestDox\\CliTestDoxPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php', + 'PHPUnit\\Util\\TestDox\\HtmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\NamePrettifier' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/NamePrettifier.php', + 'PHPUnit\\Util\\TestDox\\ResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/ResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\TestDoxPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TestDoxPrinter.php', + 'PHPUnit\\Util\\TestDox\\TextResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/TextResultPrinter.php', + 'PHPUnit\\Util\\TestDox\\XmlResultPrinter' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TestDox/XmlResultPrinter.php', + 'PHPUnit\\Util\\TextTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/TextTestListRenderer.php', + 'PHPUnit\\Util\\Type' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Type.php', + 'PHPUnit\\Util\\VersionComparisonOperator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/VersionComparisonOperator.php', + 'PHPUnit\\Util\\XdebugFilterScriptGenerator' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XdebugFilterScriptGenerator.php', + 'PHPUnit\\Util\\Xml' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/Xml.php', + 'PHPUnit\\Util\\XmlTestListRenderer' => __DIR__ . '/..' . '/phpunit/phpunit/src/Util/XmlTestListRenderer.php', + 'PHP_Token' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScope' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_TokenWithScopeAndVisibility' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ABSTRACT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AMPERSAND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AND_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ARRAY_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_AT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BACKTICK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BAD_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOLEAN_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BOOL_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_BREAK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CALLABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CARET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CASE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CATCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CHARACTER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLASS_NAME_CONSTANT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLONE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CLOSE_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COALESCE_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMA' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONCAT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONSTANT_ENCAPSED_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CONTINUE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_CURLY_OPEN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DEFAULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DIV_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOC_COMMENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOLLAR_OPEN_CURLY_BRACES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_ARROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_COLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_DOUBLE_QUOTES' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELLIPSIS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ELSEIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EMPTY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENCAPSED_AND_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDDECLARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDFOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDIF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDSWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ENDWHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_END_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EVAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXCLAMATION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_EXTENDS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FINALLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FOREACH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_FUNC_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GLOBAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GOTO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_GT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_HALT_COMPILER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IMPLEMENTS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INCLUDE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INLINE_HTML' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTANCEOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INSTEADOF' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INTERFACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_INT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_ISSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_GREATER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_NOT_IDENTICAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_IS_SMALLER_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Includes' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LINE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LIST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LNUMBER' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_AND' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_OR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LOGICAL_XOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_LT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_METHOD_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MINUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MOD_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MULT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_MUL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NAMESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NEW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NS_SEPARATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_NUM_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OBJECT_OPERATOR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_BRACKET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_CURLY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_SQUARE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OPEN_TAG_WITH_ECHO' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_OR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PAAMAYIM_NEKUDOTAYIM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PERCENT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PIPE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PLUS_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_POW_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRINT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PRIVATE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PROTECTED' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_PUBLIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_QUESTION_MARK' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_REQUIRE_ONCE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_RETURN' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SEMICOLON' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SL_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SPACESHIP' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_START_HEREDOC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STATIC' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_STRING_VARNAME' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_SWITCH' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Stream' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream.php', + 'PHP_Token_Stream_CachingFactory' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php', + 'PHP_Token_THROW' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TILDE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRAIT_C' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_TRY' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_UNSET_CAST' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_USE_FUNCTION' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_Util' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token/Util.php', + 'PHP_Token_VAR' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_VARIABLE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHILE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_WHITESPACE' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_XOR_EQUAL' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PHP_Token_YIELD_FROM' => __DIR__ . '/..' . '/phpunit/php-token-stream/src/Token.php', + 'PharIo\\Manifest\\Application' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Application.php', + 'PharIo\\Manifest\\ApplicationName' => __DIR__ . '/..' . '/phar-io/manifest/src/values/ApplicationName.php', + 'PharIo\\Manifest\\Author' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Author.php', + 'PharIo\\Manifest\\AuthorCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollection.php', + 'PharIo\\Manifest\\AuthorCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/AuthorCollectionIterator.php', + 'PharIo\\Manifest\\AuthorElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElement.php', + 'PharIo\\Manifest\\AuthorElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/AuthorElementCollection.php', + 'PharIo\\Manifest\\BundledComponent' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponent.php', + 'PharIo\\Manifest\\BundledComponentCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollection.php', + 'PharIo\\Manifest\\BundledComponentCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/BundledComponentCollectionIterator.php', + 'PharIo\\Manifest\\BundlesElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/BundlesElement.php', + 'PharIo\\Manifest\\ComponentElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElement.php', + 'PharIo\\Manifest\\ComponentElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ComponentElementCollection.php', + 'PharIo\\Manifest\\ContainsElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ContainsElement.php', + 'PharIo\\Manifest\\CopyrightElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/CopyrightElement.php', + 'PharIo\\Manifest\\CopyrightInformation' => __DIR__ . '/..' . '/phar-io/manifest/src/values/CopyrightInformation.php', + 'PharIo\\Manifest\\ElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ElementCollection.php', + 'PharIo\\Manifest\\Email' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Email.php', + 'PharIo\\Manifest\\Exception' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/Exception.php', + 'PharIo\\Manifest\\ExtElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElement.php', + 'PharIo\\Manifest\\ExtElementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtElementCollection.php', + 'PharIo\\Manifest\\Extension' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Extension.php', + 'PharIo\\Manifest\\ExtensionElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ExtensionElement.php', + 'PharIo\\Manifest\\InvalidApplicationNameException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php', + 'PharIo\\Manifest\\InvalidEmailException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidEmailException.php', + 'PharIo\\Manifest\\InvalidUrlException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/InvalidUrlException.php', + 'PharIo\\Manifest\\Library' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Library.php', + 'PharIo\\Manifest\\License' => __DIR__ . '/..' . '/phar-io/manifest/src/values/License.php', + 'PharIo\\Manifest\\LicenseElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/LicenseElement.php', + 'PharIo\\Manifest\\Manifest' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Manifest.php', + 'PharIo\\Manifest\\ManifestDocument' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocument.php', + 'PharIo\\Manifest\\ManifestDocumentException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentException.php', + 'PharIo\\Manifest\\ManifestDocumentLoadingException' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php', + 'PharIo\\Manifest\\ManifestDocumentMapper' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestDocumentMapper.php', + 'PharIo\\Manifest\\ManifestDocumentMapperException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestDocumentMapperException.php', + 'PharIo\\Manifest\\ManifestElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/ManifestElement.php', + 'PharIo\\Manifest\\ManifestElementException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestElementException.php', + 'PharIo\\Manifest\\ManifestLoader' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestLoader.php', + 'PharIo\\Manifest\\ManifestLoaderException' => __DIR__ . '/..' . '/phar-io/manifest/src/exceptions/ManifestLoaderException.php', + 'PharIo\\Manifest\\ManifestSerializer' => __DIR__ . '/..' . '/phar-io/manifest/src/ManifestSerializer.php', + 'PharIo\\Manifest\\PhpElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/PhpElement.php', + 'PharIo\\Manifest\\PhpExtensionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpExtensionRequirement.php', + 'PharIo\\Manifest\\PhpVersionRequirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/PhpVersionRequirement.php', + 'PharIo\\Manifest\\Requirement' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Requirement.php', + 'PharIo\\Manifest\\RequirementCollection' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollection.php', + 'PharIo\\Manifest\\RequirementCollectionIterator' => __DIR__ . '/..' . '/phar-io/manifest/src/values/RequirementCollectionIterator.php', + 'PharIo\\Manifest\\RequiresElement' => __DIR__ . '/..' . '/phar-io/manifest/src/xml/RequiresElement.php', + 'PharIo\\Manifest\\Type' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Type.php', + 'PharIo\\Manifest\\Url' => __DIR__ . '/..' . '/phar-io/manifest/src/values/Url.php', + 'PharIo\\Version\\AbstractVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AbstractVersionConstraint.php', + 'PharIo\\Version\\AndVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AndVersionConstraintGroup.php', + 'PharIo\\Version\\AnyVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/AnyVersionConstraint.php', + 'PharIo\\Version\\ExactVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/ExactVersionConstraint.php', + 'PharIo\\Version\\Exception' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/Exception.php', + 'PharIo\\Version\\GreaterThanOrEqualToVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php', + 'PharIo\\Version\\InvalidPreReleaseSuffixException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php', + 'PharIo\\Version\\InvalidVersionException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/InvalidVersionException.php', + 'PharIo\\Version\\OrVersionConstraintGroup' => __DIR__ . '/..' . '/phar-io/version/src/constraints/OrVersionConstraintGroup.php', + 'PharIo\\Version\\PreReleaseSuffix' => __DIR__ . '/..' . '/phar-io/version/src/PreReleaseSuffix.php', + 'PharIo\\Version\\SpecificMajorAndMinorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php', + 'PharIo\\Version\\SpecificMajorVersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php', + 'PharIo\\Version\\UnsupportedVersionConstraintException' => __DIR__ . '/..' . '/phar-io/version/src/exceptions/UnsupportedVersionConstraintException.php', + 'PharIo\\Version\\Version' => __DIR__ . '/..' . '/phar-io/version/src/Version.php', + 'PharIo\\Version\\VersionConstraint' => __DIR__ . '/..' . '/phar-io/version/src/constraints/VersionConstraint.php', + 'PharIo\\Version\\VersionConstraintParser' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintParser.php', + 'PharIo\\Version\\VersionConstraintValue' => __DIR__ . '/..' . '/phar-io/version/src/VersionConstraintValue.php', + 'PharIo\\Version\\VersionNumber' => __DIR__ . '/..' . '/phar-io/version/src/VersionNumber.php', + 'SebastianBergmann\\CodeCoverage\\CodeCoverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/CodeCoverage.php', + 'SebastianBergmann\\CodeCoverage\\CoveredCodeNotExecutedException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Driver' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Driver.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PCOV' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PCOV.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\PHPDBG' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/PHPDBG.php', + 'SebastianBergmann\\CodeCoverage\\Driver\\Xdebug' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Driver/Xdebug.php', + 'SebastianBergmann\\CodeCoverage\\Exception' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/Exception.php', + 'SebastianBergmann\\CodeCoverage\\Filter' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Filter.php', + 'SebastianBergmann\\CodeCoverage\\InvalidArgumentException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\CodeCoverage\\MissingCoversAnnotationException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php', + 'SebastianBergmann\\CodeCoverage\\Node\\AbstractNode' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/AbstractNode.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Builder' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Builder.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Node\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/File.php', + 'SebastianBergmann\\CodeCoverage\\Node\\Iterator' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Node/Iterator.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Clover' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Clover.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Crap4j' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Crap4j.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Dashboard' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Html\\Renderer' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Html/Renderer.php', + 'SebastianBergmann\\CodeCoverage\\Report\\PHP' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/PHP.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Text' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Text.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\BuildInformation' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Coverage' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Coverage.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Directory' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Directory.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Facade' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Facade.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\File' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/File.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Method' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Method.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Node' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Node.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Project' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Project.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Report' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Report.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Source' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Source.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Tests' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Tests.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Totals' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Totals.php', + 'SebastianBergmann\\CodeCoverage\\Report\\Xml\\Unit' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Report/Xml/Unit.php', + 'SebastianBergmann\\CodeCoverage\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/RuntimeException.php', + 'SebastianBergmann\\CodeCoverage\\UnintentionallyCoveredCodeException' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php', + 'SebastianBergmann\\CodeCoverage\\Util' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Util.php', + 'SebastianBergmann\\CodeCoverage\\Version' => __DIR__ . '/..' . '/phpunit/php-code-coverage/src/Version.php', + 'SebastianBergmann\\CodeUnitReverseLookup\\Wizard' => __DIR__ . '/..' . '/sebastian/code-unit-reverse-lookup/src/Wizard.php', + 'SebastianBergmann\\Comparator\\ArrayComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ArrayComparator.php', + 'SebastianBergmann\\Comparator\\Comparator' => __DIR__ . '/..' . '/sebastian/comparator/src/Comparator.php', + 'SebastianBergmann\\Comparator\\ComparisonFailure' => __DIR__ . '/..' . '/sebastian/comparator/src/ComparisonFailure.php', + 'SebastianBergmann\\Comparator\\DOMNodeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DOMNodeComparator.php', + 'SebastianBergmann\\Comparator\\DateTimeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DateTimeComparator.php', + 'SebastianBergmann\\Comparator\\DoubleComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/DoubleComparator.php', + 'SebastianBergmann\\Comparator\\ExceptionComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ExceptionComparator.php', + 'SebastianBergmann\\Comparator\\Factory' => __DIR__ . '/..' . '/sebastian/comparator/src/Factory.php', + 'SebastianBergmann\\Comparator\\MockObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/MockObjectComparator.php', + 'SebastianBergmann\\Comparator\\NumericComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/NumericComparator.php', + 'SebastianBergmann\\Comparator\\ObjectComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ObjectComparator.php', + 'SebastianBergmann\\Comparator\\ResourceComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ResourceComparator.php', + 'SebastianBergmann\\Comparator\\ScalarComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/ScalarComparator.php', + 'SebastianBergmann\\Comparator\\SplObjectStorageComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/SplObjectStorageComparator.php', + 'SebastianBergmann\\Comparator\\TypeComparator' => __DIR__ . '/..' . '/sebastian/comparator/src/TypeComparator.php', + 'SebastianBergmann\\Diff\\Chunk' => __DIR__ . '/..' . '/sebastian/diff/src/Chunk.php', + 'SebastianBergmann\\Diff\\ConfigurationException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/ConfigurationException.php', + 'SebastianBergmann\\Diff\\Diff' => __DIR__ . '/..' . '/sebastian/diff/src/Diff.php', + 'SebastianBergmann\\Diff\\Differ' => __DIR__ . '/..' . '/sebastian/diff/src/Differ.php', + 'SebastianBergmann\\Diff\\Exception' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/Exception.php', + 'SebastianBergmann\\Diff\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/diff/src/Exception/InvalidArgumentException.php', + 'SebastianBergmann\\Diff\\Line' => __DIR__ . '/..' . '/sebastian/diff/src/Line.php', + 'SebastianBergmann\\Diff\\LongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/LongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\MemoryEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/MemoryEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Diff\\Output\\AbstractChunkOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/AbstractChunkOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOnlyOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOnlyOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\DiffOutputBuilderInterface' => __DIR__ . '/..' . '/sebastian/diff/src/Output/DiffOutputBuilderInterface.php', + 'SebastianBergmann\\Diff\\Output\\StrictUnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/StrictUnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Output\\UnifiedDiffOutputBuilder' => __DIR__ . '/..' . '/sebastian/diff/src/Output/UnifiedDiffOutputBuilder.php', + 'SebastianBergmann\\Diff\\Parser' => __DIR__ . '/..' . '/sebastian/diff/src/Parser.php', + 'SebastianBergmann\\Diff\\TimeEfficientLongestCommonSubsequenceCalculator' => __DIR__ . '/..' . '/sebastian/diff/src/TimeEfficientLongestCommonSubsequenceCalculator.php', + 'SebastianBergmann\\Environment\\Console' => __DIR__ . '/..' . '/sebastian/environment/src/Console.php', + 'SebastianBergmann\\Environment\\OperatingSystem' => __DIR__ . '/..' . '/sebastian/environment/src/OperatingSystem.php', + 'SebastianBergmann\\Environment\\Runtime' => __DIR__ . '/..' . '/sebastian/environment/src/Runtime.php', + 'SebastianBergmann\\Exporter\\Exporter' => __DIR__ . '/..' . '/sebastian/exporter/src/Exporter.php', + 'SebastianBergmann\\FileIterator\\Facade' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Facade.php', + 'SebastianBergmann\\FileIterator\\Factory' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Factory.php', + 'SebastianBergmann\\FileIterator\\Iterator' => __DIR__ . '/..' . '/phpunit/php-file-iterator/src/Iterator.php', + 'SebastianBergmann\\GlobalState\\Blacklist' => __DIR__ . '/..' . '/sebastian/global-state/src/Blacklist.php', + 'SebastianBergmann\\GlobalState\\CodeExporter' => __DIR__ . '/..' . '/sebastian/global-state/src/CodeExporter.php', + 'SebastianBergmann\\GlobalState\\Exception' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/Exception.php', + 'SebastianBergmann\\GlobalState\\Restorer' => __DIR__ . '/..' . '/sebastian/global-state/src/Restorer.php', + 'SebastianBergmann\\GlobalState\\RuntimeException' => __DIR__ . '/..' . '/sebastian/global-state/src/exceptions/RuntimeException.php', + 'SebastianBergmann\\GlobalState\\Snapshot' => __DIR__ . '/..' . '/sebastian/global-state/src/Snapshot.php', + 'SebastianBergmann\\ObjectEnumerator\\Enumerator' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Enumerator.php', + 'SebastianBergmann\\ObjectEnumerator\\Exception' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/Exception.php', + 'SebastianBergmann\\ObjectEnumerator\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-enumerator/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\Exception' => __DIR__ . '/..' . '/sebastian/object-reflector/src/Exception.php', + 'SebastianBergmann\\ObjectReflector\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/object-reflector/src/InvalidArgumentException.php', + 'SebastianBergmann\\ObjectReflector\\ObjectReflector' => __DIR__ . '/..' . '/sebastian/object-reflector/src/ObjectReflector.php', + 'SebastianBergmann\\RecursionContext\\Context' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Context.php', + 'SebastianBergmann\\RecursionContext\\Exception' => __DIR__ . '/..' . '/sebastian/recursion-context/src/Exception.php', + 'SebastianBergmann\\RecursionContext\\InvalidArgumentException' => __DIR__ . '/..' . '/sebastian/recursion-context/src/InvalidArgumentException.php', + 'SebastianBergmann\\ResourceOperations\\ResourceOperations' => __DIR__ . '/..' . '/sebastian/resource-operations/src/ResourceOperations.php', + 'SebastianBergmann\\Timer\\Exception' => __DIR__ . '/..' . '/phpunit/php-timer/src/Exception.php', + 'SebastianBergmann\\Timer\\RuntimeException' => __DIR__ . '/..' . '/phpunit/php-timer/src/RuntimeException.php', + 'SebastianBergmann\\Timer\\Timer' => __DIR__ . '/..' . '/phpunit/php-timer/src/Timer.php', + 'SebastianBergmann\\Type\\CallableType' => __DIR__ . '/..' . '/sebastian/type/src/CallableType.php', + 'SebastianBergmann\\Type\\Exception' => __DIR__ . '/..' . '/sebastian/type/src/exception/Exception.php', + 'SebastianBergmann\\Type\\GenericObjectType' => __DIR__ . '/..' . '/sebastian/type/src/GenericObjectType.php', + 'SebastianBergmann\\Type\\IterableType' => __DIR__ . '/..' . '/sebastian/type/src/IterableType.php', + 'SebastianBergmann\\Type\\NullType' => __DIR__ . '/..' . '/sebastian/type/src/NullType.php', + 'SebastianBergmann\\Type\\ObjectType' => __DIR__ . '/..' . '/sebastian/type/src/ObjectType.php', + 'SebastianBergmann\\Type\\RuntimeException' => __DIR__ . '/..' . '/sebastian/type/src/exception/RuntimeException.php', + 'SebastianBergmann\\Type\\SimpleType' => __DIR__ . '/..' . '/sebastian/type/src/SimpleType.php', + 'SebastianBergmann\\Type\\Type' => __DIR__ . '/..' . '/sebastian/type/src/Type.php', + 'SebastianBergmann\\Type\\TypeName' => __DIR__ . '/..' . '/sebastian/type/src/TypeName.php', + 'SebastianBergmann\\Type\\UnknownType' => __DIR__ . '/..' . '/sebastian/type/src/UnknownType.php', + 'SebastianBergmann\\Type\\VoidType' => __DIR__ . '/..' . '/sebastian/type/src/VoidType.php', + 'SebastianBergmann\\Version' => __DIR__ . '/..' . '/sebastian/version/src/Version.php', + 'Text_Template' => __DIR__ . '/..' . '/phpunit/php-text-template/src/Template.php', + 'TheSeer\\Tokenizer\\Exception' => __DIR__ . '/..' . '/theseer/tokenizer/src/Exception.php', + 'TheSeer\\Tokenizer\\NamespaceUri' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUri.php', + 'TheSeer\\Tokenizer\\NamespaceUriException' => __DIR__ . '/..' . '/theseer/tokenizer/src/NamespaceUriException.php', + 'TheSeer\\Tokenizer\\Token' => __DIR__ . '/..' . '/theseer/tokenizer/src/Token.php', + 'TheSeer\\Tokenizer\\TokenCollection' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollection.php', + 'TheSeer\\Tokenizer\\TokenCollectionException' => __DIR__ . '/..' . '/theseer/tokenizer/src/TokenCollectionException.php', + 'TheSeer\\Tokenizer\\Tokenizer' => __DIR__ . '/..' . '/theseer/tokenizer/src/Tokenizer.php', + 'TheSeer\\Tokenizer\\XMLSerializer' => __DIR__ . '/..' . '/theseer/tokenizer/src/XMLSerializer.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::$prefixDirsPsr4; + $loader->prefixesPsr0 = ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::$prefixesPsr0; + $loader->classMap = ComposerStaticInitbbfefea263758c542cf1b7e1de76aa47::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json new file mode 100644 index 0000000..84d09ac --- /dev/null +++ b/vendor/composer/installed.json @@ -0,0 +1,2202 @@ +[ + { + "name": "codeigniter4/framework", + "version": "v4.0.4", + "version_normalized": "4.0.4.0", + "source": { + "type": "git", + "url": "https://github.com/codeigniter4/framework.git", + "reference": "1edcf84f77ff794640fddbfc59a10a024cd15b50" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/codeigniter4/framework/zipball/1edcf84f77ff794640fddbfc59a10a024cd15b50", + "reference": "1edcf84f77ff794640fddbfc59a10a024cd15b50", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-intl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "kint-php/kint": "^3.3", + "laminas/laminas-escaper": "^2.6", + "php": ">=7.2", + "psr/log": "^1.1" + }, + "require-dev": { + "codeigniter4/codeigniter4-standard": "^1.0", + "fzaninotto/faker": "^1.9@dev", + "mikey179/vfsstream": "1.6.*", + "phpunit/phpunit": "^8.5", + "predis/predis": "^1.1", + "squizlabs/php_codesniffer": "^3.3" + }, + "time": "2020-07-16T03:44:28+00:00", + "type": "project", + "installation-source": "dist", + "autoload": { + "psr-4": { + "CodeIgniter\\": "system/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The CodeIgniter framework v4", + "homepage": "https://codeigniter.com" + }, + { + "name": "doctrine/instantiator", + "version": "1.3.1", + "version_normalized": "1.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "time": "2020-05-29T17:27:14+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ] + }, + { + "name": "dompdf/dompdf", + "version": "v0.8.6", + "version_normalized": "0.8.6.0", + "source": { + "type": "git", + "url": "https://github.com/dompdf/dompdf.git", + "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dompdf/dompdf/zipball/db91d81866c69a42dad1d2926f61515a1e3f42c5", + "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "phenx/php-font-lib": "^0.5.2", + "phenx/php-svg-lib": "^0.3.3", + "php": "^7.1" + }, + "require-dev": { + "mockery/mockery": "^1.3", + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-gmagick": "Improves image processing performance", + "ext-imagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "time": "2020-08-30T22:54:22+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "0.7-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + }, + { + "name": "Brian Sweeney", + "email": "eclecticgeek@gmail.com" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + } + ], + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf" + }, + { + "name": "fzaninotto/faker", + "version": "dev-master", + "version_normalized": "9999999-dev", + "source": { + "type": "git", + "url": "https://github.com/fzaninotto/Faker.git", + "reference": "ac73e5287024f5e98dd6d0bf10e6a6f7877b7513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fzaninotto/Faker/zipball/ac73e5287024f5e98dd6d0bf10e6a6f7877b7513", + "reference": "ac73e5287024f5e98dd6d0bf10e6a6f7877b7513", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0" + }, + "require-dev": { + "ext-intl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7", + "squizlabs/php_codesniffer": "^2.9.2" + }, + "time": "2020-10-27T14:15:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "installation-source": "source", + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "abandoned": true + }, + { + "name": "kint-php/kint", + "version": "3.3", + "version_normalized": "3.3.0.0", + "source": { + "type": "git", + "url": "https://github.com/kint-php/kint.git", + "reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kint-php/kint/zipball/335ac1bcaf04d87df70d8aa51e8887ba2c6d203b", + "reference": "335ac1bcaf04d87df70d8aa51e8887ba2c6d203b", + "shasum": "" + }, + "require": { + "php": ">=5.3.6" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpunit/phpunit": "^4.0", + "seld/phar-utils": "^1.0", + "symfony/finder": "^2.0 || ^3.0 || ^4.0", + "vimeo/psalm": "^3.0" + }, + "suggest": { + "ext-ctype": "Simple data type tests", + "ext-iconv": "Provides fallback detection for ambiguous legacy string encodings such as the Windows and ISO 8859 code pages", + "ext-mbstring": "Provides string encoding detection", + "kint-php/kint-js": "Provides a simplified dump to console.log()", + "kint-php/kint-twig": "Provides d() and s() functions in twig templates", + "symfony/polyfill-ctype": "Replacement for ext-ctype if missing", + "symfony/polyfill-iconv": "Replacement for ext-iconv if missing", + "symfony/polyfill-mbstring": "Replacement for ext-mbstring if missing" + }, + "time": "2019-10-17T18:05:24+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "files": [ + "init.php" + ], + "psr-4": { + "Kint\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jonathan Vollebregt", + "homepage": "https://github.com/jnvsor" + }, + { + "name": "Rokas Šleinius", + "homepage": "https://github.com/raveren" + }, + { + "name": "Contributors", + "homepage": "https://github.com/kint-php/kint/graphs/contributors" + } + ], + "description": "Kint - debugging tool for PHP developers", + "homepage": "https://kint-php.github.io/kint/", + "keywords": [ + "debug", + "kint", + "php" + ] + }, + { + "name": "laminas/laminas-escaper", + "version": "2.6.1", + "version_normalized": "2.6.1.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-escaper.git", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/25f2a053eadfa92ddacb609dcbbc39362610da70", + "reference": "25f2a053eadfa92ddacb609dcbbc39362610da70", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^5.6 || ^7.0" + }, + "replace": { + "zendframework/zend-escaper": "self.version" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "time": "2019-12-31T16:43:30+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "homepage": "https://laminas.dev", + "keywords": [ + "escaper", + "laminas" + ] + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", + "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", + "squizlabs/php_codesniffer": "^3.5" + }, + "time": "2020-09-14T14:23:00+00:00", + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "installation-source": "dist", + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ] + }, + { + "name": "mikey179/vfsstream", + "version": "v1.6.8", + "version_normalized": "1.6.8.0", + "source": { + "type": "git", + "url": "https://github.com/bovigo/vfsStream.git", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "time": "2019-10-30T15:31:00+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-0": { + "org\\bovigo\\vfs\\": "src/main/php" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "description": "Virtual file system to mock the real file system in unit tests.", + "homepage": "http://vfs.bovigo.org/" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.1", + "version_normalized": "1.10.1.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "time": "2020-06-29T13:22:24+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ] + }, + { + "name": "phar-io/manifest", + "version": "1.0.3", + "version_normalized": "1.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0", + "php": "^5.6 || ^7.0" + }, + "time": "2018-07-08T19:23:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)" + }, + { + "name": "phar-io/version", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "time": "2018-07-08T19:19:57+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints" + }, + { + "name": "phenx/php-font-lib", + "version": "0.5.2", + "version_normalized": "0.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/PhenX/php-font-lib.git", + "reference": "ca6ad461f032145fff5971b5985e5af9e7fa88d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PhenX/php-font-lib/zipball/ca6ad461f032145fff5971b5985e5af9e7fa88d8", + "reference": "ca6ad461f032145fff5971b5985e5af9e7fa88d8", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5 || ^6 || ^7" + }, + "time": "2020-03-08T15:31:32+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib" + }, + { + "name": "phenx/php-svg-lib", + "version": "v0.3.3", + "version_normalized": "0.3.3.0", + "source": { + "type": "git", + "url": "https://github.com/PhenX/php-svg-lib.git", + "reference": "5fa61b65e612ce1ae15f69b3d223cb14ecc60e32" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PhenX/php-svg-lib/zipball/5fa61b65e612ce1ae15f69b3d223cb14ecc60e32", + "reference": "5fa61b65e612ce1ae15f69b3d223cb14ecc60e32", + "shasum": "" + }, + "require": { + "sabberworm/php-css-parser": "^8.3" + }, + "require-dev": { + "phpunit/phpunit": "^5.5|^6.5" + }, + "time": "2019-09-11T20:02:13+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "version_normalized": "2.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "time": "2020-06-27T09:03:43+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ] + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.2", + "version_normalized": "5.2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", + "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "time": "2020-09-03T19:13:55+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock." + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.4.0", + "version_normalized": "1.4.0.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "time": "2020-09-17T18:55:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names" + }, + { + "name": "phpspec/prophecy", + "version": "1.12.1", + "version_normalized": "1.12.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + }, + "time": "2020-09-29T09:10:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ] + }, + { + "name": "phpunit/php-code-coverage", + "version": "7.0.10", + "version_normalized": "7.0.10.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf", + "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.2", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.1.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.2.2" + }, + "suggest": { + "ext-xdebug": "^2.7.2" + }, + "time": "2019-11-20T13:55:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ] + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.2", + "version_normalized": "2.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "050bedf145a257b1ff02746c31894800e5122946" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946", + "reference": "050bedf145a257b1ff02746c31894800e5122946", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "time": "2018-09-13T20:33:42+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ] + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "version_normalized": "1.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "time": "2015-06-21T13:50:34+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ] + }, + { + "name": "phpunit/php-timer", + "version": "2.1.2", + "version_normalized": "2.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e", + "reference": "1038454804406b0b5f5f520358e78c1c2f71501e", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "time": "2019-06-07T04:22:29+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ] + }, + { + "name": "phpunit/php-token-stream", + "version": "3.1.1", + "version_normalized": "3.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff", + "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "time": "2019-09-17T06:23:10+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "abandoned": true + }, + { + "name": "phpunit/phpunit", + "version": "8.5.8", + "version_normalized": "8.5.8.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2.0", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "php": "^7.2", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0.0" + }, + "time": "2020-06-22T07:06:58+00:00", + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "8.5-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ] + }, + { + "name": "psr/log", + "version": "1.1.3", + "version_normalized": "1.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "time": "2020-03-23T09:12:05+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ] + }, + { + "name": "sabberworm/php-css-parser", + "version": "8.3.1", + "version_normalized": "8.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", + "reference": "d217848e1396ef962fb1997cf3e2421acba7f796" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/d217848e1396ef962fb1997cf3e2421acba7f796", + "reference": "d217848e1396ef962fb1997cf3e2421acba7f796", + "shasum": "" + }, + "require": { + "php": ">=5.3.2" + }, + "require-dev": { + "codacy/coverage": "^1.4", + "phpunit/phpunit": "~4.8" + }, + "time": "2020-06-01T09:10:00+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-0": { + "Sabberworm\\CSS": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Raphael Schweikert" + } + ], + "description": "Parser for CSS Files written in PHP", + "homepage": "http://www.sabberworm.com/blog/2010/6/10/php-css-parser", + "keywords": [ + "css", + "parser", + "stylesheet" + ] + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "version_normalized": "1.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "time": "2017-03-04T06:30:41+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/" + }, + { + "name": "sebastian/comparator", + "version": "3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "time": "2018-07-12T15:12:46+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ] + }, + { + "name": "sebastian/diff", + "version": "3.0.2", + "version_normalized": "3.0.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "time": "2019-02-04T06:01:07+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ] + }, + { + "name": "sebastian/environment", + "version": "4.2.3", + "version_normalized": "4.2.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.5" + }, + "suggest": { + "ext-posix": "*" + }, + "time": "2019-11-20T08:46:58+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.2-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ] + }, + { + "name": "sebastian/exporter", + "version": "3.1.2", + "version_normalized": "3.1.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e", + "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "time": "2019-09-14T09:02:43+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ] + }, + { + "name": "sebastian/global-state", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4", + "shasum": "" + }, + "require": { + "php": "^7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "time": "2019-02-01T05:30:01+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ] + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "version_normalized": "3.0.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-08-03T12:35:26+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "version_normalized": "1.1.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-29T09:07:27+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "version_normalized": "3.0.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "time": "2017-03-03T06:23:57+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context" + }, + { + "name": "sebastian/resource-operations", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "time": "2018-10-04T04:07:39+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations" + }, + { + "name": "sebastian/type", + "version": "1.1.3", + "version_normalized": "1.1.3.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3", + "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3", + "shasum": "" + }, + "require": { + "php": "^7.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.2" + }, + "time": "2019-07-02T08:10:15+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "version_normalized": "2.0.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "time": "2016-10-03T07:35:21+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.18.1", + "version_normalized": "1.18.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "time": "2020-07-14T12:35:20+00:00", + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "installation-source": "dist", + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ] + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "version_normalized": "1.2.0.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "time": "2020-07-12T23:59:07+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ] + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "version_normalized": "1.9.1.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "time": "2020-07-08T17:02:28+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ] + } +] diff --git a/vendor/doctrine/instantiator/.doctrine-project.json b/vendor/doctrine/instantiator/.doctrine-project.json new file mode 100644 index 0000000..4fe86ee --- /dev/null +++ b/vendor/doctrine/instantiator/.doctrine-project.json @@ -0,0 +1,26 @@ +{ + "active": true, + "name": "Instantiator", + "slug": "instantiator", + "docsSlug": "doctrine-instantiator", + "codePath": "/src", + "versions": [ + { + "name": "1.1", + "branchName": "master", + "slug": "latest", + "aliases": [ + "current", + "stable" + ], + "maintained": true, + "current": true + }, + { + "name": "1.0", + "branchName": "1.0.x", + "slug": "1.0" + } + ] +} + diff --git a/vendor/doctrine/instantiator/.github/FUNDING.yml b/vendor/doctrine/instantiator/.github/FUNDING.yml new file mode 100644 index 0000000..9a35064 --- /dev/null +++ b/vendor/doctrine/instantiator/.github/FUNDING.yml @@ -0,0 +1,3 @@ +patreon: phpdoctrine +tidelift: packagist/doctrine%2Finstantiator +custom: https://www.doctrine-project.org/sponsorship.html diff --git a/vendor/doctrine/instantiator/CONTRIBUTING.md b/vendor/doctrine/instantiator/CONTRIBUTING.md new file mode 100644 index 0000000..c1a2c42 --- /dev/null +++ b/vendor/doctrine/instantiator/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing + + * Follow the [Doctrine Coding Standard](https://github.com/doctrine/coding-standard) + * The project will follow strict [object calisthenics](http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php) + * Any contribution must provide tests for additional introduced conditions + * Any un-confirmed issue needs a failing test case before being accepted + * Pull requests must be sent from a new hotfix/feature branch, not from `master`. + +## Installation + +To install the project and run the tests, you need to clone it first: + +```sh +$ git clone git://github.com/doctrine/instantiator.git +``` + +You will then need to run a composer installation: + +```sh +$ cd Instantiator +$ curl -s https://getcomposer.org/installer | php +$ php composer.phar update +``` + +## Testing + +The PHPUnit version to be used is the one installed as a dev- dependency via composer: + +```sh +$ ./vendor/bin/phpunit +``` + +Accepted coverage for new contributions is 80%. Any contribution not satisfying this requirement +won't be merged. + diff --git a/vendor/doctrine/instantiator/LICENSE b/vendor/doctrine/instantiator/LICENSE new file mode 100644 index 0000000..4d983d1 --- /dev/null +++ b/vendor/doctrine/instantiator/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2014 Doctrine Project + +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/doctrine/instantiator/README.md b/vendor/doctrine/instantiator/README.md new file mode 100644 index 0000000..eff5a0c --- /dev/null +++ b/vendor/doctrine/instantiator/README.md @@ -0,0 +1,39 @@ +# Instantiator + +This library provides a way of avoiding usage of constructors when instantiating PHP classes. + +[![Build Status](https://travis-ci.org/doctrine/instantiator.svg?branch=master)](https://travis-ci.org/doctrine/instantiator) +[![Code Coverage](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/doctrine/instantiator/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/doctrine/instantiator/?branch=master) +[![Dependency Status](https://www.versioneye.com/package/php--doctrine--instantiator/badge.svg)](https://www.versioneye.com/package/php--doctrine--instantiator) + +[![Latest Stable Version](https://poser.pugx.org/doctrine/instantiator/v/stable.png)](https://packagist.org/packages/doctrine/instantiator) +[![Latest Unstable Version](https://poser.pugx.org/doctrine/instantiator/v/unstable.png)](https://packagist.org/packages/doctrine/instantiator) + +## Installation + +The suggested installation method is via [composer](https://getcomposer.org/): + +```sh +php composer.phar require "doctrine/instantiator:~1.0.3" +``` + +## Usage + +The instantiator is able to create new instances of any class without using the constructor or any API of the class +itself: + +```php +$instantiator = new \Doctrine\Instantiator\Instantiator(); + +$instance = $instantiator->instantiate(\My\ClassName\Here::class); +``` + +## Contributing + +Please read the [CONTRIBUTING.md](CONTRIBUTING.md) contents if you wish to help out! + +## Credits + +This library was migrated from [ocramius/instantiator](https://github.com/Ocramius/Instantiator), which +has been donated to the doctrine organization, and which is now deprecated in favour of this package. diff --git a/vendor/doctrine/instantiator/composer.json b/vendor/doctrine/instantiator/composer.json new file mode 100644 index 0000000..a84baa7 --- /dev/null +++ b/vendor/doctrine/instantiator/composer.json @@ -0,0 +1,52 @@ +{ + "name": "doctrine/instantiator", + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "type": "library", + "license": "MIT", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "instantiate", + "constructor" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "config": { + "platform": { + "php": "7.1.27" + } + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "ext-phar": "*", + "ext-pdo": "*", + "doctrine/coding-standard": "^6.0", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "autoload-dev": { + "psr-0": { + "DoctrineTest\\InstantiatorPerformance\\": "tests", + "DoctrineTest\\InstantiatorTest\\": "tests", + "DoctrineTest\\InstantiatorTestAsset\\": "tests" + } + }, + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + } +} diff --git a/vendor/doctrine/instantiator/docs/en/index.rst b/vendor/doctrine/instantiator/docs/en/index.rst new file mode 100644 index 0000000..0c85da0 --- /dev/null +++ b/vendor/doctrine/instantiator/docs/en/index.rst @@ -0,0 +1,68 @@ +Introduction +============ + +This library provides a way of avoiding usage of constructors when instantiating PHP classes. + +Installation +============ + +The suggested installation method is via `composer`_: + +.. code-block:: console + + $ composer require doctrine/instantiator + +Usage +===== + +The instantiator is able to create new instances of any class without +using the constructor or any API of the class itself: + +.. code-block:: php + + instantiate(User::class); + +Contributing +============ + +- Follow the `Doctrine Coding Standard`_ +- The project will follow strict `object calisthenics`_ +- Any contribution must provide tests for additional introduced + conditions +- Any un-confirmed issue needs a failing test case before being + accepted +- Pull requests must be sent from a new hotfix/feature branch, not from + ``master``. + +Testing +======= + +The PHPUnit version to be used is the one installed as a dev- dependency +via composer: + +.. code-block:: console + + $ ./vendor/bin/phpunit + +Accepted coverage for new contributions is 80%. Any contribution not +satisfying this requirement won’t be merged. + +Credits +======= + +This library was migrated from `ocramius/instantiator`_, which has been +donated to the doctrine organization, and which is now deprecated in +favour of this package. + +.. _composer: https://getcomposer.org/ +.. _CONTRIBUTING.md: CONTRIBUTING.md +.. _ocramius/instantiator: https://github.com/Ocramius/Instantiator +.. _Doctrine Coding Standard: https://github.com/doctrine/coding-standard +.. _object calisthenics: http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php diff --git a/vendor/doctrine/instantiator/docs/en/sidebar.rst b/vendor/doctrine/instantiator/docs/en/sidebar.rst new file mode 100644 index 0000000..0c36479 --- /dev/null +++ b/vendor/doctrine/instantiator/docs/en/sidebar.rst @@ -0,0 +1,4 @@ +.. toctree:: + :depth: 3 + + index diff --git a/vendor/doctrine/instantiator/phpbench.json b/vendor/doctrine/instantiator/phpbench.json new file mode 100644 index 0000000..fce5dd6 --- /dev/null +++ b/vendor/doctrine/instantiator/phpbench.json @@ -0,0 +1,4 @@ +{ + "bootstrap": "vendor/autoload.php", + "path": "tests/DoctrineTest/InstantiatorPerformance" +} diff --git a/vendor/doctrine/instantiator/phpcs.xml.dist b/vendor/doctrine/instantiator/phpcs.xml.dist new file mode 100644 index 0000000..1fcac4a --- /dev/null +++ b/vendor/doctrine/instantiator/phpcs.xml.dist @@ -0,0 +1,35 @@ + + + + + + + + + + + + src + tests + + + + + + + + + + tests/DoctrineTest/InstantiatorTestAsset/AbstractClassAsset.php + + + + src/Doctrine/Instantiator/Exception/UnexpectedValueException.php + src/Doctrine/Instantiator/Exception/InvalidArgumentException.php + + + + src/Doctrine/Instantiator/Exception/ExceptionInterface.php + src/Doctrine/Instantiator/InstantiatorInterface.php + + diff --git a/vendor/doctrine/instantiator/phpstan.neon.dist b/vendor/doctrine/instantiator/phpstan.neon.dist new file mode 100644 index 0000000..ecc38ef --- /dev/null +++ b/vendor/doctrine/instantiator/phpstan.neon.dist @@ -0,0 +1,19 @@ +includes: + - vendor/phpstan/phpstan-phpunit/extension.neon + - vendor/phpstan/phpstan-phpunit/rules.neon + +parameters: + level: max + paths: + - src + - tests + + ignoreErrors: + - + message: '#::__construct\(\) does not call parent constructor from#' + path: '*/tests/DoctrineTest/InstantiatorTestAsset/*.php' + + # dynamic properties confuse static analysis + - + message: '#Access to an undefined property object::\$foo\.#' + path: '*/tests/DoctrineTest/InstantiatorTest/InstantiatorTest.php' diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php new file mode 100644 index 0000000..e6a5195 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/ExceptionInterface.php @@ -0,0 +1,12 @@ += 50400 && trait_exists($className)) { + return new self(sprintf('The provided type "%s" is a trait, and can not be instantiated', $className)); + } + + return new self(sprintf('The provided class "%s" does not exist', $className)); + } + + public static function fromAbstractClass(ReflectionClass $reflectionClass) : self + { + return new self(sprintf( + 'The provided class "%s" is abstract, and can not be instantiated', + $reflectionClass->getName() + )); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php new file mode 100644 index 0000000..d946731 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Exception/UnexpectedValueException.php @@ -0,0 +1,48 @@ +getName() + ), + 0, + $exception + ); + } + + public static function fromUncleanUnSerialization( + ReflectionClass $reflectionClass, + string $errorString, + int $errorCode, + string $errorFile, + int $errorLine + ) : self { + return new self( + sprintf( + 'Could not produce an instance of "%s" via un-serialization, since an error was triggered ' + . 'in file "%s" at line "%d"', + $reflectionClass->getName(), + $errorFile, + $errorLine + ), + 0, + new Exception($errorString, $errorCode) + ); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php new file mode 100644 index 0000000..9c67862 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/Instantiator.php @@ -0,0 +1,203 @@ +buildAndCacheFromFactory($className); + } + + /** + * Builds the requested object and caches it in static properties for performance + * + * @return object + */ + private function buildAndCacheFromFactory(string $className) + { + $factory = self::$cachedInstantiators[$className] = $this->buildFactory($className); + $instance = $factory(); + + if ($this->isSafeToClone(new ReflectionClass($instance))) { + self::$cachedCloneables[$className] = clone $instance; + } + + return $instance; + } + + /** + * Builds a callable capable of instantiating the given $className without + * invoking its constructor. + * + * @throws InvalidArgumentException + * @throws UnexpectedValueException + * @throws ReflectionException + */ + private function buildFactory(string $className) : callable + { + $reflectionClass = $this->getReflectionClass($className); + + if ($this->isInstantiableViaReflection($reflectionClass)) { + return [$reflectionClass, 'newInstanceWithoutConstructor']; + } + + $serializedString = sprintf( + '%s:%d:"%s":0:{}', + is_subclass_of($className, Serializable::class) ? self::SERIALIZATION_FORMAT_USE_UNSERIALIZER : self::SERIALIZATION_FORMAT_AVOID_UNSERIALIZER, + strlen($className), + $className + ); + + $this->checkIfUnSerializationIsSupported($reflectionClass, $serializedString); + + return static function () use ($serializedString) { + return unserialize($serializedString); + }; + } + + /** + * @throws InvalidArgumentException + * @throws ReflectionException + */ + private function getReflectionClass(string $className) : ReflectionClass + { + if (! class_exists($className)) { + throw InvalidArgumentException::fromNonExistingClass($className); + } + + $reflection = new ReflectionClass($className); + + if ($reflection->isAbstract()) { + throw InvalidArgumentException::fromAbstractClass($reflection); + } + + return $reflection; + } + + /** + * @throws UnexpectedValueException + */ + private function checkIfUnSerializationIsSupported(ReflectionClass $reflectionClass, string $serializedString) : void + { + set_error_handler(static function (int $code, string $message, string $file, int $line) use ($reflectionClass, &$error) : bool { + $error = UnexpectedValueException::fromUncleanUnSerialization( + $reflectionClass, + $message, + $code, + $file, + $line + ); + + return true; + }); + + try { + $this->attemptInstantiationViaUnSerialization($reflectionClass, $serializedString); + } finally { + restore_error_handler(); + } + + if ($error) { + throw $error; + } + } + + /** + * @throws UnexpectedValueException + */ + private function attemptInstantiationViaUnSerialization(ReflectionClass $reflectionClass, string $serializedString) : void + { + try { + unserialize($serializedString); + } catch (Exception $exception) { + throw UnexpectedValueException::fromSerializationTriggeredException($reflectionClass, $exception); + } + } + + private function isInstantiableViaReflection(ReflectionClass $reflectionClass) : bool + { + return ! ($this->hasInternalAncestors($reflectionClass) && $reflectionClass->isFinal()); + } + + /** + * Verifies whether the given class is to be considered internal + */ + private function hasInternalAncestors(ReflectionClass $reflectionClass) : bool + { + do { + if ($reflectionClass->isInternal()) { + return true; + } + + $reflectionClass = $reflectionClass->getParentClass(); + } while ($reflectionClass); + + return false; + } + + /** + * Checks if a class is cloneable + * + * Classes implementing `__clone` cannot be safely cloned, as that may cause side-effects. + */ + private function isSafeToClone(ReflectionClass $reflection) : bool + { + return $reflection->isCloneable() + && ! $reflection->hasMethod('__clone') + && ! $reflection->isSubclassOf(ArrayIterator::class); + } +} diff --git a/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php new file mode 100644 index 0000000..95299f4 --- /dev/null +++ b/vendor/doctrine/instantiator/src/Doctrine/Instantiator/InstantiatorInterface.php @@ -0,0 +1,20 @@ +loadHtml('hello world'); + +// (Optional) Setup the paper size and orientation +$dompdf->setPaper('A4', 'landscape'); + +// Render the HTML as PDF +$dompdf->render(); + +// Output the generated PDF to Browser +$dompdf->stream(); +``` + +### Setting Options + +Set options during dompdf instantiation: + +```php +use Dompdf\Dompdf; +use Dompdf\Options; + +$options = new Options(); +$options->set('defaultFont', 'Courier'); +$dompdf = new Dompdf($options); +``` + +or at run time + +```php +use Dompdf\Dompdf; + +$dompdf = new Dompdf(); +$options = $dompdf->getOptions(); +$options->setDefaultFont('Courier'); +$dompdf->setOptions($options); +``` + +See [Dompdf\Options](src/Options.php) for a list of available options. + + +## Limitations (Known Issues) + + * Dompdf is not particularly tolerant to poorly-formed HTML input. To avoid + any unexpected rendering issues you should either enable the built-in HTML5 + parser at runtime (`$options->setIsHtml5ParserEnabled(true);`) + or run your HTML through a HTML validator/cleaner (such as + [Tidy](http://tidy.sourceforge.net) or the + [W3C Markup Validation Service](http://validator.w3.org)). + * Table cells are not pageable, meaning a table row must fit on a single page. + * Elements are rendered on the active page when they are parsed. + * Embedding "raw" SVG's (``) isn't working yet, you need to + either link to an external SVG file, or use a DataURI like this: + ```php + $html = ''; + ``` + Watch https://github.com/dompdf/dompdf/issues/320 for progress + +--- + +[![Donate button](https://www.paypal.com/en_US/i/btn/btn_donate_SM.gif)](http://goo.gl/DSvWf) + +*If you find this project useful, please consider making a donation. Any funds donated will be used to help further development on this project.)* diff --git a/vendor/dompdf/dompdf/VERSION b/vendor/dompdf/dompdf/VERSION new file mode 100644 index 0000000..7fc2521 --- /dev/null +++ b/vendor/dompdf/dompdf/VERSION @@ -0,0 +1 @@ +0.8.6 diff --git a/vendor/dompdf/dompdf/composer.json b/vendor/dompdf/dompdf/composer.json new file mode 100644 index 0000000..262614d --- /dev/null +++ b/vendor/dompdf/dompdf/composer.json @@ -0,0 +1,57 @@ +{ + "name": "dompdf/dompdf", + "type": "library", + "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", + "homepage": "https://github.com/dompdf/dompdf", + "license": "LGPL-2.1", + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + }, + { + "name": "Brian Sweeney", + "email": "eclecticgeek@gmail.com" + }, + { + "name": "Gabriel Bull", + "email": "me@gabrielbull.com" + } + ], + "autoload": { + "psr-4": { + "Dompdf\\": "src/" + }, + "classmap": [ + "lib/" + ] + }, + "autoload-dev": { + "psr-4": { + "Dompdf\\Tests\\": "tests/" + } + }, + "require": { + "php": "^7.1", + "ext-dom": "*", + "ext-mbstring": "*", + "phenx/php-font-lib": "^0.5.2", + "phenx/php-svg-lib": "^0.3.3" + }, + "require-dev": { + "phpunit/phpunit": "^7.5", + "squizlabs/php_codesniffer": "^3.5", + "mockery/mockery": "^1.3" + }, + "suggest": { + "ext-gd": "Needed to process images", + "ext-imagick": "Improves image processing performance", + "ext-gmagick": "Improves image processing performance", + "ext-zlib": "Needed for pdf stream compression" + }, + "extra": { + "branch-alias": { + "dev-develop": "0.7-dev" + } + } +} diff --git a/vendor/dompdf/dompdf/lib/Cpdf.php b/vendor/dompdf/dompdf/lib/Cpdf.php new file mode 100644 index 0000000..0a6e9b5 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/Cpdf.php @@ -0,0 +1,6466 @@ + + * @author Orion Richardson + * @author Helmut Tischer + * @author Ryan H. Masten + * @author Brian Sweeney + * @author Fabien Ménager + * @license Public Domain http://creativecommons.org/licenses/publicdomain/ + * @package Cpdf + */ + +namespace Dompdf; + +use FontLib\Exception\FontNotFoundException; +use FontLib\Font; +use FontLib\BinaryStream; + +class Cpdf +{ + + const ACROFORM_SIG_SIGNATURESEXISTS = 0x0001; + const ACROFORM_SIG_APPENDONLY = 0x0002; + + const ACROFORM_FIELD_BUTTON = 'Btn'; + const ACROFORM_FIELD_TEXT = 'Tx'; + const ACROFORM_FIELD_CHOICE = 'Ch'; + const ACROFORM_FIELD_SIG = 'Sig'; + + const ACROFORM_FIELD_READONLY = 0x0001; + const ACROFORM_FIELD_REQUIRED = 0x0002; + + const ACROFORM_FIELD_TEXT_MULTILINE = 0x1000; + const ACROFORM_FIELD_TEXT_PASSWORD = 0x2000; + const ACROFORM_FIELD_TEXT_RICHTEXT = 0x10000; + + const ACROFORM_FIELD_CHOICE_COMBO = 0x20000; + const ACROFORM_FIELD_CHOICE_EDIT = 0x40000; + const ACROFORM_FIELD_CHOICE_SORT = 0x80000; + const ACROFORM_FIELD_CHOICE_MULTISELECT = 0x200000; + + const XOBJECT_SUBTYPE_FORM = 'Form'; + + /** + * @var integer The current number of pdf objects in the document + */ + public $numObj = 0; + + /** + * @var array This array contains all of the pdf objects, ready for final assembly + */ + public $objects = []; + + /** + * @var integer The objectId (number within the objects array) of the document catalog + */ + public $catalogId; + + /** + * @var integer The objectId (number within the objects array) of indirect references (Javascript EmbeddedFiles) + */ + protected $indirectReferenceId = 0; + + /** + * @var integer The objectId (number within the objects array) + */ + protected $embeddedFilesId = 0; + + /** + * AcroForm objectId + * + * @var integer + */ + public $acroFormId; + + /** + * @var int + */ + public $signatureMaxLen = 5000; + + /** + * @var array Array carrying information about the fonts that the system currently knows about + * Used to ensure that a font is not loaded twice, among other things + */ + public $fonts = []; + + /** + * @var string The default font metrics file to use if no other font has been loaded. + * The path to the directory containing the font metrics should be included + */ + public $defaultFont = './fonts/Helvetica.afm'; + + /** + * @string A record of the current font + */ + public $currentFont = ''; + + /** + * @var string The current base font + */ + public $currentBaseFont = ''; + + /** + * @var integer The number of the current font within the font array + */ + public $currentFontNum = 0; + + /** + * @var integer + */ + public $currentNode; + + /** + * @var integer Object number of the current page + */ + public $currentPage; + + /** + * @var integer Object number of the currently active contents block + */ + public $currentContents; + + /** + * @var integer Number of fonts within the system + */ + public $numFonts = 0; + + /** + * @var integer Number of graphic state resources used + */ + private $numStates = 0; + + /** + * @var array Number of graphic state resources used + */ + private $gstates = []; + + /** + * @var array Current color for fill operations, defaults to inactive value, + * all three components should be between 0 and 1 inclusive when active + */ + public $currentColor = null; + + /** + * @var array Current color for stroke operations (lines etc.) + */ + public $currentStrokeColor = null; + + /** + * @var string Fill rule (nonzero or evenodd) + */ + public $fillRule = "nonzero"; + + /** + * @var string Current style that lines are drawn in + */ + public $currentLineStyle = ''; + + /** + * @var array Current line transparency (partial graphics state) + */ + public $currentLineTransparency = ["mode" => "Normal", "opacity" => 1.0]; + + /** + * array Current fill transparency (partial graphics state) + */ + public $currentFillTransparency = ["mode" => "Normal", "opacity" => 1.0]; + + /** + * @var array An array which is used to save the state of the document, mainly the colors and styles + * it is used to temporarily change to another state, then change back to what it was before + */ + public $stateStack = []; + + /** + * @var integer Number of elements within the state stack + */ + public $nStateStack = 0; + + /** + * @var integer Number of page objects within the document + */ + public $numPages = 0; + + /** + * @var array Object Id storage stack + */ + public $stack = []; + + /** + * @var integer Number of elements within the object Id storage stack + */ + public $nStack = 0; + + /** + * an array which contains information about the objects which are not firmly attached to pages + * these have been added with the addObject function + */ + public $looseObjects = []; + + /** + * array contains information about how the loose objects are to be added to the document + */ + public $addLooseObjects = []; + + /** + * @var integer The objectId of the information object for the document + * this contains authorship, title etc. + */ + public $infoObject = 0; + + /** + * @var integer Number of images being tracked within the document + */ + public $numImages = 0; + + /** + * @var array An array containing options about the document + * it defaults to turning on the compression of the objects + */ + public $options = ['compression' => true]; + + /** + * @var integer The objectId of the first page of the document + */ + public $firstPageId; + + /** + * @var integer The object Id of the procset object + */ + public $procsetObjectId; + + /** + * @var array Store the information about the relationship between font families + * this used so that the code knows which font is the bold version of another font, etc. + * the value of this array is initialised in the constructor function. + */ + public $fontFamilies = []; + + /** + * @var string Folder for php serialized formats of font metrics files. + * If empty string, use same folder as original metrics files. + * This can be passed in from class creator. + * If this folder does not exist or is not writable, Cpdf will be **much** slower. + * Because of potential trouble with php safe mode, folder cannot be created at runtime. + */ + public $fontcache = ''; + + /** + * @var integer The version of the font metrics cache file. + * This value must be manually incremented whenever the internal font data structure is modified. + */ + public $fontcacheVersion = 6; + + /** + * @var string Temporary folder. + * If empty string, will attempt system tmp folder. + * This can be passed in from class creator. + */ + public $tmp = ''; + + /** + * @var string Track if the current font is bolded or italicised + */ + public $currentTextState = ''; + + /** + * @var string Messages are stored here during processing, these can be selected afterwards to give some useful debug information + */ + public $messages = ''; + + /** + * @var string The encryption array for the document encryption is stored here + */ + public $arc4 = ''; + + /** + * @var integer The object Id of the encryption information + */ + public $arc4_objnum = 0; + + /** + * @var string The file identifier, used to uniquely identify a pdf document + */ + public $fileIdentifier = ''; + + /** + * @var boolean A flag to say if a document is to be encrypted or not + */ + public $encrypted = false; + + /** + * @var string The encryption key for the encryption of all the document content (structure is not encrypted) + */ + public $encryptionKey = ''; + + /** + * @var array Array which forms a stack to keep track of nested callback functions + */ + public $callback = []; + + /** + * @var integer The number of callback functions in the callback array + */ + public $nCallback = 0; + + /** + * @var array Store label->id pairs for named destinations, these will be used to replace internal links + * done this way so that destinations can be defined after the location that links to them + */ + public $destinations = []; + + /** + * @var array Store the stack for the transaction commands, each item in here is a record of the values of all the + * publiciables within the class, so that the user can rollback at will (from each 'start' command) + * note that this includes the objects array, so these can be large. + */ + public $checkpoint = ''; + + /** + * @var array Table of Image origin filenames and image labels which were already added with o_image(). + * Allows to merge identical images + */ + public $imagelist = []; + + /** + * @var boolean Whether the text passed in should be treated as Unicode or just local character set. + */ + public $isUnicode = false; + + /** + * @var string the JavaScript code of the document + */ + public $javascript = ''; + + /** + * @var boolean whether the compression is possible + */ + protected $compressionReady = false; + + /** + * @var array Current page size + */ + protected $currentPageSize = ["width" => 0, "height" => 0]; + + /** + * @var array All the chars that will be required in the font subsets + */ + protected $stringSubsets = []; + + /** + * @var string The target internal encoding + */ + protected static $targetEncoding = 'Windows-1252'; + + /** + * @var array + */ + protected $byteRange = array(); + + /** + * @var array The list of the core fonts + */ + protected static $coreFonts = [ + 'courier', + 'courier-bold', + 'courier-oblique', + 'courier-boldoblique', + 'helvetica', + 'helvetica-bold', + 'helvetica-oblique', + 'helvetica-boldoblique', + 'times-roman', + 'times-bold', + 'times-italic', + 'times-bolditalic', + 'symbol', + 'zapfdingbats' + ]; + + /** + * Class constructor + * This will start a new document + * + * @param array $pageSize Array of 4 numbers, defining the bottom left and upper right corner of the page. first two are normally zero. + * @param boolean $isUnicode Whether text will be treated as Unicode or not. + * @param string $fontcache The font cache folder + * @param string $tmp The temporary folder + */ + function __construct($pageSize = [0, 0, 612, 792], $isUnicode = false, $fontcache = '', $tmp = '') + { + $this->isUnicode = $isUnicode; + $this->fontcache = rtrim($fontcache, DIRECTORY_SEPARATOR."/\\"); + $this->tmp = ($tmp !== '' ? $tmp : sys_get_temp_dir()); + $this->newDocument($pageSize); + + $this->compressionReady = function_exists('gzcompress'); + + if (in_array('Windows-1252', mb_list_encodings())) { + self::$targetEncoding = 'Windows-1252'; + } + + // also initialize the font families that are known about already + $this->setFontFamily('init'); + } + + /** + * Document object methods (internal use only) + * + * There is about one object method for each type of object in the pdf document + * Each function has the same call list ($id,$action,$options). + * $id = the object ID of the object, or what it is to be if it is being created + * $action = a string specifying the action to be performed, though ALL must support: + * 'new' - create the object with the id $id + * 'out' - produce the output for the pdf object + * $options = optional, a string or array containing the various parameters for the object + * + * These, in conjunction with the output function are the ONLY way for output to be produced + * within the pdf 'file'. + */ + + /** + * Destination object, used to specify the location for the user to jump to, presently on opening + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_destination($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'destination', 'info' => []]; + $tmp = ''; + switch ($options['type']) { + case 'XYZ': + /** @noinspection PhpMissingBreakStatementInspection */ + case 'FitR': + $tmp = ' ' . $options['p3'] . $tmp; + case 'FitH': + case 'FitV': + case 'FitBH': + /** @noinspection PhpMissingBreakStatementInspection */ + case 'FitBV': + $tmp = ' ' . $options['p1'] . ' ' . $options['p2'] . $tmp; + case 'Fit': + case 'FitB': + $tmp = $options['type'] . $tmp; + $this->objects[$id]['info']['string'] = $tmp; + $this->objects[$id]['info']['page'] = $options['page']; + } + break; + + case 'out': + $o = &$this->objects[$id]; + + $tmp = $o['info']; + $res = "\n$id 0 obj\n" . '[' . $tmp['page'] . ' 0 R /' . $tmp['string'] . "]\nendobj"; + + return $res; + } + + return null; + } + + /** + * set the viewer preferences + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + */ + protected function o_viewerPreferences($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'viewerPreferences', 'info' => []]; + break; + + case 'add': + $o = &$this->objects[$id]; + + foreach ($options as $k => $v) { + switch ($k) { + // Boolean keys + case 'HideToolbar': + case 'HideMenubar': + case 'HideWindowUI': + case 'FitWindow': + case 'CenterWindow': + case 'DisplayDocTitle': + case 'PickTrayByPDFSize': + $o['info'][$k] = (bool)$v; + break; + + // Integer keys + case 'NumCopies': + $o['info'][$k] = (int)$v; + break; + + // Name keys + case 'ViewArea': + case 'ViewClip': + case 'PrintClip': + case 'PrintArea': + $o['info'][$k] = (string)$v; + break; + + // Named with limited valid values + case 'NonFullScreenPageMode': + if (!in_array($v, ['UseNone', 'UseOutlines', 'UseThumbs', 'UseOC'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'Direction': + if (!in_array($v, ['L2R', 'R2L'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'PrintScaling': + if (!in_array($v, ['None', 'AppDefault'])) { + break; + } + $o['info'][$k] = $v; + break; + + case 'Duplex': + if (!in_array($v, ['None', 'Simplex', 'DuplexFlipShortEdge', 'DuplexFlipLongEdge'])) { + break; + } + $o['info'][$k] = $v; + break; + + // Integer array + case 'PrintPageRange': + // Cast to integer array + foreach ($v as $vK => $vV) { + $v[$vK] = (int)$vV; + } + $o['info'][$k] = array_values($v); + break; + } + } + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + + foreach ($o['info'] as $k => $v) { + if (is_string($v)) { + $v = '/' . $v; + } elseif (is_int($v)) { + $v = (string) $v; + } elseif (is_bool($v)) { + $v = ($v ? 'true' : 'false'); + } elseif (is_array($v)) { + $v = '[' . implode(' ', $v) . ']'; + } + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * define the document catalog, the overall controller for the document + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + */ + protected function o_catalog($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'catalog', 'info' => []]; + $this->catalogId = $id; + break; + + case 'acroform': + case 'outlines': + case 'pages': + case 'openHere': + case 'names': + $o['info'][$action] = $options; + break; + + case 'viewerPreferences': + if (!isset($o['info']['viewerPreferences'])) { + $this->numObj++; + $this->o_viewerPreferences($this->numObj, 'new'); + $o['info']['viewerPreferences'] = $this->numObj; + } + + $vp = $o['info']['viewerPreferences']; + $this->o_viewerPreferences($vp, 'add', $options); + + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Catalog"; + + foreach ($o['info'] as $k => $v) { + switch ($k) { + case 'outlines': + $res .= "\n/Outlines $v 0 R"; + break; + + case 'pages': + $res .= "\n/Pages $v 0 R"; + break; + + case 'viewerPreferences': + $res .= "\n/ViewerPreferences $v 0 R"; + break; + + case 'openHere': + $res .= "\n/OpenAction $v 0 R"; + break; + + case 'names': + $res .= "\n/Names $v 0 R"; + break; + + case 'acroform': + $res .= "\n/AcroForm $v 0 R"; + break; + } + } + + $res .= " >>\nendobj"; + + return $res; + } + + return null; + } + + /** + * object which is a parent to the pages in the document + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_pages($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'pages', 'info' => []]; + $this->o_catalog($this->catalogId, 'pages', $id); + break; + + case 'page': + if (!is_array($options)) { + // then it will just be the id of the new page + $o['info']['pages'][] = $options; + } else { + // then it should be an array having 'id','rid','pos', where rid=the page to which this one will be placed relative + // and pos is either 'before' or 'after', saying where this page will fit. + if (isset($options['id']) && isset($options['rid']) && isset($options['pos'])) { + $i = array_search($options['rid'], $o['info']['pages']); + if (isset($o['info']['pages'][$i]) && $o['info']['pages'][$i] == $options['rid']) { + + // then there is a match + // make a space + switch ($options['pos']) { + case 'before': + $k = $i; + break; + + case 'after': + $k = $i + 1; + break; + + default: + $k = -1; + break; + } + + if ($k >= 0) { + for ($j = count($o['info']['pages']) - 1; $j >= $k; $j--) { + $o['info']['pages'][$j + 1] = $o['info']['pages'][$j]; + } + + $o['info']['pages'][$k] = $options['id']; + } + } + } + } + break; + + case 'procset': + $o['info']['procset'] = $options; + break; + + case 'mediaBox': + $o['info']['mediaBox'] = $options; + // which should be an array of 4 numbers + $this->currentPageSize = ['width' => $options[2], 'height' => $options[3]]; + break; + + case 'font': + $o['info']['fonts'][] = ['objNum' => $options['objNum'], 'fontNum' => $options['fontNum']]; + break; + + case 'extGState': + $o['info']['extGStates'][] = ['objNum' => $options['objNum'], 'stateNum' => $options['stateNum']]; + break; + + case 'xObject': + $o['info']['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; + break; + + case 'out': + if (count($o['info']['pages'])) { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Kids ["; + foreach ($o['info']['pages'] as $v) { + $res .= "$v 0 R\n"; + } + + $res .= "]\n/Count " . count($this->objects[$id]['info']['pages']); + + if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) || + isset($o['info']['procset']) || + (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) + ) { + $res .= "\n/Resources <<"; + + if (isset($o['info']['procset'])) { + $res .= "\n/ProcSet " . $o['info']['procset'] . " 0 R"; + } + + if (isset($o['info']['fonts']) && count($o['info']['fonts'])) { + $res .= "\n/Font << "; + foreach ($o['info']['fonts'] as $finfo) { + $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])) { + $res .= "\n/XObject << "; + foreach ($o['info']['xObjects'] as $finfo) { + $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) { + $res .= "\n/ExtGState << "; + foreach ($o['info']['extGStates'] as $gstate) { + $res .= "\n/GS" . $gstate['stateNum'] . " " . $gstate['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + $res .= "\n>>"; + if (isset($o['info']['mediaBox'])) { + $tmp = $o['info']['mediaBox']; + $res .= "\n/MediaBox [" . sprintf( + '%.3F %.3F %.3F %.3F', + $tmp[0], + $tmp[1], + $tmp[2], + $tmp[3] + ) . ']'; + } + } + + $res .= "\n >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj"; + } + + return $res; + } + + return null; + } + + /** + * define the outlines in the doc, empty for now + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_outlines($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'outlines', 'info' => ['outlines' => []]]; + $this->o_catalog($this->catalogId, 'outlines', $id); + break; + + case 'outline': + $o['info']['outlines'][] = $options; + break; + + case 'out': + if (count($o['info']['outlines'])) { + $res = "\n$id 0 obj\n<< /Type /Outlines /Kids ["; + foreach ($o['info']['outlines'] as $v) { + $res .= "$v 0 R "; + } + + $res .= "] /Count " . count($o['info']['outlines']) . " >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj"; + } + + return $res; + } + + return null; + } + + /** + * an object to hold the font description + * + * @param $id + * @param $action + * @param string|array $options + * @return string|null + * @throws FontNotFoundException + */ + protected function o_font($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'font', + 'info' => [ + 'name' => $options['name'], + 'fontFileName' => $options['fontFileName'], + 'SubType' => 'Type1', + 'isSubsetting' => $options['isSubsetting'] + ] + ]; + $fontNum = $this->numFonts; + $this->objects[$id]['info']['fontNum'] = $fontNum; + + // deal with the encoding and the differences + if (isset($options['differences'])) { + // then we'll need an encoding dictionary + $this->numObj++; + $this->o_fontEncoding($this->numObj, 'new', $options); + $this->objects[$id]['info']['encodingDictionary'] = $this->numObj; + } else { + if (isset($options['encoding'])) { + // we can specify encoding here + switch ($options['encoding']) { + case 'WinAnsiEncoding': + case 'MacRomanEncoding': + case 'MacExpertEncoding': + $this->objects[$id]['info']['encoding'] = $options['encoding']; + break; + + case 'none': + break; + + default: + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + break; + } + } else { + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + } + } + + if ($this->fonts[$options['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more information. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $toUnicodeId = ++$this->numObj; + $this->o_toUnicode($toUnicodeId, 'new'); + $this->objects[$id]['info']['toUnicode'] = $toUnicodeId; + + $cidFontId = ++$this->numObj; + $this->o_fontDescendentCID($cidFontId, 'new', $options); + $this->objects[$id]['info']['cidFont'] = $cidFontId; + } + + // also tell the pages node about the new font + $this->o_pages($this->currentNode, 'font', ['fontNum' => $fontNum, 'objNum' => $id]); + break; + + case 'add': + $font_options = $this->processFont($id, $o['info']); + + if ($font_options !== false) { + foreach ($font_options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + case 'FirstChar': + case 'LastChar': + case 'Widths': + case 'FontDescriptor': + case 'SubType': + $this->addMessage('o_font ' . $k . " : " . $v); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to descendent font + if (isset($o['info']['cidFont'])) { + $this->o_fontDescendentCID($o['info']['cidFont'], 'add', $font_options); + } + } + break; + + case 'out': + if ($this->fonts[$this->objects[$id]['info']['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more information. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $res = "\n$id 0 obj\n<fonts[$fontFileName])) { + return false; + } + + $font = &$this->fonts[$fontFileName]; + + $fileSuffix = $font['fileSuffix']; + $fileSuffixLower = strtolower($font['fileSuffix']); + $fbfile = "$fontFileName.$fileSuffix"; + $isTtfFont = $fileSuffixLower === 'ttf'; + $isPfbFont = $fileSuffixLower === 'pfb'; + + $this->addMessage('selectFont: checking for - ' . $fbfile); + + if (!$fileSuffix) { + $this->addMessage( + 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts' + ); + + return false; + } else { + $adobeFontName = isset($font['PostScriptName']) ? $font['PostScriptName'] : $font['FontName']; + // $fontObj = $this->numObj; + $this->addMessage("selectFont: adding font file - $fbfile - $adobeFontName"); + + // find the array of font widths, and put that into an object. + $firstChar = -1; + $lastChar = 0; + $widths = []; + $cid_widths = []; + + foreach ($font['C'] as $num => $d) { + if (intval($num) > 0 || $num == '0') { + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + if ($lastChar > 0 && $num > $lastChar + 1) { + for ($i = $lastChar + 1; $i < $num; $i++) { + $widths[] = 0; + } + } + } + + $widths[] = $d; + + if ($font['isUnicode']) { + $cid_widths[$num] = $d; + } + + if ($firstChar == -1) { + $firstChar = $num; + } + + $lastChar = $num; + } + } + + // also need to adjust the widths for the differences array + if (isset($object['differences'])) { + foreach ($object['differences'] as $charNum => $charName) { + if ($charNum > $lastChar) { + if (!$object['isUnicode']) { + // With Unicode, widths array isn't used + for ($i = $lastChar + 1; $i <= $charNum; $i++) { + $widths[] = 0; + } + } + + $lastChar = $charNum; + } + + if (isset($font['C'][$charName])) { + $widths[$charNum - $firstChar] = $font['C'][$charName]; + if ($font['isUnicode']) { + $cid_widths[$charName] = $font['C'][$charName]; + } + } + } + } + + if ($font['isUnicode']) { + $font['CIDWidths'] = $cid_widths; + } + + $this->addMessage('selectFont: FirstChar = ' . $firstChar); + $this->addMessage('selectFont: LastChar = ' . $lastChar); + + $widthid = -1; + + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + + $this->numObj++; + $this->o_contents($this->numObj, 'new', 'raw'); + $this->objects[$this->numObj]['c'] .= '[' . implode(' ', $widths) . ']'; + $widthid = $this->numObj; + } + + $missing_width = 500; + $stemV = 70; + + if (isset($font['MissingWidth'])) { + $missing_width = $font['MissingWidth']; + } + if (isset($font['StdVW'])) { + $stemV = $font['StdVW']; + } else { + if (isset($font['Weight']) && preg_match('!(bold|black)!i', $font['Weight'])) { + $stemV = 120; + } + } + + // load the pfb file, and put that into an object too. + // note that pdf supports only binary format type 1 font files, though there is a + // simple utility to convert them from pfa to pfb. + if (!$font['isSubsetting']) { + $data = file_get_contents($fbfile); + } else { + $adobeFontName = $this->getFontSubsettingTag($font) . '+' . $adobeFontName; + $this->stringSubsets[$fontFileName][] = 32; // Force space if not in yet + + $subset = $this->stringSubsets[$fontFileName]; + sort($subset); + + // Load font + $font_obj = Font::load($fbfile); + $font_obj->parse(); + + // Define subset + $font_obj->setSubset($subset); + $font_obj->reduce(); + + // Write new font + $tmp_name = $this->tmp . "/" . basename($fbfile) . ".tmp." . uniqid(); + touch($tmp_name); + $font_obj->open($tmp_name, BinaryStream::modeReadWrite); + $font_obj->encode(["OS/2"]); + $font_obj->close(); + + // Parse the new font to get cid2gid and widths + $font_obj = Font::load($tmp_name); + + // Find Unicode char map table + $subtable = null; + foreach ($font_obj->getData("cmap", "subtables") as $_subtable) { + if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { + $subtable = $_subtable; + break; + } + } + + if ($subtable) { + $glyphIndexArray = $subtable["glyphIndexArray"]; + $hmtx = $font_obj->getData("hmtx"); + + unset($glyphIndexArray[0xFFFF]); + + $cidtogid = str_pad('', max(array_keys($glyphIndexArray)) * 2 + 1, "\x00"); + $font['CIDWidths'] = []; + foreach ($glyphIndexArray as $cid => $gid) { + if ($cid >= 0 && $cid < 0xFFFF && $gid) { + $cidtogid[$cid * 2] = chr($gid >> 8); + $cidtogid[$cid * 2 + 1] = chr($gid & 0xFF); + } + + $width = $font_obj->normalizeFUnit(isset($hmtx[$gid]) ? $hmtx[$gid][0] : $hmtx[0][0]); + $font['CIDWidths'][$cid] = $width; + } + + $font['CIDtoGID'] = base64_encode(gzcompress($cidtogid)); + $font['CIDtoGID_Compressed'] = true; + + $data = file_get_contents($tmp_name); + } else { + $data = file_get_contents($fbfile); + } + + $font_obj->close(); + unlink($tmp_name); + } + + // create the font descriptor + $this->numObj++; + $fontDescriptorId = $this->numObj; + + $this->numObj++; + $pfbid = $this->numObj; + + // determine flags (more than a little flakey, hopefully will not matter much) + $flags = 0; + + if ($font['ItalicAngle'] != 0) { + $flags += pow(2, 6); + } + + if ($font['IsFixedPitch'] === 'true') { + $flags += 1; + } + + $flags += pow(2, 5); // assume non-sybolic + $list = [ + 'Ascent' => 'Ascender', + 'CapHeight' => 'Ascender', //FIXME: php-font-lib is not grabbing this value, so we'll fake it and use the Ascender value // 'CapHeight' + 'MissingWidth' => 'MissingWidth', + 'Descent' => 'Descender', + 'FontBBox' => 'FontBBox', + 'ItalicAngle' => 'ItalicAngle' + ]; + $fdopt = [ + 'Flags' => $flags, + 'FontName' => $adobeFontName, + 'StemV' => $stemV + ]; + + foreach ($list as $k => $v) { + if (isset($font[$v])) { + $fdopt[$k] = $font[$v]; + } + } + + if ($isPfbFont) { + $fdopt['FontFile'] = $pfbid; + } elseif ($isTtfFont) { + $fdopt['FontFile2'] = $pfbid; + } + + $this->o_fontDescriptor($fontDescriptorId, 'new', $fdopt); + + // embed the font program + $this->o_contents($this->numObj, 'new'); + $this->objects[$pfbid]['c'] .= $data; + + // determine the cruicial lengths within this file + if ($isPfbFont) { + $l1 = strpos($data, 'eexec') + 6; + $l2 = strpos($data, '00000000') - $l1; + $l3 = mb_strlen($data, '8bit') - $l2 - $l1; + $this->o_contents( + $this->numObj, + 'add', + ['Length1' => $l1, 'Length2' => $l2, 'Length3' => $l3] + ); + } elseif ($isTtfFont) { + $l1 = mb_strlen($data, '8bit'); + $this->o_contents($this->numObj, 'add', ['Length1' => $l1]); + } + + // tell the font object about all this new stuff + $options = [ + 'BaseFont' => $adobeFontName, + 'MissingWidth' => $missing_width, + 'Widths' => $widthid, + 'FirstChar' => $firstChar, + 'LastChar' => $lastChar, + 'FontDescriptor' => $fontDescriptorId + ]; + + if ($isTtfFont) { + $options['SubType'] = 'TrueType'; + } + + $this->addMessage("adding extra info to font.($fontObjId)"); + + foreach ($options as $fk => $fv) { + $this->addMessage("$fk : $fv"); + } + } + + return $options; + } + + /** + * A toUnicode section, needed for unicode fonts + * + * @param $id + * @param $action + * @return null|string + */ + protected function o_toUnicode($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'toUnicode' + ]; + break; + case 'add': + break; + case 'out': + $ordering = 'UCS'; + $registry = 'Adobe'; + + if ($this->encrypted) { + $this->encryptInit($id); + $ordering = $this->ARC4($ordering); + $registry = $this->filterText($this->ARC4($registry), false, false); + } + + $stream = <<> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> +endcodespacerange +1 beginbfrange +<0000> <0000> +endbfrange +endcmap +CMapName currentdict /CMap defineresource pop +end +end +EOT; + + $res = "\n$id 0 obj\n"; + $res .= "<>\n"; + $res .= "stream\n" . $stream . "\nendstream" . "\nendobj";; + + return $res; + } + + return null; + } + + /** + * a font descriptor, needed for including additional fonts + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_fontDescriptor($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontDescriptor', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /FontDescriptor\n"; + foreach ($o['info'] as $label => $value) { + switch ($label) { + case 'Ascent': + case 'CapHeight': + case 'Descent': + case 'Flags': + case 'ItalicAngle': + case 'StemV': + case 'AvgWidth': + case 'Leading': + case 'MaxWidth': + case 'MissingWidth': + case 'StemH': + case 'XHeight': + case 'CharSet': + if (mb_strlen($value, '8bit')) { + $res .= "/$label $value\n"; + } + + break; + case 'FontFile': + case 'FontFile2': + case 'FontFile3': + $res .= "/$label $value 0 R\n"; + break; + + case 'FontBBox': + $res .= "/$label [$value[0] $value[1] $value[2] $value[3]]\n"; + break; + + case 'FontName': + $res .= "/$label /$value\n"; + break; + } + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * the font encoding + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_fontEncoding($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // the options array should contain 'differences' and maybe 'encoding' + $this->objects[$id] = ['t' => 'fontEncoding', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Encoding\n"; + if (!isset($o['info']['encoding'])) { + $o['info']['encoding'] = 'WinAnsiEncoding'; + } + + if ($o['info']['encoding'] !== 'none') { + $res .= "/BaseEncoding /" . $o['info']['encoding'] . "\n"; + } + + $res .= "/Differences \n["; + + $onum = -100; + + foreach ($o['info']['differences'] as $num => $label) { + if ($num != $onum + 1) { + // we cannot make use of consecutive numbering + $res .= "\n$num /$label"; + } else { + $res .= " /$label"; + } + + $onum = $num; + } + + $res .= "\n]\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * a descendent cid font, needed for unicode fonts + * + * @param $id + * @param $action + * @param string|array $options + * @return null|string + */ + protected function o_fontDescendentCID($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontDescendentCID', 'info' => $options]; + + // we need a CID system info section + $cidSystemInfoId = ++$this->numObj; + $this->o_cidSystemInfo($cidSystemInfoId, 'new'); + $this->objects[$id]['info']['cidSystemInfo'] = $cidSystemInfoId; + + // and a CID to GID map + $cidToGidMapId = ++$this->numObj; + $this->o_fontGIDtoCIDMap($cidToGidMapId, 'new', $options); + $this->objects[$id]['info']['cidToGidMap'] = $cidToGidMapId; + break; + + case 'add': + foreach ($options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + + case 'FirstChar': + case 'LastChar': + case 'MissingWidth': + case 'FontDescriptor': + case 'SubType': + $this->addMessage("o_fontDescendentCID $k : $v"); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to cid to gid map + $this->o_fontGIDtoCIDMap($o['info']['cidToGidMap'], 'add', $options); + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $res .= "<fonts[$o['info']['fontFileName']]['CIDWidths'])) { + $cid_widths = &$this->fonts[$o['info']['fontFileName']]['CIDWidths']; + $w = ''; + foreach ($cid_widths as $cid => $width) { + $w .= "$cid [$width] "; + } + $res .= "/W [$w]\n"; + } + + $res .= "/CIDToGIDMap " . $o['info']['cidToGidMap'] . " 0 R\n"; + $res .= ">>\n"; + $res .= "endobj"; + + return $res; + } + + return null; + } + + /** + * CID system info section, needed for unicode fonts + * + * @param $id + * @param $action + * @return null|string + */ + protected function o_cidSystemInfo($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'cidSystemInfo' + ]; + break; + case 'add': + break; + case 'out': + $ordering = 'UCS'; + $registry = 'Adobe'; + + if ($this->encrypted) { + $this->encryptInit($id); + $ordering = $this->ARC4($ordering); + $registry = $this->ARC4($registry); + } + + + $res = "\n$id 0 obj\n"; + + $res .= '<objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'fontGIDtoCIDMap', 'info' => $options]; + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $fontFileName = $o['info']['fontFileName']; + $tmp = $this->fonts[$fontFileName]['CIDtoGID'] = base64_decode($this->fonts[$fontFileName]['CIDtoGID']); + + $compressed = isset($this->fonts[$fontFileName]['CIDtoGID_Compressed']) && + $this->fonts[$fontFileName]['CIDtoGID_Compressed']; + + if (!$compressed && isset($o['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + + if (!$compressed && $this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $compressed = true; + $tmp = gzcompress($tmp, 6); + } + if ($compressed) { + $res .= "\n/Filter /FlateDecode"; + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + + return null; + } + + /** + * the document procset, solves some problems with printing to old PS printers + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_procset($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'procset', 'info' => ['PDF' => 1, 'Text' => 1]]; + $this->o_pages($this->currentNode, 'procset', $id); + $this->procsetObjectId = $id; + break; + + case 'add': + // this is to add new items to the procset list, despite the fact that this is considered + // obsolete, the items are required for printing to some postscript printers + switch ($options) { + case 'ImageB': + case 'ImageC': + case 'ImageI': + $o['info'][$options] = 1; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n["; + foreach ($o['info'] as $label => $val) { + $res .= "/$label "; + } + $res .= "]\nendobj"; + + return $res; + } + + return null; + } + + /** + * define the document information + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_info($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->infoObject = $id; + $date = 'D:' . @date('Ymd'); + $this->objects[$id] = [ + 't' => 'info', + 'info' => [ + 'Producer' => 'CPDF (dompdf)', + 'CreationDate' => $date + ] + ]; + break; + case 'Title': + case 'Author': + case 'Subject': + case 'Keywords': + case 'Creator': + case 'Producer': + case 'CreationDate': + case 'ModDate': + case 'Trapped': + $this->objects[$id]['info'][$action] = $options; + break; + + case 'out': + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<<\n"; + $o = &$this->objects[$id]; + foreach ($o['info'] as $k => $v) { + $res .= "/$k ("; + + // dates must be outputted as-is, without Unicode transformations + if ($k !== 'CreationDate' && $k !== 'ModDate') { + $v = $this->filterText($v, true, false); + } + + if ($encrypted) { + $v = $this->ARC4($v); + } + + $res .= $v; + $res .= ")\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an action object, used to link to URLS initially + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_action($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + if (is_array($options)) { + $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => $options['type']]; + } else { + // then assume a URI action + $this->objects[$id] = ['t' => 'action', 'info' => $options, 'type' => 'URI']; + } + break; + + case 'out': + if ($this->encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<< /Type /Action"; + switch ($o['type']) { + case 'ilink': + if (!isset($this->destinations[(string)$o['info']['label']])) { + break; + } + + // there will be an 'label' setting, this is the name of the destination + $res .= "\n/S /GoTo\n/D " . $this->destinations[(string)$o['info']['label']] . " 0 R"; + break; + + case 'URI': + $res .= "\n/S /URI\n/URI ("; + if ($this->encrypted) { + $res .= $this->filterText($this->ARC4($o['info']), false, false); + } else { + $res .= $this->filterText($o['info'], false, false); + } + + $res .= ")"; + break; + } + + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an annotation object, this will add an annotation to the current page. + * initially will support just link annotations + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_annotation($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // add the annotation to the current page + $pageId = $this->currentPage; + $this->o_page($pageId, 'annot', $id); + + // and add the action object which is going to be required + switch ($options['type']) { + case 'link': + $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; + $this->numObj++; + $this->o_action($this->numObj, 'new', $options['url']); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + + case 'ilink': + // this is to a named internal link + $label = $options['label']; + $this->objects[$id] = ['t' => 'annotation', 'info' => $options]; + $this->numObj++; + $this->o_action($this->numObj, 'new', ['type' => 'ilink', 'label' => $label]); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Annot"; + switch ($o['info']['type']) { + case 'link': + case 'ilink': + $res .= "\n/Subtype /Link"; + break; + } + $res .= "\n/A " . $o['info']['actionId'] . " 0 R"; + $res .= "\n/Border [0 0 0]"; + $res .= "\n/H /I"; + $res .= "\n/Rect [ "; + + foreach ($o['info']['rect'] as $v) { + $res .= sprintf("%.4F ", $v); + } + + $res .= "]"; + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * a page object, it also creates a contents object to hold its contents + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_page($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->numPages++; + $this->objects[$id] = [ + 't' => 'page', + 'info' => [ + 'parent' => $this->currentNode, + 'pageNum' => $this->numPages, + 'mediaBox' => $this->objects[$this->currentNode]['info']['mediaBox'] + ] + ]; + + if (is_array($options)) { + // then this must be a page insertion, array should contain 'rid','pos'=[before|after] + $options['id'] = $id; + $this->o_pages($this->currentNode, 'page', $options); + } else { + $this->o_pages($this->currentNode, 'page', $id); + } + + $this->currentPage = $id; + //make a contents object to go with this page + $this->numObj++; + $this->o_contents($this->numObj, 'new', $id); + $this->currentContents = $this->numObj; + $this->objects[$id]['info']['contents'] = []; + $this->objects[$id]['info']['contents'][] = $this->numObj; + + $match = ($this->numPages % 2 ? 'odd' : 'even'); + foreach ($this->addLooseObjects as $oId => $target) { + if ($target === 'all' || $match === $target) { + $this->objects[$id]['info']['contents'][] = $oId; + } + } + break; + + case 'content': + $o['info']['contents'][] = $options; + break; + + case 'annot': + // add an annotation to this page + if (!isset($o['info']['annot'])) { + $o['info']['annot'] = []; + } + + // $options should contain the id of the annotation dictionary + $o['info']['annot'][] = $options; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Page"; + if (isset($o['info']['mediaBox'])) { + $tmp = $o['info']['mediaBox']; + $res .= "\n/MediaBox [" . sprintf( + '%.3F %.3F %.3F %.3F', + $tmp[0], + $tmp[1], + $tmp[2], + $tmp[3] + ) . ']'; + } + $res .= "\n/Parent " . $o['info']['parent'] . " 0 R"; + + if (isset($o['info']['annot'])) { + $res .= "\n/Annots ["; + foreach ($o['info']['annot'] as $aId) { + $res .= " $aId 0 R"; + } + $res .= " ]"; + } + + $count = count($o['info']['contents']); + if ($count == 1) { + $res .= "\n/Contents " . $o['info']['contents'][0] . " 0 R"; + } else { + if ($count > 1) { + $res .= "\n/Contents [\n"; + + // reverse the page contents so added objects are below normal content + //foreach (array_reverse($o['info']['contents']) as $cId) { + // Back to normal now that I've got transparency working --Benj + foreach ($o['info']['contents'] as $cId) { + $res .= "$cId 0 R\n"; + } + $res .= "]"; + } + } + + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * the contents objects hold all of the content which appears on pages + * + * @param $id + * @param $action + * @param string|array $options + * @return null|string + */ + protected function o_contents($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'contents', 'c' => '', 'info' => []]; + if (mb_strlen($options, '8bit') && intval($options)) { + // then this contents is the primary for a page + $this->objects[$id]['onPage'] = $options; + } else { + if ($options === 'raw') { + // then this page contains some other type of system object + $this->objects[$id]['raw'] = 1; + } + } + break; + + case 'add': + // add more options to the declaration + foreach ($options as $k => $v) { + $o['info'][$k] = $v; + } + + case 'out': + $tmp = $o['c']; + $res = "\n$id 0 obj\n"; + + if (isset($this->objects[$id]['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $res .= " /Filter /FlateDecode"; + $tmp = gzcompress($tmp, 6); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . " >>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @return string|null + */ + protected function o_embedjs($id, $action) + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'embedjs', + 'info' => [ + 'Names' => '[(EmbeddedJS) ' . ($id + 1) . ' 0 R]' + ] + ]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param string $code + * @return null|string + */ + protected function o_javascript($id, $action, $code = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = [ + 't' => 'javascript', + 'info' => [ + 'S' => '/JavaScript', + 'JS' => '(' . $this->filterText($code, true, false) . ')', + ] + ]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< "; + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + /** + * an image object, will be an XObject in the document, includes description and data + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_image($id, $action, $options = '') + { + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = ['t' => 'image', 'data' => &$options['data'], 'info' => []]; + + $info =& $this->objects[$id]['info']; + + $info['Type'] = '/XObject'; + $info['Subtype'] = '/Image'; + $info['Width'] = $options['iw']; + $info['Height'] = $options['ih']; + + if (isset($options['masked']) && $options['masked']) { + $info['SMask'] = ($this->numObj - 1) . ' 0 R'; + } + + if (!isset($options['type']) || $options['type'] === 'jpg') { + if (!isset($options['channels'])) { + $options['channels'] = 3; + } + + switch ($options['channels']) { + case 1: + $info['ColorSpace'] = '/DeviceGray'; + break; + case 4: + $info['ColorSpace'] = '/DeviceCMYK'; + break; + default: + $info['ColorSpace'] = '/DeviceRGB'; + break; + } + + if ($info['ColorSpace'] === '/DeviceCMYK') { + $info['Decode'] = '[1 0 1 0 1 0 1 0]'; + } + + $info['Filter'] = '/DCTDecode'; + $info['BitsPerComponent'] = 8; + } else { + if ($options['type'] === 'png') { + $info['Filter'] = '/FlateDecode'; + $info['DecodeParms'] = '<< /Predictor 15 /Colors ' . $options['ncolor'] . ' /Columns ' . $options['iw'] . ' /BitsPerComponent ' . $options['bitsPerComponent'] . '>>'; + + if ($options['isMask']) { + $info['ColorSpace'] = '/DeviceGray'; + } else { + if (mb_strlen($options['pdata'], '8bit')) { + $tmp = ' [ /Indexed /DeviceRGB ' . (mb_strlen($options['pdata'], '8bit') / 3 - 1) . ' '; + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->objects[$this->numObj]['c'] = $options['pdata']; + $tmp .= $this->numObj . ' 0 R'; + $tmp .= ' ]'; + $info['ColorSpace'] = $tmp; + + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . + $transparency['g'] . ' ' . $transparency['g'] . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + } else { + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . ' ' . + $transparency['g'] . ' ' . $transparency['g'] . ' ' . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + $info['ColorSpace'] = '/' . $options['color']; + } + } + + $info['BitsPerComponent'] = $options['bitsPerComponent']; + } + } + + // assign it a place in the named resource dictionary as an external object, according to + // the label passed in with it. + $this->o_pages($this->currentNode, 'xObject', ['label' => $options['label'], 'objNum' => $id]); + + // also make sure that we have the right procset object for it. + $this->o_procset($this->procsetObjectId, 'add', 'ImageC'); + break; + + case 'out': + $o = &$this->objects[$id]; + $tmp = &$o['data']; + $res = "\n$id 0 obj\n<<"; + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream\nendobj"; + + return $res; + } + + return null; + } + + /** + * graphics state object + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_extGState($id, $action, $options = "") + { + static $valid_params = [ + "LW", + "LC", + "LC", + "LJ", + "ML", + "D", + "RI", + "OP", + "op", + "OPM", + "Font", + "BG", + "BG2", + "UCR", + "TR", + "TR2", + "HT", + "FL", + "SM", + "SA", + "BM", + "SMask", + "CA", + "ca", + "AIS", + "TK" + ]; + + switch ($action) { + case "new": + $this->objects[$id] = ['t' => 'extGState', 'info' => $options]; + + // Tell the pages about the new resource + $this->numStates++; + $this->o_pages($this->currentNode, 'extGState', ["objNum" => $id, "stateNum" => $this->numStates]); + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /ExtGState\n"; + + foreach ($o["info"] as $k => $v) { + if (!in_array($k, $valid_params)) { + continue; + } + $res .= "/$k $v\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param integer $id + * @param string $action + * @param mixed $options + * @return string + */ + protected function o_xobject($id, $action, $options = '') + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'xobject', 'info' => $options, 'c' => '']; + break; + + case 'procset': + $this->objects[$id]['procset'] = $options; + break; + + case 'font': + $this->objects[$id]['fonts'][$options['fontNum']] = [ + 'objNum' => $options['objNum'], + 'fontNum' => $options['fontNum'] + ]; + break; + + case 'xObject': + $this->objects[$id]['xObjects'][] = ['objNum' => $options['objNum'], 'label' => $options['label']]; + break; + + case 'out': + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /XObject\n"; + + foreach ($o["info"] as $k => $v) { + switch($k) + { + case 'Subtype': + $res .= "/Subtype /$v\n"; + break; + case 'bbox': + $res .= "/BBox ["; + foreach ($v as $value) { + $res .= sprintf("%.4F ", $value); + } + $res .= "]\n"; + break; + default: + $res .= "/$k $v\n"; + break; + } + } + $res .= "/Matrix[1.0 0.0 0.0 1.0 0.0 0.0]\n"; + + $res .= "/Resources <<"; + if (isset($o['procset'])) { + $res .= "\n/ProcSet " . $o['procset'] . " 0 R"; + } else { + $res .= "\n/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]"; + } + if (isset($o['fonts']) && count($o['fonts'])) { + $res .= "\n/Font << "; + foreach ($o['fonts'] as $finfo) { + $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + if (isset($o['xObjects']) && count($o['xObjects'])) { + $res .= "\n/XObject << "; + foreach ($o['xObjects'] as $finfo) { + $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + $res .= "\n>>\n"; + + $tmp = $o["c"]; + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $res .= " /Filter /FlateDecode\n"; + $tmp = gzcompress($tmp, 6); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "/Length " . mb_strlen($tmp, '8bit') . " >>\n"; + $res .= "stream\n" . $tmp . "\nendstream" . "\nendobj";; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_acroform($id, $action, $options = '') + { + switch ($action) { + case "new": + $this->o_catalog($this->catalogId, 'acroform', $id); + $this->objects[$id] = array('t' => 'acroform', 'info' => $options); + break; + + case 'addfield': + $this->objects[$id]['info']['Fields'][] = $options; + break; + + case 'font': + $this->objects[$id]['fonts'][$options['fontNum']] = [ + 'objNum' => $options['objNum'], + 'fontNum' => $options['fontNum'] + ]; + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<<"; + + foreach ($o["info"] as $k => $v) { + switch($k) { + case 'Fields': + $res .= " /Fields ["; + foreach ($v as $i) { + $res .= "$i 0 R "; + } + $res .= "]\n"; + break; + default: + $res .= "/$k $v\n"; + } + } + + $res .= "/DR <<\n"; + if (isset($o['fonts']) && count($o['fonts'])) { + $res .= "/Font << \n"; + foreach ($o['fonts'] as $finfo) { + $res .= "/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R\n"; + } + $res .= ">>\n"; + } + $res .= ">>\n"; + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * @param $id + * @param $action + * @param mixed $options + * @return null|string + */ + protected function o_field($id, $action, $options = '') + { + switch ($action) { + case "new": + $this->o_page($options['pageid'], 'annot', $id); + $this->o_acroform($this->acroFormId, 'addfield', $id); + $this->objects[$id] = ['t' => 'field', 'info' => $options]; + break; + + case 'set': + $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); + break; + + case "out": + $o = &$this->objects[$id]; + $res = "\n$id 0 obj\n<< /Type /Annot /Subtype /Widget \n"; + + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + foreach ($o["info"] as $k => $v) { + switch ($k) { + case 'pageid': + $res .= "/P $v 0 R\n"; + break; + case 'value': + if ($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/V ($v)\n"; + break; + case 'refvalue': + $res .= "/V $v 0 R\n"; + break; + case 'da': + if ($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/DA ($v)\n"; + break; + case 'options': + $res .= "/Opt [\n"; + foreach ($v as $opt) { + if ($encrypted) { + $opt = $this->filterText($this->ARC4($opt), false, false); + } + $res .= "($opt)\n"; + } + $res .= "]\n"; + break; + case 'rect': + $res .= "/Rect ["; + foreach ($v as $value) { + $res .= sprintf("%.4F ", $value); + } + $res .= "]\n"; + break; + case 'appearance': + $res .= "/AP << "; + foreach ($v as $a => $ref) { + $res .= "/$a $ref 0 R "; + } + $res .= ">>\n"; + break; + case 'T': + if($encrypted) { + $v = $this->filterText($this->ARC4($v), false, false); + } + $res .= "/T ($v)\n"; + break; + default: + $res .= "/$k $v\n"; + } + + } + + $res .= ">>\nendobj"; + + return $res; + } + + return null; + + } + + /** + * + * @param $id + * @param $action + * @param string $options + * @return null|string + */ + protected function o_sig($id, $action, $options = '') + { + $sign_maxlen = $this->signatureMaxLen; + + switch ($action) { + case "new": + $this->objects[$id] = array('t' => 'sig', 'info' => $options); + $this->byteRange[$id] = ['t' => 'sig']; + break; + + case 'byterange': + $o = &$this->objects[$id]; + $content =& $options['content']; + $content_len = strlen($content); + $pos = strpos($content, sprintf("/ByteRange [ %'.010d", $id)); + $len = strlen('/ByteRange [ ********** ********** ********** ********** ]'); + $rangeStartPos = $pos + $len + 1 + 10; // before '<' + $content = substr_replace($content, str_pad(sprintf('/ByteRange [ 0 %u %u %u ]', $rangeStartPos, $rangeStartPos + $sign_maxlen + 2, $content_len - 2 - $sign_maxlen - $rangeStartPos ), $len, ' ', STR_PAD_RIGHT), $pos, $len); + + $fuid = uniqid(); + $tmpInput = $this->tmp . "/pkcs7.tmp." . $fuid . '.in'; + $tmpOutput = $this->tmp . "/pkcs7.tmp." . $fuid . '.out'; + + if (file_put_contents($tmpInput, substr($content, 0, $rangeStartPos)) === false) { + throw new \Exception("Unable to write temporary file for signing."); + } + if (file_put_contents($tmpInput, substr($content, $rangeStartPos + 2 + $sign_maxlen), + FILE_APPEND) === false) { + throw new \Exception("Unable to write temporary file for signing."); + } + + if (openssl_pkcs7_sign($tmpInput, $tmpOutput, + $o['info']['SignCert'], + array($o['info']['PrivKey'], $o['info']['Password']), + array(), PKCS7_BINARY | PKCS7_DETACHED) === false) { + throw new \Exception("Failed to prepare signature."); + } + + $signature = file_get_contents($tmpOutput); + + unlink($tmpInput); + unlink($tmpOutput); + + $sign = substr($signature, (strpos($signature, "%%EOF\n\n------") + 13)); + list($head, $signature) = explode("\n\n", $sign); + + $signature = base64_decode(trim($signature)); + + $signature = current(unpack('H*', $signature)); + $signature = str_pad($signature, $sign_maxlen, '0'); + $siglen = strlen($signature); + if (strlen($signature) > $sign_maxlen) { + throw new \Exception("Signature length ($siglen) exceeds the $sign_maxlen limit."); + } + + $content = substr_replace($content, $signature, $rangeStartPos + 1, $sign_maxlen); + break; + + case "out": + $res = "\n$id 0 obj\n<<\n"; + + $encrypted = $this->encrypted; + if ($encrypted) { + $this->encryptInit($id); + } + + $res .= "/ByteRange " .sprintf("[ %'.010d ********** ********** ********** ]\n", $id); + $res .= "/Contents <" . str_pad('', $sign_maxlen, '0') . ">\n"; + $res .= "/Filter/Adobe.PPKLite\n"; //PPKMS \n"; + $res .= "/Type/Sig/SubFilter/adbe.pkcs7.detached \n"; + + $date = "D:" . substr_replace(date('YmdHisO'), '\'', -2, 0) . '\''; + if ($encrypted) { + $date = $this->ARC4($date); + } + + $res .= "/M ($date)\n"; + $res .= "/Prop_Build << /App << /Name /DomPDF >> /Filter << /Name /Adobe.PPKLite >> >>\n"; + + $o = &$this->objects[$id]; + foreach ($o['info'] as $k => $v) { + switch($k) { + case 'Name': + case 'Location': + case 'Reason': + case 'ContactInfo': + if ($v !== null && $v !== '') { + $res .= "/$k (" . + ($encrypted ? $this->filterText($this->ARC4($v), false, false) : $v) . ") \n"; + } + break; + } + } + $res .= ">>\nendobj"; + + return $res; + } + + return null; + } + + /** + * encryption object. + * + * @param $id + * @param $action + * @param string $options + * @return string|null + */ + protected function o_encryption($id, $action, $options = '') + { + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = ['t' => 'encryption', 'info' => $options]; + $this->arc4_objnum = $id; + break; + + case 'keys': + // figure out the additional parameters required + $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41) + . chr(0x64) . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) + . chr(0x2E) . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) + . chr(0x2F) . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A); + + $info = $this->objects[$id]['info']; + + $len = mb_strlen($info['owner'], '8bit'); + + if ($len > 32) { + $owner = substr($info['owner'], 0, 32); + } else { + if ($len < 32) { + $owner = $info['owner'] . substr($pad, 0, 32 - $len); + } else { + $owner = $info['owner']; + } + } + + $len = mb_strlen($info['user'], '8bit'); + if ($len > 32) { + $user = substr($info['user'], 0, 32); + } else { + if ($len < 32) { + $user = $info['user'] . substr($pad, 0, 32 - $len); + } else { + $user = $info['user']; + } + } + + $tmp = $this->md5_16($owner); + $okey = substr($tmp, 0, 5); + $this->ARC4_init($okey); + $ovalue = $this->ARC4($user); + $this->objects[$id]['info']['O'] = $ovalue; + + // now make the u value, phew. + $tmp = $this->md5_16( + $user . $ovalue . chr($info['p']) . chr(255) . chr(255) . chr(255) . hex2bin($this->fileIdentifier) + ); + + $ukey = substr($tmp, 0, 5); + $this->ARC4_init($ukey); + $this->encryptionKey = $ukey; + $this->encrypted = true; + $uvalue = $this->ARC4($pad); + $this->objects[$id]['info']['U'] = $uvalue; + // initialize the arc4 array + break; + + case 'out': + $o = &$this->objects[$id]; + + $res = "\n$id 0 obj\n<<"; + $res .= "\n/Filter /Standard"; + $res .= "\n/V 1"; + $res .= "\n/R 2"; + $res .= "\n/O (" . $this->filterText($o['info']['O'], false, false) . ')'; + $res .= "\n/U (" . $this->filterText($o['info']['U'], false, false) . ')'; + // and the p-value needs to be converted to account for the twos-complement approach + $o['info']['p'] = (($o['info']['p'] ^ 255) + 1) * -1; + $res .= "\n/P " . ($o['info']['p']); + $res .= "\n>>\nendobj"; + + return $res; + } + + return null; + } + + protected function o_indirect_references($id, $action, $options = null) + { + switch ($action) { + case 'new': + case 'add': + if ($id === 0) { + $id = ++$this->numObj; + $this->o_catalog($this->catalogId, 'names', $id); + $this->objects[$id] = ['t' => 'indirect_references', 'info' => $options]; + $this->indirectReferenceId = $id; + } else { + $this->objects[$id]['info'] = array_merge($this->objects[$id]['info'], $options); + } + break; + case 'out': + $res = "\n$id 0 obj << "; + + foreach($this->objects[$id]['info'] as $referenceObjName => $referenceObjId) { + $res .= "/$referenceObjName $referenceObjId 0 R "; + } + + $res .= ">> endobj"; + return $res; + } + + return null; + } + + protected function o_names($id, $action, $options = null) + { + switch ($action) { + case 'new': + case 'add': + if ($id === 0) { + $id = ++$this->numObj; + $this->objects[$id] = ['t' => 'names', 'info' => [$options]]; + $this->o_indirect_references($this->indirectReferenceId, 'add', ['EmbeddedFiles' => $id]); + $this->embeddedFilesId = $id; + } else { + $this->objects[$id]['info'][] = $options; + } + break; + case 'out': + $info = &$this->objects[$id]['info']; + $res = ''; + if (count($info) > 0) { + $res = "\n$id 0 obj << /Names [ "; + + if ($this->encrypted) { + $this->encryptInit($id); + } + + foreach ($info as $entry) { + if ($this->encrypted) { + $filename = $this->ARC4($entry['filename']); + } else { + $filename = $entry['filename']; + } + + $res .= "($filename) " . $entry['dict_reference'] . " 0 R "; + } + + $res .= "] >> endobj"; + } + return $res; + } + + return null; + } + + protected function o_embedded_file_dictionary($id, $action, $options = null) + { + switch ($action) { + case 'new': + $embeddedFileId = ++$this->numObj; + $options['embedded_reference'] = $embeddedFileId; + $this->objects[$id] = ['t' => 'embedded_file_dictionary', 'info' => $options]; + $this->o_embedded_file($embeddedFileId, 'new', $options); + $options['dict_reference'] = $id; + $this->o_names($this->embeddedFilesId, 'add', $options); + break; + case 'out': + $info = &$this->objects[$id]['info']; + + if ($this->encrypted) { + $this->encryptInit($id); + $filename = $this->ARC4($info['filename']); + $description = $this->ARC4($info['description']); + } else { + $filename = $info['filename']; + $description = $info['description']; + } + + $res = "\n$id 0 obj <>"; + $res .= " /F ($filename) /UF ($filename) /Desc ($description)"; + $res .= " >> endobj"; + return $res; + } + + return null; + } + + protected function o_embedded_file($id, $action, $options = null): ?string + { + switch ($action) { + case 'new': + $this->objects[$id] = ['t' => 'embedded_file', 'info' => $options]; + break; + case 'out': + $info = &$this->objects[$id]['info']; + + if ($this->compressionReady) { + $filepath = $info['filepath']; + $checksum = md5_file($filepath); + $f = fopen($filepath, "rb"); + + $file_content_compressed = ''; + $deflateContext = deflate_init(ZLIB_ENCODING_DEFLATE, ['level' => 6]); + while (($block = fread($f, 8192))) { + $file_content_compressed .= deflate_add($deflateContext, $block, ZLIB_NO_FLUSH); + } + $file_content_compressed .= deflate_add($deflateContext, '', ZLIB_FINISH); + $file_size_uncompressed = ftell($f); + fclose($f); + } else { + $file_content = file_get_contents($info['filepath']); + $file_size_uncompressed = mb_strlen($file_content, '8bit'); + $checksum = md5($file_content); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $checksum = $this->ARC4($checksum); + $file_content_compressed = $this->ARC4($file_content_compressed); + } + $file_size_compressed = mb_strlen($file_content_compressed, '8bit'); + + $res = "\n$id 0 obj <>" . + " /Type/EmbeddedFile /Filter/FlateDecode" . + " /Length $file_size_compressed >> stream\n$file_content_compressed\nendstream\nendobj"; + + return $res; + } + + return null; + } + + /** + * ARC4 functions + * A series of function to implement ARC4 encoding in PHP + */ + + /** + * calculate the 16 byte version of the 128 bit md5 digest of the string + * + * @param $string + * @return string + */ + function md5_16($string) + { + $tmp = md5($string); + $out = ''; + for ($i = 0; $i <= 30; $i = $i + 2) { + $out .= chr(hexdec(substr($tmp, $i, 2))); + } + + return $out; + } + + /** + * initialize the encryption for processing a particular object + * + * @param $id + */ + function encryptInit($id) + { + $tmp = $this->encryptionKey; + $hex = dechex($id); + if (mb_strlen($hex, '8bit') < 6) { + $hex = substr('000000', 0, 6 - mb_strlen($hex, '8bit')) . $hex; + } + $tmp .= chr(hexdec(substr($hex, 4, 2))) + . chr(hexdec(substr($hex, 2, 2))) + . chr(hexdec(substr($hex, 0, 2))) + . chr(0) + . chr(0) + ; + $key = $this->md5_16($tmp); + $this->ARC4_init(substr($key, 0, 10)); + } + + /** + * initialize the ARC4 encryption + * + * @param string $key + */ + function ARC4_init($key = '') + { + $this->arc4 = ''; + + // setup the control array + if (mb_strlen($key, '8bit') == 0) { + return; + } + + $k = ''; + while (mb_strlen($k, '8bit') < 256) { + $k .= $key; + } + + $k = substr($k, 0, 256); + for ($i = 0; $i < 256; $i++) { + $this->arc4 .= chr($i); + } + + $j = 0; + + for ($i = 0; $i < 256; $i++) { + $t = $this->arc4[$i]; + $j = ($j + ord($t) + ord($k[$i])) % 256; + $this->arc4[$i] = $this->arc4[$j]; + $this->arc4[$j] = $t; + } + } + + /** + * ARC4 encrypt a text string + * + * @param $text + * @return string + */ + function ARC4($text) + { + $len = mb_strlen($text, '8bit'); + $a = 0; + $b = 0; + $c = $this->arc4; + $out = ''; + for ($i = 0; $i < $len; $i++) { + $a = ($a + 1) % 256; + $t = $c[$a]; + $b = ($b + ord($t)) % 256; + $c[$a] = $c[$b]; + $c[$b] = $t; + $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]); + $out .= chr(ord($text[$i]) ^ $k); + } + + return $out; + } + + /** + * functions which can be called to adjust or add to the document + */ + + /** + * add a link in the document to an external URL + * + * @param $url + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + */ + function addLink($url, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = ['type' => 'link', 'url' => $url, 'rect' => [$x0, $y0, $x1, $y1]]; + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * add a link in the document to an internal destination (ie. within the document) + * + * @param $label + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + */ + function addInternalLink($label, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = ['type' => 'ilink', 'label' => $label, 'rect' => [$x0, $y0, $x1, $y1]]; + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * set the encryption of the document + * can be used to turn it on and/or set the passwords which it will have. + * also the functions that the user will have are set here, such as print, modify, add + * + * @param string $userPass + * @param string $ownerPass + * @param array $pc + */ + function setEncryption($userPass = '', $ownerPass = '', $pc = []) + { + $p = bindec("11000000"); + + $options = ['print' => 4, 'modify' => 8, 'copy' => 16, 'add' => 32]; + + foreach ($pc as $k => $v) { + if ($v && isset($options[$k])) { + $p += $options[$k]; + } else { + if (isset($options[$v])) { + $p += $options[$v]; + } + } + } + + // implement encryption on the document + if ($this->arc4_objnum == 0) { + // then the block does not exist already, add it. + $this->numObj++; + if (mb_strlen($ownerPass) == 0) { + $ownerPass = $userPass; + } + + $this->o_encryption($this->numObj, 'new', ['user' => $userPass, 'owner' => $ownerPass, 'p' => $p]); + } + } + + /** + * should be used for internal checks, not implemented as yet + */ + function checkAllHere() + { + } + + /** + * return the pdf stream as a string returned from the function + * + * @param bool $debug + * @return string + */ + function output($debug = false) + { + if ($debug) { + // turn compression off + $this->options['compression'] = false; + } + + if ($this->javascript) { + $this->numObj++; + + $js_id = $this->numObj; + $this->o_embedjs($js_id, 'new'); + $this->o_javascript(++$this->numObj, 'new', $this->javascript); + + $id = $this->catalogId; + + $this->o_indirect_references($this->indirectReferenceId, 'add', ['Javascript' => $js_id]); + } + + if ($this->fileIdentifier === '') { + $tmp = implode('', $this->objects[$this->infoObject]['info']); + $this->fileIdentifier = md5('DOMPDF' . __FILE__ . $tmp . microtime() . mt_rand()); + } + + if ($this->arc4_objnum) { + $this->o_encryption($this->arc4_objnum, 'keys'); + $this->ARC4_init($this->encryptionKey); + } + + $this->checkAllHere(); + + $xref = []; + $content = '%PDF-1.7'; + $pos = mb_strlen($content, '8bit'); + + // pre-process o_font objects before output of all objects + foreach ($this->objects as $k => $v) { + if ($v['t'] === 'font') { + $this->o_font($k, 'add'); + } + } + + foreach ($this->objects as $k => $v) { + $tmp = 'o_' . $v['t']; + $cont = $this->$tmp($k, 'out'); + $content .= $cont; + $xref[] = $pos + 1; //+1 to account for \n at the start of each object + $pos += mb_strlen($cont, '8bit'); + } + + $content .= "\nxref\n0 " . (count($xref) + 1) . "\n0000000000 65535 f \n"; + + foreach ($xref as $p) { + $content .= str_pad($p, 10, "0", STR_PAD_LEFT) . " 00000 n \n"; + } + + $content .= "trailer\n<<\n" . + '/Size ' . (count($xref) + 1) . "\n" . + '/Root 1 0 R' . "\n" . + '/Info ' . $this->infoObject . " 0 R\n" + ; + + // if encryption has been applied to this document then add the marker for this dictionary + if ($this->arc4_objnum > 0) { + $content .= '/Encrypt ' . $this->arc4_objnum . " 0 R\n"; + } + + $content .= '/ID[<' . $this->fileIdentifier . '><' . $this->fileIdentifier . ">]\n"; + + // account for \n added at start of xref table + $pos++; + + $content .= ">>\nstartxref\n$pos\n%%EOF\n"; + + if (count($this->byteRange) > 0) { + foreach ($this->byteRange as $k => $v) { + $tmp = 'o_' . $v['t']; + $this->$tmp($k, 'byterange', ['content' => &$content]); + } + } + + return $content; + } + + /** + * initialize a new document + * if this is called on an existing document results may be unpredictable, but the existing document would be lost at minimum + * this function is called automatically by the constructor function + * + * @param array $pageSize + */ + private function newDocument($pageSize = [0, 0, 612, 792]) + { + $this->numObj = 0; + $this->objects = []; + + $this->numObj++; + $this->o_catalog($this->numObj, 'new'); + + $this->numObj++; + $this->o_outlines($this->numObj, 'new'); + + $this->numObj++; + $this->o_pages($this->numObj, 'new'); + + $this->o_pages($this->numObj, 'mediaBox', $pageSize); + $this->currentNode = 3; + + $this->numObj++; + $this->o_procset($this->numObj, 'new'); + + $this->numObj++; + $this->o_info($this->numObj, 'new'); + + $this->numObj++; + $this->o_page($this->numObj, 'new'); + + // need to store the first page id as there is no way to get it to the user during + // startup + $this->firstPageId = $this->currentContents; + } + + /** + * open the font file and return a php structure containing it. + * first check if this one has been done before and saved in a form more suited to php + * note that if a php serialized version does not exist it will try and make one, but will + * require write access to the directory to do it... it is MUCH faster to have these serialized + * files. + * + * @param $font + */ + private function openFont($font) + { + // assume that $font contains the path and file but not the extension + $name = basename($font); + $dir = dirname($font) . '/'; + + $fontcache = $this->fontcache; + if ($fontcache == '') { + $fontcache = rtrim($dir, DIRECTORY_SEPARATOR."/\\"); + } + + //$name filename without folder and extension of font metrics + //$dir folder of font metrics + //$fontcache folder of runtime created php serialized version of font metrics. + // If this is not given, the same folder as the font metrics will be used. + // Storing and reusing serialized versions improves speed much + + $this->addMessage("openFont: $font - $name"); + + if (!$this->isUnicode || in_array(mb_strtolower(basename($name)), self::$coreFonts)) { + $metrics_name = "$name.afm"; + } else { + $metrics_name = "$name.ufm"; + } + + $cache_name = "$metrics_name.php"; + $this->addMessage("metrics: $metrics_name, cache: $cache_name"); + + if (file_exists($fontcache . '/' . $cache_name)) { + $this->addMessage("openFont: php file exists $fontcache/$cache_name"); + $this->fonts[$font] = require($fontcache . '/' . $cache_name); + + if (!isset($this->fonts[$font]['_version_']) || $this->fonts[$font]['_version_'] != $this->fontcacheVersion) { + // if the font file is old, then clear it out and prepare for re-creation + $this->addMessage('openFont: clear out, make way for new version.'); + $this->fonts[$font] = null; + unset($this->fonts[$font]); + } + } else { + $old_cache_name = "php_$metrics_name"; + if (file_exists($fontcache . '/' . $old_cache_name)) { + $this->addMessage( + "openFont: php file doesn't exist $fontcache/$cache_name, creating it from the old format" + ); + $old_cache = file_get_contents($fontcache . '/' . $old_cache_name); + file_put_contents($fontcache . '/' . $cache_name, 'openFont($font); + return; + } + } + + if (!isset($this->fonts[$font]) && file_exists($dir . $metrics_name)) { + // then rebuild the php_.afm file from the .afm file + $this->addMessage("openFont: build php file from $dir$metrics_name"); + $data = []; + + // 20 => 'space' + $data['codeToName'] = []; + + // Since we're not going to enable Unicode for the core fonts we need to use a font-based + // setting for Unicode support rather than a global setting. + $data['isUnicode'] = (strtolower(substr($metrics_name, -3)) !== 'afm'); + + $cidtogid = ''; + if ($data['isUnicode']) { + $cidtogid = str_pad('', 256 * 256 * 2, "\x00"); + } + + $file = file($dir . $metrics_name); + + foreach ($file as $rowA) { + $row = trim($rowA); + $pos = strpos($row, ' '); + + if ($pos) { + // then there must be some keyword + $key = substr($row, 0, $pos); + switch ($key) { + case 'FontName': + case 'FullName': + case 'FamilyName': + case 'PostScriptName': + case 'Weight': + case 'ItalicAngle': + case 'IsFixedPitch': + case 'CharacterSet': + case 'UnderlinePosition': + case 'UnderlineThickness': + case 'Version': + case 'EncodingScheme': + case 'CapHeight': + case 'XHeight': + case 'Ascender': + case 'Descender': + case 'StdHW': + case 'StdVW': + case 'StartCharMetrics': + case 'FontHeightOffset': // OAR - Added so we can offset the height calculation of a Windows font. Otherwise it's too big. + $data[$key] = trim(substr($row, $pos)); + break; + + case 'FontBBox': + $data[$key] = explode(' ', trim(substr($row, $pos))); + break; + + //C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; + case 'C': // Found in AFM files + $bits = explode(';', trim($row)); + $dtmp = ['C' => null, 'N' => null, 'WX' => null, 'B' => []]; + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') == 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = []; + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['C']; + $n = $dtmp['N']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + if (!ctype_xdigit($n) || $c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } elseif (isset($n)) { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + // U 827 ; WX 0 ; N squaresubnosp ; G 675 ; + case 'U': // Found in UFM files + if (!$data['isUnicode']) { + break; + } + + $bits = explode(';', trim($row)); + $dtmp = ['G' => null, 'N' => null, 'U' => null, 'WX' => null]; + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') === 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = []; + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['U']; + $n = $dtmp['N']; + $glyph = $dtmp['G']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + // Set values in CID to GID map + if ($c >= 0 && $c < 0xFFFF && $glyph) { + $cidtogid[$c * 2] = chr($glyph >> 8); + $cidtogid[$c * 2 + 1] = chr($glyph & 0xFF); + } + + if (!ctype_xdigit($n) || $c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } elseif (isset($n)) { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c === -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + case 'KPX': + break; // don't include them as they are not used yet + //KPX Adieresis yacute -40 + /*$bits = explode(' ', trim($row)); + $data['KPX'][$bits[1]][$bits[2]] = $bits[3]; + break;*/ + } + } + } + + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on CIDtoGID string + $data['CIDtoGID_Compressed'] = true; + $cidtogid = gzcompress($cidtogid, 6); + } + $data['CIDtoGID'] = base64_encode($cidtogid); + $data['_version_'] = $this->fontcacheVersion; + $this->fonts[$font] = $data; + + //Because of potential trouble with php safe mode, expect that the folder already exists. + //If not existing, this will hit performance because of missing cached results. + if (is_dir($fontcache) && is_writable($fontcache)) { + file_put_contents($fontcache . '/' . $cache_name, 'fonts[$font])) { + $this->addMessage("openFont: no font file found for $font. Do you need to run load_font.php?"); + } + + //pre_r($this->messages); + } + + /** + * if the font is not loaded then load it and make the required object + * else just make it the current font + * the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding' + * note that encoding='none' will need to be used for symbolic fonts + * and 'differences' => an array of mappings between numbers 0->255 and character names. + * + * @param $fontName + * @param string $encoding + * @param bool $set + * @param bool $isSubsetting + * @return int + * @throws FontNotFoundException + */ + function selectFont($fontName, $encoding = '', $set = true, $isSubsetting = true) + { + $ext = substr($fontName, -4); + if ($ext === '.afm' || $ext === '.ufm') { + $fontName = substr($fontName, 0, mb_strlen($fontName) - 4); + } + + if (!isset($this->fonts[$fontName])) { + $this->addMessage("selectFont: selecting - $fontName - $encoding, $set"); + + // load the file + $this->openFont($fontName); + + if (isset($this->fonts[$fontName])) { + $this->numObj++; + $this->numFonts++; + + $font = &$this->fonts[$fontName]; + + $name = basename($fontName); + $options = ['name' => $name, 'fontFileName' => $fontName, 'isSubsetting' => $isSubsetting]; + + if (is_array($encoding)) { + // then encoding and differences might be set + if (isset($encoding['encoding'])) { + $options['encoding'] = $encoding['encoding']; + } + + if (isset($encoding['differences'])) { + $options['differences'] = $encoding['differences']; + } + } else { + if (mb_strlen($encoding, '8bit')) { + // then perhaps only the encoding has been set + $options['encoding'] = $encoding; + } + } + + $this->o_font($this->numObj, 'new', $options); + + if (file_exists("$fontName.ttf")) { + $fileSuffix = 'ttf'; + } elseif (file_exists("$fontName.TTF")) { + $fileSuffix = 'TTF'; + } elseif (file_exists("$fontName.pfb")) { + $fileSuffix = 'pfb'; + } elseif (file_exists("$fontName.PFB")) { + $fileSuffix = 'PFB'; + } else { + $fileSuffix = ''; + } + + $font['fileSuffix'] = $fileSuffix; + + $font['fontNum'] = $this->numFonts; + $font['isSubsetting'] = $isSubsetting && $font['isUnicode'] && strtolower($fileSuffix) === 'ttf'; + + // also set the differences here, note that this means that these will take effect only the + //first time that a font is selected, else they are ignored + if (isset($options['differences'])) { + $font['differences'] = $options['differences']; + } + } + } + + if ($set && isset($this->fonts[$fontName])) { + // so if for some reason the font was not set in the last one then it will not be selected + $this->currentBaseFont = $fontName; + + // the next lines mean that if a new font is selected, then the current text state will be + // applied to it as well. + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + } + + return $this->currentFontNum; + } + + /** + * sets up the current font, based on the font families, and the current text state + * note that this system is quite flexible, a bold-italic font can be completely different to a + * italic-bold font, and even bold-bold will have to be defined within the family to have meaning + * This function is to be called whenever the currentTextState is changed, it will update + * the currentFont setting to whatever the appropriate family one is. + * If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont + * This function will change the currentFont to whatever it should be, but will not change the + * currentBaseFont. + */ + private function setCurrentFont() + { + // if (strlen($this->currentBaseFont) == 0){ + // // then assume an initial font + // $this->selectFont($this->defaultFont); + // } + // $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1); + // if (strlen($this->currentTextState) + // && isset($this->fontFamilies[$cf]) + // && isset($this->fontFamilies[$cf][$this->currentTextState])){ + // // then we are in some state or another + // // and this font has a family, and the current setting exists within it + // // select the font, then return it + // $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState]; + // $this->selectFont($nf,'',0); + // $this->currentFont = $nf; + // $this->currentFontNum = $this->fonts[$nf]['fontNum']; + // } else { + // // the this font must not have the right family member for the current state + // // simply assume the base font + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + // } + } + + /** + * function for the user to find out what the ID is of the first page that was created during + * startup - useful if they wish to add something to it later. + * + * @return int + */ + function getFirstPageId() + { + return $this->firstPageId; + } + + /** + * add content to the currently active object + * + * @param $content + */ + private function addContent($content) + { + $this->objects[$this->currentContents]['c'] .= $content; + } + + /** + * sets the color for fill operations + * + * @param $color + * @param bool $force + */ + function setColor($color, $force = false) + { + $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; + + if (!$force && $this->currentColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + $this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F k", $this->currentColor)); + } else { + if (isset($new_color[2])) { + $this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F rg", $this->currentColor)); + } + } + } + + /** + * sets the color for fill operations + * + * @param $fillRule + */ + function setFillRule($fillRule) + { + if (!in_array($fillRule, ["nonzero", "evenodd"])) { + return; + } + + $this->fillRule = $fillRule; + } + + /** + * sets the color for stroke operations + * + * @param $color + * @param bool $force + */ + function setStrokeColor($color, $force = false) + { + $new_color = [$color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null]; + + if (!$force && $this->currentStrokeColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + $this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F K", $this->currentStrokeColor)); + } else { + if (isset($new_color[2])) { + $this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F RG", $this->currentStrokeColor)); + } + } + } + + /** + * Set the graphics state for compositions + * + * @param $parameters + */ + function setGraphicsState($parameters) + { + // Create a new graphics state object if necessary + if (($gstate = array_search($parameters, $this->gstates)) === false) { + $this->numObj++; + $this->o_extGState($this->numObj, 'new', $parameters); + $gstate = $this->numStates; + $this->gstates[$gstate] = $parameters; + } + $this->addContent("\n/GS$gstate gs"); + } + + /** + * Set current blend mode & opacity for lines. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setLineTransparency($mode, $opacity) + { + static $blend_modes = [ + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ]; + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + // Only create a new graphics state if required + if ($mode === $this->currentLineTransparency["mode"] && + $opacity == $this->currentLineTransparency["opacity"] + ) { + return; + } + + $this->currentLineTransparency["mode"] = $mode; + $this->currentLineTransparency["opacity"] = $opacity; + + $options = [ + "BM" => "/$mode", + "CA" => (float)$opacity + ]; + + $this->setGraphicsState($options); + } + + /** + * Set current blend mode & opacity for filled objects. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setFillTransparency($mode, $opacity) + { + static $blend_modes = [ + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ]; + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + if ($mode === $this->currentFillTransparency["mode"] && + $opacity == $this->currentFillTransparency["opacity"] + ) { + return; + } + + $this->currentFillTransparency["mode"] = $mode; + $this->currentFillTransparency["opacity"] = $opacity; + + $options = [ + "BM" => "/$mode", + "ca" => (float)$opacity, + ]; + + $this->setGraphicsState($options); + } + + /** + * draw a line from one set of coordinates to another + * + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param bool $stroke + */ + function line($x1, $y1, $x2, $y2, $stroke = true) + { + $this->addContent(sprintf("\n%.3F %.3F m %.3F %.3F l", $x1, $y1, $x2, $y2)); + + if ($stroke) { + $this->addContent(' S'); + } + } + + /** + * draw a bezier curve based on 4 control points + * + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param $x3 + * @param $y3 + */ + function curve($x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) + { + // in the current line style, draw a bezier curve from (x0,y0) to (x3,y3) using the other two points + // as the control points for the curve. + $this->addContent( + sprintf("\n%.3F %.3F m %.3F %.3F %.3F %.3F %.3F %.3F c S", $x0, $y0, $x1, $y1, $x2, $y2, $x3, $y3) + ); + } + + /** + * draw a part of an ellipse + * + * @param $x0 + * @param $y0 + * @param $astart + * @param $afinish + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + */ + function partEllipse($x0, $y0, $astart, $afinish, $r1, $r2 = 0, $angle = 0, $nSeg = 8) + { + $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, false); + } + + /** + * draw a filled ellipse + * + * @param $x0 + * @param $y0 + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + * @param int $astart + * @param int $afinish + */ + function filledEllipse($x0, $y0, $r1, $r2 = 0, $angle = 0, $nSeg = 8, $astart = 0, $afinish = 360) + { + $this->ellipse($x0, $y0, $r1, $r2, $angle, $nSeg, $astart, $afinish, true, true); + } + + /** + * @param $x + * @param $y + */ + function lineTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F l", $x, $y)); + } + + /** + * @param $x + * @param $y + */ + function moveTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F m", $x, $y)); + } + + /** + * draw a bezier curve based on 4 control points + * + * @param $x1 + * @param $y1 + * @param $x2 + * @param $y2 + * @param $x3 + * @param $y3 + */ + function curveTo($x1, $y1, $x2, $y2, $x3, $y3) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F %.3F %.3F c", $x1, $y1, $x2, $y2, $x3, $y3)); + } + + /** + * draw a bezier curve based on 4 control points + */ + function quadTo($cpx, $cpy, $x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F v", $cpx, $cpy, $x, $y)); + } + + function closePath() + { + $this->addContent(' h'); + } + + function endPath() + { + $this->addContent(' n'); + } + + /** + * draw an ellipse + * note that the part and filled ellipse are just special cases of this function + * + * draws an ellipse in the current line style + * centered at $x0,$y0, radii $r1,$r2 + * if $r2 is not set, then a circle is drawn + * from $astart to $afinish, measured in degrees, running anti-clockwise from the right hand side of the ellipse. + * nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a + * pretty crappy shape at 2, as we are approximating with bezier curves. + * + * @param $x0 + * @param $y0 + * @param $r1 + * @param int $r2 + * @param int $angle + * @param int $nSeg + * @param int $astart + * @param int $afinish + * @param bool $close + * @param bool $fill + * @param bool $stroke + * @param bool $incomplete + */ + function ellipse( + $x0, + $y0, + $r1, + $r2 = 0, + $angle = 0, + $nSeg = 8, + $astart = 0, + $afinish = 360, + $close = true, + $fill = false, + $stroke = true, + $incomplete = false + ) { + if ($r1 == 0) { + return; + } + + if ($r2 == 0) { + $r2 = $r1; + } + + if ($nSeg < 2) { + $nSeg = 2; + } + + $astart = deg2rad((float)$astart); + $afinish = deg2rad((float)$afinish); + $totalAngle = $afinish - $astart; + + $dt = $totalAngle / $nSeg; + $dtm = $dt / 3; + + if ($angle != 0) { + $a = -1 * deg2rad((float)$angle); + + $this->addContent( + sprintf("\n q %.3F %.3F %.3F %.3F %.3F %.3F cm", cos($a), -sin($a), sin($a), cos($a), $x0, $y0) + ); + + $x0 = 0; + $y0 = 0; + } + + $t1 = $astart; + $a0 = $x0 + $r1 * cos($t1); + $b0 = $y0 + $r2 * sin($t1); + $c0 = -$r1 * sin($t1); + $d0 = $r2 * cos($t1); + + if (!$incomplete) { + $this->addContent(sprintf("\n%.3F %.3F m ", $a0, $b0)); + } + + for ($i = 1; $i <= $nSeg; $i++) { + // draw this bit of the total curve + $t1 = $i * $dt + $astart; + $a1 = $x0 + $r1 * cos($t1); + $b1 = $y0 + $r2 * sin($t1); + $c1 = -$r1 * sin($t1); + $d1 = $r2 * cos($t1); + + $this->addContent( + sprintf( + "\n%.3F %.3F %.3F %.3F %.3F %.3F c", + ($a0 + $c0 * $dtm), + ($b0 + $d0 * $dtm), + ($a1 - $c1 * $dtm), + ($b1 - $d1 * $dtm), + $a1, + $b1 + ) + ); + + $a0 = $a1; + $b0 = $b1; + $c0 = $c1; + $d0 = $d1; + } + + if (!$incomplete) { + if ($fill) { + $this->addContent(' f'); + } + + if ($stroke) { + if ($close) { + $this->addContent(' s'); // small 's' signifies closing the path as well + } else { + $this->addContent(' S'); + } + } + } + + if ($angle != 0) { + $this->addContent(' Q'); + } + } + + /** + * this sets the line drawing style. + * width, is the thickness of the line in user units + * cap is the type of cap to put on the line, values can be 'butt','round','square' + * where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the + * end of the line. + * join can be 'miter', 'round', 'bevel' + * dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the + * on and off dashes. + * (2) represents 2 on, 2 off, 2 on , 2 off ... + * (2,1) is 2 on, 1 off, 2 on, 1 off.. etc + * phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. + * + * @param int $width + * @param string $cap + * @param string $join + * @param string $dash + * @param int $phase + */ + function setLineStyle($width = 1, $cap = '', $join = '', $dash = '', $phase = 0) + { + // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day + $string = ''; + + if ($width > 0) { + $string .= "$width w"; + } + + $ca = ['butt' => 0, 'round' => 1, 'square' => 2]; + + if (isset($ca[$cap])) { + $string .= " $ca[$cap] J"; + } + + $ja = ['miter' => 0, 'round' => 1, 'bevel' => 2]; + + if (isset($ja[$join])) { + $string .= " $ja[$join] j"; + } + + if (is_array($dash)) { + $string .= ' [ ' . implode(' ', $dash) . " ] $phase d"; + } + + $this->currentLineStyle = $string; + $this->addContent("\n$string"); + } + + /** + * draw a polygon, the syntax for this is similar to the GD polygon command + * + * @param $p + * @param $np + * @param bool $f + */ + function polygon($p, $np, $f = false) + { + $this->addContent(sprintf("\n%.3F %.3F m ", $p[0], $p[1])); + + for ($i = 2; $i < $np * 2; $i = $i + 2) { + $this->addContent(sprintf("%.3F %.3F l ", $p[$i], $p[$i + 1])); + } + + if ($f) { + $this->addContent(' f'); + } else { + $this->addContent(' S'); + } + } + + /** + * a filled rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function filledRectangle($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re f", $x1, $y1, $width, $height)); + } + + /** + * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function rectangle($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re S", $x1, $y1, $width, $height)); + } + + /** + * draw a rectangle, note that it is the width and height of the rectangle which are the secondary parameters, not + * the coordinates of the upper-right corner + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function rect($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re", $x1, $y1, $width, $height)); + } + + function stroke() + { + $this->addContent("\nS"); + } + + function fill() + { + $this->addContent("\nf" . ($this->fillRule === "evenodd" ? "*" : "")); + } + + function fillStroke() + { + $this->addContent("\nb" . ($this->fillRule === "evenodd" ? "*" : "")); + } + + /** + * @param string $subtype + * @param integer $x + * @param integer $y + * @param integer $w + * @param integer $h + * @return int + */ + function addXObject($subtype, $x, $y, $w, $h) + { + $id = ++$this->numObj; + $this->o_xobject($id, 'new', ['Subtype' => $subtype, 'bbox' => [$x, $y, $w, $h]]); + return $id; + } + + /** + * @param integer $numXObject + * @param string $type + * @param array $options + */ + function setXObjectResource($numXObject, $type, $options) + { + if (in_array($type, ['procset', 'font', 'xObject'])) { + $this->o_xobject($numXObject, $type, $options); + } + } + + /** + * add signature + * + * $fieldSigId = $cpdf->addFormField(Cpdf::ACROFORM_FIELD_SIG, 'Signature1', 0, 0, 0, 0, 0); + * + * $signatureId = $cpdf->addSignature([ + * 'signcert' => file_get_contents('dompdf.crt'), + * 'privkey' => file_get_contents('dompdf.key'), + * 'password' => 'password', + * 'name' => 'DomPDF DEMO', + * 'location' => 'Home', + * 'reason' => 'First Form', + * 'contactinfo' => 'info' + * ]); + * $cpdf->setFormFieldValue($fieldSigId, "$signatureId 0 R"); + * + * @param string $signcert + * @param string $privkey + * @param string $password + * @param string|null $name + * @param string|null $location + * @param string|null $reason + * @param string|null $contactinfo + * @return int + */ + function addSignature($signcert, $privkey, $password = '', + $name = null, $location = null, $reason = null, $contactinfo = null + ) { + $sigId = ++$this->numObj; + $this->o_sig($sigId, 'new', [ + 'SignCert' => $signcert, + 'PrivKey' => $privkey, + 'Password' => $password, + 'Name' => $name, + 'Location' => $location, + 'Reason' => $reason, + 'ContactInfo' => $contactinfo + ]); + + return $sigId; + } + + /** + * add field to form + * + * @param string $type ACROFORM_FIELD_* + * @param string $name + * @param $x0 + * @param $y0 + * @param $x1 + * @param $y1 + * @param integer $ff Field Flag ACROFORM_FIELD_*_* + * @param float $size + * @param array $color + * @return int + */ + public function addFormField($type, $name, $x0, $y0, $x1, $y1, $ff = 0, $size = 10.0, $color = [0, 0, 0]) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $color = implode(' ', $color) . ' rg'; + + $currentFontNum = $this->currentFontNum; + $font = array_filter($this->objects[$this->currentNode]['info']['fonts'], + function($item) use ($currentFontNum) { return $item['fontNum'] == $currentFontNum; }); + + $this->o_acroform($this->acroFormId, 'font', + ['objNum' => $font[0]['objNum'], 'fontNum' => $font[0]['fontNum']]); + + $fieldId = ++$this->numObj; + $this->o_field($fieldId, 'new', [ + 'rect' => [$x0, $y0, $x1, $y1], + 'F' => 4, + 'FT' => "/$type", + 'T' => $name, + 'Ff' => $ff, + 'pageid' => $this->currentPage, + 'da' => "$color /F$this->currentFontNum " . sprintf('%.1F Tf ', $size) + ]); + + return $fieldId; + } + + /** + * set Field value + * + * @param integer $numFieldObj + * @param string $value + */ + public function setFormFieldValue($numFieldObj, $value) + { + $this->o_field($numFieldObj, 'set', ['value' => $value]); + } + + /** + * set Field value (reference) + * + * @param integer $numFieldObj + * @param integer $numObj Object number + */ + public function setFormFieldRefValue($numFieldObj, $numObj) + { + $this->o_field($numFieldObj, 'set', ['refvalue' => $numObj]); + } + + /** + * set Field Appearanc (reference) + * + * @param integer $numFieldObj + * @param integer $normalNumObj + * @param integer|null $rolloverNumObj + * @param integer|null $downNumObj + */ + public function setFormFieldAppearance($numFieldObj, $normalNumObj, $rolloverNumObj = null, $downNumObj = null) + { + $appearance['N'] = $normalNumObj; + + if ($rolloverNumObj !== null) { + $appearance['R'] = $rolloverNumObj; + } + + if ($downNumObj !== null) { + $appearance['D'] = $downNumObj; + } + + $this->o_field($numFieldObj, 'set', ['appearance' => $appearance]); + } + + /** + * set Choice Field option values + * + * @param integer $numFieldObj + * @param array $value + */ + public function setFormFieldOpt($numFieldObj, $value) + { + $this->o_field($numFieldObj, 'set', ['options' => $value]); + } + + /** + * add form to document + * + * @param integer $sigFlags + * @param boolean $needAppearances + */ + public function addForm($sigFlags = 0, $needAppearances = false) + { + $this->acroFormId = ++$this->numObj; + $this->o_acroform($this->acroFormId, 'new', [ + 'NeedAppearances' => $needAppearances ? 'true' : 'false', + 'SigFlags' => $sigFlags + ]); + } + + /** + * save the current graphic state + */ + function save() + { + // we must reset the color cache or it will keep bad colors after clipping + $this->currentColor = null; + $this->currentStrokeColor = null; + $this->addContent("\nq"); + } + + /** + * restore the last graphic state + */ + function restore() + { + // we must reset the color cache or it will keep bad colors after clipping + $this->currentColor = null; + $this->currentStrokeColor = null; + $this->addContent("\nQ"); + } + + /** + * draw a clipping rectangle, all the elements added after this will be clipped + * + * @param $x1 + * @param $y1 + * @param $width + * @param $height + */ + function clippingRectangle($x1, $y1, $width, $height) + { + $this->save(); + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re W n", $x1, $y1, $width, $height)); + } + + /** + * draw a clipping rounded rectangle, all the elements added after this will be clipped + * + * @param $x1 + * @param $y1 + * @param $w + * @param $h + * @param $rTL + * @param $rTR + * @param $rBR + * @param $rBL + */ + function clippingRectangleRounded($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL) + { + $this->save(); + + // start: top edge, left end + $this->addContent(sprintf("\n%.3F %.3F m ", $x1, $y1 - $rTL + $h)); + + // line: bottom edge, left end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1, $y1 + $rBL)); + + // curve: bottom-left corner + $this->ellipse($x1 + $rBL, $y1 + $rBL, $rBL, 0, 0, 8, 180, 270, false, false, false, true); + + // line: right edge, bottom end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w - $rBR, $y1)); + + // curve: bottom-right corner + $this->ellipse($x1 + $w - $rBR, $y1 + $rBR, $rBR, 0, 0, 8, 270, 360, false, false, false, true); + + // line: right edge, top end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $w, $y1 + $h - $rTR)); + + // curve: bottom-right corner + $this->ellipse($x1 + $w - $rTR, $y1 + $h - $rTR, $rTR, 0, 0, 8, 0, 90, false, false, false, true); + + // line: bottom edge, right end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rTL, $y1 + $h)); + + // curve: top-right corner + $this->ellipse($x1 + $rTL, $y1 + $h - $rTL, $rTL, 0, 0, 8, 90, 180, false, false, false, true); + + // line: top edge, left end + $this->addContent(sprintf("\n%.3F %.3F l ", $x1 + $rBL, $y1)); + + // Close & clip + $this->addContent(" W n"); + } + + /** + * ends the last clipping shape + */ + function clippingEnd() + { + $this->restore(); + } + + /** + * scale + * + * @param float $s_x scaling factor for width as percent + * @param float $s_y scaling factor for height as percent + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function scale($s_x, $s_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tm = [ + $s_x, + 0, + 0, + $s_y, + $x * (1 - $s_x), + $y * (1 - $s_y) + ]; + + $this->transform($tm); + } + + /** + * translate + * + * @param float $t_x movement to the right + * @param float $t_y movement to the bottom + */ + function translate($t_x, $t_y) + { + $tm = [ + 1, + 0, + 0, + 1, + $t_x, + -$t_y + ]; + + $this->transform($tm); + } + + /** + * rotate + * + * @param float $angle angle in degrees for counter-clockwise rotation + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function rotate($angle, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $a = deg2rad($angle); + $cos_a = cos($a); + $sin_a = sin($a); + + $tm = [ + $cos_a, + -$sin_a, + $sin_a, + $cos_a, + $x - $sin_a * $y - $cos_a * $x, + $y - $cos_a * $y + $sin_a * $x, + ]; + + $this->transform($tm); + } + + /** + * skew + * + * @param float $angle_x + * @param float $angle_y + * @param float $x Origin abscissa + * @param float $y Origin ordinate + */ + function skew($angle_x, $angle_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tan_x = tan(deg2rad($angle_x)); + $tan_y = tan(deg2rad($angle_y)); + + $tm = [ + 1, + -$tan_y, + -$tan_x, + 1, + $tan_x * $y, + $tan_y * $x, + ]; + + $this->transform($tm); + } + + /** + * apply graphic transformations + * + * @param array $tm transformation matrix + */ + function transform($tm) + { + $this->addContent(vsprintf("\n %.3F %.3F %.3F %.3F %.3F %.3F cm", $tm)); + } + + /** + * add a new page to the document + * this also makes the new page the current active object + * + * @param int $insert + * @param int $id + * @param string $pos + * @return int + */ + function newPage($insert = 0, $id = 0, $pos = 'after') + { + // if there is a state saved, then go up the stack closing them + // then on the new page, re-open them with the right setings + + if ($this->nStateStack) { + for ($i = $this->nStateStack; $i >= 1; $i--) { + $this->restoreState($i); + } + } + + $this->numObj++; + + if ($insert) { + // the id from the ezPdf class is the id of the contents of the page, not the page object itself + // query that object to find the parent + $rid = $this->objects[$id]['onPage']; + $opt = ['rid' => $rid, 'pos' => $pos]; + $this->o_page($this->numObj, 'new', $opt); + } else { + $this->o_page($this->numObj, 'new'); + } + + // if there is a stack saved, then put that onto the page + if ($this->nStateStack) { + for ($i = 1; $i <= $this->nStateStack; $i++) { + $this->saveState($i); + } + } + + // and if there has been a stroke or fill color set, then transfer them + if (isset($this->currentColor)) { + $this->setColor($this->currentColor, true); + } + + if (isset($this->currentStrokeColor)) { + $this->setStrokeColor($this->currentStrokeColor, true); + } + + // if there is a line style set, then put this in too + if (mb_strlen($this->currentLineStyle, '8bit')) { + $this->addContent("\n$this->currentLineStyle"); + } + + // the call to the o_page object set currentContents to the present page, so this can be returned as the page id + return $this->currentContents; + } + + /** + * Streams the PDF to the client. + * + * @param string $filename The filename to present to the client. + * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1). + */ + function stream($filename = "document.pdf", $options = []) + { + if (headers_sent()) { + die("Unable to stream pdf: headers already sent"); + } + + if (!isset($options["compress"])) $options["compress"] = true; + if (!isset($options["Attachment"])) $options["Attachment"] = true; + + $debug = !$options['compress']; + $tmp = ltrim($this->output($debug)); + + header("Cache-Control: private"); + header("Content-Type: application/pdf"); + header("Content-Length: " . mb_strlen($tmp, "8bit")); + + $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf"; + $attachment = $options["Attachment"] ? "attachment" : "inline"; + + $encoding = mb_detect_encoding($filename); + $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); + $fallbackfilename = str_replace("\"", "", $fallbackfilename); + $encodedfilename = rawurlencode($filename); + + $contentDisposition = "Content-Disposition: $attachment; filename=\"$fallbackfilename\""; + if ($fallbackfilename !== $filename) { + $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; + } + header($contentDisposition); + + echo $tmp; + flush(); + } + + /** + * return the height in units of the current font in the given size + * + * @param $size + * @return float|int + */ + function getFontHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['Ascender']) && isset($font['Descender'])) { + $h = $font['Ascender'] - $font['Descender']; + } else { + $h = $font['FontBBox'][3] - $font['FontBBox'][1]; + } + + // have to adjust by a font offset for Windows fonts. unfortunately it looks like + // the bounding box calculations are wrong and I don't know why. + if (isset($font['FontHeightOffset'])) { + // For CourierNew from Windows this needs to be -646 to match the + // Adobe native Courier font. + // + // For FreeMono from GNU this needs to be -337 to match the + // Courier font. + // + // Both have been added manually to the .afm and .ufm files. + $h += (int)$font['FontHeightOffset']; + } + + return $size * $h / 1000; + } + + /** + * @param $size + * @return float|int + */ + function getFontXHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['XHeight'])) { + $xh = $font['Ascender'] - $font['Descender']; + } else { + $xh = $this->getFontHeight($size) / 2; + } + + return $size * $xh / 1000; + } + + /** + * return the font descender, this will normally return a negative number + * if you add this number to the baseline, you get the level of the bottom of the font + * it is in the pdf user units + * + * @param $size + * @return float|int + */ + function getFontDescender($size) + { + // note that this will most likely return a negative value + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + //$h = $this->fonts[$this->currentFont]['FontBBox'][1]; + $h = $this->fonts[$this->currentFont]['Descender']; + + return $size * $h / 1000; + } + + /** + * filter the text, this is applied to all text just before being inserted into the pdf document + * it escapes the various things that need to be escaped, and so on + * + * @access private + * + * @param $text + * @param bool $bom + * @param bool $convert_encoding + * @return string + */ + function filterText($text, $bom = true, $convert_encoding = true) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + if ($convert_encoding) { + $cf = $this->currentFont; + if (isset($this->fonts[$cf]) && $this->fonts[$cf]['isUnicode']) { + $text = $this->utf8toUtf16BE($text, $bom); + } else { + //$text = html_entity_decode($text, ENT_QUOTES); + $text = mb_convert_encoding($text, self::$targetEncoding, 'UTF-8'); + } + } else if ($bom) { + $text = $this->utf8toUtf16BE($text, $bom); + } + + // the chr(13) substitution fixes a bug seen in TCPDF (bug #1421290) + return strtr($text, [')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r']); + } + + /** + * return array containing codepoints (UTF-8 character values) for the + * string passed in. + * + * based on the excellent TCPDF code by Nicola Asuni and the + * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html + * + * @access private + * @author Orion Richardson + * @since January 5, 2008 + * + * @param string $text UTF-8 string to process + * + * @return array UTF-8 codepoints array for the string + */ + function utf8toCodePointsArray(&$text) + { + $length = mb_strlen($text, '8bit'); // http://www.php.net/manual/en/function.mb-strlen.php#77040 + $unicode = []; // array containing unicode values + $bytes = []; // array containing single character byte sequences + $numbytes = 1; // number of octets needed to represent the UTF-8 character + + for ($i = 0; $i < $length; $i++) { + $c = ord($text[$i]); // get one string character at time + if (count($bytes) === 0) { // get starting octect + if ($c <= 0x7F) { + $unicode[] = $c; // use the character "as is" because is ASCII + $numbytes = 1; + } elseif (($c >> 0x05) === 0x06) { // 2 bytes character (0x06 = 110 BIN) + $bytes[] = ($c - 0xC0) << 0x06; + $numbytes = 2; + } elseif (($c >> 0x04) === 0x0E) { // 3 bytes character (0x0E = 1110 BIN) + $bytes[] = ($c - 0xE0) << 0x0C; + $numbytes = 3; + } elseif (($c >> 0x03) === 0x1E) { // 4 bytes character (0x1E = 11110 BIN) + $bytes[] = ($c - 0xF0) << 0x12; + $numbytes = 4; + } else { + // use replacement character for other invalid sequences + $unicode[] = 0xFFFD; + $bytes = []; + $numbytes = 1; + } + } elseif (($c >> 0x06) === 0x02) { // bytes 2, 3 and 4 must start with 0x02 = 10 BIN + $bytes[] = $c - 0x80; + if (count($bytes) === $numbytes) { + // compose UTF-8 bytes to a single unicode value + $c = $bytes[0]; + for ($j = 1; $j < $numbytes; $j++) { + $c += ($bytes[$j] << (($numbytes - $j - 1) * 0x06)); + } + if ((($c >= 0xD800) and ($c <= 0xDFFF)) or ($c >= 0x10FFFF)) { + // The definition of UTF-8 prohibits encoding character numbers between + // U+D800 and U+DFFF, which are reserved for use with the UTF-16 + // encoding form (as surrogate pairs) and do not directly represent + // characters. + $unicode[] = 0xFFFD; // use replacement character + } else { + $unicode[] = $c; // add char to array + } + // reset data for next char + $bytes = []; + $numbytes = 1; + } + } else { + // use replacement character for other invalid sequences + $unicode[] = 0xFFFD; + $bytes = []; + $numbytes = 1; + } + } + + return $unicode; + } + + /** + * convert UTF-8 to UTF-16 with an additional byte order marker + * at the front if required. + * + * based on the excellent TCPDF code by Nicola Asuni and the + * RFC for UTF-8 at http://www.faqs.org/rfcs/rfc3629.html + * + * @access private + * @author Orion Richardson + * @since January 5, 2008 + * + * @param string $text UTF-8 string to process + * @param boolean $bom whether to add the byte order marker + * + * @return string UTF-16 result string + */ + function utf8toUtf16BE(&$text, $bom = true) + { + $out = $bom ? "\xFE\xFF" : ''; + + $unicode = $this->utf8toCodePointsArray($text); + foreach ($unicode as $c) { + if ($c === 0xFFFD) { + $out .= "\xFF\xFD"; // replacement character + } elseif ($c < 0x10000) { + $out .= chr($c >> 0x08) . chr($c & 0xFF); + } else { + $c -= 0x10000; + $w1 = 0xD800 | ($c >> 0x10); + $w2 = 0xDC00 | ($c & 0x3FF); + $out .= chr($w1 >> 0x08) . chr($w1 & 0xFF) . chr($w2 >> 0x08) . chr($w2 & 0xFF); + } + } + + return $out; + } + + /** + * given a start position and information about how text is to be laid out, calculate where + * on the page the text will end + * + * @param $x + * @param $y + * @param $angle + * @param $size + * @param $wa + * @param $text + * @return array + */ + private function getTextPosition($x, $y, $angle, $size, $wa, $text) + { + // given this information return an array containing x and y for the end position as elements 0 and 1 + $w = $this->getTextWidth($size, $text); + + // need to adjust for the number of spaces in this text + $words = explode(' ', $text); + $nspaces = count($words) - 1; + $w += $wa * $nspaces; + $a = deg2rad((float)$angle); + + return [cos($a) * $w + $x, -sin($a) * $w + $y]; + } + + /** + * Callback method used by smallCaps + * + * @param array $matches + * + * @return string + */ + function toUpper($matches) + { + return mb_strtoupper($matches[0]); + } + + function concatMatches($matches) + { + $str = ""; + foreach ($matches as $match) { + $str .= $match[0]; + } + + return $str; + } + + /** + * register text for font subsetting + * + * @param $font + * @param $text + */ + function registerText($font, $text) + { + if (!$this->isUnicode || in_array(mb_strtolower(basename($font)), self::$coreFonts)) { + return; + } + + if (!isset($this->stringSubsets[$font])) { + $this->stringSubsets[$font] = []; + } + + $this->stringSubsets[$font] = array_unique( + array_merge($this->stringSubsets[$font], $this->utf8toCodePointsArray($text)) + ); + } + + /** + * add text to the document, at a specified location, size and angle on the page + * + * @param $x + * @param $y + * @param $size + * @param $text + * @param int $angle + * @param int $wordSpaceAdjust + * @param int $charSpaceAdjust + * @param bool $smallCaps + */ + function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSpaceAdjust = 0, $smallCaps = false) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(["\r", "\n"], "", $text); + + if ($smallCaps) { + preg_match_all("/(\P{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + $lower = $this->concatMatches($matches); + d($lower); + + preg_match_all("/(\p{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + $other = $this->concatMatches($matches); + d($other); + + //$text = preg_replace_callback("/\p{Ll}/u", array($this, "toUpper"), $text); + } + + // if there are any open callbacks, then they should be called, to show the start of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $info = [ + 'x' => $x, + 'y' => $y, + 'angle' => $angle, + 'status' => 'sol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ]; + + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + + if ($angle == 0) { + $this->addContent(sprintf("\nBT %.3F %.3F Td", $x, $y)); + } else { + $a = deg2rad((float)$angle); + $this->addContent( + sprintf("\nBT %.3F %.3F %.3F %.3F %.3F %.3F Tm", cos($a), -sin($a), sin($a), cos($a), $x, $y) + ); + } + + if ($wordSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tw", $wordSpaceAdjust)); + } + + if ($charSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tc", $charSpaceAdjust)); + } + + $len = mb_strlen($text); + $start = 0; + + if ($start < $len) { + $part = $text; // OAR - Don't need this anymore, given that $start always equals zero. substr($text, $start); + $place_text = $this->filterText($part, false); + // modify unicode text so that extra word spacing is manually implemented (bug #) + if ($this->fonts[$this->currentFont]['isUnicode'] && $wordSpaceAdjust != 0) { + $space_scale = 1000 / $size; + $place_text = str_replace("\x00\x20", "\x00\x20)\x00\x20" . (-round($space_scale * $wordSpaceAdjust)) . "\x00\x20(", $place_text); + } + $this->addContent(" /F$this->currentFontNum " . sprintf('%.1F Tf ', $size)); + $this->addContent(" [($place_text)] TJ"); + } + + if ($wordSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tw", 0)); + } + + if ($charSpaceAdjust != 0) { + $this->addContent(sprintf(" %.3F Tc", 0)); + } + + $this->addContent(' ET'); + + // if there are any open callbacks, then they should be called, to show the end of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $tmp = $this->getTextPosition($x, $y, $angle, $size, $wordSpaceAdjust, $text); + $info = [ + 'x' => $tmp[0], + 'y' => $tmp[1], + 'angle' => $angle, + 'status' => 'eol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ]; + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + + if ($this->fonts[$this->currentFont]['isSubsetting']) { + $this->registerText($this->currentFont, $text); + } + } + + /** + * calculate how wide a given text string will be on a page, at a given size. + * this can be called externally, but is also used by the other class functions + * + * @param $size + * @param $text + * @param int $word_spacing + * @param int $char_spacing + * @return float|int + */ + function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) + { + static $ord_cache = []; + + // this function should not change any of the settings, though it will need to + // track any directives which change during calculation, so copy them at the start + // and put them back at the end. + $store_currentTextState = $this->currentTextState; + + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(["\r", "\n"], "", $text); + + // converts a number or a float to a string so it can get the width + $text = "$text"; + + // hmm, this is where it all starts to get tricky - use the font information to + // calculate the width of each character, add them up and convert to user units + $w = 0; + $cf = $this->currentFont; + $current_font = $this->fonts[$cf]; + $space_scale = 1000 / ($size > 0 ? $size : 1); + $n_spaces = 0; + + if ($current_font['isUnicode']) { + // for Unicode, use the code points array to calculate width rather + // than just the string itself + $unicode = $this->utf8toCodePointsArray($text); + + foreach ($unicode as $char) { + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + $n_spaces++; + } + } + } + + // add additional char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * (count($unicode) + $n_spaces); + } + + } else { + // If CPDF is in Unicode mode but the current font does not support Unicode we need to convert the character set to Windows-1252 + if ($this->isUnicode) { + $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); + } + + $len = mb_strlen($text, 'Windows-1252'); + + for ($i = 0; $i < $len; $i++) { + $c = $text[$i]; + $char = isset($ord_cache[$c]) ? $ord_cache[$c] : ($ord_cache[$c] = ord($c)); + + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + $n_spaces++; + } + } + } + + // add additional char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * ($len + $n_spaces); + } + } + + $this->currentTextState = $store_currentTextState; + $this->setCurrentFont(); + + return $w * $size / 1000; + } + + /** + * this will be called at a new page to return the state to what it was on the + * end of the previous page, before the stack was closed down + * This is to get around not being able to have open 'q' across pages + * + * @param int $pageEnd + */ + function saveState($pageEnd = 0) + { + if ($pageEnd) { + // this will be called at a new page to return the state to what it was on the + // end of the previous page, before the stack was closed down + // This is to get around not being able to have open 'q' across pages + $opt = $this->stateStack[$pageEnd]; + // ok to use this as stack starts numbering at 1 + $this->setColor($opt['col'], true); + $this->setStrokeColor($opt['str'], true); + $this->addContent("\n" . $opt['lin']); + // $this->currentLineStyle = $opt['lin']; + } else { + $this->nStateStack++; + $this->stateStack[$this->nStateStack] = [ + 'col' => $this->currentColor, + 'str' => $this->currentStrokeColor, + 'lin' => $this->currentLineStyle + ]; + } + + $this->save(); + } + + /** + * restore a previously saved state + * + * @param int $pageEnd + */ + function restoreState($pageEnd = 0) + { + if (!$pageEnd) { + $n = $this->nStateStack; + $this->currentColor = $this->stateStack[$n]['col']; + $this->currentStrokeColor = $this->stateStack[$n]['str']; + $this->addContent("\n" . $this->stateStack[$n]['lin']); + $this->currentLineStyle = $this->stateStack[$n]['lin']; + $this->stateStack[$n] = null; + unset($this->stateStack[$n]); + $this->nStateStack--; + } + + $this->restore(); + } + + /** + * make a loose object, the output will go into this object, until it is closed, then will revert to + * the current one. + * this object will not appear until it is included within a page. + * the function will return the object number + * + * @return int + */ + function openObject() + { + $this->nStack++; + $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; + // add a new object of the content type, to hold the data flow + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->currentContents = $this->numObj; + $this->looseObjects[$this->numObj] = 1; + + return $this->numObj; + } + + /** + * open an existing object for editing + * + * @param $id + */ + function reopenObject($id) + { + $this->nStack++; + $this->stack[$this->nStack] = ['c' => $this->currentContents, 'p' => $this->currentPage]; + $this->currentContents = $id; + + // also if this object is the primary contents for a page, then set the current page to its parent + if (isset($this->objects[$id]['onPage'])) { + $this->currentPage = $this->objects[$id]['onPage']; + } + } + + /** + * close an object + */ + function closeObject() + { + // close the object, as long as there was one open in the first place, which will be indicated by + // an objectId on the stack. + if ($this->nStack > 0) { + $this->currentContents = $this->stack[$this->nStack]['c']; + $this->currentPage = $this->stack[$this->nStack]['p']; + $this->nStack--; + // easier to probably not worry about removing the old entries, they will be overwritten + // if there are new ones. + } + } + + /** + * stop an object from appearing on pages from this point on + * + * @param $id + */ + function stopObject($id) + { + // if an object has been appearing on pages up to now, then stop it, this page will + // be the last one that could contain it. + if (isset($this->addLooseObjects[$id])) { + $this->addLooseObjects[$id] = ''; + } + } + + /** + * after an object has been created, it wil only show if it has been added, using this function. + * + * @param $id + * @param string $options + */ + function addObject($id, $options = 'add') + { + // add the specified object to the page + if (isset($this->looseObjects[$id]) && $this->currentContents != $id) { + // then it is a valid object, and it is not being added to itself + switch ($options) { + case 'all': + // then this object is to be added to this page (done in the next block) and + // all future new pages. + $this->addLooseObjects[$id] = 'all'; + + case 'add': + if (isset($this->objects[$this->currentContents]['onPage'])) { + // then the destination contents is the primary for the page + // (though this object is actually added to that page) + $this->o_page($this->objects[$this->currentContents]['onPage'], 'content', $id); + } + break; + + case 'even': + $this->addLooseObjects[$id] = 'even'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 0) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'odd': + $this->addLooseObjects[$id] = 'odd'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 1) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'next': + $this->addLooseObjects[$id] = 'all'; + break; + + case 'nexteven': + $this->addLooseObjects[$id] = 'even'; + break; + + case 'nextodd': + $this->addLooseObjects[$id] = 'odd'; + break; + } + } + } + + /** + * return a storable representation of a specific object + * + * @param $id + * @return string|null + */ + function serializeObject($id) + { + if (array_key_exists($id, $this->objects)) { + return serialize($this->objects[$id]); + } + + return null; + } + + /** + * restore an object from its stored representation. Returns its new object id. + * + * @param $obj + * @return int + */ + function restoreSerializedObject($obj) + { + $obj_id = $this->openObject(); + $this->objects[$obj_id] = unserialize($obj); + $this->closeObject(); + + return $obj_id; + } + + /** + * Embeds a file inside the PDF + * + * @param string $filepath path to the file to store inside the PDF + * @param string $embeddedFilename the filename displayed in the list of embedded files + * @param string $description a description in the list of embedded files + */ + public function addEmbeddedFile(string $filepath, string $embeddedFilename, string $description): void + { + $this->numObj++; + $this->o_embedded_file_dictionary( + $this->numObj, + 'new', + [ + 'filepath' => $filepath, + 'filename' => $embeddedFilename, + 'description' => $description + ] + ); + } + + /** + * add content to the documents info object + * + * @param $label + * @param int $value + */ + function addInfo($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + // modify this so that arrays can be passed as well. + // if $label is an array then assume that it is key => value pairs + // else assume that they are both scalar, anything else will probably error + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_info($this->infoObject, $l, $v); + } + } else { + $this->o_info($this->infoObject, $label, $value); + } + } + + /** + * set the viewer preferences of the document, it is up to the browser to obey these. + * + * @param $label + * @param int $value + */ + function setPreferences($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_catalog($this->catalogId, 'viewerPreferences', [$l => $v]); + } + } else { + $this->o_catalog($this->catalogId, 'viewerPreferences', [$label => $value]); + } + } + + /** + * extract an integer from a position in a byte stream + * + * @param $data + * @param $pos + * @param $num + * @return int + */ + private function getBytes(&$data, $pos, $num) + { + // return the integer represented by $num bytes from $pos within $data + $ret = 0; + for ($i = 0; $i < $num; $i++) { + $ret *= 256; + $ret += ord($data[$pos + $i]); + } + + return $ret; + } + + /** + * Check if image already added to pdf image directory. + * If yes, need not to create again (pass empty data) + * + * @param $imgname + * @return bool + */ + function image_iscached($imgname) + { + return isset($this->imagelist[$imgname]); + } + + /** + * add a PNG image into the document, from a GD object + * this should work with remote files + * + * @param string $file The PNG file + * @param float $x X position + * @param float $y Y position + * @param float $w Width + * @param float $h Height + * @param resource $img A GD resource + * @param bool $is_mask true if the image is a mask + * @param bool $mask true if the image is masked + * @throws Exception + */ + function addImagePng($file, $x, $y, $w = 0.0, $h = 0.0, &$img, $is_mask = false, $mask = null) + { + if (!function_exists("imagepng")) { + throw new \Exception("The PHP GD extension is required, but is not installed."); + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $data = null; + } else { + // Example for transparency handling on new image. Retain for current image + // $tIndex = imagecolortransparent($img); + // if ($tIndex > 0) { + // $tColor = imagecolorsforindex($img, $tIndex); + // $new_tIndex = imagecolorallocate($new_img, $tColor['red'], $tColor['green'], $tColor['blue']); + // imagefill($new_img, 0, 0, $new_tIndex); + // imagecolortransparent($new_img, $new_tIndex); + // } + // blending mode (literal/blending) on drawing into current image. not relevant when not saved or not drawn + //imagealphablending($img, true); + + //default, but explicitely set to ensure pdf compatibility + imagesavealpha($img, false/*!$is_mask && !$mask*/); + + $error = 0; + //DEBUG_IMG_TEMP + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addImagePng ' . $file . ']'; + } + + ob_start(); + @imagepng($img); + $data = ob_get_clean(); + + if ($data == '') { + $error = 1; + $errormsg = 'trouble writing file from GD'; + //DEBUG_IMG_TEMP + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print 'trouble writing file from GD'; + } + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + } //End isset($this->imagelist[$file]) (png Duplicate removal) + + $this->addPngFromBuf($file, $x, $y, $w, $h, $data, $is_mask, $mask); + } + + /** + * @param $file + * @param $x + * @param $y + * @param $w + * @param $h + * @param $byte + */ + protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte) + { + // generate images + $img = imagecreatefrompng($file); + + if ($img === false) { + return; + } + + // FIXME The pixel transformation doesn't work well with 8bit PNGs + $eight_bit = ($byte & 4) !== 4; + + $wpx = imagesx($img); + $hpx = imagesy($img); + + imagesavealpha($img, false); + + // create temp alpha file + $tempfile_alpha = @tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_alpha); + $tempfile_alpha = "$tempfile_alpha.png"; + + // create temp plain file + $tempfile_plain = @tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_plain); + $tempfile_plain = "$tempfile_plain.png"; + + $imgalpha = imagecreate($wpx, $hpx); + imagesavealpha($imgalpha, false); + + // generate gray scale palette (0 -> 255) + for ($c = 0; $c < 256; ++$c) { + imagecolorallocate($imgalpha, $c, $c, $c); + } + + // Use PECL gmagick + Graphics Magic to process transparent PNG images + if (extension_loaded("gmagick")) { + $gmagick = new \Gmagick($file); + $gmagick->setimageformat('png'); + + // Get opacity channel (negative of alpha channel) + $alpha_channel_neg = clone $gmagick; + $alpha_channel_neg->separateimagechannel(\Gmagick::CHANNEL_OPACITY); + + // Negate opacity channel + $alpha_channel = new \Gmagick(); + $alpha_channel->newimage($wpx, $hpx, "#FFFFFF", "png"); + $alpha_channel->compositeimage($alpha_channel_neg, \Gmagick::COMPOSITE_DIFFERENCE, 0, 0); + $alpha_channel->separateimagechannel(\Gmagick::CHANNEL_RED); + $alpha_channel->writeimage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + + // Make opaque image + $color_channels = new \Gmagick(); + $color_channels->newimage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeimage($gmagick, \Gmagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeimage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } + // Use PECL imagick + ImageMagic to process transparent PNG images + elseif (extension_loaded("imagick")) { + // Native cloning was added to pecl-imagick in svn commit 263814 + // the first version containing it was 3.0.1RC1 + static $imagickClonable = null; + if ($imagickClonable === null) { + $imagickClonable = version_compare(\Imagick::IMAGICK_EXTVER, '3.0.1rc1') > 0; + } + + $imagick = new \Imagick($file); + $imagick->setFormat('png'); + + // Get opacity channel (negative of alpha channel) + if ($imagick->getImageAlphaChannel() !== 0) { + $alpha_channel = $imagickClonable ? clone $imagick : $imagick->clone(); + $alpha_channel->separateImageChannel(\Imagick::CHANNEL_ALPHA); + // Since ImageMagick7 negate invert transparency as default + if (\Imagick::getVersion()['versionNumber'] < 1800) { + $alpha_channel->negateImage(true); + } + $alpha_channel->writeImage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + } else { + $tempfile_alpha = null; + } + + // Make opaque image + $color_channels = new \Imagick(); + $color_channels->newImage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeImage($imagick, \Imagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeImage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } else { + // allocated colors cache + $allocated_colors = []; + + // extract alpha channel + for ($xpx = 0; $xpx < $wpx; ++$xpx) { + for ($ypx = 0; $ypx < $hpx; ++$ypx) { + $color = imagecolorat($img, $xpx, $ypx); + $col = imagecolorsforindex($img, $color); + $alpha = $col['alpha']; + + if ($eight_bit) { + // with gamma correction + $gammacorr = 2.2; + $pixel = pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255; + } else { + // without gamma correction + $pixel = (127 - $alpha) * 2; + + $key = $col['red'] . $col['green'] . $col['blue']; + + if (!isset($allocated_colors[$key])) { + $pixel_img = imagecolorallocate($img, $col['red'], $col['green'], $col['blue']); + $allocated_colors[$key] = $pixel_img; + } else { + $pixel_img = $allocated_colors[$key]; + } + + imagesetpixel($img, $xpx, $ypx, $pixel_img); + } + + imagesetpixel($imgalpha, $xpx, $ypx, $pixel); + } + } + + // extract image without alpha channel + $imgplain = imagecreatetruecolor($wpx, $hpx); + imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($img); + + imagepng($imgalpha, $tempfile_alpha); + imagepng($imgplain, $tempfile_plain); + } + + // embed mask image + if ($tempfile_alpha) { + $this->addImagePng($tempfile_alpha, $x, $y, $w, $h, $imgalpha, true); + imagedestroy($imgalpha); + } + + // embed image, masked with previously embedded mask + $this->addImagePng($tempfile_plain, $x, $y, $w, $h, $imgplain, false, ($tempfile_alpha !== null)); + imagedestroy($imgplain); + + // remove temp files + if ($tempfile_alpha) { + unlink($tempfile_alpha); + } + unlink($tempfile_plain); + } + + /** + * add a PNG image into the document, from a file + * this should work with remote files + * + * @param $file + * @param $x + * @param $y + * @param int $w + * @param int $h + * @throws Exception + */ + function addPngFromFile($file, $x, $y, $w = 0, $h = 0) + { + if (!function_exists("imagecreatefrompng")) { + throw new \Exception("The PHP GD extension is required, but is not installed."); + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $img = null; + } else { + $info = file_get_contents($file, false, null, 24, 5); + $meta = unpack("CbitDepth/CcolorType/CcompressionMethod/CfilterMethod/CinterlaceMethod", $info); + $bit_depth = $meta["bitDepth"]; + $color_type = $meta["colorType"]; + + // http://www.w3.org/TR/PNG/#11IHDR + // 3 => indexed + // 4 => greyscale with alpha + // 6 => fullcolor with alpha + $is_alpha = in_array($color_type, [4, 6]) || ($color_type == 3 && $bit_depth != 4); + + if ($is_alpha) { // exclude grayscale alpha + $this->addImagePngAlpha($file, $x, $y, $w, $h, $color_type); + return; + } + + //png files typically contain an alpha channel. + //pdf file format or class.pdf does not support alpha blending. + //on alpha blended images, more transparent areas have a color near black. + //This appears in the result on not storing the alpha channel. + //Correct would be the box background image or its parent when transparent. + //But this would make the image dependent on the background. + //Therefore create an image with white background and copy in + //A more natural background than black is white. + //Therefore create an empty image with white background and merge the + //image in with alpha blending. + $imgtmp = @imagecreatefrompng($file); + if (!$imgtmp) { + return; + } + $sx = imagesx($imgtmp); + $sy = imagesy($imgtmp); + $img = imagecreatetruecolor($sx, $sy); + imagealphablending($img, true); + + // @todo is it still needed ?? + $ti = imagecolortransparent($imgtmp); + if ($ti >= 0) { + $tc = imagecolorsforindex($imgtmp, $ti); + $ti = imagecolorallocate($img, $tc['red'], $tc['green'], $tc['blue']); + imagefill($img, 0, 0, $ti); + imagecolortransparent($img, $ti); + } else { + imagefill($img, 1, 1, imagecolorallocate($img, 255, 255, 255)); + } + + imagecopy($img, $imgtmp, 0, 0, 0, 0, $sx, $sy); + imagedestroy($imgtmp); + } + $this->addImagePng($file, $x, $y, $w, $h, $img); + + if ($img) { + imagedestroy($img); + } + } + + /** + * add a PNG image into the document, from a file + * this should work with remote files + * + * @param $file + * @param $x + * @param $y + * @param int $w + * @param int $h + */ + function addSvgFromFile($file, $x, $y, $w = 0, $h = 0) + { + $doc = new \Svg\Document(); + $doc->loadFile($file); + $dimensions = $doc->getDimensions(); + + $this->save(); + + $this->transform([$w / $dimensions["width"], 0, 0, $h / $dimensions["height"], $x, $y]); + + $surface = new \Svg\Surface\SurfaceCpdf($doc, $this); + $doc->render($surface); + + $this->restore(); + } + + /** + * add a PNG image into the document, from a memory buffer of the file + * + * @param $file + * @param $x + * @param $y + * @param float $w + * @param float $h + * @param $data + * @param bool $is_mask + * @param null $mask + */ + function addPngFromBuf($file, $x, $y, $w = 0.0, $h = 0.0, &$data, $is_mask = false, $mask = null) + { + if (isset($this->imagelist[$file])) { + $data = null; + $info['width'] = $this->imagelist[$file]['w']; + $info['height'] = $this->imagelist[$file]['h']; + $label = $this->imagelist[$file]['label']; + } else { + if ($data == null) { + $this->addMessage('addPngFromBuf error - data not present!'); + + return; + } + + $error = 0; + + if (!$error) { + $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10); + + if (mb_substr($data, 0, 8, '8bit') != $header) { + $error = 1; + + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile this file does not have a valid header ' . $file . ']'; + } + + $errormsg = 'this file does not have a valid header'; + } + } + + if (!$error) { + // set pointer + $p = 8; + $len = mb_strlen($data, '8bit'); + + // cycle through the file, identifying chunks + $haveHeader = 0; + $info = []; + $idata = ''; + $pdata = ''; + + while ($p < $len) { + $chunkLen = $this->getBytes($data, $p, 4); + $chunkType = mb_substr($data, $p + 4, 4, '8bit'); + + switch ($chunkType) { + case 'IHDR': + // this is where all the file information comes from + $info['width'] = $this->getBytes($data, $p + 8, 4); + $info['height'] = $this->getBytes($data, $p + 12, 4); + $info['bitDepth'] = ord($data[$p + 16]); + $info['colorType'] = ord($data[$p + 17]); + $info['compressionMethod'] = ord($data[$p + 18]); + $info['filterMethod'] = ord($data[$p + 19]); + $info['interlaceMethod'] = ord($data[$p + 20]); + + //print_r($info); + $haveHeader = 1; + if ($info['compressionMethod'] != 0) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported compression method ' . $file . ']'; + } + + $errormsg = 'unsupported compression method'; + } + + if ($info['filterMethod'] != 0) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported filter method ' . $file . ']'; + } + + $errormsg = 'unsupported filter method'; + } + break; + + case 'PLTE': + $pdata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'IDAT': + $idata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'tRNS': + //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk + //print "tRNS found, color type = ".$info['colorType']."\n"; + $transparency = []; + + switch ($info['colorType']) { + // indexed color, rbg + case 3: + /* corresponding to entries in the plte chunk + Alpha for palette index 0: 1 byte + Alpha for palette index 1: 1 byte + ...etc... + */ + // there will be one entry for each palette entry. up until the last non-opaque entry. + // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent) + $transparency['type'] = 'indexed'; + $trans = 0; + + for ($i = $chunkLen; $i >= 0; $i--) { + if (ord($data[$p + 8 + $i]) == 0) { + $trans = $i; + } + } + + $transparency['data'] = $trans; + break; + + // grayscale + case 0: + /* corresponding to entries in the plte chunk + Gray: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + // $transparency['grayscale'] = $this->PRVT_getBytes($data,$p+8,2); // g = grayscale + $transparency['type'] = 'indexed'; + $transparency['data'] = ord($data[$p + 8 + 1]); + break; + + // truecolor + case 2: + /* corresponding to entries in the plte chunk + Red: 2 bytes, range 0 .. (2^bitdepth)-1 + Green: 2 bytes, range 0 .. (2^bitdepth)-1 + Blue: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + $transparency['r'] = $this->getBytes($data, $p + 8, 2); + // r from truecolor + $transparency['g'] = $this->getBytes($data, $p + 10, 2); + // g from truecolor + $transparency['b'] = $this->getBytes($data, $p + 12, 2); + // b from truecolor + + $transparency['type'] = 'color-key'; + break; + + //unsupported transparency type + default: + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile unsupported transparency type ' . $file . ']'; + } + break; + } + + // KS End new code + break; + + default: + break; + } + + $p += $chunkLen + 12; + } + + if (!$haveHeader) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile information header is missing ' . $file . ']'; + } + + $errormsg = 'information header is missing'; + } + + if (isset($info['interlaceMethod']) && $info['interlaceMethod']) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile no support for interlaced images in pdf ' . $file . ']'; + } + + $errormsg = 'There appears to be no support for interlaced images in pdf.'; + } + } + + if (!$error && $info['bitDepth'] > 8) { + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile bit depth of 8 or less is supported ' . $file . ']'; + } + + $errormsg = 'only bit depth of 8 or less is supported'; + } + + if (!$error) { + switch ($info['colorType']) { + case 3: + $color = 'DeviceRGB'; + $ncolor = 1; + break; + + case 2: + $color = 'DeviceRGB'; + $ncolor = 3; + break; + + case 0: + $color = 'DeviceGray'; + $ncolor = 1; + break; + + default: + $error = 1; + + //debugpng + if (defined("DEBUGPNG") && DEBUGPNG) { + print '[addPngFromFile alpha channel not supported: ' . $info['colorType'] . ' ' . $file . ']'; + } + + $errormsg = 'transparency alpha channel not supported, transparency only supported for palette images.'; + } + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + + //print_r($info); + // so this image is ok... add it in. + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + // $this->o_image($this->numObj,'new',array('label' => $label,'data' => $idata,'iw' => $w,'ih' => $h,'type' => 'png','ic' => $info['width'])); + $options = [ + 'label' => $label, + 'data' => $idata, + 'bitsPerComponent' => $info['bitDepth'], + 'pdata' => $pdata, + 'iw' => $info['width'], + 'ih' => $info['height'], + 'type' => 'png', + 'color' => $color, + 'ncolor' => $ncolor, + 'masked' => $mask, + 'isMask' => $is_mask + ]; + + if (isset($transparency)) { + $options['transparency'] = $transparency; + } + + $this->o_image($this->numObj, 'new', $options); + $this->imagelist[$file] = ['label' => $label, 'w' => $info['width'], 'h' => $info['height']]; + } + + if ($is_mask) { + return; + } + + if ($w <= 0 && $h <= 0) { + $w = $info['width']; + $h = $info['height']; + } + + if ($w <= 0) { + $w = $h / $info['height'] * $info['width']; + } + + if ($h <= 0) { + $h = $w * $info['height'] / $info['width']; + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ", $w, $h, $x, $y, $label)); + } + + /** + * add a JPEG image into the document, from a file + * + * @param $img + * @param $x + * @param $y + * @param int $w + * @param int $h + */ + function addJpegFromFile($img, $x, $y, $w = 0, $h = 0) + { + // attempt to add a jpeg image straight from a file, using no GD commands + // note that this function is unable to operate on a remote file. + + if (!file_exists($img)) { + return; + } + + if ($this->image_iscached($img)) { + $data = null; + $imageWidth = $this->imagelist[$img]['w']; + $imageHeight = $this->imagelist[$img]['h']; + $channels = $this->imagelist[$img]['c']; + } else { + $tmp = getimagesize($img); + $imageWidth = $tmp[0]; + $imageHeight = $tmp[1]; + + if (isset($tmp['channels'])) { + $channels = $tmp['channels']; + } else { + $channels = 3; + } + + $data = file_get_contents($img); + } + + if ($w <= 0 && $h <= 0) { + $w = $imageWidth; + } + + if ($w == 0) { + $w = $h / $imageHeight * $imageWidth; + } + + if ($h == 0) { + $h = $w * $imageHeight / $imageWidth; + } + + $this->addJpegImage_common($data, $x, $y, $w, $h, $imageWidth, $imageHeight, $channels, $img); + } + + /** + * common code used by the two JPEG adding functions + * @param $data + * @param $x + * @param $y + * @param int $w + * @param int $h + * @param $imageWidth + * @param $imageHeight + * @param int $channels + * @param $imgname + */ + private function addJpegImage_common( + &$data, + $x, + $y, + $w = 0, + $h = 0, + $imageWidth, + $imageHeight, + $channels = 3, + $imgname + ) { + if ($this->image_iscached($imgname)) { + $label = $this->imagelist[$imgname]['label']; + //debugpng + //if (DEBUGPNG) print '[addJpegImage_common Duplicate '.$imgname.']'; + + } else { + if ($data == null) { + $this->addMessage('addJpegImage_common error - (' . $imgname . ') data not present!'); + + return; + } + + // note that this function is not to be called externally + // it is just the common code between the GD and the file options + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + $this->o_image( + $this->numObj, + 'new', + [ + 'label' => $label, + 'data' => &$data, + 'iw' => $imageWidth, + 'ih' => $imageHeight, + 'channels' => $channels + ] + ); + + $this->imagelist[$imgname] = [ + 'label' => $label, + 'w' => $imageWidth, + 'h' => $imageHeight, + 'c' => $channels + ]; + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ ", $w, $h, $x, $y, $label)); + } + + /** + * specify where the document should open when it first starts + * + * @param $style + * @param int $a + * @param int $b + * @param int $c + */ + function openHere($style, $a = 0, $b = 0, $c = 0) + { + // this function will open the document at a specified page, in a specified style + // the values for style, and the required parameters are: + // 'XYZ' left, top, zoom + // 'Fit' + // 'FitH' top + // 'FitV' left + // 'FitR' left,bottom,right + // 'FitB' + // 'FitBH' top + // 'FitBV' left + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] + ); + $id = $this->catalogId; + $this->o_catalog($id, 'openHere', $this->numObj); + } + + /** + * Add JavaScript code to the PDF document + * + * @param string $code + */ + function addJavascript($code) + { + $this->javascript .= $code; + } + + /** + * create a labelled destination within the document + * + * @param $label + * @param $style + * @param int $a + * @param int $b + * @param int $c + */ + function addDestination($label, $style, $a = 0, $b = 0, $c = 0) + { + // associates the given label with the destination, it is done this way so that a destination can be specified after + // it has been linked to + // styles are the same as the 'openHere' function + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + ['page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c] + ); + $id = $this->numObj; + + // store the label->idf relationship, note that this means that labels can be used only once + $this->destinations["$label"] = $id; + } + + /** + * define font families, this is used to initialize the font families for the default fonts + * and for the user to add new ones for their fonts. The default bahavious can be overridden should + * that be desired. + * + * @param $family + * @param string $options + */ + function setFontFamily($family, $options = '') + { + if (!is_array($options)) { + if ($family === 'init') { + // set the known family groups + // these font families will be used to enable bold and italic markers to be included + // within text streams. html forms will be used... + $this->fontFamilies['Helvetica.afm'] = + [ + 'b' => 'Helvetica-Bold.afm', + 'i' => 'Helvetica-Oblique.afm', + 'bi' => 'Helvetica-BoldOblique.afm', + 'ib' => 'Helvetica-BoldOblique.afm' + ]; + + $this->fontFamilies['Courier.afm'] = + [ + 'b' => 'Courier-Bold.afm', + 'i' => 'Courier-Oblique.afm', + 'bi' => 'Courier-BoldOblique.afm', + 'ib' => 'Courier-BoldOblique.afm' + ]; + + $this->fontFamilies['Times-Roman.afm'] = + [ + 'b' => 'Times-Bold.afm', + 'i' => 'Times-Italic.afm', + 'bi' => 'Times-BoldItalic.afm', + 'ib' => 'Times-BoldItalic.afm' + ]; + } + } else { + + // the user is trying to set a font family + // note that this can also be used to set the base ones to something else + if (mb_strlen($family)) { + $this->fontFamilies[$family] = $options; + } + } + } + + /** + * used to add messages for use in debugging + * + * @param $message + */ + function addMessage($message) + { + $this->messages .= $message . "\n"; + } + + /** + * a few functions which should allow the document to be treated transactionally. + * + * @param $action + */ + function transaction($action) + { + switch ($action) { + case 'start': + // store all the data away into the checkpoint variable + $data = get_object_vars($this); + $this->checkpoint = $data; + unset($data); + break; + + case 'commit': + if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])) { + $tmp = $this->checkpoint['checkpoint']; + $this->checkpoint = $tmp; + unset($tmp); + } else { + $this->checkpoint = ''; + } + break; + + case 'rewind': + // do not destroy the current checkpoint, but move us back to the state then, so that we can try again + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + + foreach ($tmp as $k => $v) { + if ($k !== 'checkpoint') { + $this->$k = $v; + } + } + unset($tmp); + } + break; + + case 'abort': + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + foreach ($tmp as $k => $v) { + $this->$k = $v; + } + unset($tmp); + } + break; + } + } +} diff --git a/vendor/dompdf/dompdf/lib/fonts/Courier-Bold.afm b/vendor/dompdf/dompdf/lib/fonts/Courier-Bold.afm new file mode 100644 index 0000000..84adbf5 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/Courier-Bold.afm @@ -0,0 +1,344 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:00 0:00:00 +Comment UniqueID 43048 +Comment VMusage 41139 52164 +FontName Courier-Bold +FullName Courier Bold +FamilyName Courier +Weight Bold +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -113 -250 749 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme WinAnsiEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 317 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 160 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 202 -15 398 572 ; +C 34 ; WX 600 ; N quotedbl ; B 135 277 465 562 ; +C 35 ; WX 600 ; N numbersign ; B 56 -45 544 651 ; +C 36 ; WX 600 ; N dollar ; B 82 -126 519 666 ; +C 37 ; WX 600 ; N percent ; B 5 -15 595 616 ; +C 38 ; WX 600 ; N ampersand ; B 36 -15 546 543 ; +C 146 ; WX 600 ; N quoteright ; B 171 277 423 562 ; +C 40 ; WX 600 ; N parenleft ; B 219 -102 461 616 ; +C 41 ; WX 600 ; N parenright ; B 139 -102 381 616 ; +C 42 ; WX 600 ; N asterisk ; B 91 219 509 601 ; +C 43 ; WX 600 ; N plus ; B 71 39 529 478 ; +C 44 ; WX 600 ; N comma ; B 123 -111 393 174 ; +C 45 ; WX 600 ; N hyphen ; B 100 203 500 313 ; +C 173 ; WX 600 ; N hyphen ; B 100 203 500 313 ; +C 46 ; WX 600 ; N period ; B 192 -15 408 171 ; +C 47 ; WX 600 ; N slash ; B 98 -77 502 626 ; +C 48 ; WX 600 ; N zero ; B 87 -15 513 616 ; +C 49 ; WX 600 ; N one ; B 81 0 539 616 ; +C 50 ; WX 600 ; N two ; B 61 0 499 616 ; +C 51 ; WX 600 ; N three ; B 63 -15 501 616 ; +C 52 ; WX 600 ; N four ; B 53 0 507 616 ; +C 53 ; WX 600 ; N five ; B 70 -15 521 601 ; +C 54 ; WX 600 ; N six ; B 90 -15 521 616 ; +C 55 ; WX 600 ; N seven ; B 55 0 494 601 ; +C 56 ; WX 600 ; N eight ; B 83 -15 517 616 ; +C 57 ; WX 600 ; N nine ; B 79 -15 510 616 ; +C 58 ; WX 600 ; N colon ; B 191 -15 407 425 ; +C 59 ; WX 600 ; N semicolon ; B 123 -111 408 425 ; +C 60 ; WX 600 ; N less ; B 66 15 523 501 ; +C 61 ; WX 600 ; N equal ; B 71 118 529 398 ; +C 62 ; WX 600 ; N greater ; B 77 15 534 501 ; +C 63 ; WX 600 ; N question ; B 98 -14 501 580 ; +C 64 ; WX 600 ; N at ; B 16 -15 584 616 ; +C 65 ; WX 600 ; N A ; B -9 0 609 562 ; +C 66 ; WX 600 ; N B ; B 30 0 573 562 ; +C 67 ; WX 600 ; N C ; B 22 -18 560 580 ; +C 68 ; WX 600 ; N D ; B 30 0 594 562 ; +C 69 ; WX 600 ; N E ; B 25 0 560 562 ; +C 70 ; WX 600 ; N F ; B 39 0 570 562 ; +C 71 ; WX 600 ; N G ; B 22 -18 594 580 ; +C 72 ; WX 600 ; N H ; B 20 0 580 562 ; +C 73 ; WX 600 ; N I ; B 77 0 523 562 ; +C 74 ; WX 600 ; N J ; B 37 -18 601 562 ; +C 75 ; WX 600 ; N K ; B 21 0 599 562 ; +C 76 ; WX 600 ; N L ; B 39 0 578 562 ; +C 77 ; WX 600 ; N M ; B -2 0 602 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 610 562 ; +C 79 ; WX 600 ; N O ; B 22 -18 578 580 ; +C 80 ; WX 600 ; N P ; B 48 0 559 562 ; +C 81 ; WX 600 ; N Q ; B 32 -138 578 580 ; +C 82 ; WX 600 ; N R ; B 24 0 599 562 ; +C 83 ; WX 600 ; N S ; B 47 -22 553 582 ; +C 84 ; WX 600 ; N T ; B 21 0 579 562 ; +C 85 ; WX 600 ; N U ; B 4 -18 596 562 ; +C 86 ; WX 600 ; N V ; B -13 0 613 562 ; +C 87 ; WX 600 ; N W ; B -18 0 618 562 ; +C 88 ; WX 600 ; N X ; B 12 0 588 562 ; +C 89 ; WX 600 ; N Y ; B 12 0 589 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 539 562 ; +C 91 ; WX 600 ; N bracketleft ; B 245 -102 475 616 ; +C 92 ; WX 600 ; N backslash ; B 99 -77 503 626 ; +C 93 ; WX 600 ; N bracketright ; B 125 -102 355 616 ; +C 94 ; WX 600 ; N asciicircum ; B 108 250 492 616 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 145 ; WX 600 ; N quoteleft ; B 178 277 428 562 ; +C 97 ; WX 600 ; N a ; B 35 -15 570 454 ; +C 98 ; WX 600 ; N b ; B 0 -15 584 626 ; +C 99 ; WX 600 ; N c ; B 40 -15 545 459 ; +C 100 ; WX 600 ; N d ; B 20 -15 591 626 ; +C 101 ; WX 600 ; N e ; B 40 -15 563 454 ; +C 102 ; WX 600 ; N f ; B 83 0 547 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 30 -146 580 454 ; +C 104 ; WX 600 ; N h ; B 5 0 592 626 ; +C 105 ; WX 600 ; N i ; B 77 0 523 658 ; +C 106 ; WX 600 ; N j ; B 63 -146 440 658 ; +C 107 ; WX 600 ; N k ; B 20 0 585 626 ; +C 108 ; WX 600 ; N l ; B 77 0 523 626 ; +C 109 ; WX 600 ; N m ; B -22 0 626 454 ; +C 110 ; WX 600 ; N n ; B 18 0 592 454 ; +C 111 ; WX 600 ; N o ; B 30 -15 570 454 ; +C 112 ; WX 600 ; N p ; B -1 -142 570 454 ; +C 113 ; WX 600 ; N q ; B 20 -142 591 454 ; +C 114 ; WX 600 ; N r ; B 47 0 580 454 ; +C 115 ; WX 600 ; N s ; B 68 -17 535 459 ; +C 116 ; WX 600 ; N t ; B 47 -15 532 562 ; +C 117 ; WX 600 ; N u ; B -1 -15 569 439 ; +C 118 ; WX 600 ; N v ; B -1 0 601 439 ; +C 119 ; WX 600 ; N w ; B -18 0 618 439 ; +C 120 ; WX 600 ; N x ; B 6 0 594 439 ; +C 121 ; WX 600 ; N y ; B -4 -142 601 439 ; +C 122 ; WX 600 ; N z ; B 81 0 520 439 ; +C 123 ; WX 600 ; N braceleft ; B 160 -102 464 616 ; +C 124 ; WX 600 ; N bar ; B 255 -250 345 750 ; +C 125 ; WX 600 ; N braceright ; B 136 -102 440 616 ; +C 126 ; WX 600 ; N asciitilde ; B 71 153 530 356 ; +C 161 ; WX 600 ; N exclamdown ; B 202 -146 398 449 ; +C 162 ; WX 600 ; N cent ; B 66 -49 518 614 ; +C 163 ; WX 600 ; N sterling ; B 72 -28 558 611 ; +C -1 ; WX 600 ; N fraction ; B 25 -60 576 661 ; +C 165 ; WX 600 ; N yen ; B 10 0 590 562 ; +C 131 ; WX 600 ; N florin ; B -30 -131 572 616 ; +C 167 ; WX 600 ; N section ; B 83 -70 517 580 ; +C 164 ; WX 600 ; N currency ; B 54 49 546 517 ; +C 39 ; WX 600 ; N quotesingle ; B 227 277 373 562 ; +C 147 ; WX 600 ; N quotedblleft ; B 71 277 535 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 8 70 553 446 ; +C 139 ; WX 600 ; N guilsinglleft ; B 141 70 459 446 ; +C 155 ; WX 600 ; N guilsinglright ; B 141 70 459 446 ; +C -1 ; WX 600 ; N fi ; B 12 0 593 626 ; +C -1 ; WX 600 ; N fl ; B 12 0 593 626 ; +C 150 ; WX 600 ; N endash ; B 65 203 535 313 ; +C 134 ; WX 600 ; N dagger ; B 106 -70 494 580 ; +C 135 ; WX 600 ; N daggerdbl ; B 106 -70 494 580 ; +C 183 ; WX 600 ; N periodcentered ; B 196 165 404 351 ; +C 182 ; WX 600 ; N paragraph ; B 6 -70 576 580 ; +C 149 ; WX 600 ; N bullet ; B 140 132 460 430 ; +C 130 ; WX 600 ; N quotesinglbase ; B 175 -142 427 143 ; +C 132 ; WX 600 ; N quotedblbase ; B 65 -142 529 143 ; +C 148 ; WX 600 ; N quotedblright ; B 61 277 525 562 ; +C 187 ; WX 600 ; N guillemotright ; B 47 70 592 446 ; +C 133 ; WX 600 ; N ellipsis ; B 26 -15 574 116 ; +C 137 ; WX 600 ; N perthousand ; B -113 -15 713 616 ; +C 191 ; WX 600 ; N questiondown ; B 99 -146 502 449 ; +C 96 ; WX 600 ; N grave ; B 132 508 395 661 ; +C 180 ; WX 600 ; N acute ; B 205 508 468 661 ; +C 136 ; WX 600 ; N circumflex ; B 103 483 497 657 ; +C 152 ; WX 600 ; N tilde ; B 89 493 512 636 ; +C 175 ; WX 600 ; N macron ; B 88 505 512 585 ; +C -1 ; WX 600 ; N breve ; B 83 468 517 631 ; +C -1 ; WX 600 ; N dotaccent ; B 230 498 370 638 ; +C 168 ; WX 600 ; N dieresis ; B 128 498 472 638 ; +C -1 ; WX 600 ; N ring ; B 198 481 402 678 ; +C 184 ; WX 600 ; N cedilla ; B 205 -206 387 0 ; +C -1 ; WX 600 ; N hungarumlaut ; B 68 488 588 661 ; +C -1 ; WX 600 ; N ogonek ; B 169 -199 400 0 ; +C -1 ; WX 600 ; N caron ; B 103 493 497 667 ; +C 151 ; WX 600 ; N emdash ; B -10 203 610 313 ; +C 198 ; WX 600 ; N AE ; B -29 0 602 562 ; +C 170 ; WX 600 ; N ordfeminine ; B 147 196 453 580 ; +C -1 ; WX 600 ; N Lslash ; B 39 0 578 562 ; +C 216 ; WX 600 ; N Oslash ; B 22 -22 578 584 ; +C 140 ; WX 600 ; N OE ; B -25 0 595 562 ; +C 186 ; WX 600 ; N ordmasculine ; B 147 196 453 580 ; +C 230 ; WX 600 ; N ae ; B -4 -15 601 454 ; +C -1 ; WX 600 ; N dotlessi ; B 77 0 523 439 ; +C -1 ; WX 600 ; N lslash ; B 77 0 523 626 ; +C 248 ; WX 600 ; N oslash ; B 30 -24 570 463 ; +C 156 ; WX 600 ; N oe ; B -18 -15 611 454 ; +C 223 ; WX 600 ; N germandbls ; B 22 -15 596 626 ; +C 207 ; WX 600 ; N Idieresis ; B 77 0 523 761 ; +C 233 ; WX 600 ; N eacute ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N abreve ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B -1 -15 628 661 ; +C -1 ; WX 600 ; N ecaron ; B 40 -15 563 667 ; +C 159 ; WX 600 ; N Ydieresis ; B 12 0 589 761 ; +C 247 ; WX 600 ; N divide ; B 71 16 529 500 ; +C 221 ; WX 600 ; N Yacute ; B 12 0 589 784 ; +C 194 ; WX 600 ; N Acircumflex ; B -9 0 609 780 ; +C 225 ; WX 600 ; N aacute ; B 35 -15 570 661 ; +C 219 ; WX 600 ; N Ucircumflex ; B 4 -18 596 780 ; +C 253 ; WX 600 ; N yacute ; B -4 -142 601 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 68 -250 535 459 ; +C 234 ; WX 600 ; N ecircumflex ; B 40 -15 563 657 ; +C -1 ; WX 600 ; N Uring ; B 4 -18 596 801 ; +C 220 ; WX 600 ; N Udieresis ; B 4 -18 596 761 ; +C -1 ; WX 600 ; N aogonek ; B 35 -199 586 454 ; +C 218 ; WX 600 ; N Uacute ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N uogonek ; B -1 -199 585 439 ; +C 203 ; WX 600 ; N Edieresis ; B 25 0 560 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 594 562 ; +C -1 ; WX 600 ; N commaaccent ; B 205 -250 397 -57 ; +C 169 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 560 708 ; +C -1 ; WX 600 ; N ccaron ; B 40 -15 545 667 ; +C 229 ; WX 600 ; N aring ; B 35 -15 570 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 610 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 523 801 ; +C 224 ; WX 600 ; N agrave ; B 35 -15 570 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 21 -250 579 562 ; +C -1 ; WX 600 ; N Cacute ; B 22 -18 560 784 ; +C 227 ; WX 600 ; N atilde ; B 35 -15 570 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 560 761 ; +C 154 ; WX 600 ; N scaron ; B 68 -17 535 667 ; +C -1 ; WX 600 ; N scedilla ; B 68 -206 535 459 ; +C 237 ; WX 600 ; N iacute ; B 77 0 523 661 ; +C -1 ; WX 600 ; N lozenge ; B 66 0 534 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 599 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 22 -250 594 580 ; +C 251 ; WX 600 ; N ucircumflex ; B -1 -15 569 657 ; +C 226 ; WX 600 ; N acircumflex ; B 35 -15 570 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 609 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 580 667 ; +C 231 ; WX 600 ; N ccedilla ; B 40 -206 545 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 539 761 ; +C 222 ; WX 600 ; N Thorn ; B 48 0 557 562 ; +C -1 ; WX 600 ; N Omacron ; B 22 -18 578 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 599 784 ; +C -1 ; WX 600 ; N Sacute ; B 47 -22 553 784 ; +C -1 ; WX 600 ; N dcaron ; B 20 -15 727 626 ; +C -1 ; WX 600 ; N Umacron ; B 4 -18 596 708 ; +C -1 ; WX 600 ; N uring ; B -1 -15 569 678 ; +C 179 ; WX 600 ; N threesuperior ; B 138 222 433 616 ; +C 210 ; WX 600 ; N Ograve ; B 22 -18 578 784 ; +C 192 ; WX 600 ; N Agrave ; B -9 0 609 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 609 784 ; +C 215 ; WX 600 ; N multiply ; B 81 39 520 478 ; +C 250 ; WX 600 ; N uacute ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N Tcaron ; B 21 0 579 790 ; +C -1 ; WX 600 ; N partialdiff ; B 63 -38 537 728 ; +C 255 ; WX 600 ; N ydieresis ; B -4 -142 601 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 610 784 ; +C 238 ; WX 600 ; N icircumflex ; B 73 0 523 657 ; +C 202 ; WX 600 ; N Ecircumflex ; B 25 0 560 780 ; +C 228 ; WX 600 ; N adieresis ; B 35 -15 570 638 ; +C 235 ; WX 600 ; N edieresis ; B 40 -15 563 638 ; +C -1 ; WX 600 ; N cacute ; B 40 -15 545 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 592 661 ; +C -1 ; WX 600 ; N umacron ; B -1 -15 569 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 610 790 ; +C 205 ; WX 600 ; N Iacute ; B 77 0 523 784 ; +C 177 ; WX 600 ; N plusminus ; B 71 24 529 515 ; +C 166 ; WX 600 ; N brokenbar ; B 255 -175 345 675 ; +C 174 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 22 -18 594 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 523 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 586 706 ; +C 200 ; WX 600 ; N Egrave ; B 25 0 560 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 580 661 ; +C -1 ; WX 600 ; N omacron ; B 30 -15 570 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 539 784 ; +C 142 ; WX 600 ; N Zcaron ; B 62 0 539 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 523 696 ; +C 208 ; WX 600 ; N Eth ; B 30 0 594 562 ; +C 199 ; WX 600 ; N Ccedilla ; B 22 -206 560 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 523 626 ; +C -1 ; WX 600 ; N tcaron ; B 47 -15 532 703 ; +C -1 ; WX 600 ; N eogonek ; B 40 -199 563 454 ; +C -1 ; WX 600 ; N Uogonek ; B 4 -199 596 562 ; +C 193 ; WX 600 ; N Aacute ; B -9 0 609 784 ; +C 196 ; WX 600 ; N Adieresis ; B -9 0 609 761 ; +C 232 ; WX 600 ; N egrave ; B 40 -15 563 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 520 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 523 658 ; +C 211 ; WX 600 ; N Oacute ; B 22 -18 578 784 ; +C 243 ; WX 600 ; N oacute ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N amacron ; B 35 -15 570 585 ; +C -1 ; WX 600 ; N sacute ; B 68 -17 535 661 ; +C 239 ; WX 600 ; N idieresis ; B 77 0 523 618 ; +C 212 ; WX 600 ; N Ocircumflex ; B 22 -18 578 780 ; +C 217 ; WX 600 ; N Ugrave ; B 4 -18 596 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C 254 ; WX 600 ; N thorn ; B -14 -142 570 626 ; +C 178 ; WX 600 ; N twosuperior ; B 143 230 436 616 ; +C 214 ; WX 600 ; N Odieresis ; B 22 -18 578 761 ; +C 181 ; WX 600 ; N mu ; B -1 -142 569 439 ; +C 236 ; WX 600 ; N igrave ; B 77 0 523 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 30 -15 668 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 576 562 ; +C -1 ; WX 600 ; N dcroat ; B 20 -15 591 626 ; +C 190 ; WX 600 ; N threequarters ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N Scedilla ; B 47 -206 553 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 597 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 599 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 578 784 ; +C 153 ; WX 600 ; N trademark ; B -9 230 749 562 ; +C -1 ; WX 600 ; N edotaccent ; B 40 -15 563 638 ; +C 204 ; WX 600 ; N Igrave ; B 77 0 523 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 523 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 637 562 ; +C 189 ; WX 600 ; N onehalf ; B -47 -60 648 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 523 696 ; +C 244 ; WX 600 ; N ocircumflex ; B 30 -15 570 657 ; +C 241 ; WX 600 ; N ntilde ; B 18 0 592 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 4 -18 638 784 ; +C 201 ; WX 600 ; N Eacute ; B 25 0 560 784 ; +C -1 ; WX 600 ; N emacron ; B 40 -15 563 585 ; +C -1 ; WX 600 ; N gbreve ; B 30 -146 580 661 ; +C 188 ; WX 600 ; N onequarter ; B -56 -60 656 661 ; +C 138 ; WX 600 ; N Scaron ; B 47 -22 553 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 47 -250 553 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 22 -18 628 784 ; +C 176 ; WX 600 ; N degree ; B 86 243 474 616 ; +C 242 ; WX 600 ; N ograve ; B 30 -15 570 661 ; +C -1 ; WX 600 ; N Ccaron ; B 22 -18 560 790 ; +C 249 ; WX 600 ; N ugrave ; B -1 -15 569 661 ; +C -1 ; WX 600 ; N radical ; B -19 -104 473 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 594 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 580 454 ; +C 209 ; WX 600 ; N Ntilde ; B 8 -12 610 759 ; +C 245 ; WX 600 ; N otilde ; B 30 -15 570 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 599 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 578 562 ; +C 195 ; WX 600 ; N Atilde ; B -9 0 609 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 625 562 ; +C 197 ; WX 600 ; N Aring ; B -9 0 609 801 ; +C 213 ; WX 600 ; N Otilde ; B 22 -18 578 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 520 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 560 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 523 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 20 -250 585 626 ; +C -1 ; WX 600 ; N minus ; B 71 203 529 313 ; +C 206 ; WX 600 ; N Icircumflex ; B 77 0 523 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 592 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 47 -250 532 562 ; +C 172 ; WX 600 ; N logicalnot ; B 71 103 529 413 ; +C 246 ; WX 600 ; N odieresis ; B 30 -15 570 638 ; +C 252 ; WX 600 ; N udieresis ; B -1 -15 569 638 ; +C -1 ; WX 600 ; N notequal ; B 12 -47 537 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 30 -146 580 714 ; +C 240 ; WX 600 ; N eth ; B 58 -27 543 626 ; +C 158 ; WX 600 ; N zcaron ; B 81 0 520 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 592 454 ; +C 185 ; WX 600 ; N onesuperior ; B 153 230 447 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 523 585 ; +C 128 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/Courier-BoldOblique.afm b/vendor/dompdf/dompdf/lib/fonts/Courier-BoldOblique.afm new file mode 100644 index 0000000..d5b616e --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/Courier-BoldOblique.afm @@ -0,0 +1,344 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Mon Jun 23 16:28:46 0:00:00 +Comment UniqueID 43049 +Comment VMusage 17529 79244 +FontName Courier-BoldOblique +FullName Courier Bold Oblique +FamilyName Courier +Weight Bold +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -57 -250 869 801 +UnderlinePosition -100 +UnderlineThickness 50 +Version 3 +Notice Copyright (c) 1989, 1990, 1991, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme WinAnsiEncoding +CapHeight 562 +XHeight 439 +Ascender 629 +Descender -157 +StdHW 84 +StdVW 106 +StartCharMetrics 317 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 160 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 215 -15 495 572 ; +C 34 ; WX 600 ; N quotedbl ; B 211 277 585 562 ; +C 35 ; WX 600 ; N numbersign ; B 88 -45 641 651 ; +C 36 ; WX 600 ; N dollar ; B 87 -126 630 666 ; +C 37 ; WX 600 ; N percent ; B 101 -15 625 616 ; +C 38 ; WX 600 ; N ampersand ; B 61 -15 595 543 ; +C 146 ; WX 600 ; N quoteright ; B 229 277 543 562 ; +C 40 ; WX 600 ; N parenleft ; B 265 -102 592 616 ; +C 41 ; WX 600 ; N parenright ; B 117 -102 444 616 ; +C 42 ; WX 600 ; N asterisk ; B 179 219 598 601 ; +C 43 ; WX 600 ; N plus ; B 114 39 596 478 ; +C 44 ; WX 600 ; N comma ; B 99 -111 430 174 ; +C 45 ; WX 600 ; N hyphen ; B 143 203 567 313 ; +C 173 ; WX 600 ; N hyphen ; B 143 203 567 313 ; +C 46 ; WX 600 ; N period ; B 206 -15 427 171 ; +C 47 ; WX 600 ; N slash ; B 90 -77 626 626 ; +C 48 ; WX 600 ; N zero ; B 135 -15 593 616 ; +C 49 ; WX 600 ; N one ; B 93 0 562 616 ; +C 50 ; WX 600 ; N two ; B 61 0 594 616 ; +C 51 ; WX 600 ; N three ; B 71 -15 571 616 ; +C 52 ; WX 600 ; N four ; B 81 0 559 616 ; +C 53 ; WX 600 ; N five ; B 77 -15 621 601 ; +C 54 ; WX 600 ; N six ; B 135 -15 652 616 ; +C 55 ; WX 600 ; N seven ; B 147 0 622 601 ; +C 56 ; WX 600 ; N eight ; B 115 -15 604 616 ; +C 57 ; WX 600 ; N nine ; B 75 -15 592 616 ; +C 58 ; WX 600 ; N colon ; B 205 -15 480 425 ; +C 59 ; WX 600 ; N semicolon ; B 99 -111 481 425 ; +C 60 ; WX 600 ; N less ; B 120 15 613 501 ; +C 61 ; WX 600 ; N equal ; B 96 118 614 398 ; +C 62 ; WX 600 ; N greater ; B 97 15 589 501 ; +C 63 ; WX 600 ; N question ; B 183 -14 592 580 ; +C 64 ; WX 600 ; N at ; B 65 -15 642 616 ; +C 65 ; WX 600 ; N A ; B -9 0 632 562 ; +C 66 ; WX 600 ; N B ; B 30 0 630 562 ; +C 67 ; WX 600 ; N C ; B 74 -18 675 580 ; +C 68 ; WX 600 ; N D ; B 30 0 664 562 ; +C 69 ; WX 600 ; N E ; B 25 0 670 562 ; +C 70 ; WX 600 ; N F ; B 39 0 684 562 ; +C 71 ; WX 600 ; N G ; B 74 -18 675 580 ; +C 72 ; WX 600 ; N H ; B 20 0 700 562 ; +C 73 ; WX 600 ; N I ; B 77 0 643 562 ; +C 74 ; WX 600 ; N J ; B 58 -18 721 562 ; +C 75 ; WX 600 ; N K ; B 21 0 692 562 ; +C 76 ; WX 600 ; N L ; B 39 0 636 562 ; +C 77 ; WX 600 ; N M ; B -2 0 722 562 ; +C 78 ; WX 600 ; N N ; B 8 -12 730 562 ; +C 79 ; WX 600 ; N O ; B 74 -18 645 580 ; +C 80 ; WX 600 ; N P ; B 48 0 643 562 ; +C 81 ; WX 600 ; N Q ; B 83 -138 636 580 ; +C 82 ; WX 600 ; N R ; B 24 0 617 562 ; +C 83 ; WX 600 ; N S ; B 54 -22 673 582 ; +C 84 ; WX 600 ; N T ; B 86 0 679 562 ; +C 85 ; WX 600 ; N U ; B 101 -18 716 562 ; +C 86 ; WX 600 ; N V ; B 84 0 733 562 ; +C 87 ; WX 600 ; N W ; B 79 0 738 562 ; +C 88 ; WX 600 ; N X ; B 12 0 690 562 ; +C 89 ; WX 600 ; N Y ; B 109 0 709 562 ; +C 90 ; WX 600 ; N Z ; B 62 0 637 562 ; +C 91 ; WX 600 ; N bracketleft ; B 223 -102 606 616 ; +C 92 ; WX 600 ; N backslash ; B 222 -77 496 626 ; +C 93 ; WX 600 ; N bracketright ; B 103 -102 486 616 ; +C 94 ; WX 600 ; N asciicircum ; B 171 250 556 616 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 585 -75 ; +C 145 ; WX 600 ; N quoteleft ; B 297 277 487 562 ; +C 97 ; WX 600 ; N a ; B 61 -15 593 454 ; +C 98 ; WX 600 ; N b ; B 13 -15 636 626 ; +C 99 ; WX 600 ; N c ; B 81 -15 631 459 ; +C 100 ; WX 600 ; N d ; B 60 -15 645 626 ; +C 101 ; WX 600 ; N e ; B 81 -15 605 454 ; +C 102 ; WX 600 ; N f ; B 83 0 677 626 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 40 -146 674 454 ; +C 104 ; WX 600 ; N h ; B 18 0 615 626 ; +C 105 ; WX 600 ; N i ; B 77 0 546 658 ; +C 106 ; WX 600 ; N j ; B 36 -146 580 658 ; +C 107 ; WX 600 ; N k ; B 33 0 643 626 ; +C 108 ; WX 600 ; N l ; B 77 0 546 626 ; +C 109 ; WX 600 ; N m ; B -22 0 649 454 ; +C 110 ; WX 600 ; N n ; B 18 0 615 454 ; +C 111 ; WX 600 ; N o ; B 71 -15 622 454 ; +C 112 ; WX 600 ; N p ; B -32 -142 622 454 ; +C 113 ; WX 600 ; N q ; B 60 -142 685 454 ; +C 114 ; WX 600 ; N r ; B 47 0 655 454 ; +C 115 ; WX 600 ; N s ; B 66 -17 608 459 ; +C 116 ; WX 600 ; N t ; B 118 -15 567 562 ; +C 117 ; WX 600 ; N u ; B 70 -15 592 439 ; +C 118 ; WX 600 ; N v ; B 70 0 695 439 ; +C 119 ; WX 600 ; N w ; B 53 0 712 439 ; +C 120 ; WX 600 ; N x ; B 6 0 671 439 ; +C 121 ; WX 600 ; N y ; B -21 -142 695 439 ; +C 122 ; WX 600 ; N z ; B 81 0 614 439 ; +C 123 ; WX 600 ; N braceleft ; B 203 -102 595 616 ; +C 124 ; WX 600 ; N bar ; B 201 -250 505 750 ; +C 125 ; WX 600 ; N braceright ; B 114 -102 506 616 ; +C 126 ; WX 600 ; N asciitilde ; B 120 153 590 356 ; +C 161 ; WX 600 ; N exclamdown ; B 196 -146 477 449 ; +C 162 ; WX 600 ; N cent ; B 121 -49 605 614 ; +C 163 ; WX 600 ; N sterling ; B 106 -28 650 611 ; +C -1 ; WX 600 ; N fraction ; B 22 -60 708 661 ; +C 165 ; WX 600 ; N yen ; B 98 0 710 562 ; +C 131 ; WX 600 ; N florin ; B -57 -131 702 616 ; +C 167 ; WX 600 ; N section ; B 74 -70 620 580 ; +C 164 ; WX 600 ; N currency ; B 77 49 644 517 ; +C 39 ; WX 600 ; N quotesingle ; B 303 277 493 562 ; +C 147 ; WX 600 ; N quotedblleft ; B 190 277 594 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 62 70 639 446 ; +C 139 ; WX 600 ; N guilsinglleft ; B 195 70 545 446 ; +C 155 ; WX 600 ; N guilsinglright ; B 165 70 514 446 ; +C -1 ; WX 600 ; N fi ; B 12 0 644 626 ; +C -1 ; WX 600 ; N fl ; B 12 0 644 626 ; +C 150 ; WX 600 ; N endash ; B 108 203 602 313 ; +C 134 ; WX 600 ; N dagger ; B 175 -70 586 580 ; +C 135 ; WX 600 ; N daggerdbl ; B 121 -70 587 580 ; +C 183 ; WX 600 ; N periodcentered ; B 248 165 461 351 ; +C 182 ; WX 600 ; N paragraph ; B 61 -70 700 580 ; +C 149 ; WX 600 ; N bullet ; B 196 132 523 430 ; +C 130 ; WX 600 ; N quotesinglbase ; B 144 -142 458 143 ; +C 132 ; WX 600 ; N quotedblbase ; B 34 -142 560 143 ; +C 148 ; WX 600 ; N quotedblright ; B 119 277 645 562 ; +C 187 ; WX 600 ; N guillemotright ; B 71 70 647 446 ; +C 133 ; WX 600 ; N ellipsis ; B 35 -15 587 116 ; +C 137 ; WX 600 ; N perthousand ; B -45 -15 743 616 ; +C 191 ; WX 600 ; N questiondown ; B 100 -146 509 449 ; +C 96 ; WX 600 ; N grave ; B 272 508 503 661 ; +C 180 ; WX 600 ; N acute ; B 312 508 609 661 ; +C 136 ; WX 600 ; N circumflex ; B 212 483 607 657 ; +C 152 ; WX 600 ; N tilde ; B 199 493 643 636 ; +C 175 ; WX 600 ; N macron ; B 195 505 637 585 ; +C -1 ; WX 600 ; N breve ; B 217 468 652 631 ; +C -1 ; WX 600 ; N dotaccent ; B 348 498 493 638 ; +C 168 ; WX 600 ; N dieresis ; B 246 498 595 638 ; +C -1 ; WX 600 ; N ring ; B 319 481 528 678 ; +C 184 ; WX 600 ; N cedilla ; B 168 -206 368 0 ; +C -1 ; WX 600 ; N hungarumlaut ; B 171 488 729 661 ; +C -1 ; WX 600 ; N ogonek ; B 143 -199 367 0 ; +C -1 ; WX 600 ; N caron ; B 238 493 633 667 ; +C 151 ; WX 600 ; N emdash ; B 33 203 677 313 ; +C 198 ; WX 600 ; N AE ; B -29 0 708 562 ; +C 170 ; WX 600 ; N ordfeminine ; B 188 196 526 580 ; +C -1 ; WX 600 ; N Lslash ; B 39 0 636 562 ; +C 216 ; WX 600 ; N Oslash ; B 48 -22 673 584 ; +C 140 ; WX 600 ; N OE ; B 26 0 701 562 ; +C 186 ; WX 600 ; N ordmasculine ; B 188 196 543 580 ; +C 230 ; WX 600 ; N ae ; B 21 -15 652 454 ; +C -1 ; WX 600 ; N dotlessi ; B 77 0 546 439 ; +C -1 ; WX 600 ; N lslash ; B 77 0 587 626 ; +C 248 ; WX 600 ; N oslash ; B 54 -24 638 463 ; +C 156 ; WX 600 ; N oe ; B 18 -15 662 454 ; +C 223 ; WX 600 ; N germandbls ; B 22 -15 629 626 ; +C 207 ; WX 600 ; N Idieresis ; B 77 0 643 761 ; +C 233 ; WX 600 ; N eacute ; B 81 -15 609 661 ; +C -1 ; WX 600 ; N abreve ; B 61 -15 658 661 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 70 -15 769 661 ; +C -1 ; WX 600 ; N ecaron ; B 81 -15 633 667 ; +C 159 ; WX 600 ; N Ydieresis ; B 109 0 709 761 ; +C 247 ; WX 600 ; N divide ; B 114 16 596 500 ; +C 221 ; WX 600 ; N Yacute ; B 109 0 709 784 ; +C 194 ; WX 600 ; N Acircumflex ; B -9 0 632 780 ; +C 225 ; WX 600 ; N aacute ; B 61 -15 609 661 ; +C 219 ; WX 600 ; N Ucircumflex ; B 101 -18 716 780 ; +C 253 ; WX 600 ; N yacute ; B -21 -142 695 661 ; +C -1 ; WX 600 ; N scommaaccent ; B 66 -250 608 459 ; +C 234 ; WX 600 ; N ecircumflex ; B 81 -15 607 657 ; +C -1 ; WX 600 ; N Uring ; B 101 -18 716 801 ; +C 220 ; WX 600 ; N Udieresis ; B 101 -18 716 761 ; +C -1 ; WX 600 ; N aogonek ; B 61 -199 593 454 ; +C 218 ; WX 600 ; N Uacute ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N uogonek ; B 70 -199 592 439 ; +C 203 ; WX 600 ; N Edieresis ; B 25 0 670 761 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 664 562 ; +C -1 ; WX 600 ; N commaaccent ; B 151 -250 385 -57 ; +C 169 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 25 0 670 708 ; +C -1 ; WX 600 ; N ccaron ; B 81 -15 633 667 ; +C 229 ; WX 600 ; N aring ; B 61 -15 593 678 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 8 -250 730 562 ; +C -1 ; WX 600 ; N lacute ; B 77 0 639 801 ; +C 224 ; WX 600 ; N agrave ; B 61 -15 593 661 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 86 -250 679 562 ; +C -1 ; WX 600 ; N Cacute ; B 74 -18 675 784 ; +C 227 ; WX 600 ; N atilde ; B 61 -15 643 636 ; +C -1 ; WX 600 ; N Edotaccent ; B 25 0 670 761 ; +C 154 ; WX 600 ; N scaron ; B 66 -17 633 667 ; +C -1 ; WX 600 ; N scedilla ; B 66 -206 608 459 ; +C 237 ; WX 600 ; N iacute ; B 77 0 609 661 ; +C -1 ; WX 600 ; N lozenge ; B 145 0 614 740 ; +C -1 ; WX 600 ; N Rcaron ; B 24 0 659 790 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 74 -250 675 580 ; +C 251 ; WX 600 ; N ucircumflex ; B 70 -15 597 657 ; +C 226 ; WX 600 ; N acircumflex ; B 61 -15 607 657 ; +C -1 ; WX 600 ; N Amacron ; B -9 0 633 708 ; +C -1 ; WX 600 ; N rcaron ; B 47 0 655 667 ; +C 231 ; WX 600 ; N ccedilla ; B 81 -206 631 459 ; +C -1 ; WX 600 ; N Zdotaccent ; B 62 0 637 761 ; +C 222 ; WX 600 ; N Thorn ; B 48 0 620 562 ; +C -1 ; WX 600 ; N Omacron ; B 74 -18 663 708 ; +C -1 ; WX 600 ; N Racute ; B 24 0 665 784 ; +C -1 ; WX 600 ; N Sacute ; B 54 -22 673 784 ; +C -1 ; WX 600 ; N dcaron ; B 60 -15 861 626 ; +C -1 ; WX 600 ; N Umacron ; B 101 -18 716 708 ; +C -1 ; WX 600 ; N uring ; B 70 -15 592 678 ; +C 179 ; WX 600 ; N threesuperior ; B 193 222 526 616 ; +C 210 ; WX 600 ; N Ograve ; B 74 -18 645 784 ; +C 192 ; WX 600 ; N Agrave ; B -9 0 632 784 ; +C -1 ; WX 600 ; N Abreve ; B -9 0 684 784 ; +C 215 ; WX 600 ; N multiply ; B 104 39 606 478 ; +C 250 ; WX 600 ; N uacute ; B 70 -15 599 661 ; +C -1 ; WX 600 ; N Tcaron ; B 86 0 679 790 ; +C -1 ; WX 600 ; N partialdiff ; B 91 -38 627 728 ; +C 255 ; WX 600 ; N ydieresis ; B -21 -142 695 638 ; +C -1 ; WX 600 ; N Nacute ; B 8 -12 730 784 ; +C 238 ; WX 600 ; N icircumflex ; B 77 0 577 657 ; +C 202 ; WX 600 ; N Ecircumflex ; B 25 0 670 780 ; +C 228 ; WX 600 ; N adieresis ; B 61 -15 595 638 ; +C 235 ; WX 600 ; N edieresis ; B 81 -15 605 638 ; +C -1 ; WX 600 ; N cacute ; B 81 -15 649 661 ; +C -1 ; WX 600 ; N nacute ; B 18 0 639 661 ; +C -1 ; WX 600 ; N umacron ; B 70 -15 637 585 ; +C -1 ; WX 600 ; N Ncaron ; B 8 -12 730 790 ; +C 205 ; WX 600 ; N Iacute ; B 77 0 643 784 ; +C 177 ; WX 600 ; N plusminus ; B 76 24 614 515 ; +C 166 ; WX 600 ; N brokenbar ; B 217 -175 489 675 ; +C 174 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 74 -18 684 784 ; +C -1 ; WX 600 ; N Idotaccent ; B 77 0 643 761 ; +C -1 ; WX 600 ; N summation ; B 15 -10 672 706 ; +C 200 ; WX 600 ; N Egrave ; B 25 0 670 784 ; +C -1 ; WX 600 ; N racute ; B 47 0 655 661 ; +C -1 ; WX 600 ; N omacron ; B 71 -15 637 585 ; +C -1 ; WX 600 ; N Zacute ; B 62 0 665 784 ; +C 142 ; WX 600 ; N Zcaron ; B 62 0 659 790 ; +C -1 ; WX 600 ; N greaterequal ; B 26 0 627 696 ; +C 208 ; WX 600 ; N Eth ; B 30 0 664 562 ; +C 199 ; WX 600 ; N Ccedilla ; B 74 -206 675 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 77 -250 546 626 ; +C -1 ; WX 600 ; N tcaron ; B 118 -15 627 703 ; +C -1 ; WX 600 ; N eogonek ; B 81 -199 605 454 ; +C -1 ; WX 600 ; N Uogonek ; B 101 -199 716 562 ; +C 193 ; WX 600 ; N Aacute ; B -9 0 655 784 ; +C 196 ; WX 600 ; N Adieresis ; B -9 0 632 761 ; +C 232 ; WX 600 ; N egrave ; B 81 -15 605 661 ; +C -1 ; WX 600 ; N zacute ; B 81 0 614 661 ; +C -1 ; WX 600 ; N iogonek ; B 77 -199 546 658 ; +C 211 ; WX 600 ; N Oacute ; B 74 -18 645 784 ; +C 243 ; WX 600 ; N oacute ; B 71 -15 649 661 ; +C -1 ; WX 600 ; N amacron ; B 61 -15 637 585 ; +C -1 ; WX 600 ; N sacute ; B 66 -17 609 661 ; +C 239 ; WX 600 ; N idieresis ; B 77 0 561 618 ; +C 212 ; WX 600 ; N Ocircumflex ; B 74 -18 645 780 ; +C 217 ; WX 600 ; N Ugrave ; B 101 -18 716 784 ; +C -1 ; WX 600 ; N Delta ; B 6 0 594 688 ; +C 254 ; WX 600 ; N thorn ; B -32 -142 622 626 ; +C 178 ; WX 600 ; N twosuperior ; B 191 230 542 616 ; +C 214 ; WX 600 ; N Odieresis ; B 74 -18 645 761 ; +C 181 ; WX 600 ; N mu ; B 49 -142 592 439 ; +C 236 ; WX 600 ; N igrave ; B 77 0 546 661 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 71 -15 809 661 ; +C -1 ; WX 600 ; N Eogonek ; B 25 -199 670 562 ; +C -1 ; WX 600 ; N dcroat ; B 60 -15 712 626 ; +C 190 ; WX 600 ; N threequarters ; B 8 -60 699 661 ; +C -1 ; WX 600 ; N Scedilla ; B 54 -206 673 582 ; +C -1 ; WX 600 ; N lcaron ; B 77 0 731 626 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 21 -250 692 562 ; +C -1 ; WX 600 ; N Lacute ; B 39 0 636 784 ; +C 153 ; WX 600 ; N trademark ; B 86 230 869 562 ; +C -1 ; WX 600 ; N edotaccent ; B 81 -15 605 638 ; +C 204 ; WX 600 ; N Igrave ; B 77 0 643 784 ; +C -1 ; WX 600 ; N Imacron ; B 77 0 663 708 ; +C -1 ; WX 600 ; N Lcaron ; B 39 0 757 562 ; +C 189 ; WX 600 ; N onehalf ; B 22 -60 716 661 ; +C -1 ; WX 600 ; N lessequal ; B 26 0 671 696 ; +C 244 ; WX 600 ; N ocircumflex ; B 71 -15 622 657 ; +C 241 ; WX 600 ; N ntilde ; B 18 0 643 636 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 101 -18 805 784 ; +C 201 ; WX 600 ; N Eacute ; B 25 0 670 784 ; +C -1 ; WX 600 ; N emacron ; B 81 -15 637 585 ; +C -1 ; WX 600 ; N gbreve ; B 40 -146 674 661 ; +C 188 ; WX 600 ; N onequarter ; B 13 -60 707 661 ; +C 138 ; WX 600 ; N Scaron ; B 54 -22 689 790 ; +C -1 ; WX 600 ; N Scommaaccent ; B 54 -250 673 582 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 74 -18 795 784 ; +C 176 ; WX 600 ; N degree ; B 173 243 570 616 ; +C 242 ; WX 600 ; N ograve ; B 71 -15 622 661 ; +C -1 ; WX 600 ; N Ccaron ; B 74 -18 689 790 ; +C 249 ; WX 600 ; N ugrave ; B 70 -15 592 661 ; +C -1 ; WX 600 ; N radical ; B 67 -104 635 778 ; +C -1 ; WX 600 ; N Dcaron ; B 30 0 664 790 ; +C -1 ; WX 600 ; N rcommaaccent ; B 47 -250 655 454 ; +C 209 ; WX 600 ; N Ntilde ; B 8 -12 730 759 ; +C 245 ; WX 600 ; N otilde ; B 71 -15 643 636 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 24 -250 617 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 39 -250 636 562 ; +C 195 ; WX 600 ; N Atilde ; B -9 0 669 759 ; +C -1 ; WX 600 ; N Aogonek ; B -9 -199 632 562 ; +C 197 ; WX 600 ; N Aring ; B -9 0 632 801 ; +C 213 ; WX 600 ; N Otilde ; B 74 -18 669 759 ; +C -1 ; WX 600 ; N zdotaccent ; B 81 0 614 638 ; +C -1 ; WX 600 ; N Ecaron ; B 25 0 670 790 ; +C -1 ; WX 600 ; N Iogonek ; B 77 -199 643 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 33 -250 643 626 ; +C -1 ; WX 600 ; N minus ; B 114 203 596 313 ; +C 206 ; WX 600 ; N Icircumflex ; B 77 0 643 780 ; +C -1 ; WX 600 ; N ncaron ; B 18 0 633 667 ; +C -1 ; WX 600 ; N tcommaaccent ; B 118 -250 567 562 ; +C 172 ; WX 600 ; N logicalnot ; B 135 103 617 413 ; +C 246 ; WX 600 ; N odieresis ; B 71 -15 622 638 ; +C 252 ; WX 600 ; N udieresis ; B 70 -15 595 638 ; +C -1 ; WX 600 ; N notequal ; B 30 -47 626 563 ; +C -1 ; WX 600 ; N gcommaaccent ; B 40 -146 674 714 ; +C 240 ; WX 600 ; N eth ; B 93 -27 661 626 ; +C 158 ; WX 600 ; N zcaron ; B 81 0 643 667 ; +C -1 ; WX 600 ; N ncommaaccent ; B 18 -250 615 454 ; +C 185 ; WX 600 ; N onesuperior ; B 212 230 514 616 ; +C -1 ; WX 600 ; N imacron ; B 77 0 575 585 ; +C 128 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/Courier-Oblique.afm b/vendor/dompdf/dompdf/lib/fonts/Courier-Oblique.afm new file mode 100644 index 0000000..c8893ff --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/Courier-Oblique.afm @@ -0,0 +1,344 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 0:00:00 17:37:52 1997 +Comment UniqueID 43051 +Comment VMusage 16248 75829 +FontName Courier-Oblique +FullName Courier Oblique +FamilyName Courier +Weight Medium +ItalicAngle -12 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -27 -250 849 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme WinAnsiEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 317 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 160 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 243 -15 464 572 ; +C 34 ; WX 600 ; N quotedbl ; B 273 328 532 562 ; +C 35 ; WX 600 ; N numbersign ; B 133 -32 596 639 ; +C 36 ; WX 600 ; N dollar ; B 108 -126 596 662 ; +C 37 ; WX 600 ; N percent ; B 134 -15 599 622 ; +C 38 ; WX 600 ; N ampersand ; B 87 -15 580 543 ; +C 146 ; WX 600 ; N quoteright ; B 283 328 495 562 ; +C 40 ; WX 600 ; N parenleft ; B 313 -108 572 622 ; +C 41 ; WX 600 ; N parenright ; B 137 -108 396 622 ; +C 42 ; WX 600 ; N asterisk ; B 212 257 580 607 ; +C 43 ; WX 600 ; N plus ; B 129 44 580 470 ; +C 44 ; WX 600 ; N comma ; B 157 -112 370 122 ; +C 45 ; WX 600 ; N hyphen ; B 152 231 558 285 ; +C 173 ; WX 600 ; N hyphen ; B 152 231 558 285 ; +C 46 ; WX 600 ; N period ; B 238 -15 382 109 ; +C 47 ; WX 600 ; N slash ; B 112 -80 604 629 ; +C 48 ; WX 600 ; N zero ; B 154 -15 575 622 ; +C 49 ; WX 600 ; N one ; B 98 0 515 622 ; +C 50 ; WX 600 ; N two ; B 70 0 568 622 ; +C 51 ; WX 600 ; N three ; B 82 -15 538 622 ; +C 52 ; WX 600 ; N four ; B 108 0 541 622 ; +C 53 ; WX 600 ; N five ; B 99 -15 589 607 ; +C 54 ; WX 600 ; N six ; B 155 -15 629 622 ; +C 55 ; WX 600 ; N seven ; B 182 0 612 607 ; +C 56 ; WX 600 ; N eight ; B 132 -15 588 622 ; +C 57 ; WX 600 ; N nine ; B 93 -15 574 622 ; +C 58 ; WX 600 ; N colon ; B 238 -15 441 385 ; +C 59 ; WX 600 ; N semicolon ; B 157 -112 441 385 ; +C 60 ; WX 600 ; N less ; B 96 42 610 472 ; +C 61 ; WX 600 ; N equal ; B 109 138 600 376 ; +C 62 ; WX 600 ; N greater ; B 85 42 599 472 ; +C 63 ; WX 600 ; N question ; B 222 -15 583 572 ; +C 64 ; WX 600 ; N at ; B 127 -15 582 622 ; +C 65 ; WX 600 ; N A ; B 3 0 607 562 ; +C 66 ; WX 600 ; N B ; B 43 0 616 562 ; +C 67 ; WX 600 ; N C ; B 93 -18 655 580 ; +C 68 ; WX 600 ; N D ; B 43 0 645 562 ; +C 69 ; WX 600 ; N E ; B 53 0 660 562 ; +C 70 ; WX 600 ; N F ; B 53 0 660 562 ; +C 71 ; WX 600 ; N G ; B 83 -18 645 580 ; +C 72 ; WX 600 ; N H ; B 32 0 687 562 ; +C 73 ; WX 600 ; N I ; B 96 0 623 562 ; +C 74 ; WX 600 ; N J ; B 52 -18 685 562 ; +C 75 ; WX 600 ; N K ; B 38 0 671 562 ; +C 76 ; WX 600 ; N L ; B 47 0 607 562 ; +C 77 ; WX 600 ; N M ; B 4 0 715 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 712 562 ; +C 79 ; WX 600 ; N O ; B 94 -18 625 580 ; +C 80 ; WX 600 ; N P ; B 79 0 644 562 ; +C 81 ; WX 600 ; N Q ; B 95 -138 625 580 ; +C 82 ; WX 600 ; N R ; B 38 0 598 562 ; +C 83 ; WX 600 ; N S ; B 76 -20 650 580 ; +C 84 ; WX 600 ; N T ; B 108 0 665 562 ; +C 85 ; WX 600 ; N U ; B 125 -18 702 562 ; +C 86 ; WX 600 ; N V ; B 105 -13 723 562 ; +C 87 ; WX 600 ; N W ; B 106 -13 722 562 ; +C 88 ; WX 600 ; N X ; B 23 0 675 562 ; +C 89 ; WX 600 ; N Y ; B 133 0 695 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 610 562 ; +C 91 ; WX 600 ; N bracketleft ; B 246 -108 574 622 ; +C 92 ; WX 600 ; N backslash ; B 249 -80 468 629 ; +C 93 ; WX 600 ; N bracketright ; B 135 -108 463 622 ; +C 94 ; WX 600 ; N asciicircum ; B 175 354 587 622 ; +C 95 ; WX 600 ; N underscore ; B -27 -125 584 -75 ; +C 145 ; WX 600 ; N quoteleft ; B 343 328 457 562 ; +C 97 ; WX 600 ; N a ; B 76 -15 569 441 ; +C 98 ; WX 600 ; N b ; B 29 -15 625 629 ; +C 99 ; WX 600 ; N c ; B 106 -15 608 441 ; +C 100 ; WX 600 ; N d ; B 85 -15 640 629 ; +C 101 ; WX 600 ; N e ; B 106 -15 598 441 ; +C 102 ; WX 600 ; N f ; B 114 0 662 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 61 -157 657 441 ; +C 104 ; WX 600 ; N h ; B 33 0 592 629 ; +C 105 ; WX 600 ; N i ; B 95 0 515 657 ; +C 106 ; WX 600 ; N j ; B 52 -157 550 657 ; +C 107 ; WX 600 ; N k ; B 58 0 633 629 ; +C 108 ; WX 600 ; N l ; B 95 0 515 629 ; +C 109 ; WX 600 ; N m ; B -5 0 615 441 ; +C 110 ; WX 600 ; N n ; B 26 0 585 441 ; +C 111 ; WX 600 ; N o ; B 102 -15 588 441 ; +C 112 ; WX 600 ; N p ; B -24 -157 605 441 ; +C 113 ; WX 600 ; N q ; B 85 -157 682 441 ; +C 114 ; WX 600 ; N r ; B 60 0 636 441 ; +C 115 ; WX 600 ; N s ; B 78 -15 584 441 ; +C 116 ; WX 600 ; N t ; B 167 -15 561 561 ; +C 117 ; WX 600 ; N u ; B 101 -15 572 426 ; +C 118 ; WX 600 ; N v ; B 90 -10 681 426 ; +C 119 ; WX 600 ; N w ; B 76 -10 695 426 ; +C 120 ; WX 600 ; N x ; B 20 0 655 426 ; +C 121 ; WX 600 ; N y ; B -4 -157 683 426 ; +C 122 ; WX 600 ; N z ; B 99 0 593 426 ; +C 123 ; WX 600 ; N braceleft ; B 233 -108 569 622 ; +C 124 ; WX 600 ; N bar ; B 222 -250 485 750 ; +C 125 ; WX 600 ; N braceright ; B 140 -108 477 622 ; +C 126 ; WX 600 ; N asciitilde ; B 116 197 600 320 ; +C 161 ; WX 600 ; N exclamdown ; B 225 -157 445 430 ; +C 162 ; WX 600 ; N cent ; B 151 -49 588 614 ; +C 163 ; WX 600 ; N sterling ; B 124 -21 621 611 ; +C -1 ; WX 600 ; N fraction ; B 84 -57 646 665 ; +C 165 ; WX 600 ; N yen ; B 120 0 693 562 ; +C 131 ; WX 600 ; N florin ; B -26 -143 671 622 ; +C 167 ; WX 600 ; N section ; B 104 -78 590 580 ; +C 164 ; WX 600 ; N currency ; B 94 58 628 506 ; +C 39 ; WX 600 ; N quotesingle ; B 345 328 460 562 ; +C 147 ; WX 600 ; N quotedblleft ; B 262 328 541 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 92 70 652 446 ; +C 139 ; WX 600 ; N guilsinglleft ; B 204 70 540 446 ; +C 155 ; WX 600 ; N guilsinglright ; B 170 70 506 446 ; +C -1 ; WX 600 ; N fi ; B 3 0 619 629 ; +C -1 ; WX 600 ; N fl ; B 3 0 619 629 ; +C 150 ; WX 600 ; N endash ; B 124 231 586 285 ; +C 134 ; WX 600 ; N dagger ; B 217 -78 546 580 ; +C 135 ; WX 600 ; N daggerdbl ; B 163 -78 546 580 ; +C 183 ; WX 600 ; N periodcentered ; B 275 189 434 327 ; +C 182 ; WX 600 ; N paragraph ; B 100 -78 630 562 ; +C 149 ; WX 600 ; N bullet ; B 224 130 485 383 ; +C 130 ; WX 600 ; N quotesinglbase ; B 185 -134 397 100 ; +C 132 ; WX 600 ; N quotedblbase ; B 115 -134 478 100 ; +C 148 ; WX 600 ; N quotedblright ; B 213 328 576 562 ; +C 187 ; WX 600 ; N guillemotright ; B 58 70 618 446 ; +C 133 ; WX 600 ; N ellipsis ; B 46 -15 575 111 ; +C 137 ; WX 600 ; N perthousand ; B 59 -15 627 622 ; +C 191 ; WX 600 ; N questiondown ; B 105 -157 466 430 ; +C 96 ; WX 600 ; N grave ; B 294 497 484 672 ; +C 180 ; WX 600 ; N acute ; B 348 497 612 672 ; +C 136 ; WX 600 ; N circumflex ; B 229 477 581 654 ; +C 152 ; WX 600 ; N tilde ; B 212 489 629 606 ; +C 175 ; WX 600 ; N macron ; B 232 525 600 565 ; +C -1 ; WX 600 ; N breve ; B 279 501 576 609 ; +C -1 ; WX 600 ; N dotaccent ; B 373 537 478 640 ; +C 168 ; WX 600 ; N dieresis ; B 272 537 579 640 ; +C -1 ; WX 600 ; N ring ; B 332 463 500 627 ; +C 184 ; WX 600 ; N cedilla ; B 197 -151 344 10 ; +C -1 ; WX 600 ; N hungarumlaut ; B 239 497 683 672 ; +C -1 ; WX 600 ; N ogonek ; B 189 -172 377 4 ; +C -1 ; WX 600 ; N caron ; B 262 492 614 669 ; +C 151 ; WX 600 ; N emdash ; B 49 231 661 285 ; +C 198 ; WX 600 ; N AE ; B 3 0 655 562 ; +C 170 ; WX 600 ; N ordfeminine ; B 209 249 512 580 ; +C -1 ; WX 600 ; N Lslash ; B 47 0 607 562 ; +C 216 ; WX 600 ; N Oslash ; B 94 -80 625 629 ; +C 140 ; WX 600 ; N OE ; B 59 0 672 562 ; +C 186 ; WX 600 ; N ordmasculine ; B 210 249 535 580 ; +C 230 ; WX 600 ; N ae ; B 41 -15 626 441 ; +C -1 ; WX 600 ; N dotlessi ; B 95 0 515 426 ; +C -1 ; WX 600 ; N lslash ; B 95 0 587 629 ; +C 248 ; WX 600 ; N oslash ; B 102 -80 588 506 ; +C 156 ; WX 600 ; N oe ; B 54 -15 615 441 ; +C 223 ; WX 600 ; N germandbls ; B 48 -15 617 629 ; +C 207 ; WX 600 ; N Idieresis ; B 96 0 623 753 ; +C 233 ; WX 600 ; N eacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N abreve ; B 76 -15 576 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 101 -15 723 672 ; +C -1 ; WX 600 ; N ecaron ; B 106 -15 614 669 ; +C 159 ; WX 600 ; N Ydieresis ; B 133 0 695 753 ; +C 247 ; WX 600 ; N divide ; B 136 48 573 467 ; +C 221 ; WX 600 ; N Yacute ; B 133 0 695 805 ; +C 194 ; WX 600 ; N Acircumflex ; B 3 0 607 787 ; +C 225 ; WX 600 ; N aacute ; B 76 -15 612 672 ; +C 219 ; WX 600 ; N Ucircumflex ; B 125 -18 702 787 ; +C 253 ; WX 600 ; N yacute ; B -4 -157 683 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 78 -250 584 441 ; +C 234 ; WX 600 ; N ecircumflex ; B 106 -15 598 654 ; +C -1 ; WX 600 ; N Uring ; B 125 -18 702 760 ; +C 220 ; WX 600 ; N Udieresis ; B 125 -18 702 753 ; +C -1 ; WX 600 ; N aogonek ; B 76 -172 569 441 ; +C 218 ; WX 600 ; N Uacute ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N uogonek ; B 101 -172 572 426 ; +C 203 ; WX 600 ; N Edieresis ; B 53 0 660 753 ; +C -1 ; WX 600 ; N Dcroat ; B 43 0 645 562 ; +C -1 ; WX 600 ; N commaaccent ; B 145 -250 323 -58 ; +C 169 ; WX 600 ; N copyright ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 660 698 ; +C -1 ; WX 600 ; N ccaron ; B 106 -15 614 669 ; +C 229 ; WX 600 ; N aring ; B 76 -15 569 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 712 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 640 805 ; +C 224 ; WX 600 ; N agrave ; B 76 -15 569 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 108 -250 665 562 ; +C -1 ; WX 600 ; N Cacute ; B 93 -18 655 805 ; +C 227 ; WX 600 ; N atilde ; B 76 -15 629 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 660 753 ; +C 154 ; WX 600 ; N scaron ; B 78 -15 614 669 ; +C -1 ; WX 600 ; N scedilla ; B 78 -151 584 441 ; +C 237 ; WX 600 ; N iacute ; B 95 0 612 672 ; +C -1 ; WX 600 ; N lozenge ; B 94 0 519 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 642 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 83 -250 645 580 ; +C 251 ; WX 600 ; N ucircumflex ; B 101 -15 572 654 ; +C 226 ; WX 600 ; N acircumflex ; B 76 -15 581 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 607 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 636 669 ; +C 231 ; WX 600 ; N ccedilla ; B 106 -151 614 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 610 753 ; +C 222 ; WX 600 ; N Thorn ; B 79 0 606 562 ; +C -1 ; WX 600 ; N Omacron ; B 94 -18 628 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 670 805 ; +C -1 ; WX 600 ; N Sacute ; B 76 -20 650 805 ; +C -1 ; WX 600 ; N dcaron ; B 85 -15 849 629 ; +C -1 ; WX 600 ; N Umacron ; B 125 -18 702 698 ; +C -1 ; WX 600 ; N uring ; B 101 -15 572 627 ; +C 179 ; WX 600 ; N threesuperior ; B 213 240 501 622 ; +C 210 ; WX 600 ; N Ograve ; B 94 -18 625 805 ; +C 192 ; WX 600 ; N Agrave ; B 3 0 607 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 607 732 ; +C 215 ; WX 600 ; N multiply ; B 103 43 607 470 ; +C 250 ; WX 600 ; N uacute ; B 101 -15 602 672 ; +C -1 ; WX 600 ; N Tcaron ; B 108 0 665 802 ; +C -1 ; WX 600 ; N partialdiff ; B 45 -38 546 710 ; +C 255 ; WX 600 ; N ydieresis ; B -4 -157 683 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 712 805 ; +C 238 ; WX 600 ; N icircumflex ; B 95 0 551 654 ; +C 202 ; WX 600 ; N Ecircumflex ; B 53 0 660 787 ; +C 228 ; WX 600 ; N adieresis ; B 76 -15 575 620 ; +C 235 ; WX 600 ; N edieresis ; B 106 -15 598 620 ; +C -1 ; WX 600 ; N cacute ; B 106 -15 612 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 602 672 ; +C -1 ; WX 600 ; N umacron ; B 101 -15 600 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 712 802 ; +C 205 ; WX 600 ; N Iacute ; B 96 0 640 805 ; +C 177 ; WX 600 ; N plusminus ; B 96 44 594 558 ; +C 166 ; WX 600 ; N brokenbar ; B 238 -175 469 675 ; +C 174 ; WX 600 ; N registered ; B 53 -18 667 580 ; +C -1 ; WX 600 ; N Gbreve ; B 83 -18 645 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 623 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 670 706 ; +C 200 ; WX 600 ; N Egrave ; B 53 0 660 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 636 672 ; +C -1 ; WX 600 ; N omacron ; B 102 -15 600 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 670 805 ; +C 142 ; WX 600 ; N Zcaron ; B 86 0 642 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 594 710 ; +C 208 ; WX 600 ; N Eth ; B 43 0 645 562 ; +C 199 ; WX 600 ; N Ccedilla ; B 93 -151 658 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 515 629 ; +C -1 ; WX 600 ; N tcaron ; B 167 -15 587 717 ; +C -1 ; WX 600 ; N eogonek ; B 106 -172 598 441 ; +C -1 ; WX 600 ; N Uogonek ; B 124 -172 702 562 ; +C 193 ; WX 600 ; N Aacute ; B 3 0 660 805 ; +C 196 ; WX 600 ; N Adieresis ; B 3 0 607 753 ; +C 232 ; WX 600 ; N egrave ; B 106 -15 598 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 612 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 515 657 ; +C 211 ; WX 600 ; N Oacute ; B 94 -18 640 805 ; +C 243 ; WX 600 ; N oacute ; B 102 -15 612 672 ; +C -1 ; WX 600 ; N amacron ; B 76 -15 600 565 ; +C -1 ; WX 600 ; N sacute ; B 78 -15 612 672 ; +C 239 ; WX 600 ; N idieresis ; B 95 0 545 620 ; +C 212 ; WX 600 ; N Ocircumflex ; B 94 -18 625 787 ; +C 217 ; WX 600 ; N Ugrave ; B 125 -18 702 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C 254 ; WX 600 ; N thorn ; B -24 -157 605 629 ; +C 178 ; WX 600 ; N twosuperior ; B 230 249 535 622 ; +C 214 ; WX 600 ; N Odieresis ; B 94 -18 625 753 ; +C 181 ; WX 600 ; N mu ; B 72 -157 572 426 ; +C 236 ; WX 600 ; N igrave ; B 95 0 515 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 102 -15 723 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 660 562 ; +C -1 ; WX 600 ; N dcroat ; B 85 -15 704 629 ; +C 190 ; WX 600 ; N threequarters ; B 73 -56 659 666 ; +C -1 ; WX 600 ; N Scedilla ; B 76 -151 650 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 667 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 671 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 607 805 ; +C 153 ; WX 600 ; N trademark ; B 75 263 742 562 ; +C -1 ; WX 600 ; N edotaccent ; B 106 -15 598 620 ; +C 204 ; WX 600 ; N Igrave ; B 96 0 623 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 628 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 632 562 ; +C 189 ; WX 600 ; N onehalf ; B 65 -57 669 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 645 710 ; +C 244 ; WX 600 ; N ocircumflex ; B 102 -15 588 654 ; +C 241 ; WX 600 ; N ntilde ; B 26 0 629 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 125 -18 761 805 ; +C 201 ; WX 600 ; N Eacute ; B 53 0 670 805 ; +C -1 ; WX 600 ; N emacron ; B 106 -15 600 565 ; +C -1 ; WX 600 ; N gbreve ; B 61 -157 657 609 ; +C 188 ; WX 600 ; N onequarter ; B 65 -57 674 665 ; +C 138 ; WX 600 ; N Scaron ; B 76 -20 672 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 76 -250 650 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 94 -18 751 805 ; +C 176 ; WX 600 ; N degree ; B 214 269 576 622 ; +C 242 ; WX 600 ; N ograve ; B 102 -15 588 672 ; +C -1 ; WX 600 ; N Ccaron ; B 93 -18 672 802 ; +C 249 ; WX 600 ; N ugrave ; B 101 -15 572 672 ; +C -1 ; WX 600 ; N radical ; B 85 -15 765 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 645 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 636 441 ; +C 209 ; WX 600 ; N Ntilde ; B 7 -13 712 729 ; +C 245 ; WX 600 ; N otilde ; B 102 -15 629 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 598 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 607 562 ; +C 195 ; WX 600 ; N Atilde ; B 3 0 655 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 607 562 ; +C 197 ; WX 600 ; N Aring ; B 3 0 607 750 ; +C 213 ; WX 600 ; N Otilde ; B 94 -18 655 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 593 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 660 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 623 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 58 -250 633 629 ; +C -1 ; WX 600 ; N minus ; B 129 232 580 283 ; +C 206 ; WX 600 ; N Icircumflex ; B 96 0 623 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 614 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 165 -250 561 561 ; +C 172 ; WX 600 ; N logicalnot ; B 155 108 591 369 ; +C 246 ; WX 600 ; N odieresis ; B 102 -15 588 620 ; +C 252 ; WX 600 ; N udieresis ; B 101 -15 575 620 ; +C -1 ; WX 600 ; N notequal ; B 43 -16 621 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 61 -157 657 708 ; +C 240 ; WX 600 ; N eth ; B 102 -15 639 629 ; +C 158 ; WX 600 ; N zcaron ; B 99 0 624 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 585 441 ; +C 185 ; WX 600 ; N onesuperior ; B 231 249 491 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 543 565 ; +C 128 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/Courier.afm b/vendor/dompdf/dompdf/lib/fonts/Courier.afm new file mode 100644 index 0000000..fb77a74 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/Courier.afm @@ -0,0 +1,344 @@ +StartFontMetrics 4.1 +Comment Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +Comment Creation Date: Thu May 1 17:27:09 1997 +Comment UniqueID 43050 +Comment VMusage 39754 50779 +FontName Courier +FullName Courier +FamilyName Courier +Weight Medium +ItalicAngle 0 +IsFixedPitch true +CharacterSet ExtendedRoman +FontBBox -23 -250 715 805 +UnderlinePosition -100 +UnderlineThickness 50 +Version 003.000 +Notice Copyright (c) 1989, 1990, 1991, 1992, 1993, 1997 Adobe Systems Incorporated. All Rights Reserved. +EncodingScheme WinAnsiEncoding +CapHeight 562 +XHeight 426 +Ascender 629 +Descender -157 +StdHW 51 +StdVW 51 +StartCharMetrics 317 +C 32 ; WX 600 ; N space ; B 0 0 0 0 ; +C 160 ; WX 600 ; N space ; B 0 0 0 0 ; +C 33 ; WX 600 ; N exclam ; B 236 -15 364 572 ; +C 34 ; WX 600 ; N quotedbl ; B 187 328 413 562 ; +C 35 ; WX 600 ; N numbersign ; B 93 -32 507 639 ; +C 36 ; WX 600 ; N dollar ; B 105 -126 496 662 ; +C 37 ; WX 600 ; N percent ; B 81 -15 518 622 ; +C 38 ; WX 600 ; N ampersand ; B 63 -15 538 543 ; +C 146 ; WX 600 ; N quoteright ; B 213 328 376 562 ; +C 40 ; WX 600 ; N parenleft ; B 269 -108 440 622 ; +C 41 ; WX 600 ; N parenright ; B 160 -108 331 622 ; +C 42 ; WX 600 ; N asterisk ; B 116 257 484 607 ; +C 43 ; WX 600 ; N plus ; B 80 44 520 470 ; +C 44 ; WX 600 ; N comma ; B 181 -112 344 122 ; +C 45 ; WX 600 ; N hyphen ; B 103 231 497 285 ; +C 173 ; WX 600 ; N hyphen ; B 103 231 497 285 ; +C 46 ; WX 600 ; N period ; B 229 -15 371 109 ; +C 47 ; WX 600 ; N slash ; B 125 -80 475 629 ; +C 48 ; WX 600 ; N zero ; B 106 -15 494 622 ; +C 49 ; WX 600 ; N one ; B 96 0 505 622 ; +C 50 ; WX 600 ; N two ; B 70 0 471 622 ; +C 51 ; WX 600 ; N three ; B 75 -15 466 622 ; +C 52 ; WX 600 ; N four ; B 78 0 500 622 ; +C 53 ; WX 600 ; N five ; B 92 -15 497 607 ; +C 54 ; WX 600 ; N six ; B 111 -15 497 622 ; +C 55 ; WX 600 ; N seven ; B 82 0 483 607 ; +C 56 ; WX 600 ; N eight ; B 102 -15 498 622 ; +C 57 ; WX 600 ; N nine ; B 96 -15 489 622 ; +C 58 ; WX 600 ; N colon ; B 229 -15 371 385 ; +C 59 ; WX 600 ; N semicolon ; B 181 -112 371 385 ; +C 60 ; WX 600 ; N less ; B 41 42 519 472 ; +C 61 ; WX 600 ; N equal ; B 80 138 520 376 ; +C 62 ; WX 600 ; N greater ; B 66 42 544 472 ; +C 63 ; WX 600 ; N question ; B 129 -15 492 572 ; +C 64 ; WX 600 ; N at ; B 77 -15 533 622 ; +C 65 ; WX 600 ; N A ; B 3 0 597 562 ; +C 66 ; WX 600 ; N B ; B 43 0 559 562 ; +C 67 ; WX 600 ; N C ; B 41 -18 540 580 ; +C 68 ; WX 600 ; N D ; B 43 0 574 562 ; +C 69 ; WX 600 ; N E ; B 53 0 550 562 ; +C 70 ; WX 600 ; N F ; B 53 0 545 562 ; +C 71 ; WX 600 ; N G ; B 31 -18 575 580 ; +C 72 ; WX 600 ; N H ; B 32 0 568 562 ; +C 73 ; WX 600 ; N I ; B 96 0 504 562 ; +C 74 ; WX 600 ; N J ; B 34 -18 566 562 ; +C 75 ; WX 600 ; N K ; B 38 0 582 562 ; +C 76 ; WX 600 ; N L ; B 47 0 554 562 ; +C 77 ; WX 600 ; N M ; B 4 0 596 562 ; +C 78 ; WX 600 ; N N ; B 7 -13 593 562 ; +C 79 ; WX 600 ; N O ; B 43 -18 557 580 ; +C 80 ; WX 600 ; N P ; B 79 0 558 562 ; +C 81 ; WX 600 ; N Q ; B 43 -138 557 580 ; +C 82 ; WX 600 ; N R ; B 38 0 588 562 ; +C 83 ; WX 600 ; N S ; B 72 -20 529 580 ; +C 84 ; WX 600 ; N T ; B 38 0 563 562 ; +C 85 ; WX 600 ; N U ; B 17 -18 583 562 ; +C 86 ; WX 600 ; N V ; B -4 -13 604 562 ; +C 87 ; WX 600 ; N W ; B -3 -13 603 562 ; +C 88 ; WX 600 ; N X ; B 23 0 577 562 ; +C 89 ; WX 600 ; N Y ; B 24 0 576 562 ; +C 90 ; WX 600 ; N Z ; B 86 0 514 562 ; +C 91 ; WX 600 ; N bracketleft ; B 269 -108 442 622 ; +C 92 ; WX 600 ; N backslash ; B 118 -80 482 629 ; +C 93 ; WX 600 ; N bracketright ; B 158 -108 331 622 ; +C 94 ; WX 600 ; N asciicircum ; B 94 354 506 622 ; +C 95 ; WX 600 ; N underscore ; B 0 -125 600 -75 ; +C 145 ; WX 600 ; N quoteleft ; B 224 328 387 562 ; +C 97 ; WX 600 ; N a ; B 53 -15 559 441 ; +C 98 ; WX 600 ; N b ; B 14 -15 575 629 ; +C 99 ; WX 600 ; N c ; B 66 -15 529 441 ; +C 100 ; WX 600 ; N d ; B 45 -15 591 629 ; +C 101 ; WX 600 ; N e ; B 66 -15 548 441 ; +C 102 ; WX 600 ; N f ; B 114 0 531 629 ; L i fi ; L l fl ; +C 103 ; WX 600 ; N g ; B 45 -157 566 441 ; +C 104 ; WX 600 ; N h ; B 18 0 582 629 ; +C 105 ; WX 600 ; N i ; B 95 0 505 657 ; +C 106 ; WX 600 ; N j ; B 82 -157 410 657 ; +C 107 ; WX 600 ; N k ; B 43 0 580 629 ; +C 108 ; WX 600 ; N l ; B 95 0 505 629 ; +C 109 ; WX 600 ; N m ; B -5 0 605 441 ; +C 110 ; WX 600 ; N n ; B 26 0 575 441 ; +C 111 ; WX 600 ; N o ; B 62 -15 538 441 ; +C 112 ; WX 600 ; N p ; B 9 -157 555 441 ; +C 113 ; WX 600 ; N q ; B 45 -157 591 441 ; +C 114 ; WX 600 ; N r ; B 60 0 559 441 ; +C 115 ; WX 600 ; N s ; B 80 -15 513 441 ; +C 116 ; WX 600 ; N t ; B 87 -15 530 561 ; +C 117 ; WX 600 ; N u ; B 21 -15 562 426 ; +C 118 ; WX 600 ; N v ; B 10 -10 590 426 ; +C 119 ; WX 600 ; N w ; B -4 -10 604 426 ; +C 120 ; WX 600 ; N x ; B 20 0 580 426 ; +C 121 ; WX 600 ; N y ; B 7 -157 592 426 ; +C 122 ; WX 600 ; N z ; B 99 0 502 426 ; +C 123 ; WX 600 ; N braceleft ; B 182 -108 437 622 ; +C 124 ; WX 600 ; N bar ; B 275 -250 326 750 ; +C 125 ; WX 600 ; N braceright ; B 163 -108 418 622 ; +C 126 ; WX 600 ; N asciitilde ; B 63 197 540 320 ; +C 161 ; WX 600 ; N exclamdown ; B 236 -157 364 430 ; +C 162 ; WX 600 ; N cent ; B 96 -49 500 614 ; +C 163 ; WX 600 ; N sterling ; B 84 -21 521 611 ; +C -1 ; WX 600 ; N fraction ; B 92 -57 509 665 ; +C 165 ; WX 600 ; N yen ; B 26 0 574 562 ; +C 131 ; WX 600 ; N florin ; B 4 -143 539 622 ; +C 167 ; WX 600 ; N section ; B 113 -78 488 580 ; +C 164 ; WX 600 ; N currency ; B 73 58 527 506 ; +C 39 ; WX 600 ; N quotesingle ; B 259 328 341 562 ; +C 147 ; WX 600 ; N quotedblleft ; B 143 328 471 562 ; +C 171 ; WX 600 ; N guillemotleft ; B 37 70 563 446 ; +C 139 ; WX 600 ; N guilsinglleft ; B 149 70 451 446 ; +C 155 ; WX 600 ; N guilsinglright ; B 149 70 451 446 ; +C -1 ; WX 600 ; N fi ; B 3 0 597 629 ; +C -1 ; WX 600 ; N fl ; B 3 0 597 629 ; +C 150 ; WX 600 ; N endash ; B 75 231 525 285 ; +C 134 ; WX 600 ; N dagger ; B 141 -78 459 580 ; +C 135 ; WX 600 ; N daggerdbl ; B 141 -78 459 580 ; +C 183 ; WX 600 ; N periodcentered ; B 222 189 378 327 ; +C 182 ; WX 600 ; N paragraph ; B 50 -78 511 562 ; +C 149 ; WX 600 ; N bullet ; B 172 130 428 383 ; +C 130 ; WX 600 ; N quotesinglbase ; B 213 -134 376 100 ; +C 132 ; WX 600 ; N quotedblbase ; B 143 -134 457 100 ; +C 148 ; WX 600 ; N quotedblright ; B 143 328 457 562 ; +C 187 ; WX 600 ; N guillemotright ; B 37 70 563 446 ; +C 133 ; WX 600 ; N ellipsis ; B 37 -15 563 111 ; +C 137 ; WX 600 ; N perthousand ; B 3 -15 600 622 ; +C 191 ; WX 600 ; N questiondown ; B 108 -157 471 430 ; +C 96 ; WX 600 ; N grave ; B 151 497 378 672 ; +C 180 ; WX 600 ; N acute ; B 242 497 469 672 ; +C 136 ; WX 600 ; N circumflex ; B 124 477 476 654 ; +C 152 ; WX 600 ; N tilde ; B 105 489 503 606 ; +C 175 ; WX 600 ; N macron ; B 120 525 480 565 ; +C -1 ; WX 600 ; N breve ; B 153 501 447 609 ; +C -1 ; WX 600 ; N dotaccent ; B 249 537 352 640 ; +C 168 ; WX 600 ; N dieresis ; B 148 537 453 640 ; +C -1 ; WX 600 ; N ring ; B 218 463 382 627 ; +C 184 ; WX 600 ; N cedilla ; B 224 -151 362 10 ; +C -1 ; WX 600 ; N hungarumlaut ; B 133 497 540 672 ; +C -1 ; WX 600 ; N ogonek ; B 211 -172 407 4 ; +C -1 ; WX 600 ; N caron ; B 124 492 476 669 ; +C 151 ; WX 600 ; N emdash ; B 0 231 600 285 ; +C 198 ; WX 600 ; N AE ; B 3 0 550 562 ; +C 170 ; WX 600 ; N ordfeminine ; B 156 249 442 580 ; +C -1 ; WX 600 ; N Lslash ; B 47 0 554 562 ; +C 216 ; WX 600 ; N Oslash ; B 43 -80 557 629 ; +C 140 ; WX 600 ; N OE ; B 7 0 567 562 ; +C 186 ; WX 600 ; N ordmasculine ; B 157 249 443 580 ; +C 230 ; WX 600 ; N ae ; B 19 -15 570 441 ; +C -1 ; WX 600 ; N dotlessi ; B 95 0 505 426 ; +C -1 ; WX 600 ; N lslash ; B 95 0 505 629 ; +C 248 ; WX 600 ; N oslash ; B 62 -80 538 506 ; +C 156 ; WX 600 ; N oe ; B 19 -15 559 441 ; +C 223 ; WX 600 ; N germandbls ; B 48 -15 588 629 ; +C 207 ; WX 600 ; N Idieresis ; B 96 0 504 753 ; +C 233 ; WX 600 ; N eacute ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N abreve ; B 53 -15 559 609 ; +C -1 ; WX 600 ; N uhungarumlaut ; B 21 -15 580 672 ; +C -1 ; WX 600 ; N ecaron ; B 66 -15 548 669 ; +C 159 ; WX 600 ; N Ydieresis ; B 24 0 576 753 ; +C 247 ; WX 600 ; N divide ; B 87 48 513 467 ; +C 221 ; WX 600 ; N Yacute ; B 24 0 576 805 ; +C 194 ; WX 600 ; N Acircumflex ; B 3 0 597 787 ; +C 225 ; WX 600 ; N aacute ; B 53 -15 559 672 ; +C 219 ; WX 600 ; N Ucircumflex ; B 17 -18 583 787 ; +C 253 ; WX 600 ; N yacute ; B 7 -157 592 672 ; +C -1 ; WX 600 ; N scommaaccent ; B 80 -250 513 441 ; +C 234 ; WX 600 ; N ecircumflex ; B 66 -15 548 654 ; +C -1 ; WX 600 ; N Uring ; B 17 -18 583 760 ; +C 220 ; WX 600 ; N Udieresis ; B 17 -18 583 753 ; +C -1 ; WX 600 ; N aogonek ; B 53 -172 587 441 ; +C 218 ; WX 600 ; N Uacute ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N uogonek ; B 21 -172 590 426 ; +C 203 ; WX 600 ; N Edieresis ; B 53 0 550 753 ; +C -1 ; WX 600 ; N Dcroat ; B 30 0 574 562 ; +C -1 ; WX 600 ; N commaaccent ; B 198 -250 335 -58 ; +C 169 ; WX 600 ; N copyright ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Emacron ; B 53 0 550 698 ; +C -1 ; WX 600 ; N ccaron ; B 66 -15 529 669 ; +C 229 ; WX 600 ; N aring ; B 53 -15 559 627 ; +C -1 ; WX 600 ; N Ncommaaccent ; B 7 -250 593 562 ; +C -1 ; WX 600 ; N lacute ; B 95 0 505 805 ; +C 224 ; WX 600 ; N agrave ; B 53 -15 559 672 ; +C -1 ; WX 600 ; N Tcommaaccent ; B 38 -250 563 562 ; +C -1 ; WX 600 ; N Cacute ; B 41 -18 540 805 ; +C 227 ; WX 600 ; N atilde ; B 53 -15 559 606 ; +C -1 ; WX 600 ; N Edotaccent ; B 53 0 550 753 ; +C 154 ; WX 600 ; N scaron ; B 80 -15 513 669 ; +C -1 ; WX 600 ; N scedilla ; B 80 -151 513 441 ; +C 237 ; WX 600 ; N iacute ; B 95 0 505 672 ; +C -1 ; WX 600 ; N lozenge ; B 18 0 443 706 ; +C -1 ; WX 600 ; N Rcaron ; B 38 0 588 802 ; +C -1 ; WX 600 ; N Gcommaaccent ; B 31 -250 575 580 ; +C 251 ; WX 600 ; N ucircumflex ; B 21 -15 562 654 ; +C 226 ; WX 600 ; N acircumflex ; B 53 -15 559 654 ; +C -1 ; WX 600 ; N Amacron ; B 3 0 597 698 ; +C -1 ; WX 600 ; N rcaron ; B 60 0 559 669 ; +C 231 ; WX 600 ; N ccedilla ; B 66 -151 529 441 ; +C -1 ; WX 600 ; N Zdotaccent ; B 86 0 514 753 ; +C 222 ; WX 600 ; N Thorn ; B 79 0 538 562 ; +C -1 ; WX 600 ; N Omacron ; B 43 -18 557 698 ; +C -1 ; WX 600 ; N Racute ; B 38 0 588 805 ; +C -1 ; WX 600 ; N Sacute ; B 72 -20 529 805 ; +C -1 ; WX 600 ; N dcaron ; B 45 -15 715 629 ; +C -1 ; WX 600 ; N Umacron ; B 17 -18 583 698 ; +C -1 ; WX 600 ; N uring ; B 21 -15 562 627 ; +C 179 ; WX 600 ; N threesuperior ; B 155 240 406 622 ; +C 210 ; WX 600 ; N Ograve ; B 43 -18 557 805 ; +C 192 ; WX 600 ; N Agrave ; B 3 0 597 805 ; +C -1 ; WX 600 ; N Abreve ; B 3 0 597 732 ; +C 215 ; WX 600 ; N multiply ; B 87 43 515 470 ; +C 250 ; WX 600 ; N uacute ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N Tcaron ; B 38 0 563 802 ; +C -1 ; WX 600 ; N partialdiff ; B 17 -38 459 710 ; +C 255 ; WX 600 ; N ydieresis ; B 7 -157 592 620 ; +C -1 ; WX 600 ; N Nacute ; B 7 -13 593 805 ; +C 238 ; WX 600 ; N icircumflex ; B 94 0 505 654 ; +C 202 ; WX 600 ; N Ecircumflex ; B 53 0 550 787 ; +C 228 ; WX 600 ; N adieresis ; B 53 -15 559 620 ; +C 235 ; WX 600 ; N edieresis ; B 66 -15 548 620 ; +C -1 ; WX 600 ; N cacute ; B 66 -15 529 672 ; +C -1 ; WX 600 ; N nacute ; B 26 0 575 672 ; +C -1 ; WX 600 ; N umacron ; B 21 -15 562 565 ; +C -1 ; WX 600 ; N Ncaron ; B 7 -13 593 802 ; +C 205 ; WX 600 ; N Iacute ; B 96 0 504 805 ; +C 177 ; WX 600 ; N plusminus ; B 87 44 513 558 ; +C 166 ; WX 600 ; N brokenbar ; B 275 -175 326 675 ; +C 174 ; WX 600 ; N registered ; B 0 -18 600 580 ; +C -1 ; WX 600 ; N Gbreve ; B 31 -18 575 732 ; +C -1 ; WX 600 ; N Idotaccent ; B 96 0 504 753 ; +C -1 ; WX 600 ; N summation ; B 15 -10 585 706 ; +C 200 ; WX 600 ; N Egrave ; B 53 0 550 805 ; +C -1 ; WX 600 ; N racute ; B 60 0 559 672 ; +C -1 ; WX 600 ; N omacron ; B 62 -15 538 565 ; +C -1 ; WX 600 ; N Zacute ; B 86 0 514 805 ; +C 142 ; WX 600 ; N Zcaron ; B 86 0 514 802 ; +C -1 ; WX 600 ; N greaterequal ; B 98 0 502 710 ; +C 208 ; WX 600 ; N Eth ; B 30 0 574 562 ; +C 199 ; WX 600 ; N Ccedilla ; B 41 -151 540 580 ; +C -1 ; WX 600 ; N lcommaaccent ; B 95 -250 505 629 ; +C -1 ; WX 600 ; N tcaron ; B 87 -15 530 717 ; +C -1 ; WX 600 ; N eogonek ; B 66 -172 548 441 ; +C -1 ; WX 600 ; N Uogonek ; B 17 -172 583 562 ; +C 193 ; WX 600 ; N Aacute ; B 3 0 597 805 ; +C 196 ; WX 600 ; N Adieresis ; B 3 0 597 753 ; +C 232 ; WX 600 ; N egrave ; B 66 -15 548 672 ; +C -1 ; WX 600 ; N zacute ; B 99 0 502 672 ; +C -1 ; WX 600 ; N iogonek ; B 95 -172 505 657 ; +C 211 ; WX 600 ; N Oacute ; B 43 -18 557 805 ; +C 243 ; WX 600 ; N oacute ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N amacron ; B 53 -15 559 565 ; +C -1 ; WX 600 ; N sacute ; B 80 -15 513 672 ; +C 239 ; WX 600 ; N idieresis ; B 95 0 505 620 ; +C 212 ; WX 600 ; N Ocircumflex ; B 43 -18 557 787 ; +C 217 ; WX 600 ; N Ugrave ; B 17 -18 583 805 ; +C -1 ; WX 600 ; N Delta ; B 6 0 598 688 ; +C 254 ; WX 600 ; N thorn ; B -6 -157 555 629 ; +C 178 ; WX 600 ; N twosuperior ; B 177 249 424 622 ; +C 214 ; WX 600 ; N Odieresis ; B 43 -18 557 753 ; +C 181 ; WX 600 ; N mu ; B 21 -157 562 426 ; +C 236 ; WX 600 ; N igrave ; B 95 0 505 672 ; +C -1 ; WX 600 ; N ohungarumlaut ; B 62 -15 580 672 ; +C -1 ; WX 600 ; N Eogonek ; B 53 -172 561 562 ; +C -1 ; WX 600 ; N dcroat ; B 45 -15 591 629 ; +C 190 ; WX 600 ; N threequarters ; B 8 -56 593 666 ; +C -1 ; WX 600 ; N Scedilla ; B 72 -151 529 580 ; +C -1 ; WX 600 ; N lcaron ; B 95 0 533 629 ; +C -1 ; WX 600 ; N Kcommaaccent ; B 38 -250 582 562 ; +C -1 ; WX 600 ; N Lacute ; B 47 0 554 805 ; +C 153 ; WX 600 ; N trademark ; B -23 263 623 562 ; +C -1 ; WX 600 ; N edotaccent ; B 66 -15 548 620 ; +C 204 ; WX 600 ; N Igrave ; B 96 0 504 805 ; +C -1 ; WX 600 ; N Imacron ; B 96 0 504 698 ; +C -1 ; WX 600 ; N Lcaron ; B 47 0 554 562 ; +C 189 ; WX 600 ; N onehalf ; B 0 -57 611 665 ; +C -1 ; WX 600 ; N lessequal ; B 98 0 502 710 ; +C 244 ; WX 600 ; N ocircumflex ; B 62 -15 538 654 ; +C 241 ; WX 600 ; N ntilde ; B 26 0 575 606 ; +C -1 ; WX 600 ; N Uhungarumlaut ; B 17 -18 590 805 ; +C 201 ; WX 600 ; N Eacute ; B 53 0 550 805 ; +C -1 ; WX 600 ; N emacron ; B 66 -15 548 565 ; +C -1 ; WX 600 ; N gbreve ; B 45 -157 566 609 ; +C 188 ; WX 600 ; N onequarter ; B 0 -57 600 665 ; +C 138 ; WX 600 ; N Scaron ; B 72 -20 529 802 ; +C -1 ; WX 600 ; N Scommaaccent ; B 72 -250 529 580 ; +C -1 ; WX 600 ; N Ohungarumlaut ; B 43 -18 580 805 ; +C 176 ; WX 600 ; N degree ; B 123 269 477 622 ; +C 242 ; WX 600 ; N ograve ; B 62 -15 538 672 ; +C -1 ; WX 600 ; N Ccaron ; B 41 -18 540 802 ; +C 249 ; WX 600 ; N ugrave ; B 21 -15 562 672 ; +C -1 ; WX 600 ; N radical ; B 3 -15 597 792 ; +C -1 ; WX 600 ; N Dcaron ; B 43 0 574 802 ; +C -1 ; WX 600 ; N rcommaaccent ; B 60 -250 559 441 ; +C 209 ; WX 600 ; N Ntilde ; B 7 -13 593 729 ; +C 245 ; WX 600 ; N otilde ; B 62 -15 538 606 ; +C -1 ; WX 600 ; N Rcommaaccent ; B 38 -250 588 562 ; +C -1 ; WX 600 ; N Lcommaaccent ; B 47 -250 554 562 ; +C 195 ; WX 600 ; N Atilde ; B 3 0 597 729 ; +C -1 ; WX 600 ; N Aogonek ; B 3 -172 608 562 ; +C 197 ; WX 600 ; N Aring ; B 3 0 597 750 ; +C 213 ; WX 600 ; N Otilde ; B 43 -18 557 729 ; +C -1 ; WX 600 ; N zdotaccent ; B 99 0 502 620 ; +C -1 ; WX 600 ; N Ecaron ; B 53 0 550 802 ; +C -1 ; WX 600 ; N Iogonek ; B 96 -172 504 562 ; +C -1 ; WX 600 ; N kcommaaccent ; B 43 -250 580 629 ; +C -1 ; WX 600 ; N minus ; B 80 232 520 283 ; +C 206 ; WX 600 ; N Icircumflex ; B 96 0 504 787 ; +C -1 ; WX 600 ; N ncaron ; B 26 0 575 669 ; +C -1 ; WX 600 ; N tcommaaccent ; B 87 -250 530 561 ; +C 172 ; WX 600 ; N logicalnot ; B 87 108 513 369 ; +C 246 ; WX 600 ; N odieresis ; B 62 -15 538 620 ; +C 252 ; WX 600 ; N udieresis ; B 21 -15 562 620 ; +C -1 ; WX 600 ; N notequal ; B 15 -16 540 529 ; +C -1 ; WX 600 ; N gcommaaccent ; B 45 -157 566 708 ; +C 240 ; WX 600 ; N eth ; B 62 -15 538 629 ; +C 158 ; WX 600 ; N zcaron ; B 99 0 502 669 ; +C -1 ; WX 600 ; N ncommaaccent ; B 26 -250 575 441 ; +C 185 ; WX 600 ; N onesuperior ; B 172 249 428 622 ; +C -1 ; WX 600 ; N imacron ; B 95 0 505 565 ; +C 128 ; WX 600 ; N Euro ; B 0 0 0 0 ; +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6d65fa7dc41ae8ffae77a4a843a73ba31ffd78c7 GIT binary patch literal 705684 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

sms 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%0A7@OA|SSm%P*^HlXor5<@yw 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 o#l5yK!`U{k*W& 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 Rzfbv7^85eY?Wcdr{{>0xQq=$e literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ufm new file mode 100644 index 0000000..5f4dd7c --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ufm @@ -0,0 +1,5712 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans +FontSubfamily Bold Oblique +UniqueID DejaVu Sans Bold Oblique +FullName DejaVu Sans Bold Oblique +Version Version 2.37 +PostScriptName DejaVuSans-BoldOblique +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +PreferredFamily DejaVu Sans +PreferredSubfamily Bold Oblique +Weight Bold +ItalicAngle -11 +IsFixedPitch false +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -1067 -385 1999 1121 +StartCharMetrics 5413 +U 32 ; WX 348 ; N space ; G 3 +U 33 ; WX 456 ; N exclam ; G 4 +U 34 ; WX 521 ; N quotedbl ; G 5 +U 35 ; WX 696 ; N numbersign ; G 6 +U 36 ; WX 696 ; N dollar ; G 7 +U 37 ; WX 1002 ; N percent ; G 8 +U 38 ; WX 872 ; N ampersand ; G 9 +U 39 ; WX 306 ; N quotesingle ; G 10 +U 40 ; WX 457 ; N parenleft ; G 11 +U 41 ; WX 457 ; N parenright ; G 12 +U 42 ; WX 523 ; N asterisk ; G 13 +U 43 ; WX 838 ; N plus ; G 14 +U 44 ; WX 380 ; N comma ; G 15 +U 45 ; WX 415 ; N hyphen ; G 16 +U 46 ; WX 380 ; N period ; G 17 +U 47 ; WX 365 ; N slash ; G 18 +U 48 ; WX 696 ; N zero ; G 19 +U 49 ; WX 696 ; N one ; G 20 +U 50 ; WX 696 ; N two ; G 21 +U 51 ; WX 696 ; N three ; G 22 +U 52 ; WX 696 ; N four ; G 23 +U 53 ; WX 696 ; N five ; G 24 +U 54 ; WX 696 ; N six ; G 25 +U 55 ; WX 696 ; N seven ; G 26 +U 56 ; WX 696 ; N eight ; G 27 +U 57 ; WX 696 ; N nine ; G 28 +U 58 ; WX 400 ; N colon ; G 29 +U 59 ; WX 400 ; N semicolon ; G 30 +U 60 ; WX 838 ; N less ; G 31 +U 61 ; WX 838 ; N equal ; G 32 +U 62 ; WX 838 ; N greater ; G 33 +U 63 ; WX 580 ; N question ; G 34 +U 64 ; WX 1000 ; N at ; G 35 +U 65 ; WX 774 ; N A ; G 36 +U 66 ; WX 762 ; N B ; G 37 +U 67 ; WX 734 ; N C ; G 38 +U 68 ; WX 830 ; N D ; G 39 +U 69 ; WX 683 ; N E ; G 40 +U 70 ; WX 683 ; N F ; G 41 +U 71 ; WX 821 ; N G ; G 42 +U 72 ; WX 837 ; N H ; G 43 +U 73 ; WX 372 ; N I ; G 44 +U 74 ; WX 372 ; N J ; G 45 +U 75 ; WX 775 ; N K ; G 46 +U 76 ; WX 637 ; N L ; G 47 +U 77 ; WX 995 ; N M ; G 48 +U 78 ; WX 837 ; N N ; G 49 +U 79 ; WX 850 ; N O ; G 50 +U 80 ; WX 733 ; N P ; G 51 +U 81 ; WX 850 ; N Q ; G 52 +U 82 ; WX 770 ; N R ; G 53 +U 83 ; WX 720 ; N S ; G 54 +U 84 ; WX 682 ; N T ; G 55 +U 85 ; WX 812 ; N U ; G 56 +U 86 ; WX 774 ; N V ; G 57 +U 87 ; WX 1103 ; N W ; G 58 +U 88 ; WX 771 ; N X ; G 59 +U 89 ; WX 724 ; N Y ; G 60 +U 90 ; WX 725 ; N Z ; G 61 +U 91 ; WX 457 ; N bracketleft ; G 62 +U 92 ; WX 365 ; N backslash ; G 63 +U 93 ; WX 457 ; N bracketright ; G 64 +U 94 ; WX 838 ; N asciicircum ; G 65 +U 95 ; WX 500 ; N underscore ; G 66 +U 96 ; WX 500 ; N grave ; G 67 +U 97 ; WX 675 ; N a ; G 68 +U 98 ; WX 716 ; N b ; G 69 +U 99 ; WX 593 ; N c ; G 70 +U 100 ; WX 716 ; N d ; G 71 +U 101 ; WX 678 ; N e ; G 72 +U 102 ; WX 435 ; N f ; G 73 +U 103 ; WX 716 ; N g ; G 74 +U 104 ; WX 712 ; N h ; G 75 +U 105 ; WX 343 ; N i ; G 76 +U 106 ; WX 343 ; N j ; G 77 +U 107 ; WX 665 ; N k ; G 78 +U 108 ; WX 343 ; N l ; G 79 +U 109 ; WX 1042 ; N m ; G 80 +U 110 ; WX 712 ; N n ; G 81 +U 111 ; WX 687 ; N o ; G 82 +U 112 ; WX 716 ; N p ; G 83 +U 113 ; WX 716 ; N q ; G 84 +U 114 ; WX 493 ; N r ; G 85 +U 115 ; WX 595 ; N s ; G 86 +U 116 ; WX 478 ; N t ; G 87 +U 117 ; WX 712 ; N u ; G 88 +U 118 ; WX 652 ; N v ; G 89 +U 119 ; WX 924 ; N w ; G 90 +U 120 ; WX 645 ; N x ; G 91 +U 121 ; WX 652 ; N y ; G 92 +U 122 ; WX 582 ; N z ; G 93 +U 123 ; WX 712 ; N braceleft ; G 94 +U 124 ; WX 365 ; N bar ; G 95 +U 125 ; WX 712 ; N braceright ; G 96 +U 126 ; WX 838 ; N asciitilde ; G 97 +U 160 ; WX 348 ; N nbspace ; G 98 +U 161 ; WX 456 ; N exclamdown ; G 99 +U 162 ; WX 696 ; N cent ; G 100 +U 163 ; WX 696 ; N sterling ; G 101 +U 164 ; WX 636 ; N currency ; G 102 +U 165 ; WX 696 ; N yen ; G 103 +U 166 ; WX 365 ; N brokenbar ; G 104 +U 167 ; WX 500 ; N section ; G 105 +U 168 ; WX 500 ; N dieresis ; G 106 +U 169 ; WX 1000 ; N copyright ; G 107 +U 170 ; WX 564 ; N ordfeminine ; G 108 +U 171 ; WX 650 ; N guillemotleft ; G 109 +U 172 ; WX 838 ; N logicalnot ; G 110 +U 173 ; WX 415 ; N sfthyphen ; G 111 +U 174 ; WX 1000 ; N registered ; G 112 +U 175 ; WX 500 ; N macron ; G 113 +U 176 ; WX 500 ; N degree ; G 114 +U 177 ; WX 838 ; N plusminus ; G 115 +U 178 ; WX 438 ; N twosuperior ; G 116 +U 179 ; WX 438 ; N threesuperior ; G 117 +U 180 ; WX 500 ; N acute ; G 118 +U 181 ; WX 736 ; N mu ; G 119 +U 182 ; WX 636 ; N paragraph ; G 120 +U 183 ; WX 380 ; N periodcentered ; G 121 +U 184 ; WX 500 ; N cedilla ; G 122 +U 185 ; WX 438 ; N onesuperior ; G 123 +U 186 ; WX 564 ; N ordmasculine ; G 124 +U 187 ; WX 650 ; N guillemotright ; G 125 +U 188 ; WX 1035 ; N onequarter ; G 126 +U 189 ; WX 1035 ; N onehalf ; G 127 +U 190 ; WX 1035 ; N threequarters ; G 128 +U 191 ; WX 580 ; N questiondown ; G 129 +U 192 ; WX 774 ; N Agrave ; G 130 +U 193 ; WX 774 ; N Aacute ; G 131 +U 194 ; WX 774 ; N Acircumflex ; G 132 +U 195 ; WX 774 ; N Atilde ; G 133 +U 196 ; WX 774 ; N Adieresis ; G 134 +U 197 ; WX 774 ; N Aring ; G 135 +U 198 ; WX 1085 ; N AE ; G 136 +U 199 ; WX 734 ; N Ccedilla ; G 137 +U 200 ; WX 683 ; N Egrave ; G 138 +U 201 ; WX 683 ; N Eacute ; G 139 +U 202 ; WX 683 ; N Ecircumflex ; G 140 +U 203 ; WX 683 ; N Edieresis ; G 141 +U 204 ; WX 372 ; N Igrave ; G 142 +U 205 ; WX 372 ; N Iacute ; G 143 +U 206 ; WX 372 ; N Icircumflex ; G 144 +U 207 ; WX 372 ; N Idieresis ; G 145 +U 208 ; WX 845 ; N Eth ; G 146 +U 209 ; WX 837 ; N Ntilde ; G 147 +U 210 ; WX 850 ; N Ograve ; G 148 +U 211 ; WX 850 ; N Oacute ; G 149 +U 212 ; WX 850 ; N Ocircumflex ; G 150 +U 213 ; WX 850 ; N Otilde ; G 151 +U 214 ; WX 850 ; N Odieresis ; G 152 +U 215 ; WX 838 ; N multiply ; G 153 +U 216 ; WX 850 ; N Oslash ; G 154 +U 217 ; WX 812 ; N Ugrave ; G 155 +U 218 ; WX 812 ; N Uacute ; G 156 +U 219 ; WX 812 ; N Ucircumflex ; G 157 +U 220 ; WX 812 ; N Udieresis ; G 158 +U 221 ; WX 724 ; N Yacute ; G 159 +U 222 ; WX 742 ; N Thorn ; G 160 +U 223 ; WX 719 ; N germandbls ; G 161 +U 224 ; WX 675 ; N agrave ; G 162 +U 225 ; WX 675 ; N aacute ; G 163 +U 226 ; WX 675 ; N acircumflex ; G 164 +U 227 ; WX 675 ; N atilde ; G 165 +U 228 ; WX 675 ; N adieresis ; G 166 +U 229 ; WX 675 ; N aring ; G 167 +U 230 ; WX 1048 ; N ae ; G 168 +U 231 ; WX 593 ; N ccedilla ; G 169 +U 232 ; WX 678 ; N egrave ; G 170 +U 233 ; WX 678 ; N eacute ; G 171 +U 234 ; WX 678 ; N ecircumflex ; G 172 +U 235 ; WX 678 ; N edieresis ; G 173 +U 236 ; WX 343 ; N igrave ; G 174 +U 237 ; WX 343 ; N iacute ; G 175 +U 238 ; WX 343 ; N icircumflex ; G 176 +U 239 ; WX 343 ; N idieresis ; G 177 +U 240 ; WX 687 ; N eth ; G 178 +U 241 ; WX 712 ; N ntilde ; G 179 +U 242 ; WX 687 ; N ograve ; G 180 +U 243 ; WX 687 ; N oacute ; G 181 +U 244 ; WX 687 ; N ocircumflex ; G 182 +U 245 ; WX 687 ; N otilde ; G 183 +U 246 ; WX 687 ; N odieresis ; G 184 +U 247 ; WX 838 ; N divide ; G 185 +U 248 ; WX 687 ; N oslash ; G 186 +U 249 ; WX 712 ; N ugrave ; G 187 +U 250 ; WX 712 ; N uacute ; G 188 +U 251 ; WX 712 ; N ucircumflex ; G 189 +U 252 ; WX 712 ; N udieresis ; G 190 +U 253 ; WX 652 ; N yacute ; G 191 +U 254 ; WX 716 ; N thorn ; G 192 +U 255 ; WX 652 ; N ydieresis ; G 193 +U 256 ; WX 774 ; N Amacron ; G 194 +U 257 ; WX 675 ; N amacron ; G 195 +U 258 ; WX 774 ; N Abreve ; G 196 +U 259 ; WX 675 ; N abreve ; G 197 +U 260 ; WX 774 ; N Aogonek ; G 198 +U 261 ; WX 675 ; N aogonek ; G 199 +U 262 ; WX 734 ; N Cacute ; G 200 +U 263 ; WX 593 ; N cacute ; G 201 +U 264 ; WX 734 ; N Ccircumflex ; G 202 +U 265 ; WX 593 ; N ccircumflex ; G 203 +U 266 ; WX 734 ; N Cdotaccent ; G 204 +U 267 ; WX 593 ; N cdotaccent ; G 205 +U 268 ; WX 734 ; N Ccaron ; G 206 +U 269 ; WX 593 ; N ccaron ; G 207 +U 270 ; WX 830 ; N Dcaron ; G 208 +U 271 ; WX 716 ; N dcaron ; G 209 +U 272 ; WX 845 ; N Dcroat ; G 210 +U 273 ; WX 716 ; N dmacron ; G 211 +U 274 ; WX 683 ; N Emacron ; G 212 +U 275 ; WX 678 ; N emacron ; G 213 +U 276 ; WX 683 ; N Ebreve ; G 214 +U 277 ; WX 678 ; N ebreve ; G 215 +U 278 ; WX 683 ; N Edotaccent ; G 216 +U 279 ; WX 678 ; N edotaccent ; G 217 +U 280 ; WX 683 ; N Eogonek ; G 218 +U 281 ; WX 678 ; N eogonek ; G 219 +U 282 ; WX 683 ; N Ecaron ; G 220 +U 283 ; WX 678 ; N ecaron ; G 221 +U 284 ; WX 821 ; N Gcircumflex ; G 222 +U 285 ; WX 716 ; N gcircumflex ; G 223 +U 286 ; WX 821 ; N Gbreve ; G 224 +U 287 ; WX 716 ; N gbreve ; G 225 +U 288 ; WX 821 ; N Gdotaccent ; G 226 +U 289 ; WX 716 ; N gdotaccent ; G 227 +U 290 ; WX 821 ; N Gcommaaccent ; G 228 +U 291 ; WX 716 ; N gcommaaccent ; G 229 +U 292 ; WX 837 ; N Hcircumflex ; G 230 +U 293 ; WX 712 ; N hcircumflex ; G 231 +U 294 ; WX 974 ; N Hbar ; G 232 +U 295 ; WX 790 ; N hbar ; G 233 +U 296 ; WX 372 ; N Itilde ; G 234 +U 297 ; WX 343 ; N itilde ; G 235 +U 298 ; WX 372 ; N Imacron ; G 236 +U 299 ; WX 343 ; N imacron ; G 237 +U 300 ; WX 372 ; N Ibreve ; G 238 +U 301 ; WX 343 ; N ibreve ; G 239 +U 302 ; WX 372 ; N Iogonek ; G 240 +U 303 ; WX 343 ; N iogonek ; G 241 +U 304 ; WX 372 ; N Idot ; G 242 +U 305 ; WX 343 ; N dotlessi ; G 243 +U 306 ; WX 744 ; N IJ ; G 244 +U 307 ; WX 686 ; N ij ; G 245 +U 308 ; WX 372 ; N Jcircumflex ; G 246 +U 309 ; WX 343 ; N jcircumflex ; G 247 +U 310 ; WX 775 ; N Kcommaaccent ; G 248 +U 311 ; WX 665 ; N kcommaaccent ; G 249 +U 312 ; WX 665 ; N kgreenlandic ; G 250 +U 313 ; WX 637 ; N Lacute ; G 251 +U 314 ; WX 343 ; N lacute ; G 252 +U 315 ; WX 637 ; N Lcommaaccent ; G 253 +U 316 ; WX 343 ; N lcommaaccent ; G 254 +U 317 ; WX 637 ; N Lcaron ; G 255 +U 318 ; WX 343 ; N lcaron ; G 256 +U 319 ; WX 637 ; N Ldot ; G 257 +U 320 ; WX 343 ; N ldot ; G 258 +U 321 ; WX 660 ; N Lslash ; G 259 +U 322 ; WX 375 ; N lslash ; G 260 +U 323 ; WX 837 ; N Nacute ; G 261 +U 324 ; WX 712 ; N nacute ; G 262 +U 325 ; WX 837 ; N Ncommaaccent ; G 263 +U 326 ; WX 712 ; N ncommaaccent ; G 264 +U 327 ; WX 837 ; N Ncaron ; G 265 +U 328 ; WX 712 ; N ncaron ; G 266 +U 329 ; WX 983 ; N napostrophe ; G 267 +U 330 ; WX 837 ; N Eng ; G 268 +U 331 ; WX 712 ; N eng ; G 269 +U 332 ; WX 850 ; N Omacron ; G 270 +U 333 ; WX 687 ; N omacron ; G 271 +U 334 ; WX 850 ; N Obreve ; G 272 +U 335 ; WX 687 ; N obreve ; G 273 +U 336 ; WX 850 ; N Ohungarumlaut ; G 274 +U 337 ; WX 687 ; N ohungarumlaut ; G 275 +U 338 ; WX 1167 ; N OE ; G 276 +U 339 ; WX 1094 ; N oe ; G 277 +U 340 ; WX 770 ; N Racute ; G 278 +U 341 ; WX 493 ; N racute ; G 279 +U 342 ; WX 770 ; N Rcommaaccent ; G 280 +U 343 ; WX 493 ; N rcommaaccent ; G 281 +U 344 ; WX 770 ; N Rcaron ; G 282 +U 345 ; WX 493 ; N rcaron ; G 283 +U 346 ; WX 720 ; N Sacute ; G 284 +U 347 ; WX 595 ; N sacute ; G 285 +U 348 ; WX 720 ; N Scircumflex ; G 286 +U 349 ; WX 595 ; N scircumflex ; G 287 +U 350 ; WX 720 ; N Scedilla ; G 288 +U 351 ; WX 595 ; N scedilla ; G 289 +U 352 ; WX 720 ; N Scaron ; G 290 +U 353 ; WX 595 ; N scaron ; G 291 +U 354 ; WX 682 ; N Tcommaaccent ; G 292 +U 355 ; WX 478 ; N tcommaaccent ; G 293 +U 356 ; WX 682 ; N Tcaron ; G 294 +U 357 ; WX 478 ; N tcaron ; G 295 +U 358 ; WX 682 ; N Tbar ; G 296 +U 359 ; WX 478 ; N tbar ; G 297 +U 360 ; WX 812 ; N Utilde ; G 298 +U 361 ; WX 712 ; N utilde ; G 299 +U 362 ; WX 812 ; N Umacron ; G 300 +U 363 ; WX 712 ; N umacron ; G 301 +U 364 ; WX 812 ; N Ubreve ; G 302 +U 365 ; WX 712 ; N ubreve ; G 303 +U 366 ; WX 812 ; N Uring ; G 304 +U 367 ; WX 712 ; N uring ; G 305 +U 368 ; WX 812 ; N Uhungarumlaut ; G 306 +U 369 ; WX 712 ; N uhungarumlaut ; G 307 +U 370 ; WX 812 ; N Uogonek ; G 308 +U 371 ; WX 712 ; N uogonek ; G 309 +U 372 ; WX 1103 ; N Wcircumflex ; G 310 +U 373 ; WX 924 ; N wcircumflex ; G 311 +U 374 ; WX 724 ; N Ycircumflex ; G 312 +U 375 ; WX 652 ; N ycircumflex ; G 313 +U 376 ; WX 724 ; N Ydieresis ; G 314 +U 377 ; WX 725 ; N Zacute ; G 315 +U 378 ; WX 582 ; N zacute ; G 316 +U 379 ; WX 725 ; N Zdotaccent ; G 317 +U 380 ; WX 582 ; N zdotaccent ; G 318 +U 381 ; WX 725 ; N Zcaron ; G 319 +U 382 ; WX 582 ; N zcaron ; G 320 +U 383 ; WX 435 ; N longs ; G 321 +U 384 ; WX 716 ; N uni0180 ; G 322 +U 385 ; WX 811 ; N uni0181 ; G 323 +U 386 ; WX 762 ; N uni0182 ; G 324 +U 387 ; WX 716 ; N uni0183 ; G 325 +U 388 ; WX 762 ; N uni0184 ; G 326 +U 389 ; WX 716 ; N uni0185 ; G 327 +U 390 ; WX 734 ; N uni0186 ; G 328 +U 391 ; WX 734 ; N uni0187 ; G 329 +U 392 ; WX 593 ; N uni0188 ; G 330 +U 393 ; WX 845 ; N uni0189 ; G 331 +U 394 ; WX 879 ; N uni018A ; G 332 +U 395 ; WX 762 ; N uni018B ; G 333 +U 396 ; WX 716 ; N uni018C ; G 334 +U 397 ; WX 687 ; N uni018D ; G 335 +U 398 ; WX 683 ; N uni018E ; G 336 +U 399 ; WX 850 ; N uni018F ; G 337 +U 400 ; WX 696 ; N uni0190 ; G 338 +U 401 ; WX 683 ; N uni0191 ; G 339 +U 402 ; WX 435 ; N florin ; G 340 +U 403 ; WX 821 ; N uni0193 ; G 341 +U 404 ; WX 793 ; N uni0194 ; G 342 +U 405 ; WX 1045 ; N uni0195 ; G 343 +U 406 ; WX 436 ; N uni0196 ; G 344 +U 407 ; WX 389 ; N uni0197 ; G 345 +U 408 ; WX 775 ; N uni0198 ; G 346 +U 409 ; WX 665 ; N uni0199 ; G 347 +U 410 ; WX 360 ; N uni019A ; G 348 +U 411 ; WX 592 ; N uni019B ; G 349 +U 412 ; WX 1042 ; N uni019C ; G 350 +U 413 ; WX 837 ; N uni019D ; G 351 +U 414 ; WX 712 ; N uni019E ; G 352 +U 415 ; WX 850 ; N uni019F ; G 353 +U 416 ; WX 850 ; N Ohorn ; G 354 +U 417 ; WX 687 ; N ohorn ; G 355 +U 418 ; WX 1114 ; N uni01A2 ; G 356 +U 419 ; WX 962 ; N uni01A3 ; G 357 +U 420 ; WX 782 ; N uni01A4 ; G 358 +U 421 ; WX 716 ; N uni01A5 ; G 359 +U 422 ; WX 770 ; N uni01A6 ; G 360 +U 423 ; WX 720 ; N uni01A7 ; G 361 +U 424 ; WX 595 ; N uni01A8 ; G 362 +U 425 ; WX 683 ; N uni01A9 ; G 363 +U 426 ; WX 552 ; N uni01AA ; G 364 +U 427 ; WX 478 ; N uni01AB ; G 365 +U 428 ; WX 707 ; N uni01AC ; G 366 +U 429 ; WX 478 ; N uni01AD ; G 367 +U 430 ; WX 682 ; N uni01AE ; G 368 +U 431 ; WX 812 ; N Uhorn ; G 369 +U 432 ; WX 712 ; N uhorn ; G 370 +U 433 ; WX 769 ; N uni01B1 ; G 371 +U 434 ; WX 813 ; N uni01B2 ; G 372 +U 435 ; WX 797 ; N uni01B3 ; G 373 +U 436 ; WX 778 ; N uni01B4 ; G 374 +U 437 ; WX 725 ; N uni01B5 ; G 375 +U 438 ; WX 582 ; N uni01B6 ; G 376 +U 439 ; WX 772 ; N uni01B7 ; G 377 +U 440 ; WX 772 ; N uni01B8 ; G 378 +U 441 ; WX 641 ; N uni01B9 ; G 379 +U 442 ; WX 582 ; N uni01BA ; G 380 +U 443 ; WX 696 ; N uni01BB ; G 381 +U 444 ; WX 772 ; N uni01BC ; G 382 +U 445 ; WX 641 ; N uni01BD ; G 383 +U 446 ; WX 573 ; N uni01BE ; G 384 +U 447 ; WX 716 ; N uni01BF ; G 385 +U 448 ; WX 372 ; N uni01C0 ; G 386 +U 449 ; WX 659 ; N uni01C1 ; G 387 +U 450 ; WX 544 ; N uni01C2 ; G 388 +U 451 ; WX 372 ; N uni01C3 ; G 389 +U 452 ; WX 1548 ; N uni01C4 ; G 390 +U 453 ; WX 1450 ; N uni01C5 ; G 391 +U 454 ; WX 1307 ; N uni01C6 ; G 392 +U 455 ; WX 977 ; N uni01C7 ; G 393 +U 456 ; WX 979 ; N uni01C8 ; G 394 +U 457 ; WX 670 ; N uni01C9 ; G 395 +U 458 ; WX 1193 ; N uni01CA ; G 396 +U 459 ; WX 1213 ; N uni01CB ; G 397 +U 460 ; WX 1063 ; N uni01CC ; G 398 +U 461 ; WX 774 ; N uni01CD ; G 399 +U 462 ; WX 675 ; N uni01CE ; G 400 +U 463 ; WX 372 ; N uni01CF ; G 401 +U 464 ; WX 343 ; N uni01D0 ; G 402 +U 465 ; WX 850 ; N uni01D1 ; G 403 +U 466 ; WX 687 ; N uni01D2 ; G 404 +U 467 ; WX 812 ; N uni01D3 ; G 405 +U 468 ; WX 712 ; N uni01D4 ; G 406 +U 469 ; WX 812 ; N uni01D5 ; G 407 +U 470 ; WX 712 ; N uni01D6 ; G 408 +U 471 ; WX 812 ; N uni01D7 ; G 409 +U 472 ; WX 712 ; N uni01D8 ; G 410 +U 473 ; WX 812 ; N uni01D9 ; G 411 +U 474 ; WX 712 ; N uni01DA ; G 412 +U 475 ; WX 812 ; N uni01DB ; G 413 +U 476 ; WX 712 ; N uni01DC ; G 414 +U 477 ; WX 678 ; N uni01DD ; G 415 +U 478 ; WX 774 ; N uni01DE ; G 416 +U 479 ; WX 675 ; N uni01DF ; G 417 +U 480 ; WX 774 ; N uni01E0 ; G 418 +U 481 ; WX 675 ; N uni01E1 ; G 419 +U 482 ; WX 1085 ; N uni01E2 ; G 420 +U 483 ; WX 1048 ; N uni01E3 ; G 421 +U 484 ; WX 821 ; N uni01E4 ; G 422 +U 485 ; WX 716 ; N uni01E5 ; G 423 +U 486 ; WX 821 ; N Gcaron ; G 424 +U 487 ; WX 716 ; N gcaron ; G 425 +U 488 ; WX 775 ; N uni01E8 ; G 426 +U 489 ; WX 665 ; N uni01E9 ; G 427 +U 490 ; WX 850 ; N uni01EA ; G 428 +U 491 ; WX 687 ; N uni01EB ; G 429 +U 492 ; WX 850 ; N uni01EC ; G 430 +U 493 ; WX 687 ; N uni01ED ; G 431 +U 494 ; WX 772 ; N uni01EE ; G 432 +U 495 ; WX 582 ; N uni01EF ; G 433 +U 496 ; WX 343 ; N uni01F0 ; G 434 +U 497 ; WX 1548 ; N uni01F1 ; G 435 +U 498 ; WX 1450 ; N uni01F2 ; G 436 +U 499 ; WX 1307 ; N uni01F3 ; G 437 +U 500 ; WX 821 ; N uni01F4 ; G 438 +U 501 ; WX 716 ; N uni01F5 ; G 439 +U 502 ; WX 1289 ; N uni01F6 ; G 440 +U 503 ; WX 787 ; N uni01F7 ; G 441 +U 504 ; WX 837 ; N uni01F8 ; G 442 +U 505 ; WX 712 ; N uni01F9 ; G 443 +U 506 ; WX 774 ; N Aringacute ; G 444 +U 507 ; WX 675 ; N aringacute ; G 445 +U 508 ; WX 1085 ; N AEacute ; G 446 +U 509 ; WX 1048 ; N aeacute ; G 447 +U 510 ; WX 850 ; N Oslashacute ; G 448 +U 511 ; WX 687 ; N oslashacute ; G 449 +U 512 ; WX 774 ; N uni0200 ; G 450 +U 513 ; WX 675 ; N uni0201 ; G 451 +U 514 ; WX 774 ; N uni0202 ; G 452 +U 515 ; WX 675 ; N uni0203 ; G 453 +U 516 ; WX 683 ; N uni0204 ; G 454 +U 517 ; WX 678 ; N uni0205 ; G 455 +U 518 ; WX 683 ; N uni0206 ; G 456 +U 519 ; WX 678 ; N uni0207 ; G 457 +U 520 ; WX 372 ; N uni0208 ; G 458 +U 521 ; WX 343 ; N uni0209 ; G 459 +U 522 ; WX 372 ; N uni020A ; G 460 +U 523 ; WX 343 ; N uni020B ; G 461 +U 524 ; WX 850 ; N uni020C ; G 462 +U 525 ; WX 687 ; N uni020D ; G 463 +U 526 ; WX 850 ; N uni020E ; G 464 +U 527 ; WX 687 ; N uni020F ; G 465 +U 528 ; WX 770 ; N uni0210 ; G 466 +U 529 ; WX 493 ; N uni0211 ; G 467 +U 530 ; WX 770 ; N uni0212 ; G 468 +U 531 ; WX 493 ; N uni0213 ; G 469 +U 532 ; WX 812 ; N uni0214 ; G 470 +U 533 ; WX 712 ; N uni0215 ; G 471 +U 534 ; WX 812 ; N uni0216 ; G 472 +U 535 ; WX 712 ; N uni0217 ; G 473 +U 536 ; WX 720 ; N Scommaaccent ; G 474 +U 537 ; WX 595 ; N scommaaccent ; G 475 +U 538 ; WX 682 ; N uni021A ; G 476 +U 539 ; WX 478 ; N uni021B ; G 477 +U 540 ; WX 690 ; N uni021C ; G 478 +U 541 ; WX 607 ; N uni021D ; G 479 +U 542 ; WX 837 ; N uni021E ; G 480 +U 543 ; WX 712 ; N uni021F ; G 481 +U 544 ; WX 837 ; N uni0220 ; G 482 +U 545 ; WX 865 ; N uni0221 ; G 483 +U 546 ; WX 809 ; N uni0222 ; G 484 +U 547 ; WX 659 ; N uni0223 ; G 485 +U 548 ; WX 725 ; N uni0224 ; G 486 +U 549 ; WX 582 ; N uni0225 ; G 487 +U 550 ; WX 774 ; N uni0226 ; G 488 +U 551 ; WX 675 ; N uni0227 ; G 489 +U 552 ; WX 683 ; N uni0228 ; G 490 +U 553 ; WX 678 ; N uni0229 ; G 491 +U 554 ; WX 850 ; N uni022A ; G 492 +U 555 ; WX 687 ; N uni022B ; G 493 +U 556 ; WX 850 ; N uni022C ; G 494 +U 557 ; WX 687 ; N uni022D ; G 495 +U 558 ; WX 850 ; N uni022E ; G 496 +U 559 ; WX 687 ; N uni022F ; G 497 +U 560 ; WX 850 ; N uni0230 ; G 498 +U 561 ; WX 687 ; N uni0231 ; G 499 +U 562 ; WX 724 ; N uni0232 ; G 500 +U 563 ; WX 652 ; N uni0233 ; G 501 +U 564 ; WX 492 ; N uni0234 ; G 502 +U 565 ; WX 867 ; N uni0235 ; G 503 +U 566 ; WX 512 ; N uni0236 ; G 504 +U 567 ; WX 343 ; N dotlessj ; G 505 +U 568 ; WX 1088 ; N uni0238 ; G 506 +U 569 ; WX 1088 ; N uni0239 ; G 507 +U 570 ; WX 774 ; N uni023A ; G 508 +U 571 ; WX 734 ; N uni023B ; G 509 +U 572 ; WX 593 ; N uni023C ; G 510 +U 573 ; WX 637 ; N uni023D ; G 511 +U 574 ; WX 682 ; N uni023E ; G 512 +U 575 ; WX 595 ; N uni023F ; G 513 +U 576 ; WX 582 ; N uni0240 ; G 514 +U 577 ; WX 782 ; N uni0241 ; G 515 +U 578 ; WX 614 ; N uni0242 ; G 516 +U 579 ; WX 762 ; N uni0243 ; G 517 +U 580 ; WX 812 ; N uni0244 ; G 518 +U 581 ; WX 774 ; N uni0245 ; G 519 +U 582 ; WX 683 ; N uni0246 ; G 520 +U 583 ; WX 678 ; N uni0247 ; G 521 +U 584 ; WX 372 ; N uni0248 ; G 522 +U 585 ; WX 343 ; N uni0249 ; G 523 +U 586 ; WX 860 ; N uni024A ; G 524 +U 587 ; WX 791 ; N uni024B ; G 525 +U 588 ; WX 770 ; N uni024C ; G 526 +U 589 ; WX 493 ; N uni024D ; G 527 +U 590 ; WX 724 ; N uni024E ; G 528 +U 591 ; WX 652 ; N uni024F ; G 529 +U 592 ; WX 675 ; N uni0250 ; G 530 +U 593 ; WX 716 ; N uni0251 ; G 531 +U 594 ; WX 716 ; N uni0252 ; G 532 +U 595 ; WX 716 ; N uni0253 ; G 533 +U 596 ; WX 593 ; N uni0254 ; G 534 +U 597 ; WX 593 ; N uni0255 ; G 535 +U 598 ; WX 791 ; N uni0256 ; G 536 +U 599 ; WX 792 ; N uni0257 ; G 537 +U 600 ; WX 678 ; N uni0258 ; G 538 +U 601 ; WX 678 ; N uni0259 ; G 539 +U 602 ; WX 876 ; N uni025A ; G 540 +U 603 ; WX 557 ; N uni025B ; G 541 +U 604 ; WX 545 ; N uni025C ; G 542 +U 605 ; WX 774 ; N uni025D ; G 543 +U 606 ; WX 731 ; N uni025E ; G 544 +U 607 ; WX 343 ; N uni025F ; G 545 +U 608 ; WX 792 ; N uni0260 ; G 546 +U 609 ; WX 716 ; N uni0261 ; G 547 +U 610 ; WX 627 ; N uni0262 ; G 548 +U 611 ; WX 735 ; N uni0263 ; G 549 +U 612 ; WX 635 ; N uni0264 ; G 550 +U 613 ; WX 712 ; N uni0265 ; G 551 +U 614 ; WX 712 ; N uni0266 ; G 552 +U 615 ; WX 712 ; N uni0267 ; G 553 +U 616 ; WX 545 ; N uni0268 ; G 554 +U 617 ; WX 440 ; N uni0269 ; G 555 +U 618 ; WX 545 ; N uni026A ; G 556 +U 619 ; WX 559 ; N uni026B ; G 557 +U 620 ; WX 693 ; N uni026C ; G 558 +U 621 ; WX 343 ; N uni026D ; G 559 +U 622 ; WX 841 ; N uni026E ; G 560 +U 623 ; WX 1042 ; N uni026F ; G 561 +U 624 ; WX 1042 ; N uni0270 ; G 562 +U 625 ; WX 1042 ; N uni0271 ; G 563 +U 626 ; WX 712 ; N uni0272 ; G 564 +U 627 ; WX 793 ; N uni0273 ; G 565 +U 628 ; WX 642 ; N uni0274 ; G 566 +U 629 ; WX 687 ; N uni0275 ; G 567 +U 630 ; WX 909 ; N uni0276 ; G 568 +U 631 ; WX 682 ; N uni0277 ; G 569 +U 632 ; WX 796 ; N uni0278 ; G 570 +U 633 ; WX 538 ; N uni0279 ; G 571 +U 634 ; WX 538 ; N uni027A ; G 572 +U 635 ; WX 650 ; N uni027B ; G 573 +U 636 ; WX 493 ; N uni027C ; G 574 +U 637 ; WX 493 ; N uni027D ; G 575 +U 638 ; WX 596 ; N uni027E ; G 576 +U 639 ; WX 596 ; N uni027F ; G 577 +U 640 ; WX 642 ; N uni0280 ; G 578 +U 641 ; WX 642 ; N uni0281 ; G 579 +U 642 ; WX 595 ; N uni0282 ; G 580 +U 643 ; WX 415 ; N uni0283 ; G 581 +U 644 ; WX 435 ; N uni0284 ; G 582 +U 645 ; WX 605 ; N uni0285 ; G 583 +U 646 ; WX 552 ; N uni0286 ; G 584 +U 647 ; WX 478 ; N uni0287 ; G 585 +U 648 ; WX 478 ; N uni0288 ; G 586 +U 649 ; WX 920 ; N uni0289 ; G 587 +U 650 ; WX 769 ; N uni028A ; G 588 +U 651 ; WX 670 ; N uni028B ; G 589 +U 652 ; WX 652 ; N uni028C ; G 590 +U 653 ; WX 924 ; N uni028D ; G 591 +U 654 ; WX 652 ; N uni028E ; G 592 +U 655 ; WX 724 ; N uni028F ; G 593 +U 656 ; WX 694 ; N uni0290 ; G 594 +U 657 ; WX 684 ; N uni0291 ; G 595 +U 658 ; WX 641 ; N uni0292 ; G 596 +U 659 ; WX 641 ; N uni0293 ; G 597 +U 660 ; WX 573 ; N uni0294 ; G 598 +U 661 ; WX 573 ; N uni0295 ; G 599 +U 662 ; WX 573 ; N uni0296 ; G 600 +U 663 ; WX 573 ; N uni0297 ; G 601 +U 664 ; WX 850 ; N uni0298 ; G 602 +U 665 ; WX 633 ; N uni0299 ; G 603 +U 666 ; WX 731 ; N uni029A ; G 604 +U 667 ; WX 685 ; N uni029B ; G 605 +U 668 ; WX 691 ; N uni029C ; G 606 +U 669 ; WX 343 ; N uni029D ; G 607 +U 670 ; WX 732 ; N uni029E ; G 608 +U 671 ; WX 539 ; N uni029F ; G 609 +U 672 ; WX 792 ; N uni02A0 ; G 610 +U 673 ; WX 573 ; N uni02A1 ; G 611 +U 674 ; WX 573 ; N uni02A2 ; G 612 +U 675 ; WX 1156 ; N uni02A3 ; G 613 +U 676 ; WX 1214 ; N uni02A4 ; G 614 +U 677 ; WX 1155 ; N uni02A5 ; G 615 +U 678 ; WX 975 ; N uni02A6 ; G 616 +U 679 ; WX 769 ; N uni02A7 ; G 617 +U 680 ; WX 929 ; N uni02A8 ; G 618 +U 681 ; WX 1026 ; N uni02A9 ; G 619 +U 682 ; WX 862 ; N uni02AA ; G 620 +U 683 ; WX 780 ; N uni02AB ; G 621 +U 684 ; WX 591 ; N uni02AC ; G 622 +U 685 ; WX 415 ; N uni02AD ; G 623 +U 686 ; WX 677 ; N uni02AE ; G 624 +U 687 ; WX 789 ; N uni02AF ; G 625 +U 688 ; WX 456 ; N uni02B0 ; G 626 +U 689 ; WX 456 ; N uni02B1 ; G 627 +U 690 ; WX 219 ; N uni02B2 ; G 628 +U 691 ; WX 315 ; N uni02B3 ; G 629 +U 692 ; WX 315 ; N uni02B4 ; G 630 +U 693 ; WX 315 ; N uni02B5 ; G 631 +U 694 ; WX 411 ; N uni02B6 ; G 632 +U 695 ; WX 591 ; N uni02B7 ; G 633 +U 696 ; WX 417 ; N uni02B8 ; G 634 +U 697 ; WX 302 ; N uni02B9 ; G 635 +U 698 ; WX 521 ; N uni02BA ; G 636 +U 699 ; WX 380 ; N uni02BB ; G 637 +U 700 ; WX 380 ; N uni02BC ; G 638 +U 701 ; WX 380 ; N uni02BD ; G 639 +U 702 ; WX 366 ; N uni02BE ; G 640 +U 703 ; WX 366 ; N uni02BF ; G 641 +U 704 ; WX 326 ; N uni02C0 ; G 642 +U 705 ; WX 326 ; N uni02C1 ; G 643 +U 706 ; WX 500 ; N uni02C2 ; G 644 +U 707 ; WX 500 ; N uni02C3 ; G 645 +U 708 ; WX 500 ; N uni02C4 ; G 646 +U 709 ; WX 500 ; N uni02C5 ; G 647 +U 710 ; WX 500 ; N circumflex ; G 648 +U 711 ; WX 500 ; N caron ; G 649 +U 712 ; WX 306 ; N uni02C8 ; G 650 +U 713 ; WX 500 ; N uni02C9 ; G 651 +U 714 ; WX 500 ; N uni02CA ; G 652 +U 715 ; WX 500 ; N uni02CB ; G 653 +U 716 ; WX 306 ; N uni02CC ; G 654 +U 717 ; WX 500 ; N uni02CD ; G 655 +U 718 ; WX 500 ; N uni02CE ; G 656 +U 719 ; WX 500 ; N uni02CF ; G 657 +U 720 ; WX 337 ; N uni02D0 ; G 658 +U 721 ; WX 337 ; N uni02D1 ; G 659 +U 722 ; WX 366 ; N uni02D2 ; G 660 +U 723 ; WX 366 ; N uni02D3 ; G 661 +U 724 ; WX 500 ; N uni02D4 ; G 662 +U 725 ; WX 500 ; N uni02D5 ; G 663 +U 726 ; WX 416 ; N uni02D6 ; G 664 +U 727 ; WX 328 ; N uni02D7 ; G 665 +U 728 ; WX 500 ; N breve ; G 666 +U 729 ; WX 500 ; N dotaccent ; G 667 +U 730 ; WX 500 ; N ring ; G 668 +U 731 ; WX 500 ; N ogonek ; G 669 +U 732 ; WX 500 ; N tilde ; G 670 +U 733 ; WX 500 ; N hungarumlaut ; G 671 +U 734 ; WX 351 ; N uni02DE ; G 672 +U 735 ; WX 500 ; N uni02DF ; G 673 +U 736 ; WX 412 ; N uni02E0 ; G 674 +U 737 ; WX 219 ; N uni02E1 ; G 675 +U 738 ; WX 381 ; N uni02E2 ; G 676 +U 739 ; WX 413 ; N uni02E3 ; G 677 +U 740 ; WX 326 ; N uni02E4 ; G 678 +U 741 ; WX 500 ; N uni02E5 ; G 679 +U 742 ; WX 500 ; N uni02E6 ; G 680 +U 743 ; WX 500 ; N uni02E7 ; G 681 +U 744 ; WX 500 ; N uni02E8 ; G 682 +U 745 ; WX 500 ; N uni02E9 ; G 683 +U 748 ; WX 500 ; N uni02EC ; G 684 +U 749 ; WX 500 ; N uni02ED ; G 685 +U 750 ; WX 644 ; N uni02EE ; G 686 +U 755 ; WX 500 ; N uni02F3 ; G 687 +U 759 ; WX 500 ; N uni02F7 ; G 688 +U 768 ; WX 0 ; N gravecomb ; G 689 +U 769 ; WX 0 ; N acutecomb ; G 690 +U 770 ; WX 0 ; N uni0302 ; G 691 +U 771 ; WX 0 ; N tildecomb ; G 692 +U 772 ; WX 0 ; N uni0304 ; G 693 +U 773 ; WX 0 ; N uni0305 ; G 694 +U 774 ; WX 0 ; N uni0306 ; G 695 +U 775 ; WX 0 ; N uni0307 ; G 696 +U 776 ; WX 0 ; N uni0308 ; G 697 +U 777 ; WX 0 ; N hookabovecomb ; G 698 +U 778 ; WX 0 ; N uni030A ; G 699 +U 779 ; WX 0 ; N uni030B ; G 700 +U 780 ; WX 0 ; N uni030C ; G 701 +U 781 ; WX 0 ; N uni030D ; G 702 +U 782 ; WX 0 ; N uni030E ; G 703 +U 783 ; WX 0 ; N uni030F ; G 704 +U 784 ; WX 0 ; N uni0310 ; G 705 +U 785 ; WX 0 ; N uni0311 ; G 706 +U 786 ; WX 0 ; N uni0312 ; G 707 +U 787 ; WX 0 ; N uni0313 ; G 708 +U 788 ; WX 0 ; N uni0314 ; G 709 +U 789 ; WX 0 ; N uni0315 ; G 710 +U 790 ; WX 0 ; N uni0316 ; G 711 +U 791 ; WX 0 ; N uni0317 ; G 712 +U 792 ; WX 0 ; N uni0318 ; G 713 +U 793 ; WX 0 ; N uni0319 ; G 714 +U 794 ; WX 0 ; N uni031A ; G 715 +U 795 ; WX 0 ; N uni031B ; G 716 +U 796 ; WX 0 ; N uni031C ; G 717 +U 797 ; WX 0 ; N uni031D ; G 718 +U 798 ; WX 0 ; N uni031E ; G 719 +U 799 ; WX 0 ; N uni031F ; G 720 +U 800 ; WX 0 ; N uni0320 ; G 721 +U 801 ; WX 0 ; N uni0321 ; G 722 +U 802 ; WX 0 ; N uni0322 ; G 723 +U 803 ; WX 0 ; N dotbelowcomb ; G 724 +U 804 ; WX 0 ; N uni0324 ; G 725 +U 805 ; WX 0 ; N uni0325 ; G 726 +U 806 ; WX 0 ; N uni0326 ; G 727 +U 807 ; WX 0 ; N uni0327 ; G 728 +U 808 ; WX 0 ; N uni0328 ; G 729 +U 809 ; WX 0 ; N uni0329 ; G 730 +U 810 ; WX 0 ; N uni032A ; G 731 +U 811 ; WX 0 ; N uni032B ; G 732 +U 812 ; WX 0 ; N uni032C ; G 733 +U 813 ; WX 0 ; N uni032D ; G 734 +U 814 ; WX 0 ; N uni032E ; G 735 +U 815 ; WX 0 ; N uni032F ; G 736 +U 816 ; WX 0 ; N uni0330 ; G 737 +U 817 ; WX 0 ; N uni0331 ; G 738 +U 818 ; WX 0 ; N uni0332 ; G 739 +U 819 ; WX 0 ; N uni0333 ; G 740 +U 820 ; WX 0 ; N uni0334 ; G 741 +U 821 ; WX 0 ; N uni0335 ; G 742 +U 822 ; WX 0 ; N uni0336 ; G 743 +U 823 ; WX 0 ; N uni0337 ; G 744 +U 824 ; WX 0 ; N uni0338 ; G 745 +U 825 ; WX 0 ; N uni0339 ; G 746 +U 826 ; WX 0 ; N uni033A ; G 747 +U 827 ; WX 0 ; N uni033B ; G 748 +U 828 ; WX 0 ; N uni033C ; G 749 +U 829 ; WX 0 ; N uni033D ; G 750 +U 830 ; WX 0 ; N uni033E ; G 751 +U 831 ; WX 0 ; N uni033F ; G 752 +U 832 ; WX 0 ; N uni0340 ; G 753 +U 833 ; WX 0 ; N uni0341 ; G 754 +U 834 ; WX 0 ; N uni0342 ; G 755 +U 835 ; WX 0 ; N uni0343 ; G 756 +U 836 ; WX 0 ; N uni0344 ; G 757 +U 837 ; WX 0 ; N uni0345 ; G 758 +U 838 ; WX 0 ; N uni0346 ; G 759 +U 839 ; WX 0 ; N uni0347 ; G 760 +U 840 ; WX 0 ; N uni0348 ; G 761 +U 841 ; WX 0 ; N uni0349 ; G 762 +U 842 ; WX 0 ; N uni034A ; G 763 +U 843 ; WX 0 ; N uni034B ; G 764 +U 844 ; WX 0 ; N uni034C ; G 765 +U 845 ; WX 0 ; N uni034D ; G 766 +U 846 ; WX 0 ; N uni034E ; G 767 +U 847 ; WX 0 ; N uni034F ; G 768 +U 849 ; WX 0 ; N uni0351 ; G 769 +U 850 ; WX 0 ; N uni0352 ; G 770 +U 851 ; WX 0 ; N uni0353 ; G 771 +U 855 ; WX 0 ; N uni0357 ; G 772 +U 856 ; WX 0 ; N uni0358 ; G 773 +U 858 ; WX 0 ; N uni035A ; G 774 +U 860 ; WX 0 ; N uni035C ; G 775 +U 861 ; WX 0 ; N uni035D ; G 776 +U 862 ; WX 0 ; N uni035E ; G 777 +U 863 ; WX 0 ; N uni035F ; G 778 +U 864 ; WX 0 ; N uni0360 ; G 779 +U 865 ; WX 0 ; N uni0361 ; G 780 +U 866 ; WX 0 ; N uni0362 ; G 781 +U 880 ; WX 698 ; N uni0370 ; G 782 +U 881 ; WX 565 ; N uni0371 ; G 783 +U 882 ; WX 1022 ; N uni0372 ; G 784 +U 883 ; WX 836 ; N uni0373 ; G 785 +U 884 ; WX 302 ; N uni0374 ; G 786 +U 885 ; WX 302 ; N uni0375 ; G 787 +U 886 ; WX 837 ; N uni0376 ; G 788 +U 887 ; WX 701 ; N uni0377 ; G 789 +U 890 ; WX 500 ; N uni037A ; G 790 +U 891 ; WX 593 ; N uni037B ; G 791 +U 892 ; WX 550 ; N uni037C ; G 792 +U 893 ; WX 549 ; N uni037D ; G 793 +U 894 ; WX 400 ; N uni037E ; G 794 +U 895 ; WX 372 ; N uni037F ; G 795 +U 900 ; WX 441 ; N tonos ; G 796 +U 901 ; WX 500 ; N dieresistonos ; G 797 +U 902 ; WX 797 ; N Alphatonos ; G 798 +U 903 ; WX 380 ; N anoteleia ; G 799 +U 904 ; WX 846 ; N Epsilontonos ; G 800 +U 905 ; WX 1009 ; N Etatonos ; G 801 +U 906 ; WX 563 ; N Iotatonos ; G 802 +U 908 ; WX 891 ; N Omicrontonos ; G 803 +U 910 ; WX 980 ; N Upsilontonos ; G 804 +U 911 ; WX 894 ; N Omegatonos ; G 805 +U 912 ; WX 390 ; N iotadieresistonos ; G 806 +U 913 ; WX 774 ; N Alpha ; G 807 +U 914 ; WX 762 ; N Beta ; G 808 +U 915 ; WX 637 ; N Gamma ; G 809 +U 916 ; WX 774 ; N uni0394 ; G 810 +U 917 ; WX 683 ; N Epsilon ; G 811 +U 918 ; WX 725 ; N Zeta ; G 812 +U 919 ; WX 837 ; N Eta ; G 813 +U 920 ; WX 850 ; N Theta ; G 814 +U 921 ; WX 372 ; N Iota ; G 815 +U 922 ; WX 775 ; N Kappa ; G 816 +U 923 ; WX 774 ; N Lambda ; G 817 +U 924 ; WX 995 ; N Mu ; G 818 +U 925 ; WX 837 ; N Nu ; G 819 +U 926 ; WX 632 ; N Xi ; G 820 +U 927 ; WX 850 ; N Omicron ; G 821 +U 928 ; WX 837 ; N Pi ; G 822 +U 929 ; WX 733 ; N Rho ; G 823 +U 931 ; WX 683 ; N Sigma ; G 824 +U 932 ; WX 682 ; N Tau ; G 825 +U 933 ; WX 724 ; N Upsilon ; G 826 +U 934 ; WX 850 ; N Phi ; G 827 +U 935 ; WX 771 ; N Chi ; G 828 +U 936 ; WX 850 ; N Psi ; G 829 +U 937 ; WX 850 ; N Omega ; G 830 +U 938 ; WX 372 ; N Iotadieresis ; G 831 +U 939 ; WX 724 ; N Upsilondieresis ; G 832 +U 940 ; WX 687 ; N alphatonos ; G 833 +U 941 ; WX 557 ; N epsilontonos ; G 834 +U 942 ; WX 712 ; N etatonos ; G 835 +U 943 ; WX 390 ; N iotatonos ; G 836 +U 944 ; WX 675 ; N upsilondieresistonos ; G 837 +U 945 ; WX 687 ; N alpha ; G 838 +U 946 ; WX 716 ; N beta ; G 839 +U 947 ; WX 681 ; N gamma ; G 840 +U 948 ; WX 687 ; N delta ; G 841 +U 949 ; WX 557 ; N epsilon ; G 842 +U 950 ; WX 591 ; N zeta ; G 843 +U 951 ; WX 712 ; N eta ; G 844 +U 952 ; WX 687 ; N theta ; G 845 +U 953 ; WX 390 ; N iota ; G 846 +U 954 ; WX 710 ; N kappa ; G 847 +U 955 ; WX 633 ; N lambda ; G 848 +U 956 ; WX 736 ; N uni03BC ; G 849 +U 957 ; WX 681 ; N nu ; G 850 +U 958 ; WX 591 ; N xi ; G 851 +U 959 ; WX 687 ; N omicron ; G 852 +U 960 ; WX 791 ; N pi ; G 853 +U 961 ; WX 716 ; N rho ; G 854 +U 962 ; WX 593 ; N sigma1 ; G 855 +U 963 ; WX 779 ; N sigma ; G 856 +U 964 ; WX 638 ; N tau ; G 857 +U 965 ; WX 675 ; N upsilon ; G 858 +U 966 ; WX 782 ; N phi ; G 859 +U 967 ; WX 645 ; N chi ; G 860 +U 968 ; WX 794 ; N psi ; G 861 +U 969 ; WX 869 ; N omega ; G 862 +U 970 ; WX 390 ; N iotadieresis ; G 863 +U 971 ; WX 675 ; N upsilondieresis ; G 864 +U 972 ; WX 687 ; N omicrontonos ; G 865 +U 973 ; WX 675 ; N upsilontonos ; G 866 +U 974 ; WX 869 ; N omegatonos ; G 867 +U 975 ; WX 775 ; N uni03CF ; G 868 +U 976 ; WX 651 ; N uni03D0 ; G 869 +U 977 ; WX 661 ; N theta1 ; G 870 +U 978 ; WX 746 ; N Upsilon1 ; G 871 +U 979 ; WX 981 ; N uni03D3 ; G 872 +U 980 ; WX 746 ; N uni03D4 ; G 873 +U 981 ; WX 796 ; N phi1 ; G 874 +U 982 ; WX 869 ; N omega1 ; G 875 +U 983 ; WX 744 ; N uni03D7 ; G 876 +U 984 ; WX 850 ; N uni03D8 ; G 877 +U 985 ; WX 687 ; N uni03D9 ; G 878 +U 986 ; WX 734 ; N uni03DA ; G 879 +U 987 ; WX 593 ; N uni03DB ; G 880 +U 988 ; WX 683 ; N uni03DC ; G 881 +U 989 ; WX 494 ; N uni03DD ; G 882 +U 990 ; WX 702 ; N uni03DE ; G 883 +U 991 ; WX 660 ; N uni03DF ; G 884 +U 992 ; WX 919 ; N uni03E0 ; G 885 +U 993 ; WX 627 ; N uni03E1 ; G 886 +U 994 ; WX 1093 ; N uni03E2 ; G 887 +U 995 ; WX 837 ; N uni03E3 ; G 888 +U 996 ; WX 832 ; N uni03E4 ; G 889 +U 997 ; WX 716 ; N uni03E5 ; G 890 +U 998 ; WX 928 ; N uni03E6 ; G 891 +U 999 ; WX 744 ; N uni03E7 ; G 892 +U 1000 ; WX 733 ; N uni03E8 ; G 893 +U 1001 ; WX 650 ; N uni03E9 ; G 894 +U 1002 ; WX 789 ; N uni03EA ; G 895 +U 1003 ; WX 671 ; N uni03EB ; G 896 +U 1004 ; WX 752 ; N uni03EC ; G 897 +U 1005 ; WX 716 ; N uni03ED ; G 898 +U 1006 ; WX 682 ; N uni03EE ; G 899 +U 1007 ; WX 590 ; N uni03EF ; G 900 +U 1008 ; WX 744 ; N uni03F0 ; G 901 +U 1009 ; WX 716 ; N uni03F1 ; G 902 +U 1010 ; WX 593 ; N uni03F2 ; G 903 +U 1011 ; WX 343 ; N uni03F3 ; G 904 +U 1012 ; WX 850 ; N uni03F4 ; G 905 +U 1013 ; WX 645 ; N uni03F5 ; G 906 +U 1014 ; WX 645 ; N uni03F6 ; G 907 +U 1015 ; WX 742 ; N uni03F7 ; G 908 +U 1016 ; WX 716 ; N uni03F8 ; G 909 +U 1017 ; WX 734 ; N uni03F9 ; G 910 +U 1018 ; WX 995 ; N uni03FA ; G 911 +U 1019 ; WX 732 ; N uni03FB ; G 912 +U 1020 ; WX 716 ; N uni03FC ; G 913 +U 1021 ; WX 734 ; N uni03FD ; G 914 +U 1022 ; WX 734 ; N uni03FE ; G 915 +U 1023 ; WX 698 ; N uni03FF ; G 916 +U 1024 ; WX 683 ; N uni0400 ; G 917 +U 1025 ; WX 683 ; N uni0401 ; G 918 +U 1026 ; WX 878 ; N uni0402 ; G 919 +U 1027 ; WX 637 ; N uni0403 ; G 920 +U 1028 ; WX 734 ; N uni0404 ; G 921 +U 1029 ; WX 720 ; N uni0405 ; G 922 +U 1030 ; WX 372 ; N uni0406 ; G 923 +U 1031 ; WX 372 ; N uni0407 ; G 924 +U 1032 ; WX 372 ; N uni0408 ; G 925 +U 1033 ; WX 1154 ; N uni0409 ; G 926 +U 1034 ; WX 1130 ; N uni040A ; G 927 +U 1035 ; WX 878 ; N uni040B ; G 928 +U 1036 ; WX 817 ; N uni040C ; G 929 +U 1037 ; WX 837 ; N uni040D ; G 930 +U 1038 ; WX 771 ; N uni040E ; G 931 +U 1039 ; WX 837 ; N uni040F ; G 932 +U 1040 ; WX 774 ; N uni0410 ; G 933 +U 1041 ; WX 762 ; N uni0411 ; G 934 +U 1042 ; WX 762 ; N uni0412 ; G 935 +U 1043 ; WX 637 ; N uni0413 ; G 936 +U 1044 ; WX 891 ; N uni0414 ; G 937 +U 1045 ; WX 683 ; N uni0415 ; G 938 +U 1046 ; WX 1224 ; N uni0416 ; G 939 +U 1047 ; WX 710 ; N uni0417 ; G 940 +U 1048 ; WX 837 ; N uni0418 ; G 941 +U 1049 ; WX 837 ; N uni0419 ; G 942 +U 1050 ; WX 817 ; N uni041A ; G 943 +U 1051 ; WX 831 ; N uni041B ; G 944 +U 1052 ; WX 995 ; N uni041C ; G 945 +U 1053 ; WX 837 ; N uni041D ; G 946 +U 1054 ; WX 850 ; N uni041E ; G 947 +U 1055 ; WX 837 ; N uni041F ; G 948 +U 1056 ; WX 733 ; N uni0420 ; G 949 +U 1057 ; WX 734 ; N uni0421 ; G 950 +U 1058 ; WX 682 ; N uni0422 ; G 951 +U 1059 ; WX 771 ; N uni0423 ; G 952 +U 1060 ; WX 992 ; N uni0424 ; G 953 +U 1061 ; WX 771 ; N uni0425 ; G 954 +U 1062 ; WX 928 ; N uni0426 ; G 955 +U 1063 ; WX 808 ; N uni0427 ; G 956 +U 1064 ; WX 1235 ; N uni0428 ; G 957 +U 1065 ; WX 1326 ; N uni0429 ; G 958 +U 1066 ; WX 939 ; N uni042A ; G 959 +U 1067 ; WX 1036 ; N uni042B ; G 960 +U 1068 ; WX 762 ; N uni042C ; G 961 +U 1069 ; WX 734 ; N uni042D ; G 962 +U 1070 ; WX 1174 ; N uni042E ; G 963 +U 1071 ; WX 770 ; N uni042F ; G 964 +U 1072 ; WX 675 ; N uni0430 ; G 965 +U 1073 ; WX 698 ; N uni0431 ; G 966 +U 1074 ; WX 633 ; N uni0432 ; G 967 +U 1075 ; WX 522 ; N uni0433 ; G 968 +U 1076 ; WX 808 ; N uni0434 ; G 969 +U 1077 ; WX 678 ; N uni0435 ; G 970 +U 1078 ; WX 995 ; N uni0436 ; G 971 +U 1079 ; WX 581 ; N uni0437 ; G 972 +U 1080 ; WX 701 ; N uni0438 ; G 973 +U 1081 ; WX 701 ; N uni0439 ; G 974 +U 1082 ; WX 679 ; N uni043A ; G 975 +U 1083 ; WX 732 ; N uni043B ; G 976 +U 1084 ; WX 817 ; N uni043C ; G 977 +U 1085 ; WX 691 ; N uni043D ; G 978 +U 1086 ; WX 687 ; N uni043E ; G 979 +U 1087 ; WX 691 ; N uni043F ; G 980 +U 1088 ; WX 716 ; N uni0440 ; G 981 +U 1089 ; WX 593 ; N uni0441 ; G 982 +U 1090 ; WX 580 ; N uni0442 ; G 983 +U 1091 ; WX 652 ; N uni0443 ; G 984 +U 1092 ; WX 992 ; N uni0444 ; G 985 +U 1093 ; WX 645 ; N uni0445 ; G 986 +U 1094 ; WX 741 ; N uni0446 ; G 987 +U 1095 ; WX 687 ; N uni0447 ; G 988 +U 1096 ; WX 1062 ; N uni0448 ; G 989 +U 1097 ; WX 1105 ; N uni0449 ; G 990 +U 1098 ; WX 751 ; N uni044A ; G 991 +U 1099 ; WX 904 ; N uni044B ; G 992 +U 1100 ; WX 632 ; N uni044C ; G 993 +U 1101 ; WX 593 ; N uni044D ; G 994 +U 1102 ; WX 972 ; N uni044E ; G 995 +U 1103 ; WX 642 ; N uni044F ; G 996 +U 1104 ; WX 678 ; N uni0450 ; G 997 +U 1105 ; WX 678 ; N uni0451 ; G 998 +U 1106 ; WX 714 ; N uni0452 ; G 999 +U 1107 ; WX 522 ; N uni0453 ; G 1000 +U 1108 ; WX 593 ; N uni0454 ; G 1001 +U 1109 ; WX 595 ; N uni0455 ; G 1002 +U 1110 ; WX 343 ; N uni0456 ; G 1003 +U 1111 ; WX 343 ; N uni0457 ; G 1004 +U 1112 ; WX 343 ; N uni0458 ; G 1005 +U 1113 ; WX 991 ; N uni0459 ; G 1006 +U 1114 ; WX 956 ; N uni045A ; G 1007 +U 1115 ; WX 734 ; N uni045B ; G 1008 +U 1116 ; WX 679 ; N uni045C ; G 1009 +U 1117 ; WX 701 ; N uni045D ; G 1010 +U 1118 ; WX 652 ; N uni045E ; G 1011 +U 1119 ; WX 691 ; N uni045F ; G 1012 +U 1120 ; WX 1093 ; N uni0460 ; G 1013 +U 1121 ; WX 869 ; N uni0461 ; G 1014 +U 1122 ; WX 840 ; N uni0462 ; G 1015 +U 1123 ; WX 736 ; N uni0463 ; G 1016 +U 1124 ; WX 1012 ; N uni0464 ; G 1017 +U 1125 ; WX 839 ; N uni0465 ; G 1018 +U 1126 ; WX 992 ; N uni0466 ; G 1019 +U 1127 ; WX 832 ; N uni0467 ; G 1020 +U 1128 ; WX 1358 ; N uni0468 ; G 1021 +U 1129 ; WX 1121 ; N uni0469 ; G 1022 +U 1130 ; WX 850 ; N uni046A ; G 1023 +U 1131 ; WX 687 ; N uni046B ; G 1024 +U 1132 ; WX 1236 ; N uni046C ; G 1025 +U 1133 ; WX 1007 ; N uni046D ; G 1026 +U 1134 ; WX 696 ; N uni046E ; G 1027 +U 1135 ; WX 557 ; N uni046F ; G 1028 +U 1136 ; WX 1075 ; N uni0470 ; G 1029 +U 1137 ; WX 1061 ; N uni0471 ; G 1030 +U 1138 ; WX 850 ; N uni0472 ; G 1031 +U 1139 ; WX 687 ; N uni0473 ; G 1032 +U 1140 ; WX 850 ; N uni0474 ; G 1033 +U 1141 ; WX 695 ; N uni0475 ; G 1034 +U 1142 ; WX 850 ; N uni0476 ; G 1035 +U 1143 ; WX 695 ; N uni0477 ; G 1036 +U 1144 ; WX 1148 ; N uni0478 ; G 1037 +U 1145 ; WX 1043 ; N uni0479 ; G 1038 +U 1146 ; WX 1074 ; N uni047A ; G 1039 +U 1147 ; WX 863 ; N uni047B ; G 1040 +U 1148 ; WX 1405 ; N uni047C ; G 1041 +U 1149 ; WX 1173 ; N uni047D ; G 1042 +U 1150 ; WX 1093 ; N uni047E ; G 1043 +U 1151 ; WX 869 ; N uni047F ; G 1044 +U 1152 ; WX 734 ; N uni0480 ; G 1045 +U 1153 ; WX 593 ; N uni0481 ; G 1046 +U 1154 ; WX 652 ; N uni0482 ; G 1047 +U 1155 ; WX 0 ; N uni0483 ; G 1048 +U 1156 ; WX 0 ; N uni0484 ; G 1049 +U 1157 ; WX 0 ; N uni0485 ; G 1050 +U 1158 ; WX 0 ; N uni0486 ; G 1051 +U 1159 ; WX 0 ; N uni0487 ; G 1052 +U 1160 ; WX 418 ; N uni0488 ; G 1053 +U 1161 ; WX 418 ; N uni0489 ; G 1054 +U 1162 ; WX 938 ; N uni048A ; G 1055 +U 1163 ; WX 806 ; N uni048B ; G 1056 +U 1164 ; WX 762 ; N uni048C ; G 1057 +U 1165 ; WX 611 ; N uni048D ; G 1058 +U 1166 ; WX 736 ; N uni048E ; G 1059 +U 1167 ; WX 718 ; N uni048F ; G 1060 +U 1168 ; WX 637 ; N uni0490 ; G 1061 +U 1169 ; WX 522 ; N uni0491 ; G 1062 +U 1170 ; WX 666 ; N uni0492 ; G 1063 +U 1171 ; WX 543 ; N uni0493 ; G 1064 +U 1172 ; WX 789 ; N uni0494 ; G 1065 +U 1173 ; WX 522 ; N uni0495 ; G 1066 +U 1174 ; WX 1224 ; N uni0496 ; G 1067 +U 1175 ; WX 995 ; N uni0497 ; G 1068 +U 1176 ; WX 710 ; N uni0498 ; G 1069 +U 1177 ; WX 581 ; N uni0499 ; G 1070 +U 1178 ; WX 775 ; N uni049A ; G 1071 +U 1179 ; WX 679 ; N uni049B ; G 1072 +U 1180 ; WX 817 ; N uni049C ; G 1073 +U 1181 ; WX 679 ; N uni049D ; G 1074 +U 1182 ; WX 817 ; N uni049E ; G 1075 +U 1183 ; WX 679 ; N uni049F ; G 1076 +U 1184 ; WX 1015 ; N uni04A0 ; G 1077 +U 1185 ; WX 826 ; N uni04A1 ; G 1078 +U 1186 ; WX 837 ; N uni04A2 ; G 1079 +U 1187 ; WX 691 ; N uni04A3 ; G 1080 +U 1188 ; WX 1103 ; N uni04A4 ; G 1081 +U 1189 ; WX 871 ; N uni04A5 ; G 1082 +U 1190 ; WX 1254 ; N uni04A6 ; G 1083 +U 1191 ; WX 979 ; N uni04A7 ; G 1084 +U 1192 ; WX 946 ; N uni04A8 ; G 1085 +U 1193 ; WX 859 ; N uni04A9 ; G 1086 +U 1194 ; WX 734 ; N uni04AA ; G 1087 +U 1195 ; WX 593 ; N uni04AB ; G 1088 +U 1196 ; WX 682 ; N uni04AC ; G 1089 +U 1197 ; WX 580 ; N uni04AD ; G 1090 +U 1198 ; WX 724 ; N uni04AE ; G 1091 +U 1199 ; WX 652 ; N uni04AF ; G 1092 +U 1200 ; WX 724 ; N uni04B0 ; G 1093 +U 1201 ; WX 652 ; N uni04B1 ; G 1094 +U 1202 ; WX 771 ; N uni04B2 ; G 1095 +U 1203 ; WX 645 ; N uni04B3 ; G 1096 +U 1204 ; WX 1104 ; N uni04B4 ; G 1097 +U 1205 ; WX 1001 ; N uni04B5 ; G 1098 +U 1206 ; WX 808 ; N uni04B6 ; G 1099 +U 1207 ; WX 687 ; N uni04B7 ; G 1100 +U 1208 ; WX 808 ; N uni04B8 ; G 1101 +U 1209 ; WX 687 ; N uni04B9 ; G 1102 +U 1210 ; WX 808 ; N uni04BA ; G 1103 +U 1211 ; WX 712 ; N uni04BB ; G 1104 +U 1212 ; WX 1026 ; N uni04BC ; G 1105 +U 1213 ; WX 810 ; N uni04BD ; G 1106 +U 1214 ; WX 1026 ; N uni04BE ; G 1107 +U 1215 ; WX 810 ; N uni04BF ; G 1108 +U 1216 ; WX 372 ; N uni04C0 ; G 1109 +U 1217 ; WX 1224 ; N uni04C1 ; G 1110 +U 1218 ; WX 995 ; N uni04C2 ; G 1111 +U 1219 ; WX 778 ; N uni04C3 ; G 1112 +U 1220 ; WX 629 ; N uni04C4 ; G 1113 +U 1221 ; WX 933 ; N uni04C5 ; G 1114 +U 1222 ; WX 804 ; N uni04C6 ; G 1115 +U 1223 ; WX 837 ; N uni04C7 ; G 1116 +U 1224 ; WX 691 ; N uni04C8 ; G 1117 +U 1225 ; WX 938 ; N uni04C9 ; G 1118 +U 1226 ; WX 806 ; N uni04CA ; G 1119 +U 1227 ; WX 808 ; N uni04CB ; G 1120 +U 1228 ; WX 687 ; N uni04CC ; G 1121 +U 1229 ; WX 1096 ; N uni04CD ; G 1122 +U 1230 ; WX 932 ; N uni04CE ; G 1123 +U 1231 ; WX 343 ; N uni04CF ; G 1124 +U 1232 ; WX 774 ; N uni04D0 ; G 1125 +U 1233 ; WX 675 ; N uni04D1 ; G 1126 +U 1234 ; WX 774 ; N uni04D2 ; G 1127 +U 1235 ; WX 675 ; N uni04D3 ; G 1128 +U 1236 ; WX 1085 ; N uni04D4 ; G 1129 +U 1237 ; WX 1048 ; N uni04D5 ; G 1130 +U 1238 ; WX 683 ; N uni04D6 ; G 1131 +U 1239 ; WX 678 ; N uni04D7 ; G 1132 +U 1240 ; WX 850 ; N uni04D8 ; G 1133 +U 1241 ; WX 678 ; N uni04D9 ; G 1134 +U 1242 ; WX 850 ; N uni04DA ; G 1135 +U 1243 ; WX 678 ; N uni04DB ; G 1136 +U 1244 ; WX 1224 ; N uni04DC ; G 1137 +U 1245 ; WX 995 ; N uni04DD ; G 1138 +U 1246 ; WX 710 ; N uni04DE ; G 1139 +U 1247 ; WX 581 ; N uni04DF ; G 1140 +U 1248 ; WX 772 ; N uni04E0 ; G 1141 +U 1249 ; WX 641 ; N uni04E1 ; G 1142 +U 1250 ; WX 837 ; N uni04E2 ; G 1143 +U 1251 ; WX 701 ; N uni04E3 ; G 1144 +U 1252 ; WX 837 ; N uni04E4 ; G 1145 +U 1253 ; WX 701 ; N uni04E5 ; G 1146 +U 1254 ; WX 850 ; N uni04E6 ; G 1147 +U 1255 ; WX 687 ; N uni04E7 ; G 1148 +U 1256 ; WX 850 ; N uni04E8 ; G 1149 +U 1257 ; WX 687 ; N uni04E9 ; G 1150 +U 1258 ; WX 850 ; N uni04EA ; G 1151 +U 1259 ; WX 687 ; N uni04EB ; G 1152 +U 1260 ; WX 734 ; N uni04EC ; G 1153 +U 1261 ; WX 593 ; N uni04ED ; G 1154 +U 1262 ; WX 771 ; N uni04EE ; G 1155 +U 1263 ; WX 652 ; N uni04EF ; G 1156 +U 1264 ; WX 771 ; N uni04F0 ; G 1157 +U 1265 ; WX 652 ; N uni04F1 ; G 1158 +U 1266 ; WX 771 ; N uni04F2 ; G 1159 +U 1267 ; WX 652 ; N uni04F3 ; G 1160 +U 1268 ; WX 808 ; N uni04F4 ; G 1161 +U 1269 ; WX 687 ; N uni04F5 ; G 1162 +U 1270 ; WX 637 ; N uni04F6 ; G 1163 +U 1271 ; WX 522 ; N uni04F7 ; G 1164 +U 1272 ; WX 1036 ; N uni04F8 ; G 1165 +U 1273 ; WX 904 ; N uni04F9 ; G 1166 +U 1274 ; WX 666 ; N uni04FA ; G 1167 +U 1275 ; WX 543 ; N uni04FB ; G 1168 +U 1276 ; WX 771 ; N uni04FC ; G 1169 +U 1277 ; WX 645 ; N uni04FD ; G 1170 +U 1278 ; WX 771 ; N uni04FE ; G 1171 +U 1279 ; WX 645 ; N uni04FF ; G 1172 +U 1280 ; WX 762 ; N uni0500 ; G 1173 +U 1281 ; WX 608 ; N uni0501 ; G 1174 +U 1282 ; WX 1159 ; N uni0502 ; G 1175 +U 1283 ; WX 893 ; N uni0503 ; G 1176 +U 1284 ; WX 1119 ; N uni0504 ; G 1177 +U 1285 ; WX 920 ; N uni0505 ; G 1178 +U 1286 ; WX 828 ; N uni0506 ; G 1179 +U 1287 ; WX 693 ; N uni0507 ; G 1180 +U 1288 ; WX 1242 ; N uni0508 ; G 1181 +U 1289 ; WX 1017 ; N uni0509 ; G 1182 +U 1290 ; WX 1289 ; N uni050A ; G 1183 +U 1291 ; WX 1013 ; N uni050B ; G 1184 +U 1292 ; WX 839 ; N uni050C ; G 1185 +U 1293 ; WX 638 ; N uni050D ; G 1186 +U 1294 ; WX 938 ; N uni050E ; G 1187 +U 1295 ; WX 803 ; N uni050F ; G 1188 +U 1296 ; WX 696 ; N uni0510 ; G 1189 +U 1297 ; WX 557 ; N uni0511 ; G 1190 +U 1298 ; WX 831 ; N uni0512 ; G 1191 +U 1299 ; WX 732 ; N uni0513 ; G 1192 +U 1300 ; WX 1286 ; N uni0514 ; G 1193 +U 1301 ; WX 1070 ; N uni0515 ; G 1194 +U 1302 ; WX 1065 ; N uni0516 ; G 1195 +U 1303 ; WX 982 ; N uni0517 ; G 1196 +U 1304 ; WX 1082 ; N uni0518 ; G 1197 +U 1305 ; WX 960 ; N uni0519 ; G 1198 +U 1306 ; WX 850 ; N uni051A ; G 1199 +U 1307 ; WX 716 ; N uni051B ; G 1200 +U 1308 ; WX 1103 ; N uni051C ; G 1201 +U 1309 ; WX 924 ; N uni051D ; G 1202 +U 1310 ; WX 817 ; N uni051E ; G 1203 +U 1311 ; WX 679 ; N uni051F ; G 1204 +U 1312 ; WX 1248 ; N uni0520 ; G 1205 +U 1313 ; WX 1022 ; N uni0521 ; G 1206 +U 1314 ; WX 1254 ; N uni0522 ; G 1207 +U 1315 ; WX 979 ; N uni0523 ; G 1208 +U 1316 ; WX 957 ; N uni0524 ; G 1209 +U 1317 ; WX 807 ; N uni0525 ; G 1210 +U 1329 ; WX 904 ; N uni0531 ; G 1211 +U 1330 ; WX 810 ; N uni0532 ; G 1212 +U 1331 ; WX 809 ; N uni0533 ; G 1213 +U 1332 ; WX 813 ; N uni0534 ; G 1214 +U 1333 ; WX 810 ; N uni0535 ; G 1215 +U 1334 ; WX 815 ; N uni0536 ; G 1216 +U 1335 ; WX 724 ; N uni0537 ; G 1217 +U 1336 ; WX 800 ; N uni0538 ; G 1218 +U 1337 ; WX 1004 ; N uni0539 ; G 1219 +U 1338 ; WX 809 ; N uni053A ; G 1220 +U 1339 ; WX 740 ; N uni053B ; G 1221 +U 1340 ; WX 620 ; N uni053C ; G 1222 +U 1341 ; WX 1068 ; N uni053D ; G 1223 +U 1342 ; WX 875 ; N uni053E ; G 1224 +U 1343 ; WX 792 ; N uni053F ; G 1225 +U 1344 ; WX 723 ; N uni0540 ; G 1226 +U 1345 ; WX 811 ; N uni0541 ; G 1227 +U 1346 ; WX 794 ; N uni0542 ; G 1228 +U 1347 ; WX 782 ; N uni0543 ; G 1229 +U 1348 ; WX 867 ; N uni0544 ; G 1230 +U 1349 ; WX 766 ; N uni0545 ; G 1231 +U 1350 ; WX 794 ; N uni0546 ; G 1232 +U 1351 ; WX 787 ; N uni0547 ; G 1233 +U 1352 ; WX 812 ; N uni0548 ; G 1234 +U 1353 ; WX 752 ; N uni0549 ; G 1235 +U 1354 ; WX 963 ; N uni054A ; G 1236 +U 1355 ; WX 790 ; N uni054B ; G 1237 +U 1356 ; WX 867 ; N uni054C ; G 1238 +U 1357 ; WX 812 ; N uni054D ; G 1239 +U 1358 ; WX 794 ; N uni054E ; G 1240 +U 1359 ; WX 771 ; N uni054F ; G 1241 +U 1360 ; WX 740 ; N uni0550 ; G 1242 +U 1361 ; WX 775 ; N uni0551 ; G 1243 +U 1362 ; WX 640 ; N uni0552 ; G 1244 +U 1363 ; WX 926 ; N uni0553 ; G 1245 +U 1364 ; WX 775 ; N uni0554 ; G 1246 +U 1365 ; WX 848 ; N uni0555 ; G 1247 +U 1366 ; WX 951 ; N uni0556 ; G 1248 +U 1369 ; WX 366 ; N uni0559 ; G 1249 +U 1370 ; WX 380 ; N uni055A ; G 1250 +U 1371 ; WX 342 ; N uni055B ; G 1251 +U 1372 ; WX 415 ; N uni055C ; G 1252 +U 1373 ; WX 348 ; N uni055D ; G 1253 +U 1374 ; WX 513 ; N uni055E ; G 1254 +U 1375 ; WX 521 ; N uni055F ; G 1255 +U 1377 ; WX 1043 ; N uni0561 ; G 1256 +U 1378 ; WX 713 ; N uni0562 ; G 1257 +U 1379 ; WX 782 ; N uni0563 ; G 1258 +U 1380 ; WX 786 ; N uni0564 ; G 1259 +U 1381 ; WX 713 ; N uni0565 ; G 1260 +U 1382 ; WX 715 ; N uni0566 ; G 1261 +U 1383 ; WX 628 ; N uni0567 ; G 1262 +U 1384 ; WX 713 ; N uni0568 ; G 1263 +U 1385 ; WX 840 ; N uni0569 ; G 1264 +U 1386 ; WX 782 ; N uni056A ; G 1265 +U 1387 ; WX 714 ; N uni056B ; G 1266 +U 1388 ; WX 344 ; N uni056C ; G 1267 +U 1389 ; WX 1094 ; N uni056D ; G 1268 +U 1390 ; WX 708 ; N uni056E ; G 1269 +U 1391 ; WX 714 ; N uni056F ; G 1270 +U 1392 ; WX 714 ; N uni0570 ; G 1271 +U 1393 ; WX 670 ; N uni0571 ; G 1272 +U 1394 ; WX 714 ; N uni0572 ; G 1273 +U 1395 ; WX 713 ; N uni0573 ; G 1274 +U 1396 ; WX 714 ; N uni0574 ; G 1275 +U 1397 ; WX 343 ; N uni0575 ; G 1276 +U 1398 ; WX 714 ; N uni0576 ; G 1277 +U 1399 ; WX 541 ; N uni0577 ; G 1278 +U 1400 ; WX 714 ; N uni0578 ; G 1279 +U 1401 ; WX 407 ; N uni0579 ; G 1280 +U 1402 ; WX 1043 ; N uni057A ; G 1281 +U 1403 ; WX 636 ; N uni057B ; G 1282 +U 1404 ; WX 740 ; N uni057C ; G 1283 +U 1405 ; WX 714 ; N uni057D ; G 1284 +U 1406 ; WX 714 ; N uni057E ; G 1285 +U 1407 ; WX 1038 ; N uni057F ; G 1286 +U 1408 ; WX 714 ; N uni0580 ; G 1287 +U 1409 ; WX 714 ; N uni0581 ; G 1288 +U 1410 ; WX 532 ; N uni0582 ; G 1289 +U 1411 ; WX 1038 ; N uni0583 ; G 1290 +U 1412 ; WX 720 ; N uni0584 ; G 1291 +U 1413 ; WX 689 ; N uni0585 ; G 1292 +U 1414 ; WX 904 ; N uni0586 ; G 1293 +U 1415 ; WX 902 ; N uni0587 ; G 1294 +U 1417 ; WX 400 ; N uni0589 ; G 1295 +U 1418 ; WX 415 ; N uni058A ; G 1296 +U 1456 ; WX 0 ; N uni05B0 ; G 1297 +U 1457 ; WX 0 ; N uni05B1 ; G 1298 +U 1458 ; WX 0 ; N uni05B2 ; G 1299 +U 1459 ; WX 0 ; N uni05B3 ; G 1300 +U 1460 ; WX 0 ; N uni05B4 ; G 1301 +U 1461 ; WX 0 ; N uni05B5 ; G 1302 +U 1462 ; WX 0 ; N uni05B6 ; G 1303 +U 1463 ; WX 0 ; N uni05B7 ; G 1304 +U 1464 ; WX 0 ; N uni05B8 ; G 1305 +U 1465 ; WX 0 ; N uni05B9 ; G 1306 +U 1466 ; WX 0 ; N uni05BA ; G 1307 +U 1467 ; WX 0 ; N uni05BB ; G 1308 +U 1468 ; WX 0 ; N uni05BC ; G 1309 +U 1469 ; WX 0 ; N uni05BD ; G 1310 +U 1470 ; WX 415 ; N uni05BE ; G 1311 +U 1471 ; WX 0 ; N uni05BF ; G 1312 +U 1472 ; WX 372 ; N uni05C0 ; G 1313 +U 1473 ; WX 0 ; N uni05C1 ; G 1314 +U 1474 ; WX 0 ; N uni05C2 ; G 1315 +U 1475 ; WX 372 ; N uni05C3 ; G 1316 +U 1478 ; WX 497 ; N uni05C6 ; G 1317 +U 1479 ; WX 0 ; N uni05C7 ; G 1318 +U 1488 ; WX 728 ; N uni05D0 ; G 1319 +U 1489 ; WX 610 ; N uni05D1 ; G 1320 +U 1490 ; WX 447 ; N uni05D2 ; G 1321 +U 1491 ; WX 588 ; N uni05D3 ; G 1322 +U 1492 ; WX 687 ; N uni05D4 ; G 1323 +U 1493 ; WX 343 ; N uni05D5 ; G 1324 +U 1494 ; WX 400 ; N uni05D6 ; G 1325 +U 1495 ; WX 687 ; N uni05D7 ; G 1326 +U 1496 ; WX 679 ; N uni05D8 ; G 1327 +U 1497 ; WX 294 ; N uni05D9 ; G 1328 +U 1498 ; WX 578 ; N uni05DA ; G 1329 +U 1499 ; WX 566 ; N uni05DB ; G 1330 +U 1500 ; WX 605 ; N uni05DC ; G 1331 +U 1501 ; WX 696 ; N uni05DD ; G 1332 +U 1502 ; WX 724 ; N uni05DE ; G 1333 +U 1503 ; WX 343 ; N uni05DF ; G 1334 +U 1504 ; WX 453 ; N uni05E0 ; G 1335 +U 1505 ; WX 680 ; N uni05E1 ; G 1336 +U 1506 ; WX 666 ; N uni05E2 ; G 1337 +U 1507 ; WX 675 ; N uni05E3 ; G 1338 +U 1508 ; WX 658 ; N uni05E4 ; G 1339 +U 1509 ; WX 661 ; N uni05E5 ; G 1340 +U 1510 ; WX 653 ; N uni05E6 ; G 1341 +U 1511 ; WX 736 ; N uni05E7 ; G 1342 +U 1512 ; WX 602 ; N uni05E8 ; G 1343 +U 1513 ; WX 749 ; N uni05E9 ; G 1344 +U 1514 ; WX 683 ; N uni05EA ; G 1345 +U 1520 ; WX 664 ; N uni05F0 ; G 1346 +U 1521 ; WX 664 ; N uni05F1 ; G 1347 +U 1522 ; WX 663 ; N uni05F2 ; G 1348 +U 1523 ; WX 444 ; N uni05F3 ; G 1349 +U 1524 ; WX 710 ; N uni05F4 ; G 1350 +U 3647 ; WX 696 ; N uni0E3F ; G 1351 +U 3713 ; WX 815 ; N uni0E81 ; G 1352 +U 3714 ; WX 748 ; N uni0E82 ; G 1353 +U 3716 ; WX 749 ; N uni0E84 ; G 1354 +U 3719 ; WX 569 ; N uni0E87 ; G 1355 +U 3720 ; WX 742 ; N uni0E88 ; G 1356 +U 3722 ; WX 744 ; N uni0E8A ; G 1357 +U 3725 ; WX 761 ; N uni0E8D ; G 1358 +U 3732 ; WX 706 ; N uni0E94 ; G 1359 +U 3733 ; WX 704 ; N uni0E95 ; G 1360 +U 3734 ; WX 747 ; N uni0E96 ; G 1361 +U 3735 ; WX 819 ; N uni0E97 ; G 1362 +U 3737 ; WX 730 ; N uni0E99 ; G 1363 +U 3738 ; WX 727 ; N uni0E9A ; G 1364 +U 3739 ; WX 727 ; N uni0E9B ; G 1365 +U 3740 ; WX 922 ; N uni0E9C ; G 1366 +U 3741 ; WX 827 ; N uni0E9D ; G 1367 +U 3742 ; WX 866 ; N uni0E9E ; G 1368 +U 3743 ; WX 866 ; N uni0E9F ; G 1369 +U 3745 ; WX 836 ; N uni0EA1 ; G 1370 +U 3746 ; WX 761 ; N uni0EA2 ; G 1371 +U 3747 ; WX 770 ; N uni0EA3 ; G 1372 +U 3749 ; WX 769 ; N uni0EA5 ; G 1373 +U 3751 ; WX 713 ; N uni0EA7 ; G 1374 +U 3754 ; WX 827 ; N uni0EAA ; G 1375 +U 3755 ; WX 1031 ; N uni0EAB ; G 1376 +U 3757 ; WX 724 ; N uni0EAD ; G 1377 +U 3758 ; WX 784 ; N uni0EAE ; G 1378 +U 3759 ; WX 934 ; N uni0EAF ; G 1379 +U 3760 ; WX 688 ; N uni0EB0 ; G 1380 +U 3761 ; WX 0 ; N uni0EB1 ; G 1381 +U 3762 ; WX 610 ; N uni0EB2 ; G 1382 +U 3763 ; WX 610 ; N uni0EB3 ; G 1383 +U 3764 ; WX 0 ; N uni0EB4 ; G 1384 +U 3765 ; WX 0 ; N uni0EB5 ; G 1385 +U 3766 ; WX 0 ; N uni0EB6 ; G 1386 +U 3767 ; WX 0 ; N uni0EB7 ; G 1387 +U 3768 ; WX 0 ; N uni0EB8 ; G 1388 +U 3769 ; WX 0 ; N uni0EB9 ; G 1389 +U 3771 ; WX 0 ; N uni0EBB ; G 1390 +U 3772 ; WX 0 ; N uni0EBC ; G 1391 +U 3773 ; WX 670 ; N uni0EBD ; G 1392 +U 3776 ; WX 516 ; N uni0EC0 ; G 1393 +U 3777 ; WX 860 ; N uni0EC1 ; G 1394 +U 3778 ; WX 516 ; N uni0EC2 ; G 1395 +U 3779 ; WX 650 ; N uni0EC3 ; G 1396 +U 3780 ; WX 632 ; N uni0EC4 ; G 1397 +U 3782 ; WX 759 ; N uni0EC6 ; G 1398 +U 3784 ; WX 0 ; N uni0EC8 ; G 1399 +U 3785 ; WX 0 ; N uni0EC9 ; G 1400 +U 3786 ; WX 0 ; N uni0ECA ; G 1401 +U 3787 ; WX 0 ; N uni0ECB ; G 1402 +U 3788 ; WX 0 ; N uni0ECC ; G 1403 +U 3789 ; WX 0 ; N uni0ECD ; G 1404 +U 3792 ; WX 771 ; N uni0ED0 ; G 1405 +U 3793 ; WX 771 ; N uni0ED1 ; G 1406 +U 3794 ; WX 693 ; N uni0ED2 ; G 1407 +U 3795 ; WX 836 ; N uni0ED3 ; G 1408 +U 3796 ; WX 729 ; N uni0ED4 ; G 1409 +U 3797 ; WX 729 ; N uni0ED5 ; G 1410 +U 3798 ; WX 849 ; N uni0ED6 ; G 1411 +U 3799 ; WX 790 ; N uni0ED7 ; G 1412 +U 3800 ; WX 759 ; N uni0ED8 ; G 1413 +U 3801 ; WX 910 ; N uni0ED9 ; G 1414 +U 3804 ; WX 1363 ; N uni0EDC ; G 1415 +U 3805 ; WX 1363 ; N uni0EDD ; G 1416 +U 4256 ; WX 874 ; N uni10A0 ; G 1417 +U 4257 ; WX 733 ; N uni10A1 ; G 1418 +U 4258 ; WX 679 ; N uni10A2 ; G 1419 +U 4259 ; WX 834 ; N uni10A3 ; G 1420 +U 4260 ; WX 615 ; N uni10A4 ; G 1421 +U 4261 ; WX 768 ; N uni10A5 ; G 1422 +U 4262 ; WX 753 ; N uni10A6 ; G 1423 +U 4263 ; WX 914 ; N uni10A7 ; G 1424 +U 4264 ; WX 453 ; N uni10A8 ; G 1425 +U 4265 ; WX 620 ; N uni10A9 ; G 1426 +U 4266 ; WX 843 ; N uni10AA ; G 1427 +U 4267 ; WX 882 ; N uni10AB ; G 1428 +U 4268 ; WX 625 ; N uni10AC ; G 1429 +U 4269 ; WX 854 ; N uni10AD ; G 1430 +U 4270 ; WX 781 ; N uni10AE ; G 1431 +U 4271 ; WX 629 ; N uni10AF ; G 1432 +U 4272 ; WX 912 ; N uni10B0 ; G 1433 +U 4273 ; WX 621 ; N uni10B1 ; G 1434 +U 4274 ; WX 620 ; N uni10B2 ; G 1435 +U 4275 ; WX 854 ; N uni10B3 ; G 1436 +U 4276 ; WX 866 ; N uni10B4 ; G 1437 +U 4277 ; WX 724 ; N uni10B5 ; G 1438 +U 4278 ; WX 630 ; N uni10B6 ; G 1439 +U 4279 ; WX 621 ; N uni10B7 ; G 1440 +U 4280 ; WX 625 ; N uni10B8 ; G 1441 +U 4281 ; WX 620 ; N uni10B9 ; G 1442 +U 4282 ; WX 818 ; N uni10BA ; G 1443 +U 4283 ; WX 874 ; N uni10BB ; G 1444 +U 4284 ; WX 615 ; N uni10BC ; G 1445 +U 4285 ; WX 623 ; N uni10BD ; G 1446 +U 4286 ; WX 625 ; N uni10BE ; G 1447 +U 4287 ; WX 725 ; N uni10BF ; G 1448 +U 4288 ; WX 844 ; N uni10C0 ; G 1449 +U 4289 ; WX 596 ; N uni10C1 ; G 1450 +U 4290 ; WX 688 ; N uni10C2 ; G 1451 +U 4291 ; WX 596 ; N uni10C3 ; G 1452 +U 4292 ; WX 594 ; N uni10C4 ; G 1453 +U 4293 ; WX 738 ; N uni10C5 ; G 1454 +U 4304 ; WX 554 ; N uni10D0 ; G 1455 +U 4305 ; WX 563 ; N uni10D1 ; G 1456 +U 4306 ; WX 622 ; N uni10D2 ; G 1457 +U 4307 ; WX 834 ; N uni10D3 ; G 1458 +U 4308 ; WX 550 ; N uni10D4 ; G 1459 +U 4309 ; WX 559 ; N uni10D5 ; G 1460 +U 4310 ; WX 546 ; N uni10D6 ; G 1461 +U 4311 ; WX 828 ; N uni10D7 ; G 1462 +U 4312 ; WX 563 ; N uni10D8 ; G 1463 +U 4313 ; WX 556 ; N uni10D9 ; G 1464 +U 4314 ; WX 1074 ; N uni10DA ; G 1465 +U 4315 ; WX 563 ; N uni10DB ; G 1466 +U 4316 ; WX 563 ; N uni10DC ; G 1467 +U 4317 ; WX 814 ; N uni10DD ; G 1468 +U 4318 ; WX 554 ; N uni10DE ; G 1469 +U 4319 ; WX 559 ; N uni10DF ; G 1470 +U 4320 ; WX 823 ; N uni10E0 ; G 1471 +U 4321 ; WX 563 ; N uni10E1 ; G 1472 +U 4322 ; WX 700 ; N uni10E2 ; G 1473 +U 4323 ; WX 582 ; N uni10E3 ; G 1474 +U 4324 ; WX 847 ; N uni10E4 ; G 1475 +U 4325 ; WX 555 ; N uni10E5 ; G 1476 +U 4326 ; WX 814 ; N uni10E6 ; G 1477 +U 4327 ; WX 559 ; N uni10E7 ; G 1478 +U 4328 ; WX 543 ; N uni10E8 ; G 1479 +U 4329 ; WX 563 ; N uni10E9 ; G 1480 +U 4330 ; WX 622 ; N uni10EA ; G 1481 +U 4331 ; WX 563 ; N uni10EB ; G 1482 +U 4332 ; WX 543 ; N uni10EC ; G 1483 +U 4333 ; WX 566 ; N uni10ED ; G 1484 +U 4334 ; WX 563 ; N uni10EE ; G 1485 +U 4335 ; WX 530 ; N uni10EF ; G 1486 +U 4336 ; WX 554 ; N uni10F0 ; G 1487 +U 4337 ; WX 554 ; N uni10F1 ; G 1488 +U 4338 ; WX 553 ; N uni10F2 ; G 1489 +U 4339 ; WX 554 ; N uni10F3 ; G 1490 +U 4340 ; WX 553 ; N uni10F4 ; G 1491 +U 4341 ; WX 583 ; N uni10F5 ; G 1492 +U 4342 ; WX 853 ; N uni10F6 ; G 1493 +U 4343 ; WX 604 ; N uni10F7 ; G 1494 +U 4344 ; WX 559 ; N uni10F8 ; G 1495 +U 4345 ; WX 632 ; N uni10F9 ; G 1496 +U 4346 ; WX 554 ; N uni10FA ; G 1497 +U 4347 ; WX 448 ; N uni10FB ; G 1498 +U 4348 ; WX 324 ; N uni10FC ; G 1499 +U 5121 ; WX 774 ; N uni1401 ; G 1500 +U 5122 ; WX 774 ; N uni1402 ; G 1501 +U 5123 ; WX 774 ; N uni1403 ; G 1502 +U 5124 ; WX 774 ; N uni1404 ; G 1503 +U 5125 ; WX 905 ; N uni1405 ; G 1504 +U 5126 ; WX 905 ; N uni1406 ; G 1505 +U 5127 ; WX 905 ; N uni1407 ; G 1506 +U 5129 ; WX 905 ; N uni1409 ; G 1507 +U 5130 ; WX 905 ; N uni140A ; G 1508 +U 5131 ; WX 905 ; N uni140B ; G 1509 +U 5132 ; WX 1018 ; N uni140C ; G 1510 +U 5133 ; WX 1009 ; N uni140D ; G 1511 +U 5134 ; WX 1018 ; N uni140E ; G 1512 +U 5135 ; WX 1009 ; N uni140F ; G 1513 +U 5136 ; WX 1018 ; N uni1410 ; G 1514 +U 5137 ; WX 1009 ; N uni1411 ; G 1515 +U 5138 ; WX 1149 ; N uni1412 ; G 1516 +U 5139 ; WX 1140 ; N uni1413 ; G 1517 +U 5140 ; WX 1149 ; N uni1414 ; G 1518 +U 5141 ; WX 1140 ; N uni1415 ; G 1519 +U 5142 ; WX 905 ; N uni1416 ; G 1520 +U 5143 ; WX 1149 ; N uni1417 ; G 1521 +U 5144 ; WX 1142 ; N uni1418 ; G 1522 +U 5145 ; WX 1149 ; N uni1419 ; G 1523 +U 5146 ; WX 1142 ; N uni141A ; G 1524 +U 5147 ; WX 905 ; N uni141B ; G 1525 +U 5149 ; WX 310 ; N uni141D ; G 1526 +U 5150 ; WX 529 ; N uni141E ; G 1527 +U 5151 ; WX 425 ; N uni141F ; G 1528 +U 5152 ; WX 425 ; N uni1420 ; G 1529 +U 5153 ; WX 395 ; N uni1421 ; G 1530 +U 5154 ; WX 395 ; N uni1422 ; G 1531 +U 5155 ; WX 395 ; N uni1423 ; G 1532 +U 5156 ; WX 395 ; N uni1424 ; G 1533 +U 5157 ; WX 564 ; N uni1425 ; G 1534 +U 5158 ; WX 470 ; N uni1426 ; G 1535 +U 5159 ; WX 310 ; N uni1427 ; G 1536 +U 5160 ; WX 395 ; N uni1428 ; G 1537 +U 5161 ; WX 395 ; N uni1429 ; G 1538 +U 5162 ; WX 395 ; N uni142A ; G 1539 +U 5163 ; WX 1213 ; N uni142B ; G 1540 +U 5164 ; WX 986 ; N uni142C ; G 1541 +U 5165 ; WX 1216 ; N uni142D ; G 1542 +U 5166 ; WX 1297 ; N uni142E ; G 1543 +U 5167 ; WX 774 ; N uni142F ; G 1544 +U 5168 ; WX 774 ; N uni1430 ; G 1545 +U 5169 ; WX 774 ; N uni1431 ; G 1546 +U 5170 ; WX 774 ; N uni1432 ; G 1547 +U 5171 ; WX 886 ; N uni1433 ; G 1548 +U 5172 ; WX 886 ; N uni1434 ; G 1549 +U 5173 ; WX 886 ; N uni1435 ; G 1550 +U 5175 ; WX 886 ; N uni1437 ; G 1551 +U 5176 ; WX 886 ; N uni1438 ; G 1552 +U 5177 ; WX 886 ; N uni1439 ; G 1553 +U 5178 ; WX 1018 ; N uni143A ; G 1554 +U 5179 ; WX 1009 ; N uni143B ; G 1555 +U 5180 ; WX 1018 ; N uni143C ; G 1556 +U 5181 ; WX 1009 ; N uni143D ; G 1557 +U 5182 ; WX 1018 ; N uni143E ; G 1558 +U 5183 ; WX 1009 ; N uni143F ; G 1559 +U 5184 ; WX 1149 ; N uni1440 ; G 1560 +U 5185 ; WX 1140 ; N uni1441 ; G 1561 +U 5186 ; WX 1149 ; N uni1442 ; G 1562 +U 5187 ; WX 1140 ; N uni1443 ; G 1563 +U 5188 ; WX 1149 ; N uni1444 ; G 1564 +U 5189 ; WX 1142 ; N uni1445 ; G 1565 +U 5190 ; WX 1149 ; N uni1446 ; G 1566 +U 5191 ; WX 1142 ; N uni1447 ; G 1567 +U 5192 ; WX 886 ; N uni1448 ; G 1568 +U 5193 ; WX 576 ; N uni1449 ; G 1569 +U 5194 ; WX 229 ; N uni144A ; G 1570 +U 5196 ; WX 812 ; N uni144C ; G 1571 +U 5197 ; WX 812 ; N uni144D ; G 1572 +U 5198 ; WX 812 ; N uni144E ; G 1573 +U 5199 ; WX 812 ; N uni144F ; G 1574 +U 5200 ; WX 815 ; N uni1450 ; G 1575 +U 5201 ; WX 815 ; N uni1451 ; G 1576 +U 5202 ; WX 815 ; N uni1452 ; G 1577 +U 5204 ; WX 815 ; N uni1454 ; G 1578 +U 5205 ; WX 815 ; N uni1455 ; G 1579 +U 5206 ; WX 815 ; N uni1456 ; G 1580 +U 5207 ; WX 1056 ; N uni1457 ; G 1581 +U 5208 ; WX 1048 ; N uni1458 ; G 1582 +U 5209 ; WX 1056 ; N uni1459 ; G 1583 +U 5210 ; WX 1048 ; N uni145A ; G 1584 +U 5211 ; WX 1056 ; N uni145B ; G 1585 +U 5212 ; WX 1048 ; N uni145C ; G 1586 +U 5213 ; WX 1060 ; N uni145D ; G 1587 +U 5214 ; WX 1054 ; N uni145E ; G 1588 +U 5215 ; WX 1060 ; N uni145F ; G 1589 +U 5216 ; WX 1054 ; N uni1460 ; G 1590 +U 5217 ; WX 1060 ; N uni1461 ; G 1591 +U 5218 ; WX 1052 ; N uni1462 ; G 1592 +U 5219 ; WX 1060 ; N uni1463 ; G 1593 +U 5220 ; WX 1052 ; N uni1464 ; G 1594 +U 5221 ; WX 1060 ; N uni1465 ; G 1595 +U 5222 ; WX 483 ; N uni1466 ; G 1596 +U 5223 ; WX 1005 ; N uni1467 ; G 1597 +U 5224 ; WX 1005 ; N uni1468 ; G 1598 +U 5225 ; WX 1023 ; N uni1469 ; G 1599 +U 5226 ; WX 1017 ; N uni146A ; G 1600 +U 5227 ; WX 743 ; N uni146B ; G 1601 +U 5228 ; WX 743 ; N uni146C ; G 1602 +U 5229 ; WX 743 ; N uni146D ; G 1603 +U 5230 ; WX 743 ; N uni146E ; G 1604 +U 5231 ; WX 743 ; N uni146F ; G 1605 +U 5232 ; WX 743 ; N uni1470 ; G 1606 +U 5233 ; WX 743 ; N uni1471 ; G 1607 +U 5234 ; WX 743 ; N uni1472 ; G 1608 +U 5235 ; WX 743 ; N uni1473 ; G 1609 +U 5236 ; WX 1029 ; N uni1474 ; G 1610 +U 5237 ; WX 975 ; N uni1475 ; G 1611 +U 5238 ; WX 980 ; N uni1476 ; G 1612 +U 5239 ; WX 975 ; N uni1477 ; G 1613 +U 5240 ; WX 980 ; N uni1478 ; G 1614 +U 5241 ; WX 975 ; N uni1479 ; G 1615 +U 5242 ; WX 1029 ; N uni147A ; G 1616 +U 5243 ; WX 975 ; N uni147B ; G 1617 +U 5244 ; WX 1029 ; N uni147C ; G 1618 +U 5245 ; WX 975 ; N uni147D ; G 1619 +U 5246 ; WX 980 ; N uni147E ; G 1620 +U 5247 ; WX 975 ; N uni147F ; G 1621 +U 5248 ; WX 980 ; N uni1480 ; G 1622 +U 5249 ; WX 975 ; N uni1481 ; G 1623 +U 5250 ; WX 980 ; N uni1482 ; G 1624 +U 5251 ; WX 501 ; N uni1483 ; G 1625 +U 5252 ; WX 501 ; N uni1484 ; G 1626 +U 5253 ; WX 938 ; N uni1485 ; G 1627 +U 5254 ; WX 938 ; N uni1486 ; G 1628 +U 5255 ; WX 938 ; N uni1487 ; G 1629 +U 5256 ; WX 938 ; N uni1488 ; G 1630 +U 5257 ; WX 743 ; N uni1489 ; G 1631 +U 5258 ; WX 743 ; N uni148A ; G 1632 +U 5259 ; WX 743 ; N uni148B ; G 1633 +U 5260 ; WX 743 ; N uni148C ; G 1634 +U 5261 ; WX 743 ; N uni148D ; G 1635 +U 5262 ; WX 743 ; N uni148E ; G 1636 +U 5263 ; WX 743 ; N uni148F ; G 1637 +U 5264 ; WX 743 ; N uni1490 ; G 1638 +U 5265 ; WX 743 ; N uni1491 ; G 1639 +U 5266 ; WX 1029 ; N uni1492 ; G 1640 +U 5267 ; WX 975 ; N uni1493 ; G 1641 +U 5268 ; WX 1029 ; N uni1494 ; G 1642 +U 5269 ; WX 975 ; N uni1495 ; G 1643 +U 5270 ; WX 1029 ; N uni1496 ; G 1644 +U 5271 ; WX 975 ; N uni1497 ; G 1645 +U 5272 ; WX 1029 ; N uni1498 ; G 1646 +U 5273 ; WX 975 ; N uni1499 ; G 1647 +U 5274 ; WX 1029 ; N uni149A ; G 1648 +U 5275 ; WX 975 ; N uni149B ; G 1649 +U 5276 ; WX 1029 ; N uni149C ; G 1650 +U 5277 ; WX 975 ; N uni149D ; G 1651 +U 5278 ; WX 1029 ; N uni149E ; G 1652 +U 5279 ; WX 975 ; N uni149F ; G 1653 +U 5280 ; WX 1029 ; N uni14A0 ; G 1654 +U 5281 ; WX 501 ; N uni14A1 ; G 1655 +U 5282 ; WX 501 ; N uni14A2 ; G 1656 +U 5283 ; WX 626 ; N uni14A3 ; G 1657 +U 5284 ; WX 626 ; N uni14A4 ; G 1658 +U 5285 ; WX 626 ; N uni14A5 ; G 1659 +U 5286 ; WX 626 ; N uni14A6 ; G 1660 +U 5287 ; WX 626 ; N uni14A7 ; G 1661 +U 5288 ; WX 626 ; N uni14A8 ; G 1662 +U 5289 ; WX 626 ; N uni14A9 ; G 1663 +U 5290 ; WX 626 ; N uni14AA ; G 1664 +U 5291 ; WX 626 ; N uni14AB ; G 1665 +U 5292 ; WX 881 ; N uni14AC ; G 1666 +U 5293 ; WX 854 ; N uni14AD ; G 1667 +U 5294 ; WX 863 ; N uni14AE ; G 1668 +U 5295 ; WX 874 ; N uni14AF ; G 1669 +U 5296 ; WX 863 ; N uni14B0 ; G 1670 +U 5297 ; WX 874 ; N uni14B1 ; G 1671 +U 5298 ; WX 881 ; N uni14B2 ; G 1672 +U 5299 ; WX 874 ; N uni14B3 ; G 1673 +U 5300 ; WX 881 ; N uni14B4 ; G 1674 +U 5301 ; WX 874 ; N uni14B5 ; G 1675 +U 5302 ; WX 863 ; N uni14B6 ; G 1676 +U 5303 ; WX 874 ; N uni14B7 ; G 1677 +U 5304 ; WX 863 ; N uni14B8 ; G 1678 +U 5305 ; WX 874 ; N uni14B9 ; G 1679 +U 5306 ; WX 863 ; N uni14BA ; G 1680 +U 5307 ; WX 436 ; N uni14BB ; G 1681 +U 5308 ; WX 548 ; N uni14BC ; G 1682 +U 5309 ; WX 436 ; N uni14BD ; G 1683 +U 5312 ; WX 988 ; N uni14C0 ; G 1684 +U 5313 ; WX 988 ; N uni14C1 ; G 1685 +U 5314 ; WX 988 ; N uni14C2 ; G 1686 +U 5315 ; WX 988 ; N uni14C3 ; G 1687 +U 5316 ; WX 931 ; N uni14C4 ; G 1688 +U 5317 ; WX 931 ; N uni14C5 ; G 1689 +U 5318 ; WX 931 ; N uni14C6 ; G 1690 +U 5319 ; WX 931 ; N uni14C7 ; G 1691 +U 5320 ; WX 931 ; N uni14C8 ; G 1692 +U 5321 ; WX 1238 ; N uni14C9 ; G 1693 +U 5322 ; WX 1247 ; N uni14CA ; G 1694 +U 5323 ; WX 1200 ; N uni14CB ; G 1695 +U 5324 ; WX 1228 ; N uni14CC ; G 1696 +U 5325 ; WX 1200 ; N uni14CD ; G 1697 +U 5326 ; WX 1228 ; N uni14CE ; G 1698 +U 5327 ; WX 931 ; N uni14CF ; G 1699 +U 5328 ; WX 660 ; N uni14D0 ; G 1700 +U 5329 ; WX 497 ; N uni14D1 ; G 1701 +U 5330 ; WX 660 ; N uni14D2 ; G 1702 +U 5331 ; WX 988 ; N uni14D3 ; G 1703 +U 5332 ; WX 988 ; N uni14D4 ; G 1704 +U 5333 ; WX 988 ; N uni14D5 ; G 1705 +U 5334 ; WX 988 ; N uni14D6 ; G 1706 +U 5335 ; WX 931 ; N uni14D7 ; G 1707 +U 5336 ; WX 931 ; N uni14D8 ; G 1708 +U 5337 ; WX 931 ; N uni14D9 ; G 1709 +U 5338 ; WX 931 ; N uni14DA ; G 1710 +U 5339 ; WX 931 ; N uni14DB ; G 1711 +U 5340 ; WX 1231 ; N uni14DC ; G 1712 +U 5341 ; WX 1247 ; N uni14DD ; G 1713 +U 5342 ; WX 1283 ; N uni14DE ; G 1714 +U 5343 ; WX 1228 ; N uni14DF ; G 1715 +U 5344 ; WX 1283 ; N uni14E0 ; G 1716 +U 5345 ; WX 1228 ; N uni14E1 ; G 1717 +U 5346 ; WX 1228 ; N uni14E2 ; G 1718 +U 5347 ; WX 1214 ; N uni14E3 ; G 1719 +U 5348 ; WX 1228 ; N uni14E4 ; G 1720 +U 5349 ; WX 1214 ; N uni14E5 ; G 1721 +U 5350 ; WX 1283 ; N uni14E6 ; G 1722 +U 5351 ; WX 1228 ; N uni14E7 ; G 1723 +U 5352 ; WX 1283 ; N uni14E8 ; G 1724 +U 5353 ; WX 1228 ; N uni14E9 ; G 1725 +U 5354 ; WX 660 ; N uni14EA ; G 1726 +U 5356 ; WX 886 ; N uni14EC ; G 1727 +U 5357 ; WX 730 ; N uni14ED ; G 1728 +U 5358 ; WX 730 ; N uni14EE ; G 1729 +U 5359 ; WX 730 ; N uni14EF ; G 1730 +U 5360 ; WX 730 ; N uni14F0 ; G 1731 +U 5361 ; WX 730 ; N uni14F1 ; G 1732 +U 5362 ; WX 730 ; N uni14F2 ; G 1733 +U 5363 ; WX 730 ; N uni14F3 ; G 1734 +U 5364 ; WX 730 ; N uni14F4 ; G 1735 +U 5365 ; WX 730 ; N uni14F5 ; G 1736 +U 5366 ; WX 998 ; N uni14F6 ; G 1737 +U 5367 ; WX 958 ; N uni14F7 ; G 1738 +U 5368 ; WX 967 ; N uni14F8 ; G 1739 +U 5369 ; WX 989 ; N uni14F9 ; G 1740 +U 5370 ; WX 967 ; N uni14FA ; G 1741 +U 5371 ; WX 989 ; N uni14FB ; G 1742 +U 5372 ; WX 998 ; N uni14FC ; G 1743 +U 5373 ; WX 958 ; N uni14FD ; G 1744 +U 5374 ; WX 998 ; N uni14FE ; G 1745 +U 5375 ; WX 958 ; N uni14FF ; G 1746 +U 5376 ; WX 967 ; N uni1500 ; G 1747 +U 5377 ; WX 989 ; N uni1501 ; G 1748 +U 5378 ; WX 967 ; N uni1502 ; G 1749 +U 5379 ; WX 989 ; N uni1503 ; G 1750 +U 5380 ; WX 967 ; N uni1504 ; G 1751 +U 5381 ; WX 493 ; N uni1505 ; G 1752 +U 5382 ; WX 460 ; N uni1506 ; G 1753 +U 5383 ; WX 493 ; N uni1507 ; G 1754 +U 5392 ; WX 923 ; N uni1510 ; G 1755 +U 5393 ; WX 923 ; N uni1511 ; G 1756 +U 5394 ; WX 923 ; N uni1512 ; G 1757 +U 5395 ; WX 1136 ; N uni1513 ; G 1758 +U 5396 ; WX 1136 ; N uni1514 ; G 1759 +U 5397 ; WX 1136 ; N uni1515 ; G 1760 +U 5398 ; WX 1136 ; N uni1516 ; G 1761 +U 5399 ; WX 1209 ; N uni1517 ; G 1762 +U 5400 ; WX 1202 ; N uni1518 ; G 1763 +U 5401 ; WX 1209 ; N uni1519 ; G 1764 +U 5402 ; WX 1202 ; N uni151A ; G 1765 +U 5403 ; WX 1209 ; N uni151B ; G 1766 +U 5404 ; WX 1202 ; N uni151C ; G 1767 +U 5405 ; WX 1431 ; N uni151D ; G 1768 +U 5406 ; WX 1420 ; N uni151E ; G 1769 +U 5407 ; WX 1431 ; N uni151F ; G 1770 +U 5408 ; WX 1420 ; N uni1520 ; G 1771 +U 5409 ; WX 1431 ; N uni1521 ; G 1772 +U 5410 ; WX 1420 ; N uni1522 ; G 1773 +U 5411 ; WX 1431 ; N uni1523 ; G 1774 +U 5412 ; WX 1420 ; N uni1524 ; G 1775 +U 5413 ; WX 746 ; N uni1525 ; G 1776 +U 5414 ; WX 776 ; N uni1526 ; G 1777 +U 5415 ; WX 776 ; N uni1527 ; G 1778 +U 5416 ; WX 776 ; N uni1528 ; G 1779 +U 5417 ; WX 776 ; N uni1529 ; G 1780 +U 5418 ; WX 776 ; N uni152A ; G 1781 +U 5419 ; WX 776 ; N uni152B ; G 1782 +U 5420 ; WX 776 ; N uni152C ; G 1783 +U 5421 ; WX 776 ; N uni152D ; G 1784 +U 5422 ; WX 776 ; N uni152E ; G 1785 +U 5423 ; WX 1003 ; N uni152F ; G 1786 +U 5424 ; WX 1003 ; N uni1530 ; G 1787 +U 5425 ; WX 1013 ; N uni1531 ; G 1788 +U 5426 ; WX 996 ; N uni1532 ; G 1789 +U 5427 ; WX 1013 ; N uni1533 ; G 1790 +U 5428 ; WX 996 ; N uni1534 ; G 1791 +U 5429 ; WX 1003 ; N uni1535 ; G 1792 +U 5430 ; WX 1003 ; N uni1536 ; G 1793 +U 5431 ; WX 1003 ; N uni1537 ; G 1794 +U 5432 ; WX 1003 ; N uni1538 ; G 1795 +U 5433 ; WX 1013 ; N uni1539 ; G 1796 +U 5434 ; WX 996 ; N uni153A ; G 1797 +U 5435 ; WX 1013 ; N uni153B ; G 1798 +U 5436 ; WX 996 ; N uni153C ; G 1799 +U 5437 ; WX 1013 ; N uni153D ; G 1800 +U 5438 ; WX 495 ; N uni153E ; G 1801 +U 5440 ; WX 395 ; N uni1540 ; G 1802 +U 5441 ; WX 510 ; N uni1541 ; G 1803 +U 5442 ; WX 1033 ; N uni1542 ; G 1804 +U 5443 ; WX 1033 ; N uni1543 ; G 1805 +U 5444 ; WX 976 ; N uni1544 ; G 1806 +U 5445 ; WX 976 ; N uni1545 ; G 1807 +U 5446 ; WX 976 ; N uni1546 ; G 1808 +U 5447 ; WX 976 ; N uni1547 ; G 1809 +U 5448 ; WX 733 ; N uni1548 ; G 1810 +U 5449 ; WX 733 ; N uni1549 ; G 1811 +U 5450 ; WX 733 ; N uni154A ; G 1812 +U 5451 ; WX 733 ; N uni154B ; G 1813 +U 5452 ; WX 733 ; N uni154C ; G 1814 +U 5453 ; WX 733 ; N uni154D ; G 1815 +U 5454 ; WX 1003 ; N uni154E ; G 1816 +U 5455 ; WX 959 ; N uni154F ; G 1817 +U 5456 ; WX 495 ; N uni1550 ; G 1818 +U 5458 ; WX 886 ; N uni1552 ; G 1819 +U 5459 ; WX 774 ; N uni1553 ; G 1820 +U 5460 ; WX 774 ; N uni1554 ; G 1821 +U 5461 ; WX 774 ; N uni1555 ; G 1822 +U 5462 ; WX 774 ; N uni1556 ; G 1823 +U 5463 ; WX 928 ; N uni1557 ; G 1824 +U 5464 ; WX 928 ; N uni1558 ; G 1825 +U 5465 ; WX 928 ; N uni1559 ; G 1826 +U 5466 ; WX 928 ; N uni155A ; G 1827 +U 5467 ; WX 1172 ; N uni155B ; G 1828 +U 5468 ; WX 1142 ; N uni155C ; G 1829 +U 5469 ; WX 602 ; N uni155D ; G 1830 +U 5470 ; WX 812 ; N uni155E ; G 1831 +U 5471 ; WX 812 ; N uni155F ; G 1832 +U 5472 ; WX 812 ; N uni1560 ; G 1833 +U 5473 ; WX 812 ; N uni1561 ; G 1834 +U 5474 ; WX 812 ; N uni1562 ; G 1835 +U 5475 ; WX 812 ; N uni1563 ; G 1836 +U 5476 ; WX 815 ; N uni1564 ; G 1837 +U 5477 ; WX 815 ; N uni1565 ; G 1838 +U 5478 ; WX 815 ; N uni1566 ; G 1839 +U 5479 ; WX 815 ; N uni1567 ; G 1840 +U 5480 ; WX 1060 ; N uni1568 ; G 1841 +U 5481 ; WX 1052 ; N uni1569 ; G 1842 +U 5482 ; WX 548 ; N uni156A ; G 1843 +U 5492 ; WX 977 ; N uni1574 ; G 1844 +U 5493 ; WX 977 ; N uni1575 ; G 1845 +U 5494 ; WX 977 ; N uni1576 ; G 1846 +U 5495 ; WX 977 ; N uni1577 ; G 1847 +U 5496 ; WX 977 ; N uni1578 ; G 1848 +U 5497 ; WX 977 ; N uni1579 ; G 1849 +U 5498 ; WX 977 ; N uni157A ; G 1850 +U 5499 ; WX 618 ; N uni157B ; G 1851 +U 5500 ; WX 837 ; N uni157C ; G 1852 +U 5501 ; WX 510 ; N uni157D ; G 1853 +U 5502 ; WX 1238 ; N uni157E ; G 1854 +U 5503 ; WX 1238 ; N uni157F ; G 1855 +U 5504 ; WX 1238 ; N uni1580 ; G 1856 +U 5505 ; WX 1238 ; N uni1581 ; G 1857 +U 5506 ; WX 1238 ; N uni1582 ; G 1858 +U 5507 ; WX 1238 ; N uni1583 ; G 1859 +U 5508 ; WX 1238 ; N uni1584 ; G 1860 +U 5509 ; WX 989 ; N uni1585 ; G 1861 +U 5514 ; WX 977 ; N uni158A ; G 1862 +U 5515 ; WX 977 ; N uni158B ; G 1863 +U 5516 ; WX 977 ; N uni158C ; G 1864 +U 5517 ; WX 977 ; N uni158D ; G 1865 +U 5518 ; WX 1591 ; N uni158E ; G 1866 +U 5519 ; WX 1591 ; N uni158F ; G 1867 +U 5520 ; WX 1591 ; N uni1590 ; G 1868 +U 5521 ; WX 1295 ; N uni1591 ; G 1869 +U 5522 ; WX 1295 ; N uni1592 ; G 1870 +U 5523 ; WX 1591 ; N uni1593 ; G 1871 +U 5524 ; WX 1591 ; N uni1594 ; G 1872 +U 5525 ; WX 848 ; N uni1595 ; G 1873 +U 5526 ; WX 1273 ; N uni1596 ; G 1874 +U 5536 ; WX 988 ; N uni15A0 ; G 1875 +U 5537 ; WX 988 ; N uni15A1 ; G 1876 +U 5538 ; WX 931 ; N uni15A2 ; G 1877 +U 5539 ; WX 931 ; N uni15A3 ; G 1878 +U 5540 ; WX 931 ; N uni15A4 ; G 1879 +U 5541 ; WX 931 ; N uni15A5 ; G 1880 +U 5542 ; WX 660 ; N uni15A6 ; G 1881 +U 5543 ; WX 776 ; N uni15A7 ; G 1882 +U 5544 ; WX 776 ; N uni15A8 ; G 1883 +U 5545 ; WX 776 ; N uni15A9 ; G 1884 +U 5546 ; WX 776 ; N uni15AA ; G 1885 +U 5547 ; WX 776 ; N uni15AB ; G 1886 +U 5548 ; WX 776 ; N uni15AC ; G 1887 +U 5549 ; WX 776 ; N uni15AD ; G 1888 +U 5550 ; WX 495 ; N uni15AE ; G 1889 +U 5551 ; WX 743 ; N uni15AF ; G 1890 +U 5598 ; WX 830 ; N uni15DE ; G 1891 +U 5601 ; WX 830 ; N uni15E1 ; G 1892 +U 5702 ; WX 496 ; N uni1646 ; G 1893 +U 5703 ; WX 496 ; N uni1647 ; G 1894 +U 5742 ; WX 413 ; N uni166E ; G 1895 +U 5743 ; WX 1238 ; N uni166F ; G 1896 +U 5744 ; WX 1591 ; N uni1670 ; G 1897 +U 5745 ; WX 2016 ; N uni1671 ; G 1898 +U 5746 ; WX 2016 ; N uni1672 ; G 1899 +U 5747 ; WX 1720 ; N uni1673 ; G 1900 +U 5748 ; WX 1678 ; N uni1674 ; G 1901 +U 5749 ; WX 2016 ; N uni1675 ; G 1902 +U 5750 ; WX 2016 ; N uni1676 ; G 1903 +U 7424 ; WX 652 ; N uni1D00 ; G 1904 +U 7425 ; WX 833 ; N uni1D01 ; G 1905 +U 7426 ; WX 1048 ; N uni1D02 ; G 1906 +U 7427 ; WX 608 ; N uni1D03 ; G 1907 +U 7428 ; WX 593 ; N uni1D04 ; G 1908 +U 7429 ; WX 676 ; N uni1D05 ; G 1909 +U 7430 ; WX 676 ; N uni1D06 ; G 1910 +U 7431 ; WX 559 ; N uni1D07 ; G 1911 +U 7432 ; WX 557 ; N uni1D08 ; G 1912 +U 7433 ; WX 343 ; N uni1D09 ; G 1913 +U 7434 ; WX 494 ; N uni1D0A ; G 1914 +U 7435 ; WX 665 ; N uni1D0B ; G 1915 +U 7436 ; WX 539 ; N uni1D0C ; G 1916 +U 7437 ; WX 817 ; N uni1D0D ; G 1917 +U 7438 ; WX 701 ; N uni1D0E ; G 1918 +U 7439 ; WX 687 ; N uni1D0F ; G 1919 +U 7440 ; WX 593 ; N uni1D10 ; G 1920 +U 7441 ; WX 660 ; N uni1D11 ; G 1921 +U 7442 ; WX 660 ; N uni1D12 ; G 1922 +U 7443 ; WX 660 ; N uni1D13 ; G 1923 +U 7444 ; WX 1094 ; N uni1D14 ; G 1924 +U 7446 ; WX 687 ; N uni1D16 ; G 1925 +U 7447 ; WX 687 ; N uni1D17 ; G 1926 +U 7448 ; WX 556 ; N uni1D18 ; G 1927 +U 7449 ; WX 642 ; N uni1D19 ; G 1928 +U 7450 ; WX 642 ; N uni1D1A ; G 1929 +U 7451 ; WX 580 ; N uni1D1B ; G 1930 +U 7452 ; WX 634 ; N uni1D1C ; G 1931 +U 7453 ; WX 737 ; N uni1D1D ; G 1932 +U 7454 ; WX 948 ; N uni1D1E ; G 1933 +U 7455 ; WX 695 ; N uni1D1F ; G 1934 +U 7456 ; WX 652 ; N uni1D20 ; G 1935 +U 7457 ; WX 924 ; N uni1D21 ; G 1936 +U 7458 ; WX 582 ; N uni1D22 ; G 1937 +U 7459 ; WX 646 ; N uni1D23 ; G 1938 +U 7462 ; WX 539 ; N uni1D26 ; G 1939 +U 7463 ; WX 652 ; N uni1D27 ; G 1940 +U 7464 ; WX 691 ; N uni1D28 ; G 1941 +U 7465 ; WX 556 ; N uni1D29 ; G 1942 +U 7466 ; WX 781 ; N uni1D2A ; G 1943 +U 7467 ; WX 732 ; N uni1D2B ; G 1944 +U 7468 ; WX 487 ; N uni1D2C ; G 1945 +U 7469 ; WX 683 ; N uni1D2D ; G 1946 +U 7470 ; WX 480 ; N uni1D2E ; G 1947 +U 7472 ; WX 523 ; N uni1D30 ; G 1948 +U 7473 ; WX 430 ; N uni1D31 ; G 1949 +U 7474 ; WX 430 ; N uni1D32 ; G 1950 +U 7475 ; WX 517 ; N uni1D33 ; G 1951 +U 7476 ; WX 527 ; N uni1D34 ; G 1952 +U 7477 ; WX 234 ; N uni1D35 ; G 1953 +U 7478 ; WX 234 ; N uni1D36 ; G 1954 +U 7479 ; WX 488 ; N uni1D37 ; G 1955 +U 7480 ; WX 401 ; N uni1D38 ; G 1956 +U 7481 ; WX 626 ; N uni1D39 ; G 1957 +U 7482 ; WX 527 ; N uni1D3A ; G 1958 +U 7483 ; WX 527 ; N uni1D3B ; G 1959 +U 7484 ; WX 535 ; N uni1D3C ; G 1960 +U 7485 ; WX 509 ; N uni1D3D ; G 1961 +U 7486 ; WX 461 ; N uni1D3E ; G 1962 +U 7487 ; WX 485 ; N uni1D3F ; G 1963 +U 7488 ; WX 430 ; N uni1D40 ; G 1964 +U 7489 ; WX 511 ; N uni1D41 ; G 1965 +U 7490 ; WX 695 ; N uni1D42 ; G 1966 +U 7491 ; WX 458 ; N uni1D43 ; G 1967 +U 7492 ; WX 458 ; N uni1D44 ; G 1968 +U 7493 ; WX 479 ; N uni1D45 ; G 1969 +U 7494 ; WX 712 ; N uni1D46 ; G 1970 +U 7495 ; WX 479 ; N uni1D47 ; G 1971 +U 7496 ; WX 479 ; N uni1D48 ; G 1972 +U 7497 ; WX 479 ; N uni1D49 ; G 1973 +U 7498 ; WX 479 ; N uni1D4A ; G 1974 +U 7499 ; WX 386 ; N uni1D4B ; G 1975 +U 7500 ; WX 386 ; N uni1D4C ; G 1976 +U 7501 ; WX 479 ; N uni1D4D ; G 1977 +U 7502 ; WX 219 ; N uni1D4E ; G 1978 +U 7503 ; WX 487 ; N uni1D4F ; G 1979 +U 7504 ; WX 664 ; N uni1D50 ; G 1980 +U 7505 ; WX 456 ; N uni1D51 ; G 1981 +U 7506 ; WX 488 ; N uni1D52 ; G 1982 +U 7507 ; WX 414 ; N uni1D53 ; G 1983 +U 7508 ; WX 488 ; N uni1D54 ; G 1984 +U 7509 ; WX 488 ; N uni1D55 ; G 1985 +U 7510 ; WX 479 ; N uni1D56 ; G 1986 +U 7511 ; WX 388 ; N uni1D57 ; G 1987 +U 7512 ; WX 456 ; N uni1D58 ; G 1988 +U 7513 ; WX 462 ; N uni1D59 ; G 1989 +U 7514 ; WX 664 ; N uni1D5A ; G 1990 +U 7515 ; WX 501 ; N uni1D5B ; G 1991 +U 7517 ; WX 451 ; N uni1D5D ; G 1992 +U 7518 ; WX 429 ; N uni1D5E ; G 1993 +U 7519 ; WX 433 ; N uni1D5F ; G 1994 +U 7520 ; WX 493 ; N uni1D60 ; G 1995 +U 7521 ; WX 406 ; N uni1D61 ; G 1996 +U 7522 ; WX 219 ; N uni1D62 ; G 1997 +U 7523 ; WX 315 ; N uni1D63 ; G 1998 +U 7524 ; WX 456 ; N uni1D64 ; G 1999 +U 7525 ; WX 501 ; N uni1D65 ; G 2000 +U 7526 ; WX 451 ; N uni1D66 ; G 2001 +U 7527 ; WX 429 ; N uni1D67 ; G 2002 +U 7528 ; WX 451 ; N uni1D68 ; G 2003 +U 7529 ; WX 493 ; N uni1D69 ; G 2004 +U 7530 ; WX 406 ; N uni1D6A ; G 2005 +U 7543 ; WX 716 ; N uni1D77 ; G 2006 +U 7544 ; WX 527 ; N uni1D78 ; G 2007 +U 7547 ; WX 545 ; N uni1D7B ; G 2008 +U 7549 ; WX 747 ; N uni1D7D ; G 2009 +U 7557 ; WX 514 ; N uni1D85 ; G 2010 +U 7579 ; WX 479 ; N uni1D9B ; G 2011 +U 7580 ; WX 414 ; N uni1D9C ; G 2012 +U 7581 ; WX 414 ; N uni1D9D ; G 2013 +U 7582 ; WX 488 ; N uni1D9E ; G 2014 +U 7583 ; WX 386 ; N uni1D9F ; G 2015 +U 7584 ; WX 377 ; N uni1DA0 ; G 2016 +U 7585 ; WX 348 ; N uni1DA1 ; G 2017 +U 7586 ; WX 479 ; N uni1DA2 ; G 2018 +U 7587 ; WX 456 ; N uni1DA3 ; G 2019 +U 7588 ; WX 347 ; N uni1DA4 ; G 2020 +U 7589 ; WX 281 ; N uni1DA5 ; G 2021 +U 7590 ; WX 347 ; N uni1DA6 ; G 2022 +U 7591 ; WX 347 ; N uni1DA7 ; G 2023 +U 7592 ; WX 431 ; N uni1DA8 ; G 2024 +U 7593 ; WX 326 ; N uni1DA9 ; G 2025 +U 7594 ; WX 330 ; N uni1DAA ; G 2026 +U 7595 ; WX 370 ; N uni1DAB ; G 2027 +U 7596 ; WX 664 ; N uni1DAC ; G 2028 +U 7597 ; WX 664 ; N uni1DAD ; G 2029 +U 7598 ; WX 562 ; N uni1DAE ; G 2030 +U 7599 ; WX 562 ; N uni1DAF ; G 2031 +U 7600 ; WX 448 ; N uni1DB0 ; G 2032 +U 7601 ; WX 488 ; N uni1DB1 ; G 2033 +U 7602 ; WX 542 ; N uni1DB2 ; G 2034 +U 7603 ; WX 422 ; N uni1DB3 ; G 2035 +U 7604 ; WX 396 ; N uni1DB4 ; G 2036 +U 7605 ; WX 388 ; N uni1DB5 ; G 2037 +U 7606 ; WX 583 ; N uni1DB6 ; G 2038 +U 7607 ; WX 494 ; N uni1DB7 ; G 2039 +U 7608 ; WX 399 ; N uni1DB8 ; G 2040 +U 7609 ; WX 451 ; N uni1DB9 ; G 2041 +U 7610 ; WX 501 ; N uni1DBA ; G 2042 +U 7611 ; WX 417 ; N uni1DBB ; G 2043 +U 7612 ; WX 523 ; N uni1DBC ; G 2044 +U 7613 ; WX 470 ; N uni1DBD ; G 2045 +U 7614 ; WX 455 ; N uni1DBE ; G 2046 +U 7615 ; WX 425 ; N uni1DBF ; G 2047 +U 7620 ; WX 0 ; N uni1DC4 ; G 2048 +U 7621 ; WX 0 ; N uni1DC5 ; G 2049 +U 7622 ; WX 0 ; N uni1DC6 ; G 2050 +U 7623 ; WX 0 ; N uni1DC7 ; G 2051 +U 7624 ; WX 0 ; N uni1DC8 ; G 2052 +U 7625 ; WX 0 ; N uni1DC9 ; G 2053 +U 7680 ; WX 774 ; N uni1E00 ; G 2054 +U 7681 ; WX 675 ; N uni1E01 ; G 2055 +U 7682 ; WX 762 ; N uni1E02 ; G 2056 +U 7683 ; WX 716 ; N uni1E03 ; G 2057 +U 7684 ; WX 762 ; N uni1E04 ; G 2058 +U 7685 ; WX 716 ; N uni1E05 ; G 2059 +U 7686 ; WX 762 ; N uni1E06 ; G 2060 +U 7687 ; WX 716 ; N uni1E07 ; G 2061 +U 7688 ; WX 734 ; N uni1E08 ; G 2062 +U 7689 ; WX 593 ; N uni1E09 ; G 2063 +U 7690 ; WX 830 ; N uni1E0A ; G 2064 +U 7691 ; WX 716 ; N uni1E0B ; G 2065 +U 7692 ; WX 830 ; N uni1E0C ; G 2066 +U 7693 ; WX 716 ; N uni1E0D ; G 2067 +U 7694 ; WX 830 ; N uni1E0E ; G 2068 +U 7695 ; WX 716 ; N uni1E0F ; G 2069 +U 7696 ; WX 830 ; N uni1E10 ; G 2070 +U 7697 ; WX 716 ; N uni1E11 ; G 2071 +U 7698 ; WX 830 ; N uni1E12 ; G 2072 +U 7699 ; WX 716 ; N uni1E13 ; G 2073 +U 7700 ; WX 683 ; N uni1E14 ; G 2074 +U 7701 ; WX 678 ; N uni1E15 ; G 2075 +U 7702 ; WX 683 ; N uni1E16 ; G 2076 +U 7703 ; WX 678 ; N uni1E17 ; G 2077 +U 7704 ; WX 683 ; N uni1E18 ; G 2078 +U 7705 ; WX 678 ; N uni1E19 ; G 2079 +U 7706 ; WX 683 ; N uni1E1A ; G 2080 +U 7707 ; WX 678 ; N uni1E1B ; G 2081 +U 7708 ; WX 683 ; N uni1E1C ; G 2082 +U 7709 ; WX 678 ; N uni1E1D ; G 2083 +U 7710 ; WX 683 ; N uni1E1E ; G 2084 +U 7711 ; WX 435 ; N uni1E1F ; G 2085 +U 7712 ; WX 821 ; N uni1E20 ; G 2086 +U 7713 ; WX 716 ; N uni1E21 ; G 2087 +U 7714 ; WX 837 ; N uni1E22 ; G 2088 +U 7715 ; WX 712 ; N uni1E23 ; G 2089 +U 7716 ; WX 837 ; N uni1E24 ; G 2090 +U 7717 ; WX 712 ; N uni1E25 ; G 2091 +U 7718 ; WX 837 ; N uni1E26 ; G 2092 +U 7719 ; WX 712 ; N uni1E27 ; G 2093 +U 7720 ; WX 837 ; N uni1E28 ; G 2094 +U 7721 ; WX 712 ; N uni1E29 ; G 2095 +U 7722 ; WX 837 ; N uni1E2A ; G 2096 +U 7723 ; WX 712 ; N uni1E2B ; G 2097 +U 7724 ; WX 372 ; N uni1E2C ; G 2098 +U 7725 ; WX 343 ; N uni1E2D ; G 2099 +U 7726 ; WX 372 ; N uni1E2E ; G 2100 +U 7727 ; WX 343 ; N uni1E2F ; G 2101 +U 7728 ; WX 775 ; N uni1E30 ; G 2102 +U 7729 ; WX 665 ; N uni1E31 ; G 2103 +U 7730 ; WX 775 ; N uni1E32 ; G 2104 +U 7731 ; WX 665 ; N uni1E33 ; G 2105 +U 7732 ; WX 775 ; N uni1E34 ; G 2106 +U 7733 ; WX 665 ; N uni1E35 ; G 2107 +U 7734 ; WX 637 ; N uni1E36 ; G 2108 +U 7735 ; WX 343 ; N uni1E37 ; G 2109 +U 7736 ; WX 637 ; N uni1E38 ; G 2110 +U 7737 ; WX 343 ; N uni1E39 ; G 2111 +U 7738 ; WX 637 ; N uni1E3A ; G 2112 +U 7739 ; WX 343 ; N uni1E3B ; G 2113 +U 7740 ; WX 637 ; N uni1E3C ; G 2114 +U 7741 ; WX 343 ; N uni1E3D ; G 2115 +U 7742 ; WX 995 ; N uni1E3E ; G 2116 +U 7743 ; WX 1042 ; N uni1E3F ; G 2117 +U 7744 ; WX 995 ; N uni1E40 ; G 2118 +U 7745 ; WX 1042 ; N uni1E41 ; G 2119 +U 7746 ; WX 995 ; N uni1E42 ; G 2120 +U 7747 ; WX 1042 ; N uni1E43 ; G 2121 +U 7748 ; WX 837 ; N uni1E44 ; G 2122 +U 7749 ; WX 712 ; N uni1E45 ; G 2123 +U 7750 ; WX 837 ; N uni1E46 ; G 2124 +U 7751 ; WX 712 ; N uni1E47 ; G 2125 +U 7752 ; WX 837 ; N uni1E48 ; G 2126 +U 7753 ; WX 712 ; N uni1E49 ; G 2127 +U 7754 ; WX 837 ; N uni1E4A ; G 2128 +U 7755 ; WX 712 ; N uni1E4B ; G 2129 +U 7756 ; WX 850 ; N uni1E4C ; G 2130 +U 7757 ; WX 687 ; N uni1E4D ; G 2131 +U 7758 ; WX 850 ; N uni1E4E ; G 2132 +U 7759 ; WX 687 ; N uni1E4F ; G 2133 +U 7760 ; WX 850 ; N uni1E50 ; G 2134 +U 7761 ; WX 687 ; N uni1E51 ; G 2135 +U 7762 ; WX 850 ; N uni1E52 ; G 2136 +U 7763 ; WX 687 ; N uni1E53 ; G 2137 +U 7764 ; WX 733 ; N uni1E54 ; G 2138 +U 7765 ; WX 716 ; N uni1E55 ; G 2139 +U 7766 ; WX 733 ; N uni1E56 ; G 2140 +U 7767 ; WX 716 ; N uni1E57 ; G 2141 +U 7768 ; WX 770 ; N uni1E58 ; G 2142 +U 7769 ; WX 493 ; N uni1E59 ; G 2143 +U 7770 ; WX 770 ; N uni1E5A ; G 2144 +U 7771 ; WX 493 ; N uni1E5B ; G 2145 +U 7772 ; WX 770 ; N uni1E5C ; G 2146 +U 7773 ; WX 493 ; N uni1E5D ; G 2147 +U 7774 ; WX 770 ; N uni1E5E ; G 2148 +U 7775 ; WX 493 ; N uni1E5F ; G 2149 +U 7776 ; WX 720 ; N uni1E60 ; G 2150 +U 7777 ; WX 595 ; N uni1E61 ; G 2151 +U 7778 ; WX 720 ; N uni1E62 ; G 2152 +U 7779 ; WX 595 ; N uni1E63 ; G 2153 +U 7780 ; WX 720 ; N uni1E64 ; G 2154 +U 7781 ; WX 595 ; N uni1E65 ; G 2155 +U 7782 ; WX 720 ; N uni1E66 ; G 2156 +U 7783 ; WX 595 ; N uni1E67 ; G 2157 +U 7784 ; WX 720 ; N uni1E68 ; G 2158 +U 7785 ; WX 595 ; N uni1E69 ; G 2159 +U 7786 ; WX 682 ; N uni1E6A ; G 2160 +U 7787 ; WX 478 ; N uni1E6B ; G 2161 +U 7788 ; WX 682 ; N uni1E6C ; G 2162 +U 7789 ; WX 478 ; N uni1E6D ; G 2163 +U 7790 ; WX 682 ; N uni1E6E ; G 2164 +U 7791 ; WX 478 ; N uni1E6F ; G 2165 +U 7792 ; WX 682 ; N uni1E70 ; G 2166 +U 7793 ; WX 478 ; N uni1E71 ; G 2167 +U 7794 ; WX 812 ; N uni1E72 ; G 2168 +U 7795 ; WX 712 ; N uni1E73 ; G 2169 +U 7796 ; WX 812 ; N uni1E74 ; G 2170 +U 7797 ; WX 712 ; N uni1E75 ; G 2171 +U 7798 ; WX 812 ; N uni1E76 ; G 2172 +U 7799 ; WX 712 ; N uni1E77 ; G 2173 +U 7800 ; WX 812 ; N uni1E78 ; G 2174 +U 7801 ; WX 712 ; N uni1E79 ; G 2175 +U 7802 ; WX 812 ; N uni1E7A ; G 2176 +U 7803 ; WX 712 ; N uni1E7B ; G 2177 +U 7804 ; WX 774 ; N uni1E7C ; G 2178 +U 7805 ; WX 652 ; N uni1E7D ; G 2179 +U 7806 ; WX 774 ; N uni1E7E ; G 2180 +U 7807 ; WX 652 ; N uni1E7F ; G 2181 +U 7808 ; WX 1103 ; N Wgrave ; G 2182 +U 7809 ; WX 924 ; N wgrave ; G 2183 +U 7810 ; WX 1103 ; N Wacute ; G 2184 +U 7811 ; WX 924 ; N wacute ; G 2185 +U 7812 ; WX 1103 ; N Wdieresis ; G 2186 +U 7813 ; WX 924 ; N wdieresis ; G 2187 +U 7814 ; WX 1103 ; N uni1E86 ; G 2188 +U 7815 ; WX 924 ; N uni1E87 ; G 2189 +U 7816 ; WX 1103 ; N uni1E88 ; G 2190 +U 7817 ; WX 924 ; N uni1E89 ; G 2191 +U 7818 ; WX 771 ; N uni1E8A ; G 2192 +U 7819 ; WX 645 ; N uni1E8B ; G 2193 +U 7820 ; WX 771 ; N uni1E8C ; G 2194 +U 7821 ; WX 645 ; N uni1E8D ; G 2195 +U 7822 ; WX 724 ; N uni1E8E ; G 2196 +U 7823 ; WX 652 ; N uni1E8F ; G 2197 +U 7824 ; WX 725 ; N uni1E90 ; G 2198 +U 7825 ; WX 582 ; N uni1E91 ; G 2199 +U 7826 ; WX 725 ; N uni1E92 ; G 2200 +U 7827 ; WX 582 ; N uni1E93 ; G 2201 +U 7828 ; WX 725 ; N uni1E94 ; G 2202 +U 7829 ; WX 582 ; N uni1E95 ; G 2203 +U 7830 ; WX 712 ; N uni1E96 ; G 2204 +U 7831 ; WX 478 ; N uni1E97 ; G 2205 +U 7832 ; WX 924 ; N uni1E98 ; G 2206 +U 7833 ; WX 652 ; N uni1E99 ; G 2207 +U 7834 ; WX 675 ; N uni1E9A ; G 2208 +U 7835 ; WX 435 ; N uni1E9B ; G 2209 +U 7836 ; WX 435 ; N uni1E9C ; G 2210 +U 7837 ; WX 435 ; N uni1E9D ; G 2211 +U 7838 ; WX 896 ; N uni1E9E ; G 2212 +U 7839 ; WX 687 ; N uni1E9F ; G 2213 +U 7840 ; WX 774 ; N uni1EA0 ; G 2214 +U 7841 ; WX 675 ; N uni1EA1 ; G 2215 +U 7842 ; WX 774 ; N uni1EA2 ; G 2216 +U 7843 ; WX 675 ; N uni1EA3 ; G 2217 +U 7844 ; WX 774 ; N uni1EA4 ; G 2218 +U 7845 ; WX 675 ; N uni1EA5 ; G 2219 +U 7846 ; WX 774 ; N uni1EA6 ; G 2220 +U 7847 ; WX 675 ; N uni1EA7 ; G 2221 +U 7848 ; WX 774 ; N uni1EA8 ; G 2222 +U 7849 ; WX 675 ; N uni1EA9 ; G 2223 +U 7850 ; WX 774 ; N uni1EAA ; G 2224 +U 7851 ; WX 675 ; N uni1EAB ; G 2225 +U 7852 ; WX 774 ; N uni1EAC ; G 2226 +U 7853 ; WX 675 ; N uni1EAD ; G 2227 +U 7854 ; WX 774 ; N uni1EAE ; G 2228 +U 7855 ; WX 675 ; N uni1EAF ; G 2229 +U 7856 ; WX 774 ; N uni1EB0 ; G 2230 +U 7857 ; WX 675 ; N uni1EB1 ; G 2231 +U 7858 ; WX 774 ; N uni1EB2 ; G 2232 +U 7859 ; WX 675 ; N uni1EB3 ; G 2233 +U 7860 ; WX 774 ; N uni1EB4 ; G 2234 +U 7861 ; WX 675 ; N uni1EB5 ; G 2235 +U 7862 ; WX 774 ; N uni1EB6 ; G 2236 +U 7863 ; WX 675 ; N uni1EB7 ; G 2237 +U 7864 ; WX 683 ; N uni1EB8 ; G 2238 +U 7865 ; WX 678 ; N uni1EB9 ; G 2239 +U 7866 ; WX 683 ; N uni1EBA ; G 2240 +U 7867 ; WX 678 ; N uni1EBB ; G 2241 +U 7868 ; WX 683 ; N uni1EBC ; G 2242 +U 7869 ; WX 678 ; N uni1EBD ; G 2243 +U 7870 ; WX 683 ; N uni1EBE ; G 2244 +U 7871 ; WX 678 ; N uni1EBF ; G 2245 +U 7872 ; WX 683 ; N uni1EC0 ; G 2246 +U 7873 ; WX 678 ; N uni1EC1 ; G 2247 +U 7874 ; WX 683 ; N uni1EC2 ; G 2248 +U 7875 ; WX 678 ; N uni1EC3 ; G 2249 +U 7876 ; WX 683 ; N uni1EC4 ; G 2250 +U 7877 ; WX 678 ; N uni1EC5 ; G 2251 +U 7878 ; WX 683 ; N uni1EC6 ; G 2252 +U 7879 ; WX 678 ; N uni1EC7 ; G 2253 +U 7880 ; WX 372 ; N uni1EC8 ; G 2254 +U 7881 ; WX 343 ; N uni1EC9 ; G 2255 +U 7882 ; WX 372 ; N uni1ECA ; G 2256 +U 7883 ; WX 343 ; N uni1ECB ; G 2257 +U 7884 ; WX 850 ; N uni1ECC ; G 2258 +U 7885 ; WX 687 ; N uni1ECD ; G 2259 +U 7886 ; WX 850 ; N uni1ECE ; G 2260 +U 7887 ; WX 687 ; N uni1ECF ; G 2261 +U 7888 ; WX 850 ; N uni1ED0 ; G 2262 +U 7889 ; WX 687 ; N uni1ED1 ; G 2263 +U 7890 ; WX 850 ; N uni1ED2 ; G 2264 +U 7891 ; WX 687 ; N uni1ED3 ; G 2265 +U 7892 ; WX 850 ; N uni1ED4 ; G 2266 +U 7893 ; WX 687 ; N uni1ED5 ; G 2267 +U 7894 ; WX 850 ; N uni1ED6 ; G 2268 +U 7895 ; WX 687 ; N uni1ED7 ; G 2269 +U 7896 ; WX 850 ; N uni1ED8 ; G 2270 +U 7897 ; WX 687 ; N uni1ED9 ; G 2271 +U 7898 ; WX 850 ; N uni1EDA ; G 2272 +U 7899 ; WX 687 ; N uni1EDB ; G 2273 +U 7900 ; WX 850 ; N uni1EDC ; G 2274 +U 7901 ; WX 687 ; N uni1EDD ; G 2275 +U 7902 ; WX 850 ; N uni1EDE ; G 2276 +U 7903 ; WX 687 ; N uni1EDF ; G 2277 +U 7904 ; WX 850 ; N uni1EE0 ; G 2278 +U 7905 ; WX 687 ; N uni1EE1 ; G 2279 +U 7906 ; WX 850 ; N uni1EE2 ; G 2280 +U 7907 ; WX 687 ; N uni1EE3 ; G 2281 +U 7908 ; WX 812 ; N uni1EE4 ; G 2282 +U 7909 ; WX 712 ; N uni1EE5 ; G 2283 +U 7910 ; WX 812 ; N uni1EE6 ; G 2284 +U 7911 ; WX 712 ; N uni1EE7 ; G 2285 +U 7912 ; WX 812 ; N uni1EE8 ; G 2286 +U 7913 ; WX 712 ; N uni1EE9 ; G 2287 +U 7914 ; WX 812 ; N uni1EEA ; G 2288 +U 7915 ; WX 712 ; N uni1EEB ; G 2289 +U 7916 ; WX 812 ; N uni1EEC ; G 2290 +U 7917 ; WX 712 ; N uni1EED ; G 2291 +U 7918 ; WX 812 ; N uni1EEE ; G 2292 +U 7919 ; WX 712 ; N uni1EEF ; G 2293 +U 7920 ; WX 812 ; N uni1EF0 ; G 2294 +U 7921 ; WX 712 ; N uni1EF1 ; G 2295 +U 7922 ; WX 724 ; N Ygrave ; G 2296 +U 7923 ; WX 652 ; N ygrave ; G 2297 +U 7924 ; WX 724 ; N uni1EF4 ; G 2298 +U 7925 ; WX 652 ; N uni1EF5 ; G 2299 +U 7926 ; WX 724 ; N uni1EF6 ; G 2300 +U 7927 ; WX 652 ; N uni1EF7 ; G 2301 +U 7928 ; WX 724 ; N uni1EF8 ; G 2302 +U 7929 ; WX 652 ; N uni1EF9 ; G 2303 +U 7930 ; WX 953 ; N uni1EFA ; G 2304 +U 7931 ; WX 644 ; N uni1EFB ; G 2305 +U 7936 ; WX 687 ; N uni1F00 ; G 2306 +U 7937 ; WX 687 ; N uni1F01 ; G 2307 +U 7938 ; WX 687 ; N uni1F02 ; G 2308 +U 7939 ; WX 687 ; N uni1F03 ; G 2309 +U 7940 ; WX 687 ; N uni1F04 ; G 2310 +U 7941 ; WX 687 ; N uni1F05 ; G 2311 +U 7942 ; WX 687 ; N uni1F06 ; G 2312 +U 7943 ; WX 687 ; N uni1F07 ; G 2313 +U 7944 ; WX 774 ; N uni1F08 ; G 2314 +U 7945 ; WX 774 ; N uni1F09 ; G 2315 +U 7946 ; WX 1041 ; N uni1F0A ; G 2316 +U 7947 ; WX 1043 ; N uni1F0B ; G 2317 +U 7948 ; WX 935 ; N uni1F0C ; G 2318 +U 7949 ; WX 963 ; N uni1F0D ; G 2319 +U 7950 ; WX 835 ; N uni1F0E ; G 2320 +U 7951 ; WX 859 ; N uni1F0F ; G 2321 +U 7952 ; WX 557 ; N uni1F10 ; G 2322 +U 7953 ; WX 557 ; N uni1F11 ; G 2323 +U 7954 ; WX 557 ; N uni1F12 ; G 2324 +U 7955 ; WX 557 ; N uni1F13 ; G 2325 +U 7956 ; WX 557 ; N uni1F14 ; G 2326 +U 7957 ; WX 557 ; N uni1F15 ; G 2327 +U 7960 ; WX 792 ; N uni1F18 ; G 2328 +U 7961 ; WX 794 ; N uni1F19 ; G 2329 +U 7962 ; WX 1100 ; N uni1F1A ; G 2330 +U 7963 ; WX 1096 ; N uni1F1B ; G 2331 +U 7964 ; WX 1023 ; N uni1F1C ; G 2332 +U 7965 ; WX 1052 ; N uni1F1D ; G 2333 +U 7968 ; WX 712 ; N uni1F20 ; G 2334 +U 7969 ; WX 712 ; N uni1F21 ; G 2335 +U 7970 ; WX 712 ; N uni1F22 ; G 2336 +U 7971 ; WX 712 ; N uni1F23 ; G 2337 +U 7972 ; WX 712 ; N uni1F24 ; G 2338 +U 7973 ; WX 712 ; N uni1F25 ; G 2339 +U 7974 ; WX 712 ; N uni1F26 ; G 2340 +U 7975 ; WX 712 ; N uni1F27 ; G 2341 +U 7976 ; WX 945 ; N uni1F28 ; G 2342 +U 7977 ; WX 951 ; N uni1F29 ; G 2343 +U 7978 ; WX 1250 ; N uni1F2A ; G 2344 +U 7979 ; WX 1250 ; N uni1F2B ; G 2345 +U 7980 ; WX 1180 ; N uni1F2C ; G 2346 +U 7981 ; WX 1206 ; N uni1F2D ; G 2347 +U 7982 ; WX 1054 ; N uni1F2E ; G 2348 +U 7983 ; WX 1063 ; N uni1F2F ; G 2349 +U 7984 ; WX 390 ; N uni1F30 ; G 2350 +U 7985 ; WX 390 ; N uni1F31 ; G 2351 +U 7986 ; WX 390 ; N uni1F32 ; G 2352 +U 7987 ; WX 390 ; N uni1F33 ; G 2353 +U 7988 ; WX 390 ; N uni1F34 ; G 2354 +U 7989 ; WX 390 ; N uni1F35 ; G 2355 +U 7990 ; WX 390 ; N uni1F36 ; G 2356 +U 7991 ; WX 390 ; N uni1F37 ; G 2357 +U 7992 ; WX 483 ; N uni1F38 ; G 2358 +U 7993 ; WX 489 ; N uni1F39 ; G 2359 +U 7994 ; WX 777 ; N uni1F3A ; G 2360 +U 7995 ; WX 785 ; N uni1F3B ; G 2361 +U 7996 ; WX 712 ; N uni1F3C ; G 2362 +U 7997 ; WX 738 ; N uni1F3D ; G 2363 +U 7998 ; WX 604 ; N uni1F3E ; G 2364 +U 7999 ; WX 604 ; N uni1F3F ; G 2365 +U 8000 ; WX 687 ; N uni1F40 ; G 2366 +U 8001 ; WX 687 ; N uni1F41 ; G 2367 +U 8002 ; WX 687 ; N uni1F42 ; G 2368 +U 8003 ; WX 687 ; N uni1F43 ; G 2369 +U 8004 ; WX 687 ; N uni1F44 ; G 2370 +U 8005 ; WX 687 ; N uni1F45 ; G 2371 +U 8008 ; WX 892 ; N uni1F48 ; G 2372 +U 8009 ; WX 933 ; N uni1F49 ; G 2373 +U 8010 ; WX 1221 ; N uni1F4A ; G 2374 +U 8011 ; WX 1224 ; N uni1F4B ; G 2375 +U 8012 ; WX 1053 ; N uni1F4C ; G 2376 +U 8013 ; WX 1082 ; N uni1F4D ; G 2377 +U 8016 ; WX 675 ; N uni1F50 ; G 2378 +U 8017 ; WX 675 ; N uni1F51 ; G 2379 +U 8018 ; WX 675 ; N uni1F52 ; G 2380 +U 8019 ; WX 675 ; N uni1F53 ; G 2381 +U 8020 ; WX 675 ; N uni1F54 ; G 2382 +U 8021 ; WX 675 ; N uni1F55 ; G 2383 +U 8022 ; WX 675 ; N uni1F56 ; G 2384 +U 8023 ; WX 675 ; N uni1F57 ; G 2385 +U 8025 ; WX 930 ; N uni1F59 ; G 2386 +U 8027 ; WX 1184 ; N uni1F5B ; G 2387 +U 8029 ; WX 1199 ; N uni1F5D ; G 2388 +U 8031 ; WX 1049 ; N uni1F5F ; G 2389 +U 8032 ; WX 869 ; N uni1F60 ; G 2390 +U 8033 ; WX 869 ; N uni1F61 ; G 2391 +U 8034 ; WX 869 ; N uni1F62 ; G 2392 +U 8035 ; WX 869 ; N uni1F63 ; G 2393 +U 8036 ; WX 869 ; N uni1F64 ; G 2394 +U 8037 ; WX 869 ; N uni1F65 ; G 2395 +U 8038 ; WX 869 ; N uni1F66 ; G 2396 +U 8039 ; WX 869 ; N uni1F67 ; G 2397 +U 8040 ; WX 909 ; N uni1F68 ; G 2398 +U 8041 ; WX 958 ; N uni1F69 ; G 2399 +U 8042 ; WX 1246 ; N uni1F6A ; G 2400 +U 8043 ; WX 1251 ; N uni1F6B ; G 2401 +U 8044 ; WX 1076 ; N uni1F6C ; G 2402 +U 8045 ; WX 1105 ; N uni1F6D ; G 2403 +U 8046 ; WX 1028 ; N uni1F6E ; G 2404 +U 8047 ; WX 1076 ; N uni1F6F ; G 2405 +U 8048 ; WX 687 ; N uni1F70 ; G 2406 +U 8049 ; WX 687 ; N uni1F71 ; G 2407 +U 8050 ; WX 557 ; N uni1F72 ; G 2408 +U 8051 ; WX 557 ; N uni1F73 ; G 2409 +U 8052 ; WX 712 ; N uni1F74 ; G 2410 +U 8053 ; WX 712 ; N uni1F75 ; G 2411 +U 8054 ; WX 390 ; N uni1F76 ; G 2412 +U 8055 ; WX 390 ; N uni1F77 ; G 2413 +U 8056 ; WX 687 ; N uni1F78 ; G 2414 +U 8057 ; WX 687 ; N uni1F79 ; G 2415 +U 8058 ; WX 675 ; N uni1F7A ; G 2416 +U 8059 ; WX 675 ; N uni1F7B ; G 2417 +U 8060 ; WX 869 ; N uni1F7C ; G 2418 +U 8061 ; WX 869 ; N uni1F7D ; G 2419 +U 8064 ; WX 687 ; N uni1F80 ; G 2420 +U 8065 ; WX 687 ; N uni1F81 ; G 2421 +U 8066 ; WX 687 ; N uni1F82 ; G 2422 +U 8067 ; WX 687 ; N uni1F83 ; G 2423 +U 8068 ; WX 687 ; N uni1F84 ; G 2424 +U 8069 ; WX 687 ; N uni1F85 ; G 2425 +U 8070 ; WX 687 ; N uni1F86 ; G 2426 +U 8071 ; WX 687 ; N uni1F87 ; G 2427 +U 8072 ; WX 774 ; N uni1F88 ; G 2428 +U 8073 ; WX 774 ; N uni1F89 ; G 2429 +U 8074 ; WX 1041 ; N uni1F8A ; G 2430 +U 8075 ; WX 1043 ; N uni1F8B ; G 2431 +U 8076 ; WX 935 ; N uni1F8C ; G 2432 +U 8077 ; WX 963 ; N uni1F8D ; G 2433 +U 8078 ; WX 835 ; N uni1F8E ; G 2434 +U 8079 ; WX 859 ; N uni1F8F ; G 2435 +U 8080 ; WX 712 ; N uni1F90 ; G 2436 +U 8081 ; WX 712 ; N uni1F91 ; G 2437 +U 8082 ; WX 712 ; N uni1F92 ; G 2438 +U 8083 ; WX 712 ; N uni1F93 ; G 2439 +U 8084 ; WX 712 ; N uni1F94 ; G 2440 +U 8085 ; WX 712 ; N uni1F95 ; G 2441 +U 8086 ; WX 712 ; N uni1F96 ; G 2442 +U 8087 ; WX 712 ; N uni1F97 ; G 2443 +U 8088 ; WX 945 ; N uni1F98 ; G 2444 +U 8089 ; WX 951 ; N uni1F99 ; G 2445 +U 8090 ; WX 1250 ; N uni1F9A ; G 2446 +U 8091 ; WX 1250 ; N uni1F9B ; G 2447 +U 8092 ; WX 1180 ; N uni1F9C ; G 2448 +U 8093 ; WX 1206 ; N uni1F9D ; G 2449 +U 8094 ; WX 1054 ; N uni1F9E ; G 2450 +U 8095 ; WX 1063 ; N uni1F9F ; G 2451 +U 8096 ; WX 869 ; N uni1FA0 ; G 2452 +U 8097 ; WX 869 ; N uni1FA1 ; G 2453 +U 8098 ; WX 869 ; N uni1FA2 ; G 2454 +U 8099 ; WX 869 ; N uni1FA3 ; G 2455 +U 8100 ; WX 869 ; N uni1FA4 ; G 2456 +U 8101 ; WX 869 ; N uni1FA5 ; G 2457 +U 8102 ; WX 869 ; N uni1FA6 ; G 2458 +U 8103 ; WX 869 ; N uni1FA7 ; G 2459 +U 8104 ; WX 909 ; N uni1FA8 ; G 2460 +U 8105 ; WX 958 ; N uni1FA9 ; G 2461 +U 8106 ; WX 1246 ; N uni1FAA ; G 2462 +U 8107 ; WX 1251 ; N uni1FAB ; G 2463 +U 8108 ; WX 1076 ; N uni1FAC ; G 2464 +U 8109 ; WX 1105 ; N uni1FAD ; G 2465 +U 8110 ; WX 1028 ; N uni1FAE ; G 2466 +U 8111 ; WX 1076 ; N uni1FAF ; G 2467 +U 8112 ; WX 687 ; N uni1FB0 ; G 2468 +U 8113 ; WX 687 ; N uni1FB1 ; G 2469 +U 8114 ; WX 687 ; N uni1FB2 ; G 2470 +U 8115 ; WX 687 ; N uni1FB3 ; G 2471 +U 8116 ; WX 687 ; N uni1FB4 ; G 2472 +U 8118 ; WX 687 ; N uni1FB6 ; G 2473 +U 8119 ; WX 687 ; N uni1FB7 ; G 2474 +U 8120 ; WX 774 ; N uni1FB8 ; G 2475 +U 8121 ; WX 774 ; N uni1FB9 ; G 2476 +U 8122 ; WX 876 ; N uni1FBA ; G 2477 +U 8123 ; WX 797 ; N uni1FBB ; G 2478 +U 8124 ; WX 774 ; N uni1FBC ; G 2479 +U 8125 ; WX 500 ; N uni1FBD ; G 2480 +U 8126 ; WX 500 ; N uni1FBE ; G 2481 +U 8127 ; WX 500 ; N uni1FBF ; G 2482 +U 8128 ; WX 500 ; N uni1FC0 ; G 2483 +U 8129 ; WX 500 ; N uni1FC1 ; G 2484 +U 8130 ; WX 712 ; N uni1FC2 ; G 2485 +U 8131 ; WX 712 ; N uni1FC3 ; G 2486 +U 8132 ; WX 712 ; N uni1FC4 ; G 2487 +U 8134 ; WX 712 ; N uni1FC6 ; G 2488 +U 8135 ; WX 712 ; N uni1FC7 ; G 2489 +U 8136 ; WX 929 ; N uni1FC8 ; G 2490 +U 8137 ; WX 846 ; N uni1FC9 ; G 2491 +U 8138 ; WX 1080 ; N uni1FCA ; G 2492 +U 8139 ; WX 1009 ; N uni1FCB ; G 2493 +U 8140 ; WX 837 ; N uni1FCC ; G 2494 +U 8141 ; WX 500 ; N uni1FCD ; G 2495 +U 8142 ; WX 500 ; N uni1FCE ; G 2496 +U 8143 ; WX 500 ; N uni1FCF ; G 2497 +U 8144 ; WX 390 ; N uni1FD0 ; G 2498 +U 8145 ; WX 390 ; N uni1FD1 ; G 2499 +U 8146 ; WX 390 ; N uni1FD2 ; G 2500 +U 8147 ; WX 390 ; N uni1FD3 ; G 2501 +U 8150 ; WX 390 ; N uni1FD6 ; G 2502 +U 8151 ; WX 390 ; N uni1FD7 ; G 2503 +U 8152 ; WX 372 ; N uni1FD8 ; G 2504 +U 8153 ; WX 372 ; N uni1FD9 ; G 2505 +U 8154 ; WX 621 ; N uni1FDA ; G 2506 +U 8155 ; WX 563 ; N uni1FDB ; G 2507 +U 8157 ; WX 500 ; N uni1FDD ; G 2508 +U 8158 ; WX 500 ; N uni1FDE ; G 2509 +U 8159 ; WX 500 ; N uni1FDF ; G 2510 +U 8160 ; WX 675 ; N uni1FE0 ; G 2511 +U 8161 ; WX 675 ; N uni1FE1 ; G 2512 +U 8162 ; WX 675 ; N uni1FE2 ; G 2513 +U 8163 ; WX 675 ; N uni1FE3 ; G 2514 +U 8164 ; WX 716 ; N uni1FE4 ; G 2515 +U 8165 ; WX 716 ; N uni1FE5 ; G 2516 +U 8166 ; WX 675 ; N uni1FE6 ; G 2517 +U 8167 ; WX 675 ; N uni1FE7 ; G 2518 +U 8168 ; WX 724 ; N uni1FE8 ; G 2519 +U 8169 ; WX 724 ; N uni1FE9 ; G 2520 +U 8170 ; WX 1020 ; N uni1FEA ; G 2521 +U 8171 ; WX 980 ; N uni1FEB ; G 2522 +U 8172 ; WX 838 ; N uni1FEC ; G 2523 +U 8173 ; WX 500 ; N uni1FED ; G 2524 +U 8174 ; WX 500 ; N uni1FEE ; G 2525 +U 8175 ; WX 500 ; N uni1FEF ; G 2526 +U 8178 ; WX 869 ; N uni1FF2 ; G 2527 +U 8179 ; WX 869 ; N uni1FF3 ; G 2528 +U 8180 ; WX 869 ; N uni1FF4 ; G 2529 +U 8182 ; WX 869 ; N uni1FF6 ; G 2530 +U 8183 ; WX 869 ; N uni1FF7 ; G 2531 +U 8184 ; WX 1065 ; N uni1FF8 ; G 2532 +U 8185 ; WX 891 ; N uni1FF9 ; G 2533 +U 8186 ; WX 1084 ; N uni1FFA ; G 2534 +U 8187 ; WX 894 ; N uni1FFB ; G 2535 +U 8188 ; WX 850 ; N uni1FFC ; G 2536 +U 8189 ; WX 500 ; N uni1FFD ; G 2537 +U 8190 ; WX 500 ; N uni1FFE ; G 2538 +U 8192 ; WX 500 ; N uni2000 ; G 2539 +U 8193 ; WX 1000 ; N uni2001 ; G 2540 +U 8194 ; WX 500 ; N uni2002 ; G 2541 +U 8195 ; WX 1000 ; N uni2003 ; G 2542 +U 8196 ; WX 330 ; N uni2004 ; G 2543 +U 8197 ; WX 250 ; N uni2005 ; G 2544 +U 8198 ; WX 167 ; N uni2006 ; G 2545 +U 8199 ; WX 696 ; N uni2007 ; G 2546 +U 8200 ; WX 380 ; N uni2008 ; G 2547 +U 8201 ; WX 200 ; N uni2009 ; G 2548 +U 8202 ; WX 100 ; N uni200A ; G 2549 +U 8203 ; WX 0 ; N uni200B ; G 2550 +U 8204 ; WX 0 ; N uni200C ; G 2551 +U 8205 ; WX 0 ; N uni200D ; G 2552 +U 8206 ; WX 0 ; N uni200E ; G 2553 +U 8207 ; WX 0 ; N uni200F ; G 2554 +U 8208 ; WX 415 ; N uni2010 ; G 2555 +U 8209 ; WX 415 ; N uni2011 ; G 2556 +U 8210 ; WX 696 ; N figuredash ; G 2557 +U 8211 ; WX 500 ; N endash ; G 2558 +U 8212 ; WX 1000 ; N emdash ; G 2559 +U 8213 ; WX 1000 ; N uni2015 ; G 2560 +U 8214 ; WX 500 ; N uni2016 ; G 2561 +U 8215 ; WX 500 ; N underscoredbl ; G 2562 +U 8216 ; WX 380 ; N quoteleft ; G 2563 +U 8217 ; WX 380 ; N quoteright ; G 2564 +U 8218 ; WX 380 ; N quotesinglbase ; G 2565 +U 8219 ; WX 380 ; N quotereversed ; G 2566 +U 8220 ; WX 644 ; N quotedblleft ; G 2567 +U 8221 ; WX 644 ; N quotedblright ; G 2568 +U 8222 ; WX 644 ; N quotedblbase ; G 2569 +U 8223 ; WX 657 ; N uni201F ; G 2570 +U 8224 ; WX 500 ; N dagger ; G 2571 +U 8225 ; WX 500 ; N daggerdbl ; G 2572 +U 8226 ; WX 639 ; N bullet ; G 2573 +U 8227 ; WX 639 ; N uni2023 ; G 2574 +U 8228 ; WX 380 ; N onedotenleader ; G 2575 +U 8229 ; WX 685 ; N twodotenleader ; G 2576 +U 8230 ; WX 1000 ; N ellipsis ; G 2577 +U 8231 ; WX 348 ; N uni2027 ; G 2578 +U 8232 ; WX 0 ; N uni2028 ; G 2579 +U 8233 ; WX 0 ; N uni2029 ; G 2580 +U 8234 ; WX 0 ; N uni202A ; G 2581 +U 8235 ; WX 0 ; N uni202B ; G 2582 +U 8236 ; WX 0 ; N uni202C ; G 2583 +U 8237 ; WX 0 ; N uni202D ; G 2584 +U 8238 ; WX 0 ; N uni202E ; G 2585 +U 8239 ; WX 200 ; N uni202F ; G 2586 +U 8240 ; WX 1454 ; N perthousand ; G 2587 +U 8241 ; WX 1908 ; N uni2031 ; G 2588 +U 8242 ; WX 264 ; N minute ; G 2589 +U 8243 ; WX 447 ; N second ; G 2590 +U 8244 ; WX 630 ; N uni2034 ; G 2591 +U 8245 ; WX 264 ; N uni2035 ; G 2592 +U 8246 ; WX 447 ; N uni2036 ; G 2593 +U 8247 ; WX 630 ; N uni2037 ; G 2594 +U 8248 ; WX 733 ; N uni2038 ; G 2595 +U 8249 ; WX 412 ; N guilsinglleft ; G 2596 +U 8250 ; WX 412 ; N guilsinglright ; G 2597 +U 8251 ; WX 972 ; N uni203B ; G 2598 +U 8252 ; WX 627 ; N exclamdbl ; G 2599 +U 8253 ; WX 580 ; N uni203D ; G 2600 +U 8254 ; WX 500 ; N uni203E ; G 2601 +U 8255 ; WX 828 ; N uni203F ; G 2602 +U 8256 ; WX 828 ; N uni2040 ; G 2603 +U 8257 ; WX 329 ; N uni2041 ; G 2604 +U 8258 ; WX 1023 ; N uni2042 ; G 2605 +U 8259 ; WX 500 ; N uni2043 ; G 2606 +U 8260 ; WX 167 ; N fraction ; G 2607 +U 8261 ; WX 457 ; N uni2045 ; G 2608 +U 8262 ; WX 457 ; N uni2046 ; G 2609 +U 8263 ; WX 1030 ; N uni2047 ; G 2610 +U 8264 ; WX 829 ; N uni2048 ; G 2611 +U 8265 ; WX 829 ; N uni2049 ; G 2612 +U 8266 ; WX 513 ; N uni204A ; G 2613 +U 8267 ; WX 687 ; N uni204B ; G 2614 +U 8268 ; WX 500 ; N uni204C ; G 2615 +U 8269 ; WX 500 ; N uni204D ; G 2616 +U 8270 ; WX 523 ; N uni204E ; G 2617 +U 8271 ; WX 400 ; N uni204F ; G 2618 +U 8272 ; WX 828 ; N uni2050 ; G 2619 +U 8273 ; WX 523 ; N uni2051 ; G 2620 +U 8274 ; WX 556 ; N uni2052 ; G 2621 +U 8275 ; WX 838 ; N uni2053 ; G 2622 +U 8276 ; WX 828 ; N uni2054 ; G 2623 +U 8277 ; WX 838 ; N uni2055 ; G 2624 +U 8278 ; WX 684 ; N uni2056 ; G 2625 +U 8279 ; WX 813 ; N uni2057 ; G 2626 +U 8280 ; WX 838 ; N uni2058 ; G 2627 +U 8281 ; WX 838 ; N uni2059 ; G 2628 +U 8282 ; WX 380 ; N uni205A ; G 2629 +U 8283 ; WX 872 ; N uni205B ; G 2630 +U 8284 ; WX 838 ; N uni205C ; G 2631 +U 8285 ; WX 380 ; N uni205D ; G 2632 +U 8286 ; WX 380 ; N uni205E ; G 2633 +U 8287 ; WX 222 ; N uni205F ; G 2634 +U 8288 ; WX 0 ; N uni2060 ; G 2635 +U 8289 ; WX 0 ; N uni2061 ; G 2636 +U 8290 ; WX 0 ; N uni2062 ; G 2637 +U 8291 ; WX 0 ; N uni2063 ; G 2638 +U 8292 ; WX 0 ; N uni2064 ; G 2639 +U 8298 ; WX 0 ; N uni206A ; G 2640 +U 8299 ; WX 0 ; N uni206B ; G 2641 +U 8300 ; WX 0 ; N uni206C ; G 2642 +U 8301 ; WX 0 ; N uni206D ; G 2643 +U 8302 ; WX 0 ; N uni206E ; G 2644 +U 8303 ; WX 0 ; N uni206F ; G 2645 +U 8304 ; WX 438 ; N uni2070 ; G 2646 +U 8305 ; WX 219 ; N uni2071 ; G 2647 +U 8308 ; WX 438 ; N uni2074 ; G 2648 +U 8309 ; WX 438 ; N uni2075 ; G 2649 +U 8310 ; WX 438 ; N uni2076 ; G 2650 +U 8311 ; WX 438 ; N uni2077 ; G 2651 +U 8312 ; WX 438 ; N uni2078 ; G 2652 +U 8313 ; WX 438 ; N uni2079 ; G 2653 +U 8314 ; WX 528 ; N uni207A ; G 2654 +U 8315 ; WX 528 ; N uni207B ; G 2655 +U 8316 ; WX 528 ; N uni207C ; G 2656 +U 8317 ; WX 288 ; N uni207D ; G 2657 +U 8318 ; WX 288 ; N uni207E ; G 2658 +U 8319 ; WX 456 ; N uni207F ; G 2659 +U 8320 ; WX 438 ; N uni2080 ; G 2660 +U 8321 ; WX 438 ; N uni2081 ; G 2661 +U 8322 ; WX 438 ; N uni2082 ; G 2662 +U 8323 ; WX 438 ; N uni2083 ; G 2663 +U 8324 ; WX 438 ; N uni2084 ; G 2664 +U 8325 ; WX 438 ; N uni2085 ; G 2665 +U 8326 ; WX 438 ; N uni2086 ; G 2666 +U 8327 ; WX 438 ; N uni2087 ; G 2667 +U 8328 ; WX 438 ; N uni2088 ; G 2668 +U 8329 ; WX 438 ; N uni2089 ; G 2669 +U 8330 ; WX 528 ; N uni208A ; G 2670 +U 8331 ; WX 528 ; N uni208B ; G 2671 +U 8332 ; WX 528 ; N uni208C ; G 2672 +U 8333 ; WX 288 ; N uni208D ; G 2673 +U 8334 ; WX 288 ; N uni208E ; G 2674 +U 8336 ; WX 458 ; N uni2090 ; G 2675 +U 8337 ; WX 479 ; N uni2091 ; G 2676 +U 8338 ; WX 488 ; N uni2092 ; G 2677 +U 8339 ; WX 413 ; N uni2093 ; G 2678 +U 8340 ; WX 479 ; N uni2094 ; G 2679 +U 8341 ; WX 456 ; N uni2095 ; G 2680 +U 8342 ; WX 487 ; N uni2096 ; G 2681 +U 8343 ; WX 219 ; N uni2097 ; G 2682 +U 8344 ; WX 664 ; N uni2098 ; G 2683 +U 8345 ; WX 456 ; N uni2099 ; G 2684 +U 8346 ; WX 479 ; N uni209A ; G 2685 +U 8347 ; WX 381 ; N uni209B ; G 2686 +U 8348 ; WX 388 ; N uni209C ; G 2687 +U 8352 ; WX 929 ; N uni20A0 ; G 2688 +U 8353 ; WX 696 ; N colonmonetary ; G 2689 +U 8354 ; WX 696 ; N uni20A2 ; G 2690 +U 8355 ; WX 696 ; N franc ; G 2691 +U 8356 ; WX 696 ; N lira ; G 2692 +U 8357 ; WX 1042 ; N uni20A5 ; G 2693 +U 8358 ; WX 696 ; N uni20A6 ; G 2694 +U 8359 ; WX 1488 ; N peseta ; G 2695 +U 8360 ; WX 1205 ; N uni20A8 ; G 2696 +U 8361 ; WX 1103 ; N uni20A9 ; G 2697 +U 8362 ; WX 854 ; N uni20AA ; G 2698 +U 8363 ; WX 696 ; N dong ; G 2699 +U 8364 ; WX 696 ; N Euro ; G 2700 +U 8365 ; WX 696 ; N uni20AD ; G 2701 +U 8366 ; WX 696 ; N uni20AE ; G 2702 +U 8367 ; WX 1392 ; N uni20AF ; G 2703 +U 8368 ; WX 696 ; N uni20B0 ; G 2704 +U 8369 ; WX 696 ; N uni20B1 ; G 2705 +U 8370 ; WX 696 ; N uni20B2 ; G 2706 +U 8371 ; WX 696 ; N uni20B3 ; G 2707 +U 8372 ; WX 859 ; N uni20B4 ; G 2708 +U 8373 ; WX 696 ; N uni20B5 ; G 2709 +U 8376 ; WX 696 ; N uni20B8 ; G 2710 +U 8377 ; WX 696 ; N uni20B9 ; G 2711 +U 8378 ; WX 696 ; N uni20BA ; G 2712 +U 8381 ; WX 696 ; N uni20BD ; G 2713 +U 8400 ; WX 0 ; N uni20D0 ; G 2714 +U 8401 ; WX 0 ; N uni20D1 ; G 2715 +U 8406 ; WX 0 ; N uni20D6 ; G 2716 +U 8407 ; WX 0 ; N uni20D7 ; G 2717 +U 8411 ; WX 0 ; N uni20DB ; G 2718 +U 8412 ; WX 0 ; N uni20DC ; G 2719 +U 8417 ; WX 0 ; N uni20E1 ; G 2720 +U 8448 ; WX 1106 ; N uni2100 ; G 2721 +U 8449 ; WX 1106 ; N uni2101 ; G 2722 +U 8450 ; WX 734 ; N uni2102 ; G 2723 +U 8451 ; WX 1211 ; N uni2103 ; G 2724 +U 8452 ; WX 896 ; N uni2104 ; G 2725 +U 8453 ; WX 1114 ; N uni2105 ; G 2726 +U 8454 ; WX 1148 ; N uni2106 ; G 2727 +U 8455 ; WX 696 ; N uni2107 ; G 2728 +U 8456 ; WX 698 ; N uni2108 ; G 2729 +U 8457 ; WX 952 ; N uni2109 ; G 2730 +U 8459 ; WX 1073 ; N uni210B ; G 2731 +U 8460 ; WX 913 ; N uni210C ; G 2732 +U 8461 ; WX 888 ; N uni210D ; G 2733 +U 8462 ; WX 712 ; N uni210E ; G 2734 +U 8463 ; WX 712 ; N uni210F ; G 2735 +U 8464 ; WX 597 ; N uni2110 ; G 2736 +U 8465 ; WX 697 ; N Ifraktur ; G 2737 +U 8466 ; WX 856 ; N uni2112 ; G 2738 +U 8467 ; WX 472 ; N uni2113 ; G 2739 +U 8468 ; WX 974 ; N uni2114 ; G 2740 +U 8469 ; WX 837 ; N uni2115 ; G 2741 +U 8470 ; WX 1203 ; N uni2116 ; G 2742 +U 8471 ; WX 1000 ; N uni2117 ; G 2743 +U 8472 ; WX 697 ; N weierstrass ; G 2744 +U 8473 ; WX 750 ; N uni2119 ; G 2745 +U 8474 ; WX 850 ; N uni211A ; G 2746 +U 8475 ; WX 938 ; N uni211B ; G 2747 +U 8476 ; WX 814 ; N Rfraktur ; G 2748 +U 8477 ; WX 801 ; N uni211D ; G 2749 +U 8478 ; WX 896 ; N prescription ; G 2750 +U 8479 ; WX 710 ; N uni211F ; G 2751 +U 8480 ; WX 1020 ; N uni2120 ; G 2752 +U 8481 ; WX 1239 ; N uni2121 ; G 2753 +U 8482 ; WX 1000 ; N trademark ; G 2754 +U 8483 ; WX 834 ; N uni2123 ; G 2755 +U 8484 ; WX 754 ; N uni2124 ; G 2756 +U 8485 ; WX 622 ; N uni2125 ; G 2757 +U 8486 ; WX 850 ; N uni2126 ; G 2758 +U 8487 ; WX 769 ; N uni2127 ; G 2759 +U 8488 ; WX 763 ; N uni2128 ; G 2760 +U 8489 ; WX 303 ; N uni2129 ; G 2761 +U 8490 ; WX 775 ; N uni212A ; G 2762 +U 8491 ; WX 774 ; N uni212B ; G 2763 +U 8492 ; WX 928 ; N uni212C ; G 2764 +U 8493 ; WX 818 ; N uni212D ; G 2765 +U 8494 ; WX 854 ; N estimated ; G 2766 +U 8495 ; WX 636 ; N uni212F ; G 2767 +U 8496 ; WX 729 ; N uni2130 ; G 2768 +U 8497 ; WX 808 ; N uni2131 ; G 2769 +U 8498 ; WX 683 ; N uni2132 ; G 2770 +U 8499 ; WX 1184 ; N uni2133 ; G 2771 +U 8500 ; WX 465 ; N uni2134 ; G 2772 +U 8501 ; WX 794 ; N aleph ; G 2773 +U 8502 ; WX 731 ; N uni2136 ; G 2774 +U 8503 ; WX 494 ; N uni2137 ; G 2775 +U 8504 ; WX 684 ; N uni2138 ; G 2776 +U 8505 ; WX 380 ; N uni2139 ; G 2777 +U 8506 ; WX 945 ; N uni213A ; G 2778 +U 8507 ; WX 1370 ; N uni213B ; G 2779 +U 8508 ; WX 790 ; N uni213C ; G 2780 +U 8509 ; WX 737 ; N uni213D ; G 2781 +U 8510 ; WX 654 ; N uni213E ; G 2782 +U 8511 ; WX 863 ; N uni213F ; G 2783 +U 8512 ; WX 840 ; N uni2140 ; G 2784 +U 8513 ; WX 786 ; N uni2141 ; G 2785 +U 8514 ; WX 576 ; N uni2142 ; G 2786 +U 8515 ; WX 637 ; N uni2143 ; G 2787 +U 8516 ; WX 760 ; N uni2144 ; G 2788 +U 8517 ; WX 830 ; N uni2145 ; G 2789 +U 8518 ; WX 716 ; N uni2146 ; G 2790 +U 8519 ; WX 678 ; N uni2147 ; G 2791 +U 8520 ; WX 343 ; N uni2148 ; G 2792 +U 8521 ; WX 343 ; N uni2149 ; G 2793 +U 8523 ; WX 872 ; N uni214B ; G 2794 +U 8526 ; WX 547 ; N uni214E ; G 2795 +U 8528 ; WX 1035 ; N uni2150 ; G 2796 +U 8529 ; WX 1035 ; N uni2151 ; G 2797 +U 8530 ; WX 1483 ; N uni2152 ; G 2798 +U 8531 ; WX 1035 ; N onethird ; G 2799 +U 8532 ; WX 1035 ; N twothirds ; G 2800 +U 8533 ; WX 1035 ; N uni2155 ; G 2801 +U 8534 ; WX 1035 ; N uni2156 ; G 2802 +U 8535 ; WX 1035 ; N uni2157 ; G 2803 +U 8536 ; WX 1035 ; N uni2158 ; G 2804 +U 8537 ; WX 1035 ; N uni2159 ; G 2805 +U 8538 ; WX 1035 ; N uni215A ; G 2806 +U 8539 ; WX 1035 ; N oneeighth ; G 2807 +U 8540 ; WX 1035 ; N threeeighths ; G 2808 +U 8541 ; WX 1035 ; N fiveeighths ; G 2809 +U 8542 ; WX 1035 ; N seveneighths ; G 2810 +U 8543 ; WX 615 ; N uni215F ; G 2811 +U 8544 ; WX 372 ; N uni2160 ; G 2812 +U 8545 ; WX 659 ; N uni2161 ; G 2813 +U 8546 ; WX 945 ; N uni2162 ; G 2814 +U 8547 ; WX 1099 ; N uni2163 ; G 2815 +U 8548 ; WX 774 ; N uni2164 ; G 2816 +U 8549 ; WX 1099 ; N uni2165 ; G 2817 +U 8550 ; WX 1386 ; N uni2166 ; G 2818 +U 8551 ; WX 1672 ; N uni2167 ; G 2819 +U 8552 ; WX 1121 ; N uni2168 ; G 2820 +U 8553 ; WX 771 ; N uni2169 ; G 2821 +U 8554 ; WX 1120 ; N uni216A ; G 2822 +U 8555 ; WX 1407 ; N uni216B ; G 2823 +U 8556 ; WX 637 ; N uni216C ; G 2824 +U 8557 ; WX 734 ; N uni216D ; G 2825 +U 8558 ; WX 830 ; N uni216E ; G 2826 +U 8559 ; WX 995 ; N uni216F ; G 2827 +U 8560 ; WX 343 ; N uni2170 ; G 2828 +U 8561 ; WX 607 ; N uni2171 ; G 2829 +U 8562 ; WX 872 ; N uni2172 ; G 2830 +U 8563 ; WX 984 ; N uni2173 ; G 2831 +U 8564 ; WX 652 ; N uni2174 ; G 2832 +U 8565 ; WX 962 ; N uni2175 ; G 2833 +U 8566 ; WX 1227 ; N uni2176 ; G 2834 +U 8567 ; WX 1491 ; N uni2177 ; G 2835 +U 8568 ; WX 969 ; N uni2178 ; G 2836 +U 8569 ; WX 645 ; N uni2179 ; G 2837 +U 8570 ; WX 969 ; N uni217A ; G 2838 +U 8571 ; WX 1233 ; N uni217B ; G 2839 +U 8572 ; WX 343 ; N uni217C ; G 2840 +U 8573 ; WX 593 ; N uni217D ; G 2841 +U 8574 ; WX 716 ; N uni217E ; G 2842 +U 8575 ; WX 1042 ; N uni217F ; G 2843 +U 8576 ; WX 1289 ; N uni2180 ; G 2844 +U 8577 ; WX 830 ; N uni2181 ; G 2845 +U 8578 ; WX 1289 ; N uni2182 ; G 2846 +U 8579 ; WX 734 ; N uni2183 ; G 2847 +U 8580 ; WX 593 ; N uni2184 ; G 2848 +U 8581 ; WX 734 ; N uni2185 ; G 2849 +U 8585 ; WX 1035 ; N uni2189 ; G 2850 +U 8592 ; WX 838 ; N arrowleft ; G 2851 +U 8593 ; WX 838 ; N arrowup ; G 2852 +U 8594 ; WX 838 ; N arrowright ; G 2853 +U 8595 ; WX 838 ; N arrowdown ; G 2854 +U 8596 ; WX 838 ; N arrowboth ; G 2855 +U 8597 ; WX 838 ; N arrowupdn ; G 2856 +U 8598 ; WX 838 ; N uni2196 ; G 2857 +U 8599 ; WX 838 ; N uni2197 ; G 2858 +U 8600 ; WX 838 ; N uni2198 ; G 2859 +U 8601 ; WX 838 ; N uni2199 ; G 2860 +U 8602 ; WX 838 ; N uni219A ; G 2861 +U 8603 ; WX 838 ; N uni219B ; G 2862 +U 8604 ; WX 838 ; N uni219C ; G 2863 +U 8605 ; WX 838 ; N uni219D ; G 2864 +U 8606 ; WX 838 ; N uni219E ; G 2865 +U 8607 ; WX 838 ; N uni219F ; G 2866 +U 8608 ; WX 838 ; N uni21A0 ; G 2867 +U 8609 ; WX 838 ; N uni21A1 ; G 2868 +U 8610 ; WX 838 ; N uni21A2 ; G 2869 +U 8611 ; WX 838 ; N uni21A3 ; G 2870 +U 8612 ; WX 838 ; N uni21A4 ; G 2871 +U 8613 ; WX 838 ; N uni21A5 ; G 2872 +U 8614 ; WX 838 ; N uni21A6 ; G 2873 +U 8615 ; WX 838 ; N uni21A7 ; G 2874 +U 8616 ; WX 838 ; N arrowupdnbse ; G 2875 +U 8617 ; WX 838 ; N uni21A9 ; G 2876 +U 8618 ; WX 838 ; N uni21AA ; G 2877 +U 8619 ; WX 838 ; N uni21AB ; G 2878 +U 8620 ; WX 838 ; N uni21AC ; G 2879 +U 8621 ; WX 838 ; N uni21AD ; G 2880 +U 8622 ; WX 838 ; N uni21AE ; G 2881 +U 8623 ; WX 838 ; N uni21AF ; G 2882 +U 8624 ; WX 838 ; N uni21B0 ; G 2883 +U 8625 ; WX 838 ; N uni21B1 ; G 2884 +U 8626 ; WX 838 ; N uni21B2 ; G 2885 +U 8627 ; WX 838 ; N uni21B3 ; G 2886 +U 8628 ; WX 838 ; N uni21B4 ; G 2887 +U 8629 ; WX 838 ; N carriagereturn ; G 2888 +U 8630 ; WX 838 ; N uni21B6 ; G 2889 +U 8631 ; WX 838 ; N uni21B7 ; G 2890 +U 8632 ; WX 838 ; N uni21B8 ; G 2891 +U 8633 ; WX 838 ; N uni21B9 ; G 2892 +U 8634 ; WX 838 ; N uni21BA ; G 2893 +U 8635 ; WX 838 ; N uni21BB ; G 2894 +U 8636 ; WX 838 ; N uni21BC ; G 2895 +U 8637 ; WX 838 ; N uni21BD ; G 2896 +U 8638 ; WX 838 ; N uni21BE ; G 2897 +U 8639 ; WX 838 ; N uni21BF ; G 2898 +U 8640 ; WX 838 ; N uni21C0 ; G 2899 +U 8641 ; WX 838 ; N uni21C1 ; G 2900 +U 8642 ; WX 838 ; N uni21C2 ; G 2901 +U 8643 ; WX 838 ; N uni21C3 ; G 2902 +U 8644 ; WX 838 ; N uni21C4 ; G 2903 +U 8645 ; WX 838 ; N uni21C5 ; G 2904 +U 8646 ; WX 838 ; N uni21C6 ; G 2905 +U 8647 ; WX 838 ; N uni21C7 ; G 2906 +U 8648 ; WX 838 ; N uni21C8 ; G 2907 +U 8649 ; WX 838 ; N uni21C9 ; G 2908 +U 8650 ; WX 838 ; N uni21CA ; G 2909 +U 8651 ; WX 838 ; N uni21CB ; G 2910 +U 8652 ; WX 838 ; N uni21CC ; G 2911 +U 8653 ; WX 838 ; N uni21CD ; G 2912 +U 8654 ; WX 838 ; N uni21CE ; G 2913 +U 8655 ; WX 838 ; N uni21CF ; G 2914 +U 8656 ; WX 838 ; N arrowdblleft ; G 2915 +U 8657 ; WX 838 ; N arrowdblup ; G 2916 +U 8658 ; WX 838 ; N arrowdblright ; G 2917 +U 8659 ; WX 838 ; N arrowdbldown ; G 2918 +U 8660 ; WX 838 ; N arrowdblboth ; G 2919 +U 8661 ; WX 838 ; N uni21D5 ; G 2920 +U 8662 ; WX 838 ; N uni21D6 ; G 2921 +U 8663 ; WX 838 ; N uni21D7 ; G 2922 +U 8664 ; WX 838 ; N uni21D8 ; G 2923 +U 8665 ; WX 838 ; N uni21D9 ; G 2924 +U 8666 ; WX 838 ; N uni21DA ; G 2925 +U 8667 ; WX 838 ; N uni21DB ; G 2926 +U 8668 ; WX 838 ; N uni21DC ; G 2927 +U 8669 ; WX 838 ; N uni21DD ; G 2928 +U 8670 ; WX 838 ; N uni21DE ; G 2929 +U 8671 ; WX 838 ; N uni21DF ; G 2930 +U 8672 ; WX 838 ; N uni21E0 ; G 2931 +U 8673 ; WX 838 ; N uni21E1 ; G 2932 +U 8674 ; WX 838 ; N uni21E2 ; G 2933 +U 8675 ; WX 838 ; N uni21E3 ; G 2934 +U 8676 ; WX 838 ; N uni21E4 ; G 2935 +U 8677 ; WX 838 ; N uni21E5 ; G 2936 +U 8678 ; WX 838 ; N uni21E6 ; G 2937 +U 8679 ; WX 838 ; N uni21E7 ; G 2938 +U 8680 ; WX 838 ; N uni21E8 ; G 2939 +U 8681 ; WX 838 ; N uni21E9 ; G 2940 +U 8682 ; WX 838 ; N uni21EA ; G 2941 +U 8683 ; WX 838 ; N uni21EB ; G 2942 +U 8684 ; WX 838 ; N uni21EC ; G 2943 +U 8685 ; WX 838 ; N uni21ED ; G 2944 +U 8686 ; WX 838 ; N uni21EE ; G 2945 +U 8687 ; WX 838 ; N uni21EF ; G 2946 +U 8688 ; WX 838 ; N uni21F0 ; G 2947 +U 8689 ; WX 838 ; N uni21F1 ; G 2948 +U 8690 ; WX 838 ; N uni21F2 ; G 2949 +U 8691 ; WX 838 ; N uni21F3 ; G 2950 +U 8692 ; WX 838 ; N uni21F4 ; G 2951 +U 8693 ; WX 838 ; N uni21F5 ; G 2952 +U 8694 ; WX 838 ; N uni21F6 ; G 2953 +U 8695 ; WX 838 ; N uni21F7 ; G 2954 +U 8696 ; WX 838 ; N uni21F8 ; G 2955 +U 8697 ; WX 838 ; N uni21F9 ; G 2956 +U 8698 ; WX 838 ; N uni21FA ; G 2957 +U 8699 ; WX 838 ; N uni21FB ; G 2958 +U 8700 ; WX 838 ; N uni21FC ; G 2959 +U 8701 ; WX 838 ; N uni21FD ; G 2960 +U 8702 ; WX 838 ; N uni21FE ; G 2961 +U 8703 ; WX 838 ; N uni21FF ; G 2962 +U 8704 ; WX 774 ; N universal ; G 2963 +U 8705 ; WX 696 ; N uni2201 ; G 2964 +U 8706 ; WX 544 ; N partialdiff ; G 2965 +U 8707 ; WX 683 ; N existential ; G 2966 +U 8708 ; WX 683 ; N uni2204 ; G 2967 +U 8709 ; WX 856 ; N emptyset ; G 2968 +U 8710 ; WX 697 ; N increment ; G 2969 +U 8711 ; WX 697 ; N gradient ; G 2970 +U 8712 ; WX 896 ; N element ; G 2971 +U 8713 ; WX 896 ; N notelement ; G 2972 +U 8714 ; WX 750 ; N uni220A ; G 2973 +U 8715 ; WX 896 ; N suchthat ; G 2974 +U 8716 ; WX 896 ; N uni220C ; G 2975 +U 8717 ; WX 750 ; N uni220D ; G 2976 +U 8718 ; WX 636 ; N uni220E ; G 2977 +U 8719 ; WX 787 ; N product ; G 2978 +U 8720 ; WX 787 ; N uni2210 ; G 2979 +U 8721 ; WX 718 ; N summation ; G 2980 +U 8722 ; WX 838 ; N minus ; G 2981 +U 8723 ; WX 838 ; N uni2213 ; G 2982 +U 8724 ; WX 696 ; N uni2214 ; G 2983 +U 8725 ; WX 365 ; N uni2215 ; G 2984 +U 8726 ; WX 696 ; N uni2216 ; G 2985 +U 8727 ; WX 838 ; N asteriskmath ; G 2986 +U 8728 ; WX 626 ; N uni2218 ; G 2987 +U 8729 ; WX 380 ; N uni2219 ; G 2988 +U 8730 ; WX 667 ; N radical ; G 2989 +U 8731 ; WX 667 ; N uni221B ; G 2990 +U 8732 ; WX 667 ; N uni221C ; G 2991 +U 8733 ; WX 712 ; N proportional ; G 2992 +U 8734 ; WX 833 ; N infinity ; G 2993 +U 8735 ; WX 838 ; N orthogonal ; G 2994 +U 8736 ; WX 896 ; N angle ; G 2995 +U 8737 ; WX 896 ; N uni2221 ; G 2996 +U 8738 ; WX 838 ; N uni2222 ; G 2997 +U 8739 ; WX 500 ; N uni2223 ; G 2998 +U 8740 ; WX 500 ; N uni2224 ; G 2999 +U 8741 ; WX 500 ; N uni2225 ; G 3000 +U 8742 ; WX 500 ; N uni2226 ; G 3001 +U 8743 ; WX 812 ; N logicaland ; G 3002 +U 8744 ; WX 812 ; N logicalor ; G 3003 +U 8745 ; WX 812 ; N intersection ; G 3004 +U 8746 ; WX 812 ; N union ; G 3005 +U 8747 ; WX 610 ; N integral ; G 3006 +U 8748 ; WX 929 ; N uni222C ; G 3007 +U 8749 ; WX 1295 ; N uni222D ; G 3008 +U 8750 ; WX 563 ; N uni222E ; G 3009 +U 8751 ; WX 977 ; N uni222F ; G 3010 +U 8752 ; WX 1313 ; N uni2230 ; G 3011 +U 8753 ; WX 563 ; N uni2231 ; G 3012 +U 8754 ; WX 563 ; N uni2232 ; G 3013 +U 8755 ; WX 563 ; N uni2233 ; G 3014 +U 8756 ; WX 696 ; N therefore ; G 3015 +U 8757 ; WX 696 ; N uni2235 ; G 3016 +U 8758 ; WX 294 ; N uni2236 ; G 3017 +U 8759 ; WX 696 ; N uni2237 ; G 3018 +U 8760 ; WX 838 ; N uni2238 ; G 3019 +U 8761 ; WX 838 ; N uni2239 ; G 3020 +U 8762 ; WX 838 ; N uni223A ; G 3021 +U 8763 ; WX 838 ; N uni223B ; G 3022 +U 8764 ; WX 838 ; N similar ; G 3023 +U 8765 ; WX 838 ; N uni223D ; G 3024 +U 8766 ; WX 838 ; N uni223E ; G 3025 +U 8767 ; WX 838 ; N uni223F ; G 3026 +U 8768 ; WX 375 ; N uni2240 ; G 3027 +U 8769 ; WX 838 ; N uni2241 ; G 3028 +U 8770 ; WX 838 ; N uni2242 ; G 3029 +U 8771 ; WX 838 ; N uni2243 ; G 3030 +U 8772 ; WX 838 ; N uni2244 ; G 3031 +U 8773 ; WX 838 ; N congruent ; G 3032 +U 8774 ; WX 838 ; N uni2246 ; G 3033 +U 8775 ; WX 838 ; N uni2247 ; G 3034 +U 8776 ; WX 838 ; N approxequal ; G 3035 +U 8777 ; WX 838 ; N uni2249 ; G 3036 +U 8778 ; WX 838 ; N uni224A ; G 3037 +U 8779 ; WX 838 ; N uni224B ; G 3038 +U 8780 ; WX 838 ; N uni224C ; G 3039 +U 8781 ; WX 838 ; N uni224D ; G 3040 +U 8782 ; WX 838 ; N uni224E ; G 3041 +U 8783 ; WX 838 ; N uni224F ; G 3042 +U 8784 ; WX 838 ; N uni2250 ; G 3043 +U 8785 ; WX 838 ; N uni2251 ; G 3044 +U 8786 ; WX 838 ; N uni2252 ; G 3045 +U 8787 ; WX 838 ; N uni2253 ; G 3046 +U 8788 ; WX 1063 ; N uni2254 ; G 3047 +U 8789 ; WX 1063 ; N uni2255 ; G 3048 +U 8790 ; WX 838 ; N uni2256 ; G 3049 +U 8791 ; WX 838 ; N uni2257 ; G 3050 +U 8792 ; WX 838 ; N uni2258 ; G 3051 +U 8793 ; WX 838 ; N uni2259 ; G 3052 +U 8794 ; WX 838 ; N uni225A ; G 3053 +U 8795 ; WX 838 ; N uni225B ; G 3054 +U 8796 ; WX 838 ; N uni225C ; G 3055 +U 8797 ; WX 838 ; N uni225D ; G 3056 +U 8798 ; WX 838 ; N uni225E ; G 3057 +U 8799 ; WX 838 ; N uni225F ; G 3058 +U 8800 ; WX 838 ; N notequal ; G 3059 +U 8801 ; WX 838 ; N equivalence ; G 3060 +U 8802 ; WX 838 ; N uni2262 ; G 3061 +U 8803 ; WX 838 ; N uni2263 ; G 3062 +U 8804 ; WX 838 ; N lessequal ; G 3063 +U 8805 ; WX 838 ; N greaterequal ; G 3064 +U 8806 ; WX 838 ; N uni2266 ; G 3065 +U 8807 ; WX 838 ; N uni2267 ; G 3066 +U 8808 ; WX 841 ; N uni2268 ; G 3067 +U 8809 ; WX 841 ; N uni2269 ; G 3068 +U 8810 ; WX 1047 ; N uni226A ; G 3069 +U 8811 ; WX 1047 ; N uni226B ; G 3070 +U 8812 ; WX 500 ; N uni226C ; G 3071 +U 8813 ; WX 838 ; N uni226D ; G 3072 +U 8814 ; WX 838 ; N uni226E ; G 3073 +U 8815 ; WX 838 ; N uni226F ; G 3074 +U 8816 ; WX 838 ; N uni2270 ; G 3075 +U 8817 ; WX 838 ; N uni2271 ; G 3076 +U 8818 ; WX 838 ; N uni2272 ; G 3077 +U 8819 ; WX 838 ; N uni2273 ; G 3078 +U 8820 ; WX 838 ; N uni2274 ; G 3079 +U 8821 ; WX 838 ; N uni2275 ; G 3080 +U 8822 ; WX 838 ; N uni2276 ; G 3081 +U 8823 ; WX 838 ; N uni2277 ; G 3082 +U 8824 ; WX 838 ; N uni2278 ; G 3083 +U 8825 ; WX 838 ; N uni2279 ; G 3084 +U 8826 ; WX 838 ; N uni227A ; G 3085 +U 8827 ; WX 838 ; N uni227B ; G 3086 +U 8828 ; WX 838 ; N uni227C ; G 3087 +U 8829 ; WX 838 ; N uni227D ; G 3088 +U 8830 ; WX 838 ; N uni227E ; G 3089 +U 8831 ; WX 838 ; N uni227F ; G 3090 +U 8832 ; WX 838 ; N uni2280 ; G 3091 +U 8833 ; WX 838 ; N uni2281 ; G 3092 +U 8834 ; WX 838 ; N propersubset ; G 3093 +U 8835 ; WX 838 ; N propersuperset ; G 3094 +U 8836 ; WX 838 ; N notsubset ; G 3095 +U 8837 ; WX 838 ; N uni2285 ; G 3096 +U 8838 ; WX 838 ; N reflexsubset ; G 3097 +U 8839 ; WX 838 ; N reflexsuperset ; G 3098 +U 8840 ; WX 838 ; N uni2288 ; G 3099 +U 8841 ; WX 838 ; N uni2289 ; G 3100 +U 8842 ; WX 838 ; N uni228A ; G 3101 +U 8843 ; WX 838 ; N uni228B ; G 3102 +U 8844 ; WX 812 ; N uni228C ; G 3103 +U 8845 ; WX 812 ; N uni228D ; G 3104 +U 8846 ; WX 812 ; N uni228E ; G 3105 +U 8847 ; WX 838 ; N uni228F ; G 3106 +U 8848 ; WX 838 ; N uni2290 ; G 3107 +U 8849 ; WX 838 ; N uni2291 ; G 3108 +U 8850 ; WX 838 ; N uni2292 ; G 3109 +U 8851 ; WX 796 ; N uni2293 ; G 3110 +U 8852 ; WX 796 ; N uni2294 ; G 3111 +U 8853 ; WX 838 ; N circleplus ; G 3112 +U 8854 ; WX 838 ; N uni2296 ; G 3113 +U 8855 ; WX 838 ; N circlemultiply ; G 3114 +U 8856 ; WX 838 ; N uni2298 ; G 3115 +U 8857 ; WX 838 ; N uni2299 ; G 3116 +U 8858 ; WX 838 ; N uni229A ; G 3117 +U 8859 ; WX 838 ; N uni229B ; G 3118 +U 8860 ; WX 838 ; N uni229C ; G 3119 +U 8861 ; WX 838 ; N uni229D ; G 3120 +U 8862 ; WX 838 ; N uni229E ; G 3121 +U 8863 ; WX 838 ; N uni229F ; G 3122 +U 8864 ; WX 838 ; N uni22A0 ; G 3123 +U 8865 ; WX 838 ; N uni22A1 ; G 3124 +U 8866 ; WX 914 ; N uni22A2 ; G 3125 +U 8867 ; WX 914 ; N uni22A3 ; G 3126 +U 8868 ; WX 914 ; N uni22A4 ; G 3127 +U 8869 ; WX 914 ; N perpendicular ; G 3128 +U 8870 ; WX 542 ; N uni22A6 ; G 3129 +U 8871 ; WX 542 ; N uni22A7 ; G 3130 +U 8872 ; WX 914 ; N uni22A8 ; G 3131 +U 8873 ; WX 914 ; N uni22A9 ; G 3132 +U 8874 ; WX 914 ; N uni22AA ; G 3133 +U 8875 ; WX 914 ; N uni22AB ; G 3134 +U 8876 ; WX 914 ; N uni22AC ; G 3135 +U 8877 ; WX 914 ; N uni22AD ; G 3136 +U 8878 ; WX 914 ; N uni22AE ; G 3137 +U 8879 ; WX 914 ; N uni22AF ; G 3138 +U 8880 ; WX 838 ; N uni22B0 ; G 3139 +U 8881 ; WX 838 ; N uni22B1 ; G 3140 +U 8882 ; WX 838 ; N uni22B2 ; G 3141 +U 8883 ; WX 838 ; N uni22B3 ; G 3142 +U 8884 ; WX 838 ; N uni22B4 ; G 3143 +U 8885 ; WX 838 ; N uni22B5 ; G 3144 +U 8886 ; WX 1000 ; N uni22B6 ; G 3145 +U 8887 ; WX 1000 ; N uni22B7 ; G 3146 +U 8888 ; WX 838 ; N uni22B8 ; G 3147 +U 8889 ; WX 838 ; N uni22B9 ; G 3148 +U 8890 ; WX 542 ; N uni22BA ; G 3149 +U 8891 ; WX 812 ; N uni22BB ; G 3150 +U 8892 ; WX 812 ; N uni22BC ; G 3151 +U 8893 ; WX 812 ; N uni22BD ; G 3152 +U 8894 ; WX 838 ; N uni22BE ; G 3153 +U 8895 ; WX 838 ; N uni22BF ; G 3154 +U 8896 ; WX 843 ; N uni22C0 ; G 3155 +U 8897 ; WX 843 ; N uni22C1 ; G 3156 +U 8898 ; WX 843 ; N uni22C2 ; G 3157 +U 8899 ; WX 843 ; N uni22C3 ; G 3158 +U 8900 ; WX 626 ; N uni22C4 ; G 3159 +U 8901 ; WX 380 ; N dotmath ; G 3160 +U 8902 ; WX 626 ; N uni22C6 ; G 3161 +U 8903 ; WX 838 ; N uni22C7 ; G 3162 +U 8904 ; WX 1000 ; N uni22C8 ; G 3163 +U 8905 ; WX 1000 ; N uni22C9 ; G 3164 +U 8906 ; WX 1000 ; N uni22CA ; G 3165 +U 8907 ; WX 1000 ; N uni22CB ; G 3166 +U 8908 ; WX 1000 ; N uni22CC ; G 3167 +U 8909 ; WX 838 ; N uni22CD ; G 3168 +U 8910 ; WX 812 ; N uni22CE ; G 3169 +U 8911 ; WX 812 ; N uni22CF ; G 3170 +U 8912 ; WX 838 ; N uni22D0 ; G 3171 +U 8913 ; WX 838 ; N uni22D1 ; G 3172 +U 8914 ; WX 838 ; N uni22D2 ; G 3173 +U 8915 ; WX 838 ; N uni22D3 ; G 3174 +U 8916 ; WX 838 ; N uni22D4 ; G 3175 +U 8917 ; WX 838 ; N uni22D5 ; G 3176 +U 8918 ; WX 838 ; N uni22D6 ; G 3177 +U 8919 ; WX 838 ; N uni22D7 ; G 3178 +U 8920 ; WX 1422 ; N uni22D8 ; G 3179 +U 8921 ; WX 1422 ; N uni22D9 ; G 3180 +U 8922 ; WX 838 ; N uni22DA ; G 3181 +U 8923 ; WX 838 ; N uni22DB ; G 3182 +U 8924 ; WX 838 ; N uni22DC ; G 3183 +U 8925 ; WX 838 ; N uni22DD ; G 3184 +U 8926 ; WX 838 ; N uni22DE ; G 3185 +U 8927 ; WX 838 ; N uni22DF ; G 3186 +U 8928 ; WX 838 ; N uni22E0 ; G 3187 +U 8929 ; WX 838 ; N uni22E1 ; G 3188 +U 8930 ; WX 838 ; N uni22E2 ; G 3189 +U 8931 ; WX 838 ; N uni22E3 ; G 3190 +U 8932 ; WX 838 ; N uni22E4 ; G 3191 +U 8933 ; WX 838 ; N uni22E5 ; G 3192 +U 8934 ; WX 838 ; N uni22E6 ; G 3193 +U 8935 ; WX 838 ; N uni22E7 ; G 3194 +U 8936 ; WX 838 ; N uni22E8 ; G 3195 +U 8937 ; WX 838 ; N uni22E9 ; G 3196 +U 8938 ; WX 838 ; N uni22EA ; G 3197 +U 8939 ; WX 838 ; N uni22EB ; G 3198 +U 8940 ; WX 838 ; N uni22EC ; G 3199 +U 8941 ; WX 838 ; N uni22ED ; G 3200 +U 8942 ; WX 1000 ; N uni22EE ; G 3201 +U 8943 ; WX 1000 ; N uni22EF ; G 3202 +U 8944 ; WX 1000 ; N uni22F0 ; G 3203 +U 8945 ; WX 1000 ; N uni22F1 ; G 3204 +U 8946 ; WX 1158 ; N uni22F2 ; G 3205 +U 8947 ; WX 896 ; N uni22F3 ; G 3206 +U 8948 ; WX 750 ; N uni22F4 ; G 3207 +U 8949 ; WX 896 ; N uni22F5 ; G 3208 +U 8950 ; WX 896 ; N uni22F6 ; G 3209 +U 8951 ; WX 750 ; N uni22F7 ; G 3210 +U 8952 ; WX 896 ; N uni22F8 ; G 3211 +U 8953 ; WX 896 ; N uni22F9 ; G 3212 +U 8954 ; WX 1158 ; N uni22FA ; G 3213 +U 8955 ; WX 896 ; N uni22FB ; G 3214 +U 8956 ; WX 750 ; N uni22FC ; G 3215 +U 8957 ; WX 896 ; N uni22FD ; G 3216 +U 8958 ; WX 750 ; N uni22FE ; G 3217 +U 8959 ; WX 896 ; N uni22FF ; G 3218 +U 8960 ; WX 602 ; N uni2300 ; G 3219 +U 8961 ; WX 602 ; N uni2301 ; G 3220 +U 8962 ; WX 716 ; N house ; G 3221 +U 8963 ; WX 838 ; N uni2303 ; G 3222 +U 8964 ; WX 838 ; N uni2304 ; G 3223 +U 8965 ; WX 838 ; N uni2305 ; G 3224 +U 8966 ; WX 838 ; N uni2306 ; G 3225 +U 8967 ; WX 488 ; N uni2307 ; G 3226 +U 8968 ; WX 457 ; N uni2308 ; G 3227 +U 8969 ; WX 457 ; N uni2309 ; G 3228 +U 8970 ; WX 457 ; N uni230A ; G 3229 +U 8971 ; WX 457 ; N uni230B ; G 3230 +U 8972 ; WX 809 ; N uni230C ; G 3231 +U 8973 ; WX 809 ; N uni230D ; G 3232 +U 8974 ; WX 809 ; N uni230E ; G 3233 +U 8975 ; WX 809 ; N uni230F ; G 3234 +U 8976 ; WX 838 ; N revlogicalnot ; G 3235 +U 8977 ; WX 539 ; N uni2311 ; G 3236 +U 8984 ; WX 928 ; N uni2318 ; G 3237 +U 8985 ; WX 838 ; N uni2319 ; G 3238 +U 8988 ; WX 469 ; N uni231C ; G 3239 +U 8989 ; WX 469 ; N uni231D ; G 3240 +U 8990 ; WX 469 ; N uni231E ; G 3241 +U 8991 ; WX 469 ; N uni231F ; G 3242 +U 8992 ; WX 610 ; N integraltp ; G 3243 +U 8993 ; WX 610 ; N integralbt ; G 3244 +U 8996 ; WX 1152 ; N uni2324 ; G 3245 +U 8997 ; WX 1152 ; N uni2325 ; G 3246 +U 8998 ; WX 1414 ; N uni2326 ; G 3247 +U 8999 ; WX 1152 ; N uni2327 ; G 3248 +U 9000 ; WX 1443 ; N uni2328 ; G 3249 +U 9003 ; WX 1414 ; N uni232B ; G 3250 +U 9004 ; WX 873 ; N uni232C ; G 3251 +U 9075 ; WX 390 ; N uni2373 ; G 3252 +U 9076 ; WX 716 ; N uni2374 ; G 3253 +U 9077 ; WX 869 ; N uni2375 ; G 3254 +U 9082 ; WX 687 ; N uni237A ; G 3255 +U 9085 ; WX 863 ; N uni237D ; G 3256 +U 9095 ; WX 1152 ; N uni2387 ; G 3257 +U 9108 ; WX 873 ; N uni2394 ; G 3258 +U 9115 ; WX 500 ; N uni239B ; G 3259 +U 9116 ; WX 500 ; N uni239C ; G 3260 +U 9117 ; WX 500 ; N uni239D ; G 3261 +U 9118 ; WX 500 ; N uni239E ; G 3262 +U 9119 ; WX 500 ; N uni239F ; G 3263 +U 9120 ; WX 500 ; N uni23A0 ; G 3264 +U 9121 ; WX 500 ; N uni23A1 ; G 3265 +U 9122 ; WX 500 ; N uni23A2 ; G 3266 +U 9123 ; WX 500 ; N uni23A3 ; G 3267 +U 9124 ; WX 500 ; N uni23A4 ; G 3268 +U 9125 ; WX 500 ; N uni23A5 ; G 3269 +U 9126 ; WX 500 ; N uni23A6 ; G 3270 +U 9127 ; WX 750 ; N uni23A7 ; G 3271 +U 9128 ; WX 750 ; N uni23A8 ; G 3272 +U 9129 ; WX 750 ; N uni23A9 ; G 3273 +U 9130 ; WX 750 ; N uni23AA ; G 3274 +U 9131 ; WX 750 ; N uni23AB ; G 3275 +U 9132 ; WX 750 ; N uni23AC ; G 3276 +U 9133 ; WX 750 ; N uni23AD ; G 3277 +U 9134 ; WX 610 ; N uni23AE ; G 3278 +U 9166 ; WX 838 ; N uni23CE ; G 3279 +U 9167 ; WX 945 ; N uni23CF ; G 3280 +U 9187 ; WX 873 ; N uni23E3 ; G 3281 +U 9189 ; WX 769 ; N uni23E5 ; G 3282 +U 9192 ; WX 696 ; N uni23E8 ; G 3283 +U 9250 ; WX 716 ; N uni2422 ; G 3284 +U 9251 ; WX 716 ; N uni2423 ; G 3285 +U 9312 ; WX 847 ; N uni2460 ; G 3286 +U 9313 ; WX 847 ; N uni2461 ; G 3287 +U 9314 ; WX 847 ; N uni2462 ; G 3288 +U 9315 ; WX 847 ; N uni2463 ; G 3289 +U 9316 ; WX 847 ; N uni2464 ; G 3290 +U 9317 ; WX 847 ; N uni2465 ; G 3291 +U 9318 ; WX 847 ; N uni2466 ; G 3292 +U 9319 ; WX 847 ; N uni2467 ; G 3293 +U 9320 ; WX 847 ; N uni2468 ; G 3294 +U 9321 ; WX 847 ; N uni2469 ; G 3295 +U 9472 ; WX 602 ; N SF100000 ; G 3296 +U 9473 ; WX 602 ; N uni2501 ; G 3297 +U 9474 ; WX 602 ; N SF110000 ; G 3298 +U 9475 ; WX 602 ; N uni2503 ; G 3299 +U 9476 ; WX 602 ; N uni2504 ; G 3300 +U 9477 ; WX 602 ; N uni2505 ; G 3301 +U 9478 ; WX 602 ; N uni2506 ; G 3302 +U 9479 ; WX 602 ; N uni2507 ; G 3303 +U 9480 ; WX 602 ; N uni2508 ; G 3304 +U 9481 ; WX 602 ; N uni2509 ; G 3305 +U 9482 ; WX 602 ; N uni250A ; G 3306 +U 9483 ; WX 602 ; N uni250B ; G 3307 +U 9484 ; WX 602 ; N SF010000 ; G 3308 +U 9485 ; WX 602 ; N uni250D ; G 3309 +U 9486 ; WX 602 ; N uni250E ; G 3310 +U 9487 ; WX 602 ; N uni250F ; G 3311 +U 9488 ; WX 602 ; N SF030000 ; G 3312 +U 9489 ; WX 602 ; N uni2511 ; G 3313 +U 9490 ; WX 602 ; N uni2512 ; G 3314 +U 9491 ; WX 602 ; N uni2513 ; G 3315 +U 9492 ; WX 602 ; N SF020000 ; G 3316 +U 9493 ; WX 602 ; N uni2515 ; G 3317 +U 9494 ; WX 602 ; N uni2516 ; G 3318 +U 9495 ; WX 602 ; N uni2517 ; G 3319 +U 9496 ; WX 602 ; N SF040000 ; G 3320 +U 9497 ; WX 602 ; N uni2519 ; G 3321 +U 9498 ; WX 602 ; N uni251A ; G 3322 +U 9499 ; WX 602 ; N uni251B ; G 3323 +U 9500 ; WX 602 ; N SF080000 ; G 3324 +U 9501 ; WX 602 ; N uni251D ; G 3325 +U 9502 ; WX 602 ; N uni251E ; G 3326 +U 9503 ; WX 602 ; N uni251F ; G 3327 +U 9504 ; WX 602 ; N uni2520 ; G 3328 +U 9505 ; WX 602 ; N uni2521 ; G 3329 +U 9506 ; WX 602 ; N uni2522 ; G 3330 +U 9507 ; WX 602 ; N uni2523 ; G 3331 +U 9508 ; WX 602 ; N SF090000 ; G 3332 +U 9509 ; WX 602 ; N uni2525 ; G 3333 +U 9510 ; WX 602 ; N uni2526 ; G 3334 +U 9511 ; WX 602 ; N uni2527 ; G 3335 +U 9512 ; WX 602 ; N uni2528 ; G 3336 +U 9513 ; WX 602 ; N uni2529 ; G 3337 +U 9514 ; WX 602 ; N uni252A ; G 3338 +U 9515 ; WX 602 ; N uni252B ; G 3339 +U 9516 ; WX 602 ; N SF060000 ; G 3340 +U 9517 ; WX 602 ; N uni252D ; G 3341 +U 9518 ; WX 602 ; N uni252E ; G 3342 +U 9519 ; WX 602 ; N uni252F ; G 3343 +U 9520 ; WX 602 ; N uni2530 ; G 3344 +U 9521 ; WX 602 ; N uni2531 ; G 3345 +U 9522 ; WX 602 ; N uni2532 ; G 3346 +U 9523 ; WX 602 ; N uni2533 ; G 3347 +U 9524 ; WX 602 ; N SF070000 ; G 3348 +U 9525 ; WX 602 ; N uni2535 ; G 3349 +U 9526 ; WX 602 ; N uni2536 ; G 3350 +U 9527 ; WX 602 ; N uni2537 ; G 3351 +U 9528 ; WX 602 ; N uni2538 ; G 3352 +U 9529 ; WX 602 ; N uni2539 ; G 3353 +U 9530 ; WX 602 ; N uni253A ; G 3354 +U 9531 ; WX 602 ; N uni253B ; G 3355 +U 9532 ; WX 602 ; N SF050000 ; G 3356 +U 9533 ; WX 602 ; N uni253D ; G 3357 +U 9534 ; WX 602 ; N uni253E ; G 3358 +U 9535 ; WX 602 ; N uni253F ; G 3359 +U 9536 ; WX 602 ; N uni2540 ; G 3360 +U 9537 ; WX 602 ; N uni2541 ; G 3361 +U 9538 ; WX 602 ; N uni2542 ; G 3362 +U 9539 ; WX 602 ; N uni2543 ; G 3363 +U 9540 ; WX 602 ; N uni2544 ; G 3364 +U 9541 ; WX 602 ; N uni2545 ; G 3365 +U 9542 ; WX 602 ; N uni2546 ; G 3366 +U 9543 ; WX 602 ; N uni2547 ; G 3367 +U 9544 ; WX 602 ; N uni2548 ; G 3368 +U 9545 ; WX 602 ; N uni2549 ; G 3369 +U 9546 ; WX 602 ; N uni254A ; G 3370 +U 9547 ; WX 602 ; N uni254B ; G 3371 +U 9548 ; WX 602 ; N uni254C ; G 3372 +U 9549 ; WX 602 ; N uni254D ; G 3373 +U 9550 ; WX 602 ; N uni254E ; G 3374 +U 9551 ; WX 602 ; N uni254F ; G 3375 +U 9552 ; WX 602 ; N SF430000 ; G 3376 +U 9553 ; WX 602 ; N SF240000 ; G 3377 +U 9554 ; WX 602 ; N SF510000 ; G 3378 +U 9555 ; WX 602 ; N SF520000 ; G 3379 +U 9556 ; WX 602 ; N SF390000 ; G 3380 +U 9557 ; WX 602 ; N SF220000 ; G 3381 +U 9558 ; WX 602 ; N SF210000 ; G 3382 +U 9559 ; WX 602 ; N SF250000 ; G 3383 +U 9560 ; WX 602 ; N SF500000 ; G 3384 +U 9561 ; WX 602 ; N SF490000 ; G 3385 +U 9562 ; WX 602 ; N SF380000 ; G 3386 +U 9563 ; WX 602 ; N SF280000 ; G 3387 +U 9564 ; WX 602 ; N SF270000 ; G 3388 +U 9565 ; WX 602 ; N SF260000 ; G 3389 +U 9566 ; WX 602 ; N SF360000 ; G 3390 +U 9567 ; WX 602 ; N SF370000 ; G 3391 +U 9568 ; WX 602 ; N SF420000 ; G 3392 +U 9569 ; WX 602 ; N SF190000 ; G 3393 +U 9570 ; WX 602 ; N SF200000 ; G 3394 +U 9571 ; WX 602 ; N SF230000 ; G 3395 +U 9572 ; WX 602 ; N SF470000 ; G 3396 +U 9573 ; WX 602 ; N SF480000 ; G 3397 +U 9574 ; WX 602 ; N SF410000 ; G 3398 +U 9575 ; WX 602 ; N SF450000 ; G 3399 +U 9576 ; WX 602 ; N SF460000 ; G 3400 +U 9577 ; WX 602 ; N SF400000 ; G 3401 +U 9578 ; WX 602 ; N SF540000 ; G 3402 +U 9579 ; WX 602 ; N SF530000 ; G 3403 +U 9580 ; WX 602 ; N SF440000 ; G 3404 +U 9581 ; WX 602 ; N uni256D ; G 3405 +U 9582 ; WX 602 ; N uni256E ; G 3406 +U 9583 ; WX 602 ; N uni256F ; G 3407 +U 9584 ; WX 602 ; N uni2570 ; G 3408 +U 9585 ; WX 602 ; N uni2571 ; G 3409 +U 9586 ; WX 602 ; N uni2572 ; G 3410 +U 9587 ; WX 602 ; N uni2573 ; G 3411 +U 9588 ; WX 602 ; N uni2574 ; G 3412 +U 9589 ; WX 602 ; N uni2575 ; G 3413 +U 9590 ; WX 602 ; N uni2576 ; G 3414 +U 9591 ; WX 602 ; N uni2577 ; G 3415 +U 9592 ; WX 602 ; N uni2578 ; G 3416 +U 9593 ; WX 602 ; N uni2579 ; G 3417 +U 9594 ; WX 602 ; N uni257A ; G 3418 +U 9595 ; WX 602 ; N uni257B ; G 3419 +U 9596 ; WX 602 ; N uni257C ; G 3420 +U 9597 ; WX 602 ; N uni257D ; G 3421 +U 9598 ; WX 602 ; N uni257E ; G 3422 +U 9599 ; WX 602 ; N uni257F ; G 3423 +U 9600 ; WX 769 ; N upblock ; G 3424 +U 9601 ; WX 769 ; N uni2581 ; G 3425 +U 9602 ; WX 769 ; N uni2582 ; G 3426 +U 9603 ; WX 769 ; N uni2583 ; G 3427 +U 9604 ; WX 769 ; N dnblock ; G 3428 +U 9605 ; WX 769 ; N uni2585 ; G 3429 +U 9606 ; WX 769 ; N uni2586 ; G 3430 +U 9607 ; WX 769 ; N uni2587 ; G 3431 +U 9608 ; WX 769 ; N block ; G 3432 +U 9609 ; WX 769 ; N uni2589 ; G 3433 +U 9610 ; WX 769 ; N uni258A ; G 3434 +U 9611 ; WX 769 ; N uni258B ; G 3435 +U 9612 ; WX 769 ; N lfblock ; G 3436 +U 9613 ; WX 769 ; N uni258D ; G 3437 +U 9614 ; WX 769 ; N uni258E ; G 3438 +U 9615 ; WX 769 ; N uni258F ; G 3439 +U 9616 ; WX 769 ; N rtblock ; G 3440 +U 9617 ; WX 769 ; N ltshade ; G 3441 +U 9618 ; WX 769 ; N shade ; G 3442 +U 9619 ; WX 769 ; N dkshade ; G 3443 +U 9620 ; WX 769 ; N uni2594 ; G 3444 +U 9621 ; WX 769 ; N uni2595 ; G 3445 +U 9622 ; WX 769 ; N uni2596 ; G 3446 +U 9623 ; WX 769 ; N uni2597 ; G 3447 +U 9624 ; WX 769 ; N uni2598 ; G 3448 +U 9625 ; WX 769 ; N uni2599 ; G 3449 +U 9626 ; WX 769 ; N uni259A ; G 3450 +U 9627 ; WX 769 ; N uni259B ; G 3451 +U 9628 ; WX 769 ; N uni259C ; G 3452 +U 9629 ; WX 769 ; N uni259D ; G 3453 +U 9630 ; WX 769 ; N uni259E ; G 3454 +U 9631 ; WX 769 ; N uni259F ; G 3455 +U 9632 ; WX 945 ; N filledbox ; G 3456 +U 9633 ; WX 945 ; N H22073 ; G 3457 +U 9634 ; WX 945 ; N uni25A2 ; G 3458 +U 9635 ; WX 945 ; N uni25A3 ; G 3459 +U 9636 ; WX 945 ; N uni25A4 ; G 3460 +U 9637 ; WX 945 ; N uni25A5 ; G 3461 +U 9638 ; WX 945 ; N uni25A6 ; G 3462 +U 9639 ; WX 945 ; N uni25A7 ; G 3463 +U 9640 ; WX 945 ; N uni25A8 ; G 3464 +U 9641 ; WX 945 ; N uni25A9 ; G 3465 +U 9642 ; WX 678 ; N H18543 ; G 3466 +U 9643 ; WX 678 ; N H18551 ; G 3467 +U 9644 ; WX 945 ; N filledrect ; G 3468 +U 9645 ; WX 945 ; N uni25AD ; G 3469 +U 9646 ; WX 550 ; N uni25AE ; G 3470 +U 9647 ; WX 550 ; N uni25AF ; G 3471 +U 9648 ; WX 769 ; N uni25B0 ; G 3472 +U 9649 ; WX 769 ; N uni25B1 ; G 3473 +U 9650 ; WX 769 ; N triagup ; G 3474 +U 9651 ; WX 769 ; N uni25B3 ; G 3475 +U 9652 ; WX 502 ; N uni25B4 ; G 3476 +U 9653 ; WX 502 ; N uni25B5 ; G 3477 +U 9654 ; WX 769 ; N uni25B6 ; G 3478 +U 9655 ; WX 769 ; N uni25B7 ; G 3479 +U 9656 ; WX 502 ; N uni25B8 ; G 3480 +U 9657 ; WX 502 ; N uni25B9 ; G 3481 +U 9658 ; WX 769 ; N triagrt ; G 3482 +U 9659 ; WX 769 ; N uni25BB ; G 3483 +U 9660 ; WX 769 ; N triagdn ; G 3484 +U 9661 ; WX 769 ; N uni25BD ; G 3485 +U 9662 ; WX 502 ; N uni25BE ; G 3486 +U 9663 ; WX 502 ; N uni25BF ; G 3487 +U 9664 ; WX 769 ; N uni25C0 ; G 3488 +U 9665 ; WX 769 ; N uni25C1 ; G 3489 +U 9666 ; WX 502 ; N uni25C2 ; G 3490 +U 9667 ; WX 502 ; N uni25C3 ; G 3491 +U 9668 ; WX 769 ; N triaglf ; G 3492 +U 9669 ; WX 769 ; N uni25C5 ; G 3493 +U 9670 ; WX 769 ; N uni25C6 ; G 3494 +U 9671 ; WX 769 ; N uni25C7 ; G 3495 +U 9672 ; WX 769 ; N uni25C8 ; G 3496 +U 9673 ; WX 873 ; N uni25C9 ; G 3497 +U 9674 ; WX 494 ; N lozenge ; G 3498 +U 9675 ; WX 873 ; N circle ; G 3499 +U 9676 ; WX 873 ; N uni25CC ; G 3500 +U 9677 ; WX 873 ; N uni25CD ; G 3501 +U 9678 ; WX 873 ; N uni25CE ; G 3502 +U 9679 ; WX 873 ; N H18533 ; G 3503 +U 9680 ; WX 873 ; N uni25D0 ; G 3504 +U 9681 ; WX 873 ; N uni25D1 ; G 3505 +U 9682 ; WX 873 ; N uni25D2 ; G 3506 +U 9683 ; WX 873 ; N uni25D3 ; G 3507 +U 9684 ; WX 873 ; N uni25D4 ; G 3508 +U 9685 ; WX 873 ; N uni25D5 ; G 3509 +U 9686 ; WX 527 ; N uni25D6 ; G 3510 +U 9687 ; WX 527 ; N uni25D7 ; G 3511 +U 9688 ; WX 840 ; N invbullet ; G 3512 +U 9689 ; WX 970 ; N invcircle ; G 3513 +U 9690 ; WX 970 ; N uni25DA ; G 3514 +U 9691 ; WX 970 ; N uni25DB ; G 3515 +U 9692 ; WX 387 ; N uni25DC ; G 3516 +U 9693 ; WX 387 ; N uni25DD ; G 3517 +U 9694 ; WX 387 ; N uni25DE ; G 3518 +U 9695 ; WX 387 ; N uni25DF ; G 3519 +U 9696 ; WX 769 ; N uni25E0 ; G 3520 +U 9697 ; WX 769 ; N uni25E1 ; G 3521 +U 9698 ; WX 769 ; N uni25E2 ; G 3522 +U 9699 ; WX 769 ; N uni25E3 ; G 3523 +U 9700 ; WX 769 ; N uni25E4 ; G 3524 +U 9701 ; WX 769 ; N uni25E5 ; G 3525 +U 9702 ; WX 639 ; N openbullet ; G 3526 +U 9703 ; WX 945 ; N uni25E7 ; G 3527 +U 9704 ; WX 945 ; N uni25E8 ; G 3528 +U 9705 ; WX 945 ; N uni25E9 ; G 3529 +U 9706 ; WX 945 ; N uni25EA ; G 3530 +U 9707 ; WX 945 ; N uni25EB ; G 3531 +U 9708 ; WX 769 ; N uni25EC ; G 3532 +U 9709 ; WX 769 ; N uni25ED ; G 3533 +U 9710 ; WX 769 ; N uni25EE ; G 3534 +U 9711 ; WX 1119 ; N uni25EF ; G 3535 +U 9712 ; WX 945 ; N uni25F0 ; G 3536 +U 9713 ; WX 945 ; N uni25F1 ; G 3537 +U 9714 ; WX 945 ; N uni25F2 ; G 3538 +U 9715 ; WX 945 ; N uni25F3 ; G 3539 +U 9716 ; WX 873 ; N uni25F4 ; G 3540 +U 9717 ; WX 873 ; N uni25F5 ; G 3541 +U 9718 ; WX 873 ; N uni25F6 ; G 3542 +U 9719 ; WX 873 ; N uni25F7 ; G 3543 +U 9720 ; WX 769 ; N uni25F8 ; G 3544 +U 9721 ; WX 769 ; N uni25F9 ; G 3545 +U 9722 ; WX 769 ; N uni25FA ; G 3546 +U 9723 ; WX 830 ; N uni25FB ; G 3547 +U 9724 ; WX 830 ; N uni25FC ; G 3548 +U 9725 ; WX 732 ; N uni25FD ; G 3549 +U 9726 ; WX 732 ; N uni25FE ; G 3550 +U 9727 ; WX 769 ; N uni25FF ; G 3551 +U 9728 ; WX 896 ; N uni2600 ; G 3552 +U 9729 ; WX 1000 ; N uni2601 ; G 3553 +U 9730 ; WX 896 ; N uni2602 ; G 3554 +U 9731 ; WX 896 ; N uni2603 ; G 3555 +U 9732 ; WX 896 ; N uni2604 ; G 3556 +U 9733 ; WX 896 ; N uni2605 ; G 3557 +U 9734 ; WX 896 ; N uni2606 ; G 3558 +U 9735 ; WX 573 ; N uni2607 ; G 3559 +U 9736 ; WX 896 ; N uni2608 ; G 3560 +U 9737 ; WX 896 ; N uni2609 ; G 3561 +U 9738 ; WX 888 ; N uni260A ; G 3562 +U 9739 ; WX 888 ; N uni260B ; G 3563 +U 9740 ; WX 671 ; N uni260C ; G 3564 +U 9741 ; WX 1013 ; N uni260D ; G 3565 +U 9742 ; WX 1246 ; N uni260E ; G 3566 +U 9743 ; WX 1250 ; N uni260F ; G 3567 +U 9744 ; WX 896 ; N uni2610 ; G 3568 +U 9745 ; WX 896 ; N uni2611 ; G 3569 +U 9746 ; WX 896 ; N uni2612 ; G 3570 +U 9747 ; WX 532 ; N uni2613 ; G 3571 +U 9748 ; WX 896 ; N uni2614 ; G 3572 +U 9749 ; WX 896 ; N uni2615 ; G 3573 +U 9750 ; WX 896 ; N uni2616 ; G 3574 +U 9751 ; WX 896 ; N uni2617 ; G 3575 +U 9752 ; WX 896 ; N uni2618 ; G 3576 +U 9753 ; WX 896 ; N uni2619 ; G 3577 +U 9754 ; WX 896 ; N uni261A ; G 3578 +U 9755 ; WX 896 ; N uni261B ; G 3579 +U 9756 ; WX 896 ; N uni261C ; G 3580 +U 9757 ; WX 609 ; N uni261D ; G 3581 +U 9758 ; WX 896 ; N uni261E ; G 3582 +U 9759 ; WX 609 ; N uni261F ; G 3583 +U 9760 ; WX 896 ; N uni2620 ; G 3584 +U 9761 ; WX 896 ; N uni2621 ; G 3585 +U 9762 ; WX 896 ; N uni2622 ; G 3586 +U 9763 ; WX 896 ; N uni2623 ; G 3587 +U 9764 ; WX 669 ; N uni2624 ; G 3588 +U 9765 ; WX 746 ; N uni2625 ; G 3589 +U 9766 ; WX 649 ; N uni2626 ; G 3590 +U 9767 ; WX 784 ; N uni2627 ; G 3591 +U 9768 ; WX 545 ; N uni2628 ; G 3592 +U 9769 ; WX 896 ; N uni2629 ; G 3593 +U 9770 ; WX 896 ; N uni262A ; G 3594 +U 9771 ; WX 896 ; N uni262B ; G 3595 +U 9772 ; WX 710 ; N uni262C ; G 3596 +U 9773 ; WX 896 ; N uni262D ; G 3597 +U 9774 ; WX 896 ; N uni262E ; G 3598 +U 9775 ; WX 896 ; N uni262F ; G 3599 +U 9776 ; WX 896 ; N uni2630 ; G 3600 +U 9777 ; WX 896 ; N uni2631 ; G 3601 +U 9778 ; WX 896 ; N uni2632 ; G 3602 +U 9779 ; WX 896 ; N uni2633 ; G 3603 +U 9780 ; WX 896 ; N uni2634 ; G 3604 +U 9781 ; WX 896 ; N uni2635 ; G 3605 +U 9782 ; WX 896 ; N uni2636 ; G 3606 +U 9783 ; WX 896 ; N uni2637 ; G 3607 +U 9784 ; WX 896 ; N uni2638 ; G 3608 +U 9785 ; WX 1042 ; N uni2639 ; G 3609 +U 9786 ; WX 1042 ; N smileface ; G 3610 +U 9787 ; WX 1042 ; N invsmileface ; G 3611 +U 9788 ; WX 896 ; N sun ; G 3612 +U 9789 ; WX 896 ; N uni263D ; G 3613 +U 9790 ; WX 896 ; N uni263E ; G 3614 +U 9791 ; WX 614 ; N uni263F ; G 3615 +U 9792 ; WX 732 ; N female ; G 3616 +U 9793 ; WX 732 ; N uni2641 ; G 3617 +U 9794 ; WX 896 ; N male ; G 3618 +U 9795 ; WX 896 ; N uni2643 ; G 3619 +U 9796 ; WX 896 ; N uni2644 ; G 3620 +U 9797 ; WX 896 ; N uni2645 ; G 3621 +U 9798 ; WX 896 ; N uni2646 ; G 3622 +U 9799 ; WX 896 ; N uni2647 ; G 3623 +U 9800 ; WX 896 ; N uni2648 ; G 3624 +U 9801 ; WX 896 ; N uni2649 ; G 3625 +U 9802 ; WX 896 ; N uni264A ; G 3626 +U 9803 ; WX 896 ; N uni264B ; G 3627 +U 9804 ; WX 896 ; N uni264C ; G 3628 +U 9805 ; WX 896 ; N uni264D ; G 3629 +U 9806 ; WX 896 ; N uni264E ; G 3630 +U 9807 ; WX 896 ; N uni264F ; G 3631 +U 9808 ; WX 896 ; N uni2650 ; G 3632 +U 9809 ; WX 896 ; N uni2651 ; G 3633 +U 9810 ; WX 896 ; N uni2652 ; G 3634 +U 9811 ; WX 896 ; N uni2653 ; G 3635 +U 9812 ; WX 896 ; N uni2654 ; G 3636 +U 9813 ; WX 896 ; N uni2655 ; G 3637 +U 9814 ; WX 896 ; N uni2656 ; G 3638 +U 9815 ; WX 896 ; N uni2657 ; G 3639 +U 9816 ; WX 896 ; N uni2658 ; G 3640 +U 9817 ; WX 896 ; N uni2659 ; G 3641 +U 9818 ; WX 896 ; N uni265A ; G 3642 +U 9819 ; WX 896 ; N uni265B ; G 3643 +U 9820 ; WX 896 ; N uni265C ; G 3644 +U 9821 ; WX 896 ; N uni265D ; G 3645 +U 9822 ; WX 896 ; N uni265E ; G 3646 +U 9823 ; WX 896 ; N uni265F ; G 3647 +U 9824 ; WX 896 ; N spade ; G 3648 +U 9825 ; WX 896 ; N uni2661 ; G 3649 +U 9826 ; WX 896 ; N uni2662 ; G 3650 +U 9827 ; WX 896 ; N club ; G 3651 +U 9828 ; WX 896 ; N uni2664 ; G 3652 +U 9829 ; WX 896 ; N heart ; G 3653 +U 9830 ; WX 896 ; N diamond ; G 3654 +U 9831 ; WX 896 ; N uni2667 ; G 3655 +U 9832 ; WX 896 ; N uni2668 ; G 3656 +U 9833 ; WX 472 ; N uni2669 ; G 3657 +U 9834 ; WX 638 ; N musicalnote ; G 3658 +U 9835 ; WX 896 ; N musicalnotedbl ; G 3659 +U 9836 ; WX 896 ; N uni266C ; G 3660 +U 9837 ; WX 472 ; N uni266D ; G 3661 +U 9838 ; WX 357 ; N uni266E ; G 3662 +U 9839 ; WX 484 ; N uni266F ; G 3663 +U 9840 ; WX 748 ; N uni2670 ; G 3664 +U 9841 ; WX 766 ; N uni2671 ; G 3665 +U 9842 ; WX 896 ; N uni2672 ; G 3666 +U 9843 ; WX 896 ; N uni2673 ; G 3667 +U 9844 ; WX 896 ; N uni2674 ; G 3668 +U 9845 ; WX 896 ; N uni2675 ; G 3669 +U 9846 ; WX 896 ; N uni2676 ; G 3670 +U 9847 ; WX 896 ; N uni2677 ; G 3671 +U 9848 ; WX 896 ; N uni2678 ; G 3672 +U 9849 ; WX 896 ; N uni2679 ; G 3673 +U 9850 ; WX 896 ; N uni267A ; G 3674 +U 9851 ; WX 896 ; N uni267B ; G 3675 +U 9852 ; WX 896 ; N uni267C ; G 3676 +U 9853 ; WX 896 ; N uni267D ; G 3677 +U 9854 ; WX 896 ; N uni267E ; G 3678 +U 9855 ; WX 896 ; N uni267F ; G 3679 +U 9856 ; WX 869 ; N uni2680 ; G 3680 +U 9857 ; WX 869 ; N uni2681 ; G 3681 +U 9858 ; WX 869 ; N uni2682 ; G 3682 +U 9859 ; WX 869 ; N uni2683 ; G 3683 +U 9860 ; WX 869 ; N uni2684 ; G 3684 +U 9861 ; WX 869 ; N uni2685 ; G 3685 +U 9862 ; WX 896 ; N uni2686 ; G 3686 +U 9863 ; WX 896 ; N uni2687 ; G 3687 +U 9864 ; WX 896 ; N uni2688 ; G 3688 +U 9865 ; WX 896 ; N uni2689 ; G 3689 +U 9866 ; WX 896 ; N uni268A ; G 3690 +U 9867 ; WX 896 ; N uni268B ; G 3691 +U 9868 ; WX 896 ; N uni268C ; G 3692 +U 9869 ; WX 896 ; N uni268D ; G 3693 +U 9870 ; WX 896 ; N uni268E ; G 3694 +U 9871 ; WX 896 ; N uni268F ; G 3695 +U 9872 ; WX 896 ; N uni2690 ; G 3696 +U 9873 ; WX 896 ; N uni2691 ; G 3697 +U 9874 ; WX 896 ; N uni2692 ; G 3698 +U 9875 ; WX 896 ; N uni2693 ; G 3699 +U 9876 ; WX 896 ; N uni2694 ; G 3700 +U 9877 ; WX 541 ; N uni2695 ; G 3701 +U 9878 ; WX 896 ; N uni2696 ; G 3702 +U 9879 ; WX 896 ; N uni2697 ; G 3703 +U 9880 ; WX 896 ; N uni2698 ; G 3704 +U 9881 ; WX 896 ; N uni2699 ; G 3705 +U 9882 ; WX 896 ; N uni269A ; G 3706 +U 9883 ; WX 896 ; N uni269B ; G 3707 +U 9884 ; WX 896 ; N uni269C ; G 3708 +U 9886 ; WX 896 ; N uni269E ; G 3709 +U 9887 ; WX 896 ; N uni269F ; G 3710 +U 9888 ; WX 896 ; N uni26A0 ; G 3711 +U 9889 ; WX 702 ; N uni26A1 ; G 3712 +U 9890 ; WX 1004 ; N uni26A2 ; G 3713 +U 9891 ; WX 1089 ; N uni26A3 ; G 3714 +U 9892 ; WX 1175 ; N uni26A4 ; G 3715 +U 9893 ; WX 903 ; N uni26A5 ; G 3716 +U 9894 ; WX 838 ; N uni26A6 ; G 3717 +U 9895 ; WX 838 ; N uni26A7 ; G 3718 +U 9896 ; WX 838 ; N uni26A8 ; G 3719 +U 9897 ; WX 838 ; N uni26A9 ; G 3720 +U 9898 ; WX 838 ; N uni26AA ; G 3721 +U 9899 ; WX 838 ; N uni26AB ; G 3722 +U 9900 ; WX 838 ; N uni26AC ; G 3723 +U 9901 ; WX 838 ; N uni26AD ; G 3724 +U 9902 ; WX 838 ; N uni26AE ; G 3725 +U 9903 ; WX 838 ; N uni26AF ; G 3726 +U 9904 ; WX 844 ; N uni26B0 ; G 3727 +U 9905 ; WX 838 ; N uni26B1 ; G 3728 +U 9906 ; WX 732 ; N uni26B2 ; G 3729 +U 9907 ; WX 732 ; N uni26B3 ; G 3730 +U 9908 ; WX 732 ; N uni26B4 ; G 3731 +U 9909 ; WX 732 ; N uni26B5 ; G 3732 +U 9910 ; WX 850 ; N uni26B6 ; G 3733 +U 9911 ; WX 732 ; N uni26B7 ; G 3734 +U 9912 ; WX 732 ; N uni26B8 ; G 3735 +U 9920 ; WX 838 ; N uni26C0 ; G 3736 +U 9921 ; WX 838 ; N uni26C1 ; G 3737 +U 9922 ; WX 838 ; N uni26C2 ; G 3738 +U 9923 ; WX 838 ; N uni26C3 ; G 3739 +U 9954 ; WX 732 ; N uni26E2 ; G 3740 +U 9985 ; WX 838 ; N uni2701 ; G 3741 +U 9986 ; WX 838 ; N uni2702 ; G 3742 +U 9987 ; WX 838 ; N uni2703 ; G 3743 +U 9988 ; WX 838 ; N uni2704 ; G 3744 +U 9990 ; WX 838 ; N uni2706 ; G 3745 +U 9991 ; WX 838 ; N uni2707 ; G 3746 +U 9992 ; WX 838 ; N uni2708 ; G 3747 +U 9993 ; WX 838 ; N uni2709 ; G 3748 +U 9996 ; WX 838 ; N uni270C ; G 3749 +U 9997 ; WX 838 ; N uni270D ; G 3750 +U 9998 ; WX 838 ; N uni270E ; G 3751 +U 9999 ; WX 838 ; N uni270F ; G 3752 +U 10000 ; WX 838 ; N uni2710 ; G 3753 +U 10001 ; WX 838 ; N uni2711 ; G 3754 +U 10002 ; WX 838 ; N uni2712 ; G 3755 +U 10003 ; WX 838 ; N uni2713 ; G 3756 +U 10004 ; WX 838 ; N uni2714 ; G 3757 +U 10005 ; WX 838 ; N uni2715 ; G 3758 +U 10006 ; WX 838 ; N uni2716 ; G 3759 +U 10007 ; WX 838 ; N uni2717 ; G 3760 +U 10008 ; WX 838 ; N uni2718 ; G 3761 +U 10009 ; WX 838 ; N uni2719 ; G 3762 +U 10010 ; WX 838 ; N uni271A ; G 3763 +U 10011 ; WX 838 ; N uni271B ; G 3764 +U 10012 ; WX 838 ; N uni271C ; G 3765 +U 10013 ; WX 838 ; N uni271D ; G 3766 +U 10014 ; WX 838 ; N uni271E ; G 3767 +U 10015 ; WX 838 ; N uni271F ; G 3768 +U 10016 ; WX 838 ; N uni2720 ; G 3769 +U 10017 ; WX 838 ; N uni2721 ; G 3770 +U 10018 ; WX 838 ; N uni2722 ; G 3771 +U 10019 ; WX 838 ; N uni2723 ; G 3772 +U 10020 ; WX 838 ; N uni2724 ; G 3773 +U 10021 ; WX 838 ; N uni2725 ; G 3774 +U 10022 ; WX 838 ; N uni2726 ; G 3775 +U 10023 ; WX 838 ; N uni2727 ; G 3776 +U 10025 ; WX 838 ; N uni2729 ; G 3777 +U 10026 ; WX 838 ; N uni272A ; G 3778 +U 10027 ; WX 838 ; N uni272B ; G 3779 +U 10028 ; WX 838 ; N uni272C ; G 3780 +U 10029 ; WX 838 ; N uni272D ; G 3781 +U 10030 ; WX 838 ; N uni272E ; G 3782 +U 10031 ; WX 838 ; N uni272F ; G 3783 +U 10032 ; WX 838 ; N uni2730 ; G 3784 +U 10033 ; WX 838 ; N uni2731 ; G 3785 +U 10034 ; WX 838 ; N uni2732 ; G 3786 +U 10035 ; WX 838 ; N uni2733 ; G 3787 +U 10036 ; WX 838 ; N uni2734 ; G 3788 +U 10037 ; WX 838 ; N uni2735 ; G 3789 +U 10038 ; WX 838 ; N uni2736 ; G 3790 +U 10039 ; WX 838 ; N uni2737 ; G 3791 +U 10040 ; WX 838 ; N uni2738 ; G 3792 +U 10041 ; WX 838 ; N uni2739 ; G 3793 +U 10042 ; WX 838 ; N uni273A ; G 3794 +U 10043 ; WX 838 ; N uni273B ; G 3795 +U 10044 ; WX 838 ; N uni273C ; G 3796 +U 10045 ; WX 838 ; N uni273D ; G 3797 +U 10046 ; WX 838 ; N uni273E ; G 3798 +U 10047 ; WX 838 ; N uni273F ; G 3799 +U 10048 ; WX 838 ; N uni2740 ; G 3800 +U 10049 ; WX 838 ; N uni2741 ; G 3801 +U 10050 ; WX 838 ; N uni2742 ; G 3802 +U 10051 ; WX 838 ; N uni2743 ; G 3803 +U 10052 ; WX 838 ; N uni2744 ; G 3804 +U 10053 ; WX 838 ; N uni2745 ; G 3805 +U 10054 ; WX 838 ; N uni2746 ; G 3806 +U 10055 ; WX 838 ; N uni2747 ; G 3807 +U 10056 ; WX 838 ; N uni2748 ; G 3808 +U 10057 ; WX 838 ; N uni2749 ; G 3809 +U 10058 ; WX 838 ; N uni274A ; G 3810 +U 10059 ; WX 838 ; N uni274B ; G 3811 +U 10061 ; WX 896 ; N uni274D ; G 3812 +U 10063 ; WX 896 ; N uni274F ; G 3813 +U 10064 ; WX 896 ; N uni2750 ; G 3814 +U 10065 ; WX 896 ; N uni2751 ; G 3815 +U 10066 ; WX 896 ; N uni2752 ; G 3816 +U 10070 ; WX 896 ; N uni2756 ; G 3817 +U 10072 ; WX 838 ; N uni2758 ; G 3818 +U 10073 ; WX 838 ; N uni2759 ; G 3819 +U 10074 ; WX 838 ; N uni275A ; G 3820 +U 10075 ; WX 322 ; N uni275B ; G 3821 +U 10076 ; WX 322 ; N uni275C ; G 3822 +U 10077 ; WX 538 ; N uni275D ; G 3823 +U 10078 ; WX 538 ; N uni275E ; G 3824 +U 10081 ; WX 838 ; N uni2761 ; G 3825 +U 10082 ; WX 838 ; N uni2762 ; G 3826 +U 10083 ; WX 838 ; N uni2763 ; G 3827 +U 10084 ; WX 838 ; N uni2764 ; G 3828 +U 10085 ; WX 838 ; N uni2765 ; G 3829 +U 10086 ; WX 838 ; N uni2766 ; G 3830 +U 10087 ; WX 838 ; N uni2767 ; G 3831 +U 10088 ; WX 838 ; N uni2768 ; G 3832 +U 10089 ; WX 838 ; N uni2769 ; G 3833 +U 10090 ; WX 838 ; N uni276A ; G 3834 +U 10091 ; WX 838 ; N uni276B ; G 3835 +U 10092 ; WX 838 ; N uni276C ; G 3836 +U 10093 ; WX 838 ; N uni276D ; G 3837 +U 10094 ; WX 838 ; N uni276E ; G 3838 +U 10095 ; WX 838 ; N uni276F ; G 3839 +U 10096 ; WX 838 ; N uni2770 ; G 3840 +U 10097 ; WX 838 ; N uni2771 ; G 3841 +U 10098 ; WX 838 ; N uni2772 ; G 3842 +U 10099 ; WX 838 ; N uni2773 ; G 3843 +U 10100 ; WX 838 ; N uni2774 ; G 3844 +U 10101 ; WX 838 ; N uni2775 ; G 3845 +U 10102 ; WX 847 ; N uni2776 ; G 3846 +U 10103 ; WX 847 ; N uni2777 ; G 3847 +U 10104 ; WX 847 ; N uni2778 ; G 3848 +U 10105 ; WX 847 ; N uni2779 ; G 3849 +U 10106 ; WX 847 ; N uni277A ; G 3850 +U 10107 ; WX 847 ; N uni277B ; G 3851 +U 10108 ; WX 847 ; N uni277C ; G 3852 +U 10109 ; WX 847 ; N uni277D ; G 3853 +U 10110 ; WX 847 ; N uni277E ; G 3854 +U 10111 ; WX 847 ; N uni277F ; G 3855 +U 10112 ; WX 838 ; N uni2780 ; G 3856 +U 10113 ; WX 838 ; N uni2781 ; G 3857 +U 10114 ; WX 838 ; N uni2782 ; G 3858 +U 10115 ; WX 838 ; N uni2783 ; G 3859 +U 10116 ; WX 838 ; N uni2784 ; G 3860 +U 10117 ; WX 838 ; N uni2785 ; G 3861 +U 10118 ; WX 838 ; N uni2786 ; G 3862 +U 10119 ; WX 838 ; N uni2787 ; G 3863 +U 10120 ; WX 838 ; N uni2788 ; G 3864 +U 10121 ; WX 838 ; N uni2789 ; G 3865 +U 10122 ; WX 838 ; N uni278A ; G 3866 +U 10123 ; WX 838 ; N uni278B ; G 3867 +U 10124 ; WX 838 ; N uni278C ; G 3868 +U 10125 ; WX 838 ; N uni278D ; G 3869 +U 10126 ; WX 838 ; N uni278E ; G 3870 +U 10127 ; WX 838 ; N uni278F ; G 3871 +U 10128 ; WX 838 ; N uni2790 ; G 3872 +U 10129 ; WX 838 ; N uni2791 ; G 3873 +U 10130 ; WX 838 ; N uni2792 ; G 3874 +U 10131 ; WX 838 ; N uni2793 ; G 3875 +U 10132 ; WX 838 ; N uni2794 ; G 3876 +U 10136 ; WX 838 ; N uni2798 ; G 3877 +U 10137 ; WX 838 ; N uni2799 ; G 3878 +U 10138 ; WX 838 ; N uni279A ; G 3879 +U 10139 ; WX 838 ; N uni279B ; G 3880 +U 10140 ; WX 838 ; N uni279C ; G 3881 +U 10141 ; WX 838 ; N uni279D ; G 3882 +U 10142 ; WX 838 ; N uni279E ; G 3883 +U 10143 ; WX 838 ; N uni279F ; G 3884 +U 10144 ; WX 838 ; N uni27A0 ; G 3885 +U 10145 ; WX 838 ; N uni27A1 ; G 3886 +U 10146 ; WX 838 ; N uni27A2 ; G 3887 +U 10147 ; WX 838 ; N uni27A3 ; G 3888 +U 10148 ; WX 838 ; N uni27A4 ; G 3889 +U 10149 ; WX 838 ; N uni27A5 ; G 3890 +U 10150 ; WX 838 ; N uni27A6 ; G 3891 +U 10151 ; WX 838 ; N uni27A7 ; G 3892 +U 10152 ; WX 838 ; N uni27A8 ; G 3893 +U 10153 ; WX 838 ; N uni27A9 ; G 3894 +U 10154 ; WX 838 ; N uni27AA ; G 3895 +U 10155 ; WX 838 ; N uni27AB ; G 3896 +U 10156 ; WX 838 ; N uni27AC ; G 3897 +U 10157 ; WX 838 ; N uni27AD ; G 3898 +U 10158 ; WX 838 ; N uni27AE ; G 3899 +U 10159 ; WX 838 ; N uni27AF ; G 3900 +U 10161 ; WX 838 ; N uni27B1 ; G 3901 +U 10162 ; WX 838 ; N uni27B2 ; G 3902 +U 10163 ; WX 838 ; N uni27B3 ; G 3903 +U 10164 ; WX 838 ; N uni27B4 ; G 3904 +U 10165 ; WX 838 ; N uni27B5 ; G 3905 +U 10166 ; WX 838 ; N uni27B6 ; G 3906 +U 10167 ; WX 838 ; N uni27B7 ; G 3907 +U 10168 ; WX 838 ; N uni27B8 ; G 3908 +U 10169 ; WX 838 ; N uni27B9 ; G 3909 +U 10170 ; WX 838 ; N uni27BA ; G 3910 +U 10171 ; WX 838 ; N uni27BB ; G 3911 +U 10172 ; WX 838 ; N uni27BC ; G 3912 +U 10173 ; WX 838 ; N uni27BD ; G 3913 +U 10174 ; WX 838 ; N uni27BE ; G 3914 +U 10181 ; WX 457 ; N uni27C5 ; G 3915 +U 10182 ; WX 457 ; N uni27C6 ; G 3916 +U 10208 ; WX 494 ; N uni27E0 ; G 3917 +U 10214 ; WX 487 ; N uni27E6 ; G 3918 +U 10215 ; WX 487 ; N uni27E7 ; G 3919 +U 10216 ; WX 457 ; N uni27E8 ; G 3920 +U 10217 ; WX 457 ; N uni27E9 ; G 3921 +U 10218 ; WX 721 ; N uni27EA ; G 3922 +U 10219 ; WX 721 ; N uni27EB ; G 3923 +U 10224 ; WX 838 ; N uni27F0 ; G 3924 +U 10225 ; WX 838 ; N uni27F1 ; G 3925 +U 10226 ; WX 838 ; N uni27F2 ; G 3926 +U 10227 ; WX 838 ; N uni27F3 ; G 3927 +U 10228 ; WX 1157 ; N uni27F4 ; G 3928 +U 10229 ; WX 1434 ; N uni27F5 ; G 3929 +U 10230 ; WX 1434 ; N uni27F6 ; G 3930 +U 10231 ; WX 1434 ; N uni27F7 ; G 3931 +U 10232 ; WX 1434 ; N uni27F8 ; G 3932 +U 10233 ; WX 1434 ; N uni27F9 ; G 3933 +U 10234 ; WX 1434 ; N uni27FA ; G 3934 +U 10235 ; WX 1434 ; N uni27FB ; G 3935 +U 10236 ; WX 1434 ; N uni27FC ; G 3936 +U 10237 ; WX 1434 ; N uni27FD ; G 3937 +U 10238 ; WX 1434 ; N uni27FE ; G 3938 +U 10239 ; WX 1434 ; N uni27FF ; G 3939 +U 10240 ; WX 781 ; N uni2800 ; G 3940 +U 10241 ; WX 781 ; N uni2801 ; G 3941 +U 10242 ; WX 781 ; N uni2802 ; G 3942 +U 10243 ; WX 781 ; N uni2803 ; G 3943 +U 10244 ; WX 781 ; N uni2804 ; G 3944 +U 10245 ; WX 781 ; N uni2805 ; G 3945 +U 10246 ; WX 781 ; N uni2806 ; G 3946 +U 10247 ; WX 781 ; N uni2807 ; G 3947 +U 10248 ; WX 781 ; N uni2808 ; G 3948 +U 10249 ; WX 781 ; N uni2809 ; G 3949 +U 10250 ; WX 781 ; N uni280A ; G 3950 +U 10251 ; WX 781 ; N uni280B ; G 3951 +U 10252 ; WX 781 ; N uni280C ; G 3952 +U 10253 ; WX 781 ; N uni280D ; G 3953 +U 10254 ; WX 781 ; N uni280E ; G 3954 +U 10255 ; WX 781 ; N uni280F ; G 3955 +U 10256 ; WX 781 ; N uni2810 ; G 3956 +U 10257 ; WX 781 ; N uni2811 ; G 3957 +U 10258 ; WX 781 ; N uni2812 ; G 3958 +U 10259 ; WX 781 ; N uni2813 ; G 3959 +U 10260 ; WX 781 ; N uni2814 ; G 3960 +U 10261 ; WX 781 ; N uni2815 ; G 3961 +U 10262 ; WX 781 ; N uni2816 ; G 3962 +U 10263 ; WX 781 ; N uni2817 ; G 3963 +U 10264 ; WX 781 ; N uni2818 ; G 3964 +U 10265 ; WX 781 ; N uni2819 ; G 3965 +U 10266 ; WX 781 ; N uni281A ; G 3966 +U 10267 ; WX 781 ; N uni281B ; G 3967 +U 10268 ; WX 781 ; N uni281C ; G 3968 +U 10269 ; WX 781 ; N uni281D ; G 3969 +U 10270 ; WX 781 ; N uni281E ; G 3970 +U 10271 ; WX 781 ; N uni281F ; G 3971 +U 10272 ; WX 781 ; N uni2820 ; G 3972 +U 10273 ; WX 781 ; N uni2821 ; G 3973 +U 10274 ; WX 781 ; N uni2822 ; G 3974 +U 10275 ; WX 781 ; N uni2823 ; G 3975 +U 10276 ; WX 781 ; N uni2824 ; G 3976 +U 10277 ; WX 781 ; N uni2825 ; G 3977 +U 10278 ; WX 781 ; N uni2826 ; G 3978 +U 10279 ; WX 781 ; N uni2827 ; G 3979 +U 10280 ; WX 781 ; N uni2828 ; G 3980 +U 10281 ; WX 781 ; N uni2829 ; G 3981 +U 10282 ; WX 781 ; N uni282A ; G 3982 +U 10283 ; WX 781 ; N uni282B ; G 3983 +U 10284 ; WX 781 ; N uni282C ; G 3984 +U 10285 ; WX 781 ; N uni282D ; G 3985 +U 10286 ; WX 781 ; N uni282E ; G 3986 +U 10287 ; WX 781 ; N uni282F ; G 3987 +U 10288 ; WX 781 ; N uni2830 ; G 3988 +U 10289 ; WX 781 ; N uni2831 ; G 3989 +U 10290 ; WX 781 ; N uni2832 ; G 3990 +U 10291 ; WX 781 ; N uni2833 ; G 3991 +U 10292 ; WX 781 ; N uni2834 ; G 3992 +U 10293 ; WX 781 ; N uni2835 ; G 3993 +U 10294 ; WX 781 ; N uni2836 ; G 3994 +U 10295 ; WX 781 ; N uni2837 ; G 3995 +U 10296 ; WX 781 ; N uni2838 ; G 3996 +U 10297 ; WX 781 ; N uni2839 ; G 3997 +U 10298 ; WX 781 ; N uni283A ; G 3998 +U 10299 ; WX 781 ; N uni283B ; G 3999 +U 10300 ; WX 781 ; N uni283C ; G 4000 +U 10301 ; WX 781 ; N uni283D ; G 4001 +U 10302 ; WX 781 ; N uni283E ; G 4002 +U 10303 ; WX 781 ; N uni283F ; G 4003 +U 10304 ; WX 781 ; N uni2840 ; G 4004 +U 10305 ; WX 781 ; N uni2841 ; G 4005 +U 10306 ; WX 781 ; N uni2842 ; G 4006 +U 10307 ; WX 781 ; N uni2843 ; G 4007 +U 10308 ; WX 781 ; N uni2844 ; G 4008 +U 10309 ; WX 781 ; N uni2845 ; G 4009 +U 10310 ; WX 781 ; N uni2846 ; G 4010 +U 10311 ; WX 781 ; N uni2847 ; G 4011 +U 10312 ; WX 781 ; N uni2848 ; G 4012 +U 10313 ; WX 781 ; N uni2849 ; G 4013 +U 10314 ; WX 781 ; N uni284A ; G 4014 +U 10315 ; WX 781 ; N uni284B ; G 4015 +U 10316 ; WX 781 ; N uni284C ; G 4016 +U 10317 ; WX 781 ; N uni284D ; G 4017 +U 10318 ; WX 781 ; N uni284E ; G 4018 +U 10319 ; WX 781 ; N uni284F ; G 4019 +U 10320 ; WX 781 ; N uni2850 ; G 4020 +U 10321 ; WX 781 ; N uni2851 ; G 4021 +U 10322 ; WX 781 ; N uni2852 ; G 4022 +U 10323 ; WX 781 ; N uni2853 ; G 4023 +U 10324 ; WX 781 ; N uni2854 ; G 4024 +U 10325 ; WX 781 ; N uni2855 ; G 4025 +U 10326 ; WX 781 ; N uni2856 ; G 4026 +U 10327 ; WX 781 ; N uni2857 ; G 4027 +U 10328 ; WX 781 ; N uni2858 ; G 4028 +U 10329 ; WX 781 ; N uni2859 ; G 4029 +U 10330 ; WX 781 ; N uni285A ; G 4030 +U 10331 ; WX 781 ; N uni285B ; G 4031 +U 10332 ; WX 781 ; N uni285C ; G 4032 +U 10333 ; WX 781 ; N uni285D ; G 4033 +U 10334 ; WX 781 ; N uni285E ; G 4034 +U 10335 ; WX 781 ; N uni285F ; G 4035 +U 10336 ; WX 781 ; N uni2860 ; G 4036 +U 10337 ; WX 781 ; N uni2861 ; G 4037 +U 10338 ; WX 781 ; N uni2862 ; G 4038 +U 10339 ; WX 781 ; N uni2863 ; G 4039 +U 10340 ; WX 781 ; N uni2864 ; G 4040 +U 10341 ; WX 781 ; N uni2865 ; G 4041 +U 10342 ; WX 781 ; N uni2866 ; G 4042 +U 10343 ; WX 781 ; N uni2867 ; G 4043 +U 10344 ; WX 781 ; N uni2868 ; G 4044 +U 10345 ; WX 781 ; N uni2869 ; G 4045 +U 10346 ; WX 781 ; N uni286A ; G 4046 +U 10347 ; WX 781 ; N uni286B ; G 4047 +U 10348 ; WX 781 ; N uni286C ; G 4048 +U 10349 ; WX 781 ; N uni286D ; G 4049 +U 10350 ; WX 781 ; N uni286E ; G 4050 +U 10351 ; WX 781 ; N uni286F ; G 4051 +U 10352 ; WX 781 ; N uni2870 ; G 4052 +U 10353 ; WX 781 ; N uni2871 ; G 4053 +U 10354 ; WX 781 ; N uni2872 ; G 4054 +U 10355 ; WX 781 ; N uni2873 ; G 4055 +U 10356 ; WX 781 ; N uni2874 ; G 4056 +U 10357 ; WX 781 ; N uni2875 ; G 4057 +U 10358 ; WX 781 ; N uni2876 ; G 4058 +U 10359 ; WX 781 ; N uni2877 ; G 4059 +U 10360 ; WX 781 ; N uni2878 ; G 4060 +U 10361 ; WX 781 ; N uni2879 ; G 4061 +U 10362 ; WX 781 ; N uni287A ; G 4062 +U 10363 ; WX 781 ; N uni287B ; G 4063 +U 10364 ; WX 781 ; N uni287C ; G 4064 +U 10365 ; WX 781 ; N uni287D ; G 4065 +U 10366 ; WX 781 ; N uni287E ; G 4066 +U 10367 ; WX 781 ; N uni287F ; G 4067 +U 10368 ; WX 781 ; N uni2880 ; G 4068 +U 10369 ; WX 781 ; N uni2881 ; G 4069 +U 10370 ; WX 781 ; N uni2882 ; G 4070 +U 10371 ; WX 781 ; N uni2883 ; G 4071 +U 10372 ; WX 781 ; N uni2884 ; G 4072 +U 10373 ; WX 781 ; N uni2885 ; G 4073 +U 10374 ; WX 781 ; N uni2886 ; G 4074 +U 10375 ; WX 781 ; N uni2887 ; G 4075 +U 10376 ; WX 781 ; N uni2888 ; G 4076 +U 10377 ; WX 781 ; N uni2889 ; G 4077 +U 10378 ; WX 781 ; N uni288A ; G 4078 +U 10379 ; WX 781 ; N uni288B ; G 4079 +U 10380 ; WX 781 ; N uni288C ; G 4080 +U 10381 ; WX 781 ; N uni288D ; G 4081 +U 10382 ; WX 781 ; N uni288E ; G 4082 +U 10383 ; WX 781 ; N uni288F ; G 4083 +U 10384 ; WX 781 ; N uni2890 ; G 4084 +U 10385 ; WX 781 ; N uni2891 ; G 4085 +U 10386 ; WX 781 ; N uni2892 ; G 4086 +U 10387 ; WX 781 ; N uni2893 ; G 4087 +U 10388 ; WX 781 ; N uni2894 ; G 4088 +U 10389 ; WX 781 ; N uni2895 ; G 4089 +U 10390 ; WX 781 ; N uni2896 ; G 4090 +U 10391 ; WX 781 ; N uni2897 ; G 4091 +U 10392 ; WX 781 ; N uni2898 ; G 4092 +U 10393 ; WX 781 ; N uni2899 ; G 4093 +U 10394 ; WX 781 ; N uni289A ; G 4094 +U 10395 ; WX 781 ; N uni289B ; G 4095 +U 10396 ; WX 781 ; N uni289C ; G 4096 +U 10397 ; WX 781 ; N uni289D ; G 4097 +U 10398 ; WX 781 ; N uni289E ; G 4098 +U 10399 ; WX 781 ; N uni289F ; G 4099 +U 10400 ; WX 781 ; N uni28A0 ; G 4100 +U 10401 ; WX 781 ; N uni28A1 ; G 4101 +U 10402 ; WX 781 ; N uni28A2 ; G 4102 +U 10403 ; WX 781 ; N uni28A3 ; G 4103 +U 10404 ; WX 781 ; N uni28A4 ; G 4104 +U 10405 ; WX 781 ; N uni28A5 ; G 4105 +U 10406 ; WX 781 ; N uni28A6 ; G 4106 +U 10407 ; WX 781 ; N uni28A7 ; G 4107 +U 10408 ; WX 781 ; N uni28A8 ; G 4108 +U 10409 ; WX 781 ; N uni28A9 ; G 4109 +U 10410 ; WX 781 ; N uni28AA ; G 4110 +U 10411 ; WX 781 ; N uni28AB ; G 4111 +U 10412 ; WX 781 ; N uni28AC ; G 4112 +U 10413 ; WX 781 ; N uni28AD ; G 4113 +U 10414 ; WX 781 ; N uni28AE ; G 4114 +U 10415 ; WX 781 ; N uni28AF ; G 4115 +U 10416 ; WX 781 ; N uni28B0 ; G 4116 +U 10417 ; WX 781 ; N uni28B1 ; G 4117 +U 10418 ; WX 781 ; N uni28B2 ; G 4118 +U 10419 ; WX 781 ; N uni28B3 ; G 4119 +U 10420 ; WX 781 ; N uni28B4 ; G 4120 +U 10421 ; WX 781 ; N uni28B5 ; G 4121 +U 10422 ; WX 781 ; N uni28B6 ; G 4122 +U 10423 ; WX 781 ; N uni28B7 ; G 4123 +U 10424 ; WX 781 ; N uni28B8 ; G 4124 +U 10425 ; WX 781 ; N uni28B9 ; G 4125 +U 10426 ; WX 781 ; N uni28BA ; G 4126 +U 10427 ; WX 781 ; N uni28BB ; G 4127 +U 10428 ; WX 781 ; N uni28BC ; G 4128 +U 10429 ; WX 781 ; N uni28BD ; G 4129 +U 10430 ; WX 781 ; N uni28BE ; G 4130 +U 10431 ; WX 781 ; N uni28BF ; G 4131 +U 10432 ; WX 781 ; N uni28C0 ; G 4132 +U 10433 ; WX 781 ; N uni28C1 ; G 4133 +U 10434 ; WX 781 ; N uni28C2 ; G 4134 +U 10435 ; WX 781 ; N uni28C3 ; G 4135 +U 10436 ; WX 781 ; N uni28C4 ; G 4136 +U 10437 ; WX 781 ; N uni28C5 ; G 4137 +U 10438 ; WX 781 ; N uni28C6 ; G 4138 +U 10439 ; WX 781 ; N uni28C7 ; G 4139 +U 10440 ; WX 781 ; N uni28C8 ; G 4140 +U 10441 ; WX 781 ; N uni28C9 ; G 4141 +U 10442 ; WX 781 ; N uni28CA ; G 4142 +U 10443 ; WX 781 ; N uni28CB ; G 4143 +U 10444 ; WX 781 ; N uni28CC ; G 4144 +U 10445 ; WX 781 ; N uni28CD ; G 4145 +U 10446 ; WX 781 ; N uni28CE ; G 4146 +U 10447 ; WX 781 ; N uni28CF ; G 4147 +U 10448 ; WX 781 ; N uni28D0 ; G 4148 +U 10449 ; WX 781 ; N uni28D1 ; G 4149 +U 10450 ; WX 781 ; N uni28D2 ; G 4150 +U 10451 ; WX 781 ; N uni28D3 ; G 4151 +U 10452 ; WX 781 ; N uni28D4 ; G 4152 +U 10453 ; WX 781 ; N uni28D5 ; G 4153 +U 10454 ; WX 781 ; N uni28D6 ; G 4154 +U 10455 ; WX 781 ; N uni28D7 ; G 4155 +U 10456 ; WX 781 ; N uni28D8 ; G 4156 +U 10457 ; WX 781 ; N uni28D9 ; G 4157 +U 10458 ; WX 781 ; N uni28DA ; G 4158 +U 10459 ; WX 781 ; N uni28DB ; G 4159 +U 10460 ; WX 781 ; N uni28DC ; G 4160 +U 10461 ; WX 781 ; N uni28DD ; G 4161 +U 10462 ; WX 781 ; N uni28DE ; G 4162 +U 10463 ; WX 781 ; N uni28DF ; G 4163 +U 10464 ; WX 781 ; N uni28E0 ; G 4164 +U 10465 ; WX 781 ; N uni28E1 ; G 4165 +U 10466 ; WX 781 ; N uni28E2 ; G 4166 +U 10467 ; WX 781 ; N uni28E3 ; G 4167 +U 10468 ; WX 781 ; N uni28E4 ; G 4168 +U 10469 ; WX 781 ; N uni28E5 ; G 4169 +U 10470 ; WX 781 ; N uni28E6 ; G 4170 +U 10471 ; WX 781 ; N uni28E7 ; G 4171 +U 10472 ; WX 781 ; N uni28E8 ; G 4172 +U 10473 ; WX 781 ; N uni28E9 ; G 4173 +U 10474 ; WX 781 ; N uni28EA ; G 4174 +U 10475 ; WX 781 ; N uni28EB ; G 4175 +U 10476 ; WX 781 ; N uni28EC ; G 4176 +U 10477 ; WX 781 ; N uni28ED ; G 4177 +U 10478 ; WX 781 ; N uni28EE ; G 4178 +U 10479 ; WX 781 ; N uni28EF ; G 4179 +U 10480 ; WX 781 ; N uni28F0 ; G 4180 +U 10481 ; WX 781 ; N uni28F1 ; G 4181 +U 10482 ; WX 781 ; N uni28F2 ; G 4182 +U 10483 ; WX 781 ; N uni28F3 ; G 4183 +U 10484 ; WX 781 ; N uni28F4 ; G 4184 +U 10485 ; WX 781 ; N uni28F5 ; G 4185 +U 10486 ; WX 781 ; N uni28F6 ; G 4186 +U 10487 ; WX 781 ; N uni28F7 ; G 4187 +U 10488 ; WX 781 ; N uni28F8 ; G 4188 +U 10489 ; WX 781 ; N uni28F9 ; G 4189 +U 10490 ; WX 781 ; N uni28FA ; G 4190 +U 10491 ; WX 781 ; N uni28FB ; G 4191 +U 10492 ; WX 781 ; N uni28FC ; G 4192 +U 10493 ; WX 781 ; N uni28FD ; G 4193 +U 10494 ; WX 781 ; N uni28FE ; G 4194 +U 10495 ; WX 781 ; N uni28FF ; G 4195 +U 10502 ; WX 838 ; N uni2906 ; G 4196 +U 10503 ; WX 838 ; N uni2907 ; G 4197 +U 10506 ; WX 838 ; N uni290A ; G 4198 +U 10507 ; WX 838 ; N uni290B ; G 4199 +U 10560 ; WX 838 ; N uni2940 ; G 4200 +U 10561 ; WX 838 ; N uni2941 ; G 4201 +U 10627 ; WX 753 ; N uni2983 ; G 4202 +U 10628 ; WX 753 ; N uni2984 ; G 4203 +U 10702 ; WX 838 ; N uni29CE ; G 4204 +U 10703 ; WX 1046 ; N uni29CF ; G 4205 +U 10704 ; WX 1046 ; N uni29D0 ; G 4206 +U 10705 ; WX 1000 ; N uni29D1 ; G 4207 +U 10706 ; WX 1000 ; N uni29D2 ; G 4208 +U 10707 ; WX 1000 ; N uni29D3 ; G 4209 +U 10708 ; WX 1000 ; N uni29D4 ; G 4210 +U 10709 ; WX 1000 ; N uni29D5 ; G 4211 +U 10731 ; WX 494 ; N uni29EB ; G 4212 +U 10746 ; WX 838 ; N uni29FA ; G 4213 +U 10747 ; WX 838 ; N uni29FB ; G 4214 +U 10752 ; WX 1000 ; N uni2A00 ; G 4215 +U 10753 ; WX 1000 ; N uni2A01 ; G 4216 +U 10754 ; WX 1000 ; N uni2A02 ; G 4217 +U 10764 ; WX 1661 ; N uni2A0C ; G 4218 +U 10765 ; WX 563 ; N uni2A0D ; G 4219 +U 10766 ; WX 563 ; N uni2A0E ; G 4220 +U 10767 ; WX 563 ; N uni2A0F ; G 4221 +U 10768 ; WX 563 ; N uni2A10 ; G 4222 +U 10769 ; WX 563 ; N uni2A11 ; G 4223 +U 10770 ; WX 563 ; N uni2A12 ; G 4224 +U 10771 ; WX 563 ; N uni2A13 ; G 4225 +U 10772 ; WX 563 ; N uni2A14 ; G 4226 +U 10773 ; WX 563 ; N uni2A15 ; G 4227 +U 10774 ; WX 563 ; N uni2A16 ; G 4228 +U 10775 ; WX 563 ; N uni2A17 ; G 4229 +U 10776 ; WX 563 ; N uni2A18 ; G 4230 +U 10777 ; WX 563 ; N uni2A19 ; G 4231 +U 10778 ; WX 563 ; N uni2A1A ; G 4232 +U 10779 ; WX 563 ; N uni2A1B ; G 4233 +U 10780 ; WX 563 ; N uni2A1C ; G 4234 +U 10799 ; WX 838 ; N uni2A2F ; G 4235 +U 10858 ; WX 838 ; N uni2A6A ; G 4236 +U 10859 ; WX 838 ; N uni2A6B ; G 4237 +U 10877 ; WX 838 ; N uni2A7D ; G 4238 +U 10878 ; WX 838 ; N uni2A7E ; G 4239 +U 10879 ; WX 838 ; N uni2A7F ; G 4240 +U 10880 ; WX 838 ; N uni2A80 ; G 4241 +U 10881 ; WX 838 ; N uni2A81 ; G 4242 +U 10882 ; WX 838 ; N uni2A82 ; G 4243 +U 10883 ; WX 838 ; N uni2A83 ; G 4244 +U 10884 ; WX 838 ; N uni2A84 ; G 4245 +U 10885 ; WX 838 ; N uni2A85 ; G 4246 +U 10886 ; WX 838 ; N uni2A86 ; G 4247 +U 10887 ; WX 838 ; N uni2A87 ; G 4248 +U 10888 ; WX 838 ; N uni2A88 ; G 4249 +U 10889 ; WX 838 ; N uni2A89 ; G 4250 +U 10890 ; WX 838 ; N uni2A8A ; G 4251 +U 10891 ; WX 838 ; N uni2A8B ; G 4252 +U 10892 ; WX 838 ; N uni2A8C ; G 4253 +U 10893 ; WX 838 ; N uni2A8D ; G 4254 +U 10894 ; WX 838 ; N uni2A8E ; G 4255 +U 10895 ; WX 838 ; N uni2A8F ; G 4256 +U 10896 ; WX 838 ; N uni2A90 ; G 4257 +U 10897 ; WX 838 ; N uni2A91 ; G 4258 +U 10898 ; WX 838 ; N uni2A92 ; G 4259 +U 10899 ; WX 838 ; N uni2A93 ; G 4260 +U 10900 ; WX 838 ; N uni2A94 ; G 4261 +U 10901 ; WX 838 ; N uni2A95 ; G 4262 +U 10902 ; WX 838 ; N uni2A96 ; G 4263 +U 10903 ; WX 838 ; N uni2A97 ; G 4264 +U 10904 ; WX 838 ; N uni2A98 ; G 4265 +U 10905 ; WX 838 ; N uni2A99 ; G 4266 +U 10906 ; WX 838 ; N uni2A9A ; G 4267 +U 10907 ; WX 838 ; N uni2A9B ; G 4268 +U 10908 ; WX 838 ; N uni2A9C ; G 4269 +U 10909 ; WX 838 ; N uni2A9D ; G 4270 +U 10910 ; WX 838 ; N uni2A9E ; G 4271 +U 10911 ; WX 838 ; N uni2A9F ; G 4272 +U 10912 ; WX 838 ; N uni2AA0 ; G 4273 +U 10926 ; WX 838 ; N uni2AAE ; G 4274 +U 10927 ; WX 838 ; N uni2AAF ; G 4275 +U 10928 ; WX 838 ; N uni2AB0 ; G 4276 +U 10929 ; WX 838 ; N uni2AB1 ; G 4277 +U 10930 ; WX 838 ; N uni2AB2 ; G 4278 +U 10931 ; WX 838 ; N uni2AB3 ; G 4279 +U 10932 ; WX 838 ; N uni2AB4 ; G 4280 +U 10933 ; WX 838 ; N uni2AB5 ; G 4281 +U 10934 ; WX 838 ; N uni2AB6 ; G 4282 +U 10935 ; WX 838 ; N uni2AB7 ; G 4283 +U 10936 ; WX 838 ; N uni2AB8 ; G 4284 +U 10937 ; WX 838 ; N uni2AB9 ; G 4285 +U 10938 ; WX 838 ; N uni2ABA ; G 4286 +U 11001 ; WX 838 ; N uni2AF9 ; G 4287 +U 11002 ; WX 838 ; N uni2AFA ; G 4288 +U 11008 ; WX 838 ; N uni2B00 ; G 4289 +U 11009 ; WX 838 ; N uni2B01 ; G 4290 +U 11010 ; WX 838 ; N uni2B02 ; G 4291 +U 11011 ; WX 838 ; N uni2B03 ; G 4292 +U 11012 ; WX 838 ; N uni2B04 ; G 4293 +U 11013 ; WX 838 ; N uni2B05 ; G 4294 +U 11014 ; WX 838 ; N uni2B06 ; G 4295 +U 11015 ; WX 838 ; N uni2B07 ; G 4296 +U 11016 ; WX 838 ; N uni2B08 ; G 4297 +U 11017 ; WX 838 ; N uni2B09 ; G 4298 +U 11018 ; WX 838 ; N uni2B0A ; G 4299 +U 11019 ; WX 838 ; N uni2B0B ; G 4300 +U 11020 ; WX 838 ; N uni2B0C ; G 4301 +U 11021 ; WX 838 ; N uni2B0D ; G 4302 +U 11022 ; WX 838 ; N uni2B0E ; G 4303 +U 11023 ; WX 838 ; N uni2B0F ; G 4304 +U 11024 ; WX 838 ; N uni2B10 ; G 4305 +U 11025 ; WX 838 ; N uni2B11 ; G 4306 +U 11026 ; WX 945 ; N uni2B12 ; G 4307 +U 11027 ; WX 945 ; N uni2B13 ; G 4308 +U 11028 ; WX 945 ; N uni2B14 ; G 4309 +U 11029 ; WX 945 ; N uni2B15 ; G 4310 +U 11030 ; WX 769 ; N uni2B16 ; G 4311 +U 11031 ; WX 769 ; N uni2B17 ; G 4312 +U 11032 ; WX 769 ; N uni2B18 ; G 4313 +U 11033 ; WX 769 ; N uni2B19 ; G 4314 +U 11034 ; WX 945 ; N uni2B1A ; G 4315 +U 11039 ; WX 869 ; N uni2B1F ; G 4316 +U 11040 ; WX 869 ; N uni2B20 ; G 4317 +U 11041 ; WX 873 ; N uni2B21 ; G 4318 +U 11042 ; WX 873 ; N uni2B22 ; G 4319 +U 11043 ; WX 873 ; N uni2B23 ; G 4320 +U 11044 ; WX 1119 ; N uni2B24 ; G 4321 +U 11091 ; WX 869 ; N uni2B53 ; G 4322 +U 11092 ; WX 869 ; N uni2B54 ; G 4323 +U 11360 ; WX 637 ; N uni2C60 ; G 4324 +U 11361 ; WX 360 ; N uni2C61 ; G 4325 +U 11362 ; WX 637 ; N uni2C62 ; G 4326 +U 11363 ; WX 733 ; N uni2C63 ; G 4327 +U 11364 ; WX 770 ; N uni2C64 ; G 4328 +U 11365 ; WX 675 ; N uni2C65 ; G 4329 +U 11366 ; WX 478 ; N uni2C66 ; G 4330 +U 11367 ; WX 956 ; N uni2C67 ; G 4331 +U 11368 ; WX 712 ; N uni2C68 ; G 4332 +U 11369 ; WX 775 ; N uni2C69 ; G 4333 +U 11370 ; WX 665 ; N uni2C6A ; G 4334 +U 11371 ; WX 725 ; N uni2C6B ; G 4335 +U 11372 ; WX 582 ; N uni2C6C ; G 4336 +U 11373 ; WX 860 ; N uni2C6D ; G 4337 +U 11374 ; WX 995 ; N uni2C6E ; G 4338 +U 11375 ; WX 774 ; N uni2C6F ; G 4339 +U 11376 ; WX 860 ; N uni2C70 ; G 4340 +U 11377 ; WX 778 ; N uni2C71 ; G 4341 +U 11378 ; WX 1221 ; N uni2C72 ; G 4342 +U 11379 ; WX 1056 ; N uni2C73 ; G 4343 +U 11380 ; WX 652 ; N uni2C74 ; G 4344 +U 11381 ; WX 698 ; N uni2C75 ; G 4345 +U 11382 ; WX 565 ; N uni2C76 ; G 4346 +U 11383 ; WX 782 ; N uni2C77 ; G 4347 +U 11385 ; WX 538 ; N uni2C79 ; G 4348 +U 11386 ; WX 687 ; N uni2C7A ; G 4349 +U 11387 ; WX 559 ; N uni2C7B ; G 4350 +U 11388 ; WX 219 ; N uni2C7C ; G 4351 +U 11389 ; WX 487 ; N uni2C7D ; G 4352 +U 11390 ; WX 720 ; N uni2C7E ; G 4353 +U 11391 ; WX 725 ; N uni2C7F ; G 4354 +U 11520 ; WX 663 ; N uni2D00 ; G 4355 +U 11521 ; WX 676 ; N uni2D01 ; G 4356 +U 11522 ; WX 661 ; N uni2D02 ; G 4357 +U 11523 ; WX 629 ; N uni2D03 ; G 4358 +U 11524 ; WX 661 ; N uni2D04 ; G 4359 +U 11525 ; WX 1032 ; N uni2D05 ; G 4360 +U 11526 ; WX 718 ; N uni2D06 ; G 4361 +U 11527 ; WX 1032 ; N uni2D07 ; G 4362 +U 11528 ; WX 648 ; N uni2D08 ; G 4363 +U 11529 ; WX 667 ; N uni2D09 ; G 4364 +U 11530 ; WX 1032 ; N uni2D0A ; G 4365 +U 11531 ; WX 673 ; N uni2D0B ; G 4366 +U 11532 ; WX 677 ; N uni2D0C ; G 4367 +U 11533 ; WX 1036 ; N uni2D0D ; G 4368 +U 11534 ; WX 680 ; N uni2D0E ; G 4369 +U 11535 ; WX 886 ; N uni2D0F ; G 4370 +U 11536 ; WX 1032 ; N uni2D10 ; G 4371 +U 11537 ; WX 683 ; N uni2D11 ; G 4372 +U 11538 ; WX 674 ; N uni2D12 ; G 4373 +U 11539 ; WX 1035 ; N uni2D13 ; G 4374 +U 11540 ; WX 1033 ; N uni2D14 ; G 4375 +U 11541 ; WX 1027 ; N uni2D15 ; G 4376 +U 11542 ; WX 676 ; N uni2D16 ; G 4377 +U 11543 ; WX 673 ; N uni2D17 ; G 4378 +U 11544 ; WX 667 ; N uni2D18 ; G 4379 +U 11545 ; WX 667 ; N uni2D19 ; G 4380 +U 11546 ; WX 660 ; N uni2D1A ; G 4381 +U 11547 ; WX 671 ; N uni2D1B ; G 4382 +U 11548 ; WX 1039 ; N uni2D1C ; G 4383 +U 11549 ; WX 673 ; N uni2D1D ; G 4384 +U 11550 ; WX 692 ; N uni2D1E ; G 4385 +U 11551 ; WX 659 ; N uni2D1F ; G 4386 +U 11552 ; WX 1048 ; N uni2D20 ; G 4387 +U 11553 ; WX 660 ; N uni2D21 ; G 4388 +U 11554 ; WX 654 ; N uni2D22 ; G 4389 +U 11555 ; WX 670 ; N uni2D23 ; G 4390 +U 11556 ; WX 733 ; N uni2D24 ; G 4391 +U 11557 ; WX 1017 ; N uni2D25 ; G 4392 +U 11800 ; WX 580 ; N uni2E18 ; G 4393 +U 11807 ; WX 838 ; N uni2E1F ; G 4394 +U 11810 ; WX 457 ; N uni2E22 ; G 4395 +U 11811 ; WX 457 ; N uni2E23 ; G 4396 +U 11812 ; WX 457 ; N uni2E24 ; G 4397 +U 11813 ; WX 457 ; N uni2E25 ; G 4398 +U 11822 ; WX 580 ; N uni2E2E ; G 4399 +U 19904 ; WX 896 ; N uni4DC0 ; G 4400 +U 19905 ; WX 896 ; N uni4DC1 ; G 4401 +U 19906 ; WX 896 ; N uni4DC2 ; G 4402 +U 19907 ; WX 896 ; N uni4DC3 ; G 4403 +U 19908 ; WX 896 ; N uni4DC4 ; G 4404 +U 19909 ; WX 896 ; N uni4DC5 ; G 4405 +U 19910 ; WX 896 ; N uni4DC6 ; G 4406 +U 19911 ; WX 896 ; N uni4DC7 ; G 4407 +U 19912 ; WX 896 ; N uni4DC8 ; G 4408 +U 19913 ; WX 896 ; N uni4DC9 ; G 4409 +U 19914 ; WX 896 ; N uni4DCA ; G 4410 +U 19915 ; WX 896 ; N uni4DCB ; G 4411 +U 19916 ; WX 896 ; N uni4DCC ; G 4412 +U 19917 ; WX 896 ; N uni4DCD ; G 4413 +U 19918 ; WX 896 ; N uni4DCE ; G 4414 +U 19919 ; WX 896 ; N uni4DCF ; G 4415 +U 19920 ; WX 896 ; N uni4DD0 ; G 4416 +U 19921 ; WX 896 ; N uni4DD1 ; G 4417 +U 19922 ; WX 896 ; N uni4DD2 ; G 4418 +U 19923 ; WX 896 ; N uni4DD3 ; G 4419 +U 19924 ; WX 896 ; N uni4DD4 ; G 4420 +U 19925 ; WX 896 ; N uni4DD5 ; G 4421 +U 19926 ; WX 896 ; N uni4DD6 ; G 4422 +U 19927 ; WX 896 ; N uni4DD7 ; G 4423 +U 19928 ; WX 896 ; N uni4DD8 ; G 4424 +U 19929 ; WX 896 ; N uni4DD9 ; G 4425 +U 19930 ; WX 896 ; N uni4DDA ; G 4426 +U 19931 ; WX 896 ; N uni4DDB ; G 4427 +U 19932 ; WX 896 ; N uni4DDC ; G 4428 +U 19933 ; WX 896 ; N uni4DDD ; G 4429 +U 19934 ; WX 896 ; N uni4DDE ; G 4430 +U 19935 ; WX 896 ; N uni4DDF ; G 4431 +U 19936 ; WX 896 ; N uni4DE0 ; G 4432 +U 19937 ; WX 896 ; N uni4DE1 ; G 4433 +U 19938 ; WX 896 ; N uni4DE2 ; G 4434 +U 19939 ; WX 896 ; N uni4DE3 ; G 4435 +U 19940 ; WX 896 ; N uni4DE4 ; G 4436 +U 19941 ; WX 896 ; N uni4DE5 ; G 4437 +U 19942 ; WX 896 ; N uni4DE6 ; G 4438 +U 19943 ; WX 896 ; N uni4DE7 ; G 4439 +U 19944 ; WX 896 ; N uni4DE8 ; G 4440 +U 19945 ; WX 896 ; N uni4DE9 ; G 4441 +U 19946 ; WX 896 ; N uni4DEA ; G 4442 +U 19947 ; WX 896 ; N uni4DEB ; G 4443 +U 19948 ; WX 896 ; N uni4DEC ; G 4444 +U 19949 ; WX 896 ; N uni4DED ; G 4445 +U 19950 ; WX 896 ; N uni4DEE ; G 4446 +U 19951 ; WX 896 ; N uni4DEF ; G 4447 +U 19952 ; WX 896 ; N uni4DF0 ; G 4448 +U 19953 ; WX 896 ; N uni4DF1 ; G 4449 +U 19954 ; WX 896 ; N uni4DF2 ; G 4450 +U 19955 ; WX 896 ; N uni4DF3 ; G 4451 +U 19956 ; WX 896 ; N uni4DF4 ; G 4452 +U 19957 ; WX 896 ; N uni4DF5 ; G 4453 +U 19958 ; WX 896 ; N uni4DF6 ; G 4454 +U 19959 ; WX 896 ; N uni4DF7 ; G 4455 +U 19960 ; WX 896 ; N uni4DF8 ; G 4456 +U 19961 ; WX 896 ; N uni4DF9 ; G 4457 +U 19962 ; WX 896 ; N uni4DFA ; G 4458 +U 19963 ; WX 896 ; N uni4DFB ; G 4459 +U 19964 ; WX 896 ; N uni4DFC ; G 4460 +U 19965 ; WX 896 ; N uni4DFD ; G 4461 +U 19966 ; WX 896 ; N uni4DFE ; G 4462 +U 19967 ; WX 896 ; N uni4DFF ; G 4463 +U 42192 ; WX 762 ; N uniA4D0 ; G 4464 +U 42193 ; WX 733 ; N uniA4D1 ; G 4465 +U 42194 ; WX 733 ; N uniA4D2 ; G 4466 +U 42195 ; WX 830 ; N uniA4D3 ; G 4467 +U 42196 ; WX 682 ; N uniA4D4 ; G 4468 +U 42197 ; WX 682 ; N uniA4D5 ; G 4469 +U 42198 ; WX 821 ; N uniA4D6 ; G 4470 +U 42199 ; WX 775 ; N uniA4D7 ; G 4471 +U 42200 ; WX 775 ; N uniA4D8 ; G 4472 +U 42201 ; WX 530 ; N uniA4D9 ; G 4473 +U 42202 ; WX 734 ; N uniA4DA ; G 4474 +U 42203 ; WX 734 ; N uniA4DB ; G 4475 +U 42204 ; WX 725 ; N uniA4DC ; G 4476 +U 42205 ; WX 683 ; N uniA4DD ; G 4477 +U 42206 ; WX 683 ; N uniA4DE ; G 4478 +U 42207 ; WX 995 ; N uniA4DF ; G 4479 +U 42208 ; WX 837 ; N uniA4E0 ; G 4480 +U 42209 ; WX 637 ; N uniA4E1 ; G 4481 +U 42210 ; WX 720 ; N uniA4E2 ; G 4482 +U 42211 ; WX 770 ; N uniA4E3 ; G 4483 +U 42212 ; WX 770 ; N uniA4E4 ; G 4484 +U 42213 ; WX 774 ; N uniA4E5 ; G 4485 +U 42214 ; WX 774 ; N uniA4E6 ; G 4486 +U 42215 ; WX 837 ; N uniA4E7 ; G 4487 +U 42216 ; WX 786 ; N uniA4E8 ; G 4488 +U 42217 ; WX 530 ; N uniA4E9 ; G 4489 +U 42218 ; WX 1103 ; N uniA4EA ; G 4490 +U 42219 ; WX 771 ; N uniA4EB ; G 4491 +U 42220 ; WX 724 ; N uniA4EC ; G 4492 +U 42221 ; WX 762 ; N uniA4ED ; G 4493 +U 42222 ; WX 774 ; N uniA4EE ; G 4494 +U 42223 ; WX 774 ; N uniA4EF ; G 4495 +U 42224 ; WX 683 ; N uniA4F0 ; G 4496 +U 42225 ; WX 683 ; N uniA4F1 ; G 4497 +U 42226 ; WX 372 ; N uniA4F2 ; G 4498 +U 42227 ; WX 850 ; N uniA4F3 ; G 4499 +U 42228 ; WX 812 ; N uniA4F4 ; G 4500 +U 42229 ; WX 812 ; N uniA4F5 ; G 4501 +U 42230 ; WX 576 ; N uniA4F6 ; G 4502 +U 42231 ; WX 830 ; N uniA4F7 ; G 4503 +U 42232 ; WX 322 ; N uniA4F8 ; G 4504 +U 42233 ; WX 322 ; N uniA4F9 ; G 4505 +U 42234 ; WX 674 ; N uniA4FA ; G 4506 +U 42235 ; WX 674 ; N uniA4FB ; G 4507 +U 42236 ; WX 322 ; N uniA4FC ; G 4508 +U 42237 ; WX 322 ; N uniA4FD ; G 4509 +U 42238 ; WX 588 ; N uniA4FE ; G 4510 +U 42239 ; WX 588 ; N uniA4FF ; G 4511 +U 42564 ; WX 720 ; N uniA644 ; G 4512 +U 42565 ; WX 595 ; N uniA645 ; G 4513 +U 42566 ; WX 436 ; N uniA646 ; G 4514 +U 42567 ; WX 440 ; N uniA647 ; G 4515 +U 42572 ; WX 1405 ; N uniA64C ; G 4516 +U 42573 ; WX 1173 ; N uniA64D ; G 4517 +U 42576 ; WX 1234 ; N uniA650 ; G 4518 +U 42577 ; WX 1027 ; N uniA651 ; G 4519 +U 42580 ; WX 1174 ; N uniA654 ; G 4520 +U 42581 ; WX 972 ; N uniA655 ; G 4521 +U 42582 ; WX 1100 ; N uniA656 ; G 4522 +U 42583 ; WX 969 ; N uniA657 ; G 4523 +U 42594 ; WX 1100 ; N uniA662 ; G 4524 +U 42595 ; WX 940 ; N uniA663 ; G 4525 +U 42596 ; WX 1096 ; N uniA664 ; G 4526 +U 42597 ; WX 915 ; N uniA665 ; G 4527 +U 42598 ; WX 1260 ; N uniA666 ; G 4528 +U 42599 ; WX 997 ; N uniA667 ; G 4529 +U 42600 ; WX 850 ; N uniA668 ; G 4530 +U 42601 ; WX 687 ; N uniA669 ; G 4531 +U 42602 ; WX 1037 ; N uniA66A ; G 4532 +U 42603 ; WX 868 ; N uniA66B ; G 4533 +U 42604 ; WX 1406 ; N uniA66C ; G 4534 +U 42605 ; WX 1106 ; N uniA66D ; G 4535 +U 42606 ; WX 961 ; N uniA66E ; G 4536 +U 42634 ; WX 944 ; N uniA68A ; G 4537 +U 42635 ; WX 749 ; N uniA68B ; G 4538 +U 42636 ; WX 682 ; N uniA68C ; G 4539 +U 42637 ; WX 580 ; N uniA68D ; G 4540 +U 42644 ; WX 808 ; N uniA694 ; G 4541 +U 42645 ; WX 712 ; N uniA695 ; G 4542 +U 42648 ; WX 1406 ; N uniA698 ; G 4543 +U 42649 ; WX 1106 ; N uniA699 ; G 4544 +U 42760 ; WX 500 ; N uniA708 ; G 4545 +U 42761 ; WX 500 ; N uniA709 ; G 4546 +U 42762 ; WX 500 ; N uniA70A ; G 4547 +U 42763 ; WX 500 ; N uniA70B ; G 4548 +U 42764 ; WX 500 ; N uniA70C ; G 4549 +U 42765 ; WX 500 ; N uniA70D ; G 4550 +U 42766 ; WX 500 ; N uniA70E ; G 4551 +U 42767 ; WX 500 ; N uniA70F ; G 4552 +U 42768 ; WX 500 ; N uniA710 ; G 4553 +U 42769 ; WX 500 ; N uniA711 ; G 4554 +U 42770 ; WX 500 ; N uniA712 ; G 4555 +U 42771 ; WX 500 ; N uniA713 ; G 4556 +U 42772 ; WX 500 ; N uniA714 ; G 4557 +U 42773 ; WX 500 ; N uniA715 ; G 4558 +U 42774 ; WX 500 ; N uniA716 ; G 4559 +U 42779 ; WX 400 ; N uniA71B ; G 4560 +U 42780 ; WX 400 ; N uniA71C ; G 4561 +U 42781 ; WX 287 ; N uniA71D ; G 4562 +U 42782 ; WX 287 ; N uniA71E ; G 4563 +U 42783 ; WX 287 ; N uniA71F ; G 4564 +U 42786 ; WX 444 ; N uniA722 ; G 4565 +U 42787 ; WX 390 ; N uniA723 ; G 4566 +U 42788 ; WX 540 ; N uniA724 ; G 4567 +U 42789 ; WX 540 ; N uniA725 ; G 4568 +U 42790 ; WX 837 ; N uniA726 ; G 4569 +U 42791 ; WX 712 ; N uniA727 ; G 4570 +U 42792 ; WX 1031 ; N uniA728 ; G 4571 +U 42793 ; WX 857 ; N uniA729 ; G 4572 +U 42794 ; WX 696 ; N uniA72A ; G 4573 +U 42795 ; WX 557 ; N uniA72B ; G 4574 +U 42800 ; WX 559 ; N uniA730 ; G 4575 +U 42801 ; WX 595 ; N uniA731 ; G 4576 +U 42802 ; WX 1349 ; N uniA732 ; G 4577 +U 42803 ; WX 1052 ; N uniA733 ; G 4578 +U 42804 ; WX 1285 ; N uniA734 ; G 4579 +U 42805 ; WX 1065 ; N uniA735 ; G 4580 +U 42806 ; WX 1245 ; N uniA736 ; G 4581 +U 42807 ; WX 1052 ; N uniA737 ; G 4582 +U 42808 ; WX 1079 ; N uniA738 ; G 4583 +U 42809 ; WX 922 ; N uniA739 ; G 4584 +U 42810 ; WX 1079 ; N uniA73A ; G 4585 +U 42811 ; WX 922 ; N uniA73B ; G 4586 +U 42812 ; WX 1035 ; N uniA73C ; G 4587 +U 42813 ; WX 922 ; N uniA73D ; G 4588 +U 42814 ; WX 698 ; N uniA73E ; G 4589 +U 42815 ; WX 549 ; N uniA73F ; G 4590 +U 42816 ; WX 656 ; N uniA740 ; G 4591 +U 42817 ; WX 579 ; N uniA741 ; G 4592 +U 42822 ; WX 850 ; N uniA746 ; G 4593 +U 42823 ; WX 542 ; N uniA747 ; G 4594 +U 42824 ; WX 683 ; N uniA748 ; G 4595 +U 42825 ; WX 531 ; N uniA749 ; G 4596 +U 42826 ; WX 918 ; N uniA74A ; G 4597 +U 42827 ; WX 814 ; N uniA74B ; G 4598 +U 42830 ; WX 1406 ; N uniA74E ; G 4599 +U 42831 ; WX 1106 ; N uniA74F ; G 4600 +U 42832 ; WX 733 ; N uniA750 ; G 4601 +U 42833 ; WX 716 ; N uniA751 ; G 4602 +U 42834 ; WX 948 ; N uniA752 ; G 4603 +U 42835 ; WX 937 ; N uniA753 ; G 4604 +U 42838 ; WX 850 ; N uniA756 ; G 4605 +U 42839 ; WX 716 ; N uniA757 ; G 4606 +U 42852 ; WX 738 ; N uniA764 ; G 4607 +U 42853 ; WX 716 ; N uniA765 ; G 4608 +U 42854 ; WX 738 ; N uniA766 ; G 4609 +U 42855 ; WX 716 ; N uniA767 ; G 4610 +U 42880 ; WX 637 ; N uniA780 ; G 4611 +U 42881 ; WX 343 ; N uniA781 ; G 4612 +U 42882 ; WX 837 ; N uniA782 ; G 4613 +U 42883 ; WX 712 ; N uniA783 ; G 4614 +U 42889 ; WX 400 ; N uniA789 ; G 4615 +U 42890 ; WX 396 ; N uniA78A ; G 4616 +U 42891 ; WX 456 ; N uniA78B ; G 4617 +U 42892 ; WX 306 ; N uniA78C ; G 4618 +U 42893 ; WX 808 ; N uniA78D ; G 4619 +U 42894 ; WX 693 ; N uniA78E ; G 4620 +U 42896 ; WX 928 ; N uniA790 ; G 4621 +U 42897 ; WX 768 ; N uniA791 ; G 4622 +U 42912 ; WX 821 ; N uniA7A0 ; G 4623 +U 42913 ; WX 716 ; N uniA7A1 ; G 4624 +U 42914 ; WX 775 ; N uniA7A2 ; G 4625 +U 42915 ; WX 665 ; N uniA7A3 ; G 4626 +U 42916 ; WX 837 ; N uniA7A4 ; G 4627 +U 42917 ; WX 712 ; N uniA7A5 ; G 4628 +U 42918 ; WX 770 ; N uniA7A6 ; G 4629 +U 42919 ; WX 493 ; N uniA7A7 ; G 4630 +U 42920 ; WX 720 ; N uniA7A8 ; G 4631 +U 42921 ; WX 595 ; N uniA7A9 ; G 4632 +U 42922 ; WX 886 ; N uniA7AA ; G 4633 +U 43000 ; WX 613 ; N uniA7F8 ; G 4634 +U 43001 ; WX 689 ; N uniA7F9 ; G 4635 +U 43002 ; WX 1062 ; N uniA7FA ; G 4636 +U 43003 ; WX 683 ; N uniA7FB ; G 4637 +U 43004 ; WX 733 ; N uniA7FC ; G 4638 +U 43005 ; WX 995 ; N uniA7FD ; G 4639 +U 43006 ; WX 372 ; N uniA7FE ; G 4640 +U 43007 ; WX 1325 ; N uniA7FF ; G 4641 +U 61184 ; WX 216 ; N uni02E5.5 ; G 4642 +U 61185 ; WX 242 ; N uni02E6.5 ; G 4643 +U 61186 ; WX 267 ; N uni02E7.5 ; G 4644 +U 61187 ; WX 277 ; N uni02E8.5 ; G 4645 +U 61188 ; WX 282 ; N uni02E9.5 ; G 4646 +U 61189 ; WX 242 ; N uni02E5.4 ; G 4647 +U 61190 ; WX 216 ; N uni02E6.4 ; G 4648 +U 61191 ; WX 242 ; N uni02E7.4 ; G 4649 +U 61192 ; WX 267 ; N uni02E8.4 ; G 4650 +U 61193 ; WX 277 ; N uni02E9.4 ; G 4651 +U 61194 ; WX 267 ; N uni02E5.3 ; G 4652 +U 61195 ; WX 242 ; N uni02E6.3 ; G 4653 +U 61196 ; WX 216 ; N uni02E7.3 ; G 4654 +U 61197 ; WX 242 ; N uni02E8.3 ; G 4655 +U 61198 ; WX 267 ; N uni02E9.3 ; G 4656 +U 61199 ; WX 277 ; N uni02E5.2 ; G 4657 +U 61200 ; WX 267 ; N uni02E6.2 ; G 4658 +U 61201 ; WX 242 ; N uni02E7.2 ; G 4659 +U 61202 ; WX 216 ; N uni02E8.2 ; G 4660 +U 61203 ; WX 242 ; N uni02E9.2 ; G 4661 +U 61204 ; WX 282 ; N uni02E5.1 ; G 4662 +U 61205 ; WX 277 ; N uni02E6.1 ; G 4663 +U 61206 ; WX 267 ; N uni02E7.1 ; G 4664 +U 61207 ; WX 242 ; N uni02E8.1 ; G 4665 +U 61208 ; WX 216 ; N uni02E9.1 ; G 4666 +U 61209 ; WX 282 ; N stem ; G 4667 +U 62464 ; WX 612 ; N uniF400 ; G 4668 +U 62465 ; WX 612 ; N uniF401 ; G 4669 +U 62466 ; WX 653 ; N uniF402 ; G 4670 +U 62467 ; WX 902 ; N uniF403 ; G 4671 +U 62468 ; WX 617 ; N uniF404 ; G 4672 +U 62469 ; WX 617 ; N uniF405 ; G 4673 +U 62470 ; WX 680 ; N uniF406 ; G 4674 +U 62471 ; WX 904 ; N uniF407 ; G 4675 +U 62472 ; WX 599 ; N uniF408 ; G 4676 +U 62473 ; WX 617 ; N uniF409 ; G 4677 +U 62474 ; WX 1163 ; N uniF40A ; G 4678 +U 62475 ; WX 621 ; N uniF40B ; G 4679 +U 62476 ; WX 622 ; N uniF40C ; G 4680 +U 62477 ; WX 893 ; N uniF40D ; G 4681 +U 62478 ; WX 612 ; N uniF40E ; G 4682 +U 62479 ; WX 622 ; N uniF40F ; G 4683 +U 62480 ; WX 924 ; N uniF410 ; G 4684 +U 62481 ; WX 622 ; N uniF411 ; G 4685 +U 62482 ; WX 754 ; N uniF412 ; G 4686 +U 62483 ; WX 624 ; N uniF413 ; G 4687 +U 62484 ; WX 886 ; N uniF414 ; G 4688 +U 62485 ; WX 622 ; N uniF415 ; G 4689 +U 62486 ; WX 907 ; N uniF416 ; G 4690 +U 62487 ; WX 621 ; N uniF417 ; G 4691 +U 62488 ; WX 611 ; N uniF418 ; G 4692 +U 62489 ; WX 624 ; N uniF419 ; G 4693 +U 62490 ; WX 677 ; N uniF41A ; G 4694 +U 62491 ; WX 621 ; N uniF41B ; G 4695 +U 62492 ; WX 611 ; N uniF41C ; G 4696 +U 62493 ; WX 630 ; N uniF41D ; G 4697 +U 62494 ; WX 622 ; N uniF41E ; G 4698 +U 62495 ; WX 561 ; N uniF41F ; G 4699 +U 62496 ; WX 612 ; N uniF420 ; G 4700 +U 62497 ; WX 626 ; N uniF421 ; G 4701 +U 62498 ; WX 612 ; N uniF422 ; G 4702 +U 62499 ; WX 611 ; N uniF423 ; G 4703 +U 62500 ; WX 618 ; N uniF424 ; G 4704 +U 62501 ; WX 667 ; N uniF425 ; G 4705 +U 62502 ; WX 963 ; N uniF426 ; G 4706 +U 62504 ; WX 1023 ; N uniF428 ; G 4707 +U 62505 ; WX 844 ; N uniF429 ; G 4708 +U 62506 ; WX 563 ; N uniF42A ; G 4709 +U 62507 ; WX 563 ; N uniF42B ; G 4710 +U 62508 ; WX 563 ; N uniF42C ; G 4711 +U 62509 ; WX 563 ; N uniF42D ; G 4712 +U 62510 ; WX 563 ; N uniF42E ; G 4713 +U 62511 ; WX 563 ; N uniF42F ; G 4714 +U 62512 ; WX 555 ; N uniF430 ; G 4715 +U 62513 ; WX 555 ; N uniF431 ; G 4716 +U 62514 ; WX 555 ; N uniF432 ; G 4717 +U 62515 ; WX 555 ; N uniF433 ; G 4718 +U 62516 ; WX 573 ; N uniF434 ; G 4719 +U 62517 ; WX 573 ; N uniF435 ; G 4720 +U 62518 ; WX 573 ; N uniF436 ; G 4721 +U 62519 ; WX 824 ; N uniF437 ; G 4722 +U 62520 ; WX 824 ; N uniF438 ; G 4723 +U 62521 ; WX 824 ; N uniF439 ; G 4724 +U 62522 ; WX 824 ; N uniF43A ; G 4725 +U 62523 ; WX 824 ; N uniF43B ; G 4726 +U 62524 ; WX 611 ; N uniF43C ; G 4727 +U 62525 ; WX 611 ; N uniF43D ; G 4728 +U 62526 ; WX 611 ; N uniF43E ; G 4729 +U 62527 ; WX 611 ; N uniF43F ; G 4730 +U 62528 ; WX 611 ; N uniF440 ; G 4731 +U 62529 ; WX 611 ; N uniF441 ; G 4732 +U 62917 ; WX 687 ; N uniF5C5 ; G 4733 +U 64256 ; WX 833 ; N uniFB00 ; G 4734 +U 64257 ; WX 787 ; N fi ; G 4735 +U 64258 ; WX 787 ; N fl ; G 4736 +U 64259 ; WX 1138 ; N uniFB03 ; G 4737 +U 64260 ; WX 1139 ; N uniFB04 ; G 4738 +U 64261 ; WX 808 ; N uniFB05 ; G 4739 +U 64262 ; WX 1020 ; N uniFB06 ; G 4740 +U 64275 ; WX 1388 ; N uniFB13 ; G 4741 +U 64276 ; WX 1384 ; N uniFB14 ; G 4742 +U 64277 ; WX 1378 ; N uniFB15 ; G 4743 +U 64278 ; WX 1384 ; N uniFB16 ; G 4744 +U 64279 ; WX 1713 ; N uniFB17 ; G 4745 +U 64285 ; WX 294 ; N uniFB1D ; G 4746 +U 64286 ; WX 0 ; N uniFB1E ; G 4747 +U 64287 ; WX 663 ; N uniFB1F ; G 4748 +U 64288 ; WX 665 ; N uniFB20 ; G 4749 +U 64289 ; WX 939 ; N uniFB21 ; G 4750 +U 64290 ; WX 788 ; N uniFB22 ; G 4751 +U 64291 ; WX 920 ; N uniFB23 ; G 4752 +U 64292 ; WX 786 ; N uniFB24 ; G 4753 +U 64293 ; WX 857 ; N uniFB25 ; G 4754 +U 64294 ; WX 869 ; N uniFB26 ; G 4755 +U 64295 ; WX 821 ; N uniFB27 ; G 4756 +U 64296 ; WX 890 ; N uniFB28 ; G 4757 +U 64297 ; WX 838 ; N uniFB29 ; G 4758 +U 64298 ; WX 749 ; N uniFB2A ; G 4759 +U 64299 ; WX 749 ; N uniFB2B ; G 4760 +U 64300 ; WX 749 ; N uniFB2C ; G 4761 +U 64301 ; WX 749 ; N uniFB2D ; G 4762 +U 64302 ; WX 728 ; N uniFB2E ; G 4763 +U 64303 ; WX 728 ; N uniFB2F ; G 4764 +U 64304 ; WX 728 ; N uniFB30 ; G 4765 +U 64305 ; WX 610 ; N uniFB31 ; G 4766 +U 64306 ; WX 447 ; N uniFB32 ; G 4767 +U 64307 ; WX 588 ; N uniFB33 ; G 4768 +U 64308 ; WX 687 ; N uniFB34 ; G 4769 +U 64309 ; WX 343 ; N uniFB35 ; G 4770 +U 64310 ; WX 400 ; N uniFB36 ; G 4771 +U 64311 ; WX 1000 ; N uniFB37 ; G 4772 +U 64312 ; WX 679 ; N uniFB38 ; G 4773 +U 64313 ; WX 436 ; N uniFB39 ; G 4774 +U 64314 ; WX 578 ; N uniFB3A ; G 4775 +U 64315 ; WX 566 ; N uniFB3B ; G 4776 +U 64316 ; WX 605 ; N uniFB3C ; G 4777 +U 64317 ; WX 1000 ; N uniFB3D ; G 4778 +U 64318 ; WX 724 ; N uniFB3E ; G 4779 +U 64319 ; WX 1000 ; N uniFB3F ; G 4780 +U 64320 ; WX 453 ; N uniFB40 ; G 4781 +U 64321 ; WX 680 ; N uniFB41 ; G 4782 +U 64322 ; WX 1000 ; N uniFB42 ; G 4783 +U 64323 ; WX 675 ; N uniFB43 ; G 4784 +U 64324 ; WX 658 ; N uniFB44 ; G 4785 +U 64325 ; WX 1000 ; N uniFB45 ; G 4786 +U 64326 ; WX 653 ; N uniFB46 ; G 4787 +U 64327 ; WX 736 ; N uniFB47 ; G 4788 +U 64328 ; WX 602 ; N uniFB48 ; G 4789 +U 64329 ; WX 749 ; N uniFB49 ; G 4790 +U 64330 ; WX 683 ; N uniFB4A ; G 4791 +U 64331 ; WX 343 ; N uniFB4B ; G 4792 +U 64332 ; WX 610 ; N uniFB4C ; G 4793 +U 64333 ; WX 566 ; N uniFB4D ; G 4794 +U 64334 ; WX 658 ; N uniFB4E ; G 4795 +U 64335 ; WX 710 ; N uniFB4F ; G 4796 +U 65024 ; WX 0 ; N uniFE00 ; G 4797 +U 65025 ; WX 0 ; N uniFE01 ; G 4798 +U 65026 ; WX 0 ; N uniFE02 ; G 4799 +U 65027 ; WX 0 ; N uniFE03 ; G 4800 +U 65028 ; WX 0 ; N uniFE04 ; G 4801 +U 65029 ; WX 0 ; N uniFE05 ; G 4802 +U 65030 ; WX 0 ; N uniFE06 ; G 4803 +U 65031 ; WX 0 ; N uniFE07 ; G 4804 +U 65032 ; WX 0 ; N uniFE08 ; G 4805 +U 65033 ; WX 0 ; N uniFE09 ; G 4806 +U 65034 ; WX 0 ; N uniFE0A ; G 4807 +U 65035 ; WX 0 ; N uniFE0B ; G 4808 +U 65036 ; WX 0 ; N uniFE0C ; G 4809 +U 65037 ; WX 0 ; N uniFE0D ; G 4810 +U 65038 ; WX 0 ; N uniFE0E ; G 4811 +U 65039 ; WX 0 ; N uniFE0F ; G 4812 +U 65056 ; WX 0 ; N uniFE20 ; G 4813 +U 65057 ; WX 0 ; N uniFE21 ; G 4814 +U 65058 ; WX 0 ; N uniFE22 ; G 4815 +U 65059 ; WX 0 ; N uniFE23 ; G 4816 +U 65529 ; WX 0 ; N uniFFF9 ; G 4817 +U 65530 ; WX 0 ; N uniFFFA ; G 4818 +U 65531 ; WX 0 ; N uniFFFB ; G 4819 +U 65532 ; WX 0 ; N uniFFFC ; G 4820 +U 65533 ; WX 1113 ; N uniFFFD ; G 4821 +EndCharMetrics +StartKernData +StartKernPairs 1921 + +KPX dollar ampersand -63 +KPX dollar two -63 +KPX dollar seven -196 +KPX dollar eight -92 +KPX dollar nine -139 +KPX dollar colon -112 +KPX dollar less -235 +KPX dollar F -63 +KPX dollar G -63 +KPX dollar W -112 +KPX dollar Y -112 +KPX dollar Z -92 +KPX dollar backslash -149 +KPX dollar copyright -63 +KPX dollar questiondown -149 +KPX dollar Aacute -149 +KPX dollar Egrave -63 +KPX dollar Eacute -63 +KPX dollar Ecircumflex -63 +KPX dollar Edieresis -63 +KPX dollar Igrave -63 +KPX dollar Iacute -63 +KPX dollar Icircumflex -63 +KPX dollar Idieresis -63 +KPX dollar Ntilde -63 +KPX dollar Oacute -63 +KPX dollar Dcaron -63 +KPX dollar Dcroat -63 +KPX dollar Emacron -63 +KPX dollar Ebreve -63 +KPX dollar Hcircumflex -196 +KPX dollar hcircumflex -112 +KPX dollar Hbar -196 +KPX dollar hbar -112 +KPX dollar Imacron -92 +KPX dollar Ibreve -92 +KPX dollar Iogonek -92 +KPX dollar Idot -92 +KPX dollar IJ -92 +KPX dollar Jcircumflex -92 +KPX dollar Kcommaaccent -112 +KPX dollar kcommaaccent -92 +KPX dollar kgreenlandic -235 +KPX dollar Lacute -149 +KPX dollar lacute -235 +KPX dollar uni01AC -63 +KPX dollar uni01AE -63 +KPX dollar uni01DC -196 +KPX dollar uni01DD -112 +KPX dollar uni01F0 -63 +KPX dollar uni01F4 -235 +KPX dollar uni01F5 -149 + +KPX percent nine -83 +KPX percent colon -112 +KPX percent less -112 +KPX percent Kcommaaccent -112 +KPX percent kgreenlandic -112 +KPX percent lacute -112 +KPX percent uni01F4 -112 + +KPX ampersand six -73 +KPX ampersand Gcircumflex -73 +KPX ampersand Gbreve -73 +KPX ampersand Gdotaccent -73 +KPX ampersand Gcommaaccent -73 +KPX ampersand uni01DA -73 + +KPX quotesingle less -159 +KPX quotesingle kgreenlandic -159 +KPX quotesingle lacute -159 +KPX quotesingle uni01F4 -159 + +KPX parenright dollar -264 +KPX parenright D -235 +KPX parenright H -159 +KPX parenright R -159 +KPX parenright U -225 +KPX parenright X -196 +KPX parenright backslash -188 +KPX parenright cent -235 +KPX parenright sterling -235 +KPX parenright currency -235 +KPX parenright yen -235 +KPX parenright brokenbar -235 +KPX parenright section -235 +KPX parenright dieresis -235 +KPX parenright ordfeminine -159 +KPX parenright guillemotleft -159 +KPX parenright logicalnot -159 +KPX parenright sfthyphen -159 +KPX parenright acute -159 +KPX parenright mu -159 +KPX parenright paragraph -159 +KPX parenright periodcentered -159 +KPX parenright cedilla -159 +KPX parenright ordmasculine -159 +KPX parenright guillemotright -196 +KPX parenright onequarter -196 +KPX parenright onehalf -196 +KPX parenright threequarters -196 +KPX parenright questiondown -188 +KPX parenright Aacute -188 +KPX parenright Acircumflex -264 +KPX parenright Atilde -235 +KPX parenright Adieresis -264 +KPX parenright Aring -235 +KPX parenright AE -264 +KPX parenright Ccedilla -235 +KPX parenright Otilde -159 +KPX parenright multiply -159 +KPX parenright Ugrave -159 +KPX parenright Ucircumflex -159 +KPX parenright Yacute -159 +KPX parenright dcaron -159 +KPX parenright dmacron -159 +KPX parenright emacron -159 +KPX parenright ebreve -159 +KPX parenright edotaccent -225 +KPX parenright eogonek -225 +KPX parenright ecaron -225 +KPX parenright imacron -196 +KPX parenright ibreve -196 +KPX parenright iogonek -196 +KPX parenright dotlessi -196 +KPX parenright ij -196 +KPX parenright jcircumflex -196 +KPX parenright Lacute -188 +KPX parenright uni01A5 -235 +KPX parenright uni01AD -159 +KPX parenright Uhorn -159 +KPX parenright uni01F1 -159 +KPX parenright uni01F5 -188 + +KPX asterisk seven -36 +KPX asterisk less -83 +KPX asterisk Hbar -36 +KPX asterisk lacute -83 + +KPX period ampersand -131 +KPX period two -131 +KPX period eight -73 +KPX period colon -55 +KPX period H -112 +KPX period R -112 +KPX period X -112 +KPX period backslash -206 +KPX period ordfeminine -112 +KPX period guillemotleft -112 +KPX period logicalnot -112 +KPX period sfthyphen -112 +KPX period acute -112 +KPX period mu -112 +KPX period paragraph -112 +KPX period periodcentered -112 +KPX period cedilla -112 +KPX period ordmasculine -112 +KPX period guillemotright -112 +KPX period onequarter -112 +KPX period onehalf -112 +KPX period threequarters -112 +KPX period questiondown -206 +KPX period Aacute -206 +KPX period Egrave -131 +KPX period Icircumflex -131 +KPX period Yacute -112 +KPX period Ebreve -178 +KPX period ebreve -112 +KPX period Idot -73 +KPX period dotlessi -112 + +KPX slash two -73 +KPX slash seven -339 +KPX slash eight -112 +KPX slash nine -282 +KPX slash colon -178 +KPX slash less -319 +KPX slash backslash -253 +KPX slash questiondown -253 +KPX slash Aacute -253 +KPX slash Ebreve -73 +KPX slash Hbar -339 +KPX slash Idot -112 +KPX slash lacute -319 + +KPX two nine -73 +KPX two semicolon -73 +KPX two less -149 +KPX two lacute -149 + +KPX three dollar -188 +KPX three D -131 +KPX three H -55 +KPX three U -63 +KPX three V -73 +KPX three X -73 +KPX three cent -131 +KPX three sterling -131 +KPX three currency -131 +KPX three yen -131 +KPX three brokenbar -131 +KPX three section -131 +KPX three dieresis -131 +KPX three ordfeminine -55 +KPX three guillemotleft -55 +KPX three logicalnot -55 +KPX three sfthyphen -55 +KPX three guillemotright -73 +KPX three onequarter -73 +KPX three onehalf -73 +KPX three threequarters -73 +KPX three Yacute -55 +KPX three edotaccent -63 +KPX three ecaron -63 +KPX three gdotaccent -73 +KPX three gcommaaccent -73 +KPX three dotlessi -73 + + +KPX five seven -92 +KPX five less -188 +KPX five H -102 +KPX five R -102 +KPX five X -112 +KPX five backslash -131 +KPX five ordfeminine -102 +KPX five guillemotleft -102 +KPX five logicalnot -102 +KPX five sfthyphen -102 +KPX five acute -102 +KPX five mu -102 +KPX five paragraph -102 +KPX five periodcentered -102 +KPX five cedilla -102 +KPX five ordmasculine -102 +KPX five guillemotright -112 +KPX five onequarter -112 +KPX five onehalf -112 +KPX five threequarters -112 +KPX five questiondown -131 +KPX five Aacute -131 +KPX five Yacute -102 +KPX five ebreve -102 +KPX five Hbar -92 +KPX five dotlessi -112 +KPX five lacute -188 + +KPX six six -73 +KPX six Gdotaccent -73 +KPX six Gcommaaccent -73 + +KPX seven dollar -159 +KPX seven seven 47 +KPX seven D -243 +KPX seven F -264 +KPX seven H -264 +KPX seven R -264 +KPX seven U -225 +KPX seven V -243 +KPX seven X -264 +KPX seven Z -282 +KPX seven backslash -339 +KPX seven cent -243 +KPX seven sterling -243 +KPX seven currency -243 +KPX seven yen -243 +KPX seven brokenbar -243 +KPX seven section -243 +KPX seven dieresis -243 +KPX seven copyright -264 +KPX seven ordfeminine -264 +KPX seven guillemotleft -264 +KPX seven logicalnot -264 +KPX seven sfthyphen -264 +KPX seven acute -264 +KPX seven mu -264 +KPX seven paragraph -264 +KPX seven periodcentered -264 +KPX seven cedilla -264 +KPX seven ordmasculine -264 +KPX seven guillemotright -264 +KPX seven onequarter -264 +KPX seven onehalf -264 +KPX seven threequarters -264 +KPX seven questiondown -339 +KPX seven Aacute -339 +KPX seven Eacute -264 +KPX seven Idieresis -264 +KPX seven Yacute -264 +KPX seven ebreve -264 +KPX seven edotaccent -225 +KPX seven ecaron -225 +KPX seven gdotaccent -243 +KPX seven gcommaaccent -243 +KPX seven Hbar 47 +KPX seven dotlessi -264 + +KPX eight dollar -92 + +KPX nine dollar -139 +KPX nine two -36 +KPX nine D -159 +KPX nine H -149 +KPX nine L -36 +KPX nine R -149 +KPX nine X -149 +KPX nine cent -159 +KPX nine sterling -159 +KPX nine currency -159 +KPX nine yen -159 +KPX nine brokenbar -159 +KPX nine section -159 +KPX nine dieresis -159 +KPX nine ordfeminine -149 +KPX nine guillemotleft -149 +KPX nine logicalnot -149 +KPX nine sfthyphen -149 +KPX nine acute -149 +KPX nine mu -149 +KPX nine paragraph -149 +KPX nine periodcentered -149 +KPX nine cedilla -149 +KPX nine ordmasculine -149 +KPX nine guillemotright -149 +KPX nine onequarter -149 +KPX nine onehalf -149 +KPX nine threequarters -149 +KPX nine Yacute -149 +KPX nine Ebreve -45 +KPX nine ebreve -149 +KPX nine dotlessi -149 + +KPX colon dollar -73 +KPX colon D -139 +KPX colon H -131 +KPX colon R -112 +KPX colon U -120 +KPX colon cent -139 +KPX colon sterling -139 +KPX colon currency -139 +KPX colon yen -139 +KPX colon brokenbar -139 +KPX colon section -139 +KPX colon dieresis -139 +KPX colon ordfeminine -131 +KPX colon guillemotleft -131 +KPX colon logicalnot -131 +KPX colon sfthyphen -131 +KPX colon acute -112 +KPX colon mu -112 +KPX colon paragraph -112 +KPX colon periodcentered -112 +KPX colon cedilla -112 +KPX colon ordmasculine -112 +KPX colon Yacute -131 +KPX colon ebreve -112 +KPX colon edotaccent -120 +KPX colon ecaron -120 + +KPX semicolon ampersand -73 +KPX semicolon two -73 +KPX semicolon H -131 +KPX semicolon ordfeminine -131 +KPX semicolon guillemotleft -131 +KPX semicolon logicalnot -131 +KPX semicolon sfthyphen -131 +KPX semicolon Egrave -73 +KPX semicolon Icircumflex -73 +KPX semicolon Yacute -131 +KPX semicolon Ebreve -112 + +KPX less dollar -196 +KPX less ampersand -73 +KPX less two -73 +KPX less D -243 +KPX less H -264 +KPX less R -264 +KPX less X -225 +KPX less cent -243 +KPX less sterling -243 +KPX less currency -243 +KPX less yen -243 +KPX less brokenbar -243 +KPX less section -243 +KPX less dieresis -243 +KPX less ordfeminine -264 +KPX less guillemotleft -264 +KPX less logicalnot -264 +KPX less sfthyphen -264 +KPX less acute -264 +KPX less mu -264 +KPX less paragraph -264 +KPX less periodcentered -264 +KPX less cedilla -264 +KPX less ordmasculine -264 +KPX less guillemotright -225 +KPX less onequarter -225 +KPX less onehalf -225 +KPX less threequarters -225 +KPX less Egrave -73 +KPX less Icircumflex -73 +KPX less Yacute -264 +KPX less Ebreve -120 +KPX less ebreve -264 +KPX less dotlessi -225 + + +KPX D backslash -63 +KPX D questiondown -63 +KPX D Aacute -63 + + +KPX N H -73 +KPX N R -73 +KPX N ordfeminine -73 +KPX N guillemotleft -73 +KPX N logicalnot -73 +KPX N sfthyphen -73 +KPX N acute -73 +KPX N mu -73 +KPX N paragraph -73 +KPX N periodcentered -73 +KPX N cedilla -73 +KPX N ordmasculine -45 +KPX N Yacute -73 +KPX N ebreve -73 + + + + + +KPX cent backslash -63 +KPX cent questiondown -63 +KPX cent Aacute -63 + +KPX sterling backslash -63 +KPX sterling questiondown -63 +KPX sterling Aacute -63 + +KPX currency backslash -63 +KPX currency questiondown -63 +KPX currency Aacute -63 + +KPX yen backslash -63 +KPX yen questiondown -63 +KPX yen Aacute -63 + +KPX brokenbar backslash -63 +KPX brokenbar questiondown -63 +KPX brokenbar Aacute -63 + +KPX section backslash -63 +KPX section questiondown -63 +KPX section Aacute -63 + + + +KPX Acircumflex ampersand -63 +KPX Acircumflex two -63 +KPX Acircumflex seven -196 +KPX Acircumflex eight -92 +KPX Acircumflex nine -139 +KPX Acircumflex colon -112 +KPX Acircumflex less -235 +KPX Acircumflex F -63 +KPX Acircumflex G -63 +KPX Acircumflex W -112 +KPX Acircumflex Y -112 +KPX Acircumflex Z -92 +KPX Acircumflex backslash -149 +KPX Acircumflex copyright -63 +KPX Acircumflex questiondown -149 +KPX Acircumflex Aacute -149 +KPX Acircumflex Egrave -63 +KPX Acircumflex Eacute -63 +KPX Acircumflex Ecircumflex -63 +KPX Acircumflex Edieresis -63 +KPX Acircumflex Igrave -63 +KPX Acircumflex Iacute -63 +KPX Acircumflex Icircumflex -63 +KPX Acircumflex Idieresis -63 +KPX Acircumflex Ntilde -63 +KPX Acircumflex Oacute -63 +KPX Acircumflex Dcaron -63 +KPX Acircumflex Dcroat -63 +KPX Acircumflex Emacron -63 +KPX Acircumflex Ebreve -63 +KPX Acircumflex Hcircumflex -196 +KPX Acircumflex hcircumflex -112 +KPX Acircumflex Hbar -196 +KPX Acircumflex hbar -112 +KPX Acircumflex Imacron -92 +KPX Acircumflex Ibreve -92 +KPX Acircumflex Iogonek -92 +KPX Acircumflex Idot -92 +KPX Acircumflex IJ -92 +KPX Acircumflex Jcircumflex -92 +KPX Acircumflex Kcommaaccent -112 +KPX Acircumflex kcommaaccent -92 +KPX Acircumflex kgreenlandic -235 +KPX Acircumflex Lacute -149 +KPX Acircumflex lacute -235 +KPX Acircumflex uni01AC -63 +KPX Acircumflex uni01AE -63 +KPX Acircumflex uni01DC -196 +KPX Acircumflex uni01DD -112 +KPX Acircumflex uni01F0 -63 +KPX Acircumflex uni01F4 -235 +KPX Acircumflex uni01F5 -149 + +KPX Adieresis ampersand -63 +KPX Adieresis two -63 +KPX Adieresis seven -196 +KPX Adieresis eight -92 +KPX Adieresis nine -139 +KPX Adieresis colon -112 +KPX Adieresis less -235 +KPX Adieresis F -63 +KPX Adieresis G -63 +KPX Adieresis W -112 +KPX Adieresis Y -112 +KPX Adieresis Z -92 +KPX Adieresis backslash -149 +KPX Adieresis copyright -63 +KPX Adieresis questiondown -149 +KPX Adieresis Aacute -149 +KPX Adieresis Egrave -63 +KPX Adieresis Eacute -63 +KPX Adieresis Ecircumflex -63 +KPX Adieresis Edieresis -63 +KPX Adieresis Igrave -63 +KPX Adieresis Iacute -63 +KPX Adieresis Icircumflex -63 +KPX Adieresis Idieresis -63 +KPX Adieresis Ntilde -63 +KPX Adieresis Oacute -63 +KPX Adieresis Dcaron -63 +KPX Adieresis Dcroat -63 +KPX Adieresis Emacron -63 +KPX Adieresis Ebreve -63 +KPX Adieresis Hcircumflex -196 +KPX Adieresis hcircumflex -112 +KPX Adieresis Hbar -196 +KPX Adieresis hbar -112 +KPX Adieresis Imacron -92 +KPX Adieresis Ibreve -92 +KPX Adieresis Iogonek -92 +KPX Adieresis Idot -92 +KPX Adieresis IJ -92 +KPX Adieresis Jcircumflex -92 +KPX Adieresis Kcommaaccent -112 +KPX Adieresis kcommaaccent -92 +KPX Adieresis kgreenlandic -235 +KPX Adieresis Lacute -149 +KPX Adieresis lacute -235 +KPX Adieresis uni01AC -63 +KPX Adieresis uni01AE -63 +KPX Adieresis uni01DC -196 +KPX Adieresis uni01DD -112 +KPX Adieresis uni01F0 -63 +KPX Adieresis uni01F4 -235 +KPX Adieresis uni01F5 -149 + +KPX AE ampersand -63 +KPX AE two -63 +KPX AE seven -196 +KPX AE eight -92 +KPX AE nine -139 +KPX AE colon -112 +KPX AE less -235 +KPX AE F -63 +KPX AE G -63 +KPX AE W -112 +KPX AE Y -112 +KPX AE Z -92 +KPX AE backslash -149 +KPX AE copyright -63 +KPX AE questiondown -149 +KPX AE Aacute -149 +KPX AE Egrave -63 +KPX AE Eacute -63 +KPX AE Ecircumflex -63 +KPX AE Edieresis -63 +KPX AE Igrave -63 +KPX AE Iacute -63 +KPX AE Icircumflex -63 +KPX AE Idieresis -63 +KPX AE Ntilde -63 +KPX AE Oacute -63 +KPX AE Dcaron -63 +KPX AE Dcroat -63 +KPX AE Emacron -63 +KPX AE Ebreve -63 +KPX AE Hcircumflex -196 +KPX AE hcircumflex -112 +KPX AE Hbar -196 +KPX AE hbar -112 +KPX AE Imacron -92 +KPX AE Ibreve -92 +KPX AE Iogonek -92 +KPX AE Idot -92 +KPX AE IJ -92 +KPX AE Jcircumflex -92 +KPX AE Kcommaaccent -112 +KPX AE kcommaaccent -92 +KPX AE kgreenlandic -235 +KPX AE Lacute -149 +KPX AE lacute -235 +KPX AE uni01AC -63 +KPX AE uni01AE -63 +KPX AE uni01DC -196 +KPX AE uni01DD -112 +KPX AE uni01F0 -63 +KPX AE uni01F4 -235 +KPX AE uni01F5 -149 + +KPX Egrave six -73 +KPX Egrave Gcircumflex -73 +KPX Egrave Gbreve -73 +KPX Egrave Gdotaccent -73 +KPX Egrave Gcommaaccent -73 +KPX Egrave uni01DA -73 + +KPX Ecircumflex six -73 +KPX Ecircumflex Gcircumflex -73 +KPX Ecircumflex Gbreve -73 +KPX Ecircumflex Gdotaccent -73 +KPX Ecircumflex Gcommaaccent -73 +KPX Ecircumflex uni01DA -73 + +KPX Igrave six -73 +KPX Igrave Gcircumflex -73 +KPX Igrave Gbreve -73 +KPX Igrave Gdotaccent -73 +KPX Igrave Gcommaaccent -73 +KPX Igrave uni01DA -73 + +KPX Icircumflex six -73 +KPX Icircumflex Gcircumflex -73 +KPX Icircumflex Gbreve -73 +KPX Icircumflex Gdotaccent -73 +KPX Icircumflex Gcommaaccent -73 +KPX Icircumflex uni01DA -73 + +KPX Eth less -159 +KPX Eth kgreenlandic -159 +KPX Eth lacute -159 +KPX Eth uni01F4 -159 + +KPX Ograve less -159 +KPX Ograve kgreenlandic -159 +KPX Ograve lacute -159 +KPX Ograve uni01F4 -159 + +KPX agrave seven -36 +KPX agrave less -83 +KPX agrave Hbar -36 +KPX agrave lacute -83 + +KPX ucircumflex two -73 +KPX ucircumflex seven -339 +KPX ucircumflex eight -112 +KPX ucircumflex nine -282 +KPX ucircumflex colon -178 +KPX ucircumflex less -319 +KPX ucircumflex backslash -253 +KPX ucircumflex questiondown -253 +KPX ucircumflex Aacute -253 +KPX ucircumflex Ebreve -73 +KPX ucircumflex Hbar -339 +KPX ucircumflex Idot -112 +KPX ucircumflex lacute -319 + +KPX ydieresis two -73 +KPX ydieresis seven -339 +KPX ydieresis eight -112 +KPX ydieresis nine -282 +KPX ydieresis colon -178 +KPX ydieresis less -319 +KPX ydieresis backslash -253 +KPX ydieresis questiondown -253 +KPX ydieresis Aacute -253 +KPX ydieresis Ebreve -73 +KPX ydieresis Hbar -339 +KPX ydieresis Idot -112 +KPX ydieresis lacute -319 + +KPX Abreve O -8 + +KPX abreve two -73 +KPX abreve seven -339 +KPX abreve eight -73 +KPX abreve nine -282 +KPX abreve colon -159 +KPX abreve less -319 +KPX abreve backslash -253 +KPX abreve questiondown -253 +KPX abreve Aacute -253 +KPX abreve Ebreve -73 +KPX abreve Hbar -339 +KPX abreve Idot -73 +KPX abreve lacute -319 + +KPX Edotaccent seven -92 +KPX Edotaccent less -188 +KPX Edotaccent H -102 +KPX Edotaccent R -102 +KPX Edotaccent X -112 +KPX Edotaccent backslash -131 +KPX Edotaccent ordfeminine -102 +KPX Edotaccent guillemotleft -102 +KPX Edotaccent logicalnot -102 +KPX Edotaccent sfthyphen -102 +KPX Edotaccent acute -102 +KPX Edotaccent mu -102 +KPX Edotaccent paragraph -102 +KPX Edotaccent periodcentered -102 +KPX Edotaccent cedilla -102 +KPX Edotaccent ordmasculine -102 +KPX Edotaccent guillemotright -112 +KPX Edotaccent onequarter -112 +KPX Edotaccent onehalf -112 +KPX Edotaccent threequarters -112 +KPX Edotaccent questiondown -131 +KPX Edotaccent Aacute -131 +KPX Edotaccent Yacute -102 +KPX Edotaccent ebreve -102 +KPX Edotaccent Hbar -92 +KPX Edotaccent dotlessi -112 +KPX Edotaccent lacute -188 + + +KPX Ecaron seven -92 +KPX Ecaron less -188 +KPX Ecaron H -102 +KPX Ecaron R -102 +KPX Ecaron X -112 +KPX Ecaron backslash -131 +KPX Ecaron ordfeminine -102 +KPX Ecaron guillemotleft -102 +KPX Ecaron logicalnot -102 +KPX Ecaron sfthyphen -102 +KPX Ecaron acute -102 +KPX Ecaron mu -102 +KPX Ecaron paragraph -102 +KPX Ecaron periodcentered -102 +KPX Ecaron cedilla -102 +KPX Ecaron ordmasculine -102 +KPX Ecaron guillemotright -112 +KPX Ecaron onequarter -112 +KPX Ecaron onehalf -112 +KPX Ecaron threequarters -112 +KPX Ecaron questiondown -131 +KPX Ecaron Aacute -131 +KPX Ecaron Yacute -102 +KPX Ecaron ebreve -102 +KPX Ecaron Hbar -92 +KPX Ecaron dotlessi -112 +KPX Ecaron lacute -188 + + +KPX Gdotaccent six -73 +KPX Gdotaccent Gdotaccent -73 +KPX Gdotaccent Gcommaaccent -73 + +KPX Gcommaaccent six -73 +KPX Gcommaaccent Gdotaccent -73 +KPX Gcommaaccent Gcommaaccent -73 + +KPX Hbar dollar -159 +KPX Hbar seven 47 +KPX Hbar D -243 +KPX Hbar F -264 +KPX Hbar H -264 +KPX Hbar R -264 +KPX Hbar U -225 +KPX Hbar V -243 +KPX Hbar X -264 +KPX Hbar Z -282 +KPX Hbar backslash -339 +KPX Hbar cent -243 +KPX Hbar sterling -243 +KPX Hbar currency -243 +KPX Hbar yen -243 +KPX Hbar brokenbar -243 +KPX Hbar section -243 +KPX Hbar dieresis -243 +KPX Hbar copyright -264 +KPX Hbar ordfeminine -264 +KPX Hbar guillemotleft -264 +KPX Hbar logicalnot -264 +KPX Hbar sfthyphen -264 +KPX Hbar acute -264 +KPX Hbar mu -264 +KPX Hbar paragraph -264 +KPX Hbar periodcentered -264 +KPX Hbar cedilla -264 +KPX Hbar ordmasculine -264 +KPX Hbar guillemotright -264 +KPX Hbar onequarter -264 +KPX Hbar onehalf -264 +KPX Hbar threequarters -264 +KPX Hbar questiondown -339 +KPX Hbar Aacute -339 +KPX Hbar Eacute -264 +KPX Hbar Idieresis -264 +KPX Hbar Yacute -264 +KPX Hbar ebreve -264 +KPX Hbar edotaccent -225 +KPX Hbar ecaron -225 +KPX Hbar gdotaccent -243 +KPX Hbar gcommaaccent -243 +KPX Hbar Hbar 47 +KPX Hbar dotlessi -264 + +KPX hbar Hbar -112 + +KPX Idot dollar -92 +KPX Idot Idot -92 + +KPX lacute dollar -196 +KPX lacute ampersand -73 +KPX lacute two -73 +KPX lacute D -243 +KPX lacute H -264 +KPX lacute R -264 +KPX lacute X -225 +KPX lacute cent -243 +KPX lacute sterling -243 +KPX lacute currency -243 +KPX lacute yen -243 +KPX lacute brokenbar -243 +KPX lacute section -243 +KPX lacute dieresis -243 +KPX lacute ordfeminine -264 +KPX lacute guillemotleft -264 +KPX lacute logicalnot -264 +KPX lacute sfthyphen -264 +KPX lacute acute -264 +KPX lacute mu -264 +KPX lacute paragraph -264 +KPX lacute periodcentered -264 +KPX lacute cedilla -264 +KPX lacute ordmasculine -264 +KPX lacute guillemotright -225 +KPX lacute onequarter -225 +KPX lacute onehalf -225 +KPX lacute threequarters -225 +KPX lacute Egrave -73 +KPX lacute Icircumflex -73 +KPX lacute Yacute -264 +KPX lacute Ebreve -120 +KPX lacute ebreve -264 +KPX lacute dotlessi -225 + + +KPX uni027D dollar -272 +KPX uni027D hyphen -92 +KPX uni027D nine 38 +KPX uni027D less 75 +KPX uni027D lacute 75 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Oblique.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..999bac7714134bc7d931efac92b962a93c52e094 GIT binary patch literal 635416 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�+*O}A)8kc1kT~y3p^3P{xJ9j_0k?kAx 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�c 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

fI);V1&`p^P@z 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%0Dm&v@4taQGLT-zh3S`AeK1 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,GZiO*k^1+ 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


*Toc{%?n7Na{@W#kyM+}-t@ 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�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

_(y_@sc** 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 literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Bold.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Bold.ufm new file mode 100644 index 0000000..d598e20 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Bold.ufm @@ -0,0 +1,3285 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans Mono +FontSubfamily Bold +UniqueID DejaVu Sans Mono Bold +FullName DejaVu Sans Mono Bold +Version Version 2.37 +PostScriptName DejaVuSansMono-Bold +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +Weight Bold +ItalicAngle 0 +IsFixedPitch true +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -447 -394 731 1041 +StartCharMetrics 3316 +U 32 ; WX 602 ; N space ; G 3 +U 33 ; WX 602 ; N exclam ; G 4 +U 34 ; WX 602 ; N quotedbl ; G 5 +U 35 ; WX 602 ; N numbersign ; G 6 +U 36 ; WX 602 ; N dollar ; G 7 +U 37 ; WX 602 ; N percent ; G 8 +U 38 ; WX 602 ; N ampersand ; G 9 +U 39 ; WX 602 ; N quotesingle ; G 10 +U 40 ; WX 602 ; N parenleft ; G 11 +U 41 ; WX 602 ; N parenright ; G 12 +U 42 ; WX 602 ; N asterisk ; G 13 +U 43 ; WX 602 ; N plus ; G 14 +U 44 ; WX 602 ; N comma ; G 15 +U 45 ; WX 602 ; N hyphen ; G 16 +U 46 ; WX 602 ; N period ; G 17 +U 47 ; WX 602 ; N slash ; G 18 +U 48 ; WX 602 ; N zero ; G 19 +U 49 ; WX 602 ; N one ; G 20 +U 50 ; WX 602 ; N two ; G 21 +U 51 ; WX 602 ; N three ; G 22 +U 52 ; WX 602 ; N four ; G 23 +U 53 ; WX 602 ; N five ; G 24 +U 54 ; WX 602 ; N six ; G 25 +U 55 ; WX 602 ; N seven ; G 26 +U 56 ; WX 602 ; N eight ; G 27 +U 57 ; WX 602 ; N nine ; G 28 +U 58 ; WX 602 ; N colon ; G 29 +U 59 ; WX 602 ; N semicolon ; G 30 +U 60 ; WX 602 ; N less ; G 31 +U 61 ; WX 602 ; N equal ; G 32 +U 62 ; WX 602 ; N greater ; G 33 +U 63 ; WX 602 ; N question ; G 34 +U 64 ; WX 602 ; N at ; G 35 +U 65 ; WX 602 ; N A ; G 36 +U 66 ; WX 602 ; N B ; G 37 +U 67 ; WX 602 ; N C ; G 38 +U 68 ; WX 602 ; N D ; G 39 +U 69 ; WX 602 ; N E ; G 40 +U 70 ; WX 602 ; N F ; G 41 +U 71 ; WX 602 ; N G ; G 42 +U 72 ; WX 602 ; N H ; G 43 +U 73 ; WX 602 ; N I ; G 44 +U 74 ; WX 602 ; N J ; G 45 +U 75 ; WX 602 ; N K ; G 46 +U 76 ; WX 602 ; N L ; G 47 +U 77 ; WX 602 ; N M ; G 48 +U 78 ; WX 602 ; N N ; G 49 +U 79 ; WX 602 ; N O ; G 50 +U 80 ; WX 602 ; N P ; G 51 +U 81 ; WX 602 ; N Q ; G 52 +U 82 ; WX 602 ; N R ; G 53 +U 83 ; WX 602 ; N S ; G 54 +U 84 ; WX 602 ; N T ; G 55 +U 85 ; WX 602 ; N U ; G 56 +U 86 ; WX 602 ; N V ; G 57 +U 87 ; WX 602 ; N W ; G 58 +U 88 ; WX 602 ; N X ; G 59 +U 89 ; WX 602 ; N Y ; G 60 +U 90 ; WX 602 ; N Z ; G 61 +U 91 ; WX 602 ; N bracketleft ; G 62 +U 92 ; WX 602 ; N backslash ; G 63 +U 93 ; WX 602 ; N bracketright ; G 64 +U 94 ; WX 602 ; N asciicircum ; G 65 +U 95 ; WX 602 ; N underscore ; G 66 +U 96 ; WX 602 ; N grave ; G 67 +U 97 ; WX 602 ; N a ; G 68 +U 98 ; WX 602 ; N b ; G 69 +U 99 ; WX 602 ; N c ; G 70 +U 100 ; WX 602 ; N d ; G 71 +U 101 ; WX 602 ; N e ; G 72 +U 102 ; WX 602 ; N f ; G 73 +U 103 ; WX 602 ; N g ; G 74 +U 104 ; WX 602 ; N h ; G 75 +U 105 ; WX 602 ; N i ; G 76 +U 106 ; WX 602 ; N j ; G 77 +U 107 ; WX 602 ; N k ; G 78 +U 108 ; WX 602 ; N l ; G 79 +U 109 ; WX 602 ; N m ; G 80 +U 110 ; WX 602 ; N n ; G 81 +U 111 ; WX 602 ; N o ; G 82 +U 112 ; WX 602 ; N p ; G 83 +U 113 ; WX 602 ; N q ; G 84 +U 114 ; WX 602 ; N r ; G 85 +U 115 ; WX 602 ; N s ; G 86 +U 116 ; WX 602 ; N t ; G 87 +U 117 ; WX 602 ; N u ; G 88 +U 118 ; WX 602 ; N v ; G 89 +U 119 ; WX 602 ; N w ; G 90 +U 120 ; WX 602 ; N x ; G 91 +U 121 ; WX 602 ; N y ; G 92 +U 122 ; WX 602 ; N z ; G 93 +U 123 ; WX 602 ; N braceleft ; G 94 +U 124 ; WX 602 ; N bar ; G 95 +U 125 ; WX 602 ; N braceright ; G 96 +U 126 ; WX 602 ; N asciitilde ; G 97 +U 160 ; WX 602 ; N nbspace ; G 98 +U 161 ; WX 602 ; N exclamdown ; G 99 +U 162 ; WX 602 ; N cent ; G 100 +U 163 ; WX 602 ; N sterling ; G 101 +U 164 ; WX 602 ; N currency ; G 102 +U 165 ; WX 602 ; N yen ; G 103 +U 166 ; WX 602 ; N brokenbar ; G 104 +U 167 ; WX 602 ; N section ; G 105 +U 168 ; WX 602 ; N dieresis ; G 106 +U 169 ; WX 602 ; N copyright ; G 107 +U 170 ; WX 602 ; N ordfeminine ; G 108 +U 171 ; WX 602 ; N guillemotleft ; G 109 +U 172 ; WX 602 ; N logicalnot ; G 110 +U 173 ; WX 602 ; N sfthyphen ; G 111 +U 174 ; WX 602 ; N registered ; G 112 +U 175 ; WX 602 ; N macron ; G 113 +U 176 ; WX 602 ; N degree ; G 114 +U 177 ; WX 602 ; N plusminus ; G 115 +U 178 ; WX 602 ; N twosuperior ; G 116 +U 179 ; WX 602 ; N threesuperior ; G 117 +U 180 ; WX 602 ; N acute ; G 118 +U 181 ; WX 602 ; N mu ; G 119 +U 182 ; WX 602 ; N paragraph ; G 120 +U 183 ; WX 602 ; N periodcentered ; G 121 +U 184 ; WX 602 ; N cedilla ; G 122 +U 185 ; WX 602 ; N onesuperior ; G 123 +U 186 ; WX 602 ; N ordmasculine ; G 124 +U 187 ; WX 602 ; N guillemotright ; G 125 +U 188 ; WX 602 ; N onequarter ; G 126 +U 189 ; WX 602 ; N onehalf ; G 127 +U 190 ; WX 602 ; N threequarters ; G 128 +U 191 ; WX 602 ; N questiondown ; G 129 +U 192 ; WX 602 ; N Agrave ; G 130 +U 193 ; WX 602 ; N Aacute ; G 131 +U 194 ; WX 602 ; N Acircumflex ; G 132 +U 195 ; WX 602 ; N Atilde ; G 133 +U 196 ; WX 602 ; N Adieresis ; G 134 +U 197 ; WX 602 ; N Aring ; G 135 +U 198 ; WX 602 ; N AE ; G 136 +U 199 ; WX 602 ; N Ccedilla ; G 137 +U 200 ; WX 602 ; N Egrave ; G 138 +U 201 ; WX 602 ; N Eacute ; G 139 +U 202 ; WX 602 ; N Ecircumflex ; G 140 +U 203 ; WX 602 ; N Edieresis ; G 141 +U 204 ; WX 602 ; N Igrave ; G 142 +U 205 ; WX 602 ; N Iacute ; G 143 +U 206 ; WX 602 ; N Icircumflex ; G 144 +U 207 ; WX 602 ; N Idieresis ; G 145 +U 208 ; WX 602 ; N Eth ; G 146 +U 209 ; WX 602 ; N Ntilde ; G 147 +U 210 ; WX 602 ; N Ograve ; G 148 +U 211 ; WX 602 ; N Oacute ; G 149 +U 212 ; WX 602 ; N Ocircumflex ; G 150 +U 213 ; WX 602 ; N Otilde ; G 151 +U 214 ; WX 602 ; N Odieresis ; G 152 +U 215 ; WX 602 ; N multiply ; G 153 +U 216 ; WX 602 ; N Oslash ; G 154 +U 217 ; WX 602 ; N Ugrave ; G 155 +U 218 ; WX 602 ; N Uacute ; G 156 +U 219 ; WX 602 ; N Ucircumflex ; G 157 +U 220 ; WX 602 ; N Udieresis ; G 158 +U 221 ; WX 602 ; N Yacute ; G 159 +U 222 ; WX 602 ; N Thorn ; G 160 +U 223 ; WX 602 ; N germandbls ; G 161 +U 224 ; WX 602 ; N agrave ; G 162 +U 225 ; WX 602 ; N aacute ; G 163 +U 226 ; WX 602 ; N acircumflex ; G 164 +U 227 ; WX 602 ; N atilde ; G 165 +U 228 ; WX 602 ; N adieresis ; G 166 +U 229 ; WX 602 ; N aring ; G 167 +U 230 ; WX 602 ; N ae ; G 168 +U 231 ; WX 602 ; N ccedilla ; G 169 +U 232 ; WX 602 ; N egrave ; G 170 +U 233 ; WX 602 ; N eacute ; G 171 +U 234 ; WX 602 ; N ecircumflex ; G 172 +U 235 ; WX 602 ; N edieresis ; G 173 +U 236 ; WX 602 ; N igrave ; G 174 +U 237 ; WX 602 ; N iacute ; G 175 +U 238 ; WX 602 ; N icircumflex ; G 176 +U 239 ; WX 602 ; N idieresis ; G 177 +U 240 ; WX 602 ; N eth ; G 178 +U 241 ; WX 602 ; N ntilde ; G 179 +U 242 ; WX 602 ; N ograve ; G 180 +U 243 ; WX 602 ; N oacute ; G 181 +U 244 ; WX 602 ; N ocircumflex ; G 182 +U 245 ; WX 602 ; N otilde ; G 183 +U 246 ; WX 602 ; N odieresis ; G 184 +U 247 ; WX 602 ; N divide ; G 185 +U 248 ; WX 602 ; N oslash ; G 186 +U 249 ; WX 602 ; N ugrave ; G 187 +U 250 ; WX 602 ; N uacute ; G 188 +U 251 ; WX 602 ; N ucircumflex ; G 189 +U 252 ; WX 602 ; N udieresis ; G 190 +U 253 ; WX 602 ; N yacute ; G 191 +U 254 ; WX 602 ; N thorn ; G 192 +U 255 ; WX 602 ; N ydieresis ; G 193 +U 256 ; WX 602 ; N Amacron ; G 194 +U 257 ; WX 602 ; N amacron ; G 195 +U 258 ; WX 602 ; N Abreve ; G 196 +U 259 ; WX 602 ; N abreve ; G 197 +U 260 ; WX 602 ; N Aogonek ; G 198 +U 261 ; WX 602 ; N aogonek ; G 199 +U 262 ; WX 602 ; N Cacute ; G 200 +U 263 ; WX 602 ; N cacute ; G 201 +U 264 ; WX 602 ; N Ccircumflex ; G 202 +U 265 ; WX 602 ; N ccircumflex ; G 203 +U 266 ; WX 602 ; N Cdotaccent ; G 204 +U 267 ; WX 602 ; N cdotaccent ; G 205 +U 268 ; WX 602 ; N Ccaron ; G 206 +U 269 ; WX 602 ; N ccaron ; G 207 +U 270 ; WX 602 ; N Dcaron ; G 208 +U 271 ; WX 602 ; N dcaron ; G 209 +U 272 ; WX 602 ; N Dcroat ; G 210 +U 273 ; WX 602 ; N dmacron ; G 211 +U 274 ; WX 602 ; N Emacron ; G 212 +U 275 ; WX 602 ; N emacron ; G 213 +U 276 ; WX 602 ; N Ebreve ; G 214 +U 277 ; WX 602 ; N ebreve ; G 215 +U 278 ; WX 602 ; N Edotaccent ; G 216 +U 279 ; WX 602 ; N edotaccent ; G 217 +U 280 ; WX 602 ; N Eogonek ; G 218 +U 281 ; WX 602 ; N eogonek ; G 219 +U 282 ; WX 602 ; N Ecaron ; G 220 +U 283 ; WX 602 ; N ecaron ; G 221 +U 284 ; WX 602 ; N Gcircumflex ; G 222 +U 285 ; WX 602 ; N gcircumflex ; G 223 +U 286 ; WX 602 ; N Gbreve ; G 224 +U 287 ; WX 602 ; N gbreve ; G 225 +U 288 ; WX 602 ; N Gdotaccent ; G 226 +U 289 ; WX 602 ; N gdotaccent ; G 227 +U 290 ; WX 602 ; N Gcommaaccent ; G 228 +U 291 ; WX 602 ; N gcommaaccent ; G 229 +U 292 ; WX 602 ; N Hcircumflex ; G 230 +U 293 ; WX 602 ; N hcircumflex ; G 231 +U 294 ; WX 602 ; N Hbar ; G 232 +U 295 ; WX 602 ; N hbar ; G 233 +U 296 ; WX 602 ; N Itilde ; G 234 +U 297 ; WX 602 ; N itilde ; G 235 +U 298 ; WX 602 ; N Imacron ; G 236 +U 299 ; WX 602 ; N imacron ; G 237 +U 300 ; WX 602 ; N Ibreve ; G 238 +U 301 ; WX 602 ; N ibreve ; G 239 +U 302 ; WX 602 ; N Iogonek ; G 240 +U 303 ; WX 602 ; N iogonek ; G 241 +U 304 ; WX 602 ; N Idot ; G 242 +U 305 ; WX 602 ; N dotlessi ; G 243 +U 306 ; WX 602 ; N IJ ; G 244 +U 307 ; WX 602 ; N ij ; G 245 +U 308 ; WX 602 ; N Jcircumflex ; G 246 +U 309 ; WX 602 ; N jcircumflex ; G 247 +U 310 ; WX 602 ; N Kcommaaccent ; G 248 +U 311 ; WX 602 ; N kcommaaccent ; G 249 +U 312 ; WX 602 ; N kgreenlandic ; G 250 +U 313 ; WX 602 ; N Lacute ; G 251 +U 314 ; WX 602 ; N lacute ; G 252 +U 315 ; WX 602 ; N Lcommaaccent ; G 253 +U 316 ; WX 602 ; N lcommaaccent ; G 254 +U 317 ; WX 602 ; N Lcaron ; G 255 +U 318 ; WX 602 ; N lcaron ; G 256 +U 319 ; WX 602 ; N Ldot ; G 257 +U 320 ; WX 602 ; N ldot ; G 258 +U 321 ; WX 602 ; N Lslash ; G 259 +U 322 ; WX 602 ; N lslash ; G 260 +U 323 ; WX 602 ; N Nacute ; G 261 +U 324 ; WX 602 ; N nacute ; G 262 +U 325 ; WX 602 ; N Ncommaaccent ; G 263 +U 326 ; WX 602 ; N ncommaaccent ; G 264 +U 327 ; WX 602 ; N Ncaron ; G 265 +U 328 ; WX 602 ; N ncaron ; G 266 +U 329 ; WX 602 ; N napostrophe ; G 267 +U 330 ; WX 602 ; N Eng ; G 268 +U 331 ; WX 602 ; N eng ; G 269 +U 332 ; WX 602 ; N Omacron ; G 270 +U 333 ; WX 602 ; N omacron ; G 271 +U 334 ; WX 602 ; N Obreve ; G 272 +U 335 ; WX 602 ; N obreve ; G 273 +U 336 ; WX 602 ; N Ohungarumlaut ; G 274 +U 337 ; WX 602 ; N ohungarumlaut ; G 275 +U 338 ; WX 602 ; N OE ; G 276 +U 339 ; WX 602 ; N oe ; G 277 +U 340 ; WX 602 ; N Racute ; G 278 +U 341 ; WX 602 ; N racute ; G 279 +U 342 ; WX 602 ; N Rcommaaccent ; G 280 +U 343 ; WX 602 ; N rcommaaccent ; G 281 +U 344 ; WX 602 ; N Rcaron ; G 282 +U 345 ; WX 602 ; N rcaron ; G 283 +U 346 ; WX 602 ; N Sacute ; G 284 +U 347 ; WX 602 ; N sacute ; G 285 +U 348 ; WX 602 ; N Scircumflex ; G 286 +U 349 ; WX 602 ; N scircumflex ; G 287 +U 350 ; WX 602 ; N Scedilla ; G 288 +U 351 ; WX 602 ; N scedilla ; G 289 +U 352 ; WX 602 ; N Scaron ; G 290 +U 353 ; WX 602 ; N scaron ; G 291 +U 354 ; WX 602 ; N Tcommaaccent ; G 292 +U 355 ; WX 602 ; N tcommaaccent ; G 293 +U 356 ; WX 602 ; N Tcaron ; G 294 +U 357 ; WX 602 ; N tcaron ; G 295 +U 358 ; WX 602 ; N Tbar ; G 296 +U 359 ; WX 602 ; N tbar ; G 297 +U 360 ; WX 602 ; N Utilde ; G 298 +U 361 ; WX 602 ; N utilde ; G 299 +U 362 ; WX 602 ; N Umacron ; G 300 +U 363 ; WX 602 ; N umacron ; G 301 +U 364 ; WX 602 ; N Ubreve ; G 302 +U 365 ; WX 602 ; N ubreve ; G 303 +U 366 ; WX 602 ; N Uring ; G 304 +U 367 ; WX 602 ; N uring ; G 305 +U 368 ; WX 602 ; N Uhungarumlaut ; G 306 +U 369 ; WX 602 ; N uhungarumlaut ; G 307 +U 370 ; WX 602 ; N Uogonek ; G 308 +U 371 ; WX 602 ; N uogonek ; G 309 +U 372 ; WX 602 ; N Wcircumflex ; G 310 +U 373 ; WX 602 ; N wcircumflex ; G 311 +U 374 ; WX 602 ; N Ycircumflex ; G 312 +U 375 ; WX 602 ; N ycircumflex ; G 313 +U 376 ; WX 602 ; N Ydieresis ; G 314 +U 377 ; WX 602 ; N Zacute ; G 315 +U 378 ; WX 602 ; N zacute ; G 316 +U 379 ; WX 602 ; N Zdotaccent ; G 317 +U 380 ; WX 602 ; N zdotaccent ; G 318 +U 381 ; WX 602 ; N Zcaron ; G 319 +U 382 ; WX 602 ; N zcaron ; G 320 +U 383 ; WX 602 ; N longs ; G 321 +U 384 ; WX 602 ; N uni0180 ; G 322 +U 385 ; WX 602 ; N uni0181 ; G 323 +U 386 ; WX 602 ; N uni0182 ; G 324 +U 387 ; WX 602 ; N uni0183 ; G 325 +U 388 ; WX 602 ; N uni0184 ; G 326 +U 389 ; WX 602 ; N uni0185 ; G 327 +U 390 ; WX 602 ; N uni0186 ; G 328 +U 391 ; WX 602 ; N uni0187 ; G 329 +U 392 ; WX 602 ; N uni0188 ; G 330 +U 393 ; WX 602 ; N uni0189 ; G 331 +U 394 ; WX 602 ; N uni018A ; G 332 +U 395 ; WX 602 ; N uni018B ; G 333 +U 396 ; WX 602 ; N uni018C ; G 334 +U 397 ; WX 602 ; N uni018D ; G 335 +U 398 ; WX 602 ; N uni018E ; G 336 +U 399 ; WX 602 ; N uni018F ; G 337 +U 400 ; WX 602 ; N uni0190 ; G 338 +U 401 ; WX 602 ; N uni0191 ; G 339 +U 402 ; WX 602 ; N florin ; G 340 +U 403 ; WX 602 ; N uni0193 ; G 341 +U 404 ; WX 602 ; N uni0194 ; G 342 +U 405 ; WX 602 ; N uni0195 ; G 343 +U 406 ; WX 602 ; N uni0196 ; G 344 +U 407 ; WX 602 ; N uni0197 ; G 345 +U 408 ; WX 602 ; N uni0198 ; G 346 +U 409 ; WX 602 ; N uni0199 ; G 347 +U 410 ; WX 602 ; N uni019A ; G 348 +U 411 ; WX 602 ; N uni019B ; G 349 +U 412 ; WX 602 ; N uni019C ; G 350 +U 413 ; WX 602 ; N uni019D ; G 351 +U 414 ; WX 602 ; N uni019E ; G 352 +U 415 ; WX 602 ; N uni019F ; G 353 +U 416 ; WX 602 ; N Ohorn ; G 354 +U 417 ; WX 602 ; N ohorn ; G 355 +U 418 ; WX 602 ; N uni01A2 ; G 356 +U 419 ; WX 602 ; N uni01A3 ; G 357 +U 420 ; WX 602 ; N uni01A4 ; G 358 +U 421 ; WX 602 ; N uni01A5 ; G 359 +U 422 ; WX 602 ; N uni01A6 ; G 360 +U 423 ; WX 602 ; N uni01A7 ; G 361 +U 424 ; WX 602 ; N uni01A8 ; G 362 +U 425 ; WX 602 ; N uni01A9 ; G 363 +U 426 ; WX 602 ; N uni01AA ; G 364 +U 427 ; WX 602 ; N uni01AB ; G 365 +U 428 ; WX 602 ; N uni01AC ; G 366 +U 429 ; WX 602 ; N uni01AD ; G 367 +U 430 ; WX 602 ; N uni01AE ; G 368 +U 431 ; WX 602 ; N Uhorn ; G 369 +U 432 ; WX 602 ; N uhorn ; G 370 +U 433 ; WX 602 ; N uni01B1 ; G 371 +U 434 ; WX 602 ; N uni01B2 ; G 372 +U 435 ; WX 602 ; N uni01B3 ; G 373 +U 436 ; WX 602 ; N uni01B4 ; G 374 +U 437 ; WX 602 ; N uni01B5 ; G 375 +U 438 ; WX 602 ; N uni01B6 ; G 376 +U 439 ; WX 602 ; N uni01B7 ; G 377 +U 440 ; WX 602 ; N uni01B8 ; G 378 +U 441 ; WX 602 ; N uni01B9 ; G 379 +U 442 ; WX 602 ; N uni01BA ; G 380 +U 443 ; WX 602 ; N uni01BB ; G 381 +U 444 ; WX 602 ; N uni01BC ; G 382 +U 445 ; WX 602 ; N uni01BD ; G 383 +U 446 ; WX 602 ; N uni01BE ; G 384 +U 447 ; WX 602 ; N uni01BF ; G 385 +U 448 ; WX 602 ; N uni01C0 ; G 386 +U 449 ; WX 602 ; N uni01C1 ; G 387 +U 450 ; WX 602 ; N uni01C2 ; G 388 +U 451 ; WX 602 ; N uni01C3 ; G 389 +U 461 ; WX 602 ; N uni01CD ; G 390 +U 462 ; WX 602 ; N uni01CE ; G 391 +U 463 ; WX 602 ; N uni01CF ; G 392 +U 464 ; WX 602 ; N uni01D0 ; G 393 +U 465 ; WX 602 ; N uni01D1 ; G 394 +U 466 ; WX 602 ; N uni01D2 ; G 395 +U 467 ; WX 602 ; N uni01D3 ; G 396 +U 468 ; WX 602 ; N uni01D4 ; G 397 +U 469 ; WX 602 ; N uni01D5 ; G 398 +U 470 ; WX 602 ; N uni01D6 ; G 399 +U 471 ; WX 602 ; N uni01D7 ; G 400 +U 472 ; WX 602 ; N uni01D8 ; G 401 +U 473 ; WX 602 ; N uni01D9 ; G 402 +U 474 ; WX 602 ; N uni01DA ; G 403 +U 475 ; WX 602 ; N uni01DB ; G 404 +U 476 ; WX 602 ; N uni01DC ; G 405 +U 477 ; WX 602 ; N uni01DD ; G 406 +U 478 ; WX 602 ; N uni01DE ; G 407 +U 479 ; WX 602 ; N uni01DF ; G 408 +U 480 ; WX 602 ; N uni01E0 ; G 409 +U 481 ; WX 602 ; N uni01E1 ; G 410 +U 482 ; WX 602 ; N uni01E2 ; G 411 +U 483 ; WX 602 ; N uni01E3 ; G 412 +U 486 ; WX 602 ; N Gcaron ; G 413 +U 487 ; WX 602 ; N gcaron ; G 414 +U 488 ; WX 602 ; N uni01E8 ; G 415 +U 489 ; WX 602 ; N uni01E9 ; G 416 +U 490 ; WX 602 ; N uni01EA ; G 417 +U 491 ; WX 602 ; N uni01EB ; G 418 +U 492 ; WX 602 ; N uni01EC ; G 419 +U 493 ; WX 602 ; N uni01ED ; G 420 +U 494 ; WX 602 ; N uni01EE ; G 421 +U 495 ; WX 602 ; N uni01EF ; G 422 +U 496 ; WX 602 ; N uni01F0 ; G 423 +U 500 ; WX 602 ; N uni01F4 ; G 424 +U 501 ; WX 602 ; N uni01F5 ; G 425 +U 502 ; WX 602 ; N uni01F6 ; G 426 +U 504 ; WX 602 ; N uni01F8 ; G 427 +U 505 ; WX 602 ; N uni01F9 ; G 428 +U 508 ; WX 602 ; N AEacute ; G 429 +U 509 ; WX 602 ; N aeacute ; G 430 +U 510 ; WX 602 ; N Oslashacute ; G 431 +U 511 ; WX 602 ; N oslashacute ; G 432 +U 512 ; WX 602 ; N uni0200 ; G 433 +U 513 ; WX 602 ; N uni0201 ; G 434 +U 514 ; WX 602 ; N uni0202 ; G 435 +U 515 ; WX 602 ; N uni0203 ; G 436 +U 516 ; WX 602 ; N uni0204 ; G 437 +U 517 ; WX 602 ; N uni0205 ; G 438 +U 518 ; WX 602 ; N uni0206 ; G 439 +U 519 ; WX 602 ; N uni0207 ; G 440 +U 520 ; WX 602 ; N uni0208 ; G 441 +U 521 ; WX 602 ; N uni0209 ; G 442 +U 522 ; WX 602 ; N uni020A ; G 443 +U 523 ; WX 602 ; N uni020B ; G 444 +U 524 ; WX 602 ; N uni020C ; G 445 +U 525 ; WX 602 ; N uni020D ; G 446 +U 526 ; WX 602 ; N uni020E ; G 447 +U 527 ; WX 602 ; N uni020F ; G 448 +U 528 ; WX 602 ; N uni0210 ; G 449 +U 529 ; WX 602 ; N uni0211 ; G 450 +U 530 ; WX 602 ; N uni0212 ; G 451 +U 531 ; WX 602 ; N uni0213 ; G 452 +U 532 ; WX 602 ; N uni0214 ; G 453 +U 533 ; WX 602 ; N uni0215 ; G 454 +U 534 ; WX 602 ; N uni0216 ; G 455 +U 535 ; WX 602 ; N uni0217 ; G 456 +U 536 ; WX 602 ; N Scommaaccent ; G 457 +U 537 ; WX 602 ; N scommaaccent ; G 458 +U 538 ; WX 602 ; N uni021A ; G 459 +U 539 ; WX 602 ; N uni021B ; G 460 +U 540 ; WX 602 ; N uni021C ; G 461 +U 541 ; WX 602 ; N uni021D ; G 462 +U 542 ; WX 602 ; N uni021E ; G 463 +U 543 ; WX 602 ; N uni021F ; G 464 +U 544 ; WX 602 ; N uni0220 ; G 465 +U 545 ; WX 602 ; N uni0221 ; G 466 +U 548 ; WX 602 ; N uni0224 ; G 467 +U 549 ; WX 602 ; N uni0225 ; G 468 +U 550 ; WX 602 ; N uni0226 ; G 469 +U 551 ; WX 602 ; N uni0227 ; G 470 +U 552 ; WX 602 ; N uni0228 ; G 471 +U 553 ; WX 602 ; N uni0229 ; G 472 +U 554 ; WX 602 ; N uni022A ; G 473 +U 555 ; WX 602 ; N uni022B ; G 474 +U 556 ; WX 602 ; N uni022C ; G 475 +U 557 ; WX 602 ; N uni022D ; G 476 +U 558 ; WX 602 ; N uni022E ; G 477 +U 559 ; WX 602 ; N uni022F ; G 478 +U 560 ; WX 602 ; N uni0230 ; G 479 +U 561 ; WX 602 ; N uni0231 ; G 480 +U 562 ; WX 602 ; N uni0232 ; G 481 +U 563 ; WX 602 ; N uni0233 ; G 482 +U 564 ; WX 602 ; N uni0234 ; G 483 +U 565 ; WX 602 ; N uni0235 ; G 484 +U 566 ; WX 602 ; N uni0236 ; G 485 +U 567 ; WX 602 ; N dotlessj ; G 486 +U 568 ; WX 602 ; N uni0238 ; G 487 +U 569 ; WX 602 ; N uni0239 ; G 488 +U 570 ; WX 602 ; N uni023A ; G 489 +U 571 ; WX 602 ; N uni023B ; G 490 +U 572 ; WX 602 ; N uni023C ; G 491 +U 573 ; WX 602 ; N uni023D ; G 492 +U 574 ; WX 602 ; N uni023E ; G 493 +U 575 ; WX 602 ; N uni023F ; G 494 +U 576 ; WX 602 ; N uni0240 ; G 495 +U 577 ; WX 602 ; N uni0241 ; G 496 +U 579 ; WX 602 ; N uni0243 ; G 497 +U 580 ; WX 602 ; N uni0244 ; G 498 +U 581 ; WX 602 ; N uni0245 ; G 499 +U 588 ; WX 602 ; N uni024C ; G 500 +U 589 ; WX 602 ; N uni024D ; G 501 +U 592 ; WX 602 ; N uni0250 ; G 502 +U 593 ; WX 602 ; N uni0251 ; G 503 +U 594 ; WX 602 ; N uni0252 ; G 504 +U 595 ; WX 602 ; N uni0253 ; G 505 +U 596 ; WX 602 ; N uni0254 ; G 506 +U 597 ; WX 602 ; N uni0255 ; G 507 +U 598 ; WX 602 ; N uni0256 ; G 508 +U 599 ; WX 602 ; N uni0257 ; G 509 +U 600 ; WX 602 ; N uni0258 ; G 510 +U 601 ; WX 602 ; N uni0259 ; G 511 +U 602 ; WX 602 ; N uni025A ; G 512 +U 603 ; WX 602 ; N uni025B ; G 513 +U 604 ; WX 602 ; N uni025C ; G 514 +U 605 ; WX 602 ; N uni025D ; G 515 +U 606 ; WX 602 ; N uni025E ; G 516 +U 607 ; WX 602 ; N uni025F ; G 517 +U 608 ; WX 602 ; N uni0260 ; G 518 +U 609 ; WX 602 ; N uni0261 ; G 519 +U 610 ; WX 602 ; N uni0262 ; G 520 +U 611 ; WX 602 ; N uni0263 ; G 521 +U 612 ; WX 602 ; N uni0264 ; G 522 +U 613 ; WX 602 ; N uni0265 ; G 523 +U 614 ; WX 602 ; N uni0266 ; G 524 +U 615 ; WX 602 ; N uni0267 ; G 525 +U 616 ; WX 602 ; N uni0268 ; G 526 +U 617 ; WX 602 ; N uni0269 ; G 527 +U 618 ; WX 602 ; N uni026A ; G 528 +U 619 ; WX 602 ; N uni026B ; G 529 +U 620 ; WX 602 ; N uni026C ; G 530 +U 621 ; WX 602 ; N uni026D ; G 531 +U 622 ; WX 602 ; N uni026E ; G 532 +U 623 ; WX 602 ; N uni026F ; G 533 +U 624 ; WX 602 ; N uni0270 ; G 534 +U 625 ; WX 602 ; N uni0271 ; G 535 +U 626 ; WX 602 ; N uni0272 ; G 536 +U 627 ; WX 602 ; N uni0273 ; G 537 +U 628 ; WX 602 ; N uni0274 ; G 538 +U 629 ; WX 602 ; N uni0275 ; G 539 +U 630 ; WX 602 ; N uni0276 ; G 540 +U 631 ; WX 602 ; N uni0277 ; G 541 +U 632 ; WX 602 ; N uni0278 ; G 542 +U 633 ; WX 602 ; N uni0279 ; G 543 +U 634 ; WX 602 ; N uni027A ; G 544 +U 635 ; WX 602 ; N uni027B ; G 545 +U 636 ; WX 602 ; N uni027C ; G 546 +U 637 ; WX 602 ; N uni027D ; G 547 +U 638 ; WX 602 ; N uni027E ; G 548 +U 639 ; WX 602 ; N uni027F ; G 549 +U 640 ; WX 602 ; N uni0280 ; G 550 +U 641 ; WX 602 ; N uni0281 ; G 551 +U 642 ; WX 602 ; N uni0282 ; G 552 +U 643 ; WX 602 ; N uni0283 ; G 553 +U 644 ; WX 602 ; N uni0284 ; G 554 +U 645 ; WX 602 ; N uni0285 ; G 555 +U 646 ; WX 602 ; N uni0286 ; G 556 +U 647 ; WX 602 ; N uni0287 ; G 557 +U 648 ; WX 602 ; N uni0288 ; G 558 +U 649 ; WX 602 ; N uni0289 ; G 559 +U 650 ; WX 602 ; N uni028A ; G 560 +U 651 ; WX 602 ; N uni028B ; G 561 +U 652 ; WX 602 ; N uni028C ; G 562 +U 653 ; WX 602 ; N uni028D ; G 563 +U 654 ; WX 602 ; N uni028E ; G 564 +U 655 ; WX 602 ; N uni028F ; G 565 +U 656 ; WX 602 ; N uni0290 ; G 566 +U 657 ; WX 602 ; N uni0291 ; G 567 +U 658 ; WX 602 ; N uni0292 ; G 568 +U 659 ; WX 602 ; N uni0293 ; G 569 +U 660 ; WX 602 ; N uni0294 ; G 570 +U 661 ; WX 602 ; N uni0295 ; G 571 +U 662 ; WX 602 ; N uni0296 ; G 572 +U 663 ; WX 602 ; N uni0297 ; G 573 +U 664 ; WX 602 ; N uni0298 ; G 574 +U 665 ; WX 602 ; N uni0299 ; G 575 +U 666 ; WX 602 ; N uni029A ; G 576 +U 667 ; WX 602 ; N uni029B ; G 577 +U 668 ; WX 602 ; N uni029C ; G 578 +U 669 ; WX 602 ; N uni029D ; G 579 +U 670 ; WX 602 ; N uni029E ; G 580 +U 671 ; WX 602 ; N uni029F ; G 581 +U 672 ; WX 602 ; N uni02A0 ; G 582 +U 673 ; WX 602 ; N uni02A1 ; G 583 +U 674 ; WX 602 ; N uni02A2 ; G 584 +U 675 ; WX 602 ; N uni02A3 ; G 585 +U 676 ; WX 602 ; N uni02A4 ; G 586 +U 677 ; WX 602 ; N uni02A5 ; G 587 +U 678 ; WX 602 ; N uni02A6 ; G 588 +U 679 ; WX 602 ; N uni02A7 ; G 589 +U 680 ; WX 602 ; N uni02A8 ; G 590 +U 681 ; WX 602 ; N uni02A9 ; G 591 +U 682 ; WX 602 ; N uni02AA ; G 592 +U 683 ; WX 602 ; N uni02AB ; G 593 +U 684 ; WX 602 ; N uni02AC ; G 594 +U 685 ; WX 602 ; N uni02AD ; G 595 +U 686 ; WX 602 ; N uni02AE ; G 596 +U 687 ; WX 602 ; N uni02AF ; G 597 +U 688 ; WX 602 ; N uni02B0 ; G 598 +U 689 ; WX 602 ; N uni02B1 ; G 599 +U 690 ; WX 602 ; N uni02B2 ; G 600 +U 691 ; WX 602 ; N uni02B3 ; G 601 +U 692 ; WX 602 ; N uni02B4 ; G 602 +U 693 ; WX 602 ; N uni02B5 ; G 603 +U 694 ; WX 602 ; N uni02B6 ; G 604 +U 695 ; WX 602 ; N uni02B7 ; G 605 +U 696 ; WX 602 ; N uni02B8 ; G 606 +U 697 ; WX 602 ; N uni02B9 ; G 607 +U 699 ; WX 602 ; N uni02BB ; G 608 +U 700 ; WX 602 ; N uni02BC ; G 609 +U 701 ; WX 602 ; N uni02BD ; G 610 +U 702 ; WX 602 ; N uni02BE ; G 611 +U 703 ; WX 602 ; N uni02BF ; G 612 +U 704 ; WX 602 ; N uni02C0 ; G 613 +U 705 ; WX 602 ; N uni02C1 ; G 614 +U 710 ; WX 602 ; N circumflex ; G 615 +U 711 ; WX 602 ; N caron ; G 616 +U 712 ; WX 602 ; N uni02C8 ; G 617 +U 713 ; WX 602 ; N uni02C9 ; G 618 +U 716 ; WX 602 ; N uni02CC ; G 619 +U 717 ; WX 602 ; N uni02CD ; G 620 +U 718 ; WX 602 ; N uni02CE ; G 621 +U 719 ; WX 602 ; N uni02CF ; G 622 +U 720 ; WX 602 ; N uni02D0 ; G 623 +U 721 ; WX 602 ; N uni02D1 ; G 624 +U 722 ; WX 602 ; N uni02D2 ; G 625 +U 723 ; WX 602 ; N uni02D3 ; G 626 +U 726 ; WX 602 ; N uni02D6 ; G 627 +U 727 ; WX 602 ; N uni02D7 ; G 628 +U 728 ; WX 602 ; N breve ; G 629 +U 729 ; WX 602 ; N dotaccent ; G 630 +U 730 ; WX 602 ; N ring ; G 631 +U 731 ; WX 602 ; N ogonek ; G 632 +U 732 ; WX 602 ; N tilde ; G 633 +U 733 ; WX 602 ; N hungarumlaut ; G 634 +U 734 ; WX 602 ; N uni02DE ; G 635 +U 736 ; WX 602 ; N uni02E0 ; G 636 +U 737 ; WX 602 ; N uni02E1 ; G 637 +U 738 ; WX 602 ; N uni02E2 ; G 638 +U 739 ; WX 602 ; N uni02E3 ; G 639 +U 740 ; WX 602 ; N uni02E4 ; G 640 +U 741 ; WX 602 ; N uni02E5 ; G 641 +U 742 ; WX 602 ; N uni02E6 ; G 642 +U 743 ; WX 602 ; N uni02E7 ; G 643 +U 744 ; WX 602 ; N uni02E8 ; G 644 +U 745 ; WX 602 ; N uni02E9 ; G 645 +U 750 ; WX 602 ; N uni02EE ; G 646 +U 755 ; WX 602 ; N uni02F3 ; G 647 +U 768 ; WX 602 ; N gravecomb ; G 648 +U 769 ; WX 602 ; N acutecomb ; G 649 +U 770 ; WX 602 ; N uni0302 ; G 650 +U 771 ; WX 602 ; N tildecomb ; G 651 +U 772 ; WX 602 ; N uni0304 ; G 652 +U 773 ; WX 602 ; N uni0305 ; G 653 +U 774 ; WX 602 ; N uni0306 ; G 654 +U 775 ; WX 602 ; N uni0307 ; G 655 +U 776 ; WX 602 ; N uni0308 ; G 656 +U 777 ; WX 602 ; N hookabovecomb ; G 657 +U 778 ; WX 602 ; N uni030A ; G 658 +U 779 ; WX 602 ; N uni030B ; G 659 +U 780 ; WX 602 ; N uni030C ; G 660 +U 781 ; WX 602 ; N uni030D ; G 661 +U 782 ; WX 602 ; N uni030E ; G 662 +U 783 ; WX 602 ; N uni030F ; G 663 +U 784 ; WX 602 ; N uni0310 ; G 664 +U 785 ; WX 602 ; N uni0311 ; G 665 +U 786 ; WX 602 ; N uni0312 ; G 666 +U 787 ; WX 602 ; N uni0313 ; G 667 +U 788 ; WX 602 ; N uni0314 ; G 668 +U 789 ; WX 602 ; N uni0315 ; G 669 +U 790 ; WX 602 ; N uni0316 ; G 670 +U 791 ; WX 602 ; N uni0317 ; G 671 +U 792 ; WX 602 ; N uni0318 ; G 672 +U 793 ; WX 602 ; N uni0319 ; G 673 +U 794 ; WX 602 ; N uni031A ; G 674 +U 795 ; WX 602 ; N uni031B ; G 675 +U 796 ; WX 602 ; N uni031C ; G 676 +U 797 ; WX 602 ; N uni031D ; G 677 +U 798 ; WX 602 ; N uni031E ; G 678 +U 799 ; WX 602 ; N uni031F ; G 679 +U 800 ; WX 602 ; N uni0320 ; G 680 +U 801 ; WX 602 ; N uni0321 ; G 681 +U 802 ; WX 602 ; N uni0322 ; G 682 +U 803 ; WX 602 ; N dotbelowcomb ; G 683 +U 804 ; WX 602 ; N uni0324 ; G 684 +U 805 ; WX 602 ; N uni0325 ; G 685 +U 806 ; WX 602 ; N uni0326 ; G 686 +U 807 ; WX 602 ; N uni0327 ; G 687 +U 808 ; WX 602 ; N uni0328 ; G 688 +U 809 ; WX 602 ; N uni0329 ; G 689 +U 810 ; WX 602 ; N uni032A ; G 690 +U 811 ; WX 602 ; N uni032B ; G 691 +U 812 ; WX 602 ; N uni032C ; G 692 +U 813 ; WX 602 ; N uni032D ; G 693 +U 814 ; WX 602 ; N uni032E ; G 694 +U 815 ; WX 602 ; N uni032F ; G 695 +U 816 ; WX 602 ; N uni0330 ; G 696 +U 817 ; WX 602 ; N uni0331 ; G 697 +U 818 ; WX 602 ; N uni0332 ; G 698 +U 819 ; WX 602 ; N uni0333 ; G 699 +U 820 ; WX 602 ; N uni0334 ; G 700 +U 821 ; WX 602 ; N uni0335 ; G 701 +U 822 ; WX 602 ; N uni0336 ; G 702 +U 823 ; WX 602 ; N uni0337 ; G 703 +U 824 ; WX 602 ; N uni0338 ; G 704 +U 825 ; WX 602 ; N uni0339 ; G 705 +U 826 ; WX 602 ; N uni033A ; G 706 +U 827 ; WX 602 ; N uni033B ; G 707 +U 828 ; WX 602 ; N uni033C ; G 708 +U 829 ; WX 602 ; N uni033D ; G 709 +U 830 ; WX 602 ; N uni033E ; G 710 +U 831 ; WX 602 ; N uni033F ; G 711 +U 835 ; WX 602 ; N uni0343 ; G 712 +U 856 ; WX 602 ; N uni0358 ; G 713 +U 865 ; WX 602 ; N uni0361 ; G 714 +U 884 ; WX 602 ; N uni0374 ; G 715 +U 885 ; WX 602 ; N uni0375 ; G 716 +U 886 ; WX 602 ; N uni0376 ; G 717 +U 887 ; WX 602 ; N uni0377 ; G 718 +U 890 ; WX 602 ; N uni037A ; G 719 +U 891 ; WX 602 ; N uni037B ; G 720 +U 892 ; WX 602 ; N uni037C ; G 721 +U 893 ; WX 602 ; N uni037D ; G 722 +U 894 ; WX 602 ; N uni037E ; G 723 +U 895 ; WX 602 ; N uni037F ; G 724 +U 900 ; WX 602 ; N tonos ; G 725 +U 901 ; WX 602 ; N dieresistonos ; G 726 +U 902 ; WX 602 ; N Alphatonos ; G 727 +U 903 ; WX 602 ; N anoteleia ; G 728 +U 904 ; WX 602 ; N Epsilontonos ; G 729 +U 905 ; WX 602 ; N Etatonos ; G 730 +U 906 ; WX 602 ; N Iotatonos ; G 731 +U 908 ; WX 602 ; N Omicrontonos ; G 732 +U 910 ; WX 602 ; N Upsilontonos ; G 733 +U 911 ; WX 602 ; N Omegatonos ; G 734 +U 912 ; WX 602 ; N iotadieresistonos ; G 735 +U 913 ; WX 602 ; N Alpha ; G 736 +U 914 ; WX 602 ; N Beta ; G 737 +U 915 ; WX 602 ; N Gamma ; G 738 +U 916 ; WX 602 ; N uni0394 ; G 739 +U 917 ; WX 602 ; N Epsilon ; G 740 +U 918 ; WX 602 ; N Zeta ; G 741 +U 919 ; WX 602 ; N Eta ; G 742 +U 920 ; WX 602 ; N Theta ; G 743 +U 921 ; WX 602 ; N Iota ; G 744 +U 922 ; WX 602 ; N Kappa ; G 745 +U 923 ; WX 602 ; N Lambda ; G 746 +U 924 ; WX 602 ; N Mu ; G 747 +U 925 ; WX 602 ; N Nu ; G 748 +U 926 ; WX 602 ; N Xi ; G 749 +U 927 ; WX 602 ; N Omicron ; G 750 +U 928 ; WX 602 ; N Pi ; G 751 +U 929 ; WX 602 ; N Rho ; G 752 +U 931 ; WX 602 ; N Sigma ; G 753 +U 932 ; WX 602 ; N Tau ; G 754 +U 933 ; WX 602 ; N Upsilon ; G 755 +U 934 ; WX 602 ; N Phi ; G 756 +U 935 ; WX 602 ; N Chi ; G 757 +U 936 ; WX 602 ; N Psi ; G 758 +U 937 ; WX 602 ; N Omega ; G 759 +U 938 ; WX 602 ; N Iotadieresis ; G 760 +U 939 ; WX 602 ; N Upsilondieresis ; G 761 +U 940 ; WX 602 ; N alphatonos ; G 762 +U 941 ; WX 602 ; N epsilontonos ; G 763 +U 942 ; WX 602 ; N etatonos ; G 764 +U 943 ; WX 602 ; N iotatonos ; G 765 +U 944 ; WX 602 ; N upsilondieresistonos ; G 766 +U 945 ; WX 602 ; N alpha ; G 767 +U 946 ; WX 602 ; N beta ; G 768 +U 947 ; WX 602 ; N gamma ; G 769 +U 948 ; WX 602 ; N delta ; G 770 +U 949 ; WX 602 ; N epsilon ; G 771 +U 950 ; WX 602 ; N zeta ; G 772 +U 951 ; WX 602 ; N eta ; G 773 +U 952 ; WX 602 ; N theta ; G 774 +U 953 ; WX 602 ; N iota ; G 775 +U 954 ; WX 602 ; N kappa ; G 776 +U 955 ; WX 602 ; N lambda ; G 777 +U 956 ; WX 602 ; N uni03BC ; G 778 +U 957 ; WX 602 ; N nu ; G 779 +U 958 ; WX 602 ; N xi ; G 780 +U 959 ; WX 602 ; N omicron ; G 781 +U 960 ; WX 602 ; N pi ; G 782 +U 961 ; WX 602 ; N rho ; G 783 +U 962 ; WX 602 ; N sigma1 ; G 784 +U 963 ; WX 602 ; N sigma ; G 785 +U 964 ; WX 602 ; N tau ; G 786 +U 965 ; WX 602 ; N upsilon ; G 787 +U 966 ; WX 602 ; N phi ; G 788 +U 967 ; WX 602 ; N chi ; G 789 +U 968 ; WX 602 ; N psi ; G 790 +U 969 ; WX 602 ; N omega ; G 791 +U 970 ; WX 602 ; N iotadieresis ; G 792 +U 971 ; WX 602 ; N upsilondieresis ; G 793 +U 972 ; WX 602 ; N omicrontonos ; G 794 +U 973 ; WX 602 ; N upsilontonos ; G 795 +U 974 ; WX 602 ; N omegatonos ; G 796 +U 976 ; WX 602 ; N uni03D0 ; G 797 +U 977 ; WX 602 ; N theta1 ; G 798 +U 978 ; WX 602 ; N Upsilon1 ; G 799 +U 979 ; WX 602 ; N uni03D3 ; G 800 +U 980 ; WX 602 ; N uni03D4 ; G 801 +U 981 ; WX 602 ; N phi1 ; G 802 +U 982 ; WX 602 ; N omega1 ; G 803 +U 983 ; WX 602 ; N uni03D7 ; G 804 +U 984 ; WX 602 ; N uni03D8 ; G 805 +U 985 ; WX 602 ; N uni03D9 ; G 806 +U 986 ; WX 602 ; N uni03DA ; G 807 +U 987 ; WX 602 ; N uni03DB ; G 808 +U 988 ; WX 602 ; N uni03DC ; G 809 +U 989 ; WX 602 ; N uni03DD ; G 810 +U 990 ; WX 602 ; N uni03DE ; G 811 +U 991 ; WX 602 ; N uni03DF ; G 812 +U 992 ; WX 602 ; N uni03E0 ; G 813 +U 993 ; WX 602 ; N uni03E1 ; G 814 +U 1008 ; WX 602 ; N uni03F0 ; G 815 +U 1009 ; WX 602 ; N uni03F1 ; G 816 +U 1010 ; WX 602 ; N uni03F2 ; G 817 +U 1011 ; WX 602 ; N uni03F3 ; G 818 +U 1012 ; WX 602 ; N uni03F4 ; G 819 +U 1013 ; WX 602 ; N uni03F5 ; G 820 +U 1014 ; WX 602 ; N uni03F6 ; G 821 +U 1015 ; WX 602 ; N uni03F7 ; G 822 +U 1016 ; WX 602 ; N uni03F8 ; G 823 +U 1017 ; WX 602 ; N uni03F9 ; G 824 +U 1018 ; WX 602 ; N uni03FA ; G 825 +U 1019 ; WX 602 ; N uni03FB ; G 826 +U 1020 ; WX 602 ; N uni03FC ; G 827 +U 1021 ; WX 602 ; N uni03FD ; G 828 +U 1022 ; WX 602 ; N uni03FE ; G 829 +U 1023 ; WX 602 ; N uni03FF ; G 830 +U 1024 ; WX 602 ; N uni0400 ; G 831 +U 1025 ; WX 602 ; N uni0401 ; G 832 +U 1026 ; WX 602 ; N uni0402 ; G 833 +U 1027 ; WX 602 ; N uni0403 ; G 834 +U 1028 ; WX 602 ; N uni0404 ; G 835 +U 1029 ; WX 602 ; N uni0405 ; G 836 +U 1030 ; WX 602 ; N uni0406 ; G 837 +U 1031 ; WX 602 ; N uni0407 ; G 838 +U 1032 ; WX 602 ; N uni0408 ; G 839 +U 1033 ; WX 602 ; N uni0409 ; G 840 +U 1034 ; WX 602 ; N uni040A ; G 841 +U 1035 ; WX 602 ; N uni040B ; G 842 +U 1036 ; WX 602 ; N uni040C ; G 843 +U 1037 ; WX 602 ; N uni040D ; G 844 +U 1038 ; WX 602 ; N uni040E ; G 845 +U 1039 ; WX 602 ; N uni040F ; G 846 +U 1040 ; WX 602 ; N uni0410 ; G 847 +U 1041 ; WX 602 ; N uni0411 ; G 848 +U 1042 ; WX 602 ; N uni0412 ; G 849 +U 1043 ; WX 602 ; N uni0413 ; G 850 +U 1044 ; WX 602 ; N uni0414 ; G 851 +U 1045 ; WX 602 ; N uni0415 ; G 852 +U 1046 ; WX 602 ; N uni0416 ; G 853 +U 1047 ; WX 602 ; N uni0417 ; G 854 +U 1048 ; WX 602 ; N uni0418 ; G 855 +U 1049 ; WX 602 ; N uni0419 ; G 856 +U 1050 ; WX 602 ; N uni041A ; G 857 +U 1051 ; WX 602 ; N uni041B ; G 858 +U 1052 ; WX 602 ; N uni041C ; G 859 +U 1053 ; WX 602 ; N uni041D ; G 860 +U 1054 ; WX 602 ; N uni041E ; G 861 +U 1055 ; WX 602 ; N uni041F ; G 862 +U 1056 ; WX 602 ; N uni0420 ; G 863 +U 1057 ; WX 602 ; N uni0421 ; G 864 +U 1058 ; WX 602 ; N uni0422 ; G 865 +U 1059 ; WX 602 ; N uni0423 ; G 866 +U 1060 ; WX 602 ; N uni0424 ; G 867 +U 1061 ; WX 602 ; N uni0425 ; G 868 +U 1062 ; WX 602 ; N uni0426 ; G 869 +U 1063 ; WX 602 ; N uni0427 ; G 870 +U 1064 ; WX 602 ; N uni0428 ; G 871 +U 1065 ; WX 602 ; N uni0429 ; G 872 +U 1066 ; WX 602 ; N uni042A ; G 873 +U 1067 ; WX 602 ; N uni042B ; G 874 +U 1068 ; WX 602 ; N uni042C ; G 875 +U 1069 ; WX 602 ; N uni042D ; G 876 +U 1070 ; WX 602 ; N uni042E ; G 877 +U 1071 ; WX 602 ; N uni042F ; G 878 +U 1072 ; WX 602 ; N uni0430 ; G 879 +U 1073 ; WX 602 ; N uni0431 ; G 880 +U 1074 ; WX 602 ; N uni0432 ; G 881 +U 1075 ; WX 602 ; N uni0433 ; G 882 +U 1076 ; WX 602 ; N uni0434 ; G 883 +U 1077 ; WX 602 ; N uni0435 ; G 884 +U 1078 ; WX 602 ; N uni0436 ; G 885 +U 1079 ; WX 602 ; N uni0437 ; G 886 +U 1080 ; WX 602 ; N uni0438 ; G 887 +U 1081 ; WX 602 ; N uni0439 ; G 888 +U 1082 ; WX 602 ; N uni043A ; G 889 +U 1083 ; WX 602 ; N uni043B ; G 890 +U 1084 ; WX 602 ; N uni043C ; G 891 +U 1085 ; WX 602 ; N uni043D ; G 892 +U 1086 ; WX 602 ; N uni043E ; G 893 +U 1087 ; WX 602 ; N uni043F ; G 894 +U 1088 ; WX 602 ; N uni0440 ; G 895 +U 1089 ; WX 602 ; N uni0441 ; G 896 +U 1090 ; WX 602 ; N uni0442 ; G 897 +U 1091 ; WX 602 ; N uni0443 ; G 898 +U 1092 ; WX 602 ; N uni0444 ; G 899 +U 1093 ; WX 602 ; N uni0445 ; G 900 +U 1094 ; WX 602 ; N uni0446 ; G 901 +U 1095 ; WX 602 ; N uni0447 ; G 902 +U 1096 ; WX 602 ; N uni0448 ; G 903 +U 1097 ; WX 602 ; N uni0449 ; G 904 +U 1098 ; WX 602 ; N uni044A ; G 905 +U 1099 ; WX 602 ; N uni044B ; G 906 +U 1100 ; WX 602 ; N uni044C ; G 907 +U 1101 ; WX 602 ; N uni044D ; G 908 +U 1102 ; WX 602 ; N uni044E ; G 909 +U 1103 ; WX 602 ; N uni044F ; G 910 +U 1104 ; WX 602 ; N uni0450 ; G 911 +U 1105 ; WX 602 ; N uni0451 ; G 912 +U 1106 ; WX 602 ; N uni0452 ; G 913 +U 1107 ; WX 602 ; N uni0453 ; G 914 +U 1108 ; WX 602 ; N uni0454 ; G 915 +U 1109 ; WX 602 ; N uni0455 ; G 916 +U 1110 ; WX 602 ; N uni0456 ; G 917 +U 1111 ; WX 602 ; N uni0457 ; G 918 +U 1112 ; WX 602 ; N uni0458 ; G 919 +U 1113 ; WX 602 ; N uni0459 ; G 920 +U 1114 ; WX 602 ; N uni045A ; G 921 +U 1115 ; WX 602 ; N uni045B ; G 922 +U 1116 ; WX 602 ; N uni045C ; G 923 +U 1117 ; WX 602 ; N uni045D ; G 924 +U 1118 ; WX 602 ; N uni045E ; G 925 +U 1119 ; WX 602 ; N uni045F ; G 926 +U 1122 ; WX 602 ; N uni0462 ; G 927 +U 1123 ; WX 602 ; N uni0463 ; G 928 +U 1138 ; WX 602 ; N uni0472 ; G 929 +U 1139 ; WX 602 ; N uni0473 ; G 930 +U 1168 ; WX 602 ; N uni0490 ; G 931 +U 1169 ; WX 602 ; N uni0491 ; G 932 +U 1170 ; WX 602 ; N uni0492 ; G 933 +U 1171 ; WX 602 ; N uni0493 ; G 934 +U 1172 ; WX 602 ; N uni0494 ; G 935 +U 1173 ; WX 602 ; N uni0495 ; G 936 +U 1174 ; WX 602 ; N uni0496 ; G 937 +U 1175 ; WX 602 ; N uni0497 ; G 938 +U 1176 ; WX 602 ; N uni0498 ; G 939 +U 1177 ; WX 602 ; N uni0499 ; G 940 +U 1178 ; WX 602 ; N uni049A ; G 941 +U 1179 ; WX 602 ; N uni049B ; G 942 +U 1186 ; WX 602 ; N uni04A2 ; G 943 +U 1187 ; WX 602 ; N uni04A3 ; G 944 +U 1188 ; WX 602 ; N uni04A4 ; G 945 +U 1189 ; WX 602 ; N uni04A5 ; G 946 +U 1194 ; WX 602 ; N uni04AA ; G 947 +U 1195 ; WX 602 ; N uni04AB ; G 948 +U 1196 ; WX 602 ; N uni04AC ; G 949 +U 1197 ; WX 602 ; N uni04AD ; G 950 +U 1198 ; WX 602 ; N uni04AE ; G 951 +U 1199 ; WX 602 ; N uni04AF ; G 952 +U 1200 ; WX 602 ; N uni04B0 ; G 953 +U 1201 ; WX 602 ; N uni04B1 ; G 954 +U 1202 ; WX 602 ; N uni04B2 ; G 955 +U 1203 ; WX 602 ; N uni04B3 ; G 956 +U 1210 ; WX 602 ; N uni04BA ; G 957 +U 1211 ; WX 602 ; N uni04BB ; G 958 +U 1216 ; WX 602 ; N uni04C0 ; G 959 +U 1217 ; WX 602 ; N uni04C1 ; G 960 +U 1218 ; WX 602 ; N uni04C2 ; G 961 +U 1219 ; WX 602 ; N uni04C3 ; G 962 +U 1220 ; WX 602 ; N uni04C4 ; G 963 +U 1223 ; WX 602 ; N uni04C7 ; G 964 +U 1224 ; WX 602 ; N uni04C8 ; G 965 +U 1227 ; WX 602 ; N uni04CB ; G 966 +U 1228 ; WX 602 ; N uni04CC ; G 967 +U 1231 ; WX 602 ; N uni04CF ; G 968 +U 1232 ; WX 602 ; N uni04D0 ; G 969 +U 1233 ; WX 602 ; N uni04D1 ; G 970 +U 1234 ; WX 602 ; N uni04D2 ; G 971 +U 1235 ; WX 602 ; N uni04D3 ; G 972 +U 1236 ; WX 602 ; N uni04D4 ; G 973 +U 1237 ; WX 602 ; N uni04D5 ; G 974 +U 1238 ; WX 602 ; N uni04D6 ; G 975 +U 1239 ; WX 602 ; N uni04D7 ; G 976 +U 1240 ; WX 602 ; N uni04D8 ; G 977 +U 1241 ; WX 602 ; N uni04D9 ; G 978 +U 1242 ; WX 602 ; N uni04DA ; G 979 +U 1243 ; WX 602 ; N uni04DB ; G 980 +U 1244 ; WX 602 ; N uni04DC ; G 981 +U 1245 ; WX 602 ; N uni04DD ; G 982 +U 1246 ; WX 602 ; N uni04DE ; G 983 +U 1247 ; WX 602 ; N uni04DF ; G 984 +U 1248 ; WX 602 ; N uni04E0 ; G 985 +U 1249 ; WX 602 ; N uni04E1 ; G 986 +U 1250 ; WX 602 ; N uni04E2 ; G 987 +U 1251 ; WX 602 ; N uni04E3 ; G 988 +U 1252 ; WX 602 ; N uni04E4 ; G 989 +U 1253 ; WX 602 ; N uni04E5 ; G 990 +U 1254 ; WX 602 ; N uni04E6 ; G 991 +U 1255 ; WX 602 ; N uni04E7 ; G 992 +U 1256 ; WX 602 ; N uni04E8 ; G 993 +U 1257 ; WX 602 ; N uni04E9 ; G 994 +U 1258 ; WX 602 ; N uni04EA ; G 995 +U 1259 ; WX 602 ; N uni04EB ; G 996 +U 1260 ; WX 602 ; N uni04EC ; G 997 +U 1261 ; WX 602 ; N uni04ED ; G 998 +U 1262 ; WX 602 ; N uni04EE ; G 999 +U 1263 ; WX 602 ; N uni04EF ; G 1000 +U 1264 ; WX 602 ; N uni04F0 ; G 1001 +U 1265 ; WX 602 ; N uni04F1 ; G 1002 +U 1266 ; WX 602 ; N uni04F2 ; G 1003 +U 1267 ; WX 602 ; N uni04F3 ; G 1004 +U 1268 ; WX 602 ; N uni04F4 ; G 1005 +U 1269 ; WX 602 ; N uni04F5 ; G 1006 +U 1270 ; WX 602 ; N uni04F6 ; G 1007 +U 1271 ; WX 602 ; N uni04F7 ; G 1008 +U 1272 ; WX 602 ; N uni04F8 ; G 1009 +U 1273 ; WX 602 ; N uni04F9 ; G 1010 +U 1296 ; WX 602 ; N uni0510 ; G 1011 +U 1297 ; WX 602 ; N uni0511 ; G 1012 +U 1306 ; WX 602 ; N uni051A ; G 1013 +U 1307 ; WX 602 ; N uni051B ; G 1014 +U 1308 ; WX 602 ; N uni051C ; G 1015 +U 1309 ; WX 602 ; N uni051D ; G 1016 +U 1329 ; WX 602 ; N uni0531 ; G 1017 +U 1330 ; WX 602 ; N uni0532 ; G 1018 +U 1331 ; WX 602 ; N uni0533 ; G 1019 +U 1332 ; WX 602 ; N uni0534 ; G 1020 +U 1333 ; WX 602 ; N uni0535 ; G 1021 +U 1334 ; WX 602 ; N uni0536 ; G 1022 +U 1335 ; WX 602 ; N uni0537 ; G 1023 +U 1336 ; WX 602 ; N uni0538 ; G 1024 +U 1337 ; WX 602 ; N uni0539 ; G 1025 +U 1338 ; WX 602 ; N uni053A ; G 1026 +U 1339 ; WX 602 ; N uni053B ; G 1027 +U 1340 ; WX 602 ; N uni053C ; G 1028 +U 1341 ; WX 602 ; N uni053D ; G 1029 +U 1342 ; WX 602 ; N uni053E ; G 1030 +U 1343 ; WX 602 ; N uni053F ; G 1031 +U 1344 ; WX 602 ; N uni0540 ; G 1032 +U 1345 ; WX 602 ; N uni0541 ; G 1033 +U 1346 ; WX 602 ; N uni0542 ; G 1034 +U 1347 ; WX 602 ; N uni0543 ; G 1035 +U 1348 ; WX 602 ; N uni0544 ; G 1036 +U 1349 ; WX 602 ; N uni0545 ; G 1037 +U 1350 ; WX 602 ; N uni0546 ; G 1038 +U 1351 ; WX 602 ; N uni0547 ; G 1039 +U 1352 ; WX 602 ; N uni0548 ; G 1040 +U 1353 ; WX 602 ; N uni0549 ; G 1041 +U 1354 ; WX 602 ; N uni054A ; G 1042 +U 1355 ; WX 602 ; N uni054B ; G 1043 +U 1356 ; WX 602 ; N uni054C ; G 1044 +U 1357 ; WX 602 ; N uni054D ; G 1045 +U 1358 ; WX 602 ; N uni054E ; G 1046 +U 1359 ; WX 602 ; N uni054F ; G 1047 +U 1360 ; WX 602 ; N uni0550 ; G 1048 +U 1361 ; WX 602 ; N uni0551 ; G 1049 +U 1362 ; WX 602 ; N uni0552 ; G 1050 +U 1363 ; WX 602 ; N uni0553 ; G 1051 +U 1364 ; WX 602 ; N uni0554 ; G 1052 +U 1365 ; WX 602 ; N uni0555 ; G 1053 +U 1366 ; WX 602 ; N uni0556 ; G 1054 +U 1369 ; WX 602 ; N uni0559 ; G 1055 +U 1370 ; WX 602 ; N uni055A ; G 1056 +U 1371 ; WX 602 ; N uni055B ; G 1057 +U 1372 ; WX 602 ; N uni055C ; G 1058 +U 1373 ; WX 602 ; N uni055D ; G 1059 +U 1374 ; WX 602 ; N uni055E ; G 1060 +U 1375 ; WX 602 ; N uni055F ; G 1061 +U 1377 ; WX 602 ; N uni0561 ; G 1062 +U 1378 ; WX 602 ; N uni0562 ; G 1063 +U 1379 ; WX 602 ; N uni0563 ; G 1064 +U 1380 ; WX 602 ; N uni0564 ; G 1065 +U 1381 ; WX 602 ; N uni0565 ; G 1066 +U 1382 ; WX 602 ; N uni0566 ; G 1067 +U 1383 ; WX 602 ; N uni0567 ; G 1068 +U 1384 ; WX 602 ; N uni0568 ; G 1069 +U 1385 ; WX 602 ; N uni0569 ; G 1070 +U 1386 ; WX 602 ; N uni056A ; G 1071 +U 1387 ; WX 602 ; N uni056B ; G 1072 +U 1388 ; WX 602 ; N uni056C ; G 1073 +U 1389 ; WX 602 ; N uni056D ; G 1074 +U 1390 ; WX 602 ; N uni056E ; G 1075 +U 1391 ; WX 602 ; N uni056F ; G 1076 +U 1392 ; WX 602 ; N uni0570 ; G 1077 +U 1393 ; WX 602 ; N uni0571 ; G 1078 +U 1394 ; WX 602 ; N uni0572 ; G 1079 +U 1395 ; WX 602 ; N uni0573 ; G 1080 +U 1396 ; WX 602 ; N uni0574 ; G 1081 +U 1397 ; WX 602 ; N uni0575 ; G 1082 +U 1398 ; WX 602 ; N uni0576 ; G 1083 +U 1399 ; WX 602 ; N uni0577 ; G 1084 +U 1400 ; WX 602 ; N uni0578 ; G 1085 +U 1401 ; WX 602 ; N uni0579 ; G 1086 +U 1402 ; WX 602 ; N uni057A ; G 1087 +U 1403 ; WX 602 ; N uni057B ; G 1088 +U 1404 ; WX 602 ; N uni057C ; G 1089 +U 1405 ; WX 602 ; N uni057D ; G 1090 +U 1406 ; WX 602 ; N uni057E ; G 1091 +U 1407 ; WX 602 ; N uni057F ; G 1092 +U 1408 ; WX 602 ; N uni0580 ; G 1093 +U 1409 ; WX 602 ; N uni0581 ; G 1094 +U 1410 ; WX 602 ; N uni0582 ; G 1095 +U 1411 ; WX 602 ; N uni0583 ; G 1096 +U 1412 ; WX 602 ; N uni0584 ; G 1097 +U 1413 ; WX 602 ; N uni0585 ; G 1098 +U 1414 ; WX 602 ; N uni0586 ; G 1099 +U 1415 ; WX 602 ; N uni0587 ; G 1100 +U 1417 ; WX 602 ; N uni0589 ; G 1101 +U 1418 ; WX 602 ; N uni058A ; G 1102 +U 1542 ; WX 602 ; N uni0606 ; G 1103 +U 1543 ; WX 602 ; N uni0607 ; G 1104 +U 1545 ; WX 602 ; N uni0609 ; G 1105 +U 1546 ; WX 602 ; N uni060A ; G 1106 +U 1548 ; WX 602 ; N uni060C ; G 1107 +U 1557 ; WX 602 ; N uni0615 ; G 1108 +U 1563 ; WX 602 ; N uni061B ; G 1109 +U 1567 ; WX 602 ; N uni061F ; G 1110 +U 1569 ; WX 602 ; N uni0621 ; G 1111 +U 1570 ; WX 602 ; N uni0622 ; G 1112 +U 1571 ; WX 602 ; N uni0623 ; G 1113 +U 1572 ; WX 602 ; N uni0624 ; G 1114 +U 1573 ; WX 602 ; N uni0625 ; G 1115 +U 1574 ; WX 602 ; N uni0626 ; G 1116 +U 1575 ; WX 602 ; N uni0627 ; G 1117 +U 1576 ; WX 602 ; N uni0628 ; G 1118 +U 1577 ; WX 602 ; N uni0629 ; G 1119 +U 1578 ; WX 602 ; N uni062A ; G 1120 +U 1579 ; WX 602 ; N uni062B ; G 1121 +U 1580 ; WX 602 ; N uni062C ; G 1122 +U 1581 ; WX 602 ; N uni062D ; G 1123 +U 1582 ; WX 602 ; N uni062E ; G 1124 +U 1583 ; WX 602 ; N uni062F ; G 1125 +U 1584 ; WX 602 ; N uni0630 ; G 1126 +U 1585 ; WX 602 ; N uni0631 ; G 1127 +U 1586 ; WX 602 ; N uni0632 ; G 1128 +U 1587 ; WX 602 ; N uni0633 ; G 1129 +U 1588 ; WX 602 ; N uni0634 ; G 1130 +U 1589 ; WX 602 ; N uni0635 ; G 1131 +U 1590 ; WX 602 ; N uni0636 ; G 1132 +U 1591 ; WX 602 ; N uni0637 ; G 1133 +U 1592 ; WX 602 ; N uni0638 ; G 1134 +U 1593 ; WX 602 ; N uni0639 ; G 1135 +U 1594 ; WX 602 ; N uni063A ; G 1136 +U 1600 ; WX 602 ; N uni0640 ; G 1137 +U 1601 ; WX 602 ; N uni0641 ; G 1138 +U 1602 ; WX 602 ; N uni0642 ; G 1139 +U 1603 ; WX 602 ; N uni0643 ; G 1140 +U 1604 ; WX 602 ; N uni0644 ; G 1141 +U 1605 ; WX 602 ; N uni0645 ; G 1142 +U 1606 ; WX 602 ; N uni0646 ; G 1143 +U 1607 ; WX 602 ; N uni0647 ; G 1144 +U 1608 ; WX 602 ; N uni0648 ; G 1145 +U 1609 ; WX 602 ; N uni0649 ; G 1146 +U 1610 ; WX 602 ; N uni064A ; G 1147 +U 1611 ; WX 602 ; N uni064B ; G 1148 +U 1612 ; WX 602 ; N uni064C ; G 1149 +U 1613 ; WX 602 ; N uni064D ; G 1150 +U 1614 ; WX 602 ; N uni064E ; G 1151 +U 1615 ; WX 602 ; N uni064F ; G 1152 +U 1616 ; WX 602 ; N uni0650 ; G 1153 +U 1617 ; WX 602 ; N uni0651 ; G 1154 +U 1618 ; WX 602 ; N uni0652 ; G 1155 +U 1619 ; WX 602 ; N uni0653 ; G 1156 +U 1620 ; WX 602 ; N uni0654 ; G 1157 +U 1621 ; WX 602 ; N uni0655 ; G 1158 +U 1626 ; WX 602 ; N uni065A ; G 1159 +U 1632 ; WX 602 ; N uni0660 ; G 1160 +U 1633 ; WX 602 ; N uni0661 ; G 1161 +U 1634 ; WX 602 ; N uni0662 ; G 1162 +U 1635 ; WX 602 ; N uni0663 ; G 1163 +U 1636 ; WX 602 ; N uni0664 ; G 1164 +U 1637 ; WX 602 ; N uni0665 ; G 1165 +U 1638 ; WX 602 ; N uni0666 ; G 1166 +U 1639 ; WX 602 ; N uni0667 ; G 1167 +U 1640 ; WX 602 ; N uni0668 ; G 1168 +U 1641 ; WX 602 ; N uni0669 ; G 1169 +U 1642 ; WX 602 ; N uni066A ; G 1170 +U 1643 ; WX 602 ; N uni066B ; G 1171 +U 1644 ; WX 602 ; N uni066C ; G 1172 +U 1645 ; WX 602 ; N uni066D ; G 1173 +U 1652 ; WX 602 ; N uni0674 ; G 1174 +U 1657 ; WX 602 ; N uni0679 ; G 1175 +U 1658 ; WX 602 ; N uni067A ; G 1176 +U 1659 ; WX 602 ; N uni067B ; G 1177 +U 1662 ; WX 602 ; N uni067E ; G 1178 +U 1663 ; WX 602 ; N uni067F ; G 1179 +U 1664 ; WX 602 ; N uni0680 ; G 1180 +U 1667 ; WX 602 ; N uni0683 ; G 1181 +U 1668 ; WX 602 ; N uni0684 ; G 1182 +U 1670 ; WX 602 ; N uni0686 ; G 1183 +U 1671 ; WX 602 ; N uni0687 ; G 1184 +U 1681 ; WX 602 ; N uni0691 ; G 1185 +U 1688 ; WX 602 ; N uni0698 ; G 1186 +U 1700 ; WX 602 ; N uni06A4 ; G 1187 +U 1705 ; WX 602 ; N uni06A9 ; G 1188 +U 1711 ; WX 602 ; N uni06AF ; G 1189 +U 1726 ; WX 602 ; N uni06BE ; G 1190 +U 1740 ; WX 602 ; N uni06CC ; G 1191 +U 1776 ; WX 602 ; N uni06F0 ; G 1192 +U 1777 ; WX 602 ; N uni06F1 ; G 1193 +U 1778 ; WX 602 ; N uni06F2 ; G 1194 +U 1779 ; WX 602 ; N uni06F3 ; G 1195 +U 1780 ; WX 602 ; N uni06F4 ; G 1196 +U 1781 ; WX 602 ; N uni06F5 ; G 1197 +U 1782 ; WX 602 ; N uni06F6 ; G 1198 +U 1783 ; WX 602 ; N uni06F7 ; G 1199 +U 1784 ; WX 602 ; N uni06F8 ; G 1200 +U 1785 ; WX 602 ; N uni06F9 ; G 1201 +U 3647 ; WX 602 ; N uni0E3F ; G 1202 +U 3713 ; WX 602 ; N uni0E81 ; G 1203 +U 3714 ; WX 602 ; N uni0E82 ; G 1204 +U 3716 ; WX 602 ; N uni0E84 ; G 1205 +U 3719 ; WX 602 ; N uni0E87 ; G 1206 +U 3720 ; WX 602 ; N uni0E88 ; G 1207 +U 3722 ; WX 602 ; N uni0E8A ; G 1208 +U 3725 ; WX 602 ; N uni0E8D ; G 1209 +U 3732 ; WX 602 ; N uni0E94 ; G 1210 +U 3733 ; WX 602 ; N uni0E95 ; G 1211 +U 3734 ; WX 602 ; N uni0E96 ; G 1212 +U 3735 ; WX 602 ; N uni0E97 ; G 1213 +U 3737 ; WX 602 ; N uni0E99 ; G 1214 +U 3738 ; WX 602 ; N uni0E9A ; G 1215 +U 3739 ; WX 602 ; N uni0E9B ; G 1216 +U 3740 ; WX 602 ; N uni0E9C ; G 1217 +U 3741 ; WX 602 ; N uni0E9D ; G 1218 +U 3742 ; WX 602 ; N uni0E9E ; G 1219 +U 3743 ; WX 602 ; N uni0E9F ; G 1220 +U 3745 ; WX 602 ; N uni0EA1 ; G 1221 +U 3746 ; WX 602 ; N uni0EA2 ; G 1222 +U 3747 ; WX 602 ; N uni0EA3 ; G 1223 +U 3749 ; WX 602 ; N uni0EA5 ; G 1224 +U 3751 ; WX 602 ; N uni0EA7 ; G 1225 +U 3754 ; WX 602 ; N uni0EAA ; G 1226 +U 3755 ; WX 602 ; N uni0EAB ; G 1227 +U 3757 ; WX 602 ; N uni0EAD ; G 1228 +U 3758 ; WX 602 ; N uni0EAE ; G 1229 +U 3759 ; WX 602 ; N uni0EAF ; G 1230 +U 3760 ; WX 602 ; N uni0EB0 ; G 1231 +U 3761 ; WX 602 ; N uni0EB1 ; G 1232 +U 3762 ; WX 602 ; N uni0EB2 ; G 1233 +U 3763 ; WX 602 ; N uni0EB3 ; G 1234 +U 3764 ; WX 602 ; N uni0EB4 ; G 1235 +U 3765 ; WX 602 ; N uni0EB5 ; G 1236 +U 3766 ; WX 602 ; N uni0EB6 ; G 1237 +U 3767 ; WX 602 ; N uni0EB7 ; G 1238 +U 3768 ; WX 602 ; N uni0EB8 ; G 1239 +U 3769 ; WX 602 ; N uni0EB9 ; G 1240 +U 3771 ; WX 602 ; N uni0EBB ; G 1241 +U 3772 ; WX 602 ; N uni0EBC ; G 1242 +U 3784 ; WX 602 ; N uni0EC8 ; G 1243 +U 3785 ; WX 602 ; N uni0EC9 ; G 1244 +U 3786 ; WX 602 ; N uni0ECA ; G 1245 +U 3787 ; WX 602 ; N uni0ECB ; G 1246 +U 3788 ; WX 602 ; N uni0ECC ; G 1247 +U 3789 ; WX 602 ; N uni0ECD ; G 1248 +U 4304 ; WX 602 ; N uni10D0 ; G 1249 +U 4305 ; WX 602 ; N uni10D1 ; G 1250 +U 4306 ; WX 602 ; N uni10D2 ; G 1251 +U 4307 ; WX 602 ; N uni10D3 ; G 1252 +U 4308 ; WX 602 ; N uni10D4 ; G 1253 +U 4309 ; WX 602 ; N uni10D5 ; G 1254 +U 4310 ; WX 602 ; N uni10D6 ; G 1255 +U 4311 ; WX 602 ; N uni10D7 ; G 1256 +U 4312 ; WX 602 ; N uni10D8 ; G 1257 +U 4313 ; WX 602 ; N uni10D9 ; G 1258 +U 4314 ; WX 602 ; N uni10DA ; G 1259 +U 4315 ; WX 602 ; N uni10DB ; G 1260 +U 4316 ; WX 602 ; N uni10DC ; G 1261 +U 4317 ; WX 602 ; N uni10DD ; G 1262 +U 4318 ; WX 602 ; N uni10DE ; G 1263 +U 4319 ; WX 602 ; N uni10DF ; G 1264 +U 4320 ; WX 602 ; N uni10E0 ; G 1265 +U 4321 ; WX 602 ; N uni10E1 ; G 1266 +U 4322 ; WX 602 ; N uni10E2 ; G 1267 +U 4323 ; WX 602 ; N uni10E3 ; G 1268 +U 4324 ; WX 602 ; N uni10E4 ; G 1269 +U 4325 ; WX 602 ; N uni10E5 ; G 1270 +U 4326 ; WX 602 ; N uni10E6 ; G 1271 +U 4327 ; WX 602 ; N uni10E7 ; G 1272 +U 4328 ; WX 602 ; N uni10E8 ; G 1273 +U 4329 ; WX 602 ; N uni10E9 ; G 1274 +U 4330 ; WX 602 ; N uni10EA ; G 1275 +U 4331 ; WX 602 ; N uni10EB ; G 1276 +U 4332 ; WX 602 ; N uni10EC ; G 1277 +U 4333 ; WX 602 ; N uni10ED ; G 1278 +U 4334 ; WX 602 ; N uni10EE ; G 1279 +U 4335 ; WX 602 ; N uni10EF ; G 1280 +U 4336 ; WX 602 ; N uni10F0 ; G 1281 +U 4337 ; WX 602 ; N uni10F1 ; G 1282 +U 4338 ; WX 602 ; N uni10F2 ; G 1283 +U 4339 ; WX 602 ; N uni10F3 ; G 1284 +U 4340 ; WX 602 ; N uni10F4 ; G 1285 +U 4341 ; WX 602 ; N uni10F5 ; G 1286 +U 4342 ; WX 602 ; N uni10F6 ; G 1287 +U 4343 ; WX 602 ; N uni10F7 ; G 1288 +U 4344 ; WX 602 ; N uni10F8 ; G 1289 +U 4345 ; WX 602 ; N uni10F9 ; G 1290 +U 4346 ; WX 602 ; N uni10FA ; G 1291 +U 4347 ; WX 602 ; N uni10FB ; G 1292 +U 4348 ; WX 602 ; N uni10FC ; G 1293 +U 7426 ; WX 602 ; N uni1D02 ; G 1294 +U 7432 ; WX 602 ; N uni1D08 ; G 1295 +U 7433 ; WX 602 ; N uni1D09 ; G 1296 +U 7444 ; WX 602 ; N uni1D14 ; G 1297 +U 7446 ; WX 602 ; N uni1D16 ; G 1298 +U 7447 ; WX 602 ; N uni1D17 ; G 1299 +U 7453 ; WX 602 ; N uni1D1D ; G 1300 +U 7454 ; WX 602 ; N uni1D1E ; G 1301 +U 7455 ; WX 602 ; N uni1D1F ; G 1302 +U 7468 ; WX 602 ; N uni1D2C ; G 1303 +U 7469 ; WX 602 ; N uni1D2D ; G 1304 +U 7470 ; WX 602 ; N uni1D2E ; G 1305 +U 7472 ; WX 602 ; N uni1D30 ; G 1306 +U 7473 ; WX 602 ; N uni1D31 ; G 1307 +U 7474 ; WX 602 ; N uni1D32 ; G 1308 +U 7475 ; WX 602 ; N uni1D33 ; G 1309 +U 7476 ; WX 602 ; N uni1D34 ; G 1310 +U 7477 ; WX 602 ; N uni1D35 ; G 1311 +U 7478 ; WX 602 ; N uni1D36 ; G 1312 +U 7479 ; WX 602 ; N uni1D37 ; G 1313 +U 7480 ; WX 602 ; N uni1D38 ; G 1314 +U 7481 ; WX 602 ; N uni1D39 ; G 1315 +U 7482 ; WX 602 ; N uni1D3A ; G 1316 +U 7483 ; WX 602 ; N uni1D3B ; G 1317 +U 7484 ; WX 602 ; N uni1D3C ; G 1318 +U 7486 ; WX 602 ; N uni1D3E ; G 1319 +U 7487 ; WX 602 ; N uni1D3F ; G 1320 +U 7488 ; WX 602 ; N uni1D40 ; G 1321 +U 7489 ; WX 602 ; N uni1D41 ; G 1322 +U 7490 ; WX 602 ; N uni1D42 ; G 1323 +U 7491 ; WX 602 ; N uni1D43 ; G 1324 +U 7492 ; WX 602 ; N uni1D44 ; G 1325 +U 7493 ; WX 602 ; N uni1D45 ; G 1326 +U 7494 ; WX 602 ; N uni1D46 ; G 1327 +U 7495 ; WX 602 ; N uni1D47 ; G 1328 +U 7496 ; WX 602 ; N uni1D48 ; G 1329 +U 7497 ; WX 602 ; N uni1D49 ; G 1330 +U 7498 ; WX 602 ; N uni1D4A ; G 1331 +U 7499 ; WX 602 ; N uni1D4B ; G 1332 +U 7500 ; WX 602 ; N uni1D4C ; G 1333 +U 7501 ; WX 602 ; N uni1D4D ; G 1334 +U 7502 ; WX 602 ; N uni1D4E ; G 1335 +U 7503 ; WX 602 ; N uni1D4F ; G 1336 +U 7504 ; WX 602 ; N uni1D50 ; G 1337 +U 7505 ; WX 602 ; N uni1D51 ; G 1338 +U 7506 ; WX 602 ; N uni1D52 ; G 1339 +U 7507 ; WX 602 ; N uni1D53 ; G 1340 +U 7508 ; WX 602 ; N uni1D54 ; G 1341 +U 7509 ; WX 602 ; N uni1D55 ; G 1342 +U 7510 ; WX 602 ; N uni1D56 ; G 1343 +U 7511 ; WX 602 ; N uni1D57 ; G 1344 +U 7512 ; WX 602 ; N uni1D58 ; G 1345 +U 7513 ; WX 602 ; N uni1D59 ; G 1346 +U 7514 ; WX 602 ; N uni1D5A ; G 1347 +U 7515 ; WX 602 ; N uni1D5B ; G 1348 +U 7522 ; WX 602 ; N uni1D62 ; G 1349 +U 7523 ; WX 602 ; N uni1D63 ; G 1350 +U 7524 ; WX 602 ; N uni1D64 ; G 1351 +U 7525 ; WX 602 ; N uni1D65 ; G 1352 +U 7543 ; WX 602 ; N uni1D77 ; G 1353 +U 7544 ; WX 602 ; N uni1D78 ; G 1354 +U 7547 ; WX 602 ; N uni1D7B ; G 1355 +U 7557 ; WX 602 ; N uni1D85 ; G 1356 +U 7579 ; WX 602 ; N uni1D9B ; G 1357 +U 7580 ; WX 602 ; N uni1D9C ; G 1358 +U 7581 ; WX 602 ; N uni1D9D ; G 1359 +U 7582 ; WX 602 ; N uni1D9E ; G 1360 +U 7583 ; WX 602 ; N uni1D9F ; G 1361 +U 7584 ; WX 602 ; N uni1DA0 ; G 1362 +U 7585 ; WX 602 ; N uni1DA1 ; G 1363 +U 7586 ; WX 602 ; N uni1DA2 ; G 1364 +U 7587 ; WX 602 ; N uni1DA3 ; G 1365 +U 7588 ; WX 602 ; N uni1DA4 ; G 1366 +U 7589 ; WX 602 ; N uni1DA5 ; G 1367 +U 7590 ; WX 602 ; N uni1DA6 ; G 1368 +U 7591 ; WX 602 ; N uni1DA7 ; G 1369 +U 7592 ; WX 602 ; N uni1DA8 ; G 1370 +U 7593 ; WX 602 ; N uni1DA9 ; G 1371 +U 7594 ; WX 602 ; N uni1DAA ; G 1372 +U 7595 ; WX 602 ; N uni1DAB ; G 1373 +U 7596 ; WX 602 ; N uni1DAC ; G 1374 +U 7597 ; WX 602 ; N uni1DAD ; G 1375 +U 7598 ; WX 602 ; N uni1DAE ; G 1376 +U 7599 ; WX 602 ; N uni1DAF ; G 1377 +U 7600 ; WX 602 ; N uni1DB0 ; G 1378 +U 7601 ; WX 602 ; N uni1DB1 ; G 1379 +U 7602 ; WX 602 ; N uni1DB2 ; G 1380 +U 7603 ; WX 602 ; N uni1DB3 ; G 1381 +U 7604 ; WX 602 ; N uni1DB4 ; G 1382 +U 7605 ; WX 602 ; N uni1DB5 ; G 1383 +U 7606 ; WX 602 ; N uni1DB6 ; G 1384 +U 7607 ; WX 602 ; N uni1DB7 ; G 1385 +U 7609 ; WX 602 ; N uni1DB9 ; G 1386 +U 7610 ; WX 602 ; N uni1DBA ; G 1387 +U 7611 ; WX 602 ; N uni1DBB ; G 1388 +U 7612 ; WX 602 ; N uni1DBC ; G 1389 +U 7613 ; WX 602 ; N uni1DBD ; G 1390 +U 7614 ; WX 602 ; N uni1DBE ; G 1391 +U 7615 ; WX 602 ; N uni1DBF ; G 1392 +U 7680 ; WX 602 ; N uni1E00 ; G 1393 +U 7681 ; WX 602 ; N uni1E01 ; G 1394 +U 7682 ; WX 602 ; N uni1E02 ; G 1395 +U 7683 ; WX 602 ; N uni1E03 ; G 1396 +U 7684 ; WX 602 ; N uni1E04 ; G 1397 +U 7685 ; WX 602 ; N uni1E05 ; G 1398 +U 7686 ; WX 602 ; N uni1E06 ; G 1399 +U 7687 ; WX 602 ; N uni1E07 ; G 1400 +U 7688 ; WX 602 ; N uni1E08 ; G 1401 +U 7689 ; WX 602 ; N uni1E09 ; G 1402 +U 7690 ; WX 602 ; N uni1E0A ; G 1403 +U 7691 ; WX 602 ; N uni1E0B ; G 1404 +U 7692 ; WX 602 ; N uni1E0C ; G 1405 +U 7693 ; WX 602 ; N uni1E0D ; G 1406 +U 7694 ; WX 602 ; N uni1E0E ; G 1407 +U 7695 ; WX 602 ; N uni1E0F ; G 1408 +U 7696 ; WX 602 ; N uni1E10 ; G 1409 +U 7697 ; WX 602 ; N uni1E11 ; G 1410 +U 7698 ; WX 602 ; N uni1E12 ; G 1411 +U 7699 ; WX 602 ; N uni1E13 ; G 1412 +U 7704 ; WX 602 ; N uni1E18 ; G 1413 +U 7705 ; WX 602 ; N uni1E19 ; G 1414 +U 7706 ; WX 602 ; N uni1E1A ; G 1415 +U 7707 ; WX 602 ; N uni1E1B ; G 1416 +U 7708 ; WX 602 ; N uni1E1C ; G 1417 +U 7709 ; WX 602 ; N uni1E1D ; G 1418 +U 7710 ; WX 602 ; N uni1E1E ; G 1419 +U 7711 ; WX 602 ; N uni1E1F ; G 1420 +U 7712 ; WX 602 ; N uni1E20 ; G 1421 +U 7713 ; WX 602 ; N uni1E21 ; G 1422 +U 7714 ; WX 602 ; N uni1E22 ; G 1423 +U 7715 ; WX 602 ; N uni1E23 ; G 1424 +U 7716 ; WX 602 ; N uni1E24 ; G 1425 +U 7717 ; WX 602 ; N uni1E25 ; G 1426 +U 7718 ; WX 602 ; N uni1E26 ; G 1427 +U 7719 ; WX 602 ; N uni1E27 ; G 1428 +U 7720 ; WX 602 ; N uni1E28 ; G 1429 +U 7721 ; WX 602 ; N uni1E29 ; G 1430 +U 7722 ; WX 602 ; N uni1E2A ; G 1431 +U 7723 ; WX 602 ; N uni1E2B ; G 1432 +U 7724 ; WX 602 ; N uni1E2C ; G 1433 +U 7725 ; WX 602 ; N uni1E2D ; G 1434 +U 7728 ; WX 602 ; N uni1E30 ; G 1435 +U 7729 ; WX 602 ; N uni1E31 ; G 1436 +U 7730 ; WX 602 ; N uni1E32 ; G 1437 +U 7731 ; WX 602 ; N uni1E33 ; G 1438 +U 7732 ; WX 602 ; N uni1E34 ; G 1439 +U 7733 ; WX 602 ; N uni1E35 ; G 1440 +U 7734 ; WX 602 ; N uni1E36 ; G 1441 +U 7735 ; WX 602 ; N uni1E37 ; G 1442 +U 7736 ; WX 602 ; N uni1E38 ; G 1443 +U 7737 ; WX 602 ; N uni1E39 ; G 1444 +U 7738 ; WX 602 ; N uni1E3A ; G 1445 +U 7739 ; WX 602 ; N uni1E3B ; G 1446 +U 7740 ; WX 602 ; N uni1E3C ; G 1447 +U 7741 ; WX 602 ; N uni1E3D ; G 1448 +U 7742 ; WX 602 ; N uni1E3E ; G 1449 +U 7743 ; WX 602 ; N uni1E3F ; G 1450 +U 7744 ; WX 602 ; N uni1E40 ; G 1451 +U 7745 ; WX 602 ; N uni1E41 ; G 1452 +U 7746 ; WX 602 ; N uni1E42 ; G 1453 +U 7747 ; WX 602 ; N uni1E43 ; G 1454 +U 7748 ; WX 602 ; N uni1E44 ; G 1455 +U 7749 ; WX 602 ; N uni1E45 ; G 1456 +U 7750 ; WX 602 ; N uni1E46 ; G 1457 +U 7751 ; WX 602 ; N uni1E47 ; G 1458 +U 7752 ; WX 602 ; N uni1E48 ; G 1459 +U 7753 ; WX 602 ; N uni1E49 ; G 1460 +U 7754 ; WX 602 ; N uni1E4A ; G 1461 +U 7755 ; WX 602 ; N uni1E4B ; G 1462 +U 7756 ; WX 602 ; N uni1E4C ; G 1463 +U 7757 ; WX 602 ; N uni1E4D ; G 1464 +U 7764 ; WX 602 ; N uni1E54 ; G 1465 +U 7765 ; WX 602 ; N uni1E55 ; G 1466 +U 7766 ; WX 602 ; N uni1E56 ; G 1467 +U 7767 ; WX 602 ; N uni1E57 ; G 1468 +U 7768 ; WX 602 ; N uni1E58 ; G 1469 +U 7769 ; WX 602 ; N uni1E59 ; G 1470 +U 7770 ; WX 602 ; N uni1E5A ; G 1471 +U 7771 ; WX 602 ; N uni1E5B ; G 1472 +U 7772 ; WX 602 ; N uni1E5C ; G 1473 +U 7773 ; WX 602 ; N uni1E5D ; G 1474 +U 7774 ; WX 602 ; N uni1E5E ; G 1475 +U 7775 ; WX 602 ; N uni1E5F ; G 1476 +U 7776 ; WX 602 ; N uni1E60 ; G 1477 +U 7777 ; WX 602 ; N uni1E61 ; G 1478 +U 7778 ; WX 602 ; N uni1E62 ; G 1479 +U 7779 ; WX 602 ; N uni1E63 ; G 1480 +U 7784 ; WX 602 ; N uni1E68 ; G 1481 +U 7785 ; WX 602 ; N uni1E69 ; G 1482 +U 7786 ; WX 602 ; N uni1E6A ; G 1483 +U 7787 ; WX 602 ; N uni1E6B ; G 1484 +U 7788 ; WX 602 ; N uni1E6C ; G 1485 +U 7789 ; WX 602 ; N uni1E6D ; G 1486 +U 7790 ; WX 602 ; N uni1E6E ; G 1487 +U 7791 ; WX 602 ; N uni1E6F ; G 1488 +U 7792 ; WX 602 ; N uni1E70 ; G 1489 +U 7793 ; WX 602 ; N uni1E71 ; G 1490 +U 7794 ; WX 602 ; N uni1E72 ; G 1491 +U 7795 ; WX 602 ; N uni1E73 ; G 1492 +U 7796 ; WX 602 ; N uni1E74 ; G 1493 +U 7797 ; WX 602 ; N uni1E75 ; G 1494 +U 7798 ; WX 602 ; N uni1E76 ; G 1495 +U 7799 ; WX 602 ; N uni1E77 ; G 1496 +U 7800 ; WX 602 ; N uni1E78 ; G 1497 +U 7801 ; WX 602 ; N uni1E79 ; G 1498 +U 7804 ; WX 602 ; N uni1E7C ; G 1499 +U 7805 ; WX 602 ; N uni1E7D ; G 1500 +U 7806 ; WX 602 ; N uni1E7E ; G 1501 +U 7807 ; WX 602 ; N uni1E7F ; G 1502 +U 7808 ; WX 602 ; N Wgrave ; G 1503 +U 7809 ; WX 602 ; N wgrave ; G 1504 +U 7810 ; WX 602 ; N Wacute ; G 1505 +U 7811 ; WX 602 ; N wacute ; G 1506 +U 7812 ; WX 602 ; N Wdieresis ; G 1507 +U 7813 ; WX 602 ; N wdieresis ; G 1508 +U 7814 ; WX 602 ; N uni1E86 ; G 1509 +U 7815 ; WX 602 ; N uni1E87 ; G 1510 +U 7816 ; WX 602 ; N uni1E88 ; G 1511 +U 7817 ; WX 602 ; N uni1E89 ; G 1512 +U 7818 ; WX 602 ; N uni1E8A ; G 1513 +U 7819 ; WX 602 ; N uni1E8B ; G 1514 +U 7820 ; WX 602 ; N uni1E8C ; G 1515 +U 7821 ; WX 602 ; N uni1E8D ; G 1516 +U 7822 ; WX 602 ; N uni1E8E ; G 1517 +U 7823 ; WX 602 ; N uni1E8F ; G 1518 +U 7824 ; WX 602 ; N uni1E90 ; G 1519 +U 7825 ; WX 602 ; N uni1E91 ; G 1520 +U 7826 ; WX 602 ; N uni1E92 ; G 1521 +U 7827 ; WX 602 ; N uni1E93 ; G 1522 +U 7828 ; WX 602 ; N uni1E94 ; G 1523 +U 7829 ; WX 602 ; N uni1E95 ; G 1524 +U 7830 ; WX 602 ; N uni1E96 ; G 1525 +U 7831 ; WX 602 ; N uni1E97 ; G 1526 +U 7832 ; WX 602 ; N uni1E98 ; G 1527 +U 7833 ; WX 602 ; N uni1E99 ; G 1528 +U 7835 ; WX 602 ; N uni1E9B ; G 1529 +U 7839 ; WX 602 ; N uni1E9F ; G 1530 +U 7840 ; WX 602 ; N uni1EA0 ; G 1531 +U 7841 ; WX 602 ; N uni1EA1 ; G 1532 +U 7852 ; WX 602 ; N uni1EAC ; G 1533 +U 7853 ; WX 602 ; N uni1EAD ; G 1534 +U 7856 ; WX 602 ; N uni1EB0 ; G 1535 +U 7857 ; WX 602 ; N uni1EB1 ; G 1536 +U 7862 ; WX 602 ; N uni1EB6 ; G 1537 +U 7863 ; WX 602 ; N uni1EB7 ; G 1538 +U 7864 ; WX 602 ; N uni1EB8 ; G 1539 +U 7865 ; WX 602 ; N uni1EB9 ; G 1540 +U 7868 ; WX 602 ; N uni1EBC ; G 1541 +U 7869 ; WX 602 ; N uni1EBD ; G 1542 +U 7878 ; WX 602 ; N uni1EC6 ; G 1543 +U 7879 ; WX 602 ; N uni1EC7 ; G 1544 +U 7882 ; WX 602 ; N uni1ECA ; G 1545 +U 7883 ; WX 602 ; N uni1ECB ; G 1546 +U 7884 ; WX 602 ; N uni1ECC ; G 1547 +U 7885 ; WX 602 ; N uni1ECD ; G 1548 +U 7896 ; WX 602 ; N uni1ED8 ; G 1549 +U 7897 ; WX 602 ; N uni1ED9 ; G 1550 +U 7898 ; WX 602 ; N uni1EDA ; G 1551 +U 7899 ; WX 602 ; N uni1EDB ; G 1552 +U 7900 ; WX 602 ; N uni1EDC ; G 1553 +U 7901 ; WX 602 ; N uni1EDD ; G 1554 +U 7904 ; WX 602 ; N uni1EE0 ; G 1555 +U 7905 ; WX 602 ; N uni1EE1 ; G 1556 +U 7906 ; WX 602 ; N uni1EE2 ; G 1557 +U 7907 ; WX 602 ; N uni1EE3 ; G 1558 +U 7908 ; WX 602 ; N uni1EE4 ; G 1559 +U 7909 ; WX 602 ; N uni1EE5 ; G 1560 +U 7912 ; WX 602 ; N uni1EE8 ; G 1561 +U 7913 ; WX 602 ; N uni1EE9 ; G 1562 +U 7914 ; WX 602 ; N uni1EEA ; G 1563 +U 7915 ; WX 602 ; N uni1EEB ; G 1564 +U 7918 ; WX 602 ; N uni1EEE ; G 1565 +U 7919 ; WX 602 ; N uni1EEF ; G 1566 +U 7920 ; WX 602 ; N uni1EF0 ; G 1567 +U 7921 ; WX 602 ; N uni1EF1 ; G 1568 +U 7922 ; WX 602 ; N Ygrave ; G 1569 +U 7923 ; WX 602 ; N ygrave ; G 1570 +U 7924 ; WX 602 ; N uni1EF4 ; G 1571 +U 7925 ; WX 602 ; N uni1EF5 ; G 1572 +U 7928 ; WX 602 ; N uni1EF8 ; G 1573 +U 7929 ; WX 602 ; N uni1EF9 ; G 1574 +U 7936 ; WX 602 ; N uni1F00 ; G 1575 +U 7937 ; WX 602 ; N uni1F01 ; G 1576 +U 7938 ; WX 602 ; N uni1F02 ; G 1577 +U 7939 ; WX 602 ; N uni1F03 ; G 1578 +U 7940 ; WX 602 ; N uni1F04 ; G 1579 +U 7941 ; WX 602 ; N uni1F05 ; G 1580 +U 7942 ; WX 602 ; N uni1F06 ; G 1581 +U 7943 ; WX 602 ; N uni1F07 ; G 1582 +U 7944 ; WX 602 ; N uni1F08 ; G 1583 +U 7945 ; WX 602 ; N uni1F09 ; G 1584 +U 7946 ; WX 602 ; N uni1F0A ; G 1585 +U 7947 ; WX 602 ; N uni1F0B ; G 1586 +U 7948 ; WX 602 ; N uni1F0C ; G 1587 +U 7949 ; WX 602 ; N uni1F0D ; G 1588 +U 7950 ; WX 602 ; N uni1F0E ; G 1589 +U 7951 ; WX 602 ; N uni1F0F ; G 1590 +U 7952 ; WX 602 ; N uni1F10 ; G 1591 +U 7953 ; WX 602 ; N uni1F11 ; G 1592 +U 7954 ; WX 602 ; N uni1F12 ; G 1593 +U 7955 ; WX 602 ; N uni1F13 ; G 1594 +U 7956 ; WX 602 ; N uni1F14 ; G 1595 +U 7957 ; WX 602 ; N uni1F15 ; G 1596 +U 7960 ; WX 602 ; N uni1F18 ; G 1597 +U 7961 ; WX 602 ; N uni1F19 ; G 1598 +U 7962 ; WX 602 ; N uni1F1A ; G 1599 +U 7963 ; WX 602 ; N uni1F1B ; G 1600 +U 7964 ; WX 602 ; N uni1F1C ; G 1601 +U 7965 ; WX 602 ; N uni1F1D ; G 1602 +U 7968 ; WX 602 ; N uni1F20 ; G 1603 +U 7969 ; WX 602 ; N uni1F21 ; G 1604 +U 7970 ; WX 602 ; N uni1F22 ; G 1605 +U 7971 ; WX 602 ; N uni1F23 ; G 1606 +U 7972 ; WX 602 ; N uni1F24 ; G 1607 +U 7973 ; WX 602 ; N uni1F25 ; G 1608 +U 7974 ; WX 602 ; N uni1F26 ; G 1609 +U 7975 ; WX 602 ; N uni1F27 ; G 1610 +U 7976 ; WX 602 ; N uni1F28 ; G 1611 +U 7977 ; WX 602 ; N uni1F29 ; G 1612 +U 7978 ; WX 602 ; N uni1F2A ; G 1613 +U 7979 ; WX 602 ; N uni1F2B ; G 1614 +U 7980 ; WX 602 ; N uni1F2C ; G 1615 +U 7981 ; WX 602 ; N uni1F2D ; G 1616 +U 7982 ; WX 602 ; N uni1F2E ; G 1617 +U 7983 ; WX 602 ; N uni1F2F ; G 1618 +U 7984 ; WX 602 ; N uni1F30 ; G 1619 +U 7985 ; WX 602 ; N uni1F31 ; G 1620 +U 7986 ; WX 602 ; N uni1F32 ; G 1621 +U 7987 ; WX 602 ; N uni1F33 ; G 1622 +U 7988 ; WX 602 ; N uni1F34 ; G 1623 +U 7989 ; WX 602 ; N uni1F35 ; G 1624 +U 7990 ; WX 602 ; N uni1F36 ; G 1625 +U 7991 ; WX 602 ; N uni1F37 ; G 1626 +U 7992 ; WX 602 ; N uni1F38 ; G 1627 +U 7993 ; WX 602 ; N uni1F39 ; G 1628 +U 7994 ; WX 602 ; N uni1F3A ; G 1629 +U 7995 ; WX 602 ; N uni1F3B ; G 1630 +U 7996 ; WX 602 ; N uni1F3C ; G 1631 +U 7997 ; WX 602 ; N uni1F3D ; G 1632 +U 7998 ; WX 602 ; N uni1F3E ; G 1633 +U 7999 ; WX 602 ; N uni1F3F ; G 1634 +U 8000 ; WX 602 ; N uni1F40 ; G 1635 +U 8001 ; WX 602 ; N uni1F41 ; G 1636 +U 8002 ; WX 602 ; N uni1F42 ; G 1637 +U 8003 ; WX 602 ; N uni1F43 ; G 1638 +U 8004 ; WX 602 ; N uni1F44 ; G 1639 +U 8005 ; WX 602 ; N uni1F45 ; G 1640 +U 8008 ; WX 602 ; N uni1F48 ; G 1641 +U 8009 ; WX 602 ; N uni1F49 ; G 1642 +U 8010 ; WX 602 ; N uni1F4A ; G 1643 +U 8011 ; WX 602 ; N uni1F4B ; G 1644 +U 8012 ; WX 602 ; N uni1F4C ; G 1645 +U 8013 ; WX 602 ; N uni1F4D ; G 1646 +U 8016 ; WX 602 ; N uni1F50 ; G 1647 +U 8017 ; WX 602 ; N uni1F51 ; G 1648 +U 8018 ; WX 602 ; N uni1F52 ; G 1649 +U 8019 ; WX 602 ; N uni1F53 ; G 1650 +U 8020 ; WX 602 ; N uni1F54 ; G 1651 +U 8021 ; WX 602 ; N uni1F55 ; G 1652 +U 8022 ; WX 602 ; N uni1F56 ; G 1653 +U 8023 ; WX 602 ; N uni1F57 ; G 1654 +U 8025 ; WX 602 ; N uni1F59 ; G 1655 +U 8027 ; WX 602 ; N uni1F5B ; G 1656 +U 8029 ; WX 602 ; N uni1F5D ; G 1657 +U 8031 ; WX 602 ; N uni1F5F ; G 1658 +U 8032 ; WX 602 ; N uni1F60 ; G 1659 +U 8033 ; WX 602 ; N uni1F61 ; G 1660 +U 8034 ; WX 602 ; N uni1F62 ; G 1661 +U 8035 ; WX 602 ; N uni1F63 ; G 1662 +U 8036 ; WX 602 ; N uni1F64 ; G 1663 +U 8037 ; WX 602 ; N uni1F65 ; G 1664 +U 8038 ; WX 602 ; N uni1F66 ; G 1665 +U 8039 ; WX 602 ; N uni1F67 ; G 1666 +U 8040 ; WX 602 ; N uni1F68 ; G 1667 +U 8041 ; WX 602 ; N uni1F69 ; G 1668 +U 8042 ; WX 602 ; N uni1F6A ; G 1669 +U 8043 ; WX 602 ; N uni1F6B ; G 1670 +U 8044 ; WX 602 ; N uni1F6C ; G 1671 +U 8045 ; WX 602 ; N uni1F6D ; G 1672 +U 8046 ; WX 602 ; N uni1F6E ; G 1673 +U 8047 ; WX 602 ; N uni1F6F ; G 1674 +U 8048 ; WX 602 ; N uni1F70 ; G 1675 +U 8049 ; WX 602 ; N uni1F71 ; G 1676 +U 8050 ; WX 602 ; N uni1F72 ; G 1677 +U 8051 ; WX 602 ; N uni1F73 ; G 1678 +U 8052 ; WX 602 ; N uni1F74 ; G 1679 +U 8053 ; WX 602 ; N uni1F75 ; G 1680 +U 8054 ; WX 602 ; N uni1F76 ; G 1681 +U 8055 ; WX 602 ; N uni1F77 ; G 1682 +U 8056 ; WX 602 ; N uni1F78 ; G 1683 +U 8057 ; WX 602 ; N uni1F79 ; G 1684 +U 8058 ; WX 602 ; N uni1F7A ; G 1685 +U 8059 ; WX 602 ; N uni1F7B ; G 1686 +U 8060 ; WX 602 ; N uni1F7C ; G 1687 +U 8061 ; WX 602 ; N uni1F7D ; G 1688 +U 8064 ; WX 602 ; N uni1F80 ; G 1689 +U 8065 ; WX 602 ; N uni1F81 ; G 1690 +U 8066 ; WX 602 ; N uni1F82 ; G 1691 +U 8067 ; WX 602 ; N uni1F83 ; G 1692 +U 8068 ; WX 602 ; N uni1F84 ; G 1693 +U 8069 ; WX 602 ; N uni1F85 ; G 1694 +U 8070 ; WX 602 ; N uni1F86 ; G 1695 +U 8071 ; WX 602 ; N uni1F87 ; G 1696 +U 8072 ; WX 602 ; N uni1F88 ; G 1697 +U 8073 ; WX 602 ; N uni1F89 ; G 1698 +U 8074 ; WX 602 ; N uni1F8A ; G 1699 +U 8075 ; WX 602 ; N uni1F8B ; G 1700 +U 8076 ; WX 602 ; N uni1F8C ; G 1701 +U 8077 ; WX 602 ; N uni1F8D ; G 1702 +U 8078 ; WX 602 ; N uni1F8E ; G 1703 +U 8079 ; WX 602 ; N uni1F8F ; G 1704 +U 8080 ; WX 602 ; N uni1F90 ; G 1705 +U 8081 ; WX 602 ; N uni1F91 ; G 1706 +U 8082 ; WX 602 ; N uni1F92 ; G 1707 +U 8083 ; WX 602 ; N uni1F93 ; G 1708 +U 8084 ; WX 602 ; N uni1F94 ; G 1709 +U 8085 ; WX 602 ; N uni1F95 ; G 1710 +U 8086 ; WX 602 ; N uni1F96 ; G 1711 +U 8087 ; WX 602 ; N uni1F97 ; G 1712 +U 8088 ; WX 602 ; N uni1F98 ; G 1713 +U 8089 ; WX 602 ; N uni1F99 ; G 1714 +U 8090 ; WX 602 ; N uni1F9A ; G 1715 +U 8091 ; WX 602 ; N uni1F9B ; G 1716 +U 8092 ; WX 602 ; N uni1F9C ; G 1717 +U 8093 ; WX 602 ; N uni1F9D ; G 1718 +U 8094 ; WX 602 ; N uni1F9E ; G 1719 +U 8095 ; WX 602 ; N uni1F9F ; G 1720 +U 8096 ; WX 602 ; N uni1FA0 ; G 1721 +U 8097 ; WX 602 ; N uni1FA1 ; G 1722 +U 8098 ; WX 602 ; N uni1FA2 ; G 1723 +U 8099 ; WX 602 ; N uni1FA3 ; G 1724 +U 8100 ; WX 602 ; N uni1FA4 ; G 1725 +U 8101 ; WX 602 ; N uni1FA5 ; G 1726 +U 8102 ; WX 602 ; N uni1FA6 ; G 1727 +U 8103 ; WX 602 ; N uni1FA7 ; G 1728 +U 8104 ; WX 602 ; N uni1FA8 ; G 1729 +U 8105 ; WX 602 ; N uni1FA9 ; G 1730 +U 8106 ; WX 602 ; N uni1FAA ; G 1731 +U 8107 ; WX 602 ; N uni1FAB ; G 1732 +U 8108 ; WX 602 ; N uni1FAC ; G 1733 +U 8109 ; WX 602 ; N uni1FAD ; G 1734 +U 8110 ; WX 602 ; N uni1FAE ; G 1735 +U 8111 ; WX 602 ; N uni1FAF ; G 1736 +U 8112 ; WX 602 ; N uni1FB0 ; G 1737 +U 8113 ; WX 602 ; N uni1FB1 ; G 1738 +U 8114 ; WX 602 ; N uni1FB2 ; G 1739 +U 8115 ; WX 602 ; N uni1FB3 ; G 1740 +U 8116 ; WX 602 ; N uni1FB4 ; G 1741 +U 8118 ; WX 602 ; N uni1FB6 ; G 1742 +U 8119 ; WX 602 ; N uni1FB7 ; G 1743 +U 8120 ; WX 602 ; N uni1FB8 ; G 1744 +U 8121 ; WX 602 ; N uni1FB9 ; G 1745 +U 8122 ; WX 602 ; N uni1FBA ; G 1746 +U 8123 ; WX 602 ; N uni1FBB ; G 1747 +U 8124 ; WX 602 ; N uni1FBC ; G 1748 +U 8125 ; WX 602 ; N uni1FBD ; G 1749 +U 8126 ; WX 602 ; N uni1FBE ; G 1750 +U 8127 ; WX 602 ; N uni1FBF ; G 1751 +U 8128 ; WX 602 ; N uni1FC0 ; G 1752 +U 8129 ; WX 602 ; N uni1FC1 ; G 1753 +U 8130 ; WX 602 ; N uni1FC2 ; G 1754 +U 8131 ; WX 602 ; N uni1FC3 ; G 1755 +U 8132 ; WX 602 ; N uni1FC4 ; G 1756 +U 8134 ; WX 602 ; N uni1FC6 ; G 1757 +U 8135 ; WX 602 ; N uni1FC7 ; G 1758 +U 8136 ; WX 602 ; N uni1FC8 ; G 1759 +U 8137 ; WX 602 ; N uni1FC9 ; G 1760 +U 8138 ; WX 602 ; N uni1FCA ; G 1761 +U 8139 ; WX 602 ; N uni1FCB ; G 1762 +U 8140 ; WX 602 ; N uni1FCC ; G 1763 +U 8141 ; WX 602 ; N uni1FCD ; G 1764 +U 8142 ; WX 602 ; N uni1FCE ; G 1765 +U 8143 ; WX 602 ; N uni1FCF ; G 1766 +U 8144 ; WX 602 ; N uni1FD0 ; G 1767 +U 8145 ; WX 602 ; N uni1FD1 ; G 1768 +U 8146 ; WX 602 ; N uni1FD2 ; G 1769 +U 8147 ; WX 602 ; N uni1FD3 ; G 1770 +U 8150 ; WX 602 ; N uni1FD6 ; G 1771 +U 8151 ; WX 602 ; N uni1FD7 ; G 1772 +U 8152 ; WX 602 ; N uni1FD8 ; G 1773 +U 8153 ; WX 602 ; N uni1FD9 ; G 1774 +U 8154 ; WX 602 ; N uni1FDA ; G 1775 +U 8155 ; WX 602 ; N uni1FDB ; G 1776 +U 8157 ; WX 602 ; N uni1FDD ; G 1777 +U 8158 ; WX 602 ; N uni1FDE ; G 1778 +U 8159 ; WX 602 ; N uni1FDF ; G 1779 +U 8160 ; WX 602 ; N uni1FE0 ; G 1780 +U 8161 ; WX 602 ; N uni1FE1 ; G 1781 +U 8162 ; WX 602 ; N uni1FE2 ; G 1782 +U 8163 ; WX 602 ; N uni1FE3 ; G 1783 +U 8164 ; WX 602 ; N uni1FE4 ; G 1784 +U 8165 ; WX 602 ; N uni1FE5 ; G 1785 +U 8166 ; WX 602 ; N uni1FE6 ; G 1786 +U 8167 ; WX 602 ; N uni1FE7 ; G 1787 +U 8168 ; WX 602 ; N uni1FE8 ; G 1788 +U 8169 ; WX 602 ; N uni1FE9 ; G 1789 +U 8170 ; WX 602 ; N uni1FEA ; G 1790 +U 8171 ; WX 602 ; N uni1FEB ; G 1791 +U 8172 ; WX 602 ; N uni1FEC ; G 1792 +U 8173 ; WX 602 ; N uni1FED ; G 1793 +U 8174 ; WX 602 ; N uni1FEE ; G 1794 +U 8175 ; WX 602 ; N uni1FEF ; G 1795 +U 8178 ; WX 602 ; N uni1FF2 ; G 1796 +U 8179 ; WX 602 ; N uni1FF3 ; G 1797 +U 8180 ; WX 602 ; N uni1FF4 ; G 1798 +U 8182 ; WX 602 ; N uni1FF6 ; G 1799 +U 8183 ; WX 602 ; N uni1FF7 ; G 1800 +U 8184 ; WX 602 ; N uni1FF8 ; G 1801 +U 8185 ; WX 602 ; N uni1FF9 ; G 1802 +U 8186 ; WX 602 ; N uni1FFA ; G 1803 +U 8187 ; WX 602 ; N uni1FFB ; G 1804 +U 8188 ; WX 602 ; N uni1FFC ; G 1805 +U 8189 ; WX 602 ; N uni1FFD ; G 1806 +U 8190 ; WX 602 ; N uni1FFE ; G 1807 +U 8192 ; WX 602 ; N uni2000 ; G 1808 +U 8193 ; WX 602 ; N uni2001 ; G 1809 +U 8194 ; WX 602 ; N uni2002 ; G 1810 +U 8195 ; WX 602 ; N uni2003 ; G 1811 +U 8196 ; WX 602 ; N uni2004 ; G 1812 +U 8197 ; WX 602 ; N uni2005 ; G 1813 +U 8198 ; WX 602 ; N uni2006 ; G 1814 +U 8199 ; WX 602 ; N uni2007 ; G 1815 +U 8200 ; WX 602 ; N uni2008 ; G 1816 +U 8201 ; WX 602 ; N uni2009 ; G 1817 +U 8202 ; WX 602 ; N uni200A ; G 1818 +U 8208 ; WX 602 ; N uni2010 ; G 1819 +U 8209 ; WX 602 ; N uni2011 ; G 1820 +U 8210 ; WX 602 ; N figuredash ; G 1821 +U 8211 ; WX 602 ; N endash ; G 1822 +U 8212 ; WX 602 ; N emdash ; G 1823 +U 8213 ; WX 602 ; N uni2015 ; G 1824 +U 8214 ; WX 602 ; N uni2016 ; G 1825 +U 8215 ; WX 602 ; N underscoredbl ; G 1826 +U 8216 ; WX 602 ; N quoteleft ; G 1827 +U 8217 ; WX 602 ; N quoteright ; G 1828 +U 8218 ; WX 602 ; N quotesinglbase ; G 1829 +U 8219 ; WX 602 ; N quotereversed ; G 1830 +U 8220 ; WX 602 ; N quotedblleft ; G 1831 +U 8221 ; WX 602 ; N quotedblright ; G 1832 +U 8222 ; WX 602 ; N quotedblbase ; G 1833 +U 8223 ; WX 602 ; N uni201F ; G 1834 +U 8224 ; WX 602 ; N dagger ; G 1835 +U 8225 ; WX 602 ; N daggerdbl ; G 1836 +U 8226 ; WX 602 ; N bullet ; G 1837 +U 8227 ; WX 602 ; N uni2023 ; G 1838 +U 8230 ; WX 602 ; N ellipsis ; G 1839 +U 8239 ; WX 602 ; N uni202F ; G 1840 +U 8240 ; WX 602 ; N perthousand ; G 1841 +U 8241 ; WX 602 ; N uni2031 ; G 1842 +U 8242 ; WX 602 ; N minute ; G 1843 +U 8243 ; WX 602 ; N second ; G 1844 +U 8244 ; WX 602 ; N uni2034 ; G 1845 +U 8245 ; WX 602 ; N uni2035 ; G 1846 +U 8246 ; WX 602 ; N uni2036 ; G 1847 +U 8247 ; WX 602 ; N uni2037 ; G 1848 +U 8249 ; WX 602 ; N guilsinglleft ; G 1849 +U 8250 ; WX 602 ; N guilsinglright ; G 1850 +U 8252 ; WX 602 ; N exclamdbl ; G 1851 +U 8253 ; WX 602 ; N uni203D ; G 1852 +U 8254 ; WX 602 ; N uni203E ; G 1853 +U 8255 ; WX 602 ; N uni203F ; G 1854 +U 8261 ; WX 602 ; N uni2045 ; G 1855 +U 8262 ; WX 602 ; N uni2046 ; G 1856 +U 8263 ; WX 602 ; N uni2047 ; G 1857 +U 8264 ; WX 602 ; N uni2048 ; G 1858 +U 8265 ; WX 602 ; N uni2049 ; G 1859 +U 8267 ; WX 602 ; N uni204B ; G 1860 +U 8287 ; WX 602 ; N uni205F ; G 1861 +U 8304 ; WX 602 ; N uni2070 ; G 1862 +U 8305 ; WX 602 ; N uni2071 ; G 1863 +U 8308 ; WX 602 ; N uni2074 ; G 1864 +U 8309 ; WX 602 ; N uni2075 ; G 1865 +U 8310 ; WX 602 ; N uni2076 ; G 1866 +U 8311 ; WX 602 ; N uni2077 ; G 1867 +U 8312 ; WX 602 ; N uni2078 ; G 1868 +U 8313 ; WX 602 ; N uni2079 ; G 1869 +U 8314 ; WX 602 ; N uni207A ; G 1870 +U 8315 ; WX 602 ; N uni207B ; G 1871 +U 8316 ; WX 602 ; N uni207C ; G 1872 +U 8317 ; WX 602 ; N uni207D ; G 1873 +U 8318 ; WX 602 ; N uni207E ; G 1874 +U 8319 ; WX 602 ; N uni207F ; G 1875 +U 8320 ; WX 602 ; N uni2080 ; G 1876 +U 8321 ; WX 602 ; N uni2081 ; G 1877 +U 8322 ; WX 602 ; N uni2082 ; G 1878 +U 8323 ; WX 602 ; N uni2083 ; G 1879 +U 8324 ; WX 602 ; N uni2084 ; G 1880 +U 8325 ; WX 602 ; N uni2085 ; G 1881 +U 8326 ; WX 602 ; N uni2086 ; G 1882 +U 8327 ; WX 602 ; N uni2087 ; G 1883 +U 8328 ; WX 602 ; N uni2088 ; G 1884 +U 8329 ; WX 602 ; N uni2089 ; G 1885 +U 8330 ; WX 602 ; N uni208A ; G 1886 +U 8331 ; WX 602 ; N uni208B ; G 1887 +U 8332 ; WX 602 ; N uni208C ; G 1888 +U 8333 ; WX 602 ; N uni208D ; G 1889 +U 8334 ; WX 602 ; N uni208E ; G 1890 +U 8336 ; WX 602 ; N uni2090 ; G 1891 +U 8337 ; WX 602 ; N uni2091 ; G 1892 +U 8338 ; WX 602 ; N uni2092 ; G 1893 +U 8339 ; WX 602 ; N uni2093 ; G 1894 +U 8340 ; WX 602 ; N uni2094 ; G 1895 +U 8341 ; WX 602 ; N uni2095 ; G 1896 +U 8342 ; WX 602 ; N uni2096 ; G 1897 +U 8343 ; WX 602 ; N uni2097 ; G 1898 +U 8344 ; WX 602 ; N uni2098 ; G 1899 +U 8345 ; WX 602 ; N uni2099 ; G 1900 +U 8346 ; WX 602 ; N uni209A ; G 1901 +U 8347 ; WX 602 ; N uni209B ; G 1902 +U 8348 ; WX 602 ; N uni209C ; G 1903 +U 8352 ; WX 602 ; N uni20A0 ; G 1904 +U 8353 ; WX 602 ; N colonmonetary ; G 1905 +U 8354 ; WX 602 ; N uni20A2 ; G 1906 +U 8355 ; WX 602 ; N franc ; G 1907 +U 8356 ; WX 602 ; N lira ; G 1908 +U 8357 ; WX 602 ; N uni20A5 ; G 1909 +U 8358 ; WX 602 ; N uni20A6 ; G 1910 +U 8359 ; WX 602 ; N peseta ; G 1911 +U 8360 ; WX 602 ; N uni20A8 ; G 1912 +U 8361 ; WX 602 ; N uni20A9 ; G 1913 +U 8362 ; WX 602 ; N uni20AA ; G 1914 +U 8363 ; WX 602 ; N dong ; G 1915 +U 8364 ; WX 602 ; N Euro ; G 1916 +U 8365 ; WX 602 ; N uni20AD ; G 1917 +U 8366 ; WX 602 ; N uni20AE ; G 1918 +U 8367 ; WX 602 ; N uni20AF ; G 1919 +U 8368 ; WX 602 ; N uni20B0 ; G 1920 +U 8369 ; WX 602 ; N uni20B1 ; G 1921 +U 8370 ; WX 602 ; N uni20B2 ; G 1922 +U 8371 ; WX 602 ; N uni20B3 ; G 1923 +U 8372 ; WX 602 ; N uni20B4 ; G 1924 +U 8373 ; WX 602 ; N uni20B5 ; G 1925 +U 8376 ; WX 602 ; N uni20B8 ; G 1926 +U 8377 ; WX 602 ; N uni20B9 ; G 1927 +U 8378 ; WX 602 ; N uni20BA ; G 1928 +U 8381 ; WX 602 ; N uni20BD ; G 1929 +U 8450 ; WX 602 ; N uni2102 ; G 1930 +U 8453 ; WX 602 ; N uni2105 ; G 1931 +U 8461 ; WX 602 ; N uni210D ; G 1932 +U 8462 ; WX 602 ; N uni210E ; G 1933 +U 8463 ; WX 602 ; N uni210F ; G 1934 +U 8469 ; WX 602 ; N uni2115 ; G 1935 +U 8470 ; WX 602 ; N uni2116 ; G 1936 +U 8471 ; WX 602 ; N uni2117 ; G 1937 +U 8473 ; WX 602 ; N uni2119 ; G 1938 +U 8474 ; WX 602 ; N uni211A ; G 1939 +U 8477 ; WX 602 ; N uni211D ; G 1940 +U 8482 ; WX 602 ; N trademark ; G 1941 +U 8484 ; WX 602 ; N uni2124 ; G 1942 +U 8486 ; WX 602 ; N uni2126 ; G 1943 +U 8490 ; WX 602 ; N uni212A ; G 1944 +U 8491 ; WX 602 ; N uni212B ; G 1945 +U 8494 ; WX 602 ; N estimated ; G 1946 +U 8520 ; WX 602 ; N uni2148 ; G 1947 +U 8528 ; WX 602 ; N uni2150 ; G 1948 +U 8529 ; WX 602 ; N uni2151 ; G 1949 +U 8531 ; WX 602 ; N onethird ; G 1950 +U 8532 ; WX 602 ; N twothirds ; G 1951 +U 8533 ; WX 602 ; N uni2155 ; G 1952 +U 8534 ; WX 602 ; N uni2156 ; G 1953 +U 8535 ; WX 602 ; N uni2157 ; G 1954 +U 8536 ; WX 602 ; N uni2158 ; G 1955 +U 8537 ; WX 602 ; N uni2159 ; G 1956 +U 8538 ; WX 602 ; N uni215A ; G 1957 +U 8539 ; WX 602 ; N oneeighth ; G 1958 +U 8540 ; WX 602 ; N threeeighths ; G 1959 +U 8541 ; WX 602 ; N fiveeighths ; G 1960 +U 8542 ; WX 602 ; N seveneighths ; G 1961 +U 8543 ; WX 602 ; N uni215F ; G 1962 +U 8585 ; WX 602 ; N uni2189 ; G 1963 +U 8592 ; WX 602 ; N arrowleft ; G 1964 +U 8593 ; WX 602 ; N arrowup ; G 1965 +U 8594 ; WX 602 ; N arrowright ; G 1966 +U 8595 ; WX 602 ; N arrowdown ; G 1967 +U 8596 ; WX 602 ; N arrowboth ; G 1968 +U 8597 ; WX 602 ; N arrowupdn ; G 1969 +U 8598 ; WX 602 ; N uni2196 ; G 1970 +U 8599 ; WX 602 ; N uni2197 ; G 1971 +U 8600 ; WX 602 ; N uni2198 ; G 1972 +U 8601 ; WX 602 ; N uni2199 ; G 1973 +U 8602 ; WX 602 ; N uni219A ; G 1974 +U 8603 ; WX 602 ; N uni219B ; G 1975 +U 8604 ; WX 602 ; N uni219C ; G 1976 +U 8605 ; WX 602 ; N uni219D ; G 1977 +U 8606 ; WX 602 ; N uni219E ; G 1978 +U 8607 ; WX 602 ; N uni219F ; G 1979 +U 8608 ; WX 602 ; N uni21A0 ; G 1980 +U 8609 ; WX 602 ; N uni21A1 ; G 1981 +U 8610 ; WX 602 ; N uni21A2 ; G 1982 +U 8611 ; WX 602 ; N uni21A3 ; G 1983 +U 8612 ; WX 602 ; N uni21A4 ; G 1984 +U 8613 ; WX 602 ; N uni21A5 ; G 1985 +U 8614 ; WX 602 ; N uni21A6 ; G 1986 +U 8615 ; WX 602 ; N uni21A7 ; G 1987 +U 8616 ; WX 602 ; N arrowupdnbse ; G 1988 +U 8617 ; WX 602 ; N uni21A9 ; G 1989 +U 8618 ; WX 602 ; N uni21AA ; G 1990 +U 8619 ; WX 602 ; N uni21AB ; G 1991 +U 8620 ; WX 602 ; N uni21AC ; G 1992 +U 8621 ; WX 602 ; N uni21AD ; G 1993 +U 8622 ; WX 602 ; N uni21AE ; G 1994 +U 8623 ; WX 602 ; N uni21AF ; G 1995 +U 8624 ; WX 602 ; N uni21B0 ; G 1996 +U 8625 ; WX 602 ; N uni21B1 ; G 1997 +U 8626 ; WX 602 ; N uni21B2 ; G 1998 +U 8627 ; WX 602 ; N uni21B3 ; G 1999 +U 8628 ; WX 602 ; N uni21B4 ; G 2000 +U 8629 ; WX 602 ; N carriagereturn ; G 2001 +U 8630 ; WX 602 ; N uni21B6 ; G 2002 +U 8631 ; WX 602 ; N uni21B7 ; G 2003 +U 8632 ; WX 602 ; N uni21B8 ; G 2004 +U 8633 ; WX 602 ; N uni21B9 ; G 2005 +U 8634 ; WX 602 ; N uni21BA ; G 2006 +U 8635 ; WX 602 ; N uni21BB ; G 2007 +U 8636 ; WX 602 ; N uni21BC ; G 2008 +U 8637 ; WX 602 ; N uni21BD ; G 2009 +U 8638 ; WX 602 ; N uni21BE ; G 2010 +U 8639 ; WX 602 ; N uni21BF ; G 2011 +U 8640 ; WX 602 ; N uni21C0 ; G 2012 +U 8641 ; WX 602 ; N uni21C1 ; G 2013 +U 8642 ; WX 602 ; N uni21C2 ; G 2014 +U 8643 ; WX 602 ; N uni21C3 ; G 2015 +U 8644 ; WX 602 ; N uni21C4 ; G 2016 +U 8645 ; WX 602 ; N uni21C5 ; G 2017 +U 8646 ; WX 602 ; N uni21C6 ; G 2018 +U 8647 ; WX 602 ; N uni21C7 ; G 2019 +U 8648 ; WX 602 ; N uni21C8 ; G 2020 +U 8649 ; WX 602 ; N uni21C9 ; G 2021 +U 8650 ; WX 602 ; N uni21CA ; G 2022 +U 8651 ; WX 602 ; N uni21CB ; G 2023 +U 8652 ; WX 602 ; N uni21CC ; G 2024 +U 8653 ; WX 602 ; N uni21CD ; G 2025 +U 8654 ; WX 602 ; N uni21CE ; G 2026 +U 8655 ; WX 602 ; N uni21CF ; G 2027 +U 8656 ; WX 602 ; N arrowdblleft ; G 2028 +U 8657 ; WX 602 ; N arrowdblup ; G 2029 +U 8658 ; WX 602 ; N arrowdblright ; G 2030 +U 8659 ; WX 602 ; N arrowdbldown ; G 2031 +U 8660 ; WX 602 ; N arrowdblboth ; G 2032 +U 8661 ; WX 602 ; N uni21D5 ; G 2033 +U 8662 ; WX 602 ; N uni21D6 ; G 2034 +U 8663 ; WX 602 ; N uni21D7 ; G 2035 +U 8664 ; WX 602 ; N uni21D8 ; G 2036 +U 8665 ; WX 602 ; N uni21D9 ; G 2037 +U 8666 ; WX 602 ; N uni21DA ; G 2038 +U 8667 ; WX 602 ; N uni21DB ; G 2039 +U 8668 ; WX 602 ; N uni21DC ; G 2040 +U 8669 ; WX 602 ; N uni21DD ; G 2041 +U 8670 ; WX 602 ; N uni21DE ; G 2042 +U 8671 ; WX 602 ; N uni21DF ; G 2043 +U 8672 ; WX 602 ; N uni21E0 ; G 2044 +U 8673 ; WX 602 ; N uni21E1 ; G 2045 +U 8674 ; WX 602 ; N uni21E2 ; G 2046 +U 8675 ; WX 602 ; N uni21E3 ; G 2047 +U 8676 ; WX 602 ; N uni21E4 ; G 2048 +U 8677 ; WX 602 ; N uni21E5 ; G 2049 +U 8678 ; WX 602 ; N uni21E6 ; G 2050 +U 8679 ; WX 602 ; N uni21E7 ; G 2051 +U 8680 ; WX 602 ; N uni21E8 ; G 2052 +U 8681 ; WX 602 ; N uni21E9 ; G 2053 +U 8682 ; WX 602 ; N uni21EA ; G 2054 +U 8683 ; WX 602 ; N uni21EB ; G 2055 +U 8684 ; WX 602 ; N uni21EC ; G 2056 +U 8685 ; WX 602 ; N uni21ED ; G 2057 +U 8686 ; WX 602 ; N uni21EE ; G 2058 +U 8687 ; WX 602 ; N uni21EF ; G 2059 +U 8688 ; WX 602 ; N uni21F0 ; G 2060 +U 8689 ; WX 602 ; N uni21F1 ; G 2061 +U 8690 ; WX 602 ; N uni21F2 ; G 2062 +U 8691 ; WX 602 ; N uni21F3 ; G 2063 +U 8692 ; WX 602 ; N uni21F4 ; G 2064 +U 8693 ; WX 602 ; N uni21F5 ; G 2065 +U 8694 ; WX 602 ; N uni21F6 ; G 2066 +U 8695 ; WX 602 ; N uni21F7 ; G 2067 +U 8696 ; WX 602 ; N uni21F8 ; G 2068 +U 8697 ; WX 602 ; N uni21F9 ; G 2069 +U 8698 ; WX 602 ; N uni21FA ; G 2070 +U 8699 ; WX 602 ; N uni21FB ; G 2071 +U 8700 ; WX 602 ; N uni21FC ; G 2072 +U 8701 ; WX 602 ; N uni21FD ; G 2073 +U 8702 ; WX 602 ; N uni21FE ; G 2074 +U 8703 ; WX 602 ; N uni21FF ; G 2075 +U 8704 ; WX 602 ; N universal ; G 2076 +U 8705 ; WX 602 ; N uni2201 ; G 2077 +U 8706 ; WX 602 ; N partialdiff ; G 2078 +U 8707 ; WX 602 ; N existential ; G 2079 +U 8708 ; WX 602 ; N uni2204 ; G 2080 +U 8709 ; WX 602 ; N emptyset ; G 2081 +U 8710 ; WX 602 ; N increment ; G 2082 +U 8711 ; WX 602 ; N gradient ; G 2083 +U 8712 ; WX 602 ; N element ; G 2084 +U 8713 ; WX 602 ; N notelement ; G 2085 +U 8714 ; WX 602 ; N uni220A ; G 2086 +U 8715 ; WX 602 ; N suchthat ; G 2087 +U 8716 ; WX 602 ; N uni220C ; G 2088 +U 8717 ; WX 602 ; N uni220D ; G 2089 +U 8718 ; WX 602 ; N uni220E ; G 2090 +U 8719 ; WX 602 ; N product ; G 2091 +U 8720 ; WX 602 ; N uni2210 ; G 2092 +U 8721 ; WX 602 ; N summation ; G 2093 +U 8722 ; WX 602 ; N minus ; G 2094 +U 8723 ; WX 602 ; N uni2213 ; G 2095 +U 8725 ; WX 602 ; N uni2215 ; G 2096 +U 8727 ; WX 602 ; N asteriskmath ; G 2097 +U 8728 ; WX 602 ; N uni2218 ; G 2098 +U 8729 ; WX 602 ; N uni2219 ; G 2099 +U 8730 ; WX 602 ; N radical ; G 2100 +U 8731 ; WX 602 ; N uni221B ; G 2101 +U 8732 ; WX 602 ; N uni221C ; G 2102 +U 8733 ; WX 602 ; N proportional ; G 2103 +U 8734 ; WX 602 ; N infinity ; G 2104 +U 8735 ; WX 602 ; N orthogonal ; G 2105 +U 8736 ; WX 602 ; N angle ; G 2106 +U 8739 ; WX 602 ; N uni2223 ; G 2107 +U 8743 ; WX 602 ; N logicaland ; G 2108 +U 8744 ; WX 602 ; N logicalor ; G 2109 +U 8745 ; WX 602 ; N intersection ; G 2110 +U 8746 ; WX 602 ; N union ; G 2111 +U 8747 ; WX 602 ; N integral ; G 2112 +U 8748 ; WX 602 ; N uni222C ; G 2113 +U 8749 ; WX 602 ; N uni222D ; G 2114 +U 8756 ; WX 602 ; N therefore ; G 2115 +U 8757 ; WX 602 ; N uni2235 ; G 2116 +U 8758 ; WX 602 ; N uni2236 ; G 2117 +U 8759 ; WX 602 ; N uni2237 ; G 2118 +U 8760 ; WX 602 ; N uni2238 ; G 2119 +U 8761 ; WX 602 ; N uni2239 ; G 2120 +U 8762 ; WX 602 ; N uni223A ; G 2121 +U 8763 ; WX 602 ; N uni223B ; G 2122 +U 8764 ; WX 602 ; N similar ; G 2123 +U 8765 ; WX 602 ; N uni223D ; G 2124 +U 8769 ; WX 602 ; N uni2241 ; G 2125 +U 8770 ; WX 602 ; N uni2242 ; G 2126 +U 8771 ; WX 602 ; N uni2243 ; G 2127 +U 8772 ; WX 602 ; N uni2244 ; G 2128 +U 8773 ; WX 602 ; N congruent ; G 2129 +U 8774 ; WX 602 ; N uni2246 ; G 2130 +U 8775 ; WX 602 ; N uni2247 ; G 2131 +U 8776 ; WX 602 ; N approxequal ; G 2132 +U 8777 ; WX 602 ; N uni2249 ; G 2133 +U 8778 ; WX 602 ; N uni224A ; G 2134 +U 8779 ; WX 602 ; N uni224B ; G 2135 +U 8780 ; WX 602 ; N uni224C ; G 2136 +U 8781 ; WX 602 ; N uni224D ; G 2137 +U 8782 ; WX 602 ; N uni224E ; G 2138 +U 8783 ; WX 602 ; N uni224F ; G 2139 +U 8784 ; WX 602 ; N uni2250 ; G 2140 +U 8785 ; WX 602 ; N uni2251 ; G 2141 +U 8786 ; WX 602 ; N uni2252 ; G 2142 +U 8787 ; WX 602 ; N uni2253 ; G 2143 +U 8788 ; WX 602 ; N uni2254 ; G 2144 +U 8789 ; WX 602 ; N uni2255 ; G 2145 +U 8790 ; WX 602 ; N uni2256 ; G 2146 +U 8791 ; WX 602 ; N uni2257 ; G 2147 +U 8792 ; WX 602 ; N uni2258 ; G 2148 +U 8793 ; WX 602 ; N uni2259 ; G 2149 +U 8794 ; WX 602 ; N uni225A ; G 2150 +U 8795 ; WX 602 ; N uni225B ; G 2151 +U 8796 ; WX 602 ; N uni225C ; G 2152 +U 8797 ; WX 602 ; N uni225D ; G 2153 +U 8798 ; WX 602 ; N uni225E ; G 2154 +U 8799 ; WX 602 ; N uni225F ; G 2155 +U 8800 ; WX 602 ; N notequal ; G 2156 +U 8801 ; WX 602 ; N equivalence ; G 2157 +U 8802 ; WX 602 ; N uni2262 ; G 2158 +U 8803 ; WX 602 ; N uni2263 ; G 2159 +U 8804 ; WX 602 ; N lessequal ; G 2160 +U 8805 ; WX 602 ; N greaterequal ; G 2161 +U 8806 ; WX 602 ; N uni2266 ; G 2162 +U 8807 ; WX 602 ; N uni2267 ; G 2163 +U 8808 ; WX 602 ; N uni2268 ; G 2164 +U 8809 ; WX 602 ; N uni2269 ; G 2165 +U 8813 ; WX 602 ; N uni226D ; G 2166 +U 8814 ; WX 602 ; N uni226E ; G 2167 +U 8815 ; WX 602 ; N uni226F ; G 2168 +U 8816 ; WX 602 ; N uni2270 ; G 2169 +U 8817 ; WX 602 ; N uni2271 ; G 2170 +U 8818 ; WX 602 ; N uni2272 ; G 2171 +U 8819 ; WX 602 ; N uni2273 ; G 2172 +U 8820 ; WX 602 ; N uni2274 ; G 2173 +U 8821 ; WX 602 ; N uni2275 ; G 2174 +U 8822 ; WX 602 ; N uni2276 ; G 2175 +U 8823 ; WX 602 ; N uni2277 ; G 2176 +U 8824 ; WX 602 ; N uni2278 ; G 2177 +U 8825 ; WX 602 ; N uni2279 ; G 2178 +U 8826 ; WX 602 ; N uni227A ; G 2179 +U 8827 ; WX 602 ; N uni227B ; G 2180 +U 8828 ; WX 602 ; N uni227C ; G 2181 +U 8829 ; WX 602 ; N uni227D ; G 2182 +U 8830 ; WX 602 ; N uni227E ; G 2183 +U 8831 ; WX 602 ; N uni227F ; G 2184 +U 8832 ; WX 602 ; N uni2280 ; G 2185 +U 8833 ; WX 602 ; N uni2281 ; G 2186 +U 8834 ; WX 602 ; N propersubset ; G 2187 +U 8835 ; WX 602 ; N propersuperset ; G 2188 +U 8836 ; WX 602 ; N notsubset ; G 2189 +U 8837 ; WX 602 ; N uni2285 ; G 2190 +U 8838 ; WX 602 ; N reflexsubset ; G 2191 +U 8839 ; WX 602 ; N reflexsuperset ; G 2192 +U 8840 ; WX 602 ; N uni2288 ; G 2193 +U 8841 ; WX 602 ; N uni2289 ; G 2194 +U 8842 ; WX 602 ; N uni228A ; G 2195 +U 8843 ; WX 602 ; N uni228B ; G 2196 +U 8845 ; WX 602 ; N uni228D ; G 2197 +U 8846 ; WX 602 ; N uni228E ; G 2198 +U 8847 ; WX 602 ; N uni228F ; G 2199 +U 8848 ; WX 602 ; N uni2290 ; G 2200 +U 8849 ; WX 602 ; N uni2291 ; G 2201 +U 8850 ; WX 602 ; N uni2292 ; G 2202 +U 8851 ; WX 602 ; N uni2293 ; G 2203 +U 8852 ; WX 602 ; N uni2294 ; G 2204 +U 8853 ; WX 602 ; N circleplus ; G 2205 +U 8854 ; WX 602 ; N uni2296 ; G 2206 +U 8855 ; WX 602 ; N circlemultiply ; G 2207 +U 8856 ; WX 602 ; N uni2298 ; G 2208 +U 8857 ; WX 602 ; N uni2299 ; G 2209 +U 8858 ; WX 602 ; N uni229A ; G 2210 +U 8859 ; WX 602 ; N uni229B ; G 2211 +U 8860 ; WX 602 ; N uni229C ; G 2212 +U 8861 ; WX 602 ; N uni229D ; G 2213 +U 8862 ; WX 602 ; N uni229E ; G 2214 +U 8863 ; WX 602 ; N uni229F ; G 2215 +U 8864 ; WX 602 ; N uni22A0 ; G 2216 +U 8865 ; WX 602 ; N uni22A1 ; G 2217 +U 8866 ; WX 602 ; N uni22A2 ; G 2218 +U 8867 ; WX 602 ; N uni22A3 ; G 2219 +U 8868 ; WX 602 ; N uni22A4 ; G 2220 +U 8869 ; WX 602 ; N perpendicular ; G 2221 +U 8882 ; WX 602 ; N uni22B2 ; G 2222 +U 8883 ; WX 602 ; N uni22B3 ; G 2223 +U 8884 ; WX 602 ; N uni22B4 ; G 2224 +U 8885 ; WX 602 ; N uni22B5 ; G 2225 +U 8888 ; WX 602 ; N uni22B8 ; G 2226 +U 8898 ; WX 602 ; N uni22C2 ; G 2227 +U 8899 ; WX 602 ; N uni22C3 ; G 2228 +U 8900 ; WX 602 ; N uni22C4 ; G 2229 +U 8901 ; WX 602 ; N dotmath ; G 2230 +U 8902 ; WX 602 ; N uni22C6 ; G 2231 +U 8909 ; WX 602 ; N uni22CD ; G 2232 +U 8910 ; WX 602 ; N uni22CE ; G 2233 +U 8911 ; WX 602 ; N uni22CF ; G 2234 +U 8912 ; WX 602 ; N uni22D0 ; G 2235 +U 8913 ; WX 602 ; N uni22D1 ; G 2236 +U 8922 ; WX 602 ; N uni22DA ; G 2237 +U 8923 ; WX 602 ; N uni22DB ; G 2238 +U 8924 ; WX 602 ; N uni22DC ; G 2239 +U 8925 ; WX 602 ; N uni22DD ; G 2240 +U 8926 ; WX 602 ; N uni22DE ; G 2241 +U 8927 ; WX 602 ; N uni22DF ; G 2242 +U 8928 ; WX 602 ; N uni22E0 ; G 2243 +U 8929 ; WX 602 ; N uni22E1 ; G 2244 +U 8930 ; WX 602 ; N uni22E2 ; G 2245 +U 8931 ; WX 602 ; N uni22E3 ; G 2246 +U 8932 ; WX 602 ; N uni22E4 ; G 2247 +U 8933 ; WX 602 ; N uni22E5 ; G 2248 +U 8934 ; WX 602 ; N uni22E6 ; G 2249 +U 8935 ; WX 602 ; N uni22E7 ; G 2250 +U 8936 ; WX 602 ; N uni22E8 ; G 2251 +U 8937 ; WX 602 ; N uni22E9 ; G 2252 +U 8943 ; WX 602 ; N uni22EF ; G 2253 +U 8960 ; WX 602 ; N uni2300 ; G 2254 +U 8961 ; WX 602 ; N uni2301 ; G 2255 +U 8962 ; WX 602 ; N house ; G 2256 +U 8963 ; WX 602 ; N uni2303 ; G 2257 +U 8964 ; WX 602 ; N uni2304 ; G 2258 +U 8965 ; WX 602 ; N uni2305 ; G 2259 +U 8966 ; WX 602 ; N uni2306 ; G 2260 +U 8968 ; WX 602 ; N uni2308 ; G 2261 +U 8969 ; WX 602 ; N uni2309 ; G 2262 +U 8970 ; WX 602 ; N uni230A ; G 2263 +U 8971 ; WX 602 ; N uni230B ; G 2264 +U 8972 ; WX 602 ; N uni230C ; G 2265 +U 8973 ; WX 602 ; N uni230D ; G 2266 +U 8974 ; WX 602 ; N uni230E ; G 2267 +U 8975 ; WX 602 ; N uni230F ; G 2268 +U 8976 ; WX 602 ; N revlogicalnot ; G 2269 +U 8977 ; WX 602 ; N uni2311 ; G 2270 +U 8978 ; WX 602 ; N uni2312 ; G 2271 +U 8979 ; WX 602 ; N uni2313 ; G 2272 +U 8980 ; WX 602 ; N uni2314 ; G 2273 +U 8981 ; WX 602 ; N uni2315 ; G 2274 +U 8984 ; WX 602 ; N uni2318 ; G 2275 +U 8985 ; WX 602 ; N uni2319 ; G 2276 +U 8988 ; WX 602 ; N uni231C ; G 2277 +U 8989 ; WX 602 ; N uni231D ; G 2278 +U 8990 ; WX 602 ; N uni231E ; G 2279 +U 8991 ; WX 602 ; N uni231F ; G 2280 +U 8992 ; WX 602 ; N integraltp ; G 2281 +U 8993 ; WX 602 ; N integralbt ; G 2282 +U 8997 ; WX 602 ; N uni2325 ; G 2283 +U 8998 ; WX 602 ; N uni2326 ; G 2284 +U 8999 ; WX 602 ; N uni2327 ; G 2285 +U 9000 ; WX 602 ; N uni2328 ; G 2286 +U 9003 ; WX 602 ; N uni232B ; G 2287 +U 9013 ; WX 602 ; N uni2335 ; G 2288 +U 9014 ; WX 602 ; N uni2336 ; G 2289 +U 9015 ; WX 602 ; N uni2337 ; G 2290 +U 9016 ; WX 602 ; N uni2338 ; G 2291 +U 9017 ; WX 602 ; N uni2339 ; G 2292 +U 9018 ; WX 602 ; N uni233A ; G 2293 +U 9019 ; WX 602 ; N uni233B ; G 2294 +U 9020 ; WX 602 ; N uni233C ; G 2295 +U 9021 ; WX 602 ; N uni233D ; G 2296 +U 9022 ; WX 602 ; N uni233E ; G 2297 +U 9023 ; WX 602 ; N uni233F ; G 2298 +U 9024 ; WX 602 ; N uni2340 ; G 2299 +U 9025 ; WX 602 ; N uni2341 ; G 2300 +U 9026 ; WX 602 ; N uni2342 ; G 2301 +U 9027 ; WX 602 ; N uni2343 ; G 2302 +U 9028 ; WX 602 ; N uni2344 ; G 2303 +U 9029 ; WX 602 ; N uni2345 ; G 2304 +U 9030 ; WX 602 ; N uni2346 ; G 2305 +U 9031 ; WX 602 ; N uni2347 ; G 2306 +U 9032 ; WX 602 ; N uni2348 ; G 2307 +U 9033 ; WX 602 ; N uni2349 ; G 2308 +U 9034 ; WX 602 ; N uni234A ; G 2309 +U 9035 ; WX 602 ; N uni234B ; G 2310 +U 9036 ; WX 602 ; N uni234C ; G 2311 +U 9037 ; WX 602 ; N uni234D ; G 2312 +U 9038 ; WX 602 ; N uni234E ; G 2313 +U 9039 ; WX 602 ; N uni234F ; G 2314 +U 9040 ; WX 602 ; N uni2350 ; G 2315 +U 9041 ; WX 602 ; N uni2351 ; G 2316 +U 9042 ; WX 602 ; N uni2352 ; G 2317 +U 9043 ; WX 602 ; N uni2353 ; G 2318 +U 9044 ; WX 602 ; N uni2354 ; G 2319 +U 9045 ; WX 602 ; N uni2355 ; G 2320 +U 9046 ; WX 602 ; N uni2356 ; G 2321 +U 9047 ; WX 602 ; N uni2357 ; G 2322 +U 9048 ; WX 602 ; N uni2358 ; G 2323 +U 9049 ; WX 602 ; N uni2359 ; G 2324 +U 9050 ; WX 602 ; N uni235A ; G 2325 +U 9051 ; WX 602 ; N uni235B ; G 2326 +U 9052 ; WX 602 ; N uni235C ; G 2327 +U 9053 ; WX 602 ; N uni235D ; G 2328 +U 9054 ; WX 602 ; N uni235E ; G 2329 +U 9055 ; WX 602 ; N uni235F ; G 2330 +U 9056 ; WX 602 ; N uni2360 ; G 2331 +U 9057 ; WX 602 ; N uni2361 ; G 2332 +U 9058 ; WX 602 ; N uni2362 ; G 2333 +U 9059 ; WX 602 ; N uni2363 ; G 2334 +U 9060 ; WX 602 ; N uni2364 ; G 2335 +U 9061 ; WX 602 ; N uni2365 ; G 2336 +U 9062 ; WX 602 ; N uni2366 ; G 2337 +U 9063 ; WX 602 ; N uni2367 ; G 2338 +U 9064 ; WX 602 ; N uni2368 ; G 2339 +U 9065 ; WX 602 ; N uni2369 ; G 2340 +U 9066 ; WX 602 ; N uni236A ; G 2341 +U 9067 ; WX 602 ; N uni236B ; G 2342 +U 9068 ; WX 602 ; N uni236C ; G 2343 +U 9069 ; WX 602 ; N uni236D ; G 2344 +U 9070 ; WX 602 ; N uni236E ; G 2345 +U 9071 ; WX 602 ; N uni236F ; G 2346 +U 9072 ; WX 602 ; N uni2370 ; G 2347 +U 9073 ; WX 602 ; N uni2371 ; G 2348 +U 9074 ; WX 602 ; N uni2372 ; G 2349 +U 9075 ; WX 602 ; N uni2373 ; G 2350 +U 9076 ; WX 602 ; N uni2374 ; G 2351 +U 9077 ; WX 602 ; N uni2375 ; G 2352 +U 9078 ; WX 602 ; N uni2376 ; G 2353 +U 9079 ; WX 602 ; N uni2377 ; G 2354 +U 9080 ; WX 602 ; N uni2378 ; G 2355 +U 9081 ; WX 602 ; N uni2379 ; G 2356 +U 9082 ; WX 602 ; N uni237A ; G 2357 +U 9085 ; WX 602 ; N uni237D ; G 2358 +U 9088 ; WX 602 ; N uni2380 ; G 2359 +U 9089 ; WX 602 ; N uni2381 ; G 2360 +U 9090 ; WX 602 ; N uni2382 ; G 2361 +U 9091 ; WX 602 ; N uni2383 ; G 2362 +U 9096 ; WX 602 ; N uni2388 ; G 2363 +U 9097 ; WX 602 ; N uni2389 ; G 2364 +U 9098 ; WX 602 ; N uni238A ; G 2365 +U 9099 ; WX 602 ; N uni238B ; G 2366 +U 9109 ; WX 602 ; N uni2395 ; G 2367 +U 9115 ; WX 602 ; N uni239B ; G 2368 +U 9116 ; WX 602 ; N uni239C ; G 2369 +U 9117 ; WX 602 ; N uni239D ; G 2370 +U 9118 ; WX 602 ; N uni239E ; G 2371 +U 9119 ; WX 602 ; N uni239F ; G 2372 +U 9120 ; WX 602 ; N uni23A0 ; G 2373 +U 9121 ; WX 602 ; N uni23A1 ; G 2374 +U 9122 ; WX 602 ; N uni23A2 ; G 2375 +U 9123 ; WX 602 ; N uni23A3 ; G 2376 +U 9124 ; WX 602 ; N uni23A4 ; G 2377 +U 9125 ; WX 602 ; N uni23A5 ; G 2378 +U 9126 ; WX 602 ; N uni23A6 ; G 2379 +U 9127 ; WX 602 ; N uni23A7 ; G 2380 +U 9128 ; WX 602 ; N uni23A8 ; G 2381 +U 9129 ; WX 602 ; N uni23A9 ; G 2382 +U 9130 ; WX 602 ; N uni23AA ; G 2383 +U 9131 ; WX 602 ; N uni23AB ; G 2384 +U 9132 ; WX 602 ; N uni23AC ; G 2385 +U 9133 ; WX 602 ; N uni23AD ; G 2386 +U 9134 ; WX 602 ; N uni23AE ; G 2387 +U 9166 ; WX 602 ; N uni23CE ; G 2388 +U 9167 ; WX 602 ; N uni23CF ; G 2389 +U 9251 ; WX 602 ; N uni2423 ; G 2390 +U 9472 ; WX 602 ; N SF100000 ; G 2391 +U 9473 ; WX 602 ; N uni2501 ; G 2392 +U 9474 ; WX 602 ; N SF110000 ; G 2393 +U 9475 ; WX 602 ; N uni2503 ; G 2394 +U 9476 ; WX 602 ; N uni2504 ; G 2395 +U 9477 ; WX 602 ; N uni2505 ; G 2396 +U 9478 ; WX 602 ; N uni2506 ; G 2397 +U 9479 ; WX 602 ; N uni2507 ; G 2398 +U 9480 ; WX 602 ; N uni2508 ; G 2399 +U 9481 ; WX 602 ; N uni2509 ; G 2400 +U 9482 ; WX 602 ; N uni250A ; G 2401 +U 9483 ; WX 602 ; N uni250B ; G 2402 +U 9484 ; WX 602 ; N SF010000 ; G 2403 +U 9485 ; WX 602 ; N uni250D ; G 2404 +U 9486 ; WX 602 ; N uni250E ; G 2405 +U 9487 ; WX 602 ; N uni250F ; G 2406 +U 9488 ; WX 602 ; N SF030000 ; G 2407 +U 9489 ; WX 602 ; N uni2511 ; G 2408 +U 9490 ; WX 602 ; N uni2512 ; G 2409 +U 9491 ; WX 602 ; N uni2513 ; G 2410 +U 9492 ; WX 602 ; N SF020000 ; G 2411 +U 9493 ; WX 602 ; N uni2515 ; G 2412 +U 9494 ; WX 602 ; N uni2516 ; G 2413 +U 9495 ; WX 602 ; N uni2517 ; G 2414 +U 9496 ; WX 602 ; N SF040000 ; G 2415 +U 9497 ; WX 602 ; N uni2519 ; G 2416 +U 9498 ; WX 602 ; N uni251A ; G 2417 +U 9499 ; WX 602 ; N uni251B ; G 2418 +U 9500 ; WX 602 ; N SF080000 ; G 2419 +U 9501 ; WX 602 ; N uni251D ; G 2420 +U 9502 ; WX 602 ; N uni251E ; G 2421 +U 9503 ; WX 602 ; N uni251F ; G 2422 +U 9504 ; WX 602 ; N uni2520 ; G 2423 +U 9505 ; WX 602 ; N uni2521 ; G 2424 +U 9506 ; WX 602 ; N uni2522 ; G 2425 +U 9507 ; WX 602 ; N uni2523 ; G 2426 +U 9508 ; WX 602 ; N SF090000 ; G 2427 +U 9509 ; WX 602 ; N uni2525 ; G 2428 +U 9510 ; WX 602 ; N uni2526 ; G 2429 +U 9511 ; WX 602 ; N uni2527 ; G 2430 +U 9512 ; WX 602 ; N uni2528 ; G 2431 +U 9513 ; WX 602 ; N uni2529 ; G 2432 +U 9514 ; WX 602 ; N uni252A ; G 2433 +U 9515 ; WX 602 ; N uni252B ; G 2434 +U 9516 ; WX 602 ; N SF060000 ; G 2435 +U 9517 ; WX 602 ; N uni252D ; G 2436 +U 9518 ; WX 602 ; N uni252E ; G 2437 +U 9519 ; WX 602 ; N uni252F ; G 2438 +U 9520 ; WX 602 ; N uni2530 ; G 2439 +U 9521 ; WX 602 ; N uni2531 ; G 2440 +U 9522 ; WX 602 ; N uni2532 ; G 2441 +U 9523 ; WX 602 ; N uni2533 ; G 2442 +U 9524 ; WX 602 ; N SF070000 ; G 2443 +U 9525 ; WX 602 ; N uni2535 ; G 2444 +U 9526 ; WX 602 ; N uni2536 ; G 2445 +U 9527 ; WX 602 ; N uni2537 ; G 2446 +U 9528 ; WX 602 ; N uni2538 ; G 2447 +U 9529 ; WX 602 ; N uni2539 ; G 2448 +U 9530 ; WX 602 ; N uni253A ; G 2449 +U 9531 ; WX 602 ; N uni253B ; G 2450 +U 9532 ; WX 602 ; N SF050000 ; G 2451 +U 9533 ; WX 602 ; N uni253D ; G 2452 +U 9534 ; WX 602 ; N uni253E ; G 2453 +U 9535 ; WX 602 ; N uni253F ; G 2454 +U 9536 ; WX 602 ; N uni2540 ; G 2455 +U 9537 ; WX 602 ; N uni2541 ; G 2456 +U 9538 ; WX 602 ; N uni2542 ; G 2457 +U 9539 ; WX 602 ; N uni2543 ; G 2458 +U 9540 ; WX 602 ; N uni2544 ; G 2459 +U 9541 ; WX 602 ; N uni2545 ; G 2460 +U 9542 ; WX 602 ; N uni2546 ; G 2461 +U 9543 ; WX 602 ; N uni2547 ; G 2462 +U 9544 ; WX 602 ; N uni2548 ; G 2463 +U 9545 ; WX 602 ; N uni2549 ; G 2464 +U 9546 ; WX 602 ; N uni254A ; G 2465 +U 9547 ; WX 602 ; N uni254B ; G 2466 +U 9548 ; WX 602 ; N uni254C ; G 2467 +U 9549 ; WX 602 ; N uni254D ; G 2468 +U 9550 ; WX 602 ; N uni254E ; G 2469 +U 9551 ; WX 602 ; N uni254F ; G 2470 +U 9552 ; WX 602 ; N SF430000 ; G 2471 +U 9553 ; WX 602 ; N SF240000 ; G 2472 +U 9554 ; WX 602 ; N SF510000 ; G 2473 +U 9555 ; WX 602 ; N SF520000 ; G 2474 +U 9556 ; WX 602 ; N SF390000 ; G 2475 +U 9557 ; WX 602 ; N SF220000 ; G 2476 +U 9558 ; WX 602 ; N SF210000 ; G 2477 +U 9559 ; WX 602 ; N SF250000 ; G 2478 +U 9560 ; WX 602 ; N SF500000 ; G 2479 +U 9561 ; WX 602 ; N SF490000 ; G 2480 +U 9562 ; WX 602 ; N SF380000 ; G 2481 +U 9563 ; WX 602 ; N SF280000 ; G 2482 +U 9564 ; WX 602 ; N SF270000 ; G 2483 +U 9565 ; WX 602 ; N SF260000 ; G 2484 +U 9566 ; WX 602 ; N SF360000 ; G 2485 +U 9567 ; WX 602 ; N SF370000 ; G 2486 +U 9568 ; WX 602 ; N SF420000 ; G 2487 +U 9569 ; WX 602 ; N SF190000 ; G 2488 +U 9570 ; WX 602 ; N SF200000 ; G 2489 +U 9571 ; WX 602 ; N SF230000 ; G 2490 +U 9572 ; WX 602 ; N SF470000 ; G 2491 +U 9573 ; WX 602 ; N SF480000 ; G 2492 +U 9574 ; WX 602 ; N SF410000 ; G 2493 +U 9575 ; WX 602 ; N SF450000 ; G 2494 +U 9576 ; WX 602 ; N SF460000 ; G 2495 +U 9577 ; WX 602 ; N SF400000 ; G 2496 +U 9578 ; WX 602 ; N SF540000 ; G 2497 +U 9579 ; WX 602 ; N SF530000 ; G 2498 +U 9580 ; WX 602 ; N SF440000 ; G 2499 +U 9581 ; WX 602 ; N uni256D ; G 2500 +U 9582 ; WX 602 ; N uni256E ; G 2501 +U 9583 ; WX 602 ; N uni256F ; G 2502 +U 9584 ; WX 602 ; N uni2570 ; G 2503 +U 9585 ; WX 602 ; N uni2571 ; G 2504 +U 9586 ; WX 602 ; N uni2572 ; G 2505 +U 9587 ; WX 602 ; N uni2573 ; G 2506 +U 9588 ; WX 602 ; N uni2574 ; G 2507 +U 9589 ; WX 602 ; N uni2575 ; G 2508 +U 9590 ; WX 602 ; N uni2576 ; G 2509 +U 9591 ; WX 602 ; N uni2577 ; G 2510 +U 9592 ; WX 602 ; N uni2578 ; G 2511 +U 9593 ; WX 602 ; N uni2579 ; G 2512 +U 9594 ; WX 602 ; N uni257A ; G 2513 +U 9595 ; WX 602 ; N uni257B ; G 2514 +U 9596 ; WX 602 ; N uni257C ; G 2515 +U 9597 ; WX 602 ; N uni257D ; G 2516 +U 9598 ; WX 602 ; N uni257E ; G 2517 +U 9599 ; WX 602 ; N uni257F ; G 2518 +U 9600 ; WX 602 ; N upblock ; G 2519 +U 9601 ; WX 602 ; N uni2581 ; G 2520 +U 9602 ; WX 602 ; N uni2582 ; G 2521 +U 9603 ; WX 602 ; N uni2583 ; G 2522 +U 9604 ; WX 602 ; N dnblock ; G 2523 +U 9605 ; WX 602 ; N uni2585 ; G 2524 +U 9606 ; WX 602 ; N uni2586 ; G 2525 +U 9607 ; WX 602 ; N uni2587 ; G 2526 +U 9608 ; WX 602 ; N block ; G 2527 +U 9609 ; WX 602 ; N uni2589 ; G 2528 +U 9610 ; WX 602 ; N uni258A ; G 2529 +U 9611 ; WX 602 ; N uni258B ; G 2530 +U 9612 ; WX 602 ; N lfblock ; G 2531 +U 9613 ; WX 602 ; N uni258D ; G 2532 +U 9614 ; WX 602 ; N uni258E ; G 2533 +U 9615 ; WX 602 ; N uni258F ; G 2534 +U 9616 ; WX 602 ; N rtblock ; G 2535 +U 9617 ; WX 602 ; N ltshade ; G 2536 +U 9618 ; WX 602 ; N shade ; G 2537 +U 9619 ; WX 602 ; N dkshade ; G 2538 +U 9620 ; WX 602 ; N uni2594 ; G 2539 +U 9621 ; WX 602 ; N uni2595 ; G 2540 +U 9622 ; WX 602 ; N uni2596 ; G 2541 +U 9623 ; WX 602 ; N uni2597 ; G 2542 +U 9624 ; WX 602 ; N uni2598 ; G 2543 +U 9625 ; WX 602 ; N uni2599 ; G 2544 +U 9626 ; WX 602 ; N uni259A ; G 2545 +U 9627 ; WX 602 ; N uni259B ; G 2546 +U 9628 ; WX 602 ; N uni259C ; G 2547 +U 9629 ; WX 602 ; N uni259D ; G 2548 +U 9630 ; WX 602 ; N uni259E ; G 2549 +U 9631 ; WX 602 ; N uni259F ; G 2550 +U 9632 ; WX 602 ; N filledbox ; G 2551 +U 9633 ; WX 602 ; N H22073 ; G 2552 +U 9634 ; WX 602 ; N uni25A2 ; G 2553 +U 9635 ; WX 602 ; N uni25A3 ; G 2554 +U 9636 ; WX 602 ; N uni25A4 ; G 2555 +U 9637 ; WX 602 ; N uni25A5 ; G 2556 +U 9638 ; WX 602 ; N uni25A6 ; G 2557 +U 9639 ; WX 602 ; N uni25A7 ; G 2558 +U 9640 ; WX 602 ; N uni25A8 ; G 2559 +U 9641 ; WX 602 ; N uni25A9 ; G 2560 +U 9642 ; WX 602 ; N H18543 ; G 2561 +U 9643 ; WX 602 ; N H18551 ; G 2562 +U 9644 ; WX 602 ; N filledrect ; G 2563 +U 9645 ; WX 602 ; N uni25AD ; G 2564 +U 9646 ; WX 602 ; N uni25AE ; G 2565 +U 9647 ; WX 602 ; N uni25AF ; G 2566 +U 9648 ; WX 602 ; N uni25B0 ; G 2567 +U 9649 ; WX 602 ; N uni25B1 ; G 2568 +U 9650 ; WX 602 ; N triagup ; G 2569 +U 9651 ; WX 602 ; N uni25B3 ; G 2570 +U 9652 ; WX 602 ; N uni25B4 ; G 2571 +U 9653 ; WX 602 ; N uni25B5 ; G 2572 +U 9654 ; WX 602 ; N uni25B6 ; G 2573 +U 9655 ; WX 602 ; N uni25B7 ; G 2574 +U 9656 ; WX 602 ; N uni25B8 ; G 2575 +U 9657 ; WX 602 ; N uni25B9 ; G 2576 +U 9658 ; WX 602 ; N triagrt ; G 2577 +U 9659 ; WX 602 ; N uni25BB ; G 2578 +U 9660 ; WX 602 ; N triagdn ; G 2579 +U 9661 ; WX 602 ; N uni25BD ; G 2580 +U 9662 ; WX 602 ; N uni25BE ; G 2581 +U 9663 ; WX 602 ; N uni25BF ; G 2582 +U 9664 ; WX 602 ; N uni25C0 ; G 2583 +U 9665 ; WX 602 ; N uni25C1 ; G 2584 +U 9666 ; WX 602 ; N uni25C2 ; G 2585 +U 9667 ; WX 602 ; N uni25C3 ; G 2586 +U 9668 ; WX 602 ; N triaglf ; G 2587 +U 9669 ; WX 602 ; N uni25C5 ; G 2588 +U 9670 ; WX 602 ; N uni25C6 ; G 2589 +U 9671 ; WX 602 ; N uni25C7 ; G 2590 +U 9672 ; WX 602 ; N uni25C8 ; G 2591 +U 9673 ; WX 602 ; N uni25C9 ; G 2592 +U 9674 ; WX 602 ; N lozenge ; G 2593 +U 9675 ; WX 602 ; N circle ; G 2594 +U 9676 ; WX 602 ; N uni25CC ; G 2595 +U 9677 ; WX 602 ; N uni25CD ; G 2596 +U 9678 ; WX 602 ; N uni25CE ; G 2597 +U 9679 ; WX 602 ; N H18533 ; G 2598 +U 9680 ; WX 602 ; N uni25D0 ; G 2599 +U 9681 ; WX 602 ; N uni25D1 ; G 2600 +U 9682 ; WX 602 ; N uni25D2 ; G 2601 +U 9683 ; WX 602 ; N uni25D3 ; G 2602 +U 9684 ; WX 602 ; N uni25D4 ; G 2603 +U 9685 ; WX 602 ; N uni25D5 ; G 2604 +U 9686 ; WX 602 ; N uni25D6 ; G 2605 +U 9687 ; WX 602 ; N uni25D7 ; G 2606 +U 9688 ; WX 602 ; N invbullet ; G 2607 +U 9689 ; WX 602 ; N invcircle ; G 2608 +U 9690 ; WX 602 ; N uni25DA ; G 2609 +U 9691 ; WX 602 ; N uni25DB ; G 2610 +U 9692 ; WX 602 ; N uni25DC ; G 2611 +U 9693 ; WX 602 ; N uni25DD ; G 2612 +U 9694 ; WX 602 ; N uni25DE ; G 2613 +U 9695 ; WX 602 ; N uni25DF ; G 2614 +U 9696 ; WX 602 ; N uni25E0 ; G 2615 +U 9697 ; WX 602 ; N uni25E1 ; G 2616 +U 9698 ; WX 602 ; N uni25E2 ; G 2617 +U 9699 ; WX 602 ; N uni25E3 ; G 2618 +U 9700 ; WX 602 ; N uni25E4 ; G 2619 +U 9701 ; WX 602 ; N uni25E5 ; G 2620 +U 9702 ; WX 602 ; N openbullet ; G 2621 +U 9703 ; WX 602 ; N uni25E7 ; G 2622 +U 9704 ; WX 602 ; N uni25E8 ; G 2623 +U 9705 ; WX 602 ; N uni25E9 ; G 2624 +U 9706 ; WX 602 ; N uni25EA ; G 2625 +U 9707 ; WX 602 ; N uni25EB ; G 2626 +U 9708 ; WX 602 ; N uni25EC ; G 2627 +U 9709 ; WX 602 ; N uni25ED ; G 2628 +U 9710 ; WX 602 ; N uni25EE ; G 2629 +U 9711 ; WX 602 ; N uni25EF ; G 2630 +U 9712 ; WX 602 ; N uni25F0 ; G 2631 +U 9713 ; WX 602 ; N uni25F1 ; G 2632 +U 9714 ; WX 602 ; N uni25F2 ; G 2633 +U 9715 ; WX 602 ; N uni25F3 ; G 2634 +U 9716 ; WX 602 ; N uni25F4 ; G 2635 +U 9717 ; WX 602 ; N uni25F5 ; G 2636 +U 9718 ; WX 602 ; N uni25F6 ; G 2637 +U 9719 ; WX 602 ; N uni25F7 ; G 2638 +U 9720 ; WX 602 ; N uni25F8 ; G 2639 +U 9721 ; WX 602 ; N uni25F9 ; G 2640 +U 9722 ; WX 602 ; N uni25FA ; G 2641 +U 9723 ; WX 602 ; N uni25FB ; G 2642 +U 9724 ; WX 602 ; N uni25FC ; G 2643 +U 9725 ; WX 602 ; N uni25FD ; G 2644 +U 9726 ; WX 602 ; N uni25FE ; G 2645 +U 9727 ; WX 602 ; N uni25FF ; G 2646 +U 9728 ; WX 602 ; N uni2600 ; G 2647 +U 9729 ; WX 602 ; N uni2601 ; G 2648 +U 9730 ; WX 602 ; N uni2602 ; G 2649 +U 9731 ; WX 602 ; N uni2603 ; G 2650 +U 9732 ; WX 602 ; N uni2604 ; G 2651 +U 9733 ; WX 602 ; N uni2605 ; G 2652 +U 9734 ; WX 602 ; N uni2606 ; G 2653 +U 9735 ; WX 602 ; N uni2607 ; G 2654 +U 9736 ; WX 602 ; N uni2608 ; G 2655 +U 9737 ; WX 602 ; N uni2609 ; G 2656 +U 9738 ; WX 602 ; N uni260A ; G 2657 +U 9739 ; WX 602 ; N uni260B ; G 2658 +U 9740 ; WX 602 ; N uni260C ; G 2659 +U 9741 ; WX 602 ; N uni260D ; G 2660 +U 9742 ; WX 602 ; N uni260E ; G 2661 +U 9743 ; WX 602 ; N uni260F ; G 2662 +U 9744 ; WX 602 ; N uni2610 ; G 2663 +U 9745 ; WX 602 ; N uni2611 ; G 2664 +U 9746 ; WX 602 ; N uni2612 ; G 2665 +U 9747 ; WX 602 ; N uni2613 ; G 2666 +U 9748 ; WX 602 ; N uni2614 ; G 2667 +U 9749 ; WX 602 ; N uni2615 ; G 2668 +U 9750 ; WX 602 ; N uni2616 ; G 2669 +U 9751 ; WX 602 ; N uni2617 ; G 2670 +U 9752 ; WX 602 ; N uni2618 ; G 2671 +U 9753 ; WX 602 ; N uni2619 ; G 2672 +U 9754 ; WX 602 ; N uni261A ; G 2673 +U 9755 ; WX 602 ; N uni261B ; G 2674 +U 9756 ; WX 602 ; N uni261C ; G 2675 +U 9757 ; WX 602 ; N uni261D ; G 2676 +U 9758 ; WX 602 ; N uni261E ; G 2677 +U 9759 ; WX 602 ; N uni261F ; G 2678 +U 9760 ; WX 602 ; N uni2620 ; G 2679 +U 9761 ; WX 602 ; N uni2621 ; G 2680 +U 9762 ; WX 602 ; N uni2622 ; G 2681 +U 9763 ; WX 602 ; N uni2623 ; G 2682 +U 9764 ; WX 602 ; N uni2624 ; G 2683 +U 9765 ; WX 602 ; N uni2625 ; G 2684 +U 9766 ; WX 602 ; N uni2626 ; G 2685 +U 9767 ; WX 602 ; N uni2627 ; G 2686 +U 9768 ; WX 602 ; N uni2628 ; G 2687 +U 9769 ; WX 602 ; N uni2629 ; G 2688 +U 9770 ; WX 602 ; N uni262A ; G 2689 +U 9771 ; WX 602 ; N uni262B ; G 2690 +U 9772 ; WX 602 ; N uni262C ; G 2691 +U 9773 ; WX 602 ; N uni262D ; G 2692 +U 9774 ; WX 602 ; N uni262E ; G 2693 +U 9775 ; WX 602 ; N uni262F ; G 2694 +U 9784 ; WX 602 ; N uni2638 ; G 2695 +U 9785 ; WX 602 ; N uni2639 ; G 2696 +U 9786 ; WX 602 ; N smileface ; G 2697 +U 9787 ; WX 602 ; N invsmileface ; G 2698 +U 9788 ; WX 602 ; N sun ; G 2699 +U 9789 ; WX 602 ; N uni263D ; G 2700 +U 9790 ; WX 602 ; N uni263E ; G 2701 +U 9791 ; WX 602 ; N uni263F ; G 2702 +U 9792 ; WX 602 ; N female ; G 2703 +U 9793 ; WX 602 ; N uni2641 ; G 2704 +U 9794 ; WX 602 ; N male ; G 2705 +U 9795 ; WX 602 ; N uni2643 ; G 2706 +U 9796 ; WX 602 ; N uni2644 ; G 2707 +U 9797 ; WX 602 ; N uni2645 ; G 2708 +U 9798 ; WX 602 ; N uni2646 ; G 2709 +U 9799 ; WX 602 ; N uni2647 ; G 2710 +U 9800 ; WX 602 ; N uni2648 ; G 2711 +U 9801 ; WX 602 ; N uni2649 ; G 2712 +U 9802 ; WX 602 ; N uni264A ; G 2713 +U 9803 ; WX 602 ; N uni264B ; G 2714 +U 9804 ; WX 602 ; N uni264C ; G 2715 +U 9805 ; WX 602 ; N uni264D ; G 2716 +U 9806 ; WX 602 ; N uni264E ; G 2717 +U 9807 ; WX 602 ; N uni264F ; G 2718 +U 9808 ; WX 602 ; N uni2650 ; G 2719 +U 9809 ; WX 602 ; N uni2651 ; G 2720 +U 9810 ; WX 602 ; N uni2652 ; G 2721 +U 9811 ; WX 602 ; N uni2653 ; G 2722 +U 9812 ; WX 602 ; N uni2654 ; G 2723 +U 9813 ; WX 602 ; N uni2655 ; G 2724 +U 9814 ; WX 602 ; N uni2656 ; G 2725 +U 9815 ; WX 602 ; N uni2657 ; G 2726 +U 9816 ; WX 602 ; N uni2658 ; G 2727 +U 9817 ; WX 602 ; N uni2659 ; G 2728 +U 9818 ; WX 602 ; N uni265A ; G 2729 +U 9819 ; WX 602 ; N uni265B ; G 2730 +U 9820 ; WX 602 ; N uni265C ; G 2731 +U 9821 ; WX 602 ; N uni265D ; G 2732 +U 9822 ; WX 602 ; N uni265E ; G 2733 +U 9823 ; WX 602 ; N uni265F ; G 2734 +U 9824 ; WX 602 ; N spade ; G 2735 +U 9825 ; WX 602 ; N uni2661 ; G 2736 +U 9826 ; WX 602 ; N uni2662 ; G 2737 +U 9827 ; WX 602 ; N club ; G 2738 +U 9828 ; WX 602 ; N uni2664 ; G 2739 +U 9829 ; WX 602 ; N heart ; G 2740 +U 9830 ; WX 602 ; N diamond ; G 2741 +U 9831 ; WX 602 ; N uni2667 ; G 2742 +U 9832 ; WX 602 ; N uni2668 ; G 2743 +U 9833 ; WX 602 ; N uni2669 ; G 2744 +U 9834 ; WX 602 ; N musicalnote ; G 2745 +U 9835 ; WX 602 ; N musicalnotedbl ; G 2746 +U 9836 ; WX 602 ; N uni266C ; G 2747 +U 9837 ; WX 602 ; N uni266D ; G 2748 +U 9838 ; WX 602 ; N uni266E ; G 2749 +U 9839 ; WX 602 ; N uni266F ; G 2750 +U 9840 ; WX 602 ; N uni2670 ; G 2751 +U 9841 ; WX 602 ; N uni2671 ; G 2752 +U 9842 ; WX 602 ; N uni2672 ; G 2753 +U 9843 ; WX 602 ; N uni2673 ; G 2754 +U 9844 ; WX 602 ; N uni2674 ; G 2755 +U 9845 ; WX 602 ; N uni2675 ; G 2756 +U 9846 ; WX 602 ; N uni2676 ; G 2757 +U 9847 ; WX 602 ; N uni2677 ; G 2758 +U 9848 ; WX 602 ; N uni2678 ; G 2759 +U 9849 ; WX 602 ; N uni2679 ; G 2760 +U 9850 ; WX 602 ; N uni267A ; G 2761 +U 9851 ; WX 602 ; N uni267B ; G 2762 +U 9852 ; WX 602 ; N uni267C ; G 2763 +U 9853 ; WX 602 ; N uni267D ; G 2764 +U 9854 ; WX 602 ; N uni267E ; G 2765 +U 9855 ; WX 602 ; N uni267F ; G 2766 +U 9856 ; WX 602 ; N uni2680 ; G 2767 +U 9857 ; WX 602 ; N uni2681 ; G 2768 +U 9858 ; WX 602 ; N uni2682 ; G 2769 +U 9859 ; WX 602 ; N uni2683 ; G 2770 +U 9860 ; WX 602 ; N uni2684 ; G 2771 +U 9861 ; WX 602 ; N uni2685 ; G 2772 +U 9862 ; WX 602 ; N uni2686 ; G 2773 +U 9863 ; WX 602 ; N uni2687 ; G 2774 +U 9864 ; WX 602 ; N uni2688 ; G 2775 +U 9865 ; WX 602 ; N uni2689 ; G 2776 +U 9866 ; WX 602 ; N uni268A ; G 2777 +U 9867 ; WX 602 ; N uni268B ; G 2778 +U 9872 ; WX 602 ; N uni2690 ; G 2779 +U 9873 ; WX 602 ; N uni2691 ; G 2780 +U 9874 ; WX 602 ; N uni2692 ; G 2781 +U 9875 ; WX 602 ; N uni2693 ; G 2782 +U 9876 ; WX 602 ; N uni2694 ; G 2783 +U 9877 ; WX 602 ; N uni2695 ; G 2784 +U 9878 ; WX 602 ; N uni2696 ; G 2785 +U 9879 ; WX 602 ; N uni2697 ; G 2786 +U 9880 ; WX 602 ; N uni2698 ; G 2787 +U 9881 ; WX 602 ; N uni2699 ; G 2788 +U 9882 ; WX 602 ; N uni269A ; G 2789 +U 9883 ; WX 602 ; N uni269B ; G 2790 +U 9884 ; WX 602 ; N uni269C ; G 2791 +U 9888 ; WX 602 ; N uni26A0 ; G 2792 +U 9889 ; WX 602 ; N uni26A1 ; G 2793 +U 9904 ; WX 602 ; N uni26B0 ; G 2794 +U 9905 ; WX 602 ; N uni26B1 ; G 2795 +U 9985 ; WX 602 ; N uni2701 ; G 2796 +U 9986 ; WX 602 ; N uni2702 ; G 2797 +U 9987 ; WX 602 ; N uni2703 ; G 2798 +U 9988 ; WX 602 ; N uni2704 ; G 2799 +U 9990 ; WX 602 ; N uni2706 ; G 2800 +U 9991 ; WX 602 ; N uni2707 ; G 2801 +U 9992 ; WX 602 ; N uni2708 ; G 2802 +U 9993 ; WX 602 ; N uni2709 ; G 2803 +U 9996 ; WX 602 ; N uni270C ; G 2804 +U 9997 ; WX 602 ; N uni270D ; G 2805 +U 9998 ; WX 602 ; N uni270E ; G 2806 +U 9999 ; WX 602 ; N uni270F ; G 2807 +U 10000 ; WX 602 ; N uni2710 ; G 2808 +U 10001 ; WX 602 ; N uni2711 ; G 2809 +U 10002 ; WX 602 ; N uni2712 ; G 2810 +U 10003 ; WX 602 ; N uni2713 ; G 2811 +U 10004 ; WX 602 ; N uni2714 ; G 2812 +U 10005 ; WX 602 ; N uni2715 ; G 2813 +U 10006 ; WX 602 ; N uni2716 ; G 2814 +U 10007 ; WX 602 ; N uni2717 ; G 2815 +U 10008 ; WX 602 ; N uni2718 ; G 2816 +U 10009 ; WX 602 ; N uni2719 ; G 2817 +U 10010 ; WX 602 ; N uni271A ; G 2818 +U 10011 ; WX 602 ; N uni271B ; G 2819 +U 10012 ; WX 602 ; N uni271C ; G 2820 +U 10013 ; WX 602 ; N uni271D ; G 2821 +U 10014 ; WX 602 ; N uni271E ; G 2822 +U 10015 ; WX 602 ; N uni271F ; G 2823 +U 10016 ; WX 602 ; N uni2720 ; G 2824 +U 10017 ; WX 602 ; N uni2721 ; G 2825 +U 10018 ; WX 602 ; N uni2722 ; G 2826 +U 10019 ; WX 602 ; N uni2723 ; G 2827 +U 10020 ; WX 602 ; N uni2724 ; G 2828 +U 10021 ; WX 602 ; N uni2725 ; G 2829 +U 10022 ; WX 602 ; N uni2726 ; G 2830 +U 10023 ; WX 602 ; N uni2727 ; G 2831 +U 10025 ; WX 602 ; N uni2729 ; G 2832 +U 10026 ; WX 602 ; N uni272A ; G 2833 +U 10027 ; WX 602 ; N uni272B ; G 2834 +U 10028 ; WX 602 ; N uni272C ; G 2835 +U 10029 ; WX 602 ; N uni272D ; G 2836 +U 10030 ; WX 602 ; N uni272E ; G 2837 +U 10031 ; WX 602 ; N uni272F ; G 2838 +U 10032 ; WX 602 ; N uni2730 ; G 2839 +U 10033 ; WX 602 ; N uni2731 ; G 2840 +U 10034 ; WX 602 ; N uni2732 ; G 2841 +U 10035 ; WX 602 ; N uni2733 ; G 2842 +U 10036 ; WX 602 ; N uni2734 ; G 2843 +U 10037 ; WX 602 ; N uni2735 ; G 2844 +U 10038 ; WX 602 ; N uni2736 ; G 2845 +U 10039 ; WX 602 ; N uni2737 ; G 2846 +U 10040 ; WX 602 ; N uni2738 ; G 2847 +U 10041 ; WX 602 ; N uni2739 ; G 2848 +U 10042 ; WX 602 ; N uni273A ; G 2849 +U 10043 ; WX 602 ; N uni273B ; G 2850 +U 10044 ; WX 602 ; N uni273C ; G 2851 +U 10045 ; WX 602 ; N uni273D ; G 2852 +U 10046 ; WX 602 ; N uni273E ; G 2853 +U 10047 ; WX 602 ; N uni273F ; G 2854 +U 10048 ; WX 602 ; N uni2740 ; G 2855 +U 10049 ; WX 602 ; N uni2741 ; G 2856 +U 10050 ; WX 602 ; N uni2742 ; G 2857 +U 10051 ; WX 602 ; N uni2743 ; G 2858 +U 10052 ; WX 602 ; N uni2744 ; G 2859 +U 10053 ; WX 602 ; N uni2745 ; G 2860 +U 10054 ; WX 602 ; N uni2746 ; G 2861 +U 10055 ; WX 602 ; N uni2747 ; G 2862 +U 10056 ; WX 602 ; N uni2748 ; G 2863 +U 10057 ; WX 602 ; N uni2749 ; G 2864 +U 10058 ; WX 602 ; N uni274A ; G 2865 +U 10059 ; WX 602 ; N uni274B ; G 2866 +U 10061 ; WX 602 ; N uni274D ; G 2867 +U 10063 ; WX 602 ; N uni274F ; G 2868 +U 10064 ; WX 602 ; N uni2750 ; G 2869 +U 10065 ; WX 602 ; N uni2751 ; G 2870 +U 10066 ; WX 602 ; N uni2752 ; G 2871 +U 10070 ; WX 602 ; N uni2756 ; G 2872 +U 10072 ; WX 602 ; N uni2758 ; G 2873 +U 10073 ; WX 602 ; N uni2759 ; G 2874 +U 10074 ; WX 602 ; N uni275A ; G 2875 +U 10075 ; WX 602 ; N uni275B ; G 2876 +U 10076 ; WX 602 ; N uni275C ; G 2877 +U 10077 ; WX 602 ; N uni275D ; G 2878 +U 10078 ; WX 602 ; N uni275E ; G 2879 +U 10081 ; WX 602 ; N uni2761 ; G 2880 +U 10082 ; WX 602 ; N uni2762 ; G 2881 +U 10083 ; WX 602 ; N uni2763 ; G 2882 +U 10084 ; WX 602 ; N uni2764 ; G 2883 +U 10085 ; WX 602 ; N uni2765 ; G 2884 +U 10086 ; WX 602 ; N uni2766 ; G 2885 +U 10087 ; WX 602 ; N uni2767 ; G 2886 +U 10088 ; WX 602 ; N uni2768 ; G 2887 +U 10089 ; WX 602 ; N uni2769 ; G 2888 +U 10090 ; WX 602 ; N uni276A ; G 2889 +U 10091 ; WX 602 ; N uni276B ; G 2890 +U 10092 ; WX 602 ; N uni276C ; G 2891 +U 10093 ; WX 602 ; N uni276D ; G 2892 +U 10094 ; WX 602 ; N uni276E ; G 2893 +U 10095 ; WX 602 ; N uni276F ; G 2894 +U 10096 ; WX 602 ; N uni2770 ; G 2895 +U 10097 ; WX 602 ; N uni2771 ; G 2896 +U 10098 ; WX 602 ; N uni2772 ; G 2897 +U 10099 ; WX 602 ; N uni2773 ; G 2898 +U 10100 ; WX 602 ; N uni2774 ; G 2899 +U 10101 ; WX 602 ; N uni2775 ; G 2900 +U 10132 ; WX 602 ; N uni2794 ; G 2901 +U 10136 ; WX 602 ; N uni2798 ; G 2902 +U 10137 ; WX 602 ; N uni2799 ; G 2903 +U 10138 ; WX 602 ; N uni279A ; G 2904 +U 10139 ; WX 602 ; N uni279B ; G 2905 +U 10140 ; WX 602 ; N uni279C ; G 2906 +U 10141 ; WX 602 ; N uni279D ; G 2907 +U 10142 ; WX 602 ; N uni279E ; G 2908 +U 10143 ; WX 602 ; N uni279F ; G 2909 +U 10144 ; WX 602 ; N uni27A0 ; G 2910 +U 10145 ; WX 602 ; N uni27A1 ; G 2911 +U 10146 ; WX 602 ; N uni27A2 ; G 2912 +U 10147 ; WX 602 ; N uni27A3 ; G 2913 +U 10148 ; WX 602 ; N uni27A4 ; G 2914 +U 10149 ; WX 602 ; N uni27A5 ; G 2915 +U 10150 ; WX 602 ; N uni27A6 ; G 2916 +U 10151 ; WX 602 ; N uni27A7 ; G 2917 +U 10152 ; WX 602 ; N uni27A8 ; G 2918 +U 10153 ; WX 602 ; N uni27A9 ; G 2919 +U 10154 ; WX 602 ; N uni27AA ; G 2920 +U 10155 ; WX 602 ; N uni27AB ; G 2921 +U 10156 ; WX 602 ; N uni27AC ; G 2922 +U 10157 ; WX 602 ; N uni27AD ; G 2923 +U 10158 ; WX 602 ; N uni27AE ; G 2924 +U 10159 ; WX 602 ; N uni27AF ; G 2925 +U 10161 ; WX 602 ; N uni27B1 ; G 2926 +U 10162 ; WX 602 ; N uni27B2 ; G 2927 +U 10163 ; WX 602 ; N uni27B3 ; G 2928 +U 10164 ; WX 602 ; N uni27B4 ; G 2929 +U 10165 ; WX 602 ; N uni27B5 ; G 2930 +U 10166 ; WX 602 ; N uni27B6 ; G 2931 +U 10167 ; WX 602 ; N uni27B7 ; G 2932 +U 10168 ; WX 602 ; N uni27B8 ; G 2933 +U 10169 ; WX 602 ; N uni27B9 ; G 2934 +U 10170 ; WX 602 ; N uni27BA ; G 2935 +U 10171 ; WX 602 ; N uni27BB ; G 2936 +U 10172 ; WX 602 ; N uni27BC ; G 2937 +U 10173 ; WX 602 ; N uni27BD ; G 2938 +U 10174 ; WX 602 ; N uni27BE ; G 2939 +U 10175 ; WX 602 ; N uni27BF ; G 2940 +U 10178 ; WX 602 ; N uni27C2 ; G 2941 +U 10181 ; WX 602 ; N uni27C5 ; G 2942 +U 10182 ; WX 602 ; N uni27C6 ; G 2943 +U 10204 ; WX 602 ; N uni27DC ; G 2944 +U 10208 ; WX 602 ; N uni27E0 ; G 2945 +U 10214 ; WX 602 ; N uni27E6 ; G 2946 +U 10215 ; WX 602 ; N uni27E7 ; G 2947 +U 10216 ; WX 602 ; N uni27E8 ; G 2948 +U 10217 ; WX 602 ; N uni27E9 ; G 2949 +U 10218 ; WX 602 ; N uni27EA ; G 2950 +U 10219 ; WX 602 ; N uni27EB ; G 2951 +U 10229 ; WX 602 ; N uni27F5 ; G 2952 +U 10230 ; WX 602 ; N uni27F6 ; G 2953 +U 10231 ; WX 602 ; N uni27F7 ; G 2954 +U 10631 ; WX 602 ; N uni2987 ; G 2955 +U 10632 ; WX 602 ; N uni2988 ; G 2956 +U 10647 ; WX 602 ; N uni2997 ; G 2957 +U 10648 ; WX 602 ; N uni2998 ; G 2958 +U 10731 ; WX 602 ; N uni29EB ; G 2959 +U 10746 ; WX 602 ; N uni29FA ; G 2960 +U 10747 ; WX 602 ; N uni29FB ; G 2961 +U 10752 ; WX 602 ; N uni2A00 ; G 2962 +U 10799 ; WX 602 ; N uni2A2F ; G 2963 +U 10858 ; WX 602 ; N uni2A6A ; G 2964 +U 10859 ; WX 602 ; N uni2A6B ; G 2965 +U 11013 ; WX 602 ; N uni2B05 ; G 2966 +U 11014 ; WX 602 ; N uni2B06 ; G 2967 +U 11015 ; WX 602 ; N uni2B07 ; G 2968 +U 11016 ; WX 602 ; N uni2B08 ; G 2969 +U 11017 ; WX 602 ; N uni2B09 ; G 2970 +U 11018 ; WX 602 ; N uni2B0A ; G 2971 +U 11019 ; WX 602 ; N uni2B0B ; G 2972 +U 11020 ; WX 602 ; N uni2B0C ; G 2973 +U 11021 ; WX 602 ; N uni2B0D ; G 2974 +U 11026 ; WX 602 ; N uni2B12 ; G 2975 +U 11027 ; WX 602 ; N uni2B13 ; G 2976 +U 11028 ; WX 602 ; N uni2B14 ; G 2977 +U 11029 ; WX 602 ; N uni2B15 ; G 2978 +U 11030 ; WX 602 ; N uni2B16 ; G 2979 +U 11031 ; WX 602 ; N uni2B17 ; G 2980 +U 11032 ; WX 602 ; N uni2B18 ; G 2981 +U 11033 ; WX 602 ; N uni2B19 ; G 2982 +U 11034 ; WX 602 ; N uni2B1A ; G 2983 +U 11364 ; WX 602 ; N uni2C64 ; G 2984 +U 11373 ; WX 602 ; N uni2C6D ; G 2985 +U 11374 ; WX 602 ; N uni2C6E ; G 2986 +U 11375 ; WX 602 ; N uni2C6F ; G 2987 +U 11376 ; WX 602 ; N uni2C70 ; G 2988 +U 11381 ; WX 602 ; N uni2C75 ; G 2989 +U 11382 ; WX 602 ; N uni2C76 ; G 2990 +U 11383 ; WX 602 ; N uni2C77 ; G 2991 +U 11385 ; WX 602 ; N uni2C79 ; G 2992 +U 11386 ; WX 602 ; N uni2C7A ; G 2993 +U 11388 ; WX 602 ; N uni2C7C ; G 2994 +U 11389 ; WX 602 ; N uni2C7D ; G 2995 +U 11390 ; WX 602 ; N uni2C7E ; G 2996 +U 11391 ; WX 602 ; N uni2C7F ; G 2997 +U 11800 ; WX 602 ; N uni2E18 ; G 2998 +U 11807 ; WX 602 ; N uni2E1F ; G 2999 +U 11810 ; WX 602 ; N uni2E22 ; G 3000 +U 11811 ; WX 602 ; N uni2E23 ; G 3001 +U 11812 ; WX 602 ; N uni2E24 ; G 3002 +U 11813 ; WX 602 ; N uni2E25 ; G 3003 +U 11822 ; WX 602 ; N uni2E2E ; G 3004 +U 42760 ; WX 602 ; N uniA708 ; G 3005 +U 42761 ; WX 602 ; N uniA709 ; G 3006 +U 42762 ; WX 602 ; N uniA70A ; G 3007 +U 42763 ; WX 602 ; N uniA70B ; G 3008 +U 42764 ; WX 602 ; N uniA70C ; G 3009 +U 42765 ; WX 602 ; N uniA70D ; G 3010 +U 42766 ; WX 602 ; N uniA70E ; G 3011 +U 42767 ; WX 602 ; N uniA70F ; G 3012 +U 42768 ; WX 602 ; N uniA710 ; G 3013 +U 42769 ; WX 602 ; N uniA711 ; G 3014 +U 42770 ; WX 602 ; N uniA712 ; G 3015 +U 42771 ; WX 602 ; N uniA713 ; G 3016 +U 42772 ; WX 602 ; N uniA714 ; G 3017 +U 42773 ; WX 602 ; N uniA715 ; G 3018 +U 42774 ; WX 602 ; N uniA716 ; G 3019 +U 42779 ; WX 602 ; N uniA71B ; G 3020 +U 42780 ; WX 602 ; N uniA71C ; G 3021 +U 42781 ; WX 602 ; N uniA71D ; G 3022 +U 42782 ; WX 602 ; N uniA71E ; G 3023 +U 42783 ; WX 602 ; N uniA71F ; G 3024 +U 42786 ; WX 602 ; N uniA722 ; G 3025 +U 42787 ; WX 602 ; N uniA723 ; G 3026 +U 42788 ; WX 602 ; N uniA724 ; G 3027 +U 42789 ; WX 602 ; N uniA725 ; G 3028 +U 42790 ; WX 602 ; N uniA726 ; G 3029 +U 42791 ; WX 602 ; N uniA727 ; G 3030 +U 42889 ; WX 602 ; N uniA789 ; G 3031 +U 42890 ; WX 602 ; N uniA78A ; G 3032 +U 42891 ; WX 602 ; N uniA78B ; G 3033 +U 42892 ; WX 602 ; N uniA78C ; G 3034 +U 42893 ; WX 602 ; N uniA78D ; G 3035 +U 42894 ; WX 602 ; N uniA78E ; G 3036 +U 42896 ; WX 602 ; N uniA790 ; G 3037 +U 42897 ; WX 602 ; N uniA791 ; G 3038 +U 42922 ; WX 602 ; N uniA7AA ; G 3039 +U 43000 ; WX 602 ; N uniA7F8 ; G 3040 +U 43001 ; WX 602 ; N uniA7F9 ; G 3041 +U 63173 ; WX 602 ; N uniF6C5 ; G 3042 +U 64257 ; WX 602 ; N fi ; G 3043 +U 64258 ; WX 602 ; N fl ; G 3044 +U 64338 ; WX 602 ; N uniFB52 ; G 3045 +U 64339 ; WX 602 ; N uniFB53 ; G 3046 +U 64340 ; WX 602 ; N uniFB54 ; G 3047 +U 64341 ; WX 602 ; N uniFB55 ; G 3048 +U 64342 ; WX 602 ; N uniFB56 ; G 3049 +U 64343 ; WX 602 ; N uniFB57 ; G 3050 +U 64344 ; WX 602 ; N uniFB58 ; G 3051 +U 64345 ; WX 602 ; N uniFB59 ; G 3052 +U 64346 ; WX 602 ; N uniFB5A ; G 3053 +U 64347 ; WX 602 ; N uniFB5B ; G 3054 +U 64348 ; WX 602 ; N uniFB5C ; G 3055 +U 64349 ; WX 602 ; N uniFB5D ; G 3056 +U 64350 ; WX 602 ; N uniFB5E ; G 3057 +U 64351 ; WX 602 ; N uniFB5F ; G 3058 +U 64352 ; WX 602 ; N uniFB60 ; G 3059 +U 64353 ; WX 602 ; N uniFB61 ; G 3060 +U 64354 ; WX 602 ; N uniFB62 ; G 3061 +U 64355 ; WX 602 ; N uniFB63 ; G 3062 +U 64356 ; WX 602 ; N uniFB64 ; G 3063 +U 64357 ; WX 602 ; N uniFB65 ; G 3064 +U 64358 ; WX 602 ; N uniFB66 ; G 3065 +U 64359 ; WX 602 ; N uniFB67 ; G 3066 +U 64360 ; WX 602 ; N uniFB68 ; G 3067 +U 64361 ; WX 602 ; N uniFB69 ; G 3068 +U 64362 ; WX 602 ; N uniFB6A ; G 3069 +U 64363 ; WX 602 ; N uniFB6B ; G 3070 +U 64364 ; WX 602 ; N uniFB6C ; G 3071 +U 64365 ; WX 602 ; N uniFB6D ; G 3072 +U 64366 ; WX 602 ; N uniFB6E ; G 3073 +U 64367 ; WX 602 ; N uniFB6F ; G 3074 +U 64368 ; WX 602 ; N uniFB70 ; G 3075 +U 64369 ; WX 602 ; N uniFB71 ; G 3076 +U 64370 ; WX 602 ; N uniFB72 ; G 3077 +U 64371 ; WX 602 ; N uniFB73 ; G 3078 +U 64372 ; WX 602 ; N uniFB74 ; G 3079 +U 64373 ; WX 602 ; N uniFB75 ; G 3080 +U 64374 ; WX 602 ; N uniFB76 ; G 3081 +U 64375 ; WX 602 ; N uniFB77 ; G 3082 +U 64376 ; WX 602 ; N uniFB78 ; G 3083 +U 64377 ; WX 602 ; N uniFB79 ; G 3084 +U 64378 ; WX 602 ; N uniFB7A ; G 3085 +U 64379 ; WX 602 ; N uniFB7B ; G 3086 +U 64380 ; WX 602 ; N uniFB7C ; G 3087 +U 64381 ; WX 602 ; N uniFB7D ; G 3088 +U 64382 ; WX 602 ; N uniFB7E ; G 3089 +U 64383 ; WX 602 ; N uniFB7F ; G 3090 +U 64384 ; WX 602 ; N uniFB80 ; G 3091 +U 64385 ; WX 602 ; N uniFB81 ; G 3092 +U 64394 ; WX 602 ; N uniFB8A ; G 3093 +U 64395 ; WX 602 ; N uniFB8B ; G 3094 +U 64396 ; WX 602 ; N uniFB8C ; G 3095 +U 64397 ; WX 602 ; N uniFB8D ; G 3096 +U 64398 ; WX 602 ; N uniFB8E ; G 3097 +U 64399 ; WX 602 ; N uniFB8F ; G 3098 +U 64400 ; WX 602 ; N uniFB90 ; G 3099 +U 64401 ; WX 602 ; N uniFB91 ; G 3100 +U 64402 ; WX 602 ; N uniFB92 ; G 3101 +U 64403 ; WX 602 ; N uniFB93 ; G 3102 +U 64404 ; WX 602 ; N uniFB94 ; G 3103 +U 64405 ; WX 602 ; N uniFB95 ; G 3104 +U 64414 ; WX 602 ; N uniFB9E ; G 3105 +U 64415 ; WX 602 ; N uniFB9F ; G 3106 +U 64426 ; WX 602 ; N uniFBAA ; G 3107 +U 64427 ; WX 602 ; N uniFBAB ; G 3108 +U 64428 ; WX 602 ; N uniFBAC ; G 3109 +U 64429 ; WX 602 ; N uniFBAD ; G 3110 +U 64488 ; WX 602 ; N uniFBE8 ; G 3111 +U 64489 ; WX 602 ; N uniFBE9 ; G 3112 +U 64508 ; WX 602 ; N uniFBFC ; G 3113 +U 64509 ; WX 602 ; N uniFBFD ; G 3114 +U 64510 ; WX 602 ; N uniFBFE ; G 3115 +U 64511 ; WX 602 ; N uniFBFF ; G 3116 +U 65136 ; WX 602 ; N uniFE70 ; G 3117 +U 65137 ; WX 602 ; N uniFE71 ; G 3118 +U 65138 ; WX 602 ; N uniFE72 ; G 3119 +U 65139 ; WX 602 ; N uniFE73 ; G 3120 +U 65140 ; WX 602 ; N uniFE74 ; G 3121 +U 65142 ; WX 602 ; N uniFE76 ; G 3122 +U 65143 ; WX 602 ; N uniFE77 ; G 3123 +U 65144 ; WX 602 ; N uniFE78 ; G 3124 +U 65145 ; WX 602 ; N uniFE79 ; G 3125 +U 65146 ; WX 602 ; N uniFE7A ; G 3126 +U 65147 ; WX 602 ; N uniFE7B ; G 3127 +U 65148 ; WX 602 ; N uniFE7C ; G 3128 +U 65149 ; WX 602 ; N uniFE7D ; G 3129 +U 65150 ; WX 602 ; N uniFE7E ; G 3130 +U 65151 ; WX 602 ; N uniFE7F ; G 3131 +U 65152 ; WX 602 ; N uniFE80 ; G 3132 +U 65153 ; WX 602 ; N uniFE81 ; G 3133 +U 65154 ; WX 602 ; N uniFE82 ; G 3134 +U 65155 ; WX 602 ; N uniFE83 ; G 3135 +U 65156 ; WX 602 ; N uniFE84 ; G 3136 +U 65157 ; WX 602 ; N uniFE85 ; G 3137 +U 65158 ; WX 602 ; N uniFE86 ; G 3138 +U 65159 ; WX 602 ; N uniFE87 ; G 3139 +U 65160 ; WX 602 ; N uniFE88 ; G 3140 +U 65161 ; WX 602 ; N uniFE89 ; G 3141 +U 65162 ; WX 602 ; N uniFE8A ; G 3142 +U 65163 ; WX 602 ; N uniFE8B ; G 3143 +U 65164 ; WX 602 ; N uniFE8C ; G 3144 +U 65165 ; WX 602 ; N uniFE8D ; G 3145 +U 65166 ; WX 602 ; N uniFE8E ; G 3146 +U 65167 ; WX 602 ; N uniFE8F ; G 3147 +U 65168 ; WX 602 ; N uniFE90 ; G 3148 +U 65169 ; WX 602 ; N uniFE91 ; G 3149 +U 65170 ; WX 602 ; N uniFE92 ; G 3150 +U 65171 ; WX 602 ; N uniFE93 ; G 3151 +U 65172 ; WX 602 ; N uniFE94 ; G 3152 +U 65173 ; WX 602 ; N uniFE95 ; G 3153 +U 65174 ; WX 602 ; N uniFE96 ; G 3154 +U 65175 ; WX 602 ; N uniFE97 ; G 3155 +U 65176 ; WX 602 ; N uniFE98 ; G 3156 +U 65177 ; WX 602 ; N uniFE99 ; G 3157 +U 65178 ; WX 602 ; N uniFE9A ; G 3158 +U 65179 ; WX 602 ; N uniFE9B ; G 3159 +U 65180 ; WX 602 ; N uniFE9C ; G 3160 +U 65181 ; WX 602 ; N uniFE9D ; G 3161 +U 65182 ; WX 602 ; N uniFE9E ; G 3162 +U 65183 ; WX 602 ; N uniFE9F ; G 3163 +U 65184 ; WX 602 ; N uniFEA0 ; G 3164 +U 65185 ; WX 602 ; N uniFEA1 ; G 3165 +U 65186 ; WX 602 ; N uniFEA2 ; G 3166 +U 65187 ; WX 602 ; N uniFEA3 ; G 3167 +U 65188 ; WX 602 ; N uniFEA4 ; G 3168 +U 65189 ; WX 602 ; N uniFEA5 ; G 3169 +U 65190 ; WX 602 ; N uniFEA6 ; G 3170 +U 65191 ; WX 602 ; N uniFEA7 ; G 3171 +U 65192 ; WX 602 ; N uniFEA8 ; G 3172 +U 65193 ; WX 602 ; N uniFEA9 ; G 3173 +U 65194 ; WX 602 ; N uniFEAA ; G 3174 +U 65195 ; WX 602 ; N uniFEAB ; G 3175 +U 65196 ; WX 602 ; N uniFEAC ; G 3176 +U 65197 ; WX 602 ; N uniFEAD ; G 3177 +U 65198 ; WX 602 ; N uniFEAE ; G 3178 +U 65199 ; WX 602 ; N uniFEAF ; G 3179 +U 65200 ; WX 602 ; N uniFEB0 ; G 3180 +U 65201 ; WX 602 ; N uniFEB1 ; G 3181 +U 65202 ; WX 602 ; N uniFEB2 ; G 3182 +U 65203 ; WX 602 ; N uniFEB3 ; G 3183 +U 65204 ; WX 602 ; N uniFEB4 ; G 3184 +U 65205 ; WX 602 ; N uniFEB5 ; G 3185 +U 65206 ; WX 602 ; N uniFEB6 ; G 3186 +U 65207 ; WX 602 ; N uniFEB7 ; G 3187 +U 65208 ; WX 602 ; N uniFEB8 ; G 3188 +U 65209 ; WX 602 ; N uniFEB9 ; G 3189 +U 65210 ; WX 602 ; N uniFEBA ; G 3190 +U 65211 ; WX 602 ; N uniFEBB ; G 3191 +U 65212 ; WX 602 ; N uniFEBC ; G 3192 +U 65213 ; WX 602 ; N uniFEBD ; G 3193 +U 65214 ; WX 602 ; N uniFEBE ; G 3194 +U 65215 ; WX 602 ; N uniFEBF ; G 3195 +U 65216 ; WX 602 ; N uniFEC0 ; G 3196 +U 65217 ; WX 602 ; N uniFEC1 ; G 3197 +U 65218 ; WX 602 ; N uniFEC2 ; G 3198 +U 65219 ; WX 602 ; N uniFEC3 ; G 3199 +U 65220 ; WX 602 ; N uniFEC4 ; G 3200 +U 65221 ; WX 602 ; N uniFEC5 ; G 3201 +U 65222 ; WX 602 ; N uniFEC6 ; G 3202 +U 65223 ; WX 602 ; N uniFEC7 ; G 3203 +U 65224 ; WX 602 ; N uniFEC8 ; G 3204 +U 65225 ; WX 602 ; N uniFEC9 ; G 3205 +U 65226 ; WX 602 ; N uniFECA ; G 3206 +U 65227 ; WX 602 ; N uniFECB ; G 3207 +U 65228 ; WX 602 ; N uniFECC ; G 3208 +U 65229 ; WX 602 ; N uniFECD ; G 3209 +U 65230 ; WX 602 ; N uniFECE ; G 3210 +U 65231 ; WX 602 ; N uniFECF ; G 3211 +U 65232 ; WX 602 ; N uniFED0 ; G 3212 +U 65233 ; WX 602 ; N uniFED1 ; G 3213 +U 65234 ; WX 602 ; N uniFED2 ; G 3214 +U 65235 ; WX 602 ; N uniFED3 ; G 3215 +U 65236 ; WX 602 ; N uniFED4 ; G 3216 +U 65237 ; WX 602 ; N uniFED5 ; G 3217 +U 65238 ; WX 602 ; N uniFED6 ; G 3218 +U 65239 ; WX 602 ; N uniFED7 ; G 3219 +U 65240 ; WX 602 ; N uniFED8 ; G 3220 +U 65241 ; WX 602 ; N uniFED9 ; G 3221 +U 65242 ; WX 602 ; N uniFEDA ; G 3222 +U 65243 ; WX 602 ; N uniFEDB ; G 3223 +U 65244 ; WX 602 ; N uniFEDC ; G 3224 +U 65245 ; WX 602 ; N uniFEDD ; G 3225 +U 65246 ; WX 602 ; N uniFEDE ; G 3226 +U 65247 ; WX 602 ; N uniFEDF ; G 3227 +U 65248 ; WX 602 ; N uniFEE0 ; G 3228 +U 65249 ; WX 602 ; N uniFEE1 ; G 3229 +U 65250 ; WX 602 ; N uniFEE2 ; G 3230 +U 65251 ; WX 602 ; N uniFEE3 ; G 3231 +U 65252 ; WX 602 ; N uniFEE4 ; G 3232 +U 65253 ; WX 602 ; N uniFEE5 ; G 3233 +U 65254 ; WX 602 ; N uniFEE6 ; G 3234 +U 65255 ; WX 602 ; N uniFEE7 ; G 3235 +U 65256 ; WX 602 ; N uniFEE8 ; G 3236 +U 65257 ; WX 602 ; N uniFEE9 ; G 3237 +U 65258 ; WX 602 ; N uniFEEA ; G 3238 +U 65259 ; WX 602 ; N uniFEEB ; G 3239 +U 65260 ; WX 602 ; N uniFEEC ; G 3240 +U 65261 ; WX 602 ; N uniFEED ; G 3241 +U 65262 ; WX 602 ; N uniFEEE ; G 3242 +U 65263 ; WX 602 ; N uniFEEF ; G 3243 +U 65264 ; WX 602 ; N uniFEF0 ; G 3244 +U 65265 ; WX 602 ; N uniFEF1 ; G 3245 +U 65266 ; WX 602 ; N uniFEF2 ; G 3246 +U 65267 ; WX 602 ; N uniFEF3 ; G 3247 +U 65268 ; WX 602 ; N uniFEF4 ; G 3248 +U 65269 ; WX 602 ; N uniFEF5 ; G 3249 +U 65270 ; WX 602 ; N uniFEF6 ; G 3250 +U 65271 ; WX 602 ; N uniFEF7 ; G 3251 +U 65272 ; WX 602 ; N uniFEF8 ; G 3252 +U 65273 ; WX 602 ; N uniFEF9 ; G 3253 +U 65274 ; WX 602 ; N uniFEFA ; G 3254 +U 65275 ; WX 602 ; N uniFEFB ; G 3255 +U 65276 ; WX 602 ; N uniFEFC ; G 3256 +U 65279 ; WX 602 ; N uniFEFF ; G 3257 +U 65529 ; WX 602 ; N uniFFF9 ; G 3258 +U 65530 ; WX 602 ; N uniFFFA ; G 3259 +U 65531 ; WX 602 ; N uniFFFB ; G 3260 +U 65532 ; WX 602 ; N uniFFFC ; G 3261 +U 65533 ; WX 602 ; N uniFFFD ; G 3262 +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..754dca7325de222c8dbdd1f98ae2c1401f882a42 GIT binary patch literal 253580 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

YQnce&OUhf~QVW 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

%F8AUQpvn(l~~zzOy>1@b4Y}v#!Cyo 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 literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ufm new file mode 100644 index 0000000..3ae612a --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-BoldOblique.ufm @@ -0,0 +1,2707 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans Mono +FontSubfamily Bold Oblique +UniqueID DejaVu Sans Mono Bold Oblique +FullName DejaVu Sans Mono Bold Oblique +Version Version 2.37 +PostScriptName DejaVuSansMono-BoldOblique +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +Weight Bold +ItalicAngle -11 +IsFixedPitch true +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -425 -394 808 1008 +StartCharMetrics 2711 +U 32 ; WX 602 ; N space ; G 3 +U 33 ; WX 602 ; N exclam ; G 4 +U 34 ; WX 602 ; N quotedbl ; G 5 +U 35 ; WX 602 ; N numbersign ; G 6 +U 36 ; WX 602 ; N dollar ; G 7 +U 37 ; WX 602 ; N percent ; G 8 +U 38 ; WX 602 ; N ampersand ; G 9 +U 39 ; WX 602 ; N quotesingle ; G 10 +U 40 ; WX 602 ; N parenleft ; G 11 +U 41 ; WX 602 ; N parenright ; G 12 +U 42 ; WX 602 ; N asterisk ; G 13 +U 43 ; WX 602 ; N plus ; G 14 +U 44 ; WX 602 ; N comma ; G 15 +U 45 ; WX 602 ; N hyphen ; G 16 +U 46 ; WX 602 ; N period ; G 17 +U 47 ; WX 602 ; N slash ; G 18 +U 48 ; WX 602 ; N zero ; G 19 +U 49 ; WX 602 ; N one ; G 20 +U 50 ; WX 602 ; N two ; G 21 +U 51 ; WX 602 ; N three ; G 22 +U 52 ; WX 602 ; N four ; G 23 +U 53 ; WX 602 ; N five ; G 24 +U 54 ; WX 602 ; N six ; G 25 +U 55 ; WX 602 ; N seven ; G 26 +U 56 ; WX 602 ; N eight ; G 27 +U 57 ; WX 602 ; N nine ; G 28 +U 58 ; WX 602 ; N colon ; G 29 +U 59 ; WX 602 ; N semicolon ; G 30 +U 60 ; WX 602 ; N less ; G 31 +U 61 ; WX 602 ; N equal ; G 32 +U 62 ; WX 602 ; N greater ; G 33 +U 63 ; WX 602 ; N question ; G 34 +U 64 ; WX 602 ; N at ; G 35 +U 65 ; WX 602 ; N A ; G 36 +U 66 ; WX 602 ; N B ; G 37 +U 67 ; WX 602 ; N C ; G 38 +U 68 ; WX 602 ; N D ; G 39 +U 69 ; WX 602 ; N E ; G 40 +U 70 ; WX 602 ; N F ; G 41 +U 71 ; WX 602 ; N G ; G 42 +U 72 ; WX 602 ; N H ; G 43 +U 73 ; WX 602 ; N I ; G 44 +U 74 ; WX 602 ; N J ; G 45 +U 75 ; WX 602 ; N K ; G 46 +U 76 ; WX 602 ; N L ; G 47 +U 77 ; WX 602 ; N M ; G 48 +U 78 ; WX 602 ; N N ; G 49 +U 79 ; WX 602 ; N O ; G 50 +U 80 ; WX 602 ; N P ; G 51 +U 81 ; WX 602 ; N Q ; G 52 +U 82 ; WX 602 ; N R ; G 53 +U 83 ; WX 602 ; N S ; G 54 +U 84 ; WX 602 ; N T ; G 55 +U 85 ; WX 602 ; N U ; G 56 +U 86 ; WX 602 ; N V ; G 57 +U 87 ; WX 602 ; N W ; G 58 +U 88 ; WX 602 ; N X ; G 59 +U 89 ; WX 602 ; N Y ; G 60 +U 90 ; WX 602 ; N Z ; G 61 +U 91 ; WX 602 ; N bracketleft ; G 62 +U 92 ; WX 602 ; N backslash ; G 63 +U 93 ; WX 602 ; N bracketright ; G 64 +U 94 ; WX 602 ; N asciicircum ; G 65 +U 95 ; WX 602 ; N underscore ; G 66 +U 96 ; WX 602 ; N grave ; G 67 +U 97 ; WX 602 ; N a ; G 68 +U 98 ; WX 602 ; N b ; G 69 +U 99 ; WX 602 ; N c ; G 70 +U 100 ; WX 602 ; N d ; G 71 +U 101 ; WX 602 ; N e ; G 72 +U 102 ; WX 602 ; N f ; G 73 +U 103 ; WX 602 ; N g ; G 74 +U 104 ; WX 602 ; N h ; G 75 +U 105 ; WX 602 ; N i ; G 76 +U 106 ; WX 602 ; N j ; G 77 +U 107 ; WX 602 ; N k ; G 78 +U 108 ; WX 602 ; N l ; G 79 +U 109 ; WX 602 ; N m ; G 80 +U 110 ; WX 602 ; N n ; G 81 +U 111 ; WX 602 ; N o ; G 82 +U 112 ; WX 602 ; N p ; G 83 +U 113 ; WX 602 ; N q ; G 84 +U 114 ; WX 602 ; N r ; G 85 +U 115 ; WX 602 ; N s ; G 86 +U 116 ; WX 602 ; N t ; G 87 +U 117 ; WX 602 ; N u ; G 88 +U 118 ; WX 602 ; N v ; G 89 +U 119 ; WX 602 ; N w ; G 90 +U 120 ; WX 602 ; N x ; G 91 +U 121 ; WX 602 ; N y ; G 92 +U 122 ; WX 602 ; N z ; G 93 +U 123 ; WX 602 ; N braceleft ; G 94 +U 124 ; WX 602 ; N bar ; G 95 +U 125 ; WX 602 ; N braceright ; G 96 +U 126 ; WX 602 ; N asciitilde ; G 97 +U 160 ; WX 602 ; N nbspace ; G 98 +U 161 ; WX 602 ; N exclamdown ; G 99 +U 162 ; WX 602 ; N cent ; G 100 +U 163 ; WX 602 ; N sterling ; G 101 +U 164 ; WX 602 ; N currency ; G 102 +U 165 ; WX 602 ; N yen ; G 103 +U 166 ; WX 602 ; N brokenbar ; G 104 +U 167 ; WX 602 ; N section ; G 105 +U 168 ; WX 602 ; N dieresis ; G 106 +U 169 ; WX 602 ; N copyright ; G 107 +U 170 ; WX 602 ; N ordfeminine ; G 108 +U 171 ; WX 602 ; N guillemotleft ; G 109 +U 172 ; WX 602 ; N logicalnot ; G 110 +U 173 ; WX 602 ; N sfthyphen ; G 111 +U 174 ; WX 602 ; N registered ; G 112 +U 175 ; WX 602 ; N macron ; G 113 +U 176 ; WX 602 ; N degree ; G 114 +U 177 ; WX 602 ; N plusminus ; G 115 +U 178 ; WX 602 ; N twosuperior ; G 116 +U 179 ; WX 602 ; N threesuperior ; G 117 +U 180 ; WX 602 ; N acute ; G 118 +U 181 ; WX 602 ; N mu ; G 119 +U 182 ; WX 602 ; N paragraph ; G 120 +U 183 ; WX 602 ; N periodcentered ; G 121 +U 184 ; WX 602 ; N cedilla ; G 122 +U 185 ; WX 602 ; N onesuperior ; G 123 +U 186 ; WX 602 ; N ordmasculine ; G 124 +U 187 ; WX 602 ; N guillemotright ; G 125 +U 188 ; WX 602 ; N onequarter ; G 126 +U 189 ; WX 602 ; N onehalf ; G 127 +U 190 ; WX 602 ; N threequarters ; G 128 +U 191 ; WX 602 ; N questiondown ; G 129 +U 192 ; WX 602 ; N Agrave ; G 130 +U 193 ; WX 602 ; N Aacute ; G 131 +U 194 ; WX 602 ; N Acircumflex ; G 132 +U 195 ; WX 602 ; N Atilde ; G 133 +U 196 ; WX 602 ; N Adieresis ; G 134 +U 197 ; WX 602 ; N Aring ; G 135 +U 198 ; WX 602 ; N AE ; G 136 +U 199 ; WX 602 ; N Ccedilla ; G 137 +U 200 ; WX 602 ; N Egrave ; G 138 +U 201 ; WX 602 ; N Eacute ; G 139 +U 202 ; WX 602 ; N Ecircumflex ; G 140 +U 203 ; WX 602 ; N Edieresis ; G 141 +U 204 ; WX 602 ; N Igrave ; G 142 +U 205 ; WX 602 ; N Iacute ; G 143 +U 206 ; WX 602 ; N Icircumflex ; G 144 +U 207 ; WX 602 ; N Idieresis ; G 145 +U 208 ; WX 602 ; N Eth ; G 146 +U 209 ; WX 602 ; N Ntilde ; G 147 +U 210 ; WX 602 ; N Ograve ; G 148 +U 211 ; WX 602 ; N Oacute ; G 149 +U 212 ; WX 602 ; N Ocircumflex ; G 150 +U 213 ; WX 602 ; N Otilde ; G 151 +U 214 ; WX 602 ; N Odieresis ; G 152 +U 215 ; WX 602 ; N multiply ; G 153 +U 216 ; WX 602 ; N Oslash ; G 154 +U 217 ; WX 602 ; N Ugrave ; G 155 +U 218 ; WX 602 ; N Uacute ; G 156 +U 219 ; WX 602 ; N Ucircumflex ; G 157 +U 220 ; WX 602 ; N Udieresis ; G 158 +U 221 ; WX 602 ; N Yacute ; G 159 +U 222 ; WX 602 ; N Thorn ; G 160 +U 223 ; WX 602 ; N germandbls ; G 161 +U 224 ; WX 602 ; N agrave ; G 162 +U 225 ; WX 602 ; N aacute ; G 163 +U 226 ; WX 602 ; N acircumflex ; G 164 +U 227 ; WX 602 ; N atilde ; G 165 +U 228 ; WX 602 ; N adieresis ; G 166 +U 229 ; WX 602 ; N aring ; G 167 +U 230 ; WX 602 ; N ae ; G 168 +U 231 ; WX 602 ; N ccedilla ; G 169 +U 232 ; WX 602 ; N egrave ; G 170 +U 233 ; WX 602 ; N eacute ; G 171 +U 234 ; WX 602 ; N ecircumflex ; G 172 +U 235 ; WX 602 ; N edieresis ; G 173 +U 236 ; WX 602 ; N igrave ; G 174 +U 237 ; WX 602 ; N iacute ; G 175 +U 238 ; WX 602 ; N icircumflex ; G 176 +U 239 ; WX 602 ; N idieresis ; G 177 +U 240 ; WX 602 ; N eth ; G 178 +U 241 ; WX 602 ; N ntilde ; G 179 +U 242 ; WX 602 ; N ograve ; G 180 +U 243 ; WX 602 ; N oacute ; G 181 +U 244 ; WX 602 ; N ocircumflex ; G 182 +U 245 ; WX 602 ; N otilde ; G 183 +U 246 ; WX 602 ; N odieresis ; G 184 +U 247 ; WX 602 ; N divide ; G 185 +U 248 ; WX 602 ; N oslash ; G 186 +U 249 ; WX 602 ; N ugrave ; G 187 +U 250 ; WX 602 ; N uacute ; G 188 +U 251 ; WX 602 ; N ucircumflex ; G 189 +U 252 ; WX 602 ; N udieresis ; G 190 +U 253 ; WX 602 ; N yacute ; G 191 +U 254 ; WX 602 ; N thorn ; G 192 +U 255 ; WX 602 ; N ydieresis ; G 193 +U 256 ; WX 602 ; N Amacron ; G 194 +U 257 ; WX 602 ; N amacron ; G 195 +U 258 ; WX 602 ; N Abreve ; G 196 +U 259 ; WX 602 ; N abreve ; G 197 +U 260 ; WX 602 ; N Aogonek ; G 198 +U 261 ; WX 602 ; N aogonek ; G 199 +U 262 ; WX 602 ; N Cacute ; G 200 +U 263 ; WX 602 ; N cacute ; G 201 +U 264 ; WX 602 ; N Ccircumflex ; G 202 +U 265 ; WX 602 ; N ccircumflex ; G 203 +U 266 ; WX 602 ; N Cdotaccent ; G 204 +U 267 ; WX 602 ; N cdotaccent ; G 205 +U 268 ; WX 602 ; N Ccaron ; G 206 +U 269 ; WX 602 ; N ccaron ; G 207 +U 270 ; WX 602 ; N Dcaron ; G 208 +U 271 ; WX 602 ; N dcaron ; G 209 +U 272 ; WX 602 ; N Dcroat ; G 210 +U 273 ; WX 602 ; N dmacron ; G 211 +U 274 ; WX 602 ; N Emacron ; G 212 +U 275 ; WX 602 ; N emacron ; G 213 +U 276 ; WX 602 ; N Ebreve ; G 214 +U 277 ; WX 602 ; N ebreve ; G 215 +U 278 ; WX 602 ; N Edotaccent ; G 216 +U 279 ; WX 602 ; N edotaccent ; G 217 +U 280 ; WX 602 ; N Eogonek ; G 218 +U 281 ; WX 602 ; N eogonek ; G 219 +U 282 ; WX 602 ; N Ecaron ; G 220 +U 283 ; WX 602 ; N ecaron ; G 221 +U 284 ; WX 602 ; N Gcircumflex ; G 222 +U 285 ; WX 602 ; N gcircumflex ; G 223 +U 286 ; WX 602 ; N Gbreve ; G 224 +U 287 ; WX 602 ; N gbreve ; G 225 +U 288 ; WX 602 ; N Gdotaccent ; G 226 +U 289 ; WX 602 ; N gdotaccent ; G 227 +U 290 ; WX 602 ; N Gcommaaccent ; G 228 +U 291 ; WX 602 ; N gcommaaccent ; G 229 +U 292 ; WX 602 ; N Hcircumflex ; G 230 +U 293 ; WX 602 ; N hcircumflex ; G 231 +U 294 ; WX 602 ; N Hbar ; G 232 +U 295 ; WX 602 ; N hbar ; G 233 +U 296 ; WX 602 ; N Itilde ; G 234 +U 297 ; WX 602 ; N itilde ; G 235 +U 298 ; WX 602 ; N Imacron ; G 236 +U 299 ; WX 602 ; N imacron ; G 237 +U 300 ; WX 602 ; N Ibreve ; G 238 +U 301 ; WX 602 ; N ibreve ; G 239 +U 302 ; WX 602 ; N Iogonek ; G 240 +U 303 ; WX 602 ; N iogonek ; G 241 +U 304 ; WX 602 ; N Idot ; G 242 +U 305 ; WX 602 ; N dotlessi ; G 243 +U 306 ; WX 602 ; N IJ ; G 244 +U 307 ; WX 602 ; N ij ; G 245 +U 308 ; WX 602 ; N Jcircumflex ; G 246 +U 309 ; WX 602 ; N jcircumflex ; G 247 +U 310 ; WX 602 ; N Kcommaaccent ; G 248 +U 311 ; WX 602 ; N kcommaaccent ; G 249 +U 312 ; WX 602 ; N kgreenlandic ; G 250 +U 313 ; WX 602 ; N Lacute ; G 251 +U 314 ; WX 602 ; N lacute ; G 252 +U 315 ; WX 602 ; N Lcommaaccent ; G 253 +U 316 ; WX 602 ; N lcommaaccent ; G 254 +U 317 ; WX 602 ; N Lcaron ; G 255 +U 318 ; WX 602 ; N lcaron ; G 256 +U 319 ; WX 602 ; N Ldot ; G 257 +U 320 ; WX 602 ; N ldot ; G 258 +U 321 ; WX 602 ; N Lslash ; G 259 +U 322 ; WX 602 ; N lslash ; G 260 +U 323 ; WX 602 ; N Nacute ; G 261 +U 324 ; WX 602 ; N nacute ; G 262 +U 325 ; WX 602 ; N Ncommaaccent ; G 263 +U 326 ; WX 602 ; N ncommaaccent ; G 264 +U 327 ; WX 602 ; N Ncaron ; G 265 +U 328 ; WX 602 ; N ncaron ; G 266 +U 329 ; WX 602 ; N napostrophe ; G 267 +U 330 ; WX 602 ; N Eng ; G 268 +U 331 ; WX 602 ; N eng ; G 269 +U 332 ; WX 602 ; N Omacron ; G 270 +U 333 ; WX 602 ; N omacron ; G 271 +U 334 ; WX 602 ; N Obreve ; G 272 +U 335 ; WX 602 ; N obreve ; G 273 +U 336 ; WX 602 ; N Ohungarumlaut ; G 274 +U 337 ; WX 602 ; N ohungarumlaut ; G 275 +U 338 ; WX 602 ; N OE ; G 276 +U 339 ; WX 602 ; N oe ; G 277 +U 340 ; WX 602 ; N Racute ; G 278 +U 341 ; WX 602 ; N racute ; G 279 +U 342 ; WX 602 ; N Rcommaaccent ; G 280 +U 343 ; WX 602 ; N rcommaaccent ; G 281 +U 344 ; WX 602 ; N Rcaron ; G 282 +U 345 ; WX 602 ; N rcaron ; G 283 +U 346 ; WX 602 ; N Sacute ; G 284 +U 347 ; WX 602 ; N sacute ; G 285 +U 348 ; WX 602 ; N Scircumflex ; G 286 +U 349 ; WX 602 ; N scircumflex ; G 287 +U 350 ; WX 602 ; N Scedilla ; G 288 +U 351 ; WX 602 ; N scedilla ; G 289 +U 352 ; WX 602 ; N Scaron ; G 290 +U 353 ; WX 602 ; N scaron ; G 291 +U 354 ; WX 602 ; N Tcommaaccent ; G 292 +U 355 ; WX 602 ; N tcommaaccent ; G 293 +U 356 ; WX 602 ; N Tcaron ; G 294 +U 357 ; WX 602 ; N tcaron ; G 295 +U 358 ; WX 602 ; N Tbar ; G 296 +U 359 ; WX 602 ; N tbar ; G 297 +U 360 ; WX 602 ; N Utilde ; G 298 +U 361 ; WX 602 ; N utilde ; G 299 +U 362 ; WX 602 ; N Umacron ; G 300 +U 363 ; WX 602 ; N umacron ; G 301 +U 364 ; WX 602 ; N Ubreve ; G 302 +U 365 ; WX 602 ; N ubreve ; G 303 +U 366 ; WX 602 ; N Uring ; G 304 +U 367 ; WX 602 ; N uring ; G 305 +U 368 ; WX 602 ; N Uhungarumlaut ; G 306 +U 369 ; WX 602 ; N uhungarumlaut ; G 307 +U 370 ; WX 602 ; N Uogonek ; G 308 +U 371 ; WX 602 ; N uogonek ; G 309 +U 372 ; WX 602 ; N Wcircumflex ; G 310 +U 373 ; WX 602 ; N wcircumflex ; G 311 +U 374 ; WX 602 ; N Ycircumflex ; G 312 +U 375 ; WX 602 ; N ycircumflex ; G 313 +U 376 ; WX 602 ; N Ydieresis ; G 314 +U 377 ; WX 602 ; N Zacute ; G 315 +U 378 ; WX 602 ; N zacute ; G 316 +U 379 ; WX 602 ; N Zdotaccent ; G 317 +U 380 ; WX 602 ; N zdotaccent ; G 318 +U 381 ; WX 602 ; N Zcaron ; G 319 +U 382 ; WX 602 ; N zcaron ; G 320 +U 383 ; WX 602 ; N longs ; G 321 +U 384 ; WX 602 ; N uni0180 ; G 322 +U 385 ; WX 602 ; N uni0181 ; G 323 +U 386 ; WX 602 ; N uni0182 ; G 324 +U 387 ; WX 602 ; N uni0183 ; G 325 +U 388 ; WX 602 ; N uni0184 ; G 326 +U 389 ; WX 602 ; N uni0185 ; G 327 +U 390 ; WX 602 ; N uni0186 ; G 328 +U 391 ; WX 602 ; N uni0187 ; G 329 +U 392 ; WX 602 ; N uni0188 ; G 330 +U 393 ; WX 602 ; N uni0189 ; G 331 +U 394 ; WX 602 ; N uni018A ; G 332 +U 395 ; WX 602 ; N uni018B ; G 333 +U 396 ; WX 602 ; N uni018C ; G 334 +U 397 ; WX 602 ; N uni018D ; G 335 +U 398 ; WX 602 ; N uni018E ; G 336 +U 399 ; WX 602 ; N uni018F ; G 337 +U 400 ; WX 602 ; N uni0190 ; G 338 +U 401 ; WX 602 ; N uni0191 ; G 339 +U 402 ; WX 602 ; N florin ; G 340 +U 403 ; WX 602 ; N uni0193 ; G 341 +U 404 ; WX 602 ; N uni0194 ; G 342 +U 405 ; WX 602 ; N uni0195 ; G 343 +U 406 ; WX 602 ; N uni0196 ; G 344 +U 407 ; WX 602 ; N uni0197 ; G 345 +U 408 ; WX 602 ; N uni0198 ; G 346 +U 409 ; WX 602 ; N uni0199 ; G 347 +U 410 ; WX 602 ; N uni019A ; G 348 +U 411 ; WX 602 ; N uni019B ; G 349 +U 412 ; WX 602 ; N uni019C ; G 350 +U 413 ; WX 602 ; N uni019D ; G 351 +U 414 ; WX 602 ; N uni019E ; G 352 +U 415 ; WX 602 ; N uni019F ; G 353 +U 416 ; WX 602 ; N Ohorn ; G 354 +U 417 ; WX 602 ; N ohorn ; G 355 +U 418 ; WX 602 ; N uni01A2 ; G 356 +U 419 ; WX 602 ; N uni01A3 ; G 357 +U 420 ; WX 602 ; N uni01A4 ; G 358 +U 421 ; WX 602 ; N uni01A5 ; G 359 +U 422 ; WX 602 ; N uni01A6 ; G 360 +U 423 ; WX 602 ; N uni01A7 ; G 361 +U 424 ; WX 602 ; N uni01A8 ; G 362 +U 425 ; WX 602 ; N uni01A9 ; G 363 +U 426 ; WX 602 ; N uni01AA ; G 364 +U 427 ; WX 602 ; N uni01AB ; G 365 +U 428 ; WX 602 ; N uni01AC ; G 366 +U 429 ; WX 602 ; N uni01AD ; G 367 +U 430 ; WX 602 ; N uni01AE ; G 368 +U 431 ; WX 602 ; N Uhorn ; G 369 +U 432 ; WX 602 ; N uhorn ; G 370 +U 433 ; WX 602 ; N uni01B1 ; G 371 +U 434 ; WX 602 ; N uni01B2 ; G 372 +U 435 ; WX 602 ; N uni01B3 ; G 373 +U 436 ; WX 602 ; N uni01B4 ; G 374 +U 437 ; WX 602 ; N uni01B5 ; G 375 +U 438 ; WX 602 ; N uni01B6 ; G 376 +U 439 ; WX 602 ; N uni01B7 ; G 377 +U 440 ; WX 602 ; N uni01B8 ; G 378 +U 441 ; WX 602 ; N uni01B9 ; G 379 +U 442 ; WX 602 ; N uni01BA ; G 380 +U 443 ; WX 602 ; N uni01BB ; G 381 +U 444 ; WX 602 ; N uni01BC ; G 382 +U 445 ; WX 602 ; N uni01BD ; G 383 +U 446 ; WX 602 ; N uni01BE ; G 384 +U 447 ; WX 602 ; N uni01BF ; G 385 +U 448 ; WX 602 ; N uni01C0 ; G 386 +U 449 ; WX 602 ; N uni01C1 ; G 387 +U 450 ; WX 602 ; N uni01C2 ; G 388 +U 451 ; WX 602 ; N uni01C3 ; G 389 +U 461 ; WX 602 ; N uni01CD ; G 390 +U 462 ; WX 602 ; N uni01CE ; G 391 +U 463 ; WX 602 ; N uni01CF ; G 392 +U 464 ; WX 602 ; N uni01D0 ; G 393 +U 465 ; WX 602 ; N uni01D1 ; G 394 +U 466 ; WX 602 ; N uni01D2 ; G 395 +U 467 ; WX 602 ; N uni01D3 ; G 396 +U 468 ; WX 602 ; N uni01D4 ; G 397 +U 469 ; WX 602 ; N uni01D5 ; G 398 +U 470 ; WX 602 ; N uni01D6 ; G 399 +U 471 ; WX 602 ; N uni01D7 ; G 400 +U 472 ; WX 602 ; N uni01D8 ; G 401 +U 473 ; WX 602 ; N uni01D9 ; G 402 +U 474 ; WX 602 ; N uni01DA ; G 403 +U 475 ; WX 602 ; N uni01DB ; G 404 +U 476 ; WX 602 ; N uni01DC ; G 405 +U 477 ; WX 602 ; N uni01DD ; G 406 +U 478 ; WX 602 ; N uni01DE ; G 407 +U 479 ; WX 602 ; N uni01DF ; G 408 +U 480 ; WX 602 ; N uni01E0 ; G 409 +U 481 ; WX 602 ; N uni01E1 ; G 410 +U 482 ; WX 602 ; N uni01E2 ; G 411 +U 483 ; WX 602 ; N uni01E3 ; G 412 +U 486 ; WX 602 ; N Gcaron ; G 413 +U 487 ; WX 602 ; N gcaron ; G 414 +U 488 ; WX 602 ; N uni01E8 ; G 415 +U 489 ; WX 602 ; N uni01E9 ; G 416 +U 490 ; WX 602 ; N uni01EA ; G 417 +U 491 ; WX 602 ; N uni01EB ; G 418 +U 492 ; WX 602 ; N uni01EC ; G 419 +U 493 ; WX 602 ; N uni01ED ; G 420 +U 494 ; WX 602 ; N uni01EE ; G 421 +U 495 ; WX 602 ; N uni01EF ; G 422 +U 500 ; WX 602 ; N uni01F4 ; G 423 +U 501 ; WX 602 ; N uni01F5 ; G 424 +U 502 ; WX 602 ; N uni01F6 ; G 425 +U 504 ; WX 602 ; N uni01F8 ; G 426 +U 505 ; WX 602 ; N uni01F9 ; G 427 +U 508 ; WX 602 ; N AEacute ; G 428 +U 509 ; WX 602 ; N aeacute ; G 429 +U 510 ; WX 602 ; N Oslashacute ; G 430 +U 511 ; WX 602 ; N oslashacute ; G 431 +U 512 ; WX 602 ; N uni0200 ; G 432 +U 513 ; WX 602 ; N uni0201 ; G 433 +U 514 ; WX 602 ; N uni0202 ; G 434 +U 515 ; WX 602 ; N uni0203 ; G 435 +U 516 ; WX 602 ; N uni0204 ; G 436 +U 517 ; WX 602 ; N uni0205 ; G 437 +U 518 ; WX 602 ; N uni0206 ; G 438 +U 519 ; WX 602 ; N uni0207 ; G 439 +U 520 ; WX 602 ; N uni0208 ; G 440 +U 521 ; WX 602 ; N uni0209 ; G 441 +U 522 ; WX 602 ; N uni020A ; G 442 +U 523 ; WX 602 ; N uni020B ; G 443 +U 524 ; WX 602 ; N uni020C ; G 444 +U 525 ; WX 602 ; N uni020D ; G 445 +U 526 ; WX 602 ; N uni020E ; G 446 +U 527 ; WX 602 ; N uni020F ; G 447 +U 528 ; WX 602 ; N uni0210 ; G 448 +U 529 ; WX 602 ; N uni0211 ; G 449 +U 530 ; WX 602 ; N uni0212 ; G 450 +U 531 ; WX 602 ; N uni0213 ; G 451 +U 532 ; WX 602 ; N uni0214 ; G 452 +U 533 ; WX 602 ; N uni0215 ; G 453 +U 534 ; WX 602 ; N uni0216 ; G 454 +U 535 ; WX 602 ; N uni0217 ; G 455 +U 536 ; WX 602 ; N Scommaaccent ; G 456 +U 537 ; WX 602 ; N scommaaccent ; G 457 +U 538 ; WX 602 ; N uni021A ; G 458 +U 539 ; WX 602 ; N uni021B ; G 459 +U 540 ; WX 602 ; N uni021C ; G 460 +U 541 ; WX 602 ; N uni021D ; G 461 +U 542 ; WX 602 ; N uni021E ; G 462 +U 543 ; WX 602 ; N uni021F ; G 463 +U 545 ; WX 602 ; N uni0221 ; G 464 +U 548 ; WX 602 ; N uni0224 ; G 465 +U 549 ; WX 602 ; N uni0225 ; G 466 +U 550 ; WX 602 ; N uni0226 ; G 467 +U 551 ; WX 602 ; N uni0227 ; G 468 +U 552 ; WX 602 ; N uni0228 ; G 469 +U 553 ; WX 602 ; N uni0229 ; G 470 +U 554 ; WX 602 ; N uni022A ; G 471 +U 555 ; WX 602 ; N uni022B ; G 472 +U 556 ; WX 602 ; N uni022C ; G 473 +U 557 ; WX 602 ; N uni022D ; G 474 +U 558 ; WX 602 ; N uni022E ; G 475 +U 559 ; WX 602 ; N uni022F ; G 476 +U 560 ; WX 602 ; N uni0230 ; G 477 +U 561 ; WX 602 ; N uni0231 ; G 478 +U 562 ; WX 602 ; N uni0232 ; G 479 +U 563 ; WX 602 ; N uni0233 ; G 480 +U 564 ; WX 602 ; N uni0234 ; G 481 +U 565 ; WX 602 ; N uni0235 ; G 482 +U 566 ; WX 602 ; N uni0236 ; G 483 +U 567 ; WX 602 ; N dotlessj ; G 484 +U 568 ; WX 602 ; N uni0238 ; G 485 +U 569 ; WX 602 ; N uni0239 ; G 486 +U 570 ; WX 602 ; N uni023A ; G 487 +U 571 ; WX 602 ; N uni023B ; G 488 +U 572 ; WX 602 ; N uni023C ; G 489 +U 573 ; WX 602 ; N uni023D ; G 490 +U 574 ; WX 602 ; N uni023E ; G 491 +U 575 ; WX 602 ; N uni023F ; G 492 +U 576 ; WX 602 ; N uni0240 ; G 493 +U 577 ; WX 602 ; N uni0241 ; G 494 +U 579 ; WX 602 ; N uni0243 ; G 495 +U 580 ; WX 602 ; N uni0244 ; G 496 +U 581 ; WX 602 ; N uni0245 ; G 497 +U 588 ; WX 602 ; N uni024C ; G 498 +U 589 ; WX 602 ; N uni024D ; G 499 +U 592 ; WX 602 ; N uni0250 ; G 500 +U 593 ; WX 602 ; N uni0251 ; G 501 +U 594 ; WX 602 ; N uni0252 ; G 502 +U 595 ; WX 602 ; N uni0253 ; G 503 +U 596 ; WX 602 ; N uni0254 ; G 504 +U 597 ; WX 602 ; N uni0255 ; G 505 +U 598 ; WX 602 ; N uni0256 ; G 506 +U 599 ; WX 602 ; N uni0257 ; G 507 +U 600 ; WX 602 ; N uni0258 ; G 508 +U 601 ; WX 602 ; N uni0259 ; G 509 +U 602 ; WX 602 ; N uni025A ; G 510 +U 603 ; WX 602 ; N uni025B ; G 511 +U 604 ; WX 602 ; N uni025C ; G 512 +U 605 ; WX 602 ; N uni025D ; G 513 +U 606 ; WX 602 ; N uni025E ; G 514 +U 607 ; WX 602 ; N uni025F ; G 515 +U 608 ; WX 602 ; N uni0260 ; G 516 +U 609 ; WX 602 ; N uni0261 ; G 517 +U 610 ; WX 602 ; N uni0262 ; G 518 +U 611 ; WX 602 ; N uni0263 ; G 519 +U 612 ; WX 602 ; N uni0264 ; G 520 +U 613 ; WX 602 ; N uni0265 ; G 521 +U 614 ; WX 602 ; N uni0266 ; G 522 +U 615 ; WX 602 ; N uni0267 ; G 523 +U 616 ; WX 602 ; N uni0268 ; G 524 +U 617 ; WX 602 ; N uni0269 ; G 525 +U 618 ; WX 602 ; N uni026A ; G 526 +U 619 ; WX 602 ; N uni026B ; G 527 +U 620 ; WX 602 ; N uni026C ; G 528 +U 621 ; WX 602 ; N uni026D ; G 529 +U 622 ; WX 602 ; N uni026E ; G 530 +U 623 ; WX 602 ; N uni026F ; G 531 +U 624 ; WX 602 ; N uni0270 ; G 532 +U 625 ; WX 602 ; N uni0271 ; G 533 +U 626 ; WX 602 ; N uni0272 ; G 534 +U 627 ; WX 602 ; N uni0273 ; G 535 +U 628 ; WX 602 ; N uni0274 ; G 536 +U 629 ; WX 602 ; N uni0275 ; G 537 +U 630 ; WX 602 ; N uni0276 ; G 538 +U 631 ; WX 602 ; N uni0277 ; G 539 +U 632 ; WX 602 ; N uni0278 ; G 540 +U 633 ; WX 602 ; N uni0279 ; G 541 +U 634 ; WX 602 ; N uni027A ; G 542 +U 635 ; WX 602 ; N uni027B ; G 543 +U 636 ; WX 602 ; N uni027C ; G 544 +U 637 ; WX 602 ; N uni027D ; G 545 +U 638 ; WX 602 ; N uni027E ; G 546 +U 639 ; WX 602 ; N uni027F ; G 547 +U 640 ; WX 602 ; N uni0280 ; G 548 +U 641 ; WX 602 ; N uni0281 ; G 549 +U 642 ; WX 602 ; N uni0282 ; G 550 +U 643 ; WX 602 ; N uni0283 ; G 551 +U 644 ; WX 602 ; N uni0284 ; G 552 +U 645 ; WX 602 ; N uni0285 ; G 553 +U 646 ; WX 602 ; N uni0286 ; G 554 +U 647 ; WX 602 ; N uni0287 ; G 555 +U 648 ; WX 602 ; N uni0288 ; G 556 +U 649 ; WX 602 ; N uni0289 ; G 557 +U 650 ; WX 602 ; N uni028A ; G 558 +U 651 ; WX 602 ; N uni028B ; G 559 +U 652 ; WX 602 ; N uni028C ; G 560 +U 653 ; WX 602 ; N uni028D ; G 561 +U 654 ; WX 602 ; N uni028E ; G 562 +U 655 ; WX 602 ; N uni028F ; G 563 +U 656 ; WX 602 ; N uni0290 ; G 564 +U 657 ; WX 602 ; N uni0291 ; G 565 +U 658 ; WX 602 ; N uni0292 ; G 566 +U 659 ; WX 602 ; N uni0293 ; G 567 +U 660 ; WX 602 ; N uni0294 ; G 568 +U 661 ; WX 602 ; N uni0295 ; G 569 +U 662 ; WX 602 ; N uni0296 ; G 570 +U 663 ; WX 602 ; N uni0297 ; G 571 +U 664 ; WX 602 ; N uni0298 ; G 572 +U 665 ; WX 602 ; N uni0299 ; G 573 +U 666 ; WX 602 ; N uni029A ; G 574 +U 667 ; WX 602 ; N uni029B ; G 575 +U 668 ; WX 602 ; N uni029C ; G 576 +U 669 ; WX 602 ; N uni029D ; G 577 +U 670 ; WX 602 ; N uni029E ; G 578 +U 671 ; WX 602 ; N uni029F ; G 579 +U 672 ; WX 602 ; N uni02A0 ; G 580 +U 673 ; WX 602 ; N uni02A1 ; G 581 +U 674 ; WX 602 ; N uni02A2 ; G 582 +U 675 ; WX 602 ; N uni02A3 ; G 583 +U 676 ; WX 602 ; N uni02A4 ; G 584 +U 677 ; WX 602 ; N uni02A5 ; G 585 +U 678 ; WX 602 ; N uni02A6 ; G 586 +U 679 ; WX 602 ; N uni02A7 ; G 587 +U 680 ; WX 602 ; N uni02A8 ; G 588 +U 681 ; WX 602 ; N uni02A9 ; G 589 +U 682 ; WX 602 ; N uni02AA ; G 590 +U 683 ; WX 602 ; N uni02AB ; G 591 +U 684 ; WX 602 ; N uni02AC ; G 592 +U 685 ; WX 602 ; N uni02AD ; G 593 +U 686 ; WX 602 ; N uni02AE ; G 594 +U 687 ; WX 602 ; N uni02AF ; G 595 +U 688 ; WX 602 ; N uni02B0 ; G 596 +U 689 ; WX 602 ; N uni02B1 ; G 597 +U 690 ; WX 602 ; N uni02B2 ; G 598 +U 691 ; WX 602 ; N uni02B3 ; G 599 +U 692 ; WX 602 ; N uni02B4 ; G 600 +U 693 ; WX 602 ; N uni02B5 ; G 601 +U 694 ; WX 602 ; N uni02B6 ; G 602 +U 695 ; WX 602 ; N uni02B7 ; G 603 +U 696 ; WX 602 ; N uni02B8 ; G 604 +U 697 ; WX 602 ; N uni02B9 ; G 605 +U 699 ; WX 602 ; N uni02BB ; G 606 +U 700 ; WX 602 ; N uni02BC ; G 607 +U 701 ; WX 602 ; N uni02BD ; G 608 +U 702 ; WX 602 ; N uni02BE ; G 609 +U 703 ; WX 602 ; N uni02BF ; G 610 +U 704 ; WX 602 ; N uni02C0 ; G 611 +U 705 ; WX 602 ; N uni02C1 ; G 612 +U 710 ; WX 602 ; N circumflex ; G 613 +U 711 ; WX 602 ; N caron ; G 614 +U 712 ; WX 602 ; N uni02C8 ; G 615 +U 713 ; WX 602 ; N uni02C9 ; G 616 +U 716 ; WX 602 ; N uni02CC ; G 617 +U 717 ; WX 602 ; N uni02CD ; G 618 +U 718 ; WX 602 ; N uni02CE ; G 619 +U 719 ; WX 602 ; N uni02CF ; G 620 +U 720 ; WX 602 ; N uni02D0 ; G 621 +U 721 ; WX 602 ; N uni02D1 ; G 622 +U 722 ; WX 602 ; N uni02D2 ; G 623 +U 723 ; WX 602 ; N uni02D3 ; G 624 +U 726 ; WX 602 ; N uni02D6 ; G 625 +U 727 ; WX 602 ; N uni02D7 ; G 626 +U 728 ; WX 602 ; N breve ; G 627 +U 729 ; WX 602 ; N dotaccent ; G 628 +U 730 ; WX 602 ; N ring ; G 629 +U 731 ; WX 602 ; N ogonek ; G 630 +U 732 ; WX 602 ; N tilde ; G 631 +U 733 ; WX 602 ; N hungarumlaut ; G 632 +U 734 ; WX 602 ; N uni02DE ; G 633 +U 736 ; WX 602 ; N uni02E0 ; G 634 +U 737 ; WX 602 ; N uni02E1 ; G 635 +U 738 ; WX 602 ; N uni02E2 ; G 636 +U 739 ; WX 602 ; N uni02E3 ; G 637 +U 740 ; WX 602 ; N uni02E4 ; G 638 +U 741 ; WX 602 ; N uni02E5 ; G 639 +U 742 ; WX 602 ; N uni02E6 ; G 640 +U 743 ; WX 602 ; N uni02E7 ; G 641 +U 744 ; WX 602 ; N uni02E8 ; G 642 +U 745 ; WX 602 ; N uni02E9 ; G 643 +U 750 ; WX 602 ; N uni02EE ; G 644 +U 755 ; WX 602 ; N uni02F3 ; G 645 +U 768 ; WX 602 ; N gravecomb ; G 646 +U 769 ; WX 602 ; N acutecomb ; G 647 +U 770 ; WX 602 ; N uni0302 ; G 648 +U 771 ; WX 602 ; N tildecomb ; G 649 +U 772 ; WX 602 ; N uni0304 ; G 650 +U 773 ; WX 602 ; N uni0305 ; G 651 +U 774 ; WX 602 ; N uni0306 ; G 652 +U 775 ; WX 602 ; N uni0307 ; G 653 +U 776 ; WX 602 ; N uni0308 ; G 654 +U 777 ; WX 602 ; N hookabovecomb ; G 655 +U 778 ; WX 602 ; N uni030A ; G 656 +U 779 ; WX 602 ; N uni030B ; G 657 +U 780 ; WX 602 ; N uni030C ; G 658 +U 781 ; WX 602 ; N uni030D ; G 659 +U 782 ; WX 602 ; N uni030E ; G 660 +U 783 ; WX 602 ; N uni030F ; G 661 +U 784 ; WX 602 ; N uni0310 ; G 662 +U 785 ; WX 602 ; N uni0311 ; G 663 +U 786 ; WX 602 ; N uni0312 ; G 664 +U 787 ; WX 602 ; N uni0313 ; G 665 +U 788 ; WX 602 ; N uni0314 ; G 666 +U 789 ; WX 602 ; N uni0315 ; G 667 +U 790 ; WX 602 ; N uni0316 ; G 668 +U 791 ; WX 602 ; N uni0317 ; G 669 +U 792 ; WX 602 ; N uni0318 ; G 670 +U 793 ; WX 602 ; N uni0319 ; G 671 +U 794 ; WX 602 ; N uni031A ; G 672 +U 795 ; WX 602 ; N uni031B ; G 673 +U 796 ; WX 602 ; N uni031C ; G 674 +U 797 ; WX 602 ; N uni031D ; G 675 +U 798 ; WX 602 ; N uni031E ; G 676 +U 799 ; WX 602 ; N uni031F ; G 677 +U 800 ; WX 602 ; N uni0320 ; G 678 +U 801 ; WX 602 ; N uni0321 ; G 679 +U 802 ; WX 602 ; N uni0322 ; G 680 +U 803 ; WX 602 ; N dotbelowcomb ; G 681 +U 804 ; WX 602 ; N uni0324 ; G 682 +U 805 ; WX 602 ; N uni0325 ; G 683 +U 806 ; WX 602 ; N uni0326 ; G 684 +U 807 ; WX 602 ; N uni0327 ; G 685 +U 808 ; WX 602 ; N uni0328 ; G 686 +U 809 ; WX 602 ; N uni0329 ; G 687 +U 810 ; WX 602 ; N uni032A ; G 688 +U 811 ; WX 602 ; N uni032B ; G 689 +U 812 ; WX 602 ; N uni032C ; G 690 +U 813 ; WX 602 ; N uni032D ; G 691 +U 814 ; WX 602 ; N uni032E ; G 692 +U 815 ; WX 602 ; N uni032F ; G 693 +U 816 ; WX 602 ; N uni0330 ; G 694 +U 817 ; WX 602 ; N uni0331 ; G 695 +U 818 ; WX 602 ; N uni0332 ; G 696 +U 819 ; WX 602 ; N uni0333 ; G 697 +U 820 ; WX 602 ; N uni0334 ; G 698 +U 821 ; WX 602 ; N uni0335 ; G 699 +U 822 ; WX 602 ; N uni0336 ; G 700 +U 823 ; WX 602 ; N uni0337 ; G 701 +U 824 ; WX 602 ; N uni0338 ; G 702 +U 825 ; WX 602 ; N uni0339 ; G 703 +U 826 ; WX 602 ; N uni033A ; G 704 +U 827 ; WX 602 ; N uni033B ; G 705 +U 828 ; WX 602 ; N uni033C ; G 706 +U 829 ; WX 602 ; N uni033D ; G 707 +U 830 ; WX 602 ; N uni033E ; G 708 +U 831 ; WX 602 ; N uni033F ; G 709 +U 835 ; WX 602 ; N uni0343 ; G 710 +U 856 ; WX 602 ; N uni0358 ; G 711 +U 865 ; WX 602 ; N uni0361 ; G 712 +U 884 ; WX 602 ; N uni0374 ; G 713 +U 885 ; WX 602 ; N uni0375 ; G 714 +U 886 ; WX 602 ; N uni0376 ; G 715 +U 887 ; WX 602 ; N uni0377 ; G 716 +U 890 ; WX 602 ; N uni037A ; G 717 +U 891 ; WX 602 ; N uni037B ; G 718 +U 892 ; WX 602 ; N uni037C ; G 719 +U 893 ; WX 602 ; N uni037D ; G 720 +U 894 ; WX 602 ; N uni037E ; G 721 +U 895 ; WX 602 ; N uni037F ; G 722 +U 900 ; WX 602 ; N tonos ; G 723 +U 901 ; WX 602 ; N dieresistonos ; G 724 +U 902 ; WX 602 ; N Alphatonos ; G 725 +U 903 ; WX 602 ; N anoteleia ; G 726 +U 904 ; WX 602 ; N Epsilontonos ; G 727 +U 905 ; WX 602 ; N Etatonos ; G 728 +U 906 ; WX 602 ; N Iotatonos ; G 729 +U 908 ; WX 602 ; N Omicrontonos ; G 730 +U 910 ; WX 602 ; N Upsilontonos ; G 731 +U 911 ; WX 602 ; N Omegatonos ; G 732 +U 912 ; WX 602 ; N iotadieresistonos ; G 733 +U 913 ; WX 602 ; N Alpha ; G 734 +U 914 ; WX 602 ; N Beta ; G 735 +U 915 ; WX 602 ; N Gamma ; G 736 +U 916 ; WX 602 ; N uni0394 ; G 737 +U 917 ; WX 602 ; N Epsilon ; G 738 +U 918 ; WX 602 ; N Zeta ; G 739 +U 919 ; WX 602 ; N Eta ; G 740 +U 920 ; WX 602 ; N Theta ; G 741 +U 921 ; WX 602 ; N Iota ; G 742 +U 922 ; WX 602 ; N Kappa ; G 743 +U 923 ; WX 602 ; N Lambda ; G 744 +U 924 ; WX 602 ; N Mu ; G 745 +U 925 ; WX 602 ; N Nu ; G 746 +U 926 ; WX 602 ; N Xi ; G 747 +U 927 ; WX 602 ; N Omicron ; G 748 +U 928 ; WX 602 ; N Pi ; G 749 +U 929 ; WX 602 ; N Rho ; G 750 +U 931 ; WX 602 ; N Sigma ; G 751 +U 932 ; WX 602 ; N Tau ; G 752 +U 933 ; WX 602 ; N Upsilon ; G 753 +U 934 ; WX 602 ; N Phi ; G 754 +U 935 ; WX 602 ; N Chi ; G 755 +U 936 ; WX 602 ; N Psi ; G 756 +U 937 ; WX 602 ; N Omega ; G 757 +U 938 ; WX 602 ; N Iotadieresis ; G 758 +U 939 ; WX 602 ; N Upsilondieresis ; G 759 +U 940 ; WX 602 ; N alphatonos ; G 760 +U 941 ; WX 602 ; N epsilontonos ; G 761 +U 942 ; WX 602 ; N etatonos ; G 762 +U 943 ; WX 602 ; N iotatonos ; G 763 +U 944 ; WX 602 ; N upsilondieresistonos ; G 764 +U 945 ; WX 602 ; N alpha ; G 765 +U 946 ; WX 602 ; N beta ; G 766 +U 947 ; WX 602 ; N gamma ; G 767 +U 948 ; WX 602 ; N delta ; G 768 +U 949 ; WX 602 ; N epsilon ; G 769 +U 950 ; WX 602 ; N zeta ; G 770 +U 951 ; WX 602 ; N eta ; G 771 +U 952 ; WX 602 ; N theta ; G 772 +U 953 ; WX 602 ; N iota ; G 773 +U 954 ; WX 602 ; N kappa ; G 774 +U 955 ; WX 602 ; N lambda ; G 775 +U 956 ; WX 602 ; N uni03BC ; G 776 +U 957 ; WX 602 ; N nu ; G 777 +U 958 ; WX 602 ; N xi ; G 778 +U 959 ; WX 602 ; N omicron ; G 779 +U 960 ; WX 602 ; N pi ; G 780 +U 961 ; WX 602 ; N rho ; G 781 +U 962 ; WX 602 ; N sigma1 ; G 782 +U 963 ; WX 602 ; N sigma ; G 783 +U 964 ; WX 602 ; N tau ; G 784 +U 965 ; WX 602 ; N upsilon ; G 785 +U 966 ; WX 602 ; N phi ; G 786 +U 967 ; WX 602 ; N chi ; G 787 +U 968 ; WX 602 ; N psi ; G 788 +U 969 ; WX 602 ; N omega ; G 789 +U 970 ; WX 602 ; N iotadieresis ; G 790 +U 971 ; WX 602 ; N upsilondieresis ; G 791 +U 972 ; WX 602 ; N omicrontonos ; G 792 +U 973 ; WX 602 ; N upsilontonos ; G 793 +U 974 ; WX 602 ; N omegatonos ; G 794 +U 976 ; WX 602 ; N uni03D0 ; G 795 +U 977 ; WX 602 ; N theta1 ; G 796 +U 978 ; WX 602 ; N Upsilon1 ; G 797 +U 979 ; WX 602 ; N uni03D3 ; G 798 +U 980 ; WX 602 ; N uni03D4 ; G 799 +U 981 ; WX 602 ; N phi1 ; G 800 +U 982 ; WX 602 ; N omega1 ; G 801 +U 983 ; WX 602 ; N uni03D7 ; G 802 +U 984 ; WX 602 ; N uni03D8 ; G 803 +U 985 ; WX 602 ; N uni03D9 ; G 804 +U 986 ; WX 602 ; N uni03DA ; G 805 +U 987 ; WX 602 ; N uni03DB ; G 806 +U 988 ; WX 602 ; N uni03DC ; G 807 +U 989 ; WX 602 ; N uni03DD ; G 808 +U 990 ; WX 602 ; N uni03DE ; G 809 +U 991 ; WX 602 ; N uni03DF ; G 810 +U 992 ; WX 602 ; N uni03E0 ; G 811 +U 993 ; WX 602 ; N uni03E1 ; G 812 +U 1008 ; WX 602 ; N uni03F0 ; G 813 +U 1009 ; WX 602 ; N uni03F1 ; G 814 +U 1010 ; WX 602 ; N uni03F2 ; G 815 +U 1011 ; WX 602 ; N uni03F3 ; G 816 +U 1012 ; WX 602 ; N uni03F4 ; G 817 +U 1013 ; WX 602 ; N uni03F5 ; G 818 +U 1014 ; WX 602 ; N uni03F6 ; G 819 +U 1015 ; WX 602 ; N uni03F7 ; G 820 +U 1016 ; WX 602 ; N uni03F8 ; G 821 +U 1017 ; WX 602 ; N uni03F9 ; G 822 +U 1018 ; WX 602 ; N uni03FA ; G 823 +U 1019 ; WX 602 ; N uni03FB ; G 824 +U 1020 ; WX 602 ; N uni03FC ; G 825 +U 1021 ; WX 602 ; N uni03FD ; G 826 +U 1022 ; WX 602 ; N uni03FE ; G 827 +U 1023 ; WX 602 ; N uni03FF ; G 828 +U 1024 ; WX 602 ; N uni0400 ; G 829 +U 1025 ; WX 602 ; N uni0401 ; G 830 +U 1026 ; WX 602 ; N uni0402 ; G 831 +U 1027 ; WX 602 ; N uni0403 ; G 832 +U 1028 ; WX 602 ; N uni0404 ; G 833 +U 1029 ; WX 602 ; N uni0405 ; G 834 +U 1030 ; WX 602 ; N uni0406 ; G 835 +U 1031 ; WX 602 ; N uni0407 ; G 836 +U 1032 ; WX 602 ; N uni0408 ; G 837 +U 1033 ; WX 602 ; N uni0409 ; G 838 +U 1034 ; WX 602 ; N uni040A ; G 839 +U 1035 ; WX 602 ; N uni040B ; G 840 +U 1036 ; WX 602 ; N uni040C ; G 841 +U 1037 ; WX 602 ; N uni040D ; G 842 +U 1038 ; WX 602 ; N uni040E ; G 843 +U 1039 ; WX 602 ; N uni040F ; G 844 +U 1040 ; WX 602 ; N uni0410 ; G 845 +U 1041 ; WX 602 ; N uni0411 ; G 846 +U 1042 ; WX 602 ; N uni0412 ; G 847 +U 1043 ; WX 602 ; N uni0413 ; G 848 +U 1044 ; WX 602 ; N uni0414 ; G 849 +U 1045 ; WX 602 ; N uni0415 ; G 850 +U 1046 ; WX 602 ; N uni0416 ; G 851 +U 1047 ; WX 602 ; N uni0417 ; G 852 +U 1048 ; WX 602 ; N uni0418 ; G 853 +U 1049 ; WX 602 ; N uni0419 ; G 854 +U 1050 ; WX 602 ; N uni041A ; G 855 +U 1051 ; WX 602 ; N uni041B ; G 856 +U 1052 ; WX 602 ; N uni041C ; G 857 +U 1053 ; WX 602 ; N uni041D ; G 858 +U 1054 ; WX 602 ; N uni041E ; G 859 +U 1055 ; WX 602 ; N uni041F ; G 860 +U 1056 ; WX 602 ; N uni0420 ; G 861 +U 1057 ; WX 602 ; N uni0421 ; G 862 +U 1058 ; WX 602 ; N uni0422 ; G 863 +U 1059 ; WX 602 ; N uni0423 ; G 864 +U 1060 ; WX 602 ; N uni0424 ; G 865 +U 1061 ; WX 602 ; N uni0425 ; G 866 +U 1062 ; WX 602 ; N uni0426 ; G 867 +U 1063 ; WX 602 ; N uni0427 ; G 868 +U 1064 ; WX 602 ; N uni0428 ; G 869 +U 1065 ; WX 602 ; N uni0429 ; G 870 +U 1066 ; WX 602 ; N uni042A ; G 871 +U 1067 ; WX 602 ; N uni042B ; G 872 +U 1068 ; WX 602 ; N uni042C ; G 873 +U 1069 ; WX 602 ; N uni042D ; G 874 +U 1070 ; WX 602 ; N uni042E ; G 875 +U 1071 ; WX 602 ; N uni042F ; G 876 +U 1072 ; WX 602 ; N uni0430 ; G 877 +U 1073 ; WX 602 ; N uni0431 ; G 878 +U 1074 ; WX 602 ; N uni0432 ; G 879 +U 1075 ; WX 602 ; N uni0433 ; G 880 +U 1076 ; WX 602 ; N uni0434 ; G 881 +U 1077 ; WX 602 ; N uni0435 ; G 882 +U 1078 ; WX 602 ; N uni0436 ; G 883 +U 1079 ; WX 602 ; N uni0437 ; G 884 +U 1080 ; WX 602 ; N uni0438 ; G 885 +U 1081 ; WX 602 ; N uni0439 ; G 886 +U 1082 ; WX 602 ; N uni043A ; G 887 +U 1083 ; WX 602 ; N uni043B ; G 888 +U 1084 ; WX 602 ; N uni043C ; G 889 +U 1085 ; WX 602 ; N uni043D ; G 890 +U 1086 ; WX 602 ; N uni043E ; G 891 +U 1087 ; WX 602 ; N uni043F ; G 892 +U 1088 ; WX 602 ; N uni0440 ; G 893 +U 1089 ; WX 602 ; N uni0441 ; G 894 +U 1090 ; WX 602 ; N uni0442 ; G 895 +U 1091 ; WX 602 ; N uni0443 ; G 896 +U 1092 ; WX 602 ; N uni0444 ; G 897 +U 1093 ; WX 602 ; N uni0445 ; G 898 +U 1094 ; WX 602 ; N uni0446 ; G 899 +U 1095 ; WX 602 ; N uni0447 ; G 900 +U 1096 ; WX 602 ; N uni0448 ; G 901 +U 1097 ; WX 602 ; N uni0449 ; G 902 +U 1098 ; WX 602 ; N uni044A ; G 903 +U 1099 ; WX 602 ; N uni044B ; G 904 +U 1100 ; WX 602 ; N uni044C ; G 905 +U 1101 ; WX 602 ; N uni044D ; G 906 +U 1102 ; WX 602 ; N uni044E ; G 907 +U 1103 ; WX 602 ; N uni044F ; G 908 +U 1104 ; WX 602 ; N uni0450 ; G 909 +U 1105 ; WX 602 ; N uni0451 ; G 910 +U 1106 ; WX 602 ; N uni0452 ; G 911 +U 1107 ; WX 602 ; N uni0453 ; G 912 +U 1108 ; WX 602 ; N uni0454 ; G 913 +U 1109 ; WX 602 ; N uni0455 ; G 914 +U 1110 ; WX 602 ; N uni0456 ; G 915 +U 1111 ; WX 602 ; N uni0457 ; G 916 +U 1112 ; WX 602 ; N uni0458 ; G 917 +U 1113 ; WX 602 ; N uni0459 ; G 918 +U 1114 ; WX 602 ; N uni045A ; G 919 +U 1115 ; WX 602 ; N uni045B ; G 920 +U 1116 ; WX 602 ; N uni045C ; G 921 +U 1117 ; WX 602 ; N uni045D ; G 922 +U 1118 ; WX 602 ; N uni045E ; G 923 +U 1119 ; WX 602 ; N uni045F ; G 924 +U 1122 ; WX 602 ; N uni0462 ; G 925 +U 1123 ; WX 602 ; N uni0463 ; G 926 +U 1138 ; WX 602 ; N uni0472 ; G 927 +U 1139 ; WX 602 ; N uni0473 ; G 928 +U 1168 ; WX 602 ; N uni0490 ; G 929 +U 1169 ; WX 602 ; N uni0491 ; G 930 +U 1170 ; WX 602 ; N uni0492 ; G 931 +U 1171 ; WX 602 ; N uni0493 ; G 932 +U 1172 ; WX 602 ; N uni0494 ; G 933 +U 1173 ; WX 602 ; N uni0495 ; G 934 +U 1174 ; WX 602 ; N uni0496 ; G 935 +U 1175 ; WX 602 ; N uni0497 ; G 936 +U 1176 ; WX 602 ; N uni0498 ; G 937 +U 1177 ; WX 602 ; N uni0499 ; G 938 +U 1178 ; WX 602 ; N uni049A ; G 939 +U 1179 ; WX 602 ; N uni049B ; G 940 +U 1186 ; WX 602 ; N uni04A2 ; G 941 +U 1187 ; WX 602 ; N uni04A3 ; G 942 +U 1188 ; WX 602 ; N uni04A4 ; G 943 +U 1189 ; WX 602 ; N uni04A5 ; G 944 +U 1194 ; WX 602 ; N uni04AA ; G 945 +U 1195 ; WX 602 ; N uni04AB ; G 946 +U 1196 ; WX 602 ; N uni04AC ; G 947 +U 1197 ; WX 602 ; N uni04AD ; G 948 +U 1198 ; WX 602 ; N uni04AE ; G 949 +U 1199 ; WX 602 ; N uni04AF ; G 950 +U 1200 ; WX 602 ; N uni04B0 ; G 951 +U 1201 ; WX 602 ; N uni04B1 ; G 952 +U 1202 ; WX 602 ; N uni04B2 ; G 953 +U 1203 ; WX 602 ; N uni04B3 ; G 954 +U 1210 ; WX 602 ; N uni04BA ; G 955 +U 1211 ; WX 602 ; N uni04BB ; G 956 +U 1216 ; WX 602 ; N uni04C0 ; G 957 +U 1217 ; WX 602 ; N uni04C1 ; G 958 +U 1218 ; WX 602 ; N uni04C2 ; G 959 +U 1219 ; WX 602 ; N uni04C3 ; G 960 +U 1220 ; WX 602 ; N uni04C4 ; G 961 +U 1223 ; WX 602 ; N uni04C7 ; G 962 +U 1224 ; WX 602 ; N uni04C8 ; G 963 +U 1227 ; WX 602 ; N uni04CB ; G 964 +U 1228 ; WX 602 ; N uni04CC ; G 965 +U 1231 ; WX 602 ; N uni04CF ; G 966 +U 1232 ; WX 602 ; N uni04D0 ; G 967 +U 1233 ; WX 602 ; N uni04D1 ; G 968 +U 1234 ; WX 602 ; N uni04D2 ; G 969 +U 1235 ; WX 602 ; N uni04D3 ; G 970 +U 1236 ; WX 602 ; N uni04D4 ; G 971 +U 1237 ; WX 602 ; N uni04D5 ; G 972 +U 1238 ; WX 602 ; N uni04D6 ; G 973 +U 1239 ; WX 602 ; N uni04D7 ; G 974 +U 1240 ; WX 602 ; N uni04D8 ; G 975 +U 1241 ; WX 602 ; N uni04D9 ; G 976 +U 1242 ; WX 602 ; N uni04DA ; G 977 +U 1243 ; WX 602 ; N uni04DB ; G 978 +U 1244 ; WX 602 ; N uni04DC ; G 979 +U 1245 ; WX 602 ; N uni04DD ; G 980 +U 1246 ; WX 602 ; N uni04DE ; G 981 +U 1247 ; WX 602 ; N uni04DF ; G 982 +U 1248 ; WX 602 ; N uni04E0 ; G 983 +U 1249 ; WX 602 ; N uni04E1 ; G 984 +U 1250 ; WX 602 ; N uni04E2 ; G 985 +U 1251 ; WX 602 ; N uni04E3 ; G 986 +U 1252 ; WX 602 ; N uni04E4 ; G 987 +U 1253 ; WX 602 ; N uni04E5 ; G 988 +U 1254 ; WX 602 ; N uni04E6 ; G 989 +U 1255 ; WX 602 ; N uni04E7 ; G 990 +U 1256 ; WX 602 ; N uni04E8 ; G 991 +U 1257 ; WX 602 ; N uni04E9 ; G 992 +U 1258 ; WX 602 ; N uni04EA ; G 993 +U 1259 ; WX 602 ; N uni04EB ; G 994 +U 1260 ; WX 602 ; N uni04EC ; G 995 +U 1261 ; WX 602 ; N uni04ED ; G 996 +U 1262 ; WX 602 ; N uni04EE ; G 997 +U 1263 ; WX 602 ; N uni04EF ; G 998 +U 1264 ; WX 602 ; N uni04F0 ; G 999 +U 1265 ; WX 602 ; N uni04F1 ; G 1000 +U 1266 ; WX 602 ; N uni04F2 ; G 1001 +U 1267 ; WX 602 ; N uni04F3 ; G 1002 +U 1268 ; WX 602 ; N uni04F4 ; G 1003 +U 1269 ; WX 602 ; N uni04F5 ; G 1004 +U 1270 ; WX 602 ; N uni04F6 ; G 1005 +U 1271 ; WX 602 ; N uni04F7 ; G 1006 +U 1272 ; WX 602 ; N uni04F8 ; G 1007 +U 1273 ; WX 602 ; N uni04F9 ; G 1008 +U 1296 ; WX 602 ; N uni0510 ; G 1009 +U 1297 ; WX 602 ; N uni0511 ; G 1010 +U 1306 ; WX 602 ; N uni051A ; G 1011 +U 1307 ; WX 602 ; N uni051B ; G 1012 +U 1308 ; WX 602 ; N uni051C ; G 1013 +U 1309 ; WX 602 ; N uni051D ; G 1014 +U 1329 ; WX 602 ; N uni0531 ; G 1015 +U 1330 ; WX 602 ; N uni0532 ; G 1016 +U 1331 ; WX 602 ; N uni0533 ; G 1017 +U 1332 ; WX 602 ; N uni0534 ; G 1018 +U 1333 ; WX 602 ; N uni0535 ; G 1019 +U 1334 ; WX 602 ; N uni0536 ; G 1020 +U 1335 ; WX 602 ; N uni0537 ; G 1021 +U 1336 ; WX 602 ; N uni0538 ; G 1022 +U 1337 ; WX 602 ; N uni0539 ; G 1023 +U 1338 ; WX 602 ; N uni053A ; G 1024 +U 1339 ; WX 602 ; N uni053B ; G 1025 +U 1340 ; WX 602 ; N uni053C ; G 1026 +U 1341 ; WX 602 ; N uni053D ; G 1027 +U 1342 ; WX 602 ; N uni053E ; G 1028 +U 1343 ; WX 602 ; N uni053F ; G 1029 +U 1344 ; WX 602 ; N uni0540 ; G 1030 +U 1345 ; WX 602 ; N uni0541 ; G 1031 +U 1346 ; WX 602 ; N uni0542 ; G 1032 +U 1347 ; WX 602 ; N uni0543 ; G 1033 +U 1348 ; WX 602 ; N uni0544 ; G 1034 +U 1349 ; WX 602 ; N uni0545 ; G 1035 +U 1350 ; WX 602 ; N uni0546 ; G 1036 +U 1351 ; WX 602 ; N uni0547 ; G 1037 +U 1352 ; WX 602 ; N uni0548 ; G 1038 +U 1353 ; WX 602 ; N uni0549 ; G 1039 +U 1354 ; WX 602 ; N uni054A ; G 1040 +U 1355 ; WX 602 ; N uni054B ; G 1041 +U 1356 ; WX 602 ; N uni054C ; G 1042 +U 1357 ; WX 602 ; N uni054D ; G 1043 +U 1358 ; WX 602 ; N uni054E ; G 1044 +U 1359 ; WX 602 ; N uni054F ; G 1045 +U 1360 ; WX 602 ; N uni0550 ; G 1046 +U 1361 ; WX 602 ; N uni0551 ; G 1047 +U 1362 ; WX 602 ; N uni0552 ; G 1048 +U 1363 ; WX 602 ; N uni0553 ; G 1049 +U 1364 ; WX 602 ; N uni0554 ; G 1050 +U 1365 ; WX 602 ; N uni0555 ; G 1051 +U 1366 ; WX 602 ; N uni0556 ; G 1052 +U 1369 ; WX 602 ; N uni0559 ; G 1053 +U 1370 ; WX 602 ; N uni055A ; G 1054 +U 1371 ; WX 602 ; N uni055B ; G 1055 +U 1372 ; WX 602 ; N uni055C ; G 1056 +U 1373 ; WX 602 ; N uni055D ; G 1057 +U 1374 ; WX 602 ; N uni055E ; G 1058 +U 1375 ; WX 602 ; N uni055F ; G 1059 +U 1377 ; WX 602 ; N uni0561 ; G 1060 +U 1378 ; WX 602 ; N uni0562 ; G 1061 +U 1379 ; WX 602 ; N uni0563 ; G 1062 +U 1380 ; WX 602 ; N uni0564 ; G 1063 +U 1381 ; WX 602 ; N uni0565 ; G 1064 +U 1382 ; WX 602 ; N uni0566 ; G 1065 +U 1383 ; WX 602 ; N uni0567 ; G 1066 +U 1384 ; WX 602 ; N uni0568 ; G 1067 +U 1385 ; WX 602 ; N uni0569 ; G 1068 +U 1386 ; WX 602 ; N uni056A ; G 1069 +U 1387 ; WX 602 ; N uni056B ; G 1070 +U 1388 ; WX 602 ; N uni056C ; G 1071 +U 1389 ; WX 602 ; N uni056D ; G 1072 +U 1390 ; WX 602 ; N uni056E ; G 1073 +U 1391 ; WX 602 ; N uni056F ; G 1074 +U 1392 ; WX 602 ; N uni0570 ; G 1075 +U 1393 ; WX 602 ; N uni0571 ; G 1076 +U 1394 ; WX 602 ; N uni0572 ; G 1077 +U 1395 ; WX 602 ; N uni0573 ; G 1078 +U 1396 ; WX 602 ; N uni0574 ; G 1079 +U 1397 ; WX 602 ; N uni0575 ; G 1080 +U 1398 ; WX 602 ; N uni0576 ; G 1081 +U 1399 ; WX 602 ; N uni0577 ; G 1082 +U 1400 ; WX 602 ; N uni0578 ; G 1083 +U 1401 ; WX 602 ; N uni0579 ; G 1084 +U 1402 ; WX 602 ; N uni057A ; G 1085 +U 1403 ; WX 602 ; N uni057B ; G 1086 +U 1404 ; WX 602 ; N uni057C ; G 1087 +U 1405 ; WX 602 ; N uni057D ; G 1088 +U 1406 ; WX 602 ; N uni057E ; G 1089 +U 1407 ; WX 602 ; N uni057F ; G 1090 +U 1408 ; WX 602 ; N uni0580 ; G 1091 +U 1409 ; WX 602 ; N uni0581 ; G 1092 +U 1410 ; WX 602 ; N uni0582 ; G 1093 +U 1411 ; WX 602 ; N uni0583 ; G 1094 +U 1412 ; WX 602 ; N uni0584 ; G 1095 +U 1413 ; WX 602 ; N uni0585 ; G 1096 +U 1414 ; WX 602 ; N uni0586 ; G 1097 +U 1415 ; WX 602 ; N uni0587 ; G 1098 +U 1417 ; WX 602 ; N uni0589 ; G 1099 +U 1418 ; WX 602 ; N uni058A ; G 1100 +U 3647 ; WX 602 ; N uni0E3F ; G 1101 +U 3713 ; WX 602 ; N uni0E81 ; G 1102 +U 3714 ; WX 602 ; N uni0E82 ; G 1103 +U 3716 ; WX 602 ; N uni0E84 ; G 1104 +U 3719 ; WX 602 ; N uni0E87 ; G 1105 +U 3720 ; WX 602 ; N uni0E88 ; G 1106 +U 3722 ; WX 602 ; N uni0E8A ; G 1107 +U 3725 ; WX 602 ; N uni0E8D ; G 1108 +U 3732 ; WX 602 ; N uni0E94 ; G 1109 +U 3733 ; WX 602 ; N uni0E95 ; G 1110 +U 3734 ; WX 602 ; N uni0E96 ; G 1111 +U 3735 ; WX 602 ; N uni0E97 ; G 1112 +U 3737 ; WX 602 ; N uni0E99 ; G 1113 +U 3738 ; WX 602 ; N uni0E9A ; G 1114 +U 3739 ; WX 602 ; N uni0E9B ; G 1115 +U 3740 ; WX 602 ; N uni0E9C ; G 1116 +U 3741 ; WX 602 ; N uni0E9D ; G 1117 +U 3742 ; WX 602 ; N uni0E9E ; G 1118 +U 3743 ; WX 602 ; N uni0E9F ; G 1119 +U 3745 ; WX 602 ; N uni0EA1 ; G 1120 +U 3746 ; WX 602 ; N uni0EA2 ; G 1121 +U 3747 ; WX 602 ; N uni0EA3 ; G 1122 +U 3749 ; WX 602 ; N uni0EA5 ; G 1123 +U 3751 ; WX 602 ; N uni0EA7 ; G 1124 +U 3754 ; WX 602 ; N uni0EAA ; G 1125 +U 3755 ; WX 602 ; N uni0EAB ; G 1126 +U 3757 ; WX 602 ; N uni0EAD ; G 1127 +U 3758 ; WX 602 ; N uni0EAE ; G 1128 +U 3759 ; WX 602 ; N uni0EAF ; G 1129 +U 3760 ; WX 602 ; N uni0EB0 ; G 1130 +U 3761 ; WX 602 ; N uni0EB1 ; G 1131 +U 3762 ; WX 602 ; N uni0EB2 ; G 1132 +U 3763 ; WX 602 ; N uni0EB3 ; G 1133 +U 3764 ; WX 602 ; N uni0EB4 ; G 1134 +U 3765 ; WX 602 ; N uni0EB5 ; G 1135 +U 3766 ; WX 602 ; N uni0EB6 ; G 1136 +U 3767 ; WX 602 ; N uni0EB7 ; G 1137 +U 3768 ; WX 602 ; N uni0EB8 ; G 1138 +U 3769 ; WX 602 ; N uni0EB9 ; G 1139 +U 3771 ; WX 602 ; N uni0EBB ; G 1140 +U 3772 ; WX 602 ; N uni0EBC ; G 1141 +U 3784 ; WX 602 ; N uni0EC8 ; G 1142 +U 3785 ; WX 602 ; N uni0EC9 ; G 1143 +U 3786 ; WX 602 ; N uni0ECA ; G 1144 +U 3787 ; WX 602 ; N uni0ECB ; G 1145 +U 3788 ; WX 602 ; N uni0ECC ; G 1146 +U 3789 ; WX 602 ; N uni0ECD ; G 1147 +U 4304 ; WX 602 ; N uni10D0 ; G 1148 +U 4305 ; WX 602 ; N uni10D1 ; G 1149 +U 4306 ; WX 602 ; N uni10D2 ; G 1150 +U 4307 ; WX 602 ; N uni10D3 ; G 1151 +U 4308 ; WX 602 ; N uni10D4 ; G 1152 +U 4309 ; WX 602 ; N uni10D5 ; G 1153 +U 4310 ; WX 602 ; N uni10D6 ; G 1154 +U 4311 ; WX 602 ; N uni10D7 ; G 1155 +U 4312 ; WX 602 ; N uni10D8 ; G 1156 +U 4313 ; WX 602 ; N uni10D9 ; G 1157 +U 4314 ; WX 602 ; N uni10DA ; G 1158 +U 4315 ; WX 602 ; N uni10DB ; G 1159 +U 4316 ; WX 602 ; N uni10DC ; G 1160 +U 4317 ; WX 602 ; N uni10DD ; G 1161 +U 4318 ; WX 602 ; N uni10DE ; G 1162 +U 4319 ; WX 602 ; N uni10DF ; G 1163 +U 4320 ; WX 602 ; N uni10E0 ; G 1164 +U 4321 ; WX 602 ; N uni10E1 ; G 1165 +U 4322 ; WX 602 ; N uni10E2 ; G 1166 +U 4323 ; WX 602 ; N uni10E3 ; G 1167 +U 4324 ; WX 602 ; N uni10E4 ; G 1168 +U 4325 ; WX 602 ; N uni10E5 ; G 1169 +U 4326 ; WX 602 ; N uni10E6 ; G 1170 +U 4327 ; WX 602 ; N uni10E7 ; G 1171 +U 4328 ; WX 602 ; N uni10E8 ; G 1172 +U 4329 ; WX 602 ; N uni10E9 ; G 1173 +U 4330 ; WX 602 ; N uni10EA ; G 1174 +U 4331 ; WX 602 ; N uni10EB ; G 1175 +U 4332 ; WX 602 ; N uni10EC ; G 1176 +U 4333 ; WX 602 ; N uni10ED ; G 1177 +U 4334 ; WX 602 ; N uni10EE ; G 1178 +U 4335 ; WX 602 ; N uni10EF ; G 1179 +U 4336 ; WX 602 ; N uni10F0 ; G 1180 +U 4337 ; WX 602 ; N uni10F1 ; G 1181 +U 4338 ; WX 602 ; N uni10F2 ; G 1182 +U 4339 ; WX 602 ; N uni10F3 ; G 1183 +U 4340 ; WX 602 ; N uni10F4 ; G 1184 +U 4341 ; WX 602 ; N uni10F5 ; G 1185 +U 4342 ; WX 602 ; N uni10F6 ; G 1186 +U 4343 ; WX 602 ; N uni10F7 ; G 1187 +U 4344 ; WX 602 ; N uni10F8 ; G 1188 +U 4345 ; WX 602 ; N uni10F9 ; G 1189 +U 4346 ; WX 602 ; N uni10FA ; G 1190 +U 4347 ; WX 602 ; N uni10FB ; G 1191 +U 4348 ; WX 602 ; N uni10FC ; G 1192 +U 7426 ; WX 602 ; N uni1D02 ; G 1193 +U 7432 ; WX 602 ; N uni1D08 ; G 1194 +U 7433 ; WX 602 ; N uni1D09 ; G 1195 +U 7444 ; WX 602 ; N uni1D14 ; G 1196 +U 7446 ; WX 602 ; N uni1D16 ; G 1197 +U 7447 ; WX 602 ; N uni1D17 ; G 1198 +U 7453 ; WX 602 ; N uni1D1D ; G 1199 +U 7454 ; WX 602 ; N uni1D1E ; G 1200 +U 7455 ; WX 602 ; N uni1D1F ; G 1201 +U 7468 ; WX 602 ; N uni1D2C ; G 1202 +U 7469 ; WX 602 ; N uni1D2D ; G 1203 +U 7470 ; WX 602 ; N uni1D2E ; G 1204 +U 7472 ; WX 602 ; N uni1D30 ; G 1205 +U 7473 ; WX 602 ; N uni1D31 ; G 1206 +U 7474 ; WX 602 ; N uni1D32 ; G 1207 +U 7475 ; WX 602 ; N uni1D33 ; G 1208 +U 7476 ; WX 602 ; N uni1D34 ; G 1209 +U 7477 ; WX 602 ; N uni1D35 ; G 1210 +U 7478 ; WX 602 ; N uni1D36 ; G 1211 +U 7479 ; WX 602 ; N uni1D37 ; G 1212 +U 7480 ; WX 602 ; N uni1D38 ; G 1213 +U 7481 ; WX 602 ; N uni1D39 ; G 1214 +U 7482 ; WX 602 ; N uni1D3A ; G 1215 +U 7483 ; WX 602 ; N uni1D3B ; G 1216 +U 7484 ; WX 602 ; N uni1D3C ; G 1217 +U 7486 ; WX 602 ; N uni1D3E ; G 1218 +U 7487 ; WX 602 ; N uni1D3F ; G 1219 +U 7488 ; WX 602 ; N uni1D40 ; G 1220 +U 7489 ; WX 602 ; N uni1D41 ; G 1221 +U 7490 ; WX 602 ; N uni1D42 ; G 1222 +U 7491 ; WX 602 ; N uni1D43 ; G 1223 +U 7492 ; WX 602 ; N uni1D44 ; G 1224 +U 7493 ; WX 602 ; N uni1D45 ; G 1225 +U 7494 ; WX 602 ; N uni1D46 ; G 1226 +U 7495 ; WX 602 ; N uni1D47 ; G 1227 +U 7496 ; WX 602 ; N uni1D48 ; G 1228 +U 7497 ; WX 602 ; N uni1D49 ; G 1229 +U 7498 ; WX 602 ; N uni1D4A ; G 1230 +U 7499 ; WX 602 ; N uni1D4B ; G 1231 +U 7500 ; WX 602 ; N uni1D4C ; G 1232 +U 7501 ; WX 602 ; N uni1D4D ; G 1233 +U 7502 ; WX 602 ; N uni1D4E ; G 1234 +U 7503 ; WX 602 ; N uni1D4F ; G 1235 +U 7504 ; WX 602 ; N uni1D50 ; G 1236 +U 7505 ; WX 602 ; N uni1D51 ; G 1237 +U 7506 ; WX 602 ; N uni1D52 ; G 1238 +U 7507 ; WX 602 ; N uni1D53 ; G 1239 +U 7508 ; WX 602 ; N uni1D54 ; G 1240 +U 7509 ; WX 602 ; N uni1D55 ; G 1241 +U 7510 ; WX 602 ; N uni1D56 ; G 1242 +U 7511 ; WX 602 ; N uni1D57 ; G 1243 +U 7512 ; WX 602 ; N uni1D58 ; G 1244 +U 7513 ; WX 602 ; N uni1D59 ; G 1245 +U 7514 ; WX 602 ; N uni1D5A ; G 1246 +U 7515 ; WX 602 ; N uni1D5B ; G 1247 +U 7522 ; WX 602 ; N uni1D62 ; G 1248 +U 7523 ; WX 602 ; N uni1D63 ; G 1249 +U 7524 ; WX 602 ; N uni1D64 ; G 1250 +U 7525 ; WX 602 ; N uni1D65 ; G 1251 +U 7543 ; WX 602 ; N uni1D77 ; G 1252 +U 7544 ; WX 602 ; N uni1D78 ; G 1253 +U 7547 ; WX 602 ; N uni1D7B ; G 1254 +U 7557 ; WX 602 ; N uni1D85 ; G 1255 +U 7579 ; WX 602 ; N uni1D9B ; G 1256 +U 7580 ; WX 602 ; N uni1D9C ; G 1257 +U 7581 ; WX 602 ; N uni1D9D ; G 1258 +U 7582 ; WX 602 ; N uni1D9E ; G 1259 +U 7583 ; WX 602 ; N uni1D9F ; G 1260 +U 7584 ; WX 602 ; N uni1DA0 ; G 1261 +U 7585 ; WX 602 ; N uni1DA1 ; G 1262 +U 7586 ; WX 602 ; N uni1DA2 ; G 1263 +U 7587 ; WX 602 ; N uni1DA3 ; G 1264 +U 7588 ; WX 602 ; N uni1DA4 ; G 1265 +U 7589 ; WX 602 ; N uni1DA5 ; G 1266 +U 7590 ; WX 602 ; N uni1DA6 ; G 1267 +U 7591 ; WX 602 ; N uni1DA7 ; G 1268 +U 7592 ; WX 602 ; N uni1DA8 ; G 1269 +U 7593 ; WX 602 ; N uni1DA9 ; G 1270 +U 7594 ; WX 602 ; N uni1DAA ; G 1271 +U 7595 ; WX 602 ; N uni1DAB ; G 1272 +U 7596 ; WX 602 ; N uni1DAC ; G 1273 +U 7597 ; WX 602 ; N uni1DAD ; G 1274 +U 7598 ; WX 602 ; N uni1DAE ; G 1275 +U 7599 ; WX 602 ; N uni1DAF ; G 1276 +U 7600 ; WX 602 ; N uni1DB0 ; G 1277 +U 7601 ; WX 602 ; N uni1DB1 ; G 1278 +U 7602 ; WX 602 ; N uni1DB2 ; G 1279 +U 7603 ; WX 602 ; N uni1DB3 ; G 1280 +U 7604 ; WX 602 ; N uni1DB4 ; G 1281 +U 7605 ; WX 602 ; N uni1DB5 ; G 1282 +U 7606 ; WX 602 ; N uni1DB6 ; G 1283 +U 7607 ; WX 602 ; N uni1DB7 ; G 1284 +U 7609 ; WX 602 ; N uni1DB9 ; G 1285 +U 7610 ; WX 602 ; N uni1DBA ; G 1286 +U 7611 ; WX 602 ; N uni1DBB ; G 1287 +U 7612 ; WX 602 ; N uni1DBC ; G 1288 +U 7613 ; WX 602 ; N uni1DBD ; G 1289 +U 7614 ; WX 602 ; N uni1DBE ; G 1290 +U 7615 ; WX 602 ; N uni1DBF ; G 1291 +U 7680 ; WX 602 ; N uni1E00 ; G 1292 +U 7681 ; WX 602 ; N uni1E01 ; G 1293 +U 7682 ; WX 602 ; N uni1E02 ; G 1294 +U 7683 ; WX 602 ; N uni1E03 ; G 1295 +U 7684 ; WX 602 ; N uni1E04 ; G 1296 +U 7685 ; WX 602 ; N uni1E05 ; G 1297 +U 7686 ; WX 602 ; N uni1E06 ; G 1298 +U 7687 ; WX 602 ; N uni1E07 ; G 1299 +U 7688 ; WX 602 ; N uni1E08 ; G 1300 +U 7689 ; WX 602 ; N uni1E09 ; G 1301 +U 7690 ; WX 602 ; N uni1E0A ; G 1302 +U 7691 ; WX 602 ; N uni1E0B ; G 1303 +U 7692 ; WX 602 ; N uni1E0C ; G 1304 +U 7693 ; WX 602 ; N uni1E0D ; G 1305 +U 7694 ; WX 602 ; N uni1E0E ; G 1306 +U 7695 ; WX 602 ; N uni1E0F ; G 1307 +U 7696 ; WX 602 ; N uni1E10 ; G 1308 +U 7697 ; WX 602 ; N uni1E11 ; G 1309 +U 7698 ; WX 602 ; N uni1E12 ; G 1310 +U 7699 ; WX 602 ; N uni1E13 ; G 1311 +U 7704 ; WX 602 ; N uni1E18 ; G 1312 +U 7705 ; WX 602 ; N uni1E19 ; G 1313 +U 7706 ; WX 602 ; N uni1E1A ; G 1314 +U 7707 ; WX 602 ; N uni1E1B ; G 1315 +U 7708 ; WX 602 ; N uni1E1C ; G 1316 +U 7709 ; WX 602 ; N uni1E1D ; G 1317 +U 7710 ; WX 602 ; N uni1E1E ; G 1318 +U 7711 ; WX 602 ; N uni1E1F ; G 1319 +U 7712 ; WX 602 ; N uni1E20 ; G 1320 +U 7713 ; WX 602 ; N uni1E21 ; G 1321 +U 7714 ; WX 602 ; N uni1E22 ; G 1322 +U 7715 ; WX 602 ; N uni1E23 ; G 1323 +U 7716 ; WX 602 ; N uni1E24 ; G 1324 +U 7717 ; WX 602 ; N uni1E25 ; G 1325 +U 7718 ; WX 602 ; N uni1E26 ; G 1326 +U 7719 ; WX 602 ; N uni1E27 ; G 1327 +U 7720 ; WX 602 ; N uni1E28 ; G 1328 +U 7721 ; WX 602 ; N uni1E29 ; G 1329 +U 7722 ; WX 602 ; N uni1E2A ; G 1330 +U 7723 ; WX 602 ; N uni1E2B ; G 1331 +U 7724 ; WX 602 ; N uni1E2C ; G 1332 +U 7725 ; WX 602 ; N uni1E2D ; G 1333 +U 7728 ; WX 602 ; N uni1E30 ; G 1334 +U 7729 ; WX 602 ; N uni1E31 ; G 1335 +U 7730 ; WX 602 ; N uni1E32 ; G 1336 +U 7731 ; WX 602 ; N uni1E33 ; G 1337 +U 7732 ; WX 602 ; N uni1E34 ; G 1338 +U 7733 ; WX 602 ; N uni1E35 ; G 1339 +U 7734 ; WX 602 ; N uni1E36 ; G 1340 +U 7735 ; WX 602 ; N uni1E37 ; G 1341 +U 7736 ; WX 602 ; N uni1E38 ; G 1342 +U 7737 ; WX 602 ; N uni1E39 ; G 1343 +U 7738 ; WX 602 ; N uni1E3A ; G 1344 +U 7739 ; WX 602 ; N uni1E3B ; G 1345 +U 7740 ; WX 602 ; N uni1E3C ; G 1346 +U 7741 ; WX 602 ; N uni1E3D ; G 1347 +U 7742 ; WX 602 ; N uni1E3E ; G 1348 +U 7743 ; WX 602 ; N uni1E3F ; G 1349 +U 7744 ; WX 602 ; N uni1E40 ; G 1350 +U 7745 ; WX 602 ; N uni1E41 ; G 1351 +U 7746 ; WX 602 ; N uni1E42 ; G 1352 +U 7747 ; WX 602 ; N uni1E43 ; G 1353 +U 7748 ; WX 602 ; N uni1E44 ; G 1354 +U 7749 ; WX 602 ; N uni1E45 ; G 1355 +U 7750 ; WX 602 ; N uni1E46 ; G 1356 +U 7751 ; WX 602 ; N uni1E47 ; G 1357 +U 7752 ; WX 602 ; N uni1E48 ; G 1358 +U 7753 ; WX 602 ; N uni1E49 ; G 1359 +U 7754 ; WX 602 ; N uni1E4A ; G 1360 +U 7755 ; WX 602 ; N uni1E4B ; G 1361 +U 7756 ; WX 602 ; N uni1E4C ; G 1362 +U 7757 ; WX 602 ; N uni1E4D ; G 1363 +U 7764 ; WX 602 ; N uni1E54 ; G 1364 +U 7765 ; WX 602 ; N uni1E55 ; G 1365 +U 7766 ; WX 602 ; N uni1E56 ; G 1366 +U 7767 ; WX 602 ; N uni1E57 ; G 1367 +U 7768 ; WX 602 ; N uni1E58 ; G 1368 +U 7769 ; WX 602 ; N uni1E59 ; G 1369 +U 7770 ; WX 602 ; N uni1E5A ; G 1370 +U 7771 ; WX 602 ; N uni1E5B ; G 1371 +U 7772 ; WX 602 ; N uni1E5C ; G 1372 +U 7773 ; WX 602 ; N uni1E5D ; G 1373 +U 7774 ; WX 602 ; N uni1E5E ; G 1374 +U 7775 ; WX 602 ; N uni1E5F ; G 1375 +U 7776 ; WX 602 ; N uni1E60 ; G 1376 +U 7777 ; WX 602 ; N uni1E61 ; G 1377 +U 7778 ; WX 602 ; N uni1E62 ; G 1378 +U 7779 ; WX 602 ; N uni1E63 ; G 1379 +U 7784 ; WX 602 ; N uni1E68 ; G 1380 +U 7785 ; WX 602 ; N uni1E69 ; G 1381 +U 7786 ; WX 602 ; N uni1E6A ; G 1382 +U 7787 ; WX 602 ; N uni1E6B ; G 1383 +U 7788 ; WX 602 ; N uni1E6C ; G 1384 +U 7789 ; WX 602 ; N uni1E6D ; G 1385 +U 7790 ; WX 602 ; N uni1E6E ; G 1386 +U 7791 ; WX 602 ; N uni1E6F ; G 1387 +U 7792 ; WX 602 ; N uni1E70 ; G 1388 +U 7793 ; WX 602 ; N uni1E71 ; G 1389 +U 7794 ; WX 602 ; N uni1E72 ; G 1390 +U 7795 ; WX 602 ; N uni1E73 ; G 1391 +U 7796 ; WX 602 ; N uni1E74 ; G 1392 +U 7797 ; WX 602 ; N uni1E75 ; G 1393 +U 7798 ; WX 602 ; N uni1E76 ; G 1394 +U 7799 ; WX 602 ; N uni1E77 ; G 1395 +U 7800 ; WX 602 ; N uni1E78 ; G 1396 +U 7801 ; WX 602 ; N uni1E79 ; G 1397 +U 7804 ; WX 602 ; N uni1E7C ; G 1398 +U 7805 ; WX 602 ; N uni1E7D ; G 1399 +U 7806 ; WX 602 ; N uni1E7E ; G 1400 +U 7807 ; WX 602 ; N uni1E7F ; G 1401 +U 7808 ; WX 602 ; N Wgrave ; G 1402 +U 7809 ; WX 602 ; N wgrave ; G 1403 +U 7810 ; WX 602 ; N Wacute ; G 1404 +U 7811 ; WX 602 ; N wacute ; G 1405 +U 7812 ; WX 602 ; N Wdieresis ; G 1406 +U 7813 ; WX 602 ; N wdieresis ; G 1407 +U 7814 ; WX 602 ; N uni1E86 ; G 1408 +U 7815 ; WX 602 ; N uni1E87 ; G 1409 +U 7816 ; WX 602 ; N uni1E88 ; G 1410 +U 7817 ; WX 602 ; N uni1E89 ; G 1411 +U 7818 ; WX 602 ; N uni1E8A ; G 1412 +U 7819 ; WX 602 ; N uni1E8B ; G 1413 +U 7820 ; WX 602 ; N uni1E8C ; G 1414 +U 7821 ; WX 602 ; N uni1E8D ; G 1415 +U 7822 ; WX 602 ; N uni1E8E ; G 1416 +U 7823 ; WX 602 ; N uni1E8F ; G 1417 +U 7824 ; WX 602 ; N uni1E90 ; G 1418 +U 7825 ; WX 602 ; N uni1E91 ; G 1419 +U 7826 ; WX 602 ; N uni1E92 ; G 1420 +U 7827 ; WX 602 ; N uni1E93 ; G 1421 +U 7828 ; WX 602 ; N uni1E94 ; G 1422 +U 7829 ; WX 602 ; N uni1E95 ; G 1423 +U 7830 ; WX 602 ; N uni1E96 ; G 1424 +U 7831 ; WX 602 ; N uni1E97 ; G 1425 +U 7832 ; WX 602 ; N uni1E98 ; G 1426 +U 7833 ; WX 602 ; N uni1E99 ; G 1427 +U 7835 ; WX 602 ; N uni1E9B ; G 1428 +U 7839 ; WX 602 ; N uni1E9F ; G 1429 +U 7840 ; WX 602 ; N uni1EA0 ; G 1430 +U 7841 ; WX 602 ; N uni1EA1 ; G 1431 +U 7852 ; WX 602 ; N uni1EAC ; G 1432 +U 7853 ; WX 602 ; N uni1EAD ; G 1433 +U 7856 ; WX 602 ; N uni1EB0 ; G 1434 +U 7857 ; WX 602 ; N uni1EB1 ; G 1435 +U 7862 ; WX 602 ; N uni1EB6 ; G 1436 +U 7863 ; WX 602 ; N uni1EB7 ; G 1437 +U 7864 ; WX 602 ; N uni1EB8 ; G 1438 +U 7865 ; WX 602 ; N uni1EB9 ; G 1439 +U 7868 ; WX 602 ; N uni1EBC ; G 1440 +U 7869 ; WX 602 ; N uni1EBD ; G 1441 +U 7878 ; WX 602 ; N uni1EC6 ; G 1442 +U 7879 ; WX 602 ; N uni1EC7 ; G 1443 +U 7882 ; WX 602 ; N uni1ECA ; G 1444 +U 7883 ; WX 602 ; N uni1ECB ; G 1445 +U 7884 ; WX 602 ; N uni1ECC ; G 1446 +U 7885 ; WX 602 ; N uni1ECD ; G 1447 +U 7896 ; WX 602 ; N uni1ED8 ; G 1448 +U 7897 ; WX 602 ; N uni1ED9 ; G 1449 +U 7898 ; WX 602 ; N uni1EDA ; G 1450 +U 7899 ; WX 602 ; N uni1EDB ; G 1451 +U 7900 ; WX 602 ; N uni1EDC ; G 1452 +U 7901 ; WX 602 ; N uni1EDD ; G 1453 +U 7904 ; WX 602 ; N uni1EE0 ; G 1454 +U 7905 ; WX 602 ; N uni1EE1 ; G 1455 +U 7906 ; WX 602 ; N uni1EE2 ; G 1456 +U 7907 ; WX 602 ; N uni1EE3 ; G 1457 +U 7908 ; WX 602 ; N uni1EE4 ; G 1458 +U 7909 ; WX 602 ; N uni1EE5 ; G 1459 +U 7912 ; WX 602 ; N uni1EE8 ; G 1460 +U 7913 ; WX 602 ; N uni1EE9 ; G 1461 +U 7914 ; WX 602 ; N uni1EEA ; G 1462 +U 7915 ; WX 602 ; N uni1EEB ; G 1463 +U 7918 ; WX 602 ; N uni1EEE ; G 1464 +U 7919 ; WX 602 ; N uni1EEF ; G 1465 +U 7920 ; WX 602 ; N uni1EF0 ; G 1466 +U 7921 ; WX 602 ; N uni1EF1 ; G 1467 +U 7922 ; WX 602 ; N Ygrave ; G 1468 +U 7923 ; WX 602 ; N ygrave ; G 1469 +U 7924 ; WX 602 ; N uni1EF4 ; G 1470 +U 7925 ; WX 602 ; N uni1EF5 ; G 1471 +U 7928 ; WX 602 ; N uni1EF8 ; G 1472 +U 7929 ; WX 602 ; N uni1EF9 ; G 1473 +U 7936 ; WX 602 ; N uni1F00 ; G 1474 +U 7937 ; WX 602 ; N uni1F01 ; G 1475 +U 7938 ; WX 602 ; N uni1F02 ; G 1476 +U 7939 ; WX 602 ; N uni1F03 ; G 1477 +U 7940 ; WX 602 ; N uni1F04 ; G 1478 +U 7941 ; WX 602 ; N uni1F05 ; G 1479 +U 7942 ; WX 602 ; N uni1F06 ; G 1480 +U 7943 ; WX 602 ; N uni1F07 ; G 1481 +U 7944 ; WX 602 ; N uni1F08 ; G 1482 +U 7945 ; WX 602 ; N uni1F09 ; G 1483 +U 7946 ; WX 602 ; N uni1F0A ; G 1484 +U 7947 ; WX 602 ; N uni1F0B ; G 1485 +U 7948 ; WX 602 ; N uni1F0C ; G 1486 +U 7949 ; WX 602 ; N uni1F0D ; G 1487 +U 7950 ; WX 602 ; N uni1F0E ; G 1488 +U 7951 ; WX 602 ; N uni1F0F ; G 1489 +U 7952 ; WX 602 ; N uni1F10 ; G 1490 +U 7953 ; WX 602 ; N uni1F11 ; G 1491 +U 7954 ; WX 602 ; N uni1F12 ; G 1492 +U 7955 ; WX 602 ; N uni1F13 ; G 1493 +U 7956 ; WX 602 ; N uni1F14 ; G 1494 +U 7957 ; WX 602 ; N uni1F15 ; G 1495 +U 7960 ; WX 602 ; N uni1F18 ; G 1496 +U 7961 ; WX 602 ; N uni1F19 ; G 1497 +U 7962 ; WX 602 ; N uni1F1A ; G 1498 +U 7963 ; WX 602 ; N uni1F1B ; G 1499 +U 7964 ; WX 602 ; N uni1F1C ; G 1500 +U 7965 ; WX 602 ; N uni1F1D ; G 1501 +U 7968 ; WX 602 ; N uni1F20 ; G 1502 +U 7969 ; WX 602 ; N uni1F21 ; G 1503 +U 7970 ; WX 602 ; N uni1F22 ; G 1504 +U 7971 ; WX 602 ; N uni1F23 ; G 1505 +U 7972 ; WX 602 ; N uni1F24 ; G 1506 +U 7973 ; WX 602 ; N uni1F25 ; G 1507 +U 7974 ; WX 602 ; N uni1F26 ; G 1508 +U 7975 ; WX 602 ; N uni1F27 ; G 1509 +U 7976 ; WX 602 ; N uni1F28 ; G 1510 +U 7977 ; WX 602 ; N uni1F29 ; G 1511 +U 7978 ; WX 602 ; N uni1F2A ; G 1512 +U 7979 ; WX 602 ; N uni1F2B ; G 1513 +U 7980 ; WX 602 ; N uni1F2C ; G 1514 +U 7981 ; WX 602 ; N uni1F2D ; G 1515 +U 7982 ; WX 602 ; N uni1F2E ; G 1516 +U 7983 ; WX 602 ; N uni1F2F ; G 1517 +U 7984 ; WX 602 ; N uni1F30 ; G 1518 +U 7985 ; WX 602 ; N uni1F31 ; G 1519 +U 7986 ; WX 602 ; N uni1F32 ; G 1520 +U 7987 ; WX 602 ; N uni1F33 ; G 1521 +U 7988 ; WX 602 ; N uni1F34 ; G 1522 +U 7989 ; WX 602 ; N uni1F35 ; G 1523 +U 7990 ; WX 602 ; N uni1F36 ; G 1524 +U 7991 ; WX 602 ; N uni1F37 ; G 1525 +U 7992 ; WX 602 ; N uni1F38 ; G 1526 +U 7993 ; WX 602 ; N uni1F39 ; G 1527 +U 7994 ; WX 602 ; N uni1F3A ; G 1528 +U 7995 ; WX 602 ; N uni1F3B ; G 1529 +U 7996 ; WX 602 ; N uni1F3C ; G 1530 +U 7997 ; WX 602 ; N uni1F3D ; G 1531 +U 7998 ; WX 602 ; N uni1F3E ; G 1532 +U 7999 ; WX 602 ; N uni1F3F ; G 1533 +U 8000 ; WX 602 ; N uni1F40 ; G 1534 +U 8001 ; WX 602 ; N uni1F41 ; G 1535 +U 8002 ; WX 602 ; N uni1F42 ; G 1536 +U 8003 ; WX 602 ; N uni1F43 ; G 1537 +U 8004 ; WX 602 ; N uni1F44 ; G 1538 +U 8005 ; WX 602 ; N uni1F45 ; G 1539 +U 8008 ; WX 602 ; N uni1F48 ; G 1540 +U 8009 ; WX 602 ; N uni1F49 ; G 1541 +U 8010 ; WX 602 ; N uni1F4A ; G 1542 +U 8011 ; WX 602 ; N uni1F4B ; G 1543 +U 8012 ; WX 602 ; N uni1F4C ; G 1544 +U 8013 ; WX 602 ; N uni1F4D ; G 1545 +U 8016 ; WX 602 ; N uni1F50 ; G 1546 +U 8017 ; WX 602 ; N uni1F51 ; G 1547 +U 8018 ; WX 602 ; N uni1F52 ; G 1548 +U 8019 ; WX 602 ; N uni1F53 ; G 1549 +U 8020 ; WX 602 ; N uni1F54 ; G 1550 +U 8021 ; WX 602 ; N uni1F55 ; G 1551 +U 8022 ; WX 602 ; N uni1F56 ; G 1552 +U 8023 ; WX 602 ; N uni1F57 ; G 1553 +U 8025 ; WX 602 ; N uni1F59 ; G 1554 +U 8027 ; WX 602 ; N uni1F5B ; G 1555 +U 8029 ; WX 602 ; N uni1F5D ; G 1556 +U 8031 ; WX 602 ; N uni1F5F ; G 1557 +U 8032 ; WX 602 ; N uni1F60 ; G 1558 +U 8033 ; WX 602 ; N uni1F61 ; G 1559 +U 8034 ; WX 602 ; N uni1F62 ; G 1560 +U 8035 ; WX 602 ; N uni1F63 ; G 1561 +U 8036 ; WX 602 ; N uni1F64 ; G 1562 +U 8037 ; WX 602 ; N uni1F65 ; G 1563 +U 8038 ; WX 602 ; N uni1F66 ; G 1564 +U 8039 ; WX 602 ; N uni1F67 ; G 1565 +U 8040 ; WX 602 ; N uni1F68 ; G 1566 +U 8041 ; WX 602 ; N uni1F69 ; G 1567 +U 8042 ; WX 602 ; N uni1F6A ; G 1568 +U 8043 ; WX 602 ; N uni1F6B ; G 1569 +U 8044 ; WX 602 ; N uni1F6C ; G 1570 +U 8045 ; WX 602 ; N uni1F6D ; G 1571 +U 8046 ; WX 602 ; N uni1F6E ; G 1572 +U 8047 ; WX 602 ; N uni1F6F ; G 1573 +U 8048 ; WX 602 ; N uni1F70 ; G 1574 +U 8049 ; WX 602 ; N uni1F71 ; G 1575 +U 8050 ; WX 602 ; N uni1F72 ; G 1576 +U 8051 ; WX 602 ; N uni1F73 ; G 1577 +U 8052 ; WX 602 ; N uni1F74 ; G 1578 +U 8053 ; WX 602 ; N uni1F75 ; G 1579 +U 8054 ; WX 602 ; N uni1F76 ; G 1580 +U 8055 ; WX 602 ; N uni1F77 ; G 1581 +U 8056 ; WX 602 ; N uni1F78 ; G 1582 +U 8057 ; WX 602 ; N uni1F79 ; G 1583 +U 8058 ; WX 602 ; N uni1F7A ; G 1584 +U 8059 ; WX 602 ; N uni1F7B ; G 1585 +U 8060 ; WX 602 ; N uni1F7C ; G 1586 +U 8061 ; WX 602 ; N uni1F7D ; G 1587 +U 8064 ; WX 602 ; N uni1F80 ; G 1588 +U 8065 ; WX 602 ; N uni1F81 ; G 1589 +U 8066 ; WX 602 ; N uni1F82 ; G 1590 +U 8067 ; WX 602 ; N uni1F83 ; G 1591 +U 8068 ; WX 602 ; N uni1F84 ; G 1592 +U 8069 ; WX 602 ; N uni1F85 ; G 1593 +U 8070 ; WX 602 ; N uni1F86 ; G 1594 +U 8071 ; WX 602 ; N uni1F87 ; G 1595 +U 8072 ; WX 602 ; N uni1F88 ; G 1596 +U 8073 ; WX 602 ; N uni1F89 ; G 1597 +U 8074 ; WX 602 ; N uni1F8A ; G 1598 +U 8075 ; WX 602 ; N uni1F8B ; G 1599 +U 8076 ; WX 602 ; N uni1F8C ; G 1600 +U 8077 ; WX 602 ; N uni1F8D ; G 1601 +U 8078 ; WX 602 ; N uni1F8E ; G 1602 +U 8079 ; WX 602 ; N uni1F8F ; G 1603 +U 8080 ; WX 602 ; N uni1F90 ; G 1604 +U 8081 ; WX 602 ; N uni1F91 ; G 1605 +U 8082 ; WX 602 ; N uni1F92 ; G 1606 +U 8083 ; WX 602 ; N uni1F93 ; G 1607 +U 8084 ; WX 602 ; N uni1F94 ; G 1608 +U 8085 ; WX 602 ; N uni1F95 ; G 1609 +U 8086 ; WX 602 ; N uni1F96 ; G 1610 +U 8087 ; WX 602 ; N uni1F97 ; G 1611 +U 8088 ; WX 602 ; N uni1F98 ; G 1612 +U 8089 ; WX 602 ; N uni1F99 ; G 1613 +U 8090 ; WX 602 ; N uni1F9A ; G 1614 +U 8091 ; WX 602 ; N uni1F9B ; G 1615 +U 8092 ; WX 602 ; N uni1F9C ; G 1616 +U 8093 ; WX 602 ; N uni1F9D ; G 1617 +U 8094 ; WX 602 ; N uni1F9E ; G 1618 +U 8095 ; WX 602 ; N uni1F9F ; G 1619 +U 8096 ; WX 602 ; N uni1FA0 ; G 1620 +U 8097 ; WX 602 ; N uni1FA1 ; G 1621 +U 8098 ; WX 602 ; N uni1FA2 ; G 1622 +U 8099 ; WX 602 ; N uni1FA3 ; G 1623 +U 8100 ; WX 602 ; N uni1FA4 ; G 1624 +U 8101 ; WX 602 ; N uni1FA5 ; G 1625 +U 8102 ; WX 602 ; N uni1FA6 ; G 1626 +U 8103 ; WX 602 ; N uni1FA7 ; G 1627 +U 8104 ; WX 602 ; N uni1FA8 ; G 1628 +U 8105 ; WX 602 ; N uni1FA9 ; G 1629 +U 8106 ; WX 602 ; N uni1FAA ; G 1630 +U 8107 ; WX 602 ; N uni1FAB ; G 1631 +U 8108 ; WX 602 ; N uni1FAC ; G 1632 +U 8109 ; WX 602 ; N uni1FAD ; G 1633 +U 8110 ; WX 602 ; N uni1FAE ; G 1634 +U 8111 ; WX 602 ; N uni1FAF ; G 1635 +U 8112 ; WX 602 ; N uni1FB0 ; G 1636 +U 8113 ; WX 602 ; N uni1FB1 ; G 1637 +U 8114 ; WX 602 ; N uni1FB2 ; G 1638 +U 8115 ; WX 602 ; N uni1FB3 ; G 1639 +U 8116 ; WX 602 ; N uni1FB4 ; G 1640 +U 8118 ; WX 602 ; N uni1FB6 ; G 1641 +U 8119 ; WX 602 ; N uni1FB7 ; G 1642 +U 8120 ; WX 602 ; N uni1FB8 ; G 1643 +U 8121 ; WX 602 ; N uni1FB9 ; G 1644 +U 8122 ; WX 602 ; N uni1FBA ; G 1645 +U 8123 ; WX 602 ; N uni1FBB ; G 1646 +U 8124 ; WX 602 ; N uni1FBC ; G 1647 +U 8125 ; WX 602 ; N uni1FBD ; G 1648 +U 8126 ; WX 602 ; N uni1FBE ; G 1649 +U 8127 ; WX 602 ; N uni1FBF ; G 1650 +U 8128 ; WX 602 ; N uni1FC0 ; G 1651 +U 8129 ; WX 602 ; N uni1FC1 ; G 1652 +U 8130 ; WX 602 ; N uni1FC2 ; G 1653 +U 8131 ; WX 602 ; N uni1FC3 ; G 1654 +U 8132 ; WX 602 ; N uni1FC4 ; G 1655 +U 8134 ; WX 602 ; N uni1FC6 ; G 1656 +U 8135 ; WX 602 ; N uni1FC7 ; G 1657 +U 8136 ; WX 602 ; N uni1FC8 ; G 1658 +U 8137 ; WX 602 ; N uni1FC9 ; G 1659 +U 8138 ; WX 602 ; N uni1FCA ; G 1660 +U 8139 ; WX 602 ; N uni1FCB ; G 1661 +U 8140 ; WX 602 ; N uni1FCC ; G 1662 +U 8141 ; WX 602 ; N uni1FCD ; G 1663 +U 8142 ; WX 602 ; N uni1FCE ; G 1664 +U 8143 ; WX 602 ; N uni1FCF ; G 1665 +U 8144 ; WX 602 ; N uni1FD0 ; G 1666 +U 8145 ; WX 602 ; N uni1FD1 ; G 1667 +U 8146 ; WX 602 ; N uni1FD2 ; G 1668 +U 8147 ; WX 602 ; N uni1FD3 ; G 1669 +U 8150 ; WX 602 ; N uni1FD6 ; G 1670 +U 8151 ; WX 602 ; N uni1FD7 ; G 1671 +U 8152 ; WX 602 ; N uni1FD8 ; G 1672 +U 8153 ; WX 602 ; N uni1FD9 ; G 1673 +U 8154 ; WX 602 ; N uni1FDA ; G 1674 +U 8155 ; WX 602 ; N uni1FDB ; G 1675 +U 8157 ; WX 602 ; N uni1FDD ; G 1676 +U 8158 ; WX 602 ; N uni1FDE ; G 1677 +U 8159 ; WX 602 ; N uni1FDF ; G 1678 +U 8160 ; WX 602 ; N uni1FE0 ; G 1679 +U 8161 ; WX 602 ; N uni1FE1 ; G 1680 +U 8162 ; WX 602 ; N uni1FE2 ; G 1681 +U 8163 ; WX 602 ; N uni1FE3 ; G 1682 +U 8164 ; WX 602 ; N uni1FE4 ; G 1683 +U 8165 ; WX 602 ; N uni1FE5 ; G 1684 +U 8166 ; WX 602 ; N uni1FE6 ; G 1685 +U 8167 ; WX 602 ; N uni1FE7 ; G 1686 +U 8168 ; WX 602 ; N uni1FE8 ; G 1687 +U 8169 ; WX 602 ; N uni1FE9 ; G 1688 +U 8170 ; WX 602 ; N uni1FEA ; G 1689 +U 8171 ; WX 602 ; N uni1FEB ; G 1690 +U 8172 ; WX 602 ; N uni1FEC ; G 1691 +U 8173 ; WX 602 ; N uni1FED ; G 1692 +U 8174 ; WX 602 ; N uni1FEE ; G 1693 +U 8175 ; WX 602 ; N uni1FEF ; G 1694 +U 8178 ; WX 602 ; N uni1FF2 ; G 1695 +U 8179 ; WX 602 ; N uni1FF3 ; G 1696 +U 8180 ; WX 602 ; N uni1FF4 ; G 1697 +U 8182 ; WX 602 ; N uni1FF6 ; G 1698 +U 8183 ; WX 602 ; N uni1FF7 ; G 1699 +U 8184 ; WX 602 ; N uni1FF8 ; G 1700 +U 8185 ; WX 602 ; N uni1FF9 ; G 1701 +U 8186 ; WX 602 ; N uni1FFA ; G 1702 +U 8187 ; WX 602 ; N uni1FFB ; G 1703 +U 8188 ; WX 602 ; N uni1FFC ; G 1704 +U 8189 ; WX 602 ; N uni1FFD ; G 1705 +U 8190 ; WX 602 ; N uni1FFE ; G 1706 +U 8192 ; WX 602 ; N uni2000 ; G 1707 +U 8193 ; WX 602 ; N uni2001 ; G 1708 +U 8194 ; WX 602 ; N uni2002 ; G 1709 +U 8195 ; WX 602 ; N uni2003 ; G 1710 +U 8196 ; WX 602 ; N uni2004 ; G 1711 +U 8197 ; WX 602 ; N uni2005 ; G 1712 +U 8198 ; WX 602 ; N uni2006 ; G 1713 +U 8199 ; WX 602 ; N uni2007 ; G 1714 +U 8200 ; WX 602 ; N uni2008 ; G 1715 +U 8201 ; WX 602 ; N uni2009 ; G 1716 +U 8202 ; WX 602 ; N uni200A ; G 1717 +U 8208 ; WX 602 ; N uni2010 ; G 1718 +U 8209 ; WX 602 ; N uni2011 ; G 1719 +U 8210 ; WX 602 ; N figuredash ; G 1720 +U 8211 ; WX 602 ; N endash ; G 1721 +U 8212 ; WX 602 ; N emdash ; G 1722 +U 8213 ; WX 602 ; N uni2015 ; G 1723 +U 8214 ; WX 602 ; N uni2016 ; G 1724 +U 8215 ; WX 602 ; N underscoredbl ; G 1725 +U 8216 ; WX 602 ; N quoteleft ; G 1726 +U 8217 ; WX 602 ; N quoteright ; G 1727 +U 8218 ; WX 602 ; N quotesinglbase ; G 1728 +U 8219 ; WX 602 ; N quotereversed ; G 1729 +U 8220 ; WX 602 ; N quotedblleft ; G 1730 +U 8221 ; WX 602 ; N quotedblright ; G 1731 +U 8222 ; WX 602 ; N quotedblbase ; G 1732 +U 8223 ; WX 602 ; N uni201F ; G 1733 +U 8224 ; WX 602 ; N dagger ; G 1734 +U 8225 ; WX 602 ; N daggerdbl ; G 1735 +U 8226 ; WX 602 ; N bullet ; G 1736 +U 8227 ; WX 602 ; N uni2023 ; G 1737 +U 8230 ; WX 602 ; N ellipsis ; G 1738 +U 8239 ; WX 602 ; N uni202F ; G 1739 +U 8240 ; WX 602 ; N perthousand ; G 1740 +U 8241 ; WX 602 ; N uni2031 ; G 1741 +U 8242 ; WX 602 ; N minute ; G 1742 +U 8243 ; WX 602 ; N second ; G 1743 +U 8244 ; WX 602 ; N uni2034 ; G 1744 +U 8245 ; WX 602 ; N uni2035 ; G 1745 +U 8246 ; WX 602 ; N uni2036 ; G 1746 +U 8247 ; WX 602 ; N uni2037 ; G 1747 +U 8249 ; WX 602 ; N guilsinglleft ; G 1748 +U 8250 ; WX 602 ; N guilsinglright ; G 1749 +U 8252 ; WX 602 ; N exclamdbl ; G 1750 +U 8253 ; WX 602 ; N uni203D ; G 1751 +U 8254 ; WX 602 ; N uni203E ; G 1752 +U 8255 ; WX 602 ; N uni203F ; G 1753 +U 8261 ; WX 602 ; N uni2045 ; G 1754 +U 8262 ; WX 602 ; N uni2046 ; G 1755 +U 8263 ; WX 602 ; N uni2047 ; G 1756 +U 8264 ; WX 602 ; N uni2048 ; G 1757 +U 8265 ; WX 602 ; N uni2049 ; G 1758 +U 8267 ; WX 602 ; N uni204B ; G 1759 +U 8287 ; WX 602 ; N uni205F ; G 1760 +U 8304 ; WX 602 ; N uni2070 ; G 1761 +U 8305 ; WX 602 ; N uni2071 ; G 1762 +U 8308 ; WX 602 ; N uni2074 ; G 1763 +U 8309 ; WX 602 ; N uni2075 ; G 1764 +U 8310 ; WX 602 ; N uni2076 ; G 1765 +U 8311 ; WX 602 ; N uni2077 ; G 1766 +U 8312 ; WX 602 ; N uni2078 ; G 1767 +U 8313 ; WX 602 ; N uni2079 ; G 1768 +U 8314 ; WX 602 ; N uni207A ; G 1769 +U 8315 ; WX 602 ; N uni207B ; G 1770 +U 8316 ; WX 602 ; N uni207C ; G 1771 +U 8317 ; WX 602 ; N uni207D ; G 1772 +U 8318 ; WX 602 ; N uni207E ; G 1773 +U 8319 ; WX 602 ; N uni207F ; G 1774 +U 8320 ; WX 602 ; N uni2080 ; G 1775 +U 8321 ; WX 602 ; N uni2081 ; G 1776 +U 8322 ; WX 602 ; N uni2082 ; G 1777 +U 8323 ; WX 602 ; N uni2083 ; G 1778 +U 8324 ; WX 602 ; N uni2084 ; G 1779 +U 8325 ; WX 602 ; N uni2085 ; G 1780 +U 8326 ; WX 602 ; N uni2086 ; G 1781 +U 8327 ; WX 602 ; N uni2087 ; G 1782 +U 8328 ; WX 602 ; N uni2088 ; G 1783 +U 8329 ; WX 602 ; N uni2089 ; G 1784 +U 8330 ; WX 602 ; N uni208A ; G 1785 +U 8331 ; WX 602 ; N uni208B ; G 1786 +U 8332 ; WX 602 ; N uni208C ; G 1787 +U 8333 ; WX 602 ; N uni208D ; G 1788 +U 8334 ; WX 602 ; N uni208E ; G 1789 +U 8336 ; WX 602 ; N uni2090 ; G 1790 +U 8337 ; WX 602 ; N uni2091 ; G 1791 +U 8338 ; WX 602 ; N uni2092 ; G 1792 +U 8339 ; WX 602 ; N uni2093 ; G 1793 +U 8340 ; WX 602 ; N uni2094 ; G 1794 +U 8341 ; WX 602 ; N uni2095 ; G 1795 +U 8342 ; WX 602 ; N uni2096 ; G 1796 +U 8343 ; WX 602 ; N uni2097 ; G 1797 +U 8344 ; WX 602 ; N uni2098 ; G 1798 +U 8345 ; WX 602 ; N uni2099 ; G 1799 +U 8346 ; WX 602 ; N uni209A ; G 1800 +U 8347 ; WX 602 ; N uni209B ; G 1801 +U 8348 ; WX 602 ; N uni209C ; G 1802 +U 8352 ; WX 602 ; N uni20A0 ; G 1803 +U 8353 ; WX 602 ; N colonmonetary ; G 1804 +U 8354 ; WX 602 ; N uni20A2 ; G 1805 +U 8355 ; WX 602 ; N franc ; G 1806 +U 8356 ; WX 602 ; N lira ; G 1807 +U 8357 ; WX 602 ; N uni20A5 ; G 1808 +U 8358 ; WX 602 ; N uni20A6 ; G 1809 +U 8359 ; WX 602 ; N peseta ; G 1810 +U 8360 ; WX 602 ; N uni20A8 ; G 1811 +U 8361 ; WX 602 ; N uni20A9 ; G 1812 +U 8362 ; WX 602 ; N uni20AA ; G 1813 +U 8363 ; WX 602 ; N dong ; G 1814 +U 8364 ; WX 602 ; N Euro ; G 1815 +U 8365 ; WX 602 ; N uni20AD ; G 1816 +U 8366 ; WX 602 ; N uni20AE ; G 1817 +U 8367 ; WX 602 ; N uni20AF ; G 1818 +U 8368 ; WX 602 ; N uni20B0 ; G 1819 +U 8369 ; WX 602 ; N uni20B1 ; G 1820 +U 8370 ; WX 602 ; N uni20B2 ; G 1821 +U 8371 ; WX 602 ; N uni20B3 ; G 1822 +U 8372 ; WX 602 ; N uni20B4 ; G 1823 +U 8373 ; WX 602 ; N uni20B5 ; G 1824 +U 8376 ; WX 602 ; N uni20B8 ; G 1825 +U 8377 ; WX 602 ; N uni20B9 ; G 1826 +U 8378 ; WX 602 ; N uni20BA ; G 1827 +U 8381 ; WX 602 ; N uni20BD ; G 1828 +U 8450 ; WX 602 ; N uni2102 ; G 1829 +U 8453 ; WX 602 ; N uni2105 ; G 1830 +U 8461 ; WX 602 ; N uni210D ; G 1831 +U 8462 ; WX 602 ; N uni210E ; G 1832 +U 8463 ; WX 602 ; N uni210F ; G 1833 +U 8469 ; WX 602 ; N uni2115 ; G 1834 +U 8470 ; WX 602 ; N uni2116 ; G 1835 +U 8471 ; WX 602 ; N uni2117 ; G 1836 +U 8473 ; WX 602 ; N uni2119 ; G 1837 +U 8474 ; WX 602 ; N uni211A ; G 1838 +U 8477 ; WX 602 ; N uni211D ; G 1839 +U 8482 ; WX 602 ; N trademark ; G 1840 +U 8484 ; WX 602 ; N uni2124 ; G 1841 +U 8486 ; WX 602 ; N uni2126 ; G 1842 +U 8490 ; WX 602 ; N uni212A ; G 1843 +U 8491 ; WX 602 ; N uni212B ; G 1844 +U 8494 ; WX 602 ; N estimated ; G 1845 +U 8520 ; WX 602 ; N uni2148 ; G 1846 +U 8528 ; WX 602 ; N uni2150 ; G 1847 +U 8529 ; WX 602 ; N uni2151 ; G 1848 +U 8531 ; WX 602 ; N onethird ; G 1849 +U 8532 ; WX 602 ; N twothirds ; G 1850 +U 8533 ; WX 602 ; N uni2155 ; G 1851 +U 8534 ; WX 602 ; N uni2156 ; G 1852 +U 8535 ; WX 602 ; N uni2157 ; G 1853 +U 8536 ; WX 602 ; N uni2158 ; G 1854 +U 8537 ; WX 602 ; N uni2159 ; G 1855 +U 8538 ; WX 602 ; N uni215A ; G 1856 +U 8539 ; WX 602 ; N oneeighth ; G 1857 +U 8540 ; WX 602 ; N threeeighths ; G 1858 +U 8541 ; WX 602 ; N fiveeighths ; G 1859 +U 8542 ; WX 602 ; N seveneighths ; G 1860 +U 8543 ; WX 602 ; N uni215F ; G 1861 +U 8585 ; WX 602 ; N uni2189 ; G 1862 +U 8592 ; WX 602 ; N arrowleft ; G 1863 +U 8593 ; WX 602 ; N arrowup ; G 1864 +U 8594 ; WX 602 ; N arrowright ; G 1865 +U 8595 ; WX 602 ; N arrowdown ; G 1866 +U 8596 ; WX 602 ; N arrowboth ; G 1867 +U 8597 ; WX 602 ; N arrowupdn ; G 1868 +U 8598 ; WX 602 ; N uni2196 ; G 1869 +U 8599 ; WX 602 ; N uni2197 ; G 1870 +U 8600 ; WX 602 ; N uni2198 ; G 1871 +U 8601 ; WX 602 ; N uni2199 ; G 1872 +U 8602 ; WX 602 ; N uni219A ; G 1873 +U 8603 ; WX 602 ; N uni219B ; G 1874 +U 8604 ; WX 602 ; N uni219C ; G 1875 +U 8605 ; WX 602 ; N uni219D ; G 1876 +U 8606 ; WX 602 ; N uni219E ; G 1877 +U 8607 ; WX 602 ; N uni219F ; G 1878 +U 8608 ; WX 602 ; N uni21A0 ; G 1879 +U 8609 ; WX 602 ; N uni21A1 ; G 1880 +U 8610 ; WX 602 ; N uni21A2 ; G 1881 +U 8611 ; WX 602 ; N uni21A3 ; G 1882 +U 8612 ; WX 602 ; N uni21A4 ; G 1883 +U 8613 ; WX 602 ; N uni21A5 ; G 1884 +U 8614 ; WX 602 ; N uni21A6 ; G 1885 +U 8615 ; WX 602 ; N uni21A7 ; G 1886 +U 8616 ; WX 602 ; N arrowupdnbse ; G 1887 +U 8617 ; WX 602 ; N uni21A9 ; G 1888 +U 8618 ; WX 602 ; N uni21AA ; G 1889 +U 8619 ; WX 602 ; N uni21AB ; G 1890 +U 8620 ; WX 602 ; N uni21AC ; G 1891 +U 8621 ; WX 602 ; N uni21AD ; G 1892 +U 8622 ; WX 602 ; N uni21AE ; G 1893 +U 8623 ; WX 602 ; N uni21AF ; G 1894 +U 8624 ; WX 602 ; N uni21B0 ; G 1895 +U 8625 ; WX 602 ; N uni21B1 ; G 1896 +U 8626 ; WX 602 ; N uni21B2 ; G 1897 +U 8627 ; WX 602 ; N uni21B3 ; G 1898 +U 8628 ; WX 602 ; N uni21B4 ; G 1899 +U 8629 ; WX 602 ; N carriagereturn ; G 1900 +U 8630 ; WX 602 ; N uni21B6 ; G 1901 +U 8631 ; WX 602 ; N uni21B7 ; G 1902 +U 8632 ; WX 602 ; N uni21B8 ; G 1903 +U 8633 ; WX 602 ; N uni21B9 ; G 1904 +U 8634 ; WX 602 ; N uni21BA ; G 1905 +U 8635 ; WX 602 ; N uni21BB ; G 1906 +U 8636 ; WX 602 ; N uni21BC ; G 1907 +U 8637 ; WX 602 ; N uni21BD ; G 1908 +U 8638 ; WX 602 ; N uni21BE ; G 1909 +U 8639 ; WX 602 ; N uni21BF ; G 1910 +U 8640 ; WX 602 ; N uni21C0 ; G 1911 +U 8641 ; WX 602 ; N uni21C1 ; G 1912 +U 8642 ; WX 602 ; N uni21C2 ; G 1913 +U 8643 ; WX 602 ; N uni21C3 ; G 1914 +U 8644 ; WX 602 ; N uni21C4 ; G 1915 +U 8645 ; WX 602 ; N uni21C5 ; G 1916 +U 8646 ; WX 602 ; N uni21C6 ; G 1917 +U 8647 ; WX 602 ; N uni21C7 ; G 1918 +U 8648 ; WX 602 ; N uni21C8 ; G 1919 +U 8649 ; WX 602 ; N uni21C9 ; G 1920 +U 8650 ; WX 602 ; N uni21CA ; G 1921 +U 8651 ; WX 602 ; N uni21CB ; G 1922 +U 8652 ; WX 602 ; N uni21CC ; G 1923 +U 8653 ; WX 602 ; N uni21CD ; G 1924 +U 8654 ; WX 602 ; N uni21CE ; G 1925 +U 8655 ; WX 602 ; N uni21CF ; G 1926 +U 8656 ; WX 602 ; N arrowdblleft ; G 1927 +U 8657 ; WX 602 ; N arrowdblup ; G 1928 +U 8658 ; WX 602 ; N arrowdblright ; G 1929 +U 8659 ; WX 602 ; N arrowdbldown ; G 1930 +U 8660 ; WX 602 ; N arrowdblboth ; G 1931 +U 8661 ; WX 602 ; N uni21D5 ; G 1932 +U 8662 ; WX 602 ; N uni21D6 ; G 1933 +U 8663 ; WX 602 ; N uni21D7 ; G 1934 +U 8664 ; WX 602 ; N uni21D8 ; G 1935 +U 8665 ; WX 602 ; N uni21D9 ; G 1936 +U 8666 ; WX 602 ; N uni21DA ; G 1937 +U 8667 ; WX 602 ; N uni21DB ; G 1938 +U 8668 ; WX 602 ; N uni21DC ; G 1939 +U 8669 ; WX 602 ; N uni21DD ; G 1940 +U 8670 ; WX 602 ; N uni21DE ; G 1941 +U 8671 ; WX 602 ; N uni21DF ; G 1942 +U 8672 ; WX 602 ; N uni21E0 ; G 1943 +U 8673 ; WX 602 ; N uni21E1 ; G 1944 +U 8674 ; WX 602 ; N uni21E2 ; G 1945 +U 8675 ; WX 602 ; N uni21E3 ; G 1946 +U 8676 ; WX 602 ; N uni21E4 ; G 1947 +U 8677 ; WX 602 ; N uni21E5 ; G 1948 +U 8678 ; WX 602 ; N uni21E6 ; G 1949 +U 8679 ; WX 602 ; N uni21E7 ; G 1950 +U 8680 ; WX 602 ; N uni21E8 ; G 1951 +U 8681 ; WX 602 ; N uni21E9 ; G 1952 +U 8682 ; WX 602 ; N uni21EA ; G 1953 +U 8683 ; WX 602 ; N uni21EB ; G 1954 +U 8684 ; WX 602 ; N uni21EC ; G 1955 +U 8685 ; WX 602 ; N uni21ED ; G 1956 +U 8686 ; WX 602 ; N uni21EE ; G 1957 +U 8687 ; WX 602 ; N uni21EF ; G 1958 +U 8688 ; WX 602 ; N uni21F0 ; G 1959 +U 8689 ; WX 602 ; N uni21F1 ; G 1960 +U 8690 ; WX 602 ; N uni21F2 ; G 1961 +U 8691 ; WX 602 ; N uni21F3 ; G 1962 +U 8692 ; WX 602 ; N uni21F4 ; G 1963 +U 8693 ; WX 602 ; N uni21F5 ; G 1964 +U 8694 ; WX 602 ; N uni21F6 ; G 1965 +U 8695 ; WX 602 ; N uni21F7 ; G 1966 +U 8696 ; WX 602 ; N uni21F8 ; G 1967 +U 8697 ; WX 602 ; N uni21F9 ; G 1968 +U 8698 ; WX 602 ; N uni21FA ; G 1969 +U 8699 ; WX 602 ; N uni21FB ; G 1970 +U 8700 ; WX 602 ; N uni21FC ; G 1971 +U 8701 ; WX 602 ; N uni21FD ; G 1972 +U 8702 ; WX 602 ; N uni21FE ; G 1973 +U 8703 ; WX 602 ; N uni21FF ; G 1974 +U 8704 ; WX 602 ; N universal ; G 1975 +U 8705 ; WX 602 ; N uni2201 ; G 1976 +U 8706 ; WX 602 ; N partialdiff ; G 1977 +U 8707 ; WX 602 ; N existential ; G 1978 +U 8708 ; WX 602 ; N uni2204 ; G 1979 +U 8709 ; WX 602 ; N emptyset ; G 1980 +U 8710 ; WX 602 ; N increment ; G 1981 +U 8711 ; WX 602 ; N gradient ; G 1982 +U 8712 ; WX 602 ; N element ; G 1983 +U 8713 ; WX 602 ; N notelement ; G 1984 +U 8714 ; WX 602 ; N uni220A ; G 1985 +U 8715 ; WX 602 ; N suchthat ; G 1986 +U 8716 ; WX 602 ; N uni220C ; G 1987 +U 8717 ; WX 602 ; N uni220D ; G 1988 +U 8718 ; WX 602 ; N uni220E ; G 1989 +U 8719 ; WX 602 ; N product ; G 1990 +U 8720 ; WX 602 ; N uni2210 ; G 1991 +U 8721 ; WX 602 ; N summation ; G 1992 +U 8722 ; WX 602 ; N minus ; G 1993 +U 8723 ; WX 602 ; N uni2213 ; G 1994 +U 8725 ; WX 602 ; N uni2215 ; G 1995 +U 8727 ; WX 602 ; N asteriskmath ; G 1996 +U 8728 ; WX 602 ; N uni2218 ; G 1997 +U 8729 ; WX 602 ; N uni2219 ; G 1998 +U 8730 ; WX 602 ; N radical ; G 1999 +U 8731 ; WX 602 ; N uni221B ; G 2000 +U 8732 ; WX 602 ; N uni221C ; G 2001 +U 8733 ; WX 602 ; N proportional ; G 2002 +U 8734 ; WX 602 ; N infinity ; G 2003 +U 8735 ; WX 602 ; N orthogonal ; G 2004 +U 8736 ; WX 602 ; N angle ; G 2005 +U 8739 ; WX 602 ; N uni2223 ; G 2006 +U 8743 ; WX 602 ; N logicaland ; G 2007 +U 8744 ; WX 602 ; N logicalor ; G 2008 +U 8745 ; WX 602 ; N intersection ; G 2009 +U 8746 ; WX 602 ; N union ; G 2010 +U 8747 ; WX 602 ; N integral ; G 2011 +U 8748 ; WX 602 ; N uni222C ; G 2012 +U 8749 ; WX 602 ; N uni222D ; G 2013 +U 8756 ; WX 602 ; N therefore ; G 2014 +U 8757 ; WX 602 ; N uni2235 ; G 2015 +U 8758 ; WX 602 ; N uni2236 ; G 2016 +U 8759 ; WX 602 ; N uni2237 ; G 2017 +U 8760 ; WX 602 ; N uni2238 ; G 2018 +U 8761 ; WX 602 ; N uni2239 ; G 2019 +U 8762 ; WX 602 ; N uni223A ; G 2020 +U 8763 ; WX 602 ; N uni223B ; G 2021 +U 8764 ; WX 602 ; N similar ; G 2022 +U 8765 ; WX 602 ; N uni223D ; G 2023 +U 8769 ; WX 602 ; N uni2241 ; G 2024 +U 8770 ; WX 602 ; N uni2242 ; G 2025 +U 8771 ; WX 602 ; N uni2243 ; G 2026 +U 8772 ; WX 602 ; N uni2244 ; G 2027 +U 8773 ; WX 602 ; N congruent ; G 2028 +U 8774 ; WX 602 ; N uni2246 ; G 2029 +U 8775 ; WX 602 ; N uni2247 ; G 2030 +U 8776 ; WX 602 ; N approxequal ; G 2031 +U 8777 ; WX 602 ; N uni2249 ; G 2032 +U 8778 ; WX 602 ; N uni224A ; G 2033 +U 8779 ; WX 602 ; N uni224B ; G 2034 +U 8780 ; WX 602 ; N uni224C ; G 2035 +U 8781 ; WX 602 ; N uni224D ; G 2036 +U 8782 ; WX 602 ; N uni224E ; G 2037 +U 8783 ; WX 602 ; N uni224F ; G 2038 +U 8784 ; WX 602 ; N uni2250 ; G 2039 +U 8785 ; WX 602 ; N uni2251 ; G 2040 +U 8786 ; WX 602 ; N uni2252 ; G 2041 +U 8787 ; WX 602 ; N uni2253 ; G 2042 +U 8788 ; WX 602 ; N uni2254 ; G 2043 +U 8789 ; WX 602 ; N uni2255 ; G 2044 +U 8790 ; WX 602 ; N uni2256 ; G 2045 +U 8791 ; WX 602 ; N uni2257 ; G 2046 +U 8792 ; WX 602 ; N uni2258 ; G 2047 +U 8793 ; WX 602 ; N uni2259 ; G 2048 +U 8794 ; WX 602 ; N uni225A ; G 2049 +U 8795 ; WX 602 ; N uni225B ; G 2050 +U 8796 ; WX 602 ; N uni225C ; G 2051 +U 8797 ; WX 602 ; N uni225D ; G 2052 +U 8798 ; WX 602 ; N uni225E ; G 2053 +U 8799 ; WX 602 ; N uni225F ; G 2054 +U 8800 ; WX 602 ; N notequal ; G 2055 +U 8801 ; WX 602 ; N equivalence ; G 2056 +U 8802 ; WX 602 ; N uni2262 ; G 2057 +U 8803 ; WX 602 ; N uni2263 ; G 2058 +U 8804 ; WX 602 ; N lessequal ; G 2059 +U 8805 ; WX 602 ; N greaterequal ; G 2060 +U 8806 ; WX 602 ; N uni2266 ; G 2061 +U 8807 ; WX 602 ; N uni2267 ; G 2062 +U 8808 ; WX 602 ; N uni2268 ; G 2063 +U 8809 ; WX 602 ; N uni2269 ; G 2064 +U 8813 ; WX 602 ; N uni226D ; G 2065 +U 8814 ; WX 602 ; N uni226E ; G 2066 +U 8815 ; WX 602 ; N uni226F ; G 2067 +U 8816 ; WX 602 ; N uni2270 ; G 2068 +U 8817 ; WX 602 ; N uni2271 ; G 2069 +U 8818 ; WX 602 ; N uni2272 ; G 2070 +U 8819 ; WX 602 ; N uni2273 ; G 2071 +U 8820 ; WX 602 ; N uni2274 ; G 2072 +U 8821 ; WX 602 ; N uni2275 ; G 2073 +U 8822 ; WX 602 ; N uni2276 ; G 2074 +U 8823 ; WX 602 ; N uni2277 ; G 2075 +U 8824 ; WX 602 ; N uni2278 ; G 2076 +U 8825 ; WX 602 ; N uni2279 ; G 2077 +U 8826 ; WX 602 ; N uni227A ; G 2078 +U 8827 ; WX 602 ; N uni227B ; G 2079 +U 8828 ; WX 602 ; N uni227C ; G 2080 +U 8829 ; WX 602 ; N uni227D ; G 2081 +U 8830 ; WX 602 ; N uni227E ; G 2082 +U 8831 ; WX 602 ; N uni227F ; G 2083 +U 8832 ; WX 602 ; N uni2280 ; G 2084 +U 8833 ; WX 602 ; N uni2281 ; G 2085 +U 8834 ; WX 602 ; N propersubset ; G 2086 +U 8835 ; WX 602 ; N propersuperset ; G 2087 +U 8836 ; WX 602 ; N notsubset ; G 2088 +U 8837 ; WX 602 ; N uni2285 ; G 2089 +U 8838 ; WX 602 ; N reflexsubset ; G 2090 +U 8839 ; WX 602 ; N reflexsuperset ; G 2091 +U 8840 ; WX 602 ; N uni2288 ; G 2092 +U 8841 ; WX 602 ; N uni2289 ; G 2093 +U 8842 ; WX 602 ; N uni228A ; G 2094 +U 8843 ; WX 602 ; N uni228B ; G 2095 +U 8845 ; WX 602 ; N uni228D ; G 2096 +U 8846 ; WX 602 ; N uni228E ; G 2097 +U 8847 ; WX 602 ; N uni228F ; G 2098 +U 8848 ; WX 602 ; N uni2290 ; G 2099 +U 8849 ; WX 602 ; N uni2291 ; G 2100 +U 8850 ; WX 602 ; N uni2292 ; G 2101 +U 8851 ; WX 602 ; N uni2293 ; G 2102 +U 8852 ; WX 602 ; N uni2294 ; G 2103 +U 8853 ; WX 602 ; N circleplus ; G 2104 +U 8854 ; WX 602 ; N uni2296 ; G 2105 +U 8855 ; WX 602 ; N circlemultiply ; G 2106 +U 8856 ; WX 602 ; N uni2298 ; G 2107 +U 8857 ; WX 602 ; N uni2299 ; G 2108 +U 8858 ; WX 602 ; N uni229A ; G 2109 +U 8859 ; WX 602 ; N uni229B ; G 2110 +U 8860 ; WX 602 ; N uni229C ; G 2111 +U 8861 ; WX 602 ; N uni229D ; G 2112 +U 8862 ; WX 602 ; N uni229E ; G 2113 +U 8863 ; WX 602 ; N uni229F ; G 2114 +U 8864 ; WX 602 ; N uni22A0 ; G 2115 +U 8865 ; WX 602 ; N uni22A1 ; G 2116 +U 8866 ; WX 602 ; N uni22A2 ; G 2117 +U 8867 ; WX 602 ; N uni22A3 ; G 2118 +U 8868 ; WX 602 ; N uni22A4 ; G 2119 +U 8869 ; WX 602 ; N perpendicular ; G 2120 +U 8882 ; WX 602 ; N uni22B2 ; G 2121 +U 8883 ; WX 602 ; N uni22B3 ; G 2122 +U 8884 ; WX 602 ; N uni22B4 ; G 2123 +U 8885 ; WX 602 ; N uni22B5 ; G 2124 +U 8888 ; WX 602 ; N uni22B8 ; G 2125 +U 8898 ; WX 602 ; N uni22C2 ; G 2126 +U 8899 ; WX 602 ; N uni22C3 ; G 2127 +U 8900 ; WX 602 ; N uni22C4 ; G 2128 +U 8901 ; WX 602 ; N dotmath ; G 2129 +U 8902 ; WX 602 ; N uni22C6 ; G 2130 +U 8909 ; WX 602 ; N uni22CD ; G 2131 +U 8910 ; WX 602 ; N uni22CE ; G 2132 +U 8911 ; WX 602 ; N uni22CF ; G 2133 +U 8912 ; WX 602 ; N uni22D0 ; G 2134 +U 8913 ; WX 602 ; N uni22D1 ; G 2135 +U 8922 ; WX 602 ; N uni22DA ; G 2136 +U 8923 ; WX 602 ; N uni22DB ; G 2137 +U 8924 ; WX 602 ; N uni22DC ; G 2138 +U 8925 ; WX 602 ; N uni22DD ; G 2139 +U 8926 ; WX 602 ; N uni22DE ; G 2140 +U 8927 ; WX 602 ; N uni22DF ; G 2141 +U 8928 ; WX 602 ; N uni22E0 ; G 2142 +U 8929 ; WX 602 ; N uni22E1 ; G 2143 +U 8930 ; WX 602 ; N uni22E2 ; G 2144 +U 8931 ; WX 602 ; N uni22E3 ; G 2145 +U 8932 ; WX 602 ; N uni22E4 ; G 2146 +U 8933 ; WX 602 ; N uni22E5 ; G 2147 +U 8934 ; WX 602 ; N uni22E6 ; G 2148 +U 8935 ; WX 602 ; N uni22E7 ; G 2149 +U 8936 ; WX 602 ; N uni22E8 ; G 2150 +U 8937 ; WX 602 ; N uni22E9 ; G 2151 +U 8943 ; WX 602 ; N uni22EF ; G 2152 +U 8960 ; WX 602 ; N uni2300 ; G 2153 +U 8961 ; WX 602 ; N uni2301 ; G 2154 +U 8962 ; WX 602 ; N house ; G 2155 +U 8963 ; WX 602 ; N uni2303 ; G 2156 +U 8964 ; WX 602 ; N uni2304 ; G 2157 +U 8965 ; WX 602 ; N uni2305 ; G 2158 +U 8966 ; WX 602 ; N uni2306 ; G 2159 +U 8968 ; WX 602 ; N uni2308 ; G 2160 +U 8969 ; WX 602 ; N uni2309 ; G 2161 +U 8970 ; WX 602 ; N uni230A ; G 2162 +U 8971 ; WX 602 ; N uni230B ; G 2163 +U 8972 ; WX 602 ; N uni230C ; G 2164 +U 8973 ; WX 602 ; N uni230D ; G 2165 +U 8974 ; WX 602 ; N uni230E ; G 2166 +U 8975 ; WX 602 ; N uni230F ; G 2167 +U 8976 ; WX 602 ; N revlogicalnot ; G 2168 +U 8977 ; WX 602 ; N uni2311 ; G 2169 +U 8978 ; WX 602 ; N uni2312 ; G 2170 +U 8979 ; WX 602 ; N uni2313 ; G 2171 +U 8980 ; WX 602 ; N uni2314 ; G 2172 +U 8981 ; WX 602 ; N uni2315 ; G 2173 +U 8984 ; WX 602 ; N uni2318 ; G 2174 +U 8985 ; WX 602 ; N uni2319 ; G 2175 +U 8988 ; WX 602 ; N uni231C ; G 2176 +U 8989 ; WX 602 ; N uni231D ; G 2177 +U 8990 ; WX 602 ; N uni231E ; G 2178 +U 8991 ; WX 602 ; N uni231F ; G 2179 +U 8992 ; WX 602 ; N integraltp ; G 2180 +U 8993 ; WX 602 ; N integralbt ; G 2181 +U 8997 ; WX 602 ; N uni2325 ; G 2182 +U 8998 ; WX 602 ; N uni2326 ; G 2183 +U 8999 ; WX 602 ; N uni2327 ; G 2184 +U 9000 ; WX 602 ; N uni2328 ; G 2185 +U 9003 ; WX 602 ; N uni232B ; G 2186 +U 9013 ; WX 602 ; N uni2335 ; G 2187 +U 9014 ; WX 602 ; N uni2336 ; G 2188 +U 9015 ; WX 602 ; N uni2337 ; G 2189 +U 9016 ; WX 602 ; N uni2338 ; G 2190 +U 9017 ; WX 602 ; N uni2339 ; G 2191 +U 9018 ; WX 602 ; N uni233A ; G 2192 +U 9019 ; WX 602 ; N uni233B ; G 2193 +U 9020 ; WX 602 ; N uni233C ; G 2194 +U 9021 ; WX 602 ; N uni233D ; G 2195 +U 9022 ; WX 602 ; N uni233E ; G 2196 +U 9023 ; WX 602 ; N uni233F ; G 2197 +U 9024 ; WX 602 ; N uni2340 ; G 2198 +U 9025 ; WX 602 ; N uni2341 ; G 2199 +U 9026 ; WX 602 ; N uni2342 ; G 2200 +U 9027 ; WX 602 ; N uni2343 ; G 2201 +U 9028 ; WX 602 ; N uni2344 ; G 2202 +U 9029 ; WX 602 ; N uni2345 ; G 2203 +U 9030 ; WX 602 ; N uni2346 ; G 2204 +U 9031 ; WX 602 ; N uni2347 ; G 2205 +U 9032 ; WX 602 ; N uni2348 ; G 2206 +U 9033 ; WX 602 ; N uni2349 ; G 2207 +U 9034 ; WX 602 ; N uni234A ; G 2208 +U 9035 ; WX 602 ; N uni234B ; G 2209 +U 9036 ; WX 602 ; N uni234C ; G 2210 +U 9037 ; WX 602 ; N uni234D ; G 2211 +U 9038 ; WX 602 ; N uni234E ; G 2212 +U 9039 ; WX 602 ; N uni234F ; G 2213 +U 9040 ; WX 602 ; N uni2350 ; G 2214 +U 9041 ; WX 602 ; N uni2351 ; G 2215 +U 9042 ; WX 602 ; N uni2352 ; G 2216 +U 9043 ; WX 602 ; N uni2353 ; G 2217 +U 9044 ; WX 602 ; N uni2354 ; G 2218 +U 9045 ; WX 602 ; N uni2355 ; G 2219 +U 9046 ; WX 602 ; N uni2356 ; G 2220 +U 9047 ; WX 602 ; N uni2357 ; G 2221 +U 9048 ; WX 602 ; N uni2358 ; G 2222 +U 9049 ; WX 602 ; N uni2359 ; G 2223 +U 9050 ; WX 602 ; N uni235A ; G 2224 +U 9051 ; WX 602 ; N uni235B ; G 2225 +U 9052 ; WX 602 ; N uni235C ; G 2226 +U 9053 ; WX 602 ; N uni235D ; G 2227 +U 9054 ; WX 602 ; N uni235E ; G 2228 +U 9055 ; WX 602 ; N uni235F ; G 2229 +U 9056 ; WX 602 ; N uni2360 ; G 2230 +U 9057 ; WX 602 ; N uni2361 ; G 2231 +U 9058 ; WX 602 ; N uni2362 ; G 2232 +U 9059 ; WX 602 ; N uni2363 ; G 2233 +U 9060 ; WX 602 ; N uni2364 ; G 2234 +U 9061 ; WX 602 ; N uni2365 ; G 2235 +U 9062 ; WX 602 ; N uni2366 ; G 2236 +U 9063 ; WX 602 ; N uni2367 ; G 2237 +U 9064 ; WX 602 ; N uni2368 ; G 2238 +U 9065 ; WX 602 ; N uni2369 ; G 2239 +U 9066 ; WX 602 ; N uni236A ; G 2240 +U 9067 ; WX 602 ; N uni236B ; G 2241 +U 9068 ; WX 602 ; N uni236C ; G 2242 +U 9069 ; WX 602 ; N uni236D ; G 2243 +U 9070 ; WX 602 ; N uni236E ; G 2244 +U 9071 ; WX 602 ; N uni236F ; G 2245 +U 9072 ; WX 602 ; N uni2370 ; G 2246 +U 9073 ; WX 602 ; N uni2371 ; G 2247 +U 9074 ; WX 602 ; N uni2372 ; G 2248 +U 9075 ; WX 602 ; N uni2373 ; G 2249 +U 9076 ; WX 602 ; N uni2374 ; G 2250 +U 9077 ; WX 602 ; N uni2375 ; G 2251 +U 9078 ; WX 602 ; N uni2376 ; G 2252 +U 9079 ; WX 602 ; N uni2377 ; G 2253 +U 9080 ; WX 602 ; N uni2378 ; G 2254 +U 9081 ; WX 602 ; N uni2379 ; G 2255 +U 9082 ; WX 602 ; N uni237A ; G 2256 +U 9085 ; WX 602 ; N uni237D ; G 2257 +U 9088 ; WX 602 ; N uni2380 ; G 2258 +U 9089 ; WX 602 ; N uni2381 ; G 2259 +U 9090 ; WX 602 ; N uni2382 ; G 2260 +U 9091 ; WX 602 ; N uni2383 ; G 2261 +U 9096 ; WX 602 ; N uni2388 ; G 2262 +U 9097 ; WX 602 ; N uni2389 ; G 2263 +U 9098 ; WX 602 ; N uni238A ; G 2264 +U 9099 ; WX 602 ; N uni238B ; G 2265 +U 9109 ; WX 602 ; N uni2395 ; G 2266 +U 9115 ; WX 602 ; N uni239B ; G 2267 +U 9116 ; WX 602 ; N uni239C ; G 2268 +U 9117 ; WX 602 ; N uni239D ; G 2269 +U 9118 ; WX 602 ; N uni239E ; G 2270 +U 9119 ; WX 602 ; N uni239F ; G 2271 +U 9120 ; WX 602 ; N uni23A0 ; G 2272 +U 9121 ; WX 602 ; N uni23A1 ; G 2273 +U 9122 ; WX 602 ; N uni23A2 ; G 2274 +U 9123 ; WX 602 ; N uni23A3 ; G 2275 +U 9124 ; WX 602 ; N uni23A4 ; G 2276 +U 9125 ; WX 602 ; N uni23A5 ; G 2277 +U 9126 ; WX 602 ; N uni23A6 ; G 2278 +U 9127 ; WX 602 ; N uni23A7 ; G 2279 +U 9128 ; WX 602 ; N uni23A8 ; G 2280 +U 9129 ; WX 602 ; N uni23A9 ; G 2281 +U 9130 ; WX 602 ; N uni23AA ; G 2282 +U 9131 ; WX 602 ; N uni23AB ; G 2283 +U 9132 ; WX 602 ; N uni23AC ; G 2284 +U 9133 ; WX 602 ; N uni23AD ; G 2285 +U 9134 ; WX 602 ; N uni23AE ; G 2286 +U 9166 ; WX 602 ; N uni23CE ; G 2287 +U 9167 ; WX 602 ; N uni23CF ; G 2288 +U 9251 ; WX 602 ; N uni2423 ; G 2289 +U 9472 ; WX 602 ; N SF100000 ; G 2290 +U 9473 ; WX 602 ; N uni2501 ; G 2291 +U 9474 ; WX 602 ; N SF110000 ; G 2292 +U 9475 ; WX 602 ; N uni2503 ; G 2293 +U 9476 ; WX 602 ; N uni2504 ; G 2294 +U 9477 ; WX 602 ; N uni2505 ; G 2295 +U 9478 ; WX 602 ; N uni2506 ; G 2296 +U 9479 ; WX 602 ; N uni2507 ; G 2297 +U 9480 ; WX 602 ; N uni2508 ; G 2298 +U 9481 ; WX 602 ; N uni2509 ; G 2299 +U 9482 ; WX 602 ; N uni250A ; G 2300 +U 9483 ; WX 602 ; N uni250B ; G 2301 +U 9484 ; WX 602 ; N SF010000 ; G 2302 +U 9485 ; WX 602 ; N uni250D ; G 2303 +U 9486 ; WX 602 ; N uni250E ; G 2304 +U 9487 ; WX 602 ; N uni250F ; G 2305 +U 9488 ; WX 602 ; N SF030000 ; G 2306 +U 9489 ; WX 602 ; N uni2511 ; G 2307 +U 9490 ; WX 602 ; N uni2512 ; G 2308 +U 9491 ; WX 602 ; N uni2513 ; G 2309 +U 9492 ; WX 602 ; N SF020000 ; G 2310 +U 9493 ; WX 602 ; N uni2515 ; G 2311 +U 9494 ; WX 602 ; N uni2516 ; G 2312 +U 9495 ; WX 602 ; N uni2517 ; G 2313 +U 9496 ; WX 602 ; N SF040000 ; G 2314 +U 9497 ; WX 602 ; N uni2519 ; G 2315 +U 9498 ; WX 602 ; N uni251A ; G 2316 +U 9499 ; WX 602 ; N uni251B ; G 2317 +U 9500 ; WX 602 ; N SF080000 ; G 2318 +U 9501 ; WX 602 ; N uni251D ; G 2319 +U 9502 ; WX 602 ; N uni251E ; G 2320 +U 9503 ; WX 602 ; N uni251F ; G 2321 +U 9504 ; WX 602 ; N uni2520 ; G 2322 +U 9505 ; WX 602 ; N uni2521 ; G 2323 +U 9506 ; WX 602 ; N uni2522 ; G 2324 +U 9507 ; WX 602 ; N uni2523 ; G 2325 +U 9508 ; WX 602 ; N SF090000 ; G 2326 +U 9509 ; WX 602 ; N uni2525 ; G 2327 +U 9510 ; WX 602 ; N uni2526 ; G 2328 +U 9511 ; WX 602 ; N uni2527 ; G 2329 +U 9512 ; WX 602 ; N uni2528 ; G 2330 +U 9513 ; WX 602 ; N uni2529 ; G 2331 +U 9514 ; WX 602 ; N uni252A ; G 2332 +U 9515 ; WX 602 ; N uni252B ; G 2333 +U 9516 ; WX 602 ; N SF060000 ; G 2334 +U 9517 ; WX 602 ; N uni252D ; G 2335 +U 9518 ; WX 602 ; N uni252E ; G 2336 +U 9519 ; WX 602 ; N uni252F ; G 2337 +U 9520 ; WX 602 ; N uni2530 ; G 2338 +U 9521 ; WX 602 ; N uni2531 ; G 2339 +U 9522 ; WX 602 ; N uni2532 ; G 2340 +U 9523 ; WX 602 ; N uni2533 ; G 2341 +U 9524 ; WX 602 ; N SF070000 ; G 2342 +U 9525 ; WX 602 ; N uni2535 ; G 2343 +U 9526 ; WX 602 ; N uni2536 ; G 2344 +U 9527 ; WX 602 ; N uni2537 ; G 2345 +U 9528 ; WX 602 ; N uni2538 ; G 2346 +U 9529 ; WX 602 ; N uni2539 ; G 2347 +U 9530 ; WX 602 ; N uni253A ; G 2348 +U 9531 ; WX 602 ; N uni253B ; G 2349 +U 9532 ; WX 602 ; N SF050000 ; G 2350 +U 9533 ; WX 602 ; N uni253D ; G 2351 +U 9534 ; WX 602 ; N uni253E ; G 2352 +U 9535 ; WX 602 ; N uni253F ; G 2353 +U 9536 ; WX 602 ; N uni2540 ; G 2354 +U 9537 ; WX 602 ; N uni2541 ; G 2355 +U 9538 ; WX 602 ; N uni2542 ; G 2356 +U 9539 ; WX 602 ; N uni2543 ; G 2357 +U 9540 ; WX 602 ; N uni2544 ; G 2358 +U 9541 ; WX 602 ; N uni2545 ; G 2359 +U 9542 ; WX 602 ; N uni2546 ; G 2360 +U 9543 ; WX 602 ; N uni2547 ; G 2361 +U 9544 ; WX 602 ; N uni2548 ; G 2362 +U 9545 ; WX 602 ; N uni2549 ; G 2363 +U 9546 ; WX 602 ; N uni254A ; G 2364 +U 9547 ; WX 602 ; N uni254B ; G 2365 +U 9548 ; WX 602 ; N uni254C ; G 2366 +U 9549 ; WX 602 ; N uni254D ; G 2367 +U 9550 ; WX 602 ; N uni254E ; G 2368 +U 9551 ; WX 602 ; N uni254F ; G 2369 +U 9552 ; WX 602 ; N SF430000 ; G 2370 +U 9553 ; WX 602 ; N SF240000 ; G 2371 +U 9554 ; WX 602 ; N SF510000 ; G 2372 +U 9555 ; WX 602 ; N SF520000 ; G 2373 +U 9556 ; WX 602 ; N SF390000 ; G 2374 +U 9557 ; WX 602 ; N SF220000 ; G 2375 +U 9558 ; WX 602 ; N SF210000 ; G 2376 +U 9559 ; WX 602 ; N SF250000 ; G 2377 +U 9560 ; WX 602 ; N SF500000 ; G 2378 +U 9561 ; WX 602 ; N SF490000 ; G 2379 +U 9562 ; WX 602 ; N SF380000 ; G 2380 +U 9563 ; WX 602 ; N SF280000 ; G 2381 +U 9564 ; WX 602 ; N SF270000 ; G 2382 +U 9565 ; WX 602 ; N SF260000 ; G 2383 +U 9566 ; WX 602 ; N SF360000 ; G 2384 +U 9567 ; WX 602 ; N SF370000 ; G 2385 +U 9568 ; WX 602 ; N SF420000 ; G 2386 +U 9569 ; WX 602 ; N SF190000 ; G 2387 +U 9570 ; WX 602 ; N SF200000 ; G 2388 +U 9571 ; WX 602 ; N SF230000 ; G 2389 +U 9572 ; WX 602 ; N SF470000 ; G 2390 +U 9573 ; WX 602 ; N SF480000 ; G 2391 +U 9574 ; WX 602 ; N SF410000 ; G 2392 +U 9575 ; WX 602 ; N SF450000 ; G 2393 +U 9576 ; WX 602 ; N SF460000 ; G 2394 +U 9577 ; WX 602 ; N SF400000 ; G 2395 +U 9578 ; WX 602 ; N SF540000 ; G 2396 +U 9579 ; WX 602 ; N SF530000 ; G 2397 +U 9580 ; WX 602 ; N SF440000 ; G 2398 +U 9581 ; WX 602 ; N uni256D ; G 2399 +U 9582 ; WX 602 ; N uni256E ; G 2400 +U 9583 ; WX 602 ; N uni256F ; G 2401 +U 9584 ; WX 602 ; N uni2570 ; G 2402 +U 9585 ; WX 602 ; N uni2571 ; G 2403 +U 9586 ; WX 602 ; N uni2572 ; G 2404 +U 9587 ; WX 602 ; N uni2573 ; G 2405 +U 9588 ; WX 602 ; N uni2574 ; G 2406 +U 9589 ; WX 602 ; N uni2575 ; G 2407 +U 9590 ; WX 602 ; N uni2576 ; G 2408 +U 9591 ; WX 602 ; N uni2577 ; G 2409 +U 9592 ; WX 602 ; N uni2578 ; G 2410 +U 9593 ; WX 602 ; N uni2579 ; G 2411 +U 9594 ; WX 602 ; N uni257A ; G 2412 +U 9595 ; WX 602 ; N uni257B ; G 2413 +U 9596 ; WX 602 ; N uni257C ; G 2414 +U 9597 ; WX 602 ; N uni257D ; G 2415 +U 9598 ; WX 602 ; N uni257E ; G 2416 +U 9599 ; WX 602 ; N uni257F ; G 2417 +U 9600 ; WX 602 ; N upblock ; G 2418 +U 9601 ; WX 602 ; N uni2581 ; G 2419 +U 9602 ; WX 602 ; N uni2582 ; G 2420 +U 9603 ; WX 602 ; N uni2583 ; G 2421 +U 9604 ; WX 602 ; N dnblock ; G 2422 +U 9605 ; WX 602 ; N uni2585 ; G 2423 +U 9606 ; WX 602 ; N uni2586 ; G 2424 +U 9607 ; WX 602 ; N uni2587 ; G 2425 +U 9608 ; WX 602 ; N block ; G 2426 +U 9609 ; WX 602 ; N uni2589 ; G 2427 +U 9610 ; WX 602 ; N uni258A ; G 2428 +U 9611 ; WX 602 ; N uni258B ; G 2429 +U 9612 ; WX 602 ; N lfblock ; G 2430 +U 9613 ; WX 602 ; N uni258D ; G 2431 +U 9614 ; WX 602 ; N uni258E ; G 2432 +U 9615 ; WX 602 ; N uni258F ; G 2433 +U 9616 ; WX 602 ; N rtblock ; G 2434 +U 9617 ; WX 602 ; N ltshade ; G 2435 +U 9618 ; WX 602 ; N shade ; G 2436 +U 9619 ; WX 602 ; N dkshade ; G 2437 +U 9620 ; WX 602 ; N uni2594 ; G 2438 +U 9621 ; WX 602 ; N uni2595 ; G 2439 +U 9622 ; WX 602 ; N uni2596 ; G 2440 +U 9623 ; WX 602 ; N uni2597 ; G 2441 +U 9624 ; WX 602 ; N uni2598 ; G 2442 +U 9625 ; WX 602 ; N uni2599 ; G 2443 +U 9626 ; WX 602 ; N uni259A ; G 2444 +U 9627 ; WX 602 ; N uni259B ; G 2445 +U 9628 ; WX 602 ; N uni259C ; G 2446 +U 9629 ; WX 602 ; N uni259D ; G 2447 +U 9630 ; WX 602 ; N uni259E ; G 2448 +U 9631 ; WX 602 ; N uni259F ; G 2449 +U 9632 ; WX 602 ; N filledbox ; G 2450 +U 9633 ; WX 602 ; N H22073 ; G 2451 +U 9634 ; WX 602 ; N uni25A2 ; G 2452 +U 9635 ; WX 602 ; N uni25A3 ; G 2453 +U 9636 ; WX 602 ; N uni25A4 ; G 2454 +U 9637 ; WX 602 ; N uni25A5 ; G 2455 +U 9638 ; WX 602 ; N uni25A6 ; G 2456 +U 9639 ; WX 602 ; N uni25A7 ; G 2457 +U 9640 ; WX 602 ; N uni25A8 ; G 2458 +U 9641 ; WX 602 ; N uni25A9 ; G 2459 +U 9642 ; WX 602 ; N H18543 ; G 2460 +U 9643 ; WX 602 ; N H18551 ; G 2461 +U 9644 ; WX 602 ; N filledrect ; G 2462 +U 9645 ; WX 602 ; N uni25AD ; G 2463 +U 9646 ; WX 602 ; N uni25AE ; G 2464 +U 9647 ; WX 602 ; N uni25AF ; G 2465 +U 9648 ; WX 602 ; N uni25B0 ; G 2466 +U 9649 ; WX 602 ; N uni25B1 ; G 2467 +U 9650 ; WX 602 ; N triagup ; G 2468 +U 9651 ; WX 602 ; N uni25B3 ; G 2469 +U 9652 ; WX 602 ; N uni25B4 ; G 2470 +U 9653 ; WX 602 ; N uni25B5 ; G 2471 +U 9654 ; WX 602 ; N uni25B6 ; G 2472 +U 9655 ; WX 602 ; N uni25B7 ; G 2473 +U 9656 ; WX 602 ; N uni25B8 ; G 2474 +U 9657 ; WX 602 ; N uni25B9 ; G 2475 +U 9658 ; WX 602 ; N triagrt ; G 2476 +U 9659 ; WX 602 ; N uni25BB ; G 2477 +U 9660 ; WX 602 ; N triagdn ; G 2478 +U 9661 ; WX 602 ; N uni25BD ; G 2479 +U 9662 ; WX 602 ; N uni25BE ; G 2480 +U 9663 ; WX 602 ; N uni25BF ; G 2481 +U 9664 ; WX 602 ; N uni25C0 ; G 2482 +U 9665 ; WX 602 ; N uni25C1 ; G 2483 +U 9666 ; WX 602 ; N uni25C2 ; G 2484 +U 9667 ; WX 602 ; N uni25C3 ; G 2485 +U 9668 ; WX 602 ; N triaglf ; G 2486 +U 9669 ; WX 602 ; N uni25C5 ; G 2487 +U 9670 ; WX 602 ; N uni25C6 ; G 2488 +U 9671 ; WX 602 ; N uni25C7 ; G 2489 +U 9672 ; WX 602 ; N uni25C8 ; G 2490 +U 9673 ; WX 602 ; N uni25C9 ; G 2491 +U 9674 ; WX 602 ; N lozenge ; G 2492 +U 9675 ; WX 602 ; N circle ; G 2493 +U 9676 ; WX 602 ; N uni25CC ; G 2494 +U 9677 ; WX 602 ; N uni25CD ; G 2495 +U 9678 ; WX 602 ; N uni25CE ; G 2496 +U 9679 ; WX 602 ; N H18533 ; G 2497 +U 9680 ; WX 602 ; N uni25D0 ; G 2498 +U 9681 ; WX 602 ; N uni25D1 ; G 2499 +U 9682 ; WX 602 ; N uni25D2 ; G 2500 +U 9683 ; WX 602 ; N uni25D3 ; G 2501 +U 9684 ; WX 602 ; N uni25D4 ; G 2502 +U 9685 ; WX 602 ; N uni25D5 ; G 2503 +U 9686 ; WX 602 ; N uni25D6 ; G 2504 +U 9687 ; WX 602 ; N uni25D7 ; G 2505 +U 9688 ; WX 602 ; N invbullet ; G 2506 +U 9689 ; WX 602 ; N invcircle ; G 2507 +U 9690 ; WX 602 ; N uni25DA ; G 2508 +U 9691 ; WX 602 ; N uni25DB ; G 2509 +U 9692 ; WX 602 ; N uni25DC ; G 2510 +U 9693 ; WX 602 ; N uni25DD ; G 2511 +U 9694 ; WX 602 ; N uni25DE ; G 2512 +U 9695 ; WX 602 ; N uni25DF ; G 2513 +U 9696 ; WX 602 ; N uni25E0 ; G 2514 +U 9697 ; WX 602 ; N uni25E1 ; G 2515 +U 9698 ; WX 602 ; N uni25E2 ; G 2516 +U 9699 ; WX 602 ; N uni25E3 ; G 2517 +U 9700 ; WX 602 ; N uni25E4 ; G 2518 +U 9701 ; WX 602 ; N uni25E5 ; G 2519 +U 9702 ; WX 602 ; N openbullet ; G 2520 +U 9703 ; WX 602 ; N uni25E7 ; G 2521 +U 9704 ; WX 602 ; N uni25E8 ; G 2522 +U 9705 ; WX 602 ; N uni25E9 ; G 2523 +U 9706 ; WX 602 ; N uni25EA ; G 2524 +U 9707 ; WX 602 ; N uni25EB ; G 2525 +U 9708 ; WX 602 ; N uni25EC ; G 2526 +U 9709 ; WX 602 ; N uni25ED ; G 2527 +U 9710 ; WX 602 ; N uni25EE ; G 2528 +U 9711 ; WX 602 ; N uni25EF ; G 2529 +U 9712 ; WX 602 ; N uni25F0 ; G 2530 +U 9713 ; WX 602 ; N uni25F1 ; G 2531 +U 9714 ; WX 602 ; N uni25F2 ; G 2532 +U 9715 ; WX 602 ; N uni25F3 ; G 2533 +U 9716 ; WX 602 ; N uni25F4 ; G 2534 +U 9717 ; WX 602 ; N uni25F5 ; G 2535 +U 9718 ; WX 602 ; N uni25F6 ; G 2536 +U 9719 ; WX 602 ; N uni25F7 ; G 2537 +U 9720 ; WX 602 ; N uni25F8 ; G 2538 +U 9721 ; WX 602 ; N uni25F9 ; G 2539 +U 9722 ; WX 602 ; N uni25FA ; G 2540 +U 9723 ; WX 602 ; N uni25FB ; G 2541 +U 9724 ; WX 602 ; N uni25FC ; G 2542 +U 9725 ; WX 602 ; N uni25FD ; G 2543 +U 9726 ; WX 602 ; N uni25FE ; G 2544 +U 9727 ; WX 602 ; N uni25FF ; G 2545 +U 9728 ; WX 602 ; N uni2600 ; G 2546 +U 9784 ; WX 602 ; N uni2638 ; G 2547 +U 9785 ; WX 602 ; N uni2639 ; G 2548 +U 9786 ; WX 602 ; N smileface ; G 2549 +U 9787 ; WX 602 ; N invsmileface ; G 2550 +U 9788 ; WX 602 ; N sun ; G 2551 +U 9791 ; WX 602 ; N uni263F ; G 2552 +U 9792 ; WX 602 ; N female ; G 2553 +U 9793 ; WX 602 ; N uni2641 ; G 2554 +U 9794 ; WX 602 ; N male ; G 2555 +U 9795 ; WX 602 ; N uni2643 ; G 2556 +U 9796 ; WX 602 ; N uni2644 ; G 2557 +U 9797 ; WX 602 ; N uni2645 ; G 2558 +U 9798 ; WX 602 ; N uni2646 ; G 2559 +U 9799 ; WX 602 ; N uni2647 ; G 2560 +U 9824 ; WX 602 ; N spade ; G 2561 +U 9825 ; WX 602 ; N uni2661 ; G 2562 +U 9826 ; WX 602 ; N uni2662 ; G 2563 +U 9827 ; WX 602 ; N club ; G 2564 +U 9828 ; WX 602 ; N uni2664 ; G 2565 +U 9829 ; WX 602 ; N heart ; G 2566 +U 9830 ; WX 602 ; N diamond ; G 2567 +U 9831 ; WX 602 ; N uni2667 ; G 2568 +U 9833 ; WX 602 ; N uni2669 ; G 2569 +U 9834 ; WX 602 ; N musicalnote ; G 2570 +U 9835 ; WX 602 ; N musicalnotedbl ; G 2571 +U 9836 ; WX 602 ; N uni266C ; G 2572 +U 9837 ; WX 602 ; N uni266D ; G 2573 +U 9838 ; WX 602 ; N uni266E ; G 2574 +U 9839 ; WX 602 ; N uni266F ; G 2575 +U 10178 ; WX 602 ; N uni27C2 ; G 2576 +U 10181 ; WX 602 ; N uni27C5 ; G 2577 +U 10182 ; WX 602 ; N uni27C6 ; G 2578 +U 10204 ; WX 602 ; N uni27DC ; G 2579 +U 10208 ; WX 602 ; N uni27E0 ; G 2580 +U 10214 ; WX 602 ; N uni27E6 ; G 2581 +U 10215 ; WX 602 ; N uni27E7 ; G 2582 +U 10216 ; WX 602 ; N uni27E8 ; G 2583 +U 10217 ; WX 602 ; N uni27E9 ; G 2584 +U 10218 ; WX 602 ; N uni27EA ; G 2585 +U 10219 ; WX 602 ; N uni27EB ; G 2586 +U 10229 ; WX 602 ; N uni27F5 ; G 2587 +U 10230 ; WX 602 ; N uni27F6 ; G 2588 +U 10231 ; WX 602 ; N uni27F7 ; G 2589 +U 10631 ; WX 602 ; N uni2987 ; G 2590 +U 10632 ; WX 602 ; N uni2988 ; G 2591 +U 10647 ; WX 602 ; N uni2997 ; G 2592 +U 10648 ; WX 602 ; N uni2998 ; G 2593 +U 10731 ; WX 602 ; N uni29EB ; G 2594 +U 10746 ; WX 602 ; N uni29FA ; G 2595 +U 10747 ; WX 602 ; N uni29FB ; G 2596 +U 10752 ; WX 602 ; N uni2A00 ; G 2597 +U 10799 ; WX 602 ; N uni2A2F ; G 2598 +U 10858 ; WX 602 ; N uni2A6A ; G 2599 +U 10859 ; WX 602 ; N uni2A6B ; G 2600 +U 11013 ; WX 602 ; N uni2B05 ; G 2601 +U 11014 ; WX 602 ; N uni2B06 ; G 2602 +U 11015 ; WX 602 ; N uni2B07 ; G 2603 +U 11016 ; WX 602 ; N uni2B08 ; G 2604 +U 11017 ; WX 602 ; N uni2B09 ; G 2605 +U 11018 ; WX 602 ; N uni2B0A ; G 2606 +U 11019 ; WX 602 ; N uni2B0B ; G 2607 +U 11020 ; WX 602 ; N uni2B0C ; G 2608 +U 11021 ; WX 602 ; N uni2B0D ; G 2609 +U 11026 ; WX 602 ; N uni2B12 ; G 2610 +U 11027 ; WX 602 ; N uni2B13 ; G 2611 +U 11028 ; WX 602 ; N uni2B14 ; G 2612 +U 11029 ; WX 602 ; N uni2B15 ; G 2613 +U 11030 ; WX 602 ; N uni2B16 ; G 2614 +U 11031 ; WX 602 ; N uni2B17 ; G 2615 +U 11032 ; WX 602 ; N uni2B18 ; G 2616 +U 11033 ; WX 602 ; N uni2B19 ; G 2617 +U 11034 ; WX 602 ; N uni2B1A ; G 2618 +U 11364 ; WX 602 ; N uni2C64 ; G 2619 +U 11373 ; WX 602 ; N uni2C6D ; G 2620 +U 11374 ; WX 602 ; N uni2C6E ; G 2621 +U 11375 ; WX 602 ; N uni2C6F ; G 2622 +U 11376 ; WX 602 ; N uni2C70 ; G 2623 +U 11381 ; WX 602 ; N uni2C75 ; G 2624 +U 11382 ; WX 602 ; N uni2C76 ; G 2625 +U 11383 ; WX 602 ; N uni2C77 ; G 2626 +U 11385 ; WX 602 ; N uni2C79 ; G 2627 +U 11386 ; WX 602 ; N uni2C7A ; G 2628 +U 11388 ; WX 602 ; N uni2C7C ; G 2629 +U 11389 ; WX 602 ; N uni2C7D ; G 2630 +U 11390 ; WX 602 ; N uni2C7E ; G 2631 +U 11391 ; WX 602 ; N uni2C7F ; G 2632 +U 11800 ; WX 602 ; N uni2E18 ; G 2633 +U 11807 ; WX 602 ; N uni2E1F ; G 2634 +U 11810 ; WX 602 ; N uni2E22 ; G 2635 +U 11811 ; WX 602 ; N uni2E23 ; G 2636 +U 11812 ; WX 602 ; N uni2E24 ; G 2637 +U 11813 ; WX 602 ; N uni2E25 ; G 2638 +U 11822 ; WX 602 ; N uni2E2E ; G 2639 +U 42760 ; WX 602 ; N uniA708 ; G 2640 +U 42761 ; WX 602 ; N uniA709 ; G 2641 +U 42762 ; WX 602 ; N uniA70A ; G 2642 +U 42763 ; WX 602 ; N uniA70B ; G 2643 +U 42764 ; WX 602 ; N uniA70C ; G 2644 +U 42765 ; WX 602 ; N uniA70D ; G 2645 +U 42766 ; WX 602 ; N uniA70E ; G 2646 +U 42767 ; WX 602 ; N uniA70F ; G 2647 +U 42768 ; WX 602 ; N uniA710 ; G 2648 +U 42769 ; WX 602 ; N uniA711 ; G 2649 +U 42770 ; WX 602 ; N uniA712 ; G 2650 +U 42771 ; WX 602 ; N uniA713 ; G 2651 +U 42772 ; WX 602 ; N uniA714 ; G 2652 +U 42773 ; WX 602 ; N uniA715 ; G 2653 +U 42774 ; WX 602 ; N uniA716 ; G 2654 +U 42779 ; WX 602 ; N uniA71B ; G 2655 +U 42780 ; WX 602 ; N uniA71C ; G 2656 +U 42781 ; WX 602 ; N uniA71D ; G 2657 +U 42782 ; WX 602 ; N uniA71E ; G 2658 +U 42783 ; WX 602 ; N uniA71F ; G 2659 +U 42786 ; WX 602 ; N uniA722 ; G 2660 +U 42787 ; WX 602 ; N uniA723 ; G 2661 +U 42788 ; WX 602 ; N uniA724 ; G 2662 +U 42789 ; WX 602 ; N uniA725 ; G 2663 +U 42790 ; WX 602 ; N uniA726 ; G 2664 +U 42791 ; WX 602 ; N uniA727 ; G 2665 +U 42889 ; WX 602 ; N uniA789 ; G 2666 +U 42890 ; WX 602 ; N uniA78A ; G 2667 +U 42891 ; WX 602 ; N uniA78B ; G 2668 +U 42892 ; WX 602 ; N uniA78C ; G 2669 +U 42893 ; WX 602 ; N uniA78D ; G 2670 +U 42894 ; WX 602 ; N uniA78E ; G 2671 +U 42896 ; WX 602 ; N uniA790 ; G 2672 +U 42897 ; WX 602 ; N uniA791 ; G 2673 +U 42922 ; WX 602 ; N uniA7AA ; G 2674 +U 43000 ; WX 602 ; N uniA7F8 ; G 2675 +U 43001 ; WX 602 ; N uniA7F9 ; G 2676 +U 63173 ; WX 602 ; N uniF6C5 ; G 2677 +U 64257 ; WX 602 ; N fi ; G 2678 +U 64258 ; WX 602 ; N fl ; G 2679 +U 65529 ; WX 602 ; N uniFFF9 ; G 2680 +U 65530 ; WX 602 ; N uniFFFA ; G 2681 +U 65531 ; WX 602 ; N uniFFFB ; G 2682 +U 65532 ; WX 602 ; N uniFFFC ; G 2683 +U 65533 ; WX 602 ; N uniFFFD ; G 2684 +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..4c858d401ad72117f18a29a9b5b9348ee7a51aba GIT binary patch literal 251932 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[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 Yk2qnm_5Kh48}NT<>;J2%6$cFXA4Aln1^@s6 literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ufm new file mode 100644 index 0000000..4cd3d2a --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono-Oblique.ufm @@ -0,0 +1,2707 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans Mono +FontSubfamily Oblique +UniqueID DejaVu Sans Mono Oblique +FullName DejaVu Sans Mono Oblique +Version Version 2.37 +PostScriptName DejaVuSansMono-Oblique +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +Weight Medium +ItalicAngle -11 +IsFixedPitch true +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -403 -375 746 998 +StartCharMetrics 2710 +U 32 ; WX 602 ; N space ; G 3 +U 33 ; WX 602 ; N exclam ; G 4 +U 34 ; WX 602 ; N quotedbl ; G 5 +U 35 ; WX 602 ; N numbersign ; G 6 +U 36 ; WX 602 ; N dollar ; G 7 +U 37 ; WX 602 ; N percent ; G 8 +U 38 ; WX 602 ; N ampersand ; G 9 +U 39 ; WX 602 ; N quotesingle ; G 10 +U 40 ; WX 602 ; N parenleft ; G 11 +U 41 ; WX 602 ; N parenright ; G 12 +U 42 ; WX 602 ; N asterisk ; G 13 +U 43 ; WX 602 ; N plus ; G 14 +U 44 ; WX 602 ; N comma ; G 15 +U 45 ; WX 602 ; N hyphen ; G 16 +U 46 ; WX 602 ; N period ; G 17 +U 47 ; WX 602 ; N slash ; G 18 +U 48 ; WX 602 ; N zero ; G 19 +U 49 ; WX 602 ; N one ; G 20 +U 50 ; WX 602 ; N two ; G 21 +U 51 ; WX 602 ; N three ; G 22 +U 52 ; WX 602 ; N four ; G 23 +U 53 ; WX 602 ; N five ; G 24 +U 54 ; WX 602 ; N six ; G 25 +U 55 ; WX 602 ; N seven ; G 26 +U 56 ; WX 602 ; N eight ; G 27 +U 57 ; WX 602 ; N nine ; G 28 +U 58 ; WX 602 ; N colon ; G 29 +U 59 ; WX 602 ; N semicolon ; G 30 +U 60 ; WX 602 ; N less ; G 31 +U 61 ; WX 602 ; N equal ; G 32 +U 62 ; WX 602 ; N greater ; G 33 +U 63 ; WX 602 ; N question ; G 34 +U 64 ; WX 602 ; N at ; G 35 +U 65 ; WX 602 ; N A ; G 36 +U 66 ; WX 602 ; N B ; G 37 +U 67 ; WX 602 ; N C ; G 38 +U 68 ; WX 602 ; N D ; G 39 +U 69 ; WX 602 ; N E ; G 40 +U 70 ; WX 602 ; N F ; G 41 +U 71 ; WX 602 ; N G ; G 42 +U 72 ; WX 602 ; N H ; G 43 +U 73 ; WX 602 ; N I ; G 44 +U 74 ; WX 602 ; N J ; G 45 +U 75 ; WX 602 ; N K ; G 46 +U 76 ; WX 602 ; N L ; G 47 +U 77 ; WX 602 ; N M ; G 48 +U 78 ; WX 602 ; N N ; G 49 +U 79 ; WX 602 ; N O ; G 50 +U 80 ; WX 602 ; N P ; G 51 +U 81 ; WX 602 ; N Q ; G 52 +U 82 ; WX 602 ; N R ; G 53 +U 83 ; WX 602 ; N S ; G 54 +U 84 ; WX 602 ; N T ; G 55 +U 85 ; WX 602 ; N U ; G 56 +U 86 ; WX 602 ; N V ; G 57 +U 87 ; WX 602 ; N W ; G 58 +U 88 ; WX 602 ; N X ; G 59 +U 89 ; WX 602 ; N Y ; G 60 +U 90 ; WX 602 ; N Z ; G 61 +U 91 ; WX 602 ; N bracketleft ; G 62 +U 92 ; WX 602 ; N backslash ; G 63 +U 93 ; WX 602 ; N bracketright ; G 64 +U 94 ; WX 602 ; N asciicircum ; G 65 +U 95 ; WX 602 ; N underscore ; G 66 +U 96 ; WX 602 ; N grave ; G 67 +U 97 ; WX 602 ; N a ; G 68 +U 98 ; WX 602 ; N b ; G 69 +U 99 ; WX 602 ; N c ; G 70 +U 100 ; WX 602 ; N d ; G 71 +U 101 ; WX 602 ; N e ; G 72 +U 102 ; WX 602 ; N f ; G 73 +U 103 ; WX 602 ; N g ; G 74 +U 104 ; WX 602 ; N h ; G 75 +U 105 ; WX 602 ; N i ; G 76 +U 106 ; WX 602 ; N j ; G 77 +U 107 ; WX 602 ; N k ; G 78 +U 108 ; WX 602 ; N l ; G 79 +U 109 ; WX 602 ; N m ; G 80 +U 110 ; WX 602 ; N n ; G 81 +U 111 ; WX 602 ; N o ; G 82 +U 112 ; WX 602 ; N p ; G 83 +U 113 ; WX 602 ; N q ; G 84 +U 114 ; WX 602 ; N r ; G 85 +U 115 ; WX 602 ; N s ; G 86 +U 116 ; WX 602 ; N t ; G 87 +U 117 ; WX 602 ; N u ; G 88 +U 118 ; WX 602 ; N v ; G 89 +U 119 ; WX 602 ; N w ; G 90 +U 120 ; WX 602 ; N x ; G 91 +U 121 ; WX 602 ; N y ; G 92 +U 122 ; WX 602 ; N z ; G 93 +U 123 ; WX 602 ; N braceleft ; G 94 +U 124 ; WX 602 ; N bar ; G 95 +U 125 ; WX 602 ; N braceright ; G 96 +U 126 ; WX 602 ; N asciitilde ; G 97 +U 160 ; WX 602 ; N nbspace ; G 98 +U 161 ; WX 602 ; N exclamdown ; G 99 +U 162 ; WX 602 ; N cent ; G 100 +U 163 ; WX 602 ; N sterling ; G 101 +U 164 ; WX 602 ; N currency ; G 102 +U 165 ; WX 602 ; N yen ; G 103 +U 166 ; WX 602 ; N brokenbar ; G 104 +U 167 ; WX 602 ; N section ; G 105 +U 168 ; WX 602 ; N dieresis ; G 106 +U 169 ; WX 602 ; N copyright ; G 107 +U 170 ; WX 602 ; N ordfeminine ; G 108 +U 171 ; WX 602 ; N guillemotleft ; G 109 +U 172 ; WX 602 ; N logicalnot ; G 110 +U 173 ; WX 602 ; N sfthyphen ; G 111 +U 174 ; WX 602 ; N registered ; G 112 +U 175 ; WX 602 ; N macron ; G 113 +U 176 ; WX 602 ; N degree ; G 114 +U 177 ; WX 602 ; N plusminus ; G 115 +U 178 ; WX 602 ; N twosuperior ; G 116 +U 179 ; WX 602 ; N threesuperior ; G 117 +U 180 ; WX 602 ; N acute ; G 118 +U 181 ; WX 602 ; N mu ; G 119 +U 182 ; WX 602 ; N paragraph ; G 120 +U 183 ; WX 602 ; N periodcentered ; G 121 +U 184 ; WX 602 ; N cedilla ; G 122 +U 185 ; WX 602 ; N onesuperior ; G 123 +U 186 ; WX 602 ; N ordmasculine ; G 124 +U 187 ; WX 602 ; N guillemotright ; G 125 +U 188 ; WX 602 ; N onequarter ; G 126 +U 189 ; WX 602 ; N onehalf ; G 127 +U 190 ; WX 602 ; N threequarters ; G 128 +U 191 ; WX 602 ; N questiondown ; G 129 +U 192 ; WX 602 ; N Agrave ; G 130 +U 193 ; WX 602 ; N Aacute ; G 131 +U 194 ; WX 602 ; N Acircumflex ; G 132 +U 195 ; WX 602 ; N Atilde ; G 133 +U 196 ; WX 602 ; N Adieresis ; G 134 +U 197 ; WX 602 ; N Aring ; G 135 +U 198 ; WX 602 ; N AE ; G 136 +U 199 ; WX 602 ; N Ccedilla ; G 137 +U 200 ; WX 602 ; N Egrave ; G 138 +U 201 ; WX 602 ; N Eacute ; G 139 +U 202 ; WX 602 ; N Ecircumflex ; G 140 +U 203 ; WX 602 ; N Edieresis ; G 141 +U 204 ; WX 602 ; N Igrave ; G 142 +U 205 ; WX 602 ; N Iacute ; G 143 +U 206 ; WX 602 ; N Icircumflex ; G 144 +U 207 ; WX 602 ; N Idieresis ; G 145 +U 208 ; WX 602 ; N Eth ; G 146 +U 209 ; WX 602 ; N Ntilde ; G 147 +U 210 ; WX 602 ; N Ograve ; G 148 +U 211 ; WX 602 ; N Oacute ; G 149 +U 212 ; WX 602 ; N Ocircumflex ; G 150 +U 213 ; WX 602 ; N Otilde ; G 151 +U 214 ; WX 602 ; N Odieresis ; G 152 +U 215 ; WX 602 ; N multiply ; G 153 +U 216 ; WX 602 ; N Oslash ; G 154 +U 217 ; WX 602 ; N Ugrave ; G 155 +U 218 ; WX 602 ; N Uacute ; G 156 +U 219 ; WX 602 ; N Ucircumflex ; G 157 +U 220 ; WX 602 ; N Udieresis ; G 158 +U 221 ; WX 602 ; N Yacute ; G 159 +U 222 ; WX 602 ; N Thorn ; G 160 +U 223 ; WX 602 ; N germandbls ; G 161 +U 224 ; WX 602 ; N agrave ; G 162 +U 225 ; WX 602 ; N aacute ; G 163 +U 226 ; WX 602 ; N acircumflex ; G 164 +U 227 ; WX 602 ; N atilde ; G 165 +U 228 ; WX 602 ; N adieresis ; G 166 +U 229 ; WX 602 ; N aring ; G 167 +U 230 ; WX 602 ; N ae ; G 168 +U 231 ; WX 602 ; N ccedilla ; G 169 +U 232 ; WX 602 ; N egrave ; G 170 +U 233 ; WX 602 ; N eacute ; G 171 +U 234 ; WX 602 ; N ecircumflex ; G 172 +U 235 ; WX 602 ; N edieresis ; G 173 +U 236 ; WX 602 ; N igrave ; G 174 +U 237 ; WX 602 ; N iacute ; G 175 +U 238 ; WX 602 ; N icircumflex ; G 176 +U 239 ; WX 602 ; N idieresis ; G 177 +U 240 ; WX 602 ; N eth ; G 178 +U 241 ; WX 602 ; N ntilde ; G 179 +U 242 ; WX 602 ; N ograve ; G 180 +U 243 ; WX 602 ; N oacute ; G 181 +U 244 ; WX 602 ; N ocircumflex ; G 182 +U 245 ; WX 602 ; N otilde ; G 183 +U 246 ; WX 602 ; N odieresis ; G 184 +U 247 ; WX 602 ; N divide ; G 185 +U 248 ; WX 602 ; N oslash ; G 186 +U 249 ; WX 602 ; N ugrave ; G 187 +U 250 ; WX 602 ; N uacute ; G 188 +U 251 ; WX 602 ; N ucircumflex ; G 189 +U 252 ; WX 602 ; N udieresis ; G 190 +U 253 ; WX 602 ; N yacute ; G 191 +U 254 ; WX 602 ; N thorn ; G 192 +U 255 ; WX 602 ; N ydieresis ; G 193 +U 256 ; WX 602 ; N Amacron ; G 194 +U 257 ; WX 602 ; N amacron ; G 195 +U 258 ; WX 602 ; N Abreve ; G 196 +U 259 ; WX 602 ; N abreve ; G 197 +U 260 ; WX 602 ; N Aogonek ; G 198 +U 261 ; WX 602 ; N aogonek ; G 199 +U 262 ; WX 602 ; N Cacute ; G 200 +U 263 ; WX 602 ; N cacute ; G 201 +U 264 ; WX 602 ; N Ccircumflex ; G 202 +U 265 ; WX 602 ; N ccircumflex ; G 203 +U 266 ; WX 602 ; N Cdotaccent ; G 204 +U 267 ; WX 602 ; N cdotaccent ; G 205 +U 268 ; WX 602 ; N Ccaron ; G 206 +U 269 ; WX 602 ; N ccaron ; G 207 +U 270 ; WX 602 ; N Dcaron ; G 208 +U 271 ; WX 602 ; N dcaron ; G 209 +U 272 ; WX 602 ; N Dcroat ; G 210 +U 273 ; WX 602 ; N dmacron ; G 211 +U 274 ; WX 602 ; N Emacron ; G 212 +U 275 ; WX 602 ; N emacron ; G 213 +U 276 ; WX 602 ; N Ebreve ; G 214 +U 277 ; WX 602 ; N ebreve ; G 215 +U 278 ; WX 602 ; N Edotaccent ; G 216 +U 279 ; WX 602 ; N edotaccent ; G 217 +U 280 ; WX 602 ; N Eogonek ; G 218 +U 281 ; WX 602 ; N eogonek ; G 219 +U 282 ; WX 602 ; N Ecaron ; G 220 +U 283 ; WX 602 ; N ecaron ; G 221 +U 284 ; WX 602 ; N Gcircumflex ; G 222 +U 285 ; WX 602 ; N gcircumflex ; G 223 +U 286 ; WX 602 ; N Gbreve ; G 224 +U 287 ; WX 602 ; N gbreve ; G 225 +U 288 ; WX 602 ; N Gdotaccent ; G 226 +U 289 ; WX 602 ; N gdotaccent ; G 227 +U 290 ; WX 602 ; N Gcommaaccent ; G 228 +U 291 ; WX 602 ; N gcommaaccent ; G 229 +U 292 ; WX 602 ; N Hcircumflex ; G 230 +U 293 ; WX 602 ; N hcircumflex ; G 231 +U 294 ; WX 602 ; N Hbar ; G 232 +U 295 ; WX 602 ; N hbar ; G 233 +U 296 ; WX 602 ; N Itilde ; G 234 +U 297 ; WX 602 ; N itilde ; G 235 +U 298 ; WX 602 ; N Imacron ; G 236 +U 299 ; WX 602 ; N imacron ; G 237 +U 300 ; WX 602 ; N Ibreve ; G 238 +U 301 ; WX 602 ; N ibreve ; G 239 +U 302 ; WX 602 ; N Iogonek ; G 240 +U 303 ; WX 602 ; N iogonek ; G 241 +U 304 ; WX 602 ; N Idot ; G 242 +U 305 ; WX 602 ; N dotlessi ; G 243 +U 306 ; WX 602 ; N IJ ; G 244 +U 307 ; WX 602 ; N ij ; G 245 +U 308 ; WX 602 ; N Jcircumflex ; G 246 +U 309 ; WX 602 ; N jcircumflex ; G 247 +U 310 ; WX 602 ; N Kcommaaccent ; G 248 +U 311 ; WX 602 ; N kcommaaccent ; G 249 +U 312 ; WX 602 ; N kgreenlandic ; G 250 +U 313 ; WX 602 ; N Lacute ; G 251 +U 314 ; WX 602 ; N lacute ; G 252 +U 315 ; WX 602 ; N Lcommaaccent ; G 253 +U 316 ; WX 602 ; N lcommaaccent ; G 254 +U 317 ; WX 602 ; N Lcaron ; G 255 +U 318 ; WX 602 ; N lcaron ; G 256 +U 319 ; WX 602 ; N Ldot ; G 257 +U 320 ; WX 602 ; N ldot ; G 258 +U 321 ; WX 602 ; N Lslash ; G 259 +U 322 ; WX 602 ; N lslash ; G 260 +U 323 ; WX 602 ; N Nacute ; G 261 +U 324 ; WX 602 ; N nacute ; G 262 +U 325 ; WX 602 ; N Ncommaaccent ; G 263 +U 326 ; WX 602 ; N ncommaaccent ; G 264 +U 327 ; WX 602 ; N Ncaron ; G 265 +U 328 ; WX 602 ; N ncaron ; G 266 +U 329 ; WX 602 ; N napostrophe ; G 267 +U 330 ; WX 602 ; N Eng ; G 268 +U 331 ; WX 602 ; N eng ; G 269 +U 332 ; WX 602 ; N Omacron ; G 270 +U 333 ; WX 602 ; N omacron ; G 271 +U 334 ; WX 602 ; N Obreve ; G 272 +U 335 ; WX 602 ; N obreve ; G 273 +U 336 ; WX 602 ; N Ohungarumlaut ; G 274 +U 337 ; WX 602 ; N ohungarumlaut ; G 275 +U 338 ; WX 602 ; N OE ; G 276 +U 339 ; WX 602 ; N oe ; G 277 +U 340 ; WX 602 ; N Racute ; G 278 +U 341 ; WX 602 ; N racute ; G 279 +U 342 ; WX 602 ; N Rcommaaccent ; G 280 +U 343 ; WX 602 ; N rcommaaccent ; G 281 +U 344 ; WX 602 ; N Rcaron ; G 282 +U 345 ; WX 602 ; N rcaron ; G 283 +U 346 ; WX 602 ; N Sacute ; G 284 +U 347 ; WX 602 ; N sacute ; G 285 +U 348 ; WX 602 ; N Scircumflex ; G 286 +U 349 ; WX 602 ; N scircumflex ; G 287 +U 350 ; WX 602 ; N Scedilla ; G 288 +U 351 ; WX 602 ; N scedilla ; G 289 +U 352 ; WX 602 ; N Scaron ; G 290 +U 353 ; WX 602 ; N scaron ; G 291 +U 354 ; WX 602 ; N Tcommaaccent ; G 292 +U 355 ; WX 602 ; N tcommaaccent ; G 293 +U 356 ; WX 602 ; N Tcaron ; G 294 +U 357 ; WX 602 ; N tcaron ; G 295 +U 358 ; WX 602 ; N Tbar ; G 296 +U 359 ; WX 602 ; N tbar ; G 297 +U 360 ; WX 602 ; N Utilde ; G 298 +U 361 ; WX 602 ; N utilde ; G 299 +U 362 ; WX 602 ; N Umacron ; G 300 +U 363 ; WX 602 ; N umacron ; G 301 +U 364 ; WX 602 ; N Ubreve ; G 302 +U 365 ; WX 602 ; N ubreve ; G 303 +U 366 ; WX 602 ; N Uring ; G 304 +U 367 ; WX 602 ; N uring ; G 305 +U 368 ; WX 602 ; N Uhungarumlaut ; G 306 +U 369 ; WX 602 ; N uhungarumlaut ; G 307 +U 370 ; WX 602 ; N Uogonek ; G 308 +U 371 ; WX 602 ; N uogonek ; G 309 +U 372 ; WX 602 ; N Wcircumflex ; G 310 +U 373 ; WX 602 ; N wcircumflex ; G 311 +U 374 ; WX 602 ; N Ycircumflex ; G 312 +U 375 ; WX 602 ; N ycircumflex ; G 313 +U 376 ; WX 602 ; N Ydieresis ; G 314 +U 377 ; WX 602 ; N Zacute ; G 315 +U 378 ; WX 602 ; N zacute ; G 316 +U 379 ; WX 602 ; N Zdotaccent ; G 317 +U 380 ; WX 602 ; N zdotaccent ; G 318 +U 381 ; WX 602 ; N Zcaron ; G 319 +U 382 ; WX 602 ; N zcaron ; G 320 +U 383 ; WX 602 ; N longs ; G 321 +U 384 ; WX 602 ; N uni0180 ; G 322 +U 385 ; WX 602 ; N uni0181 ; G 323 +U 386 ; WX 602 ; N uni0182 ; G 324 +U 387 ; WX 602 ; N uni0183 ; G 325 +U 388 ; WX 602 ; N uni0184 ; G 326 +U 389 ; WX 602 ; N uni0185 ; G 327 +U 390 ; WX 602 ; N uni0186 ; G 328 +U 391 ; WX 602 ; N uni0187 ; G 329 +U 392 ; WX 602 ; N uni0188 ; G 330 +U 393 ; WX 602 ; N uni0189 ; G 331 +U 394 ; WX 602 ; N uni018A ; G 332 +U 395 ; WX 602 ; N uni018B ; G 333 +U 396 ; WX 602 ; N uni018C ; G 334 +U 397 ; WX 602 ; N uni018D ; G 335 +U 398 ; WX 602 ; N uni018E ; G 336 +U 399 ; WX 602 ; N uni018F ; G 337 +U 400 ; WX 602 ; N uni0190 ; G 338 +U 401 ; WX 602 ; N uni0191 ; G 339 +U 402 ; WX 602 ; N florin ; G 340 +U 403 ; WX 602 ; N uni0193 ; G 341 +U 404 ; WX 602 ; N uni0194 ; G 342 +U 405 ; WX 602 ; N uni0195 ; G 343 +U 406 ; WX 602 ; N uni0196 ; G 344 +U 407 ; WX 602 ; N uni0197 ; G 345 +U 408 ; WX 602 ; N uni0198 ; G 346 +U 409 ; WX 602 ; N uni0199 ; G 347 +U 410 ; WX 602 ; N uni019A ; G 348 +U 411 ; WX 602 ; N uni019B ; G 349 +U 412 ; WX 602 ; N uni019C ; G 350 +U 413 ; WX 602 ; N uni019D ; G 351 +U 414 ; WX 602 ; N uni019E ; G 352 +U 415 ; WX 602 ; N uni019F ; G 353 +U 416 ; WX 602 ; N Ohorn ; G 354 +U 417 ; WX 602 ; N ohorn ; G 355 +U 418 ; WX 602 ; N uni01A2 ; G 356 +U 419 ; WX 602 ; N uni01A3 ; G 357 +U 420 ; WX 602 ; N uni01A4 ; G 358 +U 421 ; WX 602 ; N uni01A5 ; G 359 +U 422 ; WX 602 ; N uni01A6 ; G 360 +U 423 ; WX 602 ; N uni01A7 ; G 361 +U 424 ; WX 602 ; N uni01A8 ; G 362 +U 425 ; WX 602 ; N uni01A9 ; G 363 +U 426 ; WX 602 ; N uni01AA ; G 364 +U 427 ; WX 602 ; N uni01AB ; G 365 +U 428 ; WX 602 ; N uni01AC ; G 366 +U 429 ; WX 602 ; N uni01AD ; G 367 +U 430 ; WX 602 ; N uni01AE ; G 368 +U 431 ; WX 602 ; N Uhorn ; G 369 +U 432 ; WX 602 ; N uhorn ; G 370 +U 433 ; WX 602 ; N uni01B1 ; G 371 +U 434 ; WX 602 ; N uni01B2 ; G 372 +U 435 ; WX 602 ; N uni01B3 ; G 373 +U 436 ; WX 602 ; N uni01B4 ; G 374 +U 437 ; WX 602 ; N uni01B5 ; G 375 +U 438 ; WX 602 ; N uni01B6 ; G 376 +U 439 ; WX 602 ; N uni01B7 ; G 377 +U 440 ; WX 602 ; N uni01B8 ; G 378 +U 441 ; WX 602 ; N uni01B9 ; G 379 +U 442 ; WX 602 ; N uni01BA ; G 380 +U 443 ; WX 602 ; N uni01BB ; G 381 +U 444 ; WX 602 ; N uni01BC ; G 382 +U 445 ; WX 602 ; N uni01BD ; G 383 +U 446 ; WX 602 ; N uni01BE ; G 384 +U 447 ; WX 602 ; N uni01BF ; G 385 +U 448 ; WX 602 ; N uni01C0 ; G 386 +U 449 ; WX 602 ; N uni01C1 ; G 387 +U 450 ; WX 602 ; N uni01C2 ; G 388 +U 451 ; WX 602 ; N uni01C3 ; G 389 +U 461 ; WX 602 ; N uni01CD ; G 390 +U 462 ; WX 602 ; N uni01CE ; G 391 +U 463 ; WX 602 ; N uni01CF ; G 392 +U 464 ; WX 602 ; N uni01D0 ; G 393 +U 465 ; WX 602 ; N uni01D1 ; G 394 +U 466 ; WX 602 ; N uni01D2 ; G 395 +U 467 ; WX 602 ; N uni01D3 ; G 396 +U 468 ; WX 602 ; N uni01D4 ; G 397 +U 469 ; WX 602 ; N uni01D5 ; G 398 +U 470 ; WX 602 ; N uni01D6 ; G 399 +U 471 ; WX 602 ; N uni01D7 ; G 400 +U 472 ; WX 602 ; N uni01D8 ; G 401 +U 473 ; WX 602 ; N uni01D9 ; G 402 +U 474 ; WX 602 ; N uni01DA ; G 403 +U 475 ; WX 602 ; N uni01DB ; G 404 +U 476 ; WX 602 ; N uni01DC ; G 405 +U 477 ; WX 602 ; N uni01DD ; G 406 +U 479 ; WX 602 ; N uni01DF ; G 407 +U 480 ; WX 602 ; N uni01E0 ; G 408 +U 481 ; WX 602 ; N uni01E1 ; G 409 +U 482 ; WX 602 ; N uni01E2 ; G 410 +U 483 ; WX 602 ; N uni01E3 ; G 411 +U 486 ; WX 602 ; N Gcaron ; G 412 +U 487 ; WX 602 ; N gcaron ; G 413 +U 488 ; WX 602 ; N uni01E8 ; G 414 +U 489 ; WX 602 ; N uni01E9 ; G 415 +U 490 ; WX 602 ; N uni01EA ; G 416 +U 491 ; WX 602 ; N uni01EB ; G 417 +U 492 ; WX 602 ; N uni01EC ; G 418 +U 493 ; WX 602 ; N uni01ED ; G 419 +U 494 ; WX 602 ; N uni01EE ; G 420 +U 495 ; WX 602 ; N uni01EF ; G 421 +U 500 ; WX 602 ; N uni01F4 ; G 422 +U 501 ; WX 602 ; N uni01F5 ; G 423 +U 502 ; WX 602 ; N uni01F6 ; G 424 +U 504 ; WX 602 ; N uni01F8 ; G 425 +U 505 ; WX 602 ; N uni01F9 ; G 426 +U 508 ; WX 602 ; N AEacute ; G 427 +U 509 ; WX 602 ; N aeacute ; G 428 +U 510 ; WX 602 ; N Oslashacute ; G 429 +U 511 ; WX 602 ; N oslashacute ; G 430 +U 512 ; WX 602 ; N uni0200 ; G 431 +U 513 ; WX 602 ; N uni0201 ; G 432 +U 514 ; WX 602 ; N uni0202 ; G 433 +U 515 ; WX 602 ; N uni0203 ; G 434 +U 516 ; WX 602 ; N uni0204 ; G 435 +U 517 ; WX 602 ; N uni0205 ; G 436 +U 518 ; WX 602 ; N uni0206 ; G 437 +U 519 ; WX 602 ; N uni0207 ; G 438 +U 520 ; WX 602 ; N uni0208 ; G 439 +U 521 ; WX 602 ; N uni0209 ; G 440 +U 522 ; WX 602 ; N uni020A ; G 441 +U 523 ; WX 602 ; N uni020B ; G 442 +U 524 ; WX 602 ; N uni020C ; G 443 +U 525 ; WX 602 ; N uni020D ; G 444 +U 526 ; WX 602 ; N uni020E ; G 445 +U 527 ; WX 602 ; N uni020F ; G 446 +U 528 ; WX 602 ; N uni0210 ; G 447 +U 529 ; WX 602 ; N uni0211 ; G 448 +U 530 ; WX 602 ; N uni0212 ; G 449 +U 531 ; WX 602 ; N uni0213 ; G 450 +U 532 ; WX 602 ; N uni0214 ; G 451 +U 533 ; WX 602 ; N uni0215 ; G 452 +U 534 ; WX 602 ; N uni0216 ; G 453 +U 535 ; WX 602 ; N uni0217 ; G 454 +U 536 ; WX 602 ; N Scommaaccent ; G 455 +U 537 ; WX 602 ; N scommaaccent ; G 456 +U 538 ; WX 602 ; N uni021A ; G 457 +U 539 ; WX 602 ; N uni021B ; G 458 +U 540 ; WX 602 ; N uni021C ; G 459 +U 541 ; WX 602 ; N uni021D ; G 460 +U 542 ; WX 602 ; N uni021E ; G 461 +U 543 ; WX 602 ; N uni021F ; G 462 +U 545 ; WX 602 ; N uni0221 ; G 463 +U 548 ; WX 602 ; N uni0224 ; G 464 +U 549 ; WX 602 ; N uni0225 ; G 465 +U 550 ; WX 602 ; N uni0226 ; G 466 +U 551 ; WX 602 ; N uni0227 ; G 467 +U 552 ; WX 602 ; N uni0228 ; G 468 +U 553 ; WX 602 ; N uni0229 ; G 469 +U 554 ; WX 602 ; N uni022A ; G 470 +U 555 ; WX 602 ; N uni022B ; G 471 +U 556 ; WX 602 ; N uni022C ; G 472 +U 557 ; WX 602 ; N uni022D ; G 473 +U 558 ; WX 602 ; N uni022E ; G 474 +U 559 ; WX 602 ; N uni022F ; G 475 +U 560 ; WX 602 ; N uni0230 ; G 476 +U 561 ; WX 602 ; N uni0231 ; G 477 +U 562 ; WX 602 ; N uni0232 ; G 478 +U 563 ; WX 602 ; N uni0233 ; G 479 +U 564 ; WX 602 ; N uni0234 ; G 480 +U 565 ; WX 602 ; N uni0235 ; G 481 +U 566 ; WX 602 ; N uni0236 ; G 482 +U 567 ; WX 602 ; N dotlessj ; G 483 +U 568 ; WX 602 ; N uni0238 ; G 484 +U 569 ; WX 602 ; N uni0239 ; G 485 +U 570 ; WX 602 ; N uni023A ; G 486 +U 571 ; WX 602 ; N uni023B ; G 487 +U 572 ; WX 602 ; N uni023C ; G 488 +U 573 ; WX 602 ; N uni023D ; G 489 +U 574 ; WX 602 ; N uni023E ; G 490 +U 575 ; WX 602 ; N uni023F ; G 491 +U 576 ; WX 602 ; N uni0240 ; G 492 +U 577 ; WX 602 ; N uni0241 ; G 493 +U 579 ; WX 602 ; N uni0243 ; G 494 +U 580 ; WX 602 ; N uni0244 ; G 495 +U 581 ; WX 602 ; N uni0245 ; G 496 +U 588 ; WX 602 ; N uni024C ; G 497 +U 589 ; WX 602 ; N uni024D ; G 498 +U 592 ; WX 602 ; N uni0250 ; G 499 +U 593 ; WX 602 ; N uni0251 ; G 500 +U 594 ; WX 602 ; N uni0252 ; G 501 +U 595 ; WX 602 ; N uni0253 ; G 502 +U 596 ; WX 602 ; N uni0254 ; G 503 +U 597 ; WX 602 ; N uni0255 ; G 504 +U 598 ; WX 602 ; N uni0256 ; G 505 +U 599 ; WX 602 ; N uni0257 ; G 506 +U 600 ; WX 602 ; N uni0258 ; G 507 +U 601 ; WX 602 ; N uni0259 ; G 508 +U 602 ; WX 602 ; N uni025A ; G 509 +U 603 ; WX 602 ; N uni025B ; G 510 +U 604 ; WX 602 ; N uni025C ; G 511 +U 605 ; WX 602 ; N uni025D ; G 512 +U 606 ; WX 602 ; N uni025E ; G 513 +U 607 ; WX 602 ; N uni025F ; G 514 +U 608 ; WX 602 ; N uni0260 ; G 515 +U 609 ; WX 602 ; N uni0261 ; G 516 +U 610 ; WX 602 ; N uni0262 ; G 517 +U 611 ; WX 602 ; N uni0263 ; G 518 +U 612 ; WX 602 ; N uni0264 ; G 519 +U 613 ; WX 602 ; N uni0265 ; G 520 +U 614 ; WX 602 ; N uni0266 ; G 521 +U 615 ; WX 602 ; N uni0267 ; G 522 +U 616 ; WX 602 ; N uni0268 ; G 523 +U 617 ; WX 602 ; N uni0269 ; G 524 +U 618 ; WX 602 ; N uni026A ; G 525 +U 619 ; WX 602 ; N uni026B ; G 526 +U 620 ; WX 602 ; N uni026C ; G 527 +U 621 ; WX 602 ; N uni026D ; G 528 +U 622 ; WX 602 ; N uni026E ; G 529 +U 623 ; WX 602 ; N uni026F ; G 530 +U 624 ; WX 602 ; N uni0270 ; G 531 +U 625 ; WX 602 ; N uni0271 ; G 532 +U 626 ; WX 602 ; N uni0272 ; G 533 +U 627 ; WX 602 ; N uni0273 ; G 534 +U 628 ; WX 602 ; N uni0274 ; G 535 +U 629 ; WX 602 ; N uni0275 ; G 536 +U 630 ; WX 602 ; N uni0276 ; G 537 +U 631 ; WX 602 ; N uni0277 ; G 538 +U 632 ; WX 602 ; N uni0278 ; G 539 +U 633 ; WX 602 ; N uni0279 ; G 540 +U 634 ; WX 602 ; N uni027A ; G 541 +U 635 ; WX 602 ; N uni027B ; G 542 +U 636 ; WX 602 ; N uni027C ; G 543 +U 637 ; WX 602 ; N uni027D ; G 544 +U 638 ; WX 602 ; N uni027E ; G 545 +U 639 ; WX 602 ; N uni027F ; G 546 +U 640 ; WX 602 ; N uni0280 ; G 547 +U 641 ; WX 602 ; N uni0281 ; G 548 +U 642 ; WX 602 ; N uni0282 ; G 549 +U 643 ; WX 602 ; N uni0283 ; G 550 +U 644 ; WX 602 ; N uni0284 ; G 551 +U 645 ; WX 602 ; N uni0285 ; G 552 +U 646 ; WX 602 ; N uni0286 ; G 553 +U 647 ; WX 602 ; N uni0287 ; G 554 +U 648 ; WX 602 ; N uni0288 ; G 555 +U 649 ; WX 602 ; N uni0289 ; G 556 +U 650 ; WX 602 ; N uni028A ; G 557 +U 651 ; WX 602 ; N uni028B ; G 558 +U 652 ; WX 602 ; N uni028C ; G 559 +U 653 ; WX 602 ; N uni028D ; G 560 +U 654 ; WX 602 ; N uni028E ; G 561 +U 655 ; WX 602 ; N uni028F ; G 562 +U 656 ; WX 602 ; N uni0290 ; G 563 +U 657 ; WX 602 ; N uni0291 ; G 564 +U 658 ; WX 602 ; N uni0292 ; G 565 +U 659 ; WX 602 ; N uni0293 ; G 566 +U 660 ; WX 602 ; N uni0294 ; G 567 +U 661 ; WX 602 ; N uni0295 ; G 568 +U 662 ; WX 602 ; N uni0296 ; G 569 +U 663 ; WX 602 ; N uni0297 ; G 570 +U 664 ; WX 602 ; N uni0298 ; G 571 +U 665 ; WX 602 ; N uni0299 ; G 572 +U 666 ; WX 602 ; N uni029A ; G 573 +U 667 ; WX 602 ; N uni029B ; G 574 +U 668 ; WX 602 ; N uni029C ; G 575 +U 669 ; WX 602 ; N uni029D ; G 576 +U 670 ; WX 602 ; N uni029E ; G 577 +U 671 ; WX 602 ; N uni029F ; G 578 +U 672 ; WX 602 ; N uni02A0 ; G 579 +U 673 ; WX 602 ; N uni02A1 ; G 580 +U 674 ; WX 602 ; N uni02A2 ; G 581 +U 675 ; WX 602 ; N uni02A3 ; G 582 +U 676 ; WX 602 ; N uni02A4 ; G 583 +U 677 ; WX 602 ; N uni02A5 ; G 584 +U 678 ; WX 602 ; N uni02A6 ; G 585 +U 679 ; WX 602 ; N uni02A7 ; G 586 +U 680 ; WX 602 ; N uni02A8 ; G 587 +U 681 ; WX 602 ; N uni02A9 ; G 588 +U 682 ; WX 602 ; N uni02AA ; G 589 +U 683 ; WX 602 ; N uni02AB ; G 590 +U 684 ; WX 602 ; N uni02AC ; G 591 +U 685 ; WX 602 ; N uni02AD ; G 592 +U 686 ; WX 602 ; N uni02AE ; G 593 +U 687 ; WX 602 ; N uni02AF ; G 594 +U 688 ; WX 602 ; N uni02B0 ; G 595 +U 689 ; WX 602 ; N uni02B1 ; G 596 +U 690 ; WX 602 ; N uni02B2 ; G 597 +U 691 ; WX 602 ; N uni02B3 ; G 598 +U 692 ; WX 602 ; N uni02B4 ; G 599 +U 693 ; WX 602 ; N uni02B5 ; G 600 +U 694 ; WX 602 ; N uni02B6 ; G 601 +U 695 ; WX 602 ; N uni02B7 ; G 602 +U 696 ; WX 602 ; N uni02B8 ; G 603 +U 697 ; WX 602 ; N uni02B9 ; G 604 +U 699 ; WX 602 ; N uni02BB ; G 605 +U 700 ; WX 602 ; N uni02BC ; G 606 +U 701 ; WX 602 ; N uni02BD ; G 607 +U 702 ; WX 602 ; N uni02BE ; G 608 +U 703 ; WX 602 ; N uni02BF ; G 609 +U 704 ; WX 602 ; N uni02C0 ; G 610 +U 705 ; WX 602 ; N uni02C1 ; G 611 +U 710 ; WX 602 ; N circumflex ; G 612 +U 711 ; WX 602 ; N caron ; G 613 +U 712 ; WX 602 ; N uni02C8 ; G 614 +U 713 ; WX 602 ; N uni02C9 ; G 615 +U 716 ; WX 602 ; N uni02CC ; G 616 +U 717 ; WX 602 ; N uni02CD ; G 617 +U 718 ; WX 602 ; N uni02CE ; G 618 +U 719 ; WX 602 ; N uni02CF ; G 619 +U 720 ; WX 602 ; N uni02D0 ; G 620 +U 721 ; WX 602 ; N uni02D1 ; G 621 +U 722 ; WX 602 ; N uni02D2 ; G 622 +U 723 ; WX 602 ; N uni02D3 ; G 623 +U 726 ; WX 602 ; N uni02D6 ; G 624 +U 727 ; WX 602 ; N uni02D7 ; G 625 +U 728 ; WX 602 ; N breve ; G 626 +U 729 ; WX 602 ; N dotaccent ; G 627 +U 730 ; WX 602 ; N ring ; G 628 +U 731 ; WX 602 ; N ogonek ; G 629 +U 732 ; WX 602 ; N tilde ; G 630 +U 733 ; WX 602 ; N hungarumlaut ; G 631 +U 734 ; WX 602 ; N uni02DE ; G 632 +U 736 ; WX 602 ; N uni02E0 ; G 633 +U 737 ; WX 602 ; N uni02E1 ; G 634 +U 738 ; WX 602 ; N uni02E2 ; G 635 +U 739 ; WX 602 ; N uni02E3 ; G 636 +U 740 ; WX 602 ; N uni02E4 ; G 637 +U 741 ; WX 602 ; N uni02E5 ; G 638 +U 742 ; WX 602 ; N uni02E6 ; G 639 +U 743 ; WX 602 ; N uni02E7 ; G 640 +U 744 ; WX 602 ; N uni02E8 ; G 641 +U 745 ; WX 602 ; N uni02E9 ; G 642 +U 750 ; WX 602 ; N uni02EE ; G 643 +U 755 ; WX 602 ; N uni02F3 ; G 644 +U 768 ; WX 602 ; N gravecomb ; G 645 +U 769 ; WX 602 ; N acutecomb ; G 646 +U 770 ; WX 602 ; N uni0302 ; G 647 +U 771 ; WX 602 ; N tildecomb ; G 648 +U 772 ; WX 602 ; N uni0304 ; G 649 +U 773 ; WX 602 ; N uni0305 ; G 650 +U 774 ; WX 602 ; N uni0306 ; G 651 +U 775 ; WX 602 ; N uni0307 ; G 652 +U 776 ; WX 602 ; N uni0308 ; G 653 +U 777 ; WX 602 ; N hookabovecomb ; G 654 +U 778 ; WX 602 ; N uni030A ; G 655 +U 779 ; WX 602 ; N uni030B ; G 656 +U 780 ; WX 602 ; N uni030C ; G 657 +U 781 ; WX 602 ; N uni030D ; G 658 +U 782 ; WX 602 ; N uni030E ; G 659 +U 783 ; WX 602 ; N uni030F ; G 660 +U 784 ; WX 602 ; N uni0310 ; G 661 +U 785 ; WX 602 ; N uni0311 ; G 662 +U 786 ; WX 602 ; N uni0312 ; G 663 +U 787 ; WX 602 ; N uni0313 ; G 664 +U 788 ; WX 602 ; N uni0314 ; G 665 +U 789 ; WX 602 ; N uni0315 ; G 666 +U 790 ; WX 602 ; N uni0316 ; G 667 +U 791 ; WX 602 ; N uni0317 ; G 668 +U 792 ; WX 602 ; N uni0318 ; G 669 +U 793 ; WX 602 ; N uni0319 ; G 670 +U 794 ; WX 602 ; N uni031A ; G 671 +U 795 ; WX 602 ; N uni031B ; G 672 +U 796 ; WX 602 ; N uni031C ; G 673 +U 797 ; WX 602 ; N uni031D ; G 674 +U 798 ; WX 602 ; N uni031E ; G 675 +U 799 ; WX 602 ; N uni031F ; G 676 +U 800 ; WX 602 ; N uni0320 ; G 677 +U 801 ; WX 602 ; N uni0321 ; G 678 +U 802 ; WX 602 ; N uni0322 ; G 679 +U 803 ; WX 602 ; N dotbelowcomb ; G 680 +U 804 ; WX 602 ; N uni0324 ; G 681 +U 805 ; WX 602 ; N uni0325 ; G 682 +U 806 ; WX 602 ; N uni0326 ; G 683 +U 807 ; WX 602 ; N uni0327 ; G 684 +U 808 ; WX 602 ; N uni0328 ; G 685 +U 809 ; WX 602 ; N uni0329 ; G 686 +U 810 ; WX 602 ; N uni032A ; G 687 +U 811 ; WX 602 ; N uni032B ; G 688 +U 812 ; WX 602 ; N uni032C ; G 689 +U 813 ; WX 602 ; N uni032D ; G 690 +U 814 ; WX 602 ; N uni032E ; G 691 +U 815 ; WX 602 ; N uni032F ; G 692 +U 816 ; WX 602 ; N uni0330 ; G 693 +U 817 ; WX 602 ; N uni0331 ; G 694 +U 818 ; WX 602 ; N uni0332 ; G 695 +U 819 ; WX 602 ; N uni0333 ; G 696 +U 820 ; WX 602 ; N uni0334 ; G 697 +U 821 ; WX 602 ; N uni0335 ; G 698 +U 822 ; WX 602 ; N uni0336 ; G 699 +U 823 ; WX 602 ; N uni0337 ; G 700 +U 824 ; WX 602 ; N uni0338 ; G 701 +U 825 ; WX 602 ; N uni0339 ; G 702 +U 826 ; WX 602 ; N uni033A ; G 703 +U 827 ; WX 602 ; N uni033B ; G 704 +U 828 ; WX 602 ; N uni033C ; G 705 +U 829 ; WX 602 ; N uni033D ; G 706 +U 830 ; WX 602 ; N uni033E ; G 707 +U 831 ; WX 602 ; N uni033F ; G 708 +U 835 ; WX 602 ; N uni0343 ; G 709 +U 856 ; WX 602 ; N uni0358 ; G 710 +U 865 ; WX 602 ; N uni0361 ; G 711 +U 884 ; WX 602 ; N uni0374 ; G 712 +U 885 ; WX 602 ; N uni0375 ; G 713 +U 886 ; WX 602 ; N uni0376 ; G 714 +U 887 ; WX 602 ; N uni0377 ; G 715 +U 890 ; WX 602 ; N uni037A ; G 716 +U 891 ; WX 602 ; N uni037B ; G 717 +U 892 ; WX 602 ; N uni037C ; G 718 +U 893 ; WX 602 ; N uni037D ; G 719 +U 894 ; WX 602 ; N uni037E ; G 720 +U 895 ; WX 602 ; N uni037F ; G 721 +U 900 ; WX 602 ; N tonos ; G 722 +U 901 ; WX 602 ; N dieresistonos ; G 723 +U 902 ; WX 602 ; N Alphatonos ; G 724 +U 903 ; WX 602 ; N anoteleia ; G 725 +U 904 ; WX 602 ; N Epsilontonos ; G 726 +U 905 ; WX 602 ; N Etatonos ; G 727 +U 906 ; WX 602 ; N Iotatonos ; G 728 +U 908 ; WX 602 ; N Omicrontonos ; G 729 +U 910 ; WX 602 ; N Upsilontonos ; G 730 +U 911 ; WX 602 ; N Omegatonos ; G 731 +U 912 ; WX 602 ; N iotadieresistonos ; G 732 +U 913 ; WX 602 ; N Alpha ; G 733 +U 914 ; WX 602 ; N Beta ; G 734 +U 915 ; WX 602 ; N Gamma ; G 735 +U 916 ; WX 602 ; N uni0394 ; G 736 +U 917 ; WX 602 ; N Epsilon ; G 737 +U 918 ; WX 602 ; N Zeta ; G 738 +U 919 ; WX 602 ; N Eta ; G 739 +U 920 ; WX 602 ; N Theta ; G 740 +U 921 ; WX 602 ; N Iota ; G 741 +U 922 ; WX 602 ; N Kappa ; G 742 +U 923 ; WX 602 ; N Lambda ; G 743 +U 924 ; WX 602 ; N Mu ; G 744 +U 925 ; WX 602 ; N Nu ; G 745 +U 926 ; WX 602 ; N Xi ; G 746 +U 927 ; WX 602 ; N Omicron ; G 747 +U 928 ; WX 602 ; N Pi ; G 748 +U 929 ; WX 602 ; N Rho ; G 749 +U 931 ; WX 602 ; N Sigma ; G 750 +U 932 ; WX 602 ; N Tau ; G 751 +U 933 ; WX 602 ; N Upsilon ; G 752 +U 934 ; WX 602 ; N Phi ; G 753 +U 935 ; WX 602 ; N Chi ; G 754 +U 936 ; WX 602 ; N Psi ; G 755 +U 937 ; WX 602 ; N Omega ; G 756 +U 938 ; WX 602 ; N Iotadieresis ; G 757 +U 939 ; WX 602 ; N Upsilondieresis ; G 758 +U 940 ; WX 602 ; N alphatonos ; G 759 +U 941 ; WX 602 ; N epsilontonos ; G 760 +U 942 ; WX 602 ; N etatonos ; G 761 +U 943 ; WX 602 ; N iotatonos ; G 762 +U 944 ; WX 602 ; N upsilondieresistonos ; G 763 +U 945 ; WX 602 ; N alpha ; G 764 +U 946 ; WX 602 ; N beta ; G 765 +U 947 ; WX 602 ; N gamma ; G 766 +U 948 ; WX 602 ; N delta ; G 767 +U 949 ; WX 602 ; N epsilon ; G 768 +U 950 ; WX 602 ; N zeta ; G 769 +U 951 ; WX 602 ; N eta ; G 770 +U 952 ; WX 602 ; N theta ; G 771 +U 953 ; WX 602 ; N iota ; G 772 +U 954 ; WX 602 ; N kappa ; G 773 +U 955 ; WX 602 ; N lambda ; G 774 +U 956 ; WX 602 ; N uni03BC ; G 775 +U 957 ; WX 602 ; N nu ; G 776 +U 958 ; WX 602 ; N xi ; G 777 +U 959 ; WX 602 ; N omicron ; G 778 +U 960 ; WX 602 ; N pi ; G 779 +U 961 ; WX 602 ; N rho ; G 780 +U 962 ; WX 602 ; N sigma1 ; G 781 +U 963 ; WX 602 ; N sigma ; G 782 +U 964 ; WX 602 ; N tau ; G 783 +U 965 ; WX 602 ; N upsilon ; G 784 +U 966 ; WX 602 ; N phi ; G 785 +U 967 ; WX 602 ; N chi ; G 786 +U 968 ; WX 602 ; N psi ; G 787 +U 969 ; WX 602 ; N omega ; G 788 +U 970 ; WX 602 ; N iotadieresis ; G 789 +U 971 ; WX 602 ; N upsilondieresis ; G 790 +U 972 ; WX 602 ; N omicrontonos ; G 791 +U 973 ; WX 602 ; N upsilontonos ; G 792 +U 974 ; WX 602 ; N omegatonos ; G 793 +U 976 ; WX 602 ; N uni03D0 ; G 794 +U 977 ; WX 602 ; N theta1 ; G 795 +U 978 ; WX 602 ; N Upsilon1 ; G 796 +U 979 ; WX 602 ; N uni03D3 ; G 797 +U 980 ; WX 602 ; N uni03D4 ; G 798 +U 981 ; WX 602 ; N phi1 ; G 799 +U 982 ; WX 602 ; N omega1 ; G 800 +U 983 ; WX 602 ; N uni03D7 ; G 801 +U 984 ; WX 602 ; N uni03D8 ; G 802 +U 985 ; WX 602 ; N uni03D9 ; G 803 +U 986 ; WX 602 ; N uni03DA ; G 804 +U 987 ; WX 602 ; N uni03DB ; G 805 +U 988 ; WX 602 ; N uni03DC ; G 806 +U 989 ; WX 602 ; N uni03DD ; G 807 +U 990 ; WX 602 ; N uni03DE ; G 808 +U 991 ; WX 602 ; N uni03DF ; G 809 +U 992 ; WX 602 ; N uni03E0 ; G 810 +U 993 ; WX 602 ; N uni03E1 ; G 811 +U 1008 ; WX 602 ; N uni03F0 ; G 812 +U 1009 ; WX 602 ; N uni03F1 ; G 813 +U 1010 ; WX 602 ; N uni03F2 ; G 814 +U 1011 ; WX 602 ; N uni03F3 ; G 815 +U 1012 ; WX 602 ; N uni03F4 ; G 816 +U 1013 ; WX 602 ; N uni03F5 ; G 817 +U 1014 ; WX 602 ; N uni03F6 ; G 818 +U 1015 ; WX 602 ; N uni03F7 ; G 819 +U 1016 ; WX 602 ; N uni03F8 ; G 820 +U 1017 ; WX 602 ; N uni03F9 ; G 821 +U 1018 ; WX 602 ; N uni03FA ; G 822 +U 1019 ; WX 602 ; N uni03FB ; G 823 +U 1020 ; WX 602 ; N uni03FC ; G 824 +U 1021 ; WX 602 ; N uni03FD ; G 825 +U 1022 ; WX 602 ; N uni03FE ; G 826 +U 1023 ; WX 602 ; N uni03FF ; G 827 +U 1024 ; WX 602 ; N uni0400 ; G 828 +U 1025 ; WX 602 ; N uni0401 ; G 829 +U 1026 ; WX 602 ; N uni0402 ; G 830 +U 1027 ; WX 602 ; N uni0403 ; G 831 +U 1028 ; WX 602 ; N uni0404 ; G 832 +U 1029 ; WX 602 ; N uni0405 ; G 833 +U 1030 ; WX 602 ; N uni0406 ; G 834 +U 1031 ; WX 602 ; N uni0407 ; G 835 +U 1032 ; WX 602 ; N uni0408 ; G 836 +U 1033 ; WX 602 ; N uni0409 ; G 837 +U 1034 ; WX 602 ; N uni040A ; G 838 +U 1035 ; WX 602 ; N uni040B ; G 839 +U 1036 ; WX 602 ; N uni040C ; G 840 +U 1037 ; WX 602 ; N uni040D ; G 841 +U 1038 ; WX 602 ; N uni040E ; G 842 +U 1039 ; WX 602 ; N uni040F ; G 843 +U 1040 ; WX 602 ; N uni0410 ; G 844 +U 1041 ; WX 602 ; N uni0411 ; G 845 +U 1042 ; WX 602 ; N uni0412 ; G 846 +U 1043 ; WX 602 ; N uni0413 ; G 847 +U 1044 ; WX 602 ; N uni0414 ; G 848 +U 1045 ; WX 602 ; N uni0415 ; G 849 +U 1046 ; WX 602 ; N uni0416 ; G 850 +U 1047 ; WX 602 ; N uni0417 ; G 851 +U 1048 ; WX 602 ; N uni0418 ; G 852 +U 1049 ; WX 602 ; N uni0419 ; G 853 +U 1050 ; WX 602 ; N uni041A ; G 854 +U 1051 ; WX 602 ; N uni041B ; G 855 +U 1052 ; WX 602 ; N uni041C ; G 856 +U 1053 ; WX 602 ; N uni041D ; G 857 +U 1054 ; WX 602 ; N uni041E ; G 858 +U 1055 ; WX 602 ; N uni041F ; G 859 +U 1056 ; WX 602 ; N uni0420 ; G 860 +U 1057 ; WX 602 ; N uni0421 ; G 861 +U 1058 ; WX 602 ; N uni0422 ; G 862 +U 1059 ; WX 602 ; N uni0423 ; G 863 +U 1060 ; WX 602 ; N uni0424 ; G 864 +U 1061 ; WX 602 ; N uni0425 ; G 865 +U 1062 ; WX 602 ; N uni0426 ; G 866 +U 1063 ; WX 602 ; N uni0427 ; G 867 +U 1064 ; WX 602 ; N uni0428 ; G 868 +U 1065 ; WX 602 ; N uni0429 ; G 869 +U 1066 ; WX 602 ; N uni042A ; G 870 +U 1067 ; WX 602 ; N uni042B ; G 871 +U 1068 ; WX 602 ; N uni042C ; G 872 +U 1069 ; WX 602 ; N uni042D ; G 873 +U 1070 ; WX 602 ; N uni042E ; G 874 +U 1071 ; WX 602 ; N uni042F ; G 875 +U 1072 ; WX 602 ; N uni0430 ; G 876 +U 1073 ; WX 602 ; N uni0431 ; G 877 +U 1074 ; WX 602 ; N uni0432 ; G 878 +U 1075 ; WX 602 ; N uni0433 ; G 879 +U 1076 ; WX 602 ; N uni0434 ; G 880 +U 1077 ; WX 602 ; N uni0435 ; G 881 +U 1078 ; WX 602 ; N uni0436 ; G 882 +U 1079 ; WX 602 ; N uni0437 ; G 883 +U 1080 ; WX 602 ; N uni0438 ; G 884 +U 1081 ; WX 602 ; N uni0439 ; G 885 +U 1082 ; WX 602 ; N uni043A ; G 886 +U 1083 ; WX 602 ; N uni043B ; G 887 +U 1084 ; WX 602 ; N uni043C ; G 888 +U 1085 ; WX 602 ; N uni043D ; G 889 +U 1086 ; WX 602 ; N uni043E ; G 890 +U 1087 ; WX 602 ; N uni043F ; G 891 +U 1088 ; WX 602 ; N uni0440 ; G 892 +U 1089 ; WX 602 ; N uni0441 ; G 893 +U 1090 ; WX 602 ; N uni0442 ; G 894 +U 1091 ; WX 602 ; N uni0443 ; G 895 +U 1092 ; WX 602 ; N uni0444 ; G 896 +U 1093 ; WX 602 ; N uni0445 ; G 897 +U 1094 ; WX 602 ; N uni0446 ; G 898 +U 1095 ; WX 602 ; N uni0447 ; G 899 +U 1096 ; WX 602 ; N uni0448 ; G 900 +U 1097 ; WX 602 ; N uni0449 ; G 901 +U 1098 ; WX 602 ; N uni044A ; G 902 +U 1099 ; WX 602 ; N uni044B ; G 903 +U 1100 ; WX 602 ; N uni044C ; G 904 +U 1101 ; WX 602 ; N uni044D ; G 905 +U 1102 ; WX 602 ; N uni044E ; G 906 +U 1103 ; WX 602 ; N uni044F ; G 907 +U 1104 ; WX 602 ; N uni0450 ; G 908 +U 1105 ; WX 602 ; N uni0451 ; G 909 +U 1106 ; WX 602 ; N uni0452 ; G 910 +U 1107 ; WX 602 ; N uni0453 ; G 911 +U 1108 ; WX 602 ; N uni0454 ; G 912 +U 1109 ; WX 602 ; N uni0455 ; G 913 +U 1110 ; WX 602 ; N uni0456 ; G 914 +U 1111 ; WX 602 ; N uni0457 ; G 915 +U 1112 ; WX 602 ; N uni0458 ; G 916 +U 1113 ; WX 602 ; N uni0459 ; G 917 +U 1114 ; WX 602 ; N uni045A ; G 918 +U 1115 ; WX 602 ; N uni045B ; G 919 +U 1116 ; WX 602 ; N uni045C ; G 920 +U 1117 ; WX 602 ; N uni045D ; G 921 +U 1118 ; WX 602 ; N uni045E ; G 922 +U 1119 ; WX 602 ; N uni045F ; G 923 +U 1122 ; WX 602 ; N uni0462 ; G 924 +U 1123 ; WX 602 ; N uni0463 ; G 925 +U 1138 ; WX 602 ; N uni0472 ; G 926 +U 1139 ; WX 602 ; N uni0473 ; G 927 +U 1168 ; WX 602 ; N uni0490 ; G 928 +U 1169 ; WX 602 ; N uni0491 ; G 929 +U 1170 ; WX 602 ; N uni0492 ; G 930 +U 1171 ; WX 602 ; N uni0493 ; G 931 +U 1172 ; WX 602 ; N uni0494 ; G 932 +U 1173 ; WX 602 ; N uni0495 ; G 933 +U 1174 ; WX 602 ; N uni0496 ; G 934 +U 1175 ; WX 602 ; N uni0497 ; G 935 +U 1176 ; WX 602 ; N uni0498 ; G 936 +U 1177 ; WX 602 ; N uni0499 ; G 937 +U 1178 ; WX 602 ; N uni049A ; G 938 +U 1179 ; WX 602 ; N uni049B ; G 939 +U 1186 ; WX 602 ; N uni04A2 ; G 940 +U 1187 ; WX 602 ; N uni04A3 ; G 941 +U 1188 ; WX 602 ; N uni04A4 ; G 942 +U 1189 ; WX 602 ; N uni04A5 ; G 943 +U 1194 ; WX 602 ; N uni04AA ; G 944 +U 1195 ; WX 602 ; N uni04AB ; G 945 +U 1196 ; WX 602 ; N uni04AC ; G 946 +U 1197 ; WX 602 ; N uni04AD ; G 947 +U 1198 ; WX 602 ; N uni04AE ; G 948 +U 1199 ; WX 602 ; N uni04AF ; G 949 +U 1200 ; WX 602 ; N uni04B0 ; G 950 +U 1201 ; WX 602 ; N uni04B1 ; G 951 +U 1202 ; WX 602 ; N uni04B2 ; G 952 +U 1203 ; WX 602 ; N uni04B3 ; G 953 +U 1210 ; WX 602 ; N uni04BA ; G 954 +U 1211 ; WX 602 ; N uni04BB ; G 955 +U 1216 ; WX 602 ; N uni04C0 ; G 956 +U 1217 ; WX 602 ; N uni04C1 ; G 957 +U 1218 ; WX 602 ; N uni04C2 ; G 958 +U 1219 ; WX 602 ; N uni04C3 ; G 959 +U 1220 ; WX 602 ; N uni04C4 ; G 960 +U 1223 ; WX 602 ; N uni04C7 ; G 961 +U 1224 ; WX 602 ; N uni04C8 ; G 962 +U 1227 ; WX 602 ; N uni04CB ; G 963 +U 1228 ; WX 602 ; N uni04CC ; G 964 +U 1231 ; WX 602 ; N uni04CF ; G 965 +U 1232 ; WX 602 ; N uni04D0 ; G 966 +U 1233 ; WX 602 ; N uni04D1 ; G 967 +U 1234 ; WX 602 ; N uni04D2 ; G 968 +U 1235 ; WX 602 ; N uni04D3 ; G 969 +U 1236 ; WX 602 ; N uni04D4 ; G 970 +U 1237 ; WX 602 ; N uni04D5 ; G 971 +U 1238 ; WX 602 ; N uni04D6 ; G 972 +U 1239 ; WX 602 ; N uni04D7 ; G 973 +U 1240 ; WX 602 ; N uni04D8 ; G 974 +U 1241 ; WX 602 ; N uni04D9 ; G 975 +U 1242 ; WX 602 ; N uni04DA ; G 976 +U 1243 ; WX 602 ; N uni04DB ; G 977 +U 1244 ; WX 602 ; N uni04DC ; G 978 +U 1245 ; WX 602 ; N uni04DD ; G 979 +U 1246 ; WX 602 ; N uni04DE ; G 980 +U 1247 ; WX 602 ; N uni04DF ; G 981 +U 1248 ; WX 602 ; N uni04E0 ; G 982 +U 1249 ; WX 602 ; N uni04E1 ; G 983 +U 1250 ; WX 602 ; N uni04E2 ; G 984 +U 1251 ; WX 602 ; N uni04E3 ; G 985 +U 1252 ; WX 602 ; N uni04E4 ; G 986 +U 1253 ; WX 602 ; N uni04E5 ; G 987 +U 1254 ; WX 602 ; N uni04E6 ; G 988 +U 1255 ; WX 602 ; N uni04E7 ; G 989 +U 1256 ; WX 602 ; N uni04E8 ; G 990 +U 1257 ; WX 602 ; N uni04E9 ; G 991 +U 1258 ; WX 602 ; N uni04EA ; G 992 +U 1259 ; WX 602 ; N uni04EB ; G 993 +U 1260 ; WX 602 ; N uni04EC ; G 994 +U 1261 ; WX 602 ; N uni04ED ; G 995 +U 1262 ; WX 602 ; N uni04EE ; G 996 +U 1263 ; WX 602 ; N uni04EF ; G 997 +U 1264 ; WX 602 ; N uni04F0 ; G 998 +U 1265 ; WX 602 ; N uni04F1 ; G 999 +U 1266 ; WX 602 ; N uni04F2 ; G 1000 +U 1267 ; WX 602 ; N uni04F3 ; G 1001 +U 1268 ; WX 602 ; N uni04F4 ; G 1002 +U 1269 ; WX 602 ; N uni04F5 ; G 1003 +U 1270 ; WX 602 ; N uni04F6 ; G 1004 +U 1271 ; WX 602 ; N uni04F7 ; G 1005 +U 1272 ; WX 602 ; N uni04F8 ; G 1006 +U 1273 ; WX 602 ; N uni04F9 ; G 1007 +U 1296 ; WX 602 ; N uni0510 ; G 1008 +U 1297 ; WX 602 ; N uni0511 ; G 1009 +U 1306 ; WX 602 ; N uni051A ; G 1010 +U 1307 ; WX 602 ; N uni051B ; G 1011 +U 1308 ; WX 602 ; N uni051C ; G 1012 +U 1309 ; WX 602 ; N uni051D ; G 1013 +U 1329 ; WX 602 ; N uni0531 ; G 1014 +U 1330 ; WX 602 ; N uni0532 ; G 1015 +U 1331 ; WX 602 ; N uni0533 ; G 1016 +U 1332 ; WX 602 ; N uni0534 ; G 1017 +U 1333 ; WX 602 ; N uni0535 ; G 1018 +U 1334 ; WX 602 ; N uni0536 ; G 1019 +U 1335 ; WX 602 ; N uni0537 ; G 1020 +U 1336 ; WX 602 ; N uni0538 ; G 1021 +U 1337 ; WX 602 ; N uni0539 ; G 1022 +U 1338 ; WX 602 ; N uni053A ; G 1023 +U 1339 ; WX 602 ; N uni053B ; G 1024 +U 1340 ; WX 602 ; N uni053C ; G 1025 +U 1341 ; WX 602 ; N uni053D ; G 1026 +U 1342 ; WX 602 ; N uni053E ; G 1027 +U 1343 ; WX 602 ; N uni053F ; G 1028 +U 1344 ; WX 602 ; N uni0540 ; G 1029 +U 1345 ; WX 602 ; N uni0541 ; G 1030 +U 1346 ; WX 602 ; N uni0542 ; G 1031 +U 1347 ; WX 602 ; N uni0543 ; G 1032 +U 1348 ; WX 602 ; N uni0544 ; G 1033 +U 1349 ; WX 602 ; N uni0545 ; G 1034 +U 1350 ; WX 602 ; N uni0546 ; G 1035 +U 1351 ; WX 602 ; N uni0547 ; G 1036 +U 1352 ; WX 602 ; N uni0548 ; G 1037 +U 1353 ; WX 602 ; N uni0549 ; G 1038 +U 1354 ; WX 602 ; N uni054A ; G 1039 +U 1355 ; WX 602 ; N uni054B ; G 1040 +U 1356 ; WX 602 ; N uni054C ; G 1041 +U 1357 ; WX 602 ; N uni054D ; G 1042 +U 1358 ; WX 602 ; N uni054E ; G 1043 +U 1359 ; WX 602 ; N uni054F ; G 1044 +U 1360 ; WX 602 ; N uni0550 ; G 1045 +U 1361 ; WX 602 ; N uni0551 ; G 1046 +U 1362 ; WX 602 ; N uni0552 ; G 1047 +U 1363 ; WX 602 ; N uni0553 ; G 1048 +U 1364 ; WX 602 ; N uni0554 ; G 1049 +U 1365 ; WX 602 ; N uni0555 ; G 1050 +U 1366 ; WX 602 ; N uni0556 ; G 1051 +U 1369 ; WX 602 ; N uni0559 ; G 1052 +U 1370 ; WX 602 ; N uni055A ; G 1053 +U 1371 ; WX 602 ; N uni055B ; G 1054 +U 1372 ; WX 602 ; N uni055C ; G 1055 +U 1373 ; WX 602 ; N uni055D ; G 1056 +U 1374 ; WX 602 ; N uni055E ; G 1057 +U 1375 ; WX 602 ; N uni055F ; G 1058 +U 1377 ; WX 602 ; N uni0561 ; G 1059 +U 1378 ; WX 602 ; N uni0562 ; G 1060 +U 1379 ; WX 602 ; N uni0563 ; G 1061 +U 1380 ; WX 602 ; N uni0564 ; G 1062 +U 1381 ; WX 602 ; N uni0565 ; G 1063 +U 1382 ; WX 602 ; N uni0566 ; G 1064 +U 1383 ; WX 602 ; N uni0567 ; G 1065 +U 1384 ; WX 602 ; N uni0568 ; G 1066 +U 1385 ; WX 602 ; N uni0569 ; G 1067 +U 1386 ; WX 602 ; N uni056A ; G 1068 +U 1387 ; WX 602 ; N uni056B ; G 1069 +U 1388 ; WX 602 ; N uni056C ; G 1070 +U 1389 ; WX 602 ; N uni056D ; G 1071 +U 1390 ; WX 602 ; N uni056E ; G 1072 +U 1391 ; WX 602 ; N uni056F ; G 1073 +U 1392 ; WX 602 ; N uni0570 ; G 1074 +U 1393 ; WX 602 ; N uni0571 ; G 1075 +U 1394 ; WX 602 ; N uni0572 ; G 1076 +U 1395 ; WX 602 ; N uni0573 ; G 1077 +U 1396 ; WX 602 ; N uni0574 ; G 1078 +U 1397 ; WX 602 ; N uni0575 ; G 1079 +U 1398 ; WX 602 ; N uni0576 ; G 1080 +U 1399 ; WX 602 ; N uni0577 ; G 1081 +U 1400 ; WX 602 ; N uni0578 ; G 1082 +U 1401 ; WX 602 ; N uni0579 ; G 1083 +U 1402 ; WX 602 ; N uni057A ; G 1084 +U 1403 ; WX 602 ; N uni057B ; G 1085 +U 1404 ; WX 602 ; N uni057C ; G 1086 +U 1405 ; WX 602 ; N uni057D ; G 1087 +U 1406 ; WX 602 ; N uni057E ; G 1088 +U 1407 ; WX 602 ; N uni057F ; G 1089 +U 1408 ; WX 602 ; N uni0580 ; G 1090 +U 1409 ; WX 602 ; N uni0581 ; G 1091 +U 1410 ; WX 602 ; N uni0582 ; G 1092 +U 1411 ; WX 602 ; N uni0583 ; G 1093 +U 1412 ; WX 602 ; N uni0584 ; G 1094 +U 1413 ; WX 602 ; N uni0585 ; G 1095 +U 1414 ; WX 602 ; N uni0586 ; G 1096 +U 1415 ; WX 602 ; N uni0587 ; G 1097 +U 1417 ; WX 602 ; N uni0589 ; G 1098 +U 1418 ; WX 602 ; N uni058A ; G 1099 +U 3647 ; WX 602 ; N uni0E3F ; G 1100 +U 3713 ; WX 602 ; N uni0E81 ; G 1101 +U 3714 ; WX 602 ; N uni0E82 ; G 1102 +U 3716 ; WX 602 ; N uni0E84 ; G 1103 +U 3719 ; WX 602 ; N uni0E87 ; G 1104 +U 3720 ; WX 602 ; N uni0E88 ; G 1105 +U 3722 ; WX 602 ; N uni0E8A ; G 1106 +U 3725 ; WX 602 ; N uni0E8D ; G 1107 +U 3732 ; WX 602 ; N uni0E94 ; G 1108 +U 3733 ; WX 602 ; N uni0E95 ; G 1109 +U 3734 ; WX 602 ; N uni0E96 ; G 1110 +U 3735 ; WX 602 ; N uni0E97 ; G 1111 +U 3737 ; WX 602 ; N uni0E99 ; G 1112 +U 3738 ; WX 602 ; N uni0E9A ; G 1113 +U 3739 ; WX 602 ; N uni0E9B ; G 1114 +U 3740 ; WX 602 ; N uni0E9C ; G 1115 +U 3741 ; WX 602 ; N uni0E9D ; G 1116 +U 3742 ; WX 602 ; N uni0E9E ; G 1117 +U 3743 ; WX 602 ; N uni0E9F ; G 1118 +U 3745 ; WX 602 ; N uni0EA1 ; G 1119 +U 3746 ; WX 602 ; N uni0EA2 ; G 1120 +U 3747 ; WX 602 ; N uni0EA3 ; G 1121 +U 3749 ; WX 602 ; N uni0EA5 ; G 1122 +U 3751 ; WX 602 ; N uni0EA7 ; G 1123 +U 3754 ; WX 602 ; N uni0EAA ; G 1124 +U 3755 ; WX 602 ; N uni0EAB ; G 1125 +U 3757 ; WX 602 ; N uni0EAD ; G 1126 +U 3758 ; WX 602 ; N uni0EAE ; G 1127 +U 3759 ; WX 602 ; N uni0EAF ; G 1128 +U 3760 ; WX 602 ; N uni0EB0 ; G 1129 +U 3761 ; WX 602 ; N uni0EB1 ; G 1130 +U 3762 ; WX 602 ; N uni0EB2 ; G 1131 +U 3763 ; WX 602 ; N uni0EB3 ; G 1132 +U 3764 ; WX 602 ; N uni0EB4 ; G 1133 +U 3765 ; WX 602 ; N uni0EB5 ; G 1134 +U 3766 ; WX 602 ; N uni0EB6 ; G 1135 +U 3767 ; WX 602 ; N uni0EB7 ; G 1136 +U 3768 ; WX 602 ; N uni0EB8 ; G 1137 +U 3769 ; WX 602 ; N uni0EB9 ; G 1138 +U 3771 ; WX 602 ; N uni0EBB ; G 1139 +U 3772 ; WX 602 ; N uni0EBC ; G 1140 +U 3784 ; WX 602 ; N uni0EC8 ; G 1141 +U 3785 ; WX 602 ; N uni0EC9 ; G 1142 +U 3786 ; WX 602 ; N uni0ECA ; G 1143 +U 3787 ; WX 602 ; N uni0ECB ; G 1144 +U 3788 ; WX 602 ; N uni0ECC ; G 1145 +U 3789 ; WX 602 ; N uni0ECD ; G 1146 +U 4304 ; WX 602 ; N uni10D0 ; G 1147 +U 4305 ; WX 602 ; N uni10D1 ; G 1148 +U 4306 ; WX 602 ; N uni10D2 ; G 1149 +U 4307 ; WX 602 ; N uni10D3 ; G 1150 +U 4308 ; WX 602 ; N uni10D4 ; G 1151 +U 4309 ; WX 602 ; N uni10D5 ; G 1152 +U 4310 ; WX 602 ; N uni10D6 ; G 1153 +U 4311 ; WX 602 ; N uni10D7 ; G 1154 +U 4312 ; WX 602 ; N uni10D8 ; G 1155 +U 4313 ; WX 602 ; N uni10D9 ; G 1156 +U 4314 ; WX 602 ; N uni10DA ; G 1157 +U 4315 ; WX 602 ; N uni10DB ; G 1158 +U 4316 ; WX 602 ; N uni10DC ; G 1159 +U 4317 ; WX 602 ; N uni10DD ; G 1160 +U 4318 ; WX 602 ; N uni10DE ; G 1161 +U 4319 ; WX 602 ; N uni10DF ; G 1162 +U 4320 ; WX 602 ; N uni10E0 ; G 1163 +U 4321 ; WX 602 ; N uni10E1 ; G 1164 +U 4322 ; WX 602 ; N uni10E2 ; G 1165 +U 4323 ; WX 602 ; N uni10E3 ; G 1166 +U 4324 ; WX 602 ; N uni10E4 ; G 1167 +U 4325 ; WX 602 ; N uni10E5 ; G 1168 +U 4326 ; WX 602 ; N uni10E6 ; G 1169 +U 4327 ; WX 602 ; N uni10E7 ; G 1170 +U 4328 ; WX 602 ; N uni10E8 ; G 1171 +U 4329 ; WX 602 ; N uni10E9 ; G 1172 +U 4330 ; WX 602 ; N uni10EA ; G 1173 +U 4331 ; WX 602 ; N uni10EB ; G 1174 +U 4332 ; WX 602 ; N uni10EC ; G 1175 +U 4333 ; WX 602 ; N uni10ED ; G 1176 +U 4334 ; WX 602 ; N uni10EE ; G 1177 +U 4335 ; WX 602 ; N uni10EF ; G 1178 +U 4336 ; WX 602 ; N uni10F0 ; G 1179 +U 4337 ; WX 602 ; N uni10F1 ; G 1180 +U 4338 ; WX 602 ; N uni10F2 ; G 1181 +U 4339 ; WX 602 ; N uni10F3 ; G 1182 +U 4340 ; WX 602 ; N uni10F4 ; G 1183 +U 4341 ; WX 602 ; N uni10F5 ; G 1184 +U 4342 ; WX 602 ; N uni10F6 ; G 1185 +U 4343 ; WX 602 ; N uni10F7 ; G 1186 +U 4344 ; WX 602 ; N uni10F8 ; G 1187 +U 4345 ; WX 602 ; N uni10F9 ; G 1188 +U 4346 ; WX 602 ; N uni10FA ; G 1189 +U 4347 ; WX 602 ; N uni10FB ; G 1190 +U 4348 ; WX 602 ; N uni10FC ; G 1191 +U 7426 ; WX 602 ; N uni1D02 ; G 1192 +U 7432 ; WX 602 ; N uni1D08 ; G 1193 +U 7433 ; WX 602 ; N uni1D09 ; G 1194 +U 7444 ; WX 602 ; N uni1D14 ; G 1195 +U 7446 ; WX 602 ; N uni1D16 ; G 1196 +U 7447 ; WX 602 ; N uni1D17 ; G 1197 +U 7453 ; WX 602 ; N uni1D1D ; G 1198 +U 7454 ; WX 602 ; N uni1D1E ; G 1199 +U 7455 ; WX 602 ; N uni1D1F ; G 1200 +U 7468 ; WX 602 ; N uni1D2C ; G 1201 +U 7469 ; WX 602 ; N uni1D2D ; G 1202 +U 7470 ; WX 602 ; N uni1D2E ; G 1203 +U 7472 ; WX 602 ; N uni1D30 ; G 1204 +U 7473 ; WX 602 ; N uni1D31 ; G 1205 +U 7474 ; WX 602 ; N uni1D32 ; G 1206 +U 7475 ; WX 602 ; N uni1D33 ; G 1207 +U 7476 ; WX 602 ; N uni1D34 ; G 1208 +U 7477 ; WX 602 ; N uni1D35 ; G 1209 +U 7478 ; WX 602 ; N uni1D36 ; G 1210 +U 7479 ; WX 602 ; N uni1D37 ; G 1211 +U 7480 ; WX 602 ; N uni1D38 ; G 1212 +U 7481 ; WX 602 ; N uni1D39 ; G 1213 +U 7482 ; WX 602 ; N uni1D3A ; G 1214 +U 7483 ; WX 602 ; N uni1D3B ; G 1215 +U 7484 ; WX 602 ; N uni1D3C ; G 1216 +U 7485 ; WX 602 ; N uni1D3D ; G 1217 +U 7486 ; WX 602 ; N uni1D3E ; G 1218 +U 7487 ; WX 602 ; N uni1D3F ; G 1219 +U 7488 ; WX 602 ; N uni1D40 ; G 1220 +U 7489 ; WX 602 ; N uni1D41 ; G 1221 +U 7490 ; WX 602 ; N uni1D42 ; G 1222 +U 7491 ; WX 602 ; N uni1D43 ; G 1223 +U 7492 ; WX 602 ; N uni1D44 ; G 1224 +U 7493 ; WX 602 ; N uni1D45 ; G 1225 +U 7494 ; WX 602 ; N uni1D46 ; G 1226 +U 7495 ; WX 602 ; N uni1D47 ; G 1227 +U 7496 ; WX 602 ; N uni1D48 ; G 1228 +U 7497 ; WX 602 ; N uni1D49 ; G 1229 +U 7498 ; WX 602 ; N uni1D4A ; G 1230 +U 7499 ; WX 602 ; N uni1D4B ; G 1231 +U 7500 ; WX 602 ; N uni1D4C ; G 1232 +U 7501 ; WX 602 ; N uni1D4D ; G 1233 +U 7502 ; WX 602 ; N uni1D4E ; G 1234 +U 7503 ; WX 602 ; N uni1D4F ; G 1235 +U 7504 ; WX 602 ; N uni1D50 ; G 1236 +U 7505 ; WX 602 ; N uni1D51 ; G 1237 +U 7506 ; WX 602 ; N uni1D52 ; G 1238 +U 7507 ; WX 602 ; N uni1D53 ; G 1239 +U 7508 ; WX 602 ; N uni1D54 ; G 1240 +U 7509 ; WX 602 ; N uni1D55 ; G 1241 +U 7510 ; WX 602 ; N uni1D56 ; G 1242 +U 7511 ; WX 602 ; N uni1D57 ; G 1243 +U 7512 ; WX 602 ; N uni1D58 ; G 1244 +U 7513 ; WX 602 ; N uni1D59 ; G 1245 +U 7514 ; WX 602 ; N uni1D5A ; G 1246 +U 7515 ; WX 602 ; N uni1D5B ; G 1247 +U 7522 ; WX 602 ; N uni1D62 ; G 1248 +U 7523 ; WX 602 ; N uni1D63 ; G 1249 +U 7524 ; WX 602 ; N uni1D64 ; G 1250 +U 7525 ; WX 602 ; N uni1D65 ; G 1251 +U 7543 ; WX 602 ; N uni1D77 ; G 1252 +U 7544 ; WX 602 ; N uni1D78 ; G 1253 +U 7547 ; WX 602 ; N uni1D7B ; G 1254 +U 7557 ; WX 602 ; N uni1D85 ; G 1255 +U 7579 ; WX 602 ; N uni1D9B ; G 1256 +U 7580 ; WX 602 ; N uni1D9C ; G 1257 +U 7581 ; WX 602 ; N uni1D9D ; G 1258 +U 7582 ; WX 602 ; N uni1D9E ; G 1259 +U 7583 ; WX 602 ; N uni1D9F ; G 1260 +U 7584 ; WX 602 ; N uni1DA0 ; G 1261 +U 7585 ; WX 602 ; N uni1DA1 ; G 1262 +U 7586 ; WX 602 ; N uni1DA2 ; G 1263 +U 7587 ; WX 602 ; N uni1DA3 ; G 1264 +U 7588 ; WX 602 ; N uni1DA4 ; G 1265 +U 7589 ; WX 602 ; N uni1DA5 ; G 1266 +U 7590 ; WX 602 ; N uni1DA6 ; G 1267 +U 7591 ; WX 602 ; N uni1DA7 ; G 1268 +U 7592 ; WX 602 ; N uni1DA8 ; G 1269 +U 7593 ; WX 602 ; N uni1DA9 ; G 1270 +U 7594 ; WX 602 ; N uni1DAA ; G 1271 +U 7595 ; WX 602 ; N uni1DAB ; G 1272 +U 7596 ; WX 602 ; N uni1DAC ; G 1273 +U 7597 ; WX 602 ; N uni1DAD ; G 1274 +U 7598 ; WX 602 ; N uni1DAE ; G 1275 +U 7599 ; WX 602 ; N uni1DAF ; G 1276 +U 7600 ; WX 602 ; N uni1DB0 ; G 1277 +U 7601 ; WX 602 ; N uni1DB1 ; G 1278 +U 7602 ; WX 602 ; N uni1DB2 ; G 1279 +U 7603 ; WX 602 ; N uni1DB3 ; G 1280 +U 7604 ; WX 602 ; N uni1DB4 ; G 1281 +U 7605 ; WX 602 ; N uni1DB5 ; G 1282 +U 7606 ; WX 602 ; N uni1DB6 ; G 1283 +U 7607 ; WX 602 ; N uni1DB7 ; G 1284 +U 7609 ; WX 602 ; N uni1DB9 ; G 1285 +U 7610 ; WX 602 ; N uni1DBA ; G 1286 +U 7611 ; WX 602 ; N uni1DBB ; G 1287 +U 7612 ; WX 602 ; N uni1DBC ; G 1288 +U 7613 ; WX 602 ; N uni1DBD ; G 1289 +U 7614 ; WX 602 ; N uni1DBE ; G 1290 +U 7615 ; WX 602 ; N uni1DBF ; G 1291 +U 7680 ; WX 602 ; N uni1E00 ; G 1292 +U 7681 ; WX 602 ; N uni1E01 ; G 1293 +U 7682 ; WX 602 ; N uni1E02 ; G 1294 +U 7683 ; WX 602 ; N uni1E03 ; G 1295 +U 7684 ; WX 602 ; N uni1E04 ; G 1296 +U 7685 ; WX 602 ; N uni1E05 ; G 1297 +U 7686 ; WX 602 ; N uni1E06 ; G 1298 +U 7687 ; WX 602 ; N uni1E07 ; G 1299 +U 7688 ; WX 602 ; N uni1E08 ; G 1300 +U 7689 ; WX 602 ; N uni1E09 ; G 1301 +U 7690 ; WX 602 ; N uni1E0A ; G 1302 +U 7691 ; WX 602 ; N uni1E0B ; G 1303 +U 7692 ; WX 602 ; N uni1E0C ; G 1304 +U 7693 ; WX 602 ; N uni1E0D ; G 1305 +U 7694 ; WX 602 ; N uni1E0E ; G 1306 +U 7695 ; WX 602 ; N uni1E0F ; G 1307 +U 7696 ; WX 602 ; N uni1E10 ; G 1308 +U 7697 ; WX 602 ; N uni1E11 ; G 1309 +U 7698 ; WX 602 ; N uni1E12 ; G 1310 +U 7699 ; WX 602 ; N uni1E13 ; G 1311 +U 7704 ; WX 602 ; N uni1E18 ; G 1312 +U 7705 ; WX 602 ; N uni1E19 ; G 1313 +U 7706 ; WX 602 ; N uni1E1A ; G 1314 +U 7707 ; WX 602 ; N uni1E1B ; G 1315 +U 7708 ; WX 602 ; N uni1E1C ; G 1316 +U 7709 ; WX 602 ; N uni1E1D ; G 1317 +U 7710 ; WX 602 ; N uni1E1E ; G 1318 +U 7711 ; WX 602 ; N uni1E1F ; G 1319 +U 7712 ; WX 602 ; N uni1E20 ; G 1320 +U 7713 ; WX 602 ; N uni1E21 ; G 1321 +U 7714 ; WX 602 ; N uni1E22 ; G 1322 +U 7715 ; WX 602 ; N uni1E23 ; G 1323 +U 7716 ; WX 602 ; N uni1E24 ; G 1324 +U 7717 ; WX 602 ; N uni1E25 ; G 1325 +U 7718 ; WX 602 ; N uni1E26 ; G 1326 +U 7719 ; WX 602 ; N uni1E27 ; G 1327 +U 7720 ; WX 602 ; N uni1E28 ; G 1328 +U 7721 ; WX 602 ; N uni1E29 ; G 1329 +U 7722 ; WX 602 ; N uni1E2A ; G 1330 +U 7723 ; WX 602 ; N uni1E2B ; G 1331 +U 7724 ; WX 602 ; N uni1E2C ; G 1332 +U 7725 ; WX 602 ; N uni1E2D ; G 1333 +U 7728 ; WX 602 ; N uni1E30 ; G 1334 +U 7729 ; WX 602 ; N uni1E31 ; G 1335 +U 7730 ; WX 602 ; N uni1E32 ; G 1336 +U 7731 ; WX 602 ; N uni1E33 ; G 1337 +U 7732 ; WX 602 ; N uni1E34 ; G 1338 +U 7733 ; WX 602 ; N uni1E35 ; G 1339 +U 7734 ; WX 602 ; N uni1E36 ; G 1340 +U 7735 ; WX 602 ; N uni1E37 ; G 1341 +U 7736 ; WX 602 ; N uni1E38 ; G 1342 +U 7737 ; WX 602 ; N uni1E39 ; G 1343 +U 7738 ; WX 602 ; N uni1E3A ; G 1344 +U 7739 ; WX 602 ; N uni1E3B ; G 1345 +U 7740 ; WX 602 ; N uni1E3C ; G 1346 +U 7741 ; WX 602 ; N uni1E3D ; G 1347 +U 7742 ; WX 602 ; N uni1E3E ; G 1348 +U 7743 ; WX 602 ; N uni1E3F ; G 1349 +U 7744 ; WX 602 ; N uni1E40 ; G 1350 +U 7745 ; WX 602 ; N uni1E41 ; G 1351 +U 7746 ; WX 602 ; N uni1E42 ; G 1352 +U 7747 ; WX 602 ; N uni1E43 ; G 1353 +U 7748 ; WX 602 ; N uni1E44 ; G 1354 +U 7749 ; WX 602 ; N uni1E45 ; G 1355 +U 7750 ; WX 602 ; N uni1E46 ; G 1356 +U 7751 ; WX 602 ; N uni1E47 ; G 1357 +U 7752 ; WX 602 ; N uni1E48 ; G 1358 +U 7753 ; WX 602 ; N uni1E49 ; G 1359 +U 7754 ; WX 602 ; N uni1E4A ; G 1360 +U 7755 ; WX 602 ; N uni1E4B ; G 1361 +U 7756 ; WX 602 ; N uni1E4C ; G 1362 +U 7757 ; WX 602 ; N uni1E4D ; G 1363 +U 7764 ; WX 602 ; N uni1E54 ; G 1364 +U 7765 ; WX 602 ; N uni1E55 ; G 1365 +U 7766 ; WX 602 ; N uni1E56 ; G 1366 +U 7767 ; WX 602 ; N uni1E57 ; G 1367 +U 7768 ; WX 602 ; N uni1E58 ; G 1368 +U 7769 ; WX 602 ; N uni1E59 ; G 1369 +U 7770 ; WX 602 ; N uni1E5A ; G 1370 +U 7771 ; WX 602 ; N uni1E5B ; G 1371 +U 7772 ; WX 602 ; N uni1E5C ; G 1372 +U 7773 ; WX 602 ; N uni1E5D ; G 1373 +U 7774 ; WX 602 ; N uni1E5E ; G 1374 +U 7775 ; WX 602 ; N uni1E5F ; G 1375 +U 7776 ; WX 602 ; N uni1E60 ; G 1376 +U 7777 ; WX 602 ; N uni1E61 ; G 1377 +U 7778 ; WX 602 ; N uni1E62 ; G 1378 +U 7779 ; WX 602 ; N uni1E63 ; G 1379 +U 7784 ; WX 602 ; N uni1E68 ; G 1380 +U 7785 ; WX 602 ; N uni1E69 ; G 1381 +U 7786 ; WX 602 ; N uni1E6A ; G 1382 +U 7787 ; WX 602 ; N uni1E6B ; G 1383 +U 7788 ; WX 602 ; N uni1E6C ; G 1384 +U 7789 ; WX 602 ; N uni1E6D ; G 1385 +U 7790 ; WX 602 ; N uni1E6E ; G 1386 +U 7791 ; WX 602 ; N uni1E6F ; G 1387 +U 7792 ; WX 602 ; N uni1E70 ; G 1388 +U 7793 ; WX 602 ; N uni1E71 ; G 1389 +U 7794 ; WX 602 ; N uni1E72 ; G 1390 +U 7795 ; WX 602 ; N uni1E73 ; G 1391 +U 7796 ; WX 602 ; N uni1E74 ; G 1392 +U 7797 ; WX 602 ; N uni1E75 ; G 1393 +U 7798 ; WX 602 ; N uni1E76 ; G 1394 +U 7799 ; WX 602 ; N uni1E77 ; G 1395 +U 7800 ; WX 602 ; N uni1E78 ; G 1396 +U 7801 ; WX 602 ; N uni1E79 ; G 1397 +U 7804 ; WX 602 ; N uni1E7C ; G 1398 +U 7805 ; WX 602 ; N uni1E7D ; G 1399 +U 7806 ; WX 602 ; N uni1E7E ; G 1400 +U 7807 ; WX 602 ; N uni1E7F ; G 1401 +U 7808 ; WX 602 ; N Wgrave ; G 1402 +U 7809 ; WX 602 ; N wgrave ; G 1403 +U 7810 ; WX 602 ; N Wacute ; G 1404 +U 7811 ; WX 602 ; N wacute ; G 1405 +U 7812 ; WX 602 ; N Wdieresis ; G 1406 +U 7813 ; WX 602 ; N wdieresis ; G 1407 +U 7814 ; WX 602 ; N uni1E86 ; G 1408 +U 7815 ; WX 602 ; N uni1E87 ; G 1409 +U 7816 ; WX 602 ; N uni1E88 ; G 1410 +U 7817 ; WX 602 ; N uni1E89 ; G 1411 +U 7818 ; WX 602 ; N uni1E8A ; G 1412 +U 7819 ; WX 602 ; N uni1E8B ; G 1413 +U 7820 ; WX 602 ; N uni1E8C ; G 1414 +U 7821 ; WX 602 ; N uni1E8D ; G 1415 +U 7822 ; WX 602 ; N uni1E8E ; G 1416 +U 7823 ; WX 602 ; N uni1E8F ; G 1417 +U 7824 ; WX 602 ; N uni1E90 ; G 1418 +U 7825 ; WX 602 ; N uni1E91 ; G 1419 +U 7826 ; WX 602 ; N uni1E92 ; G 1420 +U 7827 ; WX 602 ; N uni1E93 ; G 1421 +U 7828 ; WX 602 ; N uni1E94 ; G 1422 +U 7829 ; WX 602 ; N uni1E95 ; G 1423 +U 7830 ; WX 602 ; N uni1E96 ; G 1424 +U 7831 ; WX 602 ; N uni1E97 ; G 1425 +U 7832 ; WX 602 ; N uni1E98 ; G 1426 +U 7833 ; WX 602 ; N uni1E99 ; G 1427 +U 7835 ; WX 602 ; N uni1E9B ; G 1428 +U 7839 ; WX 602 ; N uni1E9F ; G 1429 +U 7840 ; WX 602 ; N uni1EA0 ; G 1430 +U 7841 ; WX 602 ; N uni1EA1 ; G 1431 +U 7852 ; WX 602 ; N uni1EAC ; G 1432 +U 7853 ; WX 602 ; N uni1EAD ; G 1433 +U 7856 ; WX 602 ; N uni1EB0 ; G 1434 +U 7857 ; WX 602 ; N uni1EB1 ; G 1435 +U 7862 ; WX 602 ; N uni1EB6 ; G 1436 +U 7863 ; WX 602 ; N uni1EB7 ; G 1437 +U 7864 ; WX 602 ; N uni1EB8 ; G 1438 +U 7865 ; WX 602 ; N uni1EB9 ; G 1439 +U 7868 ; WX 602 ; N uni1EBC ; G 1440 +U 7869 ; WX 602 ; N uni1EBD ; G 1441 +U 7878 ; WX 602 ; N uni1EC6 ; G 1442 +U 7879 ; WX 602 ; N uni1EC7 ; G 1443 +U 7882 ; WX 602 ; N uni1ECA ; G 1444 +U 7883 ; WX 602 ; N uni1ECB ; G 1445 +U 7884 ; WX 602 ; N uni1ECC ; G 1446 +U 7885 ; WX 602 ; N uni1ECD ; G 1447 +U 7896 ; WX 602 ; N uni1ED8 ; G 1448 +U 7897 ; WX 602 ; N uni1ED9 ; G 1449 +U 7898 ; WX 602 ; N uni1EDA ; G 1450 +U 7899 ; WX 602 ; N uni1EDB ; G 1451 +U 7900 ; WX 602 ; N uni1EDC ; G 1452 +U 7901 ; WX 602 ; N uni1EDD ; G 1453 +U 7904 ; WX 602 ; N uni1EE0 ; G 1454 +U 7905 ; WX 602 ; N uni1EE1 ; G 1455 +U 7906 ; WX 602 ; N uni1EE2 ; G 1456 +U 7907 ; WX 602 ; N uni1EE3 ; G 1457 +U 7908 ; WX 602 ; N uni1EE4 ; G 1458 +U 7909 ; WX 602 ; N uni1EE5 ; G 1459 +U 7912 ; WX 602 ; N uni1EE8 ; G 1460 +U 7913 ; WX 602 ; N uni1EE9 ; G 1461 +U 7914 ; WX 602 ; N uni1EEA ; G 1462 +U 7915 ; WX 602 ; N uni1EEB ; G 1463 +U 7918 ; WX 602 ; N uni1EEE ; G 1464 +U 7919 ; WX 602 ; N uni1EEF ; G 1465 +U 7920 ; WX 602 ; N uni1EF0 ; G 1466 +U 7921 ; WX 602 ; N uni1EF1 ; G 1467 +U 7922 ; WX 602 ; N Ygrave ; G 1468 +U 7923 ; WX 602 ; N ygrave ; G 1469 +U 7924 ; WX 602 ; N uni1EF4 ; G 1470 +U 7925 ; WX 602 ; N uni1EF5 ; G 1471 +U 7928 ; WX 602 ; N uni1EF8 ; G 1472 +U 7929 ; WX 602 ; N uni1EF9 ; G 1473 +U 7936 ; WX 602 ; N uni1F00 ; G 1474 +U 7937 ; WX 602 ; N uni1F01 ; G 1475 +U 7938 ; WX 602 ; N uni1F02 ; G 1476 +U 7939 ; WX 602 ; N uni1F03 ; G 1477 +U 7940 ; WX 602 ; N uni1F04 ; G 1478 +U 7941 ; WX 602 ; N uni1F05 ; G 1479 +U 7942 ; WX 602 ; N uni1F06 ; G 1480 +U 7943 ; WX 602 ; N uni1F07 ; G 1481 +U 7944 ; WX 602 ; N uni1F08 ; G 1482 +U 7945 ; WX 602 ; N uni1F09 ; G 1483 +U 7946 ; WX 602 ; N uni1F0A ; G 1484 +U 7947 ; WX 602 ; N uni1F0B ; G 1485 +U 7948 ; WX 602 ; N uni1F0C ; G 1486 +U 7949 ; WX 602 ; N uni1F0D ; G 1487 +U 7950 ; WX 602 ; N uni1F0E ; G 1488 +U 7951 ; WX 602 ; N uni1F0F ; G 1489 +U 7952 ; WX 602 ; N uni1F10 ; G 1490 +U 7953 ; WX 602 ; N uni1F11 ; G 1491 +U 7954 ; WX 602 ; N uni1F12 ; G 1492 +U 7955 ; WX 602 ; N uni1F13 ; G 1493 +U 7956 ; WX 602 ; N uni1F14 ; G 1494 +U 7957 ; WX 602 ; N uni1F15 ; G 1495 +U 7960 ; WX 602 ; N uni1F18 ; G 1496 +U 7961 ; WX 602 ; N uni1F19 ; G 1497 +U 7962 ; WX 602 ; N uni1F1A ; G 1498 +U 7963 ; WX 602 ; N uni1F1B ; G 1499 +U 7964 ; WX 602 ; N uni1F1C ; G 1500 +U 7965 ; WX 602 ; N uni1F1D ; G 1501 +U 7968 ; WX 602 ; N uni1F20 ; G 1502 +U 7969 ; WX 602 ; N uni1F21 ; G 1503 +U 7970 ; WX 602 ; N uni1F22 ; G 1504 +U 7971 ; WX 602 ; N uni1F23 ; G 1505 +U 7972 ; WX 602 ; N uni1F24 ; G 1506 +U 7973 ; WX 602 ; N uni1F25 ; G 1507 +U 7974 ; WX 602 ; N uni1F26 ; G 1508 +U 7975 ; WX 602 ; N uni1F27 ; G 1509 +U 7976 ; WX 602 ; N uni1F28 ; G 1510 +U 7977 ; WX 602 ; N uni1F29 ; G 1511 +U 7978 ; WX 602 ; N uni1F2A ; G 1512 +U 7979 ; WX 602 ; N uni1F2B ; G 1513 +U 7980 ; WX 602 ; N uni1F2C ; G 1514 +U 7981 ; WX 602 ; N uni1F2D ; G 1515 +U 7982 ; WX 602 ; N uni1F2E ; G 1516 +U 7983 ; WX 602 ; N uni1F2F ; G 1517 +U 7984 ; WX 602 ; N uni1F30 ; G 1518 +U 7985 ; WX 602 ; N uni1F31 ; G 1519 +U 7986 ; WX 602 ; N uni1F32 ; G 1520 +U 7987 ; WX 602 ; N uni1F33 ; G 1521 +U 7988 ; WX 602 ; N uni1F34 ; G 1522 +U 7989 ; WX 602 ; N uni1F35 ; G 1523 +U 7990 ; WX 602 ; N uni1F36 ; G 1524 +U 7991 ; WX 602 ; N uni1F37 ; G 1525 +U 7992 ; WX 602 ; N uni1F38 ; G 1526 +U 7993 ; WX 602 ; N uni1F39 ; G 1527 +U 7994 ; WX 602 ; N uni1F3A ; G 1528 +U 7995 ; WX 602 ; N uni1F3B ; G 1529 +U 7996 ; WX 602 ; N uni1F3C ; G 1530 +U 7997 ; WX 602 ; N uni1F3D ; G 1531 +U 7998 ; WX 602 ; N uni1F3E ; G 1532 +U 7999 ; WX 602 ; N uni1F3F ; G 1533 +U 8000 ; WX 602 ; N uni1F40 ; G 1534 +U 8001 ; WX 602 ; N uni1F41 ; G 1535 +U 8002 ; WX 602 ; N uni1F42 ; G 1536 +U 8003 ; WX 602 ; N uni1F43 ; G 1537 +U 8004 ; WX 602 ; N uni1F44 ; G 1538 +U 8005 ; WX 602 ; N uni1F45 ; G 1539 +U 8008 ; WX 602 ; N uni1F48 ; G 1540 +U 8009 ; WX 602 ; N uni1F49 ; G 1541 +U 8010 ; WX 602 ; N uni1F4A ; G 1542 +U 8011 ; WX 602 ; N uni1F4B ; G 1543 +U 8012 ; WX 602 ; N uni1F4C ; G 1544 +U 8013 ; WX 602 ; N uni1F4D ; G 1545 +U 8016 ; WX 602 ; N uni1F50 ; G 1546 +U 8017 ; WX 602 ; N uni1F51 ; G 1547 +U 8018 ; WX 602 ; N uni1F52 ; G 1548 +U 8019 ; WX 602 ; N uni1F53 ; G 1549 +U 8020 ; WX 602 ; N uni1F54 ; G 1550 +U 8021 ; WX 602 ; N uni1F55 ; G 1551 +U 8022 ; WX 602 ; N uni1F56 ; G 1552 +U 8023 ; WX 602 ; N uni1F57 ; G 1553 +U 8025 ; WX 602 ; N uni1F59 ; G 1554 +U 8027 ; WX 602 ; N uni1F5B ; G 1555 +U 8029 ; WX 602 ; N uni1F5D ; G 1556 +U 8031 ; WX 602 ; N uni1F5F ; G 1557 +U 8032 ; WX 602 ; N uni1F60 ; G 1558 +U 8033 ; WX 602 ; N uni1F61 ; G 1559 +U 8034 ; WX 602 ; N uni1F62 ; G 1560 +U 8035 ; WX 602 ; N uni1F63 ; G 1561 +U 8036 ; WX 602 ; N uni1F64 ; G 1562 +U 8037 ; WX 602 ; N uni1F65 ; G 1563 +U 8038 ; WX 602 ; N uni1F66 ; G 1564 +U 8039 ; WX 602 ; N uni1F67 ; G 1565 +U 8040 ; WX 602 ; N uni1F68 ; G 1566 +U 8041 ; WX 602 ; N uni1F69 ; G 1567 +U 8042 ; WX 602 ; N uni1F6A ; G 1568 +U 8043 ; WX 602 ; N uni1F6B ; G 1569 +U 8044 ; WX 602 ; N uni1F6C ; G 1570 +U 8045 ; WX 602 ; N uni1F6D ; G 1571 +U 8046 ; WX 602 ; N uni1F6E ; G 1572 +U 8047 ; WX 602 ; N uni1F6F ; G 1573 +U 8048 ; WX 602 ; N uni1F70 ; G 1574 +U 8049 ; WX 602 ; N uni1F71 ; G 1575 +U 8050 ; WX 602 ; N uni1F72 ; G 1576 +U 8051 ; WX 602 ; N uni1F73 ; G 1577 +U 8052 ; WX 602 ; N uni1F74 ; G 1578 +U 8053 ; WX 602 ; N uni1F75 ; G 1579 +U 8054 ; WX 602 ; N uni1F76 ; G 1580 +U 8055 ; WX 602 ; N uni1F77 ; G 1581 +U 8056 ; WX 602 ; N uni1F78 ; G 1582 +U 8057 ; WX 602 ; N uni1F79 ; G 1583 +U 8058 ; WX 602 ; N uni1F7A ; G 1584 +U 8059 ; WX 602 ; N uni1F7B ; G 1585 +U 8060 ; WX 602 ; N uni1F7C ; G 1586 +U 8061 ; WX 602 ; N uni1F7D ; G 1587 +U 8064 ; WX 602 ; N uni1F80 ; G 1588 +U 8065 ; WX 602 ; N uni1F81 ; G 1589 +U 8066 ; WX 602 ; N uni1F82 ; G 1590 +U 8067 ; WX 602 ; N uni1F83 ; G 1591 +U 8068 ; WX 602 ; N uni1F84 ; G 1592 +U 8069 ; WX 602 ; N uni1F85 ; G 1593 +U 8070 ; WX 602 ; N uni1F86 ; G 1594 +U 8071 ; WX 602 ; N uni1F87 ; G 1595 +U 8072 ; WX 602 ; N uni1F88 ; G 1596 +U 8073 ; WX 602 ; N uni1F89 ; G 1597 +U 8074 ; WX 602 ; N uni1F8A ; G 1598 +U 8075 ; WX 602 ; N uni1F8B ; G 1599 +U 8076 ; WX 602 ; N uni1F8C ; G 1600 +U 8077 ; WX 602 ; N uni1F8D ; G 1601 +U 8078 ; WX 602 ; N uni1F8E ; G 1602 +U 8079 ; WX 602 ; N uni1F8F ; G 1603 +U 8080 ; WX 602 ; N uni1F90 ; G 1604 +U 8081 ; WX 602 ; N uni1F91 ; G 1605 +U 8082 ; WX 602 ; N uni1F92 ; G 1606 +U 8083 ; WX 602 ; N uni1F93 ; G 1607 +U 8084 ; WX 602 ; N uni1F94 ; G 1608 +U 8085 ; WX 602 ; N uni1F95 ; G 1609 +U 8086 ; WX 602 ; N uni1F96 ; G 1610 +U 8087 ; WX 602 ; N uni1F97 ; G 1611 +U 8088 ; WX 602 ; N uni1F98 ; G 1612 +U 8089 ; WX 602 ; N uni1F99 ; G 1613 +U 8090 ; WX 602 ; N uni1F9A ; G 1614 +U 8091 ; WX 602 ; N uni1F9B ; G 1615 +U 8092 ; WX 602 ; N uni1F9C ; G 1616 +U 8093 ; WX 602 ; N uni1F9D ; G 1617 +U 8094 ; WX 602 ; N uni1F9E ; G 1618 +U 8095 ; WX 602 ; N uni1F9F ; G 1619 +U 8096 ; WX 602 ; N uni1FA0 ; G 1620 +U 8097 ; WX 602 ; N uni1FA1 ; G 1621 +U 8098 ; WX 602 ; N uni1FA2 ; G 1622 +U 8099 ; WX 602 ; N uni1FA3 ; G 1623 +U 8100 ; WX 602 ; N uni1FA4 ; G 1624 +U 8101 ; WX 602 ; N uni1FA5 ; G 1625 +U 8102 ; WX 602 ; N uni1FA6 ; G 1626 +U 8103 ; WX 602 ; N uni1FA7 ; G 1627 +U 8104 ; WX 602 ; N uni1FA8 ; G 1628 +U 8105 ; WX 602 ; N uni1FA9 ; G 1629 +U 8106 ; WX 602 ; N uni1FAA ; G 1630 +U 8107 ; WX 602 ; N uni1FAB ; G 1631 +U 8108 ; WX 602 ; N uni1FAC ; G 1632 +U 8109 ; WX 602 ; N uni1FAD ; G 1633 +U 8110 ; WX 602 ; N uni1FAE ; G 1634 +U 8111 ; WX 602 ; N uni1FAF ; G 1635 +U 8112 ; WX 602 ; N uni1FB0 ; G 1636 +U 8113 ; WX 602 ; N uni1FB1 ; G 1637 +U 8114 ; WX 602 ; N uni1FB2 ; G 1638 +U 8115 ; WX 602 ; N uni1FB3 ; G 1639 +U 8116 ; WX 602 ; N uni1FB4 ; G 1640 +U 8118 ; WX 602 ; N uni1FB6 ; G 1641 +U 8119 ; WX 602 ; N uni1FB7 ; G 1642 +U 8120 ; WX 602 ; N uni1FB8 ; G 1643 +U 8121 ; WX 602 ; N uni1FB9 ; G 1644 +U 8122 ; WX 602 ; N uni1FBA ; G 1645 +U 8123 ; WX 602 ; N uni1FBB ; G 1646 +U 8124 ; WX 602 ; N uni1FBC ; G 1647 +U 8125 ; WX 602 ; N uni1FBD ; G 1648 +U 8126 ; WX 602 ; N uni1FBE ; G 1649 +U 8127 ; WX 602 ; N uni1FBF ; G 1650 +U 8128 ; WX 602 ; N uni1FC0 ; G 1651 +U 8129 ; WX 602 ; N uni1FC1 ; G 1652 +U 8130 ; WX 602 ; N uni1FC2 ; G 1653 +U 8131 ; WX 602 ; N uni1FC3 ; G 1654 +U 8132 ; WX 602 ; N uni1FC4 ; G 1655 +U 8134 ; WX 602 ; N uni1FC6 ; G 1656 +U 8135 ; WX 602 ; N uni1FC7 ; G 1657 +U 8136 ; WX 602 ; N uni1FC8 ; G 1658 +U 8137 ; WX 602 ; N uni1FC9 ; G 1659 +U 8138 ; WX 602 ; N uni1FCA ; G 1660 +U 8139 ; WX 602 ; N uni1FCB ; G 1661 +U 8140 ; WX 602 ; N uni1FCC ; G 1662 +U 8141 ; WX 602 ; N uni1FCD ; G 1663 +U 8142 ; WX 602 ; N uni1FCE ; G 1664 +U 8143 ; WX 602 ; N uni1FCF ; G 1665 +U 8144 ; WX 602 ; N uni1FD0 ; G 1666 +U 8145 ; WX 602 ; N uni1FD1 ; G 1667 +U 8146 ; WX 602 ; N uni1FD2 ; G 1668 +U 8147 ; WX 602 ; N uni1FD3 ; G 1669 +U 8150 ; WX 602 ; N uni1FD6 ; G 1670 +U 8151 ; WX 602 ; N uni1FD7 ; G 1671 +U 8152 ; WX 602 ; N uni1FD8 ; G 1672 +U 8153 ; WX 602 ; N uni1FD9 ; G 1673 +U 8154 ; WX 602 ; N uni1FDA ; G 1674 +U 8155 ; WX 602 ; N uni1FDB ; G 1675 +U 8157 ; WX 602 ; N uni1FDD ; G 1676 +U 8158 ; WX 602 ; N uni1FDE ; G 1677 +U 8159 ; WX 602 ; N uni1FDF ; G 1678 +U 8160 ; WX 602 ; N uni1FE0 ; G 1679 +U 8161 ; WX 602 ; N uni1FE1 ; G 1680 +U 8162 ; WX 602 ; N uni1FE2 ; G 1681 +U 8163 ; WX 602 ; N uni1FE3 ; G 1682 +U 8164 ; WX 602 ; N uni1FE4 ; G 1683 +U 8165 ; WX 602 ; N uni1FE5 ; G 1684 +U 8166 ; WX 602 ; N uni1FE6 ; G 1685 +U 8167 ; WX 602 ; N uni1FE7 ; G 1686 +U 8168 ; WX 602 ; N uni1FE8 ; G 1687 +U 8169 ; WX 602 ; N uni1FE9 ; G 1688 +U 8170 ; WX 602 ; N uni1FEA ; G 1689 +U 8171 ; WX 602 ; N uni1FEB ; G 1690 +U 8172 ; WX 602 ; N uni1FEC ; G 1691 +U 8173 ; WX 602 ; N uni1FED ; G 1692 +U 8174 ; WX 602 ; N uni1FEE ; G 1693 +U 8175 ; WX 602 ; N uni1FEF ; G 1694 +U 8178 ; WX 602 ; N uni1FF2 ; G 1695 +U 8179 ; WX 602 ; N uni1FF3 ; G 1696 +U 8180 ; WX 602 ; N uni1FF4 ; G 1697 +U 8182 ; WX 602 ; N uni1FF6 ; G 1698 +U 8183 ; WX 602 ; N uni1FF7 ; G 1699 +U 8184 ; WX 602 ; N uni1FF8 ; G 1700 +U 8185 ; WX 602 ; N uni1FF9 ; G 1701 +U 8186 ; WX 602 ; N uni1FFA ; G 1702 +U 8187 ; WX 602 ; N uni1FFB ; G 1703 +U 8188 ; WX 602 ; N uni1FFC ; G 1704 +U 8189 ; WX 602 ; N uni1FFD ; G 1705 +U 8190 ; WX 602 ; N uni1FFE ; G 1706 +U 8192 ; WX 602 ; N uni2000 ; G 1707 +U 8193 ; WX 602 ; N uni2001 ; G 1708 +U 8194 ; WX 602 ; N uni2002 ; G 1709 +U 8195 ; WX 602 ; N uni2003 ; G 1710 +U 8196 ; WX 602 ; N uni2004 ; G 1711 +U 8197 ; WX 602 ; N uni2005 ; G 1712 +U 8198 ; WX 602 ; N uni2006 ; G 1713 +U 8199 ; WX 602 ; N uni2007 ; G 1714 +U 8200 ; WX 602 ; N uni2008 ; G 1715 +U 8201 ; WX 602 ; N uni2009 ; G 1716 +U 8202 ; WX 602 ; N uni200A ; G 1717 +U 8208 ; WX 602 ; N uni2010 ; G 1718 +U 8209 ; WX 602 ; N uni2011 ; G 1719 +U 8210 ; WX 602 ; N figuredash ; G 1720 +U 8211 ; WX 602 ; N endash ; G 1721 +U 8212 ; WX 602 ; N emdash ; G 1722 +U 8213 ; WX 602 ; N uni2015 ; G 1723 +U 8214 ; WX 602 ; N uni2016 ; G 1724 +U 8215 ; WX 602 ; N underscoredbl ; G 1725 +U 8216 ; WX 602 ; N quoteleft ; G 1726 +U 8217 ; WX 602 ; N quoteright ; G 1727 +U 8218 ; WX 602 ; N quotesinglbase ; G 1728 +U 8219 ; WX 602 ; N quotereversed ; G 1729 +U 8220 ; WX 602 ; N quotedblleft ; G 1730 +U 8221 ; WX 602 ; N quotedblright ; G 1731 +U 8222 ; WX 602 ; N quotedblbase ; G 1732 +U 8223 ; WX 602 ; N uni201F ; G 1733 +U 8224 ; WX 602 ; N dagger ; G 1734 +U 8225 ; WX 602 ; N daggerdbl ; G 1735 +U 8226 ; WX 602 ; N bullet ; G 1736 +U 8227 ; WX 602 ; N uni2023 ; G 1737 +U 8230 ; WX 602 ; N ellipsis ; G 1738 +U 8239 ; WX 602 ; N uni202F ; G 1739 +U 8240 ; WX 602 ; N perthousand ; G 1740 +U 8241 ; WX 602 ; N uni2031 ; G 1741 +U 8242 ; WX 602 ; N minute ; G 1742 +U 8243 ; WX 602 ; N second ; G 1743 +U 8244 ; WX 602 ; N uni2034 ; G 1744 +U 8245 ; WX 602 ; N uni2035 ; G 1745 +U 8246 ; WX 602 ; N uni2036 ; G 1746 +U 8247 ; WX 602 ; N uni2037 ; G 1747 +U 8249 ; WX 602 ; N guilsinglleft ; G 1748 +U 8250 ; WX 602 ; N guilsinglright ; G 1749 +U 8252 ; WX 602 ; N exclamdbl ; G 1750 +U 8253 ; WX 602 ; N uni203D ; G 1751 +U 8254 ; WX 602 ; N uni203E ; G 1752 +U 8255 ; WX 602 ; N uni203F ; G 1753 +U 8261 ; WX 602 ; N uni2045 ; G 1754 +U 8262 ; WX 602 ; N uni2046 ; G 1755 +U 8263 ; WX 602 ; N uni2047 ; G 1756 +U 8264 ; WX 602 ; N uni2048 ; G 1757 +U 8265 ; WX 602 ; N uni2049 ; G 1758 +U 8267 ; WX 602 ; N uni204B ; G 1759 +U 8287 ; WX 602 ; N uni205F ; G 1760 +U 8304 ; WX 602 ; N uni2070 ; G 1761 +U 8305 ; WX 602 ; N uni2071 ; G 1762 +U 8308 ; WX 602 ; N uni2074 ; G 1763 +U 8309 ; WX 602 ; N uni2075 ; G 1764 +U 8310 ; WX 602 ; N uni2076 ; G 1765 +U 8311 ; WX 602 ; N uni2077 ; G 1766 +U 8312 ; WX 602 ; N uni2078 ; G 1767 +U 8313 ; WX 602 ; N uni2079 ; G 1768 +U 8314 ; WX 602 ; N uni207A ; G 1769 +U 8315 ; WX 602 ; N uni207B ; G 1770 +U 8316 ; WX 602 ; N uni207C ; G 1771 +U 8317 ; WX 602 ; N uni207D ; G 1772 +U 8318 ; WX 602 ; N uni207E ; G 1773 +U 8319 ; WX 602 ; N uni207F ; G 1774 +U 8320 ; WX 602 ; N uni2080 ; G 1775 +U 8321 ; WX 602 ; N uni2081 ; G 1776 +U 8322 ; WX 602 ; N uni2082 ; G 1777 +U 8323 ; WX 602 ; N uni2083 ; G 1778 +U 8324 ; WX 602 ; N uni2084 ; G 1779 +U 8325 ; WX 602 ; N uni2085 ; G 1780 +U 8326 ; WX 602 ; N uni2086 ; G 1781 +U 8327 ; WX 602 ; N uni2087 ; G 1782 +U 8328 ; WX 602 ; N uni2088 ; G 1783 +U 8329 ; WX 602 ; N uni2089 ; G 1784 +U 8330 ; WX 602 ; N uni208A ; G 1785 +U 8331 ; WX 602 ; N uni208B ; G 1786 +U 8332 ; WX 602 ; N uni208C ; G 1787 +U 8333 ; WX 602 ; N uni208D ; G 1788 +U 8334 ; WX 602 ; N uni208E ; G 1789 +U 8336 ; WX 602 ; N uni2090 ; G 1790 +U 8337 ; WX 602 ; N uni2091 ; G 1791 +U 8338 ; WX 602 ; N uni2092 ; G 1792 +U 8339 ; WX 602 ; N uni2093 ; G 1793 +U 8340 ; WX 602 ; N uni2094 ; G 1794 +U 8341 ; WX 602 ; N uni2095 ; G 1795 +U 8342 ; WX 602 ; N uni2096 ; G 1796 +U 8343 ; WX 602 ; N uni2097 ; G 1797 +U 8344 ; WX 602 ; N uni2098 ; G 1798 +U 8345 ; WX 602 ; N uni2099 ; G 1799 +U 8346 ; WX 602 ; N uni209A ; G 1800 +U 8347 ; WX 602 ; N uni209B ; G 1801 +U 8348 ; WX 602 ; N uni209C ; G 1802 +U 8352 ; WX 602 ; N uni20A0 ; G 1803 +U 8353 ; WX 602 ; N colonmonetary ; G 1804 +U 8354 ; WX 602 ; N uni20A2 ; G 1805 +U 8355 ; WX 602 ; N franc ; G 1806 +U 8356 ; WX 602 ; N lira ; G 1807 +U 8357 ; WX 602 ; N uni20A5 ; G 1808 +U 8358 ; WX 602 ; N uni20A6 ; G 1809 +U 8359 ; WX 602 ; N peseta ; G 1810 +U 8360 ; WX 602 ; N uni20A8 ; G 1811 +U 8361 ; WX 602 ; N uni20A9 ; G 1812 +U 8362 ; WX 602 ; N uni20AA ; G 1813 +U 8363 ; WX 602 ; N dong ; G 1814 +U 8364 ; WX 602 ; N Euro ; G 1815 +U 8365 ; WX 602 ; N uni20AD ; G 1816 +U 8366 ; WX 602 ; N uni20AE ; G 1817 +U 8367 ; WX 602 ; N uni20AF ; G 1818 +U 8368 ; WX 602 ; N uni20B0 ; G 1819 +U 8369 ; WX 602 ; N uni20B1 ; G 1820 +U 8370 ; WX 602 ; N uni20B2 ; G 1821 +U 8371 ; WX 602 ; N uni20B3 ; G 1822 +U 8372 ; WX 602 ; N uni20B4 ; G 1823 +U 8373 ; WX 602 ; N uni20B5 ; G 1824 +U 8376 ; WX 602 ; N uni20B8 ; G 1825 +U 8377 ; WX 602 ; N uni20B9 ; G 1826 +U 8378 ; WX 602 ; N uni20BA ; G 1827 +U 8381 ; WX 602 ; N uni20BD ; G 1828 +U 8450 ; WX 602 ; N uni2102 ; G 1829 +U 8453 ; WX 602 ; N uni2105 ; G 1830 +U 8461 ; WX 602 ; N uni210D ; G 1831 +U 8462 ; WX 602 ; N uni210E ; G 1832 +U 8463 ; WX 602 ; N uni210F ; G 1833 +U 8469 ; WX 602 ; N uni2115 ; G 1834 +U 8470 ; WX 602 ; N uni2116 ; G 1835 +U 8471 ; WX 602 ; N uni2117 ; G 1836 +U 8473 ; WX 602 ; N uni2119 ; G 1837 +U 8474 ; WX 602 ; N uni211A ; G 1838 +U 8477 ; WX 602 ; N uni211D ; G 1839 +U 8482 ; WX 602 ; N trademark ; G 1840 +U 8484 ; WX 602 ; N uni2124 ; G 1841 +U 8486 ; WX 602 ; N uni2126 ; G 1842 +U 8490 ; WX 602 ; N uni212A ; G 1843 +U 8491 ; WX 602 ; N uni212B ; G 1844 +U 8494 ; WX 602 ; N estimated ; G 1845 +U 8520 ; WX 602 ; N uni2148 ; G 1846 +U 8528 ; WX 602 ; N uni2150 ; G 1847 +U 8529 ; WX 602 ; N uni2151 ; G 1848 +U 8531 ; WX 602 ; N onethird ; G 1849 +U 8532 ; WX 602 ; N twothirds ; G 1850 +U 8533 ; WX 602 ; N uni2155 ; G 1851 +U 8534 ; WX 602 ; N uni2156 ; G 1852 +U 8535 ; WX 602 ; N uni2157 ; G 1853 +U 8536 ; WX 602 ; N uni2158 ; G 1854 +U 8537 ; WX 602 ; N uni2159 ; G 1855 +U 8538 ; WX 602 ; N uni215A ; G 1856 +U 8539 ; WX 602 ; N oneeighth ; G 1857 +U 8540 ; WX 602 ; N threeeighths ; G 1858 +U 8541 ; WX 602 ; N fiveeighths ; G 1859 +U 8542 ; WX 602 ; N seveneighths ; G 1860 +U 8543 ; WX 602 ; N uni215F ; G 1861 +U 8585 ; WX 602 ; N uni2189 ; G 1862 +U 8592 ; WX 602 ; N arrowleft ; G 1863 +U 8593 ; WX 602 ; N arrowup ; G 1864 +U 8594 ; WX 602 ; N arrowright ; G 1865 +U 8595 ; WX 602 ; N arrowdown ; G 1866 +U 8596 ; WX 602 ; N arrowboth ; G 1867 +U 8597 ; WX 602 ; N arrowupdn ; G 1868 +U 8598 ; WX 602 ; N uni2196 ; G 1869 +U 8599 ; WX 602 ; N uni2197 ; G 1870 +U 8600 ; WX 602 ; N uni2198 ; G 1871 +U 8601 ; WX 602 ; N uni2199 ; G 1872 +U 8602 ; WX 602 ; N uni219A ; G 1873 +U 8603 ; WX 602 ; N uni219B ; G 1874 +U 8604 ; WX 602 ; N uni219C ; G 1875 +U 8605 ; WX 602 ; N uni219D ; G 1876 +U 8606 ; WX 602 ; N uni219E ; G 1877 +U 8607 ; WX 602 ; N uni219F ; G 1878 +U 8608 ; WX 602 ; N uni21A0 ; G 1879 +U 8609 ; WX 602 ; N uni21A1 ; G 1880 +U 8610 ; WX 602 ; N uni21A2 ; G 1881 +U 8611 ; WX 602 ; N uni21A3 ; G 1882 +U 8612 ; WX 602 ; N uni21A4 ; G 1883 +U 8613 ; WX 602 ; N uni21A5 ; G 1884 +U 8614 ; WX 602 ; N uni21A6 ; G 1885 +U 8615 ; WX 602 ; N uni21A7 ; G 1886 +U 8616 ; WX 602 ; N arrowupdnbse ; G 1887 +U 8617 ; WX 602 ; N uni21A9 ; G 1888 +U 8618 ; WX 602 ; N uni21AA ; G 1889 +U 8619 ; WX 602 ; N uni21AB ; G 1890 +U 8620 ; WX 602 ; N uni21AC ; G 1891 +U 8621 ; WX 602 ; N uni21AD ; G 1892 +U 8622 ; WX 602 ; N uni21AE ; G 1893 +U 8623 ; WX 602 ; N uni21AF ; G 1894 +U 8624 ; WX 602 ; N uni21B0 ; G 1895 +U 8625 ; WX 602 ; N uni21B1 ; G 1896 +U 8626 ; WX 602 ; N uni21B2 ; G 1897 +U 8627 ; WX 602 ; N uni21B3 ; G 1898 +U 8628 ; WX 602 ; N uni21B4 ; G 1899 +U 8629 ; WX 602 ; N carriagereturn ; G 1900 +U 8630 ; WX 602 ; N uni21B6 ; G 1901 +U 8631 ; WX 602 ; N uni21B7 ; G 1902 +U 8632 ; WX 602 ; N uni21B8 ; G 1903 +U 8633 ; WX 602 ; N uni21B9 ; G 1904 +U 8634 ; WX 602 ; N uni21BA ; G 1905 +U 8635 ; WX 602 ; N uni21BB ; G 1906 +U 8636 ; WX 602 ; N uni21BC ; G 1907 +U 8637 ; WX 602 ; N uni21BD ; G 1908 +U 8638 ; WX 602 ; N uni21BE ; G 1909 +U 8639 ; WX 602 ; N uni21BF ; G 1910 +U 8640 ; WX 602 ; N uni21C0 ; G 1911 +U 8641 ; WX 602 ; N uni21C1 ; G 1912 +U 8642 ; WX 602 ; N uni21C2 ; G 1913 +U 8643 ; WX 602 ; N uni21C3 ; G 1914 +U 8644 ; WX 602 ; N uni21C4 ; G 1915 +U 8645 ; WX 602 ; N uni21C5 ; G 1916 +U 8646 ; WX 602 ; N uni21C6 ; G 1917 +U 8647 ; WX 602 ; N uni21C7 ; G 1918 +U 8648 ; WX 602 ; N uni21C8 ; G 1919 +U 8649 ; WX 602 ; N uni21C9 ; G 1920 +U 8650 ; WX 602 ; N uni21CA ; G 1921 +U 8651 ; WX 602 ; N uni21CB ; G 1922 +U 8652 ; WX 602 ; N uni21CC ; G 1923 +U 8653 ; WX 602 ; N uni21CD ; G 1924 +U 8654 ; WX 602 ; N uni21CE ; G 1925 +U 8655 ; WX 602 ; N uni21CF ; G 1926 +U 8656 ; WX 602 ; N arrowdblleft ; G 1927 +U 8657 ; WX 602 ; N arrowdblup ; G 1928 +U 8658 ; WX 602 ; N arrowdblright ; G 1929 +U 8659 ; WX 602 ; N arrowdbldown ; G 1930 +U 8660 ; WX 602 ; N arrowdblboth ; G 1931 +U 8661 ; WX 602 ; N uni21D5 ; G 1932 +U 8662 ; WX 602 ; N uni21D6 ; G 1933 +U 8663 ; WX 602 ; N uni21D7 ; G 1934 +U 8664 ; WX 602 ; N uni21D8 ; G 1935 +U 8665 ; WX 602 ; N uni21D9 ; G 1936 +U 8666 ; WX 602 ; N uni21DA ; G 1937 +U 8667 ; WX 602 ; N uni21DB ; G 1938 +U 8668 ; WX 602 ; N uni21DC ; G 1939 +U 8669 ; WX 602 ; N uni21DD ; G 1940 +U 8670 ; WX 602 ; N uni21DE ; G 1941 +U 8671 ; WX 602 ; N uni21DF ; G 1942 +U 8672 ; WX 602 ; N uni21E0 ; G 1943 +U 8673 ; WX 602 ; N uni21E1 ; G 1944 +U 8674 ; WX 602 ; N uni21E2 ; G 1945 +U 8675 ; WX 602 ; N uni21E3 ; G 1946 +U 8676 ; WX 602 ; N uni21E4 ; G 1947 +U 8677 ; WX 602 ; N uni21E5 ; G 1948 +U 8678 ; WX 602 ; N uni21E6 ; G 1949 +U 8679 ; WX 602 ; N uni21E7 ; G 1950 +U 8680 ; WX 602 ; N uni21E8 ; G 1951 +U 8681 ; WX 602 ; N uni21E9 ; G 1952 +U 8682 ; WX 602 ; N uni21EA ; G 1953 +U 8683 ; WX 602 ; N uni21EB ; G 1954 +U 8684 ; WX 602 ; N uni21EC ; G 1955 +U 8685 ; WX 602 ; N uni21ED ; G 1956 +U 8686 ; WX 602 ; N uni21EE ; G 1957 +U 8687 ; WX 602 ; N uni21EF ; G 1958 +U 8688 ; WX 602 ; N uni21F0 ; G 1959 +U 8689 ; WX 602 ; N uni21F1 ; G 1960 +U 8690 ; WX 602 ; N uni21F2 ; G 1961 +U 8691 ; WX 602 ; N uni21F3 ; G 1962 +U 8692 ; WX 602 ; N uni21F4 ; G 1963 +U 8693 ; WX 602 ; N uni21F5 ; G 1964 +U 8694 ; WX 602 ; N uni21F6 ; G 1965 +U 8695 ; WX 602 ; N uni21F7 ; G 1966 +U 8696 ; WX 602 ; N uni21F8 ; G 1967 +U 8697 ; WX 602 ; N uni21F9 ; G 1968 +U 8698 ; WX 602 ; N uni21FA ; G 1969 +U 8699 ; WX 602 ; N uni21FB ; G 1970 +U 8700 ; WX 602 ; N uni21FC ; G 1971 +U 8701 ; WX 602 ; N uni21FD ; G 1972 +U 8702 ; WX 602 ; N uni21FE ; G 1973 +U 8703 ; WX 602 ; N uni21FF ; G 1974 +U 8704 ; WX 602 ; N universal ; G 1975 +U 8705 ; WX 602 ; N uni2201 ; G 1976 +U 8706 ; WX 602 ; N partialdiff ; G 1977 +U 8707 ; WX 602 ; N existential ; G 1978 +U 8708 ; WX 602 ; N uni2204 ; G 1979 +U 8709 ; WX 602 ; N emptyset ; G 1980 +U 8710 ; WX 602 ; N increment ; G 1981 +U 8711 ; WX 602 ; N gradient ; G 1982 +U 8712 ; WX 602 ; N element ; G 1983 +U 8713 ; WX 602 ; N notelement ; G 1984 +U 8714 ; WX 602 ; N uni220A ; G 1985 +U 8715 ; WX 602 ; N suchthat ; G 1986 +U 8716 ; WX 602 ; N uni220C ; G 1987 +U 8717 ; WX 602 ; N uni220D ; G 1988 +U 8718 ; WX 602 ; N uni220E ; G 1989 +U 8719 ; WX 602 ; N product ; G 1990 +U 8720 ; WX 602 ; N uni2210 ; G 1991 +U 8721 ; WX 602 ; N summation ; G 1992 +U 8722 ; WX 602 ; N minus ; G 1993 +U 8723 ; WX 602 ; N uni2213 ; G 1994 +U 8725 ; WX 602 ; N uni2215 ; G 1995 +U 8727 ; WX 602 ; N asteriskmath ; G 1996 +U 8728 ; WX 602 ; N uni2218 ; G 1997 +U 8729 ; WX 602 ; N uni2219 ; G 1998 +U 8730 ; WX 602 ; N radical ; G 1999 +U 8731 ; WX 602 ; N uni221B ; G 2000 +U 8732 ; WX 602 ; N uni221C ; G 2001 +U 8733 ; WX 602 ; N proportional ; G 2002 +U 8734 ; WX 602 ; N infinity ; G 2003 +U 8735 ; WX 602 ; N orthogonal ; G 2004 +U 8736 ; WX 602 ; N angle ; G 2005 +U 8739 ; WX 602 ; N uni2223 ; G 2006 +U 8743 ; WX 602 ; N logicaland ; G 2007 +U 8744 ; WX 602 ; N logicalor ; G 2008 +U 8745 ; WX 602 ; N intersection ; G 2009 +U 8746 ; WX 602 ; N union ; G 2010 +U 8747 ; WX 602 ; N integral ; G 2011 +U 8748 ; WX 602 ; N uni222C ; G 2012 +U 8749 ; WX 602 ; N uni222D ; G 2013 +U 8756 ; WX 602 ; N therefore ; G 2014 +U 8757 ; WX 602 ; N uni2235 ; G 2015 +U 8758 ; WX 602 ; N uni2236 ; G 2016 +U 8759 ; WX 602 ; N uni2237 ; G 2017 +U 8760 ; WX 602 ; N uni2238 ; G 2018 +U 8761 ; WX 602 ; N uni2239 ; G 2019 +U 8762 ; WX 602 ; N uni223A ; G 2020 +U 8763 ; WX 602 ; N uni223B ; G 2021 +U 8764 ; WX 602 ; N similar ; G 2022 +U 8765 ; WX 602 ; N uni223D ; G 2023 +U 8769 ; WX 602 ; N uni2241 ; G 2024 +U 8770 ; WX 602 ; N uni2242 ; G 2025 +U 8771 ; WX 602 ; N uni2243 ; G 2026 +U 8772 ; WX 602 ; N uni2244 ; G 2027 +U 8773 ; WX 602 ; N congruent ; G 2028 +U 8774 ; WX 602 ; N uni2246 ; G 2029 +U 8775 ; WX 602 ; N uni2247 ; G 2030 +U 8776 ; WX 602 ; N approxequal ; G 2031 +U 8777 ; WX 602 ; N uni2249 ; G 2032 +U 8778 ; WX 602 ; N uni224A ; G 2033 +U 8779 ; WX 602 ; N uni224B ; G 2034 +U 8780 ; WX 602 ; N uni224C ; G 2035 +U 8781 ; WX 602 ; N uni224D ; G 2036 +U 8782 ; WX 602 ; N uni224E ; G 2037 +U 8783 ; WX 602 ; N uni224F ; G 2038 +U 8784 ; WX 602 ; N uni2250 ; G 2039 +U 8785 ; WX 602 ; N uni2251 ; G 2040 +U 8786 ; WX 602 ; N uni2252 ; G 2041 +U 8787 ; WX 602 ; N uni2253 ; G 2042 +U 8788 ; WX 602 ; N uni2254 ; G 2043 +U 8789 ; WX 602 ; N uni2255 ; G 2044 +U 8790 ; WX 602 ; N uni2256 ; G 2045 +U 8791 ; WX 602 ; N uni2257 ; G 2046 +U 8792 ; WX 602 ; N uni2258 ; G 2047 +U 8793 ; WX 602 ; N uni2259 ; G 2048 +U 8794 ; WX 602 ; N uni225A ; G 2049 +U 8795 ; WX 602 ; N uni225B ; G 2050 +U 8796 ; WX 602 ; N uni225C ; G 2051 +U 8797 ; WX 602 ; N uni225D ; G 2052 +U 8798 ; WX 602 ; N uni225E ; G 2053 +U 8799 ; WX 602 ; N uni225F ; G 2054 +U 8800 ; WX 602 ; N notequal ; G 2055 +U 8801 ; WX 602 ; N equivalence ; G 2056 +U 8802 ; WX 602 ; N uni2262 ; G 2057 +U 8803 ; WX 602 ; N uni2263 ; G 2058 +U 8804 ; WX 602 ; N lessequal ; G 2059 +U 8805 ; WX 602 ; N greaterequal ; G 2060 +U 8806 ; WX 602 ; N uni2266 ; G 2061 +U 8807 ; WX 602 ; N uni2267 ; G 2062 +U 8808 ; WX 602 ; N uni2268 ; G 2063 +U 8809 ; WX 602 ; N uni2269 ; G 2064 +U 8813 ; WX 602 ; N uni226D ; G 2065 +U 8814 ; WX 602 ; N uni226E ; G 2066 +U 8815 ; WX 602 ; N uni226F ; G 2067 +U 8816 ; WX 602 ; N uni2270 ; G 2068 +U 8817 ; WX 602 ; N uni2271 ; G 2069 +U 8818 ; WX 602 ; N uni2272 ; G 2070 +U 8819 ; WX 602 ; N uni2273 ; G 2071 +U 8820 ; WX 602 ; N uni2274 ; G 2072 +U 8821 ; WX 602 ; N uni2275 ; G 2073 +U 8822 ; WX 602 ; N uni2276 ; G 2074 +U 8823 ; WX 602 ; N uni2277 ; G 2075 +U 8824 ; WX 602 ; N uni2278 ; G 2076 +U 8825 ; WX 602 ; N uni2279 ; G 2077 +U 8826 ; WX 602 ; N uni227A ; G 2078 +U 8827 ; WX 602 ; N uni227B ; G 2079 +U 8828 ; WX 602 ; N uni227C ; G 2080 +U 8829 ; WX 602 ; N uni227D ; G 2081 +U 8830 ; WX 602 ; N uni227E ; G 2082 +U 8831 ; WX 602 ; N uni227F ; G 2083 +U 8832 ; WX 602 ; N uni2280 ; G 2084 +U 8833 ; WX 602 ; N uni2281 ; G 2085 +U 8834 ; WX 602 ; N propersubset ; G 2086 +U 8835 ; WX 602 ; N propersuperset ; G 2087 +U 8836 ; WX 602 ; N notsubset ; G 2088 +U 8837 ; WX 602 ; N uni2285 ; G 2089 +U 8838 ; WX 602 ; N reflexsubset ; G 2090 +U 8839 ; WX 602 ; N reflexsuperset ; G 2091 +U 8840 ; WX 602 ; N uni2288 ; G 2092 +U 8841 ; WX 602 ; N uni2289 ; G 2093 +U 8842 ; WX 602 ; N uni228A ; G 2094 +U 8843 ; WX 602 ; N uni228B ; G 2095 +U 8845 ; WX 602 ; N uni228D ; G 2096 +U 8846 ; WX 602 ; N uni228E ; G 2097 +U 8847 ; WX 602 ; N uni228F ; G 2098 +U 8848 ; WX 602 ; N uni2290 ; G 2099 +U 8849 ; WX 602 ; N uni2291 ; G 2100 +U 8850 ; WX 602 ; N uni2292 ; G 2101 +U 8851 ; WX 602 ; N uni2293 ; G 2102 +U 8852 ; WX 602 ; N uni2294 ; G 2103 +U 8853 ; WX 602 ; N circleplus ; G 2104 +U 8854 ; WX 602 ; N uni2296 ; G 2105 +U 8855 ; WX 602 ; N circlemultiply ; G 2106 +U 8856 ; WX 602 ; N uni2298 ; G 2107 +U 8857 ; WX 602 ; N uni2299 ; G 2108 +U 8858 ; WX 602 ; N uni229A ; G 2109 +U 8859 ; WX 602 ; N uni229B ; G 2110 +U 8860 ; WX 602 ; N uni229C ; G 2111 +U 8861 ; WX 602 ; N uni229D ; G 2112 +U 8862 ; WX 602 ; N uni229E ; G 2113 +U 8863 ; WX 602 ; N uni229F ; G 2114 +U 8864 ; WX 602 ; N uni22A0 ; G 2115 +U 8865 ; WX 602 ; N uni22A1 ; G 2116 +U 8866 ; WX 602 ; N uni22A2 ; G 2117 +U 8867 ; WX 602 ; N uni22A3 ; G 2118 +U 8868 ; WX 602 ; N uni22A4 ; G 2119 +U 8869 ; WX 602 ; N perpendicular ; G 2120 +U 8882 ; WX 602 ; N uni22B2 ; G 2121 +U 8883 ; WX 602 ; N uni22B3 ; G 2122 +U 8884 ; WX 602 ; N uni22B4 ; G 2123 +U 8885 ; WX 602 ; N uni22B5 ; G 2124 +U 8888 ; WX 602 ; N uni22B8 ; G 2125 +U 8898 ; WX 602 ; N uni22C2 ; G 2126 +U 8899 ; WX 602 ; N uni22C3 ; G 2127 +U 8900 ; WX 602 ; N uni22C4 ; G 2128 +U 8901 ; WX 602 ; N dotmath ; G 2129 +U 8902 ; WX 602 ; N uni22C6 ; G 2130 +U 8909 ; WX 602 ; N uni22CD ; G 2131 +U 8910 ; WX 602 ; N uni22CE ; G 2132 +U 8911 ; WX 602 ; N uni22CF ; G 2133 +U 8912 ; WX 602 ; N uni22D0 ; G 2134 +U 8913 ; WX 602 ; N uni22D1 ; G 2135 +U 8922 ; WX 602 ; N uni22DA ; G 2136 +U 8923 ; WX 602 ; N uni22DB ; G 2137 +U 8924 ; WX 602 ; N uni22DC ; G 2138 +U 8925 ; WX 602 ; N uni22DD ; G 2139 +U 8926 ; WX 602 ; N uni22DE ; G 2140 +U 8927 ; WX 602 ; N uni22DF ; G 2141 +U 8928 ; WX 602 ; N uni22E0 ; G 2142 +U 8929 ; WX 602 ; N uni22E1 ; G 2143 +U 8930 ; WX 602 ; N uni22E2 ; G 2144 +U 8931 ; WX 602 ; N uni22E3 ; G 2145 +U 8932 ; WX 602 ; N uni22E4 ; G 2146 +U 8933 ; WX 602 ; N uni22E5 ; G 2147 +U 8934 ; WX 602 ; N uni22E6 ; G 2148 +U 8935 ; WX 602 ; N uni22E7 ; G 2149 +U 8936 ; WX 602 ; N uni22E8 ; G 2150 +U 8937 ; WX 602 ; N uni22E9 ; G 2151 +U 8943 ; WX 602 ; N uni22EF ; G 2152 +U 8960 ; WX 602 ; N uni2300 ; G 2153 +U 8961 ; WX 602 ; N uni2301 ; G 2154 +U 8962 ; WX 602 ; N house ; G 2155 +U 8963 ; WX 602 ; N uni2303 ; G 2156 +U 8964 ; WX 602 ; N uni2304 ; G 2157 +U 8965 ; WX 602 ; N uni2305 ; G 2158 +U 8966 ; WX 602 ; N uni2306 ; G 2159 +U 8968 ; WX 602 ; N uni2308 ; G 2160 +U 8969 ; WX 602 ; N uni2309 ; G 2161 +U 8970 ; WX 602 ; N uni230A ; G 2162 +U 8971 ; WX 602 ; N uni230B ; G 2163 +U 8972 ; WX 602 ; N uni230C ; G 2164 +U 8973 ; WX 602 ; N uni230D ; G 2165 +U 8974 ; WX 602 ; N uni230E ; G 2166 +U 8975 ; WX 602 ; N uni230F ; G 2167 +U 8976 ; WX 602 ; N revlogicalnot ; G 2168 +U 8977 ; WX 602 ; N uni2311 ; G 2169 +U 8978 ; WX 602 ; N uni2312 ; G 2170 +U 8979 ; WX 602 ; N uni2313 ; G 2171 +U 8980 ; WX 602 ; N uni2314 ; G 2172 +U 8981 ; WX 602 ; N uni2315 ; G 2173 +U 8984 ; WX 602 ; N uni2318 ; G 2174 +U 8985 ; WX 602 ; N uni2319 ; G 2175 +U 8988 ; WX 602 ; N uni231C ; G 2176 +U 8989 ; WX 602 ; N uni231D ; G 2177 +U 8990 ; WX 602 ; N uni231E ; G 2178 +U 8991 ; WX 602 ; N uni231F ; G 2179 +U 8992 ; WX 602 ; N integraltp ; G 2180 +U 8993 ; WX 602 ; N integralbt ; G 2181 +U 8997 ; WX 602 ; N uni2325 ; G 2182 +U 8998 ; WX 602 ; N uni2326 ; G 2183 +U 8999 ; WX 602 ; N uni2327 ; G 2184 +U 9000 ; WX 602 ; N uni2328 ; G 2185 +U 9003 ; WX 602 ; N uni232B ; G 2186 +U 9013 ; WX 602 ; N uni2335 ; G 2187 +U 9014 ; WX 602 ; N uni2336 ; G 2188 +U 9015 ; WX 602 ; N uni2337 ; G 2189 +U 9016 ; WX 602 ; N uni2338 ; G 2190 +U 9017 ; WX 602 ; N uni2339 ; G 2191 +U 9018 ; WX 602 ; N uni233A ; G 2192 +U 9019 ; WX 602 ; N uni233B ; G 2193 +U 9020 ; WX 602 ; N uni233C ; G 2194 +U 9021 ; WX 602 ; N uni233D ; G 2195 +U 9022 ; WX 602 ; N uni233E ; G 2196 +U 9023 ; WX 602 ; N uni233F ; G 2197 +U 9024 ; WX 602 ; N uni2340 ; G 2198 +U 9025 ; WX 602 ; N uni2341 ; G 2199 +U 9026 ; WX 602 ; N uni2342 ; G 2200 +U 9027 ; WX 602 ; N uni2343 ; G 2201 +U 9028 ; WX 602 ; N uni2344 ; G 2202 +U 9029 ; WX 602 ; N uni2345 ; G 2203 +U 9030 ; WX 602 ; N uni2346 ; G 2204 +U 9031 ; WX 602 ; N uni2347 ; G 2205 +U 9032 ; WX 602 ; N uni2348 ; G 2206 +U 9033 ; WX 602 ; N uni2349 ; G 2207 +U 9034 ; WX 602 ; N uni234A ; G 2208 +U 9035 ; WX 602 ; N uni234B ; G 2209 +U 9036 ; WX 602 ; N uni234C ; G 2210 +U 9037 ; WX 602 ; N uni234D ; G 2211 +U 9038 ; WX 602 ; N uni234E ; G 2212 +U 9039 ; WX 602 ; N uni234F ; G 2213 +U 9040 ; WX 602 ; N uni2350 ; G 2214 +U 9041 ; WX 602 ; N uni2351 ; G 2215 +U 9042 ; WX 602 ; N uni2352 ; G 2216 +U 9043 ; WX 602 ; N uni2353 ; G 2217 +U 9044 ; WX 602 ; N uni2354 ; G 2218 +U 9045 ; WX 602 ; N uni2355 ; G 2219 +U 9046 ; WX 602 ; N uni2356 ; G 2220 +U 9047 ; WX 602 ; N uni2357 ; G 2221 +U 9048 ; WX 602 ; N uni2358 ; G 2222 +U 9049 ; WX 602 ; N uni2359 ; G 2223 +U 9050 ; WX 602 ; N uni235A ; G 2224 +U 9051 ; WX 602 ; N uni235B ; G 2225 +U 9052 ; WX 602 ; N uni235C ; G 2226 +U 9053 ; WX 602 ; N uni235D ; G 2227 +U 9054 ; WX 602 ; N uni235E ; G 2228 +U 9055 ; WX 602 ; N uni235F ; G 2229 +U 9056 ; WX 602 ; N uni2360 ; G 2230 +U 9057 ; WX 602 ; N uni2361 ; G 2231 +U 9058 ; WX 602 ; N uni2362 ; G 2232 +U 9059 ; WX 602 ; N uni2363 ; G 2233 +U 9060 ; WX 602 ; N uni2364 ; G 2234 +U 9061 ; WX 602 ; N uni2365 ; G 2235 +U 9062 ; WX 602 ; N uni2366 ; G 2236 +U 9063 ; WX 602 ; N uni2367 ; G 2237 +U 9064 ; WX 602 ; N uni2368 ; G 2238 +U 9065 ; WX 602 ; N uni2369 ; G 2239 +U 9066 ; WX 602 ; N uni236A ; G 2240 +U 9067 ; WX 602 ; N uni236B ; G 2241 +U 9068 ; WX 602 ; N uni236C ; G 2242 +U 9069 ; WX 602 ; N uni236D ; G 2243 +U 9070 ; WX 602 ; N uni236E ; G 2244 +U 9071 ; WX 602 ; N uni236F ; G 2245 +U 9072 ; WX 602 ; N uni2370 ; G 2246 +U 9073 ; WX 602 ; N uni2371 ; G 2247 +U 9074 ; WX 602 ; N uni2372 ; G 2248 +U 9075 ; WX 602 ; N uni2373 ; G 2249 +U 9076 ; WX 602 ; N uni2374 ; G 2250 +U 9077 ; WX 602 ; N uni2375 ; G 2251 +U 9078 ; WX 602 ; N uni2376 ; G 2252 +U 9079 ; WX 602 ; N uni2377 ; G 2253 +U 9080 ; WX 602 ; N uni2378 ; G 2254 +U 9081 ; WX 602 ; N uni2379 ; G 2255 +U 9082 ; WX 602 ; N uni237A ; G 2256 +U 9085 ; WX 602 ; N uni237D ; G 2257 +U 9088 ; WX 602 ; N uni2380 ; G 2258 +U 9089 ; WX 602 ; N uni2381 ; G 2259 +U 9090 ; WX 602 ; N uni2382 ; G 2260 +U 9091 ; WX 602 ; N uni2383 ; G 2261 +U 9096 ; WX 602 ; N uni2388 ; G 2262 +U 9097 ; WX 602 ; N uni2389 ; G 2263 +U 9098 ; WX 602 ; N uni238A ; G 2264 +U 9099 ; WX 602 ; N uni238B ; G 2265 +U 9109 ; WX 602 ; N uni2395 ; G 2266 +U 9115 ; WX 602 ; N uni239B ; G 2267 +U 9116 ; WX 602 ; N uni239C ; G 2268 +U 9117 ; WX 602 ; N uni239D ; G 2269 +U 9118 ; WX 602 ; N uni239E ; G 2270 +U 9119 ; WX 602 ; N uni239F ; G 2271 +U 9120 ; WX 602 ; N uni23A0 ; G 2272 +U 9121 ; WX 602 ; N uni23A1 ; G 2273 +U 9122 ; WX 602 ; N uni23A2 ; G 2274 +U 9123 ; WX 602 ; N uni23A3 ; G 2275 +U 9124 ; WX 602 ; N uni23A4 ; G 2276 +U 9125 ; WX 602 ; N uni23A5 ; G 2277 +U 9126 ; WX 602 ; N uni23A6 ; G 2278 +U 9127 ; WX 602 ; N uni23A7 ; G 2279 +U 9128 ; WX 602 ; N uni23A8 ; G 2280 +U 9129 ; WX 602 ; N uni23A9 ; G 2281 +U 9130 ; WX 602 ; N uni23AA ; G 2282 +U 9131 ; WX 602 ; N uni23AB ; G 2283 +U 9132 ; WX 602 ; N uni23AC ; G 2284 +U 9133 ; WX 602 ; N uni23AD ; G 2285 +U 9134 ; WX 602 ; N uni23AE ; G 2286 +U 9166 ; WX 602 ; N uni23CE ; G 2287 +U 9167 ; WX 602 ; N uni23CF ; G 2288 +U 9251 ; WX 602 ; N uni2423 ; G 2289 +U 9472 ; WX 602 ; N SF100000 ; G 2290 +U 9473 ; WX 602 ; N uni2501 ; G 2291 +U 9474 ; WX 602 ; N SF110000 ; G 2292 +U 9475 ; WX 602 ; N uni2503 ; G 2293 +U 9476 ; WX 602 ; N uni2504 ; G 2294 +U 9477 ; WX 602 ; N uni2505 ; G 2295 +U 9478 ; WX 602 ; N uni2506 ; G 2296 +U 9479 ; WX 602 ; N uni2507 ; G 2297 +U 9480 ; WX 602 ; N uni2508 ; G 2298 +U 9481 ; WX 602 ; N uni2509 ; G 2299 +U 9482 ; WX 602 ; N uni250A ; G 2300 +U 9483 ; WX 602 ; N uni250B ; G 2301 +U 9484 ; WX 602 ; N SF010000 ; G 2302 +U 9485 ; WX 602 ; N uni250D ; G 2303 +U 9486 ; WX 602 ; N uni250E ; G 2304 +U 9487 ; WX 602 ; N uni250F ; G 2305 +U 9488 ; WX 602 ; N SF030000 ; G 2306 +U 9489 ; WX 602 ; N uni2511 ; G 2307 +U 9490 ; WX 602 ; N uni2512 ; G 2308 +U 9491 ; WX 602 ; N uni2513 ; G 2309 +U 9492 ; WX 602 ; N SF020000 ; G 2310 +U 9493 ; WX 602 ; N uni2515 ; G 2311 +U 9494 ; WX 602 ; N uni2516 ; G 2312 +U 9495 ; WX 602 ; N uni2517 ; G 2313 +U 9496 ; WX 602 ; N SF040000 ; G 2314 +U 9497 ; WX 602 ; N uni2519 ; G 2315 +U 9498 ; WX 602 ; N uni251A ; G 2316 +U 9499 ; WX 602 ; N uni251B ; G 2317 +U 9500 ; WX 602 ; N SF080000 ; G 2318 +U 9501 ; WX 602 ; N uni251D ; G 2319 +U 9502 ; WX 602 ; N uni251E ; G 2320 +U 9503 ; WX 602 ; N uni251F ; G 2321 +U 9504 ; WX 602 ; N uni2520 ; G 2322 +U 9505 ; WX 602 ; N uni2521 ; G 2323 +U 9506 ; WX 602 ; N uni2522 ; G 2324 +U 9507 ; WX 602 ; N uni2523 ; G 2325 +U 9508 ; WX 602 ; N SF090000 ; G 2326 +U 9509 ; WX 602 ; N uni2525 ; G 2327 +U 9510 ; WX 602 ; N uni2526 ; G 2328 +U 9511 ; WX 602 ; N uni2527 ; G 2329 +U 9512 ; WX 602 ; N uni2528 ; G 2330 +U 9513 ; WX 602 ; N uni2529 ; G 2331 +U 9514 ; WX 602 ; N uni252A ; G 2332 +U 9515 ; WX 602 ; N uni252B ; G 2333 +U 9516 ; WX 602 ; N SF060000 ; G 2334 +U 9517 ; WX 602 ; N uni252D ; G 2335 +U 9518 ; WX 602 ; N uni252E ; G 2336 +U 9519 ; WX 602 ; N uni252F ; G 2337 +U 9520 ; WX 602 ; N uni2530 ; G 2338 +U 9521 ; WX 602 ; N uni2531 ; G 2339 +U 9522 ; WX 602 ; N uni2532 ; G 2340 +U 9523 ; WX 602 ; N uni2533 ; G 2341 +U 9524 ; WX 602 ; N SF070000 ; G 2342 +U 9525 ; WX 602 ; N uni2535 ; G 2343 +U 9526 ; WX 602 ; N uni2536 ; G 2344 +U 9527 ; WX 602 ; N uni2537 ; G 2345 +U 9528 ; WX 602 ; N uni2538 ; G 2346 +U 9529 ; WX 602 ; N uni2539 ; G 2347 +U 9530 ; WX 602 ; N uni253A ; G 2348 +U 9531 ; WX 602 ; N uni253B ; G 2349 +U 9532 ; WX 602 ; N SF050000 ; G 2350 +U 9533 ; WX 602 ; N uni253D ; G 2351 +U 9534 ; WX 602 ; N uni253E ; G 2352 +U 9535 ; WX 602 ; N uni253F ; G 2353 +U 9536 ; WX 602 ; N uni2540 ; G 2354 +U 9537 ; WX 602 ; N uni2541 ; G 2355 +U 9538 ; WX 602 ; N uni2542 ; G 2356 +U 9539 ; WX 602 ; N uni2543 ; G 2357 +U 9540 ; WX 602 ; N uni2544 ; G 2358 +U 9541 ; WX 602 ; N uni2545 ; G 2359 +U 9542 ; WX 602 ; N uni2546 ; G 2360 +U 9543 ; WX 602 ; N uni2547 ; G 2361 +U 9544 ; WX 602 ; N uni2548 ; G 2362 +U 9545 ; WX 602 ; N uni2549 ; G 2363 +U 9546 ; WX 602 ; N uni254A ; G 2364 +U 9547 ; WX 602 ; N uni254B ; G 2365 +U 9548 ; WX 602 ; N uni254C ; G 2366 +U 9549 ; WX 602 ; N uni254D ; G 2367 +U 9550 ; WX 602 ; N uni254E ; G 2368 +U 9551 ; WX 602 ; N uni254F ; G 2369 +U 9552 ; WX 602 ; N SF430000 ; G 2370 +U 9553 ; WX 602 ; N SF240000 ; G 2371 +U 9554 ; WX 602 ; N SF510000 ; G 2372 +U 9555 ; WX 602 ; N SF520000 ; G 2373 +U 9556 ; WX 602 ; N SF390000 ; G 2374 +U 9557 ; WX 602 ; N SF220000 ; G 2375 +U 9558 ; WX 602 ; N SF210000 ; G 2376 +U 9559 ; WX 602 ; N SF250000 ; G 2377 +U 9560 ; WX 602 ; N SF500000 ; G 2378 +U 9561 ; WX 602 ; N SF490000 ; G 2379 +U 9562 ; WX 602 ; N SF380000 ; G 2380 +U 9563 ; WX 602 ; N SF280000 ; G 2381 +U 9564 ; WX 602 ; N SF270000 ; G 2382 +U 9565 ; WX 602 ; N SF260000 ; G 2383 +U 9566 ; WX 602 ; N SF360000 ; G 2384 +U 9567 ; WX 602 ; N SF370000 ; G 2385 +U 9568 ; WX 602 ; N SF420000 ; G 2386 +U 9569 ; WX 602 ; N SF190000 ; G 2387 +U 9570 ; WX 602 ; N SF200000 ; G 2388 +U 9571 ; WX 602 ; N SF230000 ; G 2389 +U 9572 ; WX 602 ; N SF470000 ; G 2390 +U 9573 ; WX 602 ; N SF480000 ; G 2391 +U 9574 ; WX 602 ; N SF410000 ; G 2392 +U 9575 ; WX 602 ; N SF450000 ; G 2393 +U 9576 ; WX 602 ; N SF460000 ; G 2394 +U 9577 ; WX 602 ; N SF400000 ; G 2395 +U 9578 ; WX 602 ; N SF540000 ; G 2396 +U 9579 ; WX 602 ; N SF530000 ; G 2397 +U 9580 ; WX 602 ; N SF440000 ; G 2398 +U 9581 ; WX 602 ; N uni256D ; G 2399 +U 9582 ; WX 602 ; N uni256E ; G 2400 +U 9583 ; WX 602 ; N uni256F ; G 2401 +U 9584 ; WX 602 ; N uni2570 ; G 2402 +U 9585 ; WX 602 ; N uni2571 ; G 2403 +U 9586 ; WX 602 ; N uni2572 ; G 2404 +U 9587 ; WX 602 ; N uni2573 ; G 2405 +U 9588 ; WX 602 ; N uni2574 ; G 2406 +U 9589 ; WX 602 ; N uni2575 ; G 2407 +U 9590 ; WX 602 ; N uni2576 ; G 2408 +U 9591 ; WX 602 ; N uni2577 ; G 2409 +U 9592 ; WX 602 ; N uni2578 ; G 2410 +U 9593 ; WX 602 ; N uni2579 ; G 2411 +U 9594 ; WX 602 ; N uni257A ; G 2412 +U 9595 ; WX 602 ; N uni257B ; G 2413 +U 9596 ; WX 602 ; N uni257C ; G 2414 +U 9597 ; WX 602 ; N uni257D ; G 2415 +U 9598 ; WX 602 ; N uni257E ; G 2416 +U 9599 ; WX 602 ; N uni257F ; G 2417 +U 9600 ; WX 602 ; N upblock ; G 2418 +U 9601 ; WX 602 ; N uni2581 ; G 2419 +U 9602 ; WX 602 ; N uni2582 ; G 2420 +U 9603 ; WX 602 ; N uni2583 ; G 2421 +U 9604 ; WX 602 ; N dnblock ; G 2422 +U 9605 ; WX 602 ; N uni2585 ; G 2423 +U 9606 ; WX 602 ; N uni2586 ; G 2424 +U 9607 ; WX 602 ; N uni2587 ; G 2425 +U 9608 ; WX 602 ; N block ; G 2426 +U 9609 ; WX 602 ; N uni2589 ; G 2427 +U 9610 ; WX 602 ; N uni258A ; G 2428 +U 9611 ; WX 602 ; N uni258B ; G 2429 +U 9612 ; WX 602 ; N lfblock ; G 2430 +U 9613 ; WX 602 ; N uni258D ; G 2431 +U 9614 ; WX 602 ; N uni258E ; G 2432 +U 9615 ; WX 602 ; N uni258F ; G 2433 +U 9616 ; WX 602 ; N rtblock ; G 2434 +U 9617 ; WX 602 ; N ltshade ; G 2435 +U 9618 ; WX 602 ; N shade ; G 2436 +U 9619 ; WX 602 ; N dkshade ; G 2437 +U 9620 ; WX 602 ; N uni2594 ; G 2438 +U 9621 ; WX 602 ; N uni2595 ; G 2439 +U 9622 ; WX 602 ; N uni2596 ; G 2440 +U 9623 ; WX 602 ; N uni2597 ; G 2441 +U 9624 ; WX 602 ; N uni2598 ; G 2442 +U 9625 ; WX 602 ; N uni2599 ; G 2443 +U 9626 ; WX 602 ; N uni259A ; G 2444 +U 9627 ; WX 602 ; N uni259B ; G 2445 +U 9628 ; WX 602 ; N uni259C ; G 2446 +U 9629 ; WX 602 ; N uni259D ; G 2447 +U 9630 ; WX 602 ; N uni259E ; G 2448 +U 9631 ; WX 602 ; N uni259F ; G 2449 +U 9632 ; WX 602 ; N filledbox ; G 2450 +U 9633 ; WX 602 ; N H22073 ; G 2451 +U 9634 ; WX 602 ; N uni25A2 ; G 2452 +U 9635 ; WX 602 ; N uni25A3 ; G 2453 +U 9636 ; WX 602 ; N uni25A4 ; G 2454 +U 9637 ; WX 602 ; N uni25A5 ; G 2455 +U 9638 ; WX 602 ; N uni25A6 ; G 2456 +U 9639 ; WX 602 ; N uni25A7 ; G 2457 +U 9640 ; WX 602 ; N uni25A8 ; G 2458 +U 9641 ; WX 602 ; N uni25A9 ; G 2459 +U 9642 ; WX 602 ; N H18543 ; G 2460 +U 9643 ; WX 602 ; N H18551 ; G 2461 +U 9644 ; WX 602 ; N filledrect ; G 2462 +U 9645 ; WX 602 ; N uni25AD ; G 2463 +U 9646 ; WX 602 ; N uni25AE ; G 2464 +U 9647 ; WX 602 ; N uni25AF ; G 2465 +U 9648 ; WX 602 ; N uni25B0 ; G 2466 +U 9649 ; WX 602 ; N uni25B1 ; G 2467 +U 9650 ; WX 602 ; N triagup ; G 2468 +U 9651 ; WX 602 ; N uni25B3 ; G 2469 +U 9652 ; WX 602 ; N uni25B4 ; G 2470 +U 9653 ; WX 602 ; N uni25B5 ; G 2471 +U 9654 ; WX 602 ; N uni25B6 ; G 2472 +U 9655 ; WX 602 ; N uni25B7 ; G 2473 +U 9656 ; WX 602 ; N uni25B8 ; G 2474 +U 9657 ; WX 602 ; N uni25B9 ; G 2475 +U 9658 ; WX 602 ; N triagrt ; G 2476 +U 9659 ; WX 602 ; N uni25BB ; G 2477 +U 9660 ; WX 602 ; N triagdn ; G 2478 +U 9661 ; WX 602 ; N uni25BD ; G 2479 +U 9662 ; WX 602 ; N uni25BE ; G 2480 +U 9663 ; WX 602 ; N uni25BF ; G 2481 +U 9664 ; WX 602 ; N uni25C0 ; G 2482 +U 9665 ; WX 602 ; N uni25C1 ; G 2483 +U 9666 ; WX 602 ; N uni25C2 ; G 2484 +U 9667 ; WX 602 ; N uni25C3 ; G 2485 +U 9668 ; WX 602 ; N triaglf ; G 2486 +U 9669 ; WX 602 ; N uni25C5 ; G 2487 +U 9670 ; WX 602 ; N uni25C6 ; G 2488 +U 9671 ; WX 602 ; N uni25C7 ; G 2489 +U 9672 ; WX 602 ; N uni25C8 ; G 2490 +U 9673 ; WX 602 ; N uni25C9 ; G 2491 +U 9674 ; WX 602 ; N lozenge ; G 2492 +U 9675 ; WX 602 ; N circle ; G 2493 +U 9676 ; WX 602 ; N uni25CC ; G 2494 +U 9677 ; WX 602 ; N uni25CD ; G 2495 +U 9678 ; WX 602 ; N uni25CE ; G 2496 +U 9679 ; WX 602 ; N H18533 ; G 2497 +U 9680 ; WX 602 ; N uni25D0 ; G 2498 +U 9681 ; WX 602 ; N uni25D1 ; G 2499 +U 9682 ; WX 602 ; N uni25D2 ; G 2500 +U 9683 ; WX 602 ; N uni25D3 ; G 2501 +U 9684 ; WX 602 ; N uni25D4 ; G 2502 +U 9685 ; WX 602 ; N uni25D5 ; G 2503 +U 9686 ; WX 602 ; N uni25D6 ; G 2504 +U 9687 ; WX 602 ; N uni25D7 ; G 2505 +U 9688 ; WX 602 ; N invbullet ; G 2506 +U 9689 ; WX 602 ; N invcircle ; G 2507 +U 9690 ; WX 602 ; N uni25DA ; G 2508 +U 9691 ; WX 602 ; N uni25DB ; G 2509 +U 9692 ; WX 602 ; N uni25DC ; G 2510 +U 9693 ; WX 602 ; N uni25DD ; G 2511 +U 9694 ; WX 602 ; N uni25DE ; G 2512 +U 9695 ; WX 602 ; N uni25DF ; G 2513 +U 9696 ; WX 602 ; N uni25E0 ; G 2514 +U 9697 ; WX 602 ; N uni25E1 ; G 2515 +U 9698 ; WX 602 ; N uni25E2 ; G 2516 +U 9699 ; WX 602 ; N uni25E3 ; G 2517 +U 9700 ; WX 602 ; N uni25E4 ; G 2518 +U 9701 ; WX 602 ; N uni25E5 ; G 2519 +U 9702 ; WX 602 ; N openbullet ; G 2520 +U 9703 ; WX 602 ; N uni25E7 ; G 2521 +U 9704 ; WX 602 ; N uni25E8 ; G 2522 +U 9705 ; WX 602 ; N uni25E9 ; G 2523 +U 9706 ; WX 602 ; N uni25EA ; G 2524 +U 9707 ; WX 602 ; N uni25EB ; G 2525 +U 9708 ; WX 602 ; N uni25EC ; G 2526 +U 9709 ; WX 602 ; N uni25ED ; G 2527 +U 9710 ; WX 602 ; N uni25EE ; G 2528 +U 9711 ; WX 602 ; N uni25EF ; G 2529 +U 9712 ; WX 602 ; N uni25F0 ; G 2530 +U 9713 ; WX 602 ; N uni25F1 ; G 2531 +U 9714 ; WX 602 ; N uni25F2 ; G 2532 +U 9715 ; WX 602 ; N uni25F3 ; G 2533 +U 9716 ; WX 602 ; N uni25F4 ; G 2534 +U 9717 ; WX 602 ; N uni25F5 ; G 2535 +U 9718 ; WX 602 ; N uni25F6 ; G 2536 +U 9719 ; WX 602 ; N uni25F7 ; G 2537 +U 9720 ; WX 602 ; N uni25F8 ; G 2538 +U 9721 ; WX 602 ; N uni25F9 ; G 2539 +U 9722 ; WX 602 ; N uni25FA ; G 2540 +U 9723 ; WX 602 ; N uni25FB ; G 2541 +U 9724 ; WX 602 ; N uni25FC ; G 2542 +U 9725 ; WX 602 ; N uni25FD ; G 2543 +U 9726 ; WX 602 ; N uni25FE ; G 2544 +U 9727 ; WX 602 ; N uni25FF ; G 2545 +U 9728 ; WX 602 ; N uni2600 ; G 2546 +U 9784 ; WX 602 ; N uni2638 ; G 2547 +U 9785 ; WX 602 ; N uni2639 ; G 2548 +U 9786 ; WX 602 ; N smileface ; G 2549 +U 9787 ; WX 602 ; N invsmileface ; G 2550 +U 9788 ; WX 602 ; N sun ; G 2551 +U 9791 ; WX 602 ; N uni263F ; G 2552 +U 9792 ; WX 602 ; N female ; G 2553 +U 9793 ; WX 602 ; N uni2641 ; G 2554 +U 9794 ; WX 602 ; N male ; G 2555 +U 9795 ; WX 602 ; N uni2643 ; G 2556 +U 9796 ; WX 602 ; N uni2644 ; G 2557 +U 9797 ; WX 602 ; N uni2645 ; G 2558 +U 9798 ; WX 602 ; N uni2646 ; G 2559 +U 9799 ; WX 602 ; N uni2647 ; G 2560 +U 9824 ; WX 602 ; N spade ; G 2561 +U 9825 ; WX 602 ; N uni2661 ; G 2562 +U 9826 ; WX 602 ; N uni2662 ; G 2563 +U 9827 ; WX 602 ; N club ; G 2564 +U 9828 ; WX 602 ; N uni2664 ; G 2565 +U 9829 ; WX 602 ; N heart ; G 2566 +U 9830 ; WX 602 ; N diamond ; G 2567 +U 9831 ; WX 602 ; N uni2667 ; G 2568 +U 9833 ; WX 602 ; N uni2669 ; G 2569 +U 9834 ; WX 602 ; N musicalnote ; G 2570 +U 9835 ; WX 602 ; N musicalnotedbl ; G 2571 +U 9836 ; WX 602 ; N uni266C ; G 2572 +U 9837 ; WX 602 ; N uni266D ; G 2573 +U 9838 ; WX 602 ; N uni266E ; G 2574 +U 9839 ; WX 602 ; N uni266F ; G 2575 +U 10178 ; WX 602 ; N uni27C2 ; G 2576 +U 10181 ; WX 602 ; N uni27C5 ; G 2577 +U 10182 ; WX 602 ; N uni27C6 ; G 2578 +U 10204 ; WX 602 ; N uni27DC ; G 2579 +U 10208 ; WX 602 ; N uni27E0 ; G 2580 +U 10214 ; WX 602 ; N uni27E6 ; G 2581 +U 10215 ; WX 602 ; N uni27E7 ; G 2582 +U 10216 ; WX 602 ; N uni27E8 ; G 2583 +U 10217 ; WX 602 ; N uni27E9 ; G 2584 +U 10218 ; WX 602 ; N uni27EA ; G 2585 +U 10219 ; WX 602 ; N uni27EB ; G 2586 +U 10229 ; WX 602 ; N uni27F5 ; G 2587 +U 10230 ; WX 602 ; N uni27F6 ; G 2588 +U 10231 ; WX 602 ; N uni27F7 ; G 2589 +U 10631 ; WX 602 ; N uni2987 ; G 2590 +U 10632 ; WX 602 ; N uni2988 ; G 2591 +U 10647 ; WX 602 ; N uni2997 ; G 2592 +U 10648 ; WX 602 ; N uni2998 ; G 2593 +U 10731 ; WX 602 ; N uni29EB ; G 2594 +U 10746 ; WX 602 ; N uni29FA ; G 2595 +U 10747 ; WX 602 ; N uni29FB ; G 2596 +U 10752 ; WX 602 ; N uni2A00 ; G 2597 +U 10799 ; WX 602 ; N uni2A2F ; G 2598 +U 10858 ; WX 602 ; N uni2A6A ; G 2599 +U 10859 ; WX 602 ; N uni2A6B ; G 2600 +U 11013 ; WX 602 ; N uni2B05 ; G 2601 +U 11014 ; WX 602 ; N uni2B06 ; G 2602 +U 11015 ; WX 602 ; N uni2B07 ; G 2603 +U 11016 ; WX 602 ; N uni2B08 ; G 2604 +U 11017 ; WX 602 ; N uni2B09 ; G 2605 +U 11018 ; WX 602 ; N uni2B0A ; G 2606 +U 11019 ; WX 602 ; N uni2B0B ; G 2607 +U 11020 ; WX 602 ; N uni2B0C ; G 2608 +U 11021 ; WX 602 ; N uni2B0D ; G 2609 +U 11026 ; WX 602 ; N uni2B12 ; G 2610 +U 11027 ; WX 602 ; N uni2B13 ; G 2611 +U 11028 ; WX 602 ; N uni2B14 ; G 2612 +U 11029 ; WX 602 ; N uni2B15 ; G 2613 +U 11030 ; WX 602 ; N uni2B16 ; G 2614 +U 11031 ; WX 602 ; N uni2B17 ; G 2615 +U 11032 ; WX 602 ; N uni2B18 ; G 2616 +U 11033 ; WX 602 ; N uni2B19 ; G 2617 +U 11034 ; WX 602 ; N uni2B1A ; G 2618 +U 11364 ; WX 602 ; N uni2C64 ; G 2619 +U 11373 ; WX 602 ; N uni2C6D ; G 2620 +U 11374 ; WX 602 ; N uni2C6E ; G 2621 +U 11375 ; WX 602 ; N uni2C6F ; G 2622 +U 11376 ; WX 602 ; N uni2C70 ; G 2623 +U 11381 ; WX 602 ; N uni2C75 ; G 2624 +U 11382 ; WX 602 ; N uni2C76 ; G 2625 +U 11383 ; WX 602 ; N uni2C77 ; G 2626 +U 11385 ; WX 602 ; N uni2C79 ; G 2627 +U 11386 ; WX 602 ; N uni2C7A ; G 2628 +U 11388 ; WX 602 ; N uni2C7C ; G 2629 +U 11389 ; WX 602 ; N uni2C7D ; G 2630 +U 11390 ; WX 602 ; N uni2C7E ; G 2631 +U 11391 ; WX 602 ; N uni2C7F ; G 2632 +U 11800 ; WX 602 ; N uni2E18 ; G 2633 +U 11807 ; WX 602 ; N uni2E1F ; G 2634 +U 11810 ; WX 602 ; N uni2E22 ; G 2635 +U 11811 ; WX 602 ; N uni2E23 ; G 2636 +U 11812 ; WX 602 ; N uni2E24 ; G 2637 +U 11813 ; WX 602 ; N uni2E25 ; G 2638 +U 11822 ; WX 602 ; N uni2E2E ; G 2639 +U 42760 ; WX 602 ; N uniA708 ; G 2640 +U 42761 ; WX 602 ; N uniA709 ; G 2641 +U 42762 ; WX 602 ; N uniA70A ; G 2642 +U 42763 ; WX 602 ; N uniA70B ; G 2643 +U 42764 ; WX 602 ; N uniA70C ; G 2644 +U 42765 ; WX 602 ; N uniA70D ; G 2645 +U 42766 ; WX 602 ; N uniA70E ; G 2646 +U 42767 ; WX 602 ; N uniA70F ; G 2647 +U 42768 ; WX 602 ; N uniA710 ; G 2648 +U 42769 ; WX 602 ; N uniA711 ; G 2649 +U 42770 ; WX 602 ; N uniA712 ; G 2650 +U 42771 ; WX 602 ; N uniA713 ; G 2651 +U 42772 ; WX 602 ; N uniA714 ; G 2652 +U 42773 ; WX 602 ; N uniA715 ; G 2653 +U 42774 ; WX 602 ; N uniA716 ; G 2654 +U 42779 ; WX 602 ; N uniA71B ; G 2655 +U 42780 ; WX 602 ; N uniA71C ; G 2656 +U 42781 ; WX 602 ; N uniA71D ; G 2657 +U 42782 ; WX 602 ; N uniA71E ; G 2658 +U 42783 ; WX 602 ; N uniA71F ; G 2659 +U 42786 ; WX 602 ; N uniA722 ; G 2660 +U 42787 ; WX 602 ; N uniA723 ; G 2661 +U 42788 ; WX 602 ; N uniA724 ; G 2662 +U 42789 ; WX 602 ; N uniA725 ; G 2663 +U 42790 ; WX 602 ; N uniA726 ; G 2664 +U 42791 ; WX 602 ; N uniA727 ; G 2665 +U 42889 ; WX 602 ; N uniA789 ; G 2666 +U 42890 ; WX 602 ; N uniA78A ; G 2667 +U 42891 ; WX 602 ; N uniA78B ; G 2668 +U 42892 ; WX 602 ; N uniA78C ; G 2669 +U 42893 ; WX 602 ; N uniA78D ; G 2670 +U 42894 ; WX 602 ; N uniA78E ; G 2671 +U 42896 ; WX 602 ; N uniA790 ; G 2672 +U 42897 ; WX 602 ; N uniA791 ; G 2673 +U 42922 ; WX 602 ; N uniA7AA ; G 2674 +U 43000 ; WX 602 ; N uniA7F8 ; G 2675 +U 43001 ; WX 602 ; N uniA7F9 ; G 2676 +U 63173 ; WX 602 ; N uniF6C5 ; G 2677 +U 64257 ; WX 602 ; N fi ; G 2678 +U 64258 ; WX 602 ; N fl ; G 2679 +U 65529 ; WX 602 ; N uniFFF9 ; G 2680 +U 65530 ; WX 602 ; N uniFFFA ; G 2681 +U 65531 ; WX 602 ; N uniFFFB ; G 2682 +U 65532 ; WX 602 ; N uniFFFC ; G 2683 +U 65533 ; WX 602 ; N uniFFFD ; G 2684 +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ttf new file mode 100644 index 0000000000000000000000000000000000000000..f5786022f18216b4c59c6fb0c634b52c8b6e7990 GIT binary patch literal 340712 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

JVuh<&iTWp{J;w*9G-ib5g= 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

( z!US=!j6dBA3^}xM^O4}7zG5xs$>(G0Y0Pzvz8o4j>VHLJN@?5p7b45!hJeo7L1+D* z63kU+4_ZICO3$z2cGj(7RK%3jylLIB zouf*IR1DxSzc_aIiw>jg8GA_YB!^hRfj}ML;r`>*Nu=vP0BRspfr}1DD<6vLc z;C}G|5ix3up{6D^gX8)`M|GZ4_Otj>8Vnh4qK$0MiyX-%cfCq`;7a?kqs2Qlzm6Z z%h=PR2BnDoXXytvg;Fw~%AfPV=MG>kUGX`+ltBIKUHQ(x7>e!+i!GCb3e$$W`iFW9 zcMl458$Mi};1!%GedyykaVJjJ)y_>!ZDt#(c3uMiDU8>;x`B8^rF2l7gn5vQz^Td3 zy|Y19TwcIr8cR7Gvl1soM%B%n80Fy5J3ZguZ^DFL;bEC0hf6MOOnppjv72i;ttiOT zgq5>x!uT?+gMAbDJsPsK9^-eH&#iU1W4tdJE^^2V79J+l6_=J44=gSHfjqZtUbA|$ z^v=|V$&HPZ8>SA}w|z%T%Z}|bO^Pwr6pY2AYMCbbOICVrlWC)(;=szVU9GLVG($rI z2gTG+oHR0Sh>!G>jm;r;<&d>4j9SyfCKoq(ylC-b88+_Ygu!({`9jW1mK41ifHam4 zEG`v4-o9_&_J*lb8$c@=7x81+C*tk~@}+W|B(C4g?*7O7IiDUh*Z}A}?iCnTOOLm^ zK?%~?i4(a6ShcD-v790cxdIfvXK#uXc`q6O8RlH@#T?YMfcHbPBdxZQ1>2Lmjhb*_ zI#1rjWX)PSd&JqZiVH{c*nzZ&{K4a>AnzzXLZzVLB!#j3dD&NxJ+ zN2HG&E-u7oN@GD@Z8>g7FDuhVHgOn?+J&v+4V?AoF#JudCLCwkbfSFV_>nlqd0}{5 z!ZKlNZEQkjZe5-Ikc6RSG9I1zTQ8}dq0!UzxkeY#{+_>u@4dYy?xYcHl!bGmkp?6xyt>OI-8lJ9InCN~HjCD%^4(<_WAknfwtTk7u(v6IC zRr0fqcor$lHdhG)pFJyWei&&fT)h`e|+cO zySp@{tgs+;X^RK~yTDRZu%Ut?0xBY6!`=&)VDB}ysIeq5N=&}S#Kc6ODK93*B%1hQ zOf==CnCeU3GkIw*MRza%&zXDg?t=RM-`^Kp+&z2d%$YN1&YU@S<_ykuAs=f9j~Boi zC-L_1ET&>M_QPpwlW2j|I3!pJ5l~iwbt~50yLJ7tb*F#$$ABYMV-NP)wLb0s>F56W z&vVmuXPn-6>4Oj0gSeU?!O5hk$WvX?4n5_wq`ppm9ii<%snp;*4BiRG()lJKu`VRoA-oH5N# z(5U0Ob%*t!xadxXLU<8|g5@fPVoBpXvJ?UvEc6$b>!aYi;At(LO3hJhqY+y(t(anz zV3o4oG#c>4#ti?%+#w-eXh_beW0l1@;uxRAnEKK6kL23znYOX^*?593NjZyOWbbAR zH~iyL_r)a(1sNTpYj^LhsqytUjSdelF1lVUiDNfT;d0`(2lGfrzSBXQY1Qcs_w*R8 z4l7d6m__cGC>{%90m5U8=RUM;>q8H12@UfL?Gk?6v}^9hiobN29+n+dH>Q5b(E23( zss&eO?LKm3_kB3j7-0*yJJMzi&T+^;7=7l?oUvfRjBd29{Xfm~m#arU`EbtMt{HQS zrq7u&YTTqDBkG4`Oz+uiu5HcUO7X{bRozBT2n-ry>QLxN?>;y)J~gv_;K=svYRYo@ zq0V6#yZ4~Y+}1%4qAB_cGfIXIE}nSL>h4*;{4(#w7pKlPh(o&M=T*2q#q^staSZ7e zV`E`|XJYKre8D|%3oLK~o^4@;2fxHY!MnHjo@ZU}yDvX)(!rhiQPIMII`&3|>$^IC zKBXm;_>+!uf1@4z?nF?^%(1FB0p88wu!vztxUVr}UK?j)`%;!Ie!QR&uEsrw+xQyG zo*|w`u*dIgpOuRT?rxu*53oVpKntuFp%T;(jcy!BVVt3qN3u7x;KfBF`zLEvO|Xe>g|iU9Vift`CH3R8hg+Q~IYb@HYZq>0d;_ z-0YEa6)JB0mP&p5Ejd@>e^llwD!?B-V|oI4XsL}MeD#f1ir6cSJk5A48=62noHOa< z0(G;nZr;3xGe;NAo3k*$Vh^2D%EW;^!~M}_XWHVq!d%yuVMPf!_eUp2qP1wp5YS$X zTQR8Z-qWi^Se2i*erLn{=Mje3UQ$vsZ$aY<1p7(RSzox9IKlSVc6K+#_ARvs_O6uZe42MdN?crH4opl?d2 zVZ&lmJ3B^XWF%&pEkly6!hwD)V|ZG6PHr8!zGL#DqI&jTA^)wP|Ipl;+}wp!mlAJ^ zX%iPKdYq*rJKJ~(uLQ#L@KM7Q7E9@Z-kkT`m7Vl*V+!3pgwqo*VmOg<)T z8sa+6uCnCv^74WA?HpKM{&`J$ik^+vr=$;)ANIAR*9=d$=wqsf9DKMMKMx-qB6iCe zH!i1}e5o|8Temb`AA3^VgYguNOfi(9j<0W&92=-g9h>TG=P*;6XL@cUV!JIOtVn2M z-@^{=nb5Voyz7KLa{ZoZMdjs1)8?f`cIgs%&=%9BON{=}y1FfaJ&1=MfotpP*0k$Q zob+xtQqE|f)P2FiZb@<>d%s<$ZVMN5#||~fOk10D#RneDRq8@Y9ZeV+^mL2+zt-e# zqUU*%k^x$om&J;#DS5+E(_&*srZi<|4=mr1*S%e4&z%S7*t3hf7j>(wiM34aG<9@I z-<8Grd6H`^=I`)~#Lx~QKH;5H2M)8_eMO_vk?~pi(Sd=s^i0E@*j=Y_0=d-hNDU>B_vkNh@h(7O^TP*X{R5Mvc@4aF+~q1wg*( zJHlp(@p%!om|&unz&6c|2|4Icn5%9u@YJtlKHr%>k4>D{*f=jW&ry2MQueXD*J>@V zcVvls>sUuTm&L2jH99{ka_vgJfN_vZ$B7`5IAN3cH0q(aBrH0=QkF*ptYqK04}(Qi zHtw8_V`053XP%lltcaO*_3Lv&{`#4oWzsWsP1Z$a!>3OlUO7LZsV;BHfK|d09Q;M$8ydkSU$xbfzu9 zwzXM9@^IE`_~52kauwBhuCi93*d{`pFE@SqNfYyZKsbPu zx0nT+#dWk30vlI%$@l1k>gDd$qu8rNw;p{u7rchy1ILFC;?`QMpip=Udw_QJ;OL0i zGBnvLAIF7FujvEpY*Qj(6cB|qf2caH~|8;JCxBTtv$s4z_ciXj_o`#4-w8at)a+M%|XycU1SUcnGvg7`k2SJ-C z+Ym!m)~T(cIlLyJp;txs$!DG}T+%CNY43$g8z;?RfmDt7XqclI$lP(_alr7M{T400Y@_TD$4i0G=QKAc)F5j>i>{V6qMqXoRDZHs|Eu^u$uJ=(SvS8Hk2{3pljvKxTWI43w53vM z%i9D+K!?LAuSkf}77oXXR>23)xCxQk(i$Id1z%~42YPKP@-z!CUt0$ibg{02ca{0(xXO8;aV`jIOBNiIVT|25#3bN)|;PazcqG>grJvpSoPG{;P{zotLl2>Z%73J>CdjIrqBF97fTIN9 z9nhadpZXcRp~VWm18|~Ga0LAUSMWC=Uy#DjDGghp54ggQ0tYsSUqC+_IRB?PJ{%Md zKLL1e&c6a5pu$N$7t}GN!x%D9{%Y`f1Mm|Hyd{al%Q<`l3vsq{I%q7MYuKdizzz8CzE z8-Kq_U#Ztaf4@p!;nPDuQpG>nhM!0kUm0f_{!qwmQ7d_3l>z>z13pu+MV$W%l^+G) zV^e|cg&&0WZspd%jSo32@{+$BAMlxc94qqC@He5}5-&Z^Qt5O3H>mW{>wM`1J~x3* zi5Go0KH!mF^ga0dReVKm9{l|(z5@5)N2>UW+&uV^D!u~O@cBKv#y?>-Y>=CkFER~5 zMp%5D1p&YOP9oz?j2mb&yAODHd3WCtGwjf3SZG< z!q=Zs>31W1kG<2s?54k8rLV|cx*bKjZ^F<#HhX zDAoVy9*1sxzztsfx59VRr%amEJJ3<|-Bl{1)q$Qv8TWS?kl!J9IRl;X;$>C=?&Ad? zrouBo>yVe;y72+`(Ld6u%xb*M?yQx?V3E0j*W(xbe}BJLAtUz8ycC z&&N8J*qXln4Cqgx47Y9Qd+Y$X@#06d1K#*(mpZPw+}!vC_iC@ke+b(9l9wJAs`N20 zOKaR?!k`L3O@k+?Z$bK zzo6^F?PNEO{}$juB!6LIuo3h}YWQf^cBOx9WIute-~%2cjaB-$75;t|UzvA3`1@7- z=eXQ7`me%XDgKQDFH`CB@o)H&`myDZ?p@S?5eGTo2l~?y^)AqL092DRZ?6ImAh_0E zn*Y4~OV&fB&*u|Ee2_sDINc<)M_D5&`s!IDjZ@c13S3(waeP&d(8~}5&b|_VYd|MK zk>j_Jqu#03r}Pu%w{`~Ia%dsw2N`J$2%=IB<1)c`2=m)|=y_MP05clsDfMuFo8~X7 z#j74#i#2|G(W{=wNp*vaiwFSt?o0sMs0-d6ZK0axY^ zMQ)z?fc!R^KNPrT&wbIZ^J;tN^Y+f>^sRs&MSHEf`7I5kS!@o6yYbQ9JLC7d1HRJU z+wmRH=S8jY!T)(f1mKUi%;)v0`~ZHGa*6})&5tr}yyuIqoKMBR@%iE+*?(=k^YP*} z9|7Bg5Bm)Ix|>|1QG&)7^#7Qu|H`_^o4!Z?HToqj|B!Z3ULXOsD9B*=K&9UXZVbFL z-0<~X;6L33{>@$BKYPQCm)-nazYF{q70%ns`Tv|Okl_OvD<(}29=I`3o<(rv3W0n) zaKqOw^x7TZKPm8*j&1P2aiM19S~0YN|E$7a;qoW`6@IQO{Irn2eT=tDf&ZfLqvPi! zh#wJl$4mZg;BNW1fxG437Ou&^EnJg-TevF!mZjjcoXZD2OY(GqbF{Y&+!(09T^rlr zf9>2w__x7-QsA<&4gNPy$OHJ0YO8vGR^Ylb_`4BwD zi@qkGws1{9IUVXpQQ=3^&$e(?KU>Jp>Br>>OfFA&3Xo?TIONIUuA(;hUpo;If_&P- ze^TLx+u(oWT+H!F-@NPnS%J%#2M|{x{Z#n5?&?kWx50l=;0)^?@e-F0dd{PtZQ*YD z{|ER#df{vKp)FjMKeK`#Mg9tXRsPJ>2CmAV#S%YU{tCV-|J&f2{7G*OT>jtQrq5n* zw?30Rz2JtgolkOkwuS$sz_~tq<9q9~H(b?c8Pp^Lm%qZ#b!8mg2LDBYD{%rYPlOOW z@^1@w%U|&W$(|_qn*7_sHT`c3*Yv+FT(b`sFwfR;dH$fv^Y0{|mZh!XZh3BO4Tn5c z`_Kli*@p+(z`s%LGx6hH@6QUHq9VA{n%WDE@sdv)xLZDL;BNcS7Ou&sEnJgNTexN) zIGpRJiSwh`hqmxvbojxzgBGas5ggOkJIM$0k)m(oTf?Dmd>-fXjyJwr-&*5Co?H**Q*GeisN)e{M5}s#R^jL!X&sld z!q0VuA3lD);oA6B{3wdowUGREy_9}OzmVTG0dXUEZ}3-?`51VLAK=E*;08fikMVhi z{CZ{napP%lgWx234AO<&COmE@H9XaBQ@t);uQJXFkJ}3kPqi<=6X5}YKRenznbR}1 zYKI0lh>;vm>35>X``1lRgBx(aA<-+ryvzMg17-klbLjvd4_@$;yTCi$1)h3mI8laO z=&Z?It5=1mdBdq+4e7Vj;cz?w@ZvKGbolr*WDwl&zDmafM}*r0m#4b%F<$Qow|T=` zI=b;e8TgPh$*slE22MAG68sf{b3Sug(b?*T=X%3Eew6_l8DtbL$>({$D0&2YYJjD= zBfQUD;3c=gXg=qPabK^}fu2B2NszcG{n?v}q793GYj z?kaNQ54;P!ycPVg8()$CAVtnDlBZIy0#~0`$m0mk`5){}#|vKR4d;5!?XsbX;KC(^ zz84&R+#TUd?gEFWb0>VF3^^=oOJ9XA_l9%+SKLmA!&iF4TP~oz+|C+Sar%%3*TeB{ z_-b#sYoi;!<}UEH-f;Pp8()$0I)%P`s11C*3jdSfoKHL#@$|d=q#KTviU+RRU;b>D z;AEY-9&)?vc|PHRgAUp2WWy$o-^yM|i!}S*#*P7>>^t>~X5YBor*$}=4-6k_^>X@v z8{Te(p9H&mOnE-d;h(Gc3OtjZCws$NASc)*su!5>Cq#9f8KJ@r!Uw#a+)nYh0^zyG z5Bs-tR`>$rmPZ0wT9EK>sBp8TS=B6L%~QU|8A@c+z{RDswN&`xr+e@HN&l+c((u4> z%ssLCXz>JMZTx8#|6C%TFmB?pYVbsDX4RMjv^gu;u$6diZG$LQ#OJs+aNaiO?f4Yi zQ`cmgOcnYh(@(wem!Ii~~fm}I1`^83de&@1pIpyZV|43)~TF7enfZ_#2fnqg819w%NZ^EU1&@W-!F?4kS+#<5Spnjal|qNhO6KL2XRox@p!z(qvNmwHFU{-Y zvgLF&*{XC&whCO6ZQHT_i^_M~v97|oekx-f5HI~iq>I}Cg8;p!wHZD)av%Cfj;F?M zm|0&UZl`wR84@p#aXAONRs{I-yxp+9_-vMb5PqY+B5zLh-8NI78upMJTF+hd%t-P5 zTEhvSd_Qk|zBVDwK(cLo?TK* ztattY1rK~j<7S^{4AF?OkJ2HY6J*qlYQgNoWvP>+rOPcNp-VmaH~6bVUT=0ud_zn} zUL3tHyx3oNSj4FVNf*rwL06ntE-G!rzGD-vPkzgJZr@n(jZ17P60qW@O@uV z9m?Ktmqq%J1e1{Ed~Gjo#d%v^!P9G@>`wU$;b&M)TadkZ_d~Djbj;? zl+xbyVn41aLCg`}8oT#3l{}P)_S3$HcFDY5{<@@MJl;C&E1nGCZ8Jt2eEkA~u3QA0 zY9qVeuw^REM0zhYRy;tBMS|it_G(SOq%~Zj?Nn)7i%q`bVT0~ufUlq0fM_F#-yj(T zU3r^C$fAL)4KtX)4cQd8`#+LbrFKb`U2EP| z=~=i8*(JzOcw_9obFEl<8~T5!rBKSyU&R>`YjFo3=`BA&x8Cq(fLN(#gMBNJxjg7f z*BfXh+WPgccnewb^c6S(KxfZ_p2j8FJDx`3iy8W>a^2orhozBwX{=~;O}ehdu_1=H zbU{9Ewf75pKMMDudgh0)3^wQS5*!K-futcs1v2fc#(!`oWfoj6u92s*JWx zV}rIu%1~>hT6z6!#x>+KY~Clt?q$v3!u18$;Uacf+%8$rwvfO0z9R-0hEj8=DObME z#0gX!3{JOfjBjiTI6u>5WoDel@Ej=jl9=f(@VnvnOOiTRo&84j z={j9GMK(ZVA~7A`s>28`)bGJ0%p1@!2n011vU z?4i-F(!OKH_31TkOrJ%M0P(RS;(L9@jNyQVg!b5@uK2!V#`Gl&PU^8oz2xbSvsn?k z-srbF-6WkZ*sCqMl*@r9lEVEaX6OYD_aH|s)IVJdcaR)z9ol%lkDsrvU&;7}KK?%Z|4o}3#+Uf{`uO+Z{{uE|{D$#^3i2u|^9lyB zg@X$UD)4SFyGMH`EmE6(W+NAaD_oJ%qDQI%+P4p=stRb=E})7eRZZ`zs{`7%Ygc`w zNt2=`EA@Zq`!Q*>m!W&RKf6e@ThYx`>E_->H`xep8&q>Sb)zwt zsDo~;Zi|>9C19U>$Kn7%a_WxZ+H~D~y%7W52F(uo^+tXs3-x88EJw`1h3V;XXDQ)~ z{Hy%y8FmP90nlg$jYS#_y+}0lY(7Rd**=X1r+`Bx&Fre&8C2er66E?yx&92&bp|Lh zcn4!wBpK)=`69^&(>{+8L88CnyCD6KI9(J;&xw(D2fE~yc+F@C#MxP%k4p@8sKSX)YtS$e(fzodUtbp&m^{8e8MLnq4$e8hBA8e!vlKstQ*?1 zx|{1YS=RTIE7J?p(z1p-V&QA)^e;%44gTNUBgmB zd?HfBvFDMSyZYEu^5c&^DnIe`G5O@ANlWL?Z(Oi+GMCjQq~2VB`4PScTq`MRd{}@@B-n3R}19y zH1=#*+xf{ak__AVF?g=-??mtKH2I<&$)1MW{dvnw=bRkG}w8<5c}sBhJ93_h`U6$Ah*(wkP+?+1w=h~OoxNwO>}fk zJ+MP3v#fL?&~socR|pF?$0wP?!y`%(hjmU%>pZN6{?_aofS+BvOUudzNO8sHurPC+ zr9&utc*v0BPY%J)lgEb)89rnB2k+0AK7GdfA55QtGbsJ&oG13iXt^-dbDk#19@l21 z(2>$-pPe@k2kbwk!=9`+_u&L&!#yBw(O<(k+IG5}XZ&>m$mr~Q!bdVZ&-@^Y&|?4g z0lxmmVYv3qw|&r+D_zgsu+eM~^edm~gE4UU;ZB@VvgG(Oi?HC(ym=etC2SRv?S|;D zxvtNA{`p04_r{UDXoB1#EeM-PU+2!Loy!NNcFqW~+53(wEGQ@(*B2QOOnG_3XBQP070;^8%X__7LSkY< zuipITmS*UxYwjTD^A7%YiA{Rd!l`qXn8U(4wX|%*y3*1~ zlfQUx=1d=7RL-J=kC7KGjoTZj6ig0u(UK!P$in4sry$#VxIXRAQGene@eX|Pig-%0 z^EnLYD8J7&L9&mcc14L}@ZBT$4t^GCDEX5L24RV>jAp&*tnY_{Ubtxx$TpHqMt-k^ zE^rGR!c98PIiVgu24R`JV!6Cxjq9dsHPuUH{zMtFF?N2G%b37(gt8CEj~Y30)cESE zDub}vwPdMl^-6i!av5cMK##WRV{slkuGpXx+e5vBu6)up<6;@zfolj35D3uq+?9)& zl+DDQjYd6%D{h-tUS2<~v9Z(a(nU)ovv$;0ITM?=me1MUT7D9DiPgxnQR2>@Q3K`N zDfS96>Ja}{b8lc~5SI|1Zk`)fg0crVtkDgFOvEiz*4WPtD+1mU4(soR^#|->UT>)z zhA|+n;do_kSRwLz>=r9QZ-5(?iL&c?*@13Yl&(lTC2Rv;xd+Db#8Ye!V1qm`-D|+} z1q>d#+O`i{CJQ&k34r1GfEVmf4ucP%!uo)h&B99L6@j%^VOfA3kV6;=S)9u6yX z!$Q!uGnA7=SmuU#%EAXy%k}`?HgOX0hPq*hL5h1R7m6P5R6KkuE*571Z;2ZQzd=04 z>&7xD{ zo>QMjxDe!(KZU1VbttPaW%LNg3)hyu^vNeL4OmlHWkn9h;r@O9E$98aZ-2qON`7LMJQ~k0FdCa$j!5GS`B?3A;rD=rnH_dm z!_Z_a9adB_=~|5mNdCe9AmOkBm)h82G7UJc%YYVU7SjszqPBESjL#{MKMR`n@{pR> zW`u_aZ3!#Pj^9!k5_ss)jvr0;URqr-yHsF#-Q>?Q3-$lzE?-p%WudZ${!tQj1fmZP&ZuC9}NmT zg=H%E!H?7n{!K7W7rQ%$95YJY@ts)fnk7`Yp8EawH@{;`rC~?qen;h#edIS-ejh5z zc&_kiXiow@P)1``1QQ~q zg96)%g@XtYukp()(o(^WocubAigM?JwOhSzsC-2ak?Kz@3hn*bsm;9yYSkQad z&mF>#{G<9t2+3bMXpngP?YHHhckUFkU4IvnU4L)d*`&M?lJT}_=T7gLDmFS=6Njnnp0&32dj~&kssK_>Qp&mPh#^VT8&jw?c)5nHHYWCn6b2E z;J^~6*tK}c(uOaW6nANtTKCt#Cg<1M#$_VW;E=c>Wiuz*h9_IA(tG#LDvcde*)%nM zbZ+gG!TJo>r5)?m?vO8@pEBF^nEvYQ%Jp>9KPfAI|z=hJ|wR_8|=uGbbQVj#r{iWXR=N1(evr ze{GsIdDG#MqeqWqXN67oWDFm;Wd%!Yez>|KwLGPusC!ZOs@fjYJIxrgb#;$=;HLcUQE1Z->zHB9%@2)i+3vBf4f?C^f4JrO#IS8kpS4Fs{+A|&_~^*H zQ}so}dp}(&?$F6Zo6L3xONe9^vz=KSb~9eMZ8L#hNZ87MbL@1rj@2G18tpgQe-Xky zdT!Q4*%k7&OV6@mHpj3y^J~%3w%}gF*Pc1k{`{G>!+VF=qN86c=|AI$DN$P8*eE+) zd&KFDOgf97t&Llq%f$uG4dQaVJ?nbhwO5$PB+SW>cPjMhQOLU;W$G{`*+SGog}7NK z7BA4P8Hh|Ec9zNxzkOxbvU}y9cS(!oF?hdpD+}JLe^->>mp_rWv!Oq}ck={GWr=L2 zeDufn^q6O{u4=-Wipz!$A<4S;Xf-cPyNATWbV;Z;2{yy7n^oMko$eo5fyv?j2#b9t z?nKm{l&}QjGlmm>d&J!dd$a8+)~rtH;bB3dDbUz&lIkQW&B|KLqM>_6c^y{=No7Y z@OM6C)Q<`e4r%A_Th~4(p{Q=^L$8AdA$I{*u2XT;6z9Wb!|JOh)pXHge!CpxFs@9TFZIN^J&vtu zKC@4@?|-Fv&9Pp`yRlW>zdAEotZWi|Tz@oOYI6NSZv>yFOP4M+DTm46%Rx6TLpKoZ zWPHS6u&DPNAacb!A&^XqmS>$OmZi(@zyXN`Y1@nZd>u!&)<0J_`K6)PSi8^z-_>8V z3I)zb(~j<)^tZWFuS|Bze}p{nk*{yR^~mgh+~}Jz{*t!YGtZ&Uu* zrVYLOe~_O3`PK5`CV#&{8CWV(|Exsda}eTr%AGFM9SOncegqKF6);iMUpc(P9MoZC z0PssTKpHfnddT?kL#js%uNyw1;kmh2t}Hq+e&p~vc_SOqYkpw+_7T&1NzGR$r>Ecg zDLsAid;JpQ1^Gu7YHoa=CDPoOn>byM>sCXMDKf(2S4R*YZ&q{Pl-t{v8*L zg|jZyPZLl_BkJIH!!TU)hN}^AHwi?;XCyv;-R@Z?!=+q;+;VFflGbm2lm9H+{J;T( zMZfy^(=U%4k$+_YM~)m3vRs$$V}3h9e>2uVS)fCE;2Kx+sJ{l?m#?_>(?L zPt490lq8f59a@%9Qjk8l%hLOHtxBz6Z?1D4T_?QSt$+V+T}w+({=9zu&+GJiPGrX% zxNqkJvDr_@M>{WH`7^TY&$mSB!5!NlI>_P@NViSj=E?3=&n+tI7RwO&|wv$OEA3(I__s|LM( z7-ys-urD4{AkxzlK5HY8E!o$dUWe=4Mh;tc!qRk_Wt^T@c6{uneg48J+z0X($*-?< z@UZ6}bFDLUa5aw^yM1L`y%+6h(8h#Aa}8C&mtyqJXrB_M>% zSp41+`{Gw7MJKBrAW#0M|c} zG78ss$-eioEUEd{U~%cHCr@`Tyj3S1cdn$js0MZGbW321%aQvj6@D&&EWW)!;Xv{; zy9-FFELc@Hs68&7=>iBjRD4*`^F;MJ5SlWDNmEYl9yqXUz{$x|PTpTOVE4(X%l=+l zTQ}m=-7FiwY7gw-dR~wQ%N^_?bx+z$IeFSAEmobPnqBPuj<2Mp>XCM{q>?h&#r-nS$`R zT3M41y*wIg5bLd@*Y$Bep~qgBx?$ zc)N(ps!SGTS&AXbM*;3OQ-s75?twot$>OOV1qBn5dkkIlKcAH*|9S%sPacOra|rNdw9fUAALv*`Ca-j0^HN!k~!NOJV-qOV4-4b`l;@L}}(C zWZj2!N~gh3aui@jc1jb#uMrwIsW>;#*Uz`TpPz5AkFQUVudh$f;P$>E3k(Us^O_I* ze01wWg97oySRdSOw14nulWvqSS{h}@aLPBX{_y?}!Djv>hxQ&|d&N0?%q**_F$U=` z7=w_#hrjd}hQ~8CPGs@AbR?LaIyC2y@a%>q$L1Vx9Kk$UFGsPj>sw$vTraUN`D4@= zp(l98idfpqbxj%LxRS@6p>3>i>NQtst<(!9;=-*xut_7;LEdolmj=AW`jTt}?E^E= zeldLBfX|dGNXscieMoz74Z3w)M*i5t`?@|Ib`i?wz;qo4=fjS9CN2@fFC-Cn$A!>M z(K#LL7F!OvBm8O8ce!PYn19od?zIEvZNr6UpC3HL;`iOp;txCRK|#XjL3sn4mak|U z==ge|y}G*V=!Jc2pJ6?YKgIey`K0{9Q>OkV6Ps0GuN<6>P&3(kthU9MVV}t=Va>-Z zBG#V{3+@ZH(+d|1^%N|xzU}*YUf)ywR%8FWmajFSe4FoEm%sh{MwPyw{1xZFO?hKKullF(`b+Ox{~f+J z_IH>65{gg!54cNt`kwe}{k_ItqU578TVtHV(I+(Q88&U9~PpC!y^tO5|49Q2yEoDNn z{E33~nTJCv;b})8KA;7Rw*}RNGOKvPHJu1k5n(5>g}T@^dc)gB-&F$Cs(ql7gc=j5 zZnV&jwhGS!^Rr4~0c8^_sm-6>M))A-Uw0ZdBSIX*g2iiYq-DIC zuVm~^^~QA|td0FeczS=@jp1R+OO9kufQ1y}ZfPRX_$zPAmv`PfPF|uln|*cPz1Y-x zv+^;wIB!-Gf0|wq9kj#&%~E>90h%o6ZI%H#Y?ay@2j%Gd?q$~$I!bRGROk$6o1}%} z7>ZI*3RopODasr3okMyR=B7lM&5@lPnbxrAfWW|z&;@P#g^zV>f;w94 z4znq5g%EASB4gNGR?zg{K*&lu*XVO$=EfS)t0u z-a$}3NarTo=!w-~wyR2#K#G?mOuD_40G$Chnv#Gv(Q(@);s?rxU?m^BIiQJKPBC(+ zj52sRKURgZVikxVA-NSlh?2n?TD_J3fuCz{y1v#VBSb+oSpa!U#-sOC9(8*weKwGV zC{5#CU%Sh@+u|h;crrAiF?7`K5&zZP?8-B)-=5n%qod1lg~*#wPJ={0jHqRxcwn&5b5F5B0K`H--Df|MBAgBCpuf zZ&{?$LxRoW5s{(hkRX4* z=G4w9IoVzFa%^3aJBAW3d@AvhCHR1M$lS7|ur_`vzDmDXEs}juV$j4Hn=bTmw`pf= zWIwk98jEX1AC zGqdu8JBEb>2KdfwB~>Y*mAI~6bqj1sVYUOjcQ}l;1xAK-T+&+1cWMLgM{^jS1Zxut zTA|umMZDda)&|-gN56Q6N&DmQ%f{ztWu|uu3uQJ<+Vb1Yd%Wa5wzarpX8HyMhJ_tWc{ z*87TFF2n!a&Yv||M5{xajVvY@07VGm3HjTun{D5?b~)j?^h6MJ}|o6nC6hpZp zl-nVWRQBO|@fjt&+w9!v=98UqJ@y-XmxxB|z3-ovWH!-xOP7atB=OZZaoYGcz33CH)I>Ez!|2 z`Gx(e%1NdI#fPMaq>g+|uQRz<4kBh#uhqj^X_{vNArw_$9|yPfI%%u)zWN-Vsf#%* zCxVq*S%YC!_~Pq2UkY7RrsL*jQQzE5=FF8%bG`TseG8wDd^O>I=R+*PHA(T?0Hl70 z4U-m$fAZ%;WVZMdSeT<$M%WAh#VPSi(+KTDq$jhAQ!eg`E=@{Gvi9pes%jc;g6l`0 zl1dk3hez0K={@qc6?V_cvPHzCTgV$1?};w09WilIOub?-E|XI-c;fN&-CVxOdE!r5Jpr!(^>=G`a+q% zQFya(U(zmoqtGB}h_gJpz8K>Ko})Xe;H#|rNj_TjN?UGmrB*^3qLK4Mth?UyL^rUH z1$zA`k8OaaJL=%8$`P)qXmiIOsH7V6;5;c^p~;vkB{`G-MPpLsQ3%_Ns4}pzM2Ajk?d5AG zig0j6P_)4=OwwA&izHTxt1pn;cxcBvz(c-`haa=j`Dmh|EurG;cPK{uD4n3hd~V|> z3BgM>>Z520o?e{ip_k@^yvS#j7w*tbP3Aoya|?8vR#BXxZUPs$CTvAQ7+#!-W_6S) z{pD3w8EJTA#1-E?;5_xnGqlb1RFNyH{4SDZe$;=E%iredTAnY|h8|fyzo@Rb}OG z1f{+ye=u&TR&V*=6{jN!HCn{c@ryK(WG^V~;>bXNk1Mhk4M0p29k#QwS>s*~)`Y@E0=U|b zZs8DZw`>&JR%5W)VREn8mBqL4LRDpD)nGTDn#3TTN?vOZPhITaYW-kTx4-3eDOVhW zvnGi7h4P3eMc^p*c`qWJ1+I%Uo6ivJ1;UqzfffikvuLVzT`Zt++p0V)I)x2s%Er4K zu@|A+XQ=4H4B<-xWYc^*%k@?Pf}KD~ z&lZS#of8*`@vKN4)|CtJ+on8?DAGOpA3ZOIxH84~12k&dQ9!8+AX#K8UQmBOyv8xI9 zj|tB=-^35OC49EU`xjq)v3XweA6k`v-~;K7H$BA7P?pLkxWj-7eYhG5JuMP=^QO4% zuYUy%EGLyf&+nX|W@G8Oi1KXBZG`kh9WSz}S|PUVg{Bu&H%ysloACp_L^od=9WB6R zGMW<{rqBe3S8NV@K_6jgs8z3lVx2TID+>}T+G+(tHZnr@B7Ei}>Kt!0<2;tdg!8comb0R> zXGK5fZ-eAbtWjjn7U9=dUmbZ-#&s~P@q+vq>K1grpmRQx=BwptYl0mX2is&4uCCUM%>F0NAN3LywwH0RE;IJJuNS|yM^YLQDfZ)T^?o;{C>Pz$e0zQ#L&_iIm# z5z?5JhlUL-{B{)wEg)Wh7|ud!EX%f70eVVb2BEp$j81XyhL*2>-kQ)rAU! zB=i?2Dx}R)3G5=xa_;y9k;M2-^*l=y$2g__UO|c%`a4CGyNyPYGDYKA2X&w&Sezy| ze9a$pF1>#1dC~ce`#GhUeCvh&I2q4rXgbE%e~_fv!3AknIv;B`L8v=>t{x*HOck2E z5kpI?aJ_%_tdM&4>>#eP^TlGno*RMQHS8Htl$pKrr?asAjn-?tMT@#t77Enj;g6;E31E@8wl^Z4YQo)tfHa zHu7EQrTXRM8Sq!A_-sqK9=%h9W3$O;XQlsT^Fw#?C{vD*uTC9=g zUKWbkoF-qCA)9m>Hc2TH>_|cZjC*khW>^}LG+WE}yb3Rhj1Eg^#@M8Klrnm5b&O^_ zX4Lb7^oQybs?NF!Xe_gnM1|M7mgp!IlW(WcBfj~5F6NiocKCX0z-D?O5p2$QbL zLr2Jt%hLq^8JA_p3Bl>a-G*`#TXVBB!Zhm9qk~7Svzr&lWSKl1Qv`2rk=}3rQ8k)0bA;(j~;iTu`V~MU0mN6 z`_7m*i3QBbi6}a}Tz(}jqhGPTUrt)s@O`Tb5~GKV|I17F-QT}+zrl6u%AZJkEcUl~ zPt0B=pFVI8t7^#2PwzgyYWN3F;?x1@(h1o6XvhlB1{~z!sIL>kv#tU35~n(M9c4F; zvVR?gj6~gumP1msAqP=8$})mE4x8HPT!0Bh>E*BoGOUTQMK4&2c5RH@*RgivCi!2i z_eR;qGk^`l~lP*Vn70M~^-#hq8aUrpg`I4e%xE`s>C@8>PdDe`MzGiyll0KZxg=IZ@oENdiBVR=3o|s zbj|h0y^W?b>hG)4RIT^3-@AglpDK7`1Zu(Q|AtyO#|AF4MSXgr%A>i5t&5-9 zhQp)xhRm-kElZF0VO_Fs`ot#|JSiOw_-oduil##6rbr~K?s>!t6X#-#qVQTqNV_LM&8v!?{x(>egm0E9fH z1Hfc^s)Oz6K){0V3YNZSnOQ89y9v~yE-VNe=jk1UC6znB59>B=4VTsRwQH|)S*;n@ zElha-X#e~XN0)uVgin?o9g&X*1+C>zdx{b;o@`+uK?1fj;2n%XE~awvpidm+FQ>2% z75US|(=i`W^8A6AMQA1}q8rnD()r|od%ot-v8%Bd!-_c1A18N_J&sG~%DIM8Cmbmx;t?b=<3fot)yu9b?>ZL~>TwT9DugiV4d6T;2)fEU$YsambGJVB-+10RW@znPp zdE)K4D;k$=Zd|;+f%HnmbMl+gW4vCoE<@)ij!F#o4HdtzTD}bQ{USZ`T4sPQF+9Z3 z5EIgnn#uJwI3GVyS|`tGNEwx&Gjw7E&IB9=gAv9@<(**JEFRz z=j6BY>hP|rcdsc+Gj@(xaP08Xs^#T9Ru5Tn*QE3_pt85zTHqKsI=BAO#Q7Uqu{GI`3;p83(? z#{&F}(Pe!H4DDJK+D;01Lg;;c?8Jh+xafjH`?R_rTrUcTM)t^WpC1R z+KV@;6QfPtx8&Y|MIcNVq-3zT_-%e7Kx!9S)ph8AzGcxyzkp-m(fK`(PMJJpRDNN{ z2%%o+?HZjqE7_9SDJCWkwe=V&9CE$*L)|ocVL^0UUctn%ip*EY8!+$wfqAZDu|A-k z0Xbs3I=fQtAN^*(u+704H!^Ny>Vvr$u+bLJ^f@C2JTu3lH=w@9_O*L02R%mbPQ?k|ygoU2Ll0bVVg|8PQE5v1@Ru53T0) zeVyNH`jpyUy$W)e@@`;eu3VwM?^Tei0dv5`*t*I2%aZ+k_y74Bf7>}Qc;_9V;7ioy z$a|y*4FBYO;rX+t#R>7A7Taw}Zb|&_;9_M~`fOWiV!SQVroM@iU%UhCdH2`uFP9lc zPOn0ynCN@km;ZTq=3w>h{{s~E_yyfsDMDHuWc4`(%bQ65%kRp=f{Z?=ShhTj+q)Nm z6RP0oM0`g$?*W%^G8r@yCBN0J6~6Vt!FNQDm-niJ)7Hx4f2zZqjxra4PO?uIoHGFx zOm~Tpe<^raC#}Xi%4MoUNHhV<1U!}uwTPRXPOQY7uL%Eig-NUBOLBvJNf?aj3hf() za!cIwsK)!iIsJdX+LD?0jC$l5@-X1n0Dlq3FGKynqxv}?4AQ{f7WNbNwuJDt3qRM4 z!N!fHF^Ahp_?w9LdPvVDMJZG~_1d|dxN9L0O^HYU+ z_P|7Q*B(!HcQ^ta-N*-Fqe1^w&_{(tpZ%Af@UG!b-5~@V6UN=CM`$0@Sm_?=DxIxo zBFqjyKn_!*J+8-U6{3XM%^}Y^H&!r-Z#+6-_>ew1Q~M82s+%FCx)$C)XZUw)@Q#5q z`?+_?{}lpgBUz5 zw6I3^GWw0yen#xk<*h}K?2aua)$c@TQvSKmoL(H(Pe=vIG%iGL8}pH4vVFwpqEDT?t;wl>~Ip!>JRKA&tUJA`5HV! z(`GL%7`lJ3e}JOpv6ejcux#lgB)T3dIY5kEmIQUU`uoR4{E+tr<0@}BfbU**cy#_% z*ae5KtT;K^8kd#XS%lHjd0ClJy43c0mtlCixv2 zf_{2!4C?(b2=POGkqI4nRhNekUKWK0g=d_%wJ%;hlfjV8_|wcxWzZM&&2?BcyOU$f zEFZaXOn#QqBSodzb4K*uSO(4;CdQ84$PW8+gV5nbn6GAwupz6H{MSIhS-hDz_^H3H;8p*xg&oPT#ICV&wm_-Clj=ws{O|S$YMlb0SPFEuvaaiptXS)-`o* z9BQ@QHaWuL9h2`nc1%p*lO#5)x0)pd_zIsw)>h;_!&3!aTvCo?wk3t?;`E`3)_8r6 zm?h7WPqEt5&#|Gd6t<1^mmfX-|Izj(@KF`X|I_{6%;ZiclM4utJKTYs+~G*L5+Dj< z2=^&B5>##wSmg#42{E`BP$5QCK!t#ccyg(T2f89CE}|j`>mnkV*ZF^|-+MEY0Peb< z-+z*sdGlU(b#--hb#--h^*-?&|HqTNpR_-{TkO%lk(cCW4#tiH7y-d;i8Oe?_9COx zxcy)uRAuuRA&anvL5WZ|DMqoNfqs;n#3#0C*1SQu$_AbFt=Hi0K6m!(duL2N-?Qv) zHN1X{*!JyXThtF%#dBwE(Gf#?4ahI(n;7YTR#Ykx4VpLmMu87)`{5O-?YnkNOUvxp zHoana`(DY7lrCzcD`N6HbxBK0>DRiWe1LhYF}~`!$AaU?Y6rXBt+Av2z$gAG z4%z|9`SG_YQ9D;jdYT;5t@Us|M2uVS+eh~i>v4|zzOIk$GxV~3x?ZO3m+3Cbbfnom zuD#)bg9wiV=kA(|>RiB)&)Gh&=hL(|EUKjsYo#tz^w=2wWZR%n_?T72TMh2(a}h7K zldD>>x~h3+afNReSN84L!AdGCZYPBHZ*SB&mq5VaAHU zjEamEhVlgKkE8e4v5$=%*Q@=M+8B3R0Z9Rq`F9d*qHBxoY%`=1rQ6Z9j9% z<_8{ln&cMgXx2QVEKfdUV`F#rzOxO<~7-@JPxa5muJtU1zu z;J0OBoJCvM{jpDggeu-AFKqp3-SgXY5Wn&wZ5yi;gKnSSnTAjTO1vlkhHcNU`)RA5 zU%}yVtWw+NDPNDr3#nk1??fnqSi3XX?sS9L$pQ!7#R9&%>+4ekjjFuBEH#$RHI}EI zVjlYMlyxBw4L3Bbb|^4sxIyud64vs_IHqdr4UEFYT;4>R2$FyfxuET8TSEz_0rayh zOHWIGFKFQyeX%iZ?%CPdIhVx8YM*XNJrff0l19y#JmiiM-B^bEXk{UD@AqnEH zEOkbGYOw?ojdVmm;C+LnnR^yNdb=A7eKN&*US^#N#bowY}f_; zEKRyZ*sKbNMg4pAoW0x!i!YWYzC77q+DPe?h7<&Og!vdAG0;Y=4DwjlIb7c;fXw#n zVfhs-uj&WkhXDbvo8Z&3oW*MUUIBbx=A$;TbBlxzBdiC$v!(R9p(+$A@vhURgkyUy z{7@xctq`vaqV=#rH3QXI>QlIqk|Yhuy)YYO=2ByI^mg#K>*9Ay7!JL38uTO#1^G=_ zfZ;)*67?G-UX?gFX~hrzh5BsF)3V7XMlna(y+cF>pISDr*%7f}2zy_9{E0crLXzDs zG|I@zE%&#m9J%AE2l&q>n*R-aMaP!i8vfHJ^0f;v>p*S9p!3muQkA1^5;VRnSVL%{ zAIu`4_SuzWXlIz-^Yk~ww`|ClZO$lJbi#M z+LT!%6?9erG|;sJUA@Ed!Wzq`hY)kE`v@_dXV2Wymo*U2^uwqd-;X!fHWzH=7y5M8 zHdnI7ODkSsBQq`yt{VHV`Flz(R{lFf(nBu?c4aCj-0C)}q){ER^g3W`!nf=R?N~p) zRLkwZwe!nAw-=|__PY-k z^BMRv8*9c0G?I9$$+Bm9Bs;Y_>!$gR+g{Q~XV%|pO=Jv%3A4DlmfFQEH&(`(qNszW zRbDO%khREA@*~K|$8;`6;k|n5v#m5tgM0Ms-LH4=0U0I&Ik~Q;CPM>>2GL|f3K4CT2zgelYMq~j-dHL@%)FWA6n63m3W2q(LtZfDD8Zua0yuO3Zf8?_HR zMCD7PR!(l8p7}Zr3p(Dj^{&PZiHI5Pa{dnINKDcLx(nS@!s;rG+>uS^} z`=z#xh?WU~;t>3E?E#XYVb)2*_DsC6u<8jmIzz{`4|wTQ-5)qjwwOF^2SdRivsrXO z>H5ZO0>zsxBwu*JfFpz)N6g08*{jB40y8;^jWof5W{}z9UbN{hKx-uT_E;OE^CY5Q zQs=kpo!@BSEZl<-_?!5|^)y=|`qg8{v`tgD=KsOc3&ec(YLvhxu4!BIe-j_wU@dMa ztM2ZTGGov3eveeVB{sFb-fvG4v)@~_qW_~6Z?OrffAp;?bR943<%I)98l@RxB&3*? zq#20^G!^*E?87X}&g@xAi>(V;vKZZvy(auxBZf%j{H+VbNw&42=*s?Rt$o1L3KDA}f>ta%CRyw?5>4?>P)^9Gadfm0JZ6iJ=ORkd-s`(VO zNFgsR46G^(wQkzuzb|5IQZ?}GtB4Mu3h4^n1WS@_`TxX@8UT&>Jp3IyQwVmaNDI% ze(gH0UKStsA12ORKC*F1yKS8olpHhqhIctC#-PN^M8Yz{ih)VB;|}oUO~sjA$C%F< zcCUC$>${glUt*)gbH9sod$H^6aWQ4n;p48apIqAZaHg{6^0ATyowl`Gvhm1e7B>tN z2E9IOWqlf0n%!DPxgZ+|Ccz`p~j!!yr}0 zoqAh%m18wD4}u>-<2lMx?M^#9`q&ema#%B2j@YM{^K2>`B#U9;vKStas-2O=upGS@ zsgpkqy?F#8_`!y5x)MTxq!oV{k73}{-Z-*y)vA?;u}b{>Gp0oS<=6VoClyUn8!>N@|@)(M;uszCGDKU1nroi~*wF0me`wbQ&imBrfKTo!-CU6#}^i9Cyht*tv=-L zFC`h{yvm95F2^Q&Ox(`Eo8g25Jo&i8)U>n~xTwm?aX4z_a$T4_r*iC$9b+q{44DO4vFH4GEp{h#te5F=ORjN~VAIna?R^(lZnxR(YU5Z*6PAvGNvy$W;oH$s#b4Pi^!`|fxU8~x;FdX{^fBa zRZL~;Z`%^L8!<$0W2`8^n734Y5>i;6zmSL#6x*C)X?wRhjwx4NKdx5Osy}3(tY&S+ z;nm^@%lb`e;QC(KUj3m`Dh{p2QdK4ar1RZ9@cf}un(#25xZxg5K0=NG-ub`{ zW4I4|sk7;}c&T6LBw-e1j%!(kRn*u%0nIa2B1m+ATwa+=)GCoI^f+-w-Veh^l*5vEDN&7VxpMTwzP*HBG`mNA6+Q-mw4Wa_h_rb-Ny^3?X8(LKCj=;7E?BpS)r9l>PijGryAGS$3qGrjR ztXM-u&>gJ(V=HICzyU1a9|OPoYJk!fek_}7HgCq7KjsPEKB^47WqL2&%A=Q>`u0w} zSR&rR_TJL5m(^ScpPxj(K>Nprur!M^6dw*Ark%UOW(0?^NmsOU$^x8x`K9;_8*7@1 zIj*Isk9R&$E8c<~H1Wu{pGRL2>w?2X$rT=LRb5MQVrCQ8LVPa1V9S&RARX#fRC5FN zFh8^x)>W9C9qZfiq+bELn>O2@kWtpfpQNZeLK)9!Hu?dhq4li&=@7EdC{y zu~{q_E-;f0V}ob-5w<}IxT9VBg38@X9(=`>!{(tQ1hDy);>Y(7iwkwjb;jzORnTko z-6@`OamSL8Zi$aAVjHMfEGw5#v0@V2fCA@;6)1cnD>=-<#m`6Z^t!uP<#q9p_%{UF z-zr(u`-d5Y%d-@UuIe24%}_iE;!%o<086`PAy{^9C0^(@d|D1Zx<|ZHAzrQeLD^v% z^38SOo8Tn|5XfYE{J@I$f$cS=~kW`PR4$5rg7}cTlYWx@$Y-mK7qg)bt!#n+?Yv)wx(&n4H$NL*%0x| zxMwf#Ten3e+yCM4Fzs*}@7JZ#;ly4~7qx`>zoB?$asoOH^)nN%1R1efw*Ut-S_Z%# zY27@W4fi}O4P+5rtnhrcXC*0#Tc0g^t;TXJ=LGh*KK5 z`%@rJ^OUL9xL{zV{W~pYTk`>5PHcTRvn*I(gH*(XiLTN)zc1Ty`PigIv9{IINVnHrch*uNE4(sF9k+TY!SHveVce0UgYu-KDF7+xITk4OO2D}G>TrF50 z+aS==O+>Y1D&x zt9zJWX&F`Ly^@eE78Wy4I5&64*lv zTpq)@L7mwSJsoYT8V-!Iy-!;&`$kIu?kjJCjodaYGLeUf6~u@6kp z%G%;FCU8aK-dSCaJaYFi<)S~YoV9bS%ZrzL@-uc^{Hn~t`ADb(WEgxU*>P5JrOFnz z?vJUs#ftEp8_%KF#%CzJ>WVGw`Wf5$b@bdjKlE0doN~PCiulzY_s3NE+&e$~ryXeu z7ll`<#INgY>p^>-Xem)&Qo2k034>S)RKLv?1I{SM)qAa>pnfpgEWyg1YGNo0Rn$c8O!$E5R1ejs9RN4+|GTf zsF*7Do z1&cy>z%FcKZAw|2Cs=CrLFKh(2j^a$dyws9BX<@S?iA(4?@jO7a~jdFiVaqy)F`Ym zVvo6u%i_y2vtU?8ESgVPi%oqpM1d&C=)+#P{t$zYo*GryEK9q=ZCTCY^TlD-7BIFU zesQ>306Y-g#iCD=(v?)x6h^jC(tZ{7-IdD@t^Q^6#Ei@@|GsG02X}nf?WA&K#i3;@ z-eIBB(;n(qdNTKeJ3bgX|LKdCFN6d9!@Y))OV&v77F3rAl%;7TfeuyHnl z^vq4gkp|?;OH(zR%%Jbdj!Wvq5ILJ9Hx_pg_yTq(Oy4qSD>qztu^U(ajTD?6KfYw| z;>Ck!&mO#Z@!loJmsCCYVA1T^MGrn$wL~1rZIhCl+xq_dTj%DE%w`e?qg*cwo*4d5LJM$KB~Ra^lE7@I5uuWAnz7xNdi_hcE-c)m@4-jv~SEb>Pc zYY*@a+5q5yDWgTrw@;x~X4uPH-@W%8w!T&vDHR^x+QFF;aNuac*e+Skqoaatz9ADF zKEh)4Nm$Gk_WHoCnc2>eq~KnN0P!imQA*`n=8O9LkbQ*?H_Yw_P;$0Jn>}b>i!(F> za1Y%K*S_M$ZwZSvP2{-Y^2w|vw@wCJjx%C^QYWfMz?ZN9Ii)VfaHwN=>;yKHJ&I+H zVln+YK8lr#k?IlGnFC7Pfdd$P(XX1IpY?{^_d~A;B})KlZ&2al6@)s9%)*hc@R3ip ztH;D0t_w;8vx-lX4d}QfTzE4b7V#U3zkvJ>9{Iqnc9~UkjG35OVoP^?Y+QyTJ<_3{(U*>& z&hW72EUptv@4&E&!E>GEb#3>$_D=JEb)ESC8Gf=CeDAvaUtN2{|G%Qie*?#!+K?G7 zMlG0jySB8-r?Hee9)e`(P*>j2PK}jU8#Qv}HJ%dOI2ixK^skk{jYC2j2Up>ZtDzx{ zLhxUue+|{2dA?*mJ>|BLiNV1WLtO9aV35Y^;gDLth8nPIL8H=e--K-z?~R3#&p^~D zfl9%D?efeLZVAO*5apX4(mpu2eF$FTLmLHm)-w##zqG-@!R&?LU^Q;2zzz_$cPPFa zH)eYqi;jIX2T9TM$RpQ1{7IgSg&^>~%7HlXcuxKz1H%UP@O^*tY2UBprsQz>1Hv zuP+H_F+WjcTk(h0KJ_|OSx9(WO}cu_NGtcxMItQ)oh2g_25JNid$0Nh<*ci*`Tl_N z7PI|3;9Ichx;mBLy$`B(zT za_98LdJDpxf&APN`wpThZxcl#L^&&hMTk0}x&wh^SJ=N?jrrH2h;3ursuTFTB7|LW z9kow&;h6~GXQiI1I z+`_`#;o5ulsanN|99)lJKL8i3D2T1oGFBmc#nW%HVPXS&&HA~9Rg-Z3b0u=t%104;%#7>aY&64^+{rLiH289`YdiRIvocz8<@>gbu76bNG_0M^=mmC1ta^;t zrP#H7xy5z=2nlJt#h`TEF`IGp?4(r~27GUNGdTDwG-B8-U;pq930jUN0qw=TeqK z;aB-)84wl#o*_^aPE_)yo36BuU{VNpfJiXbd1^+-bzyY?=emTtYj+%g!>7rc5ya=U zVd-r|5o#TvHz8)UmG~JUZhw*TC$zi>l={QUFVIb`jZ&zzab1vyvJkv?!Ly%3Yo%zv z7N_2WnT^?CDNAsKBqpatQnytdAyy}BADIr>xv2+t>MW)l=OuUF{Y0ra&cbKDSunV; z6cbeO!{P(t0rvPO=--_oTYgy6GgO(h+O@l3AttP>|IQmP;!2c@mv)Mu)L&g2Rx>NB zx27lBjeKO&(N`!o9VE9EA{*5r!7byh@o`dazfn|NY#nYaSt4a3+Ik1tnqq8&zBJWA zZ=u%0+3!j$OcBwgDeQ>wDHXo#NULjX?X_#x&)IOX^+t2pYlkDe=I0c^uSmLe`yzpUo5@Z#(1AvQ0%>M7s5?gt!C-=MWr zxnh_|Y>bg2qc!SjFTuHl@xUmf%?AR*5Z>tU!9h(>QYt=zt?XBq4Nx8G- z`erLaQ}WLCPjOrinF9*hUttZGGcFvd`uq^UgL*yulK41^cqk5Oo4 z_NM6ijOfM=fJ+l>LB#&rFO}LVet#tg-!X{dn|Rg`WBvOk9*KnnrjCpd@%U@N98MnHN@TI$OWAdil~Q``TB#R{*j5m87!2a6kHH_9 z;_2h8Y|`0vM%c~U*xy}^(TCN%>X*el`_$^~${N@GIP&c#9tps_(ZZlENhSfSF;XX# zmD=kpPTQ>Wh*)@9ETnF2Z4MS$B3Z=x85m^lkRqbB$s>^%kzpZ~5MU^TL!o328V8AC zoN(kxjwe@NLnG?0vq*(xn16QaRMD}ca(Y2!MyB8Gh%+A9Cs{wdaJv#MEXCBLjWDg}&SO4qd>c#(n8(vxB+Mqa4yf{D#i6FWfb7&YiHKnf0=5 zL97SV)YQ>xYHBW8iq!9|!$Xq&dQgpEH-}q9t@I5&=}rEzZNrtcbV_e(=%mnwWe;Q7 z$Bwb(N008--AioSjvhUFBf;opB=hi6PZ;@09$QQZR`fN*(=`ET?bH*3eKLW~(wq`X z-y1VNRpFx!noIu!YeYzLAo@d%&BPh|ls;1)we~XZw+*pTYfxQC@3L*v?^{aHdU|UR ze?Eh;p#{c<<|N16u>^4rGAV)dM=s*jHRumbgziCqGNfSWpqQl6_ykW(!Mid#mv+h+ z-rgNmu+8+uxK_Zs8` zO_!$dybpn1toIqk0Yfis3V|$qPjo1)TD)r2V(jvy>p6o)jJTV%E758=U%7$J->{N@ zt~KAF&ERWCOkDKfgb_Ml7BY$r;zc9NC`qG23;cR&-G_9LIGr`(p_*$EIQAr7kMzJc zyWT4sgJ7r#Gq;#6LVCziwC@h+3x1Xuxq=+)l)lQ)tP^Puqg{zt=nMNk5$6HqwKiY| zNtH@%{@i9wQv3Kvl`kr6$6_sM-*UG}BFf3CK5)YIJi%CubVn8c2E0Mgcq0>mjFcj9Cl{jgy5*C z$VlIN=ZUzv6N4k=HJi95HzTk?bjDcJQjb!eMJ_>su94VVxU6|uc*Xmz z)ntK4@W=NT4;WCqAGtibsGatdlc^JO0u%h3<1S!SbTux<5cWH_zBhL1R`J_xM6+qrN=w2>o9%N z>NnSKtPnvhf;17c%il+|NM1q`&~8 znUb#G*T+TVH^xOO#S0GIm*b)W=<jB!D4kz47cJHl4l6rXLcm*jF!zM0V;0kpv!+ z_8hf6EFumW?O)n-67{tm@OCGbWyWj4au6L|P0K%e{7Jc*;4%M*sQ4knayt(iGjU?< z_+F##Tf1^~{=kf>>Fp<__HUb!7!m5W5B)nkyKVLZ6C#_7vSDpArVN=dH6$;mQNw#k zOG=5p6ZN#=?<>%?JusxzhG1|Q)_9q590e9Q!>t$)v9LjFQ2zl>TJ%sx&CHr9+RbEJ zXeRC2dwW#xjf)6nRg2{7OflPjTU=YUlBm|f)rq}Doh(D(bwT4b-pYTCqt%@5Udy+_SNld${&Mw?JYzbeLy*Zb2tF8I@@ z7R=FXY%B!^^d?M@6Q7nRry?DWo1 zX55CGP8fA(N8xPPLVs)PJ=aR3TXUCL9r3R@tLMC4%yL%a8~jyV}*ucIpR^8 zWJfq{b;O^3JJOM%d+#S_C4+?%?UA&rp=@kgN=`dx@UGOI(a}3ocZGzu%SlNao8Bt7 zT`1jT(a|rZ?!?{PR_To!rZ)4nS5(-2o252f+Bh1&d@3q@@GJWD=bj7U&7OPC(e{`v ztYKTHbNt=obNd(Mu<>`_6XtB&FwAyLJ_rpPfA=_^Q_w$`jk|k%SSUTY#~Kjc%-44m zyZ4<@zP`=E1FXgk@rZHb<j&vy(N_+>b=e*j_dxmX z@(1Fgl%i*jw@oW}Ag-Q>`si7Ey|@Po(zwHu9J%0-SIQ=IY+LX^PR;`bZMTXgJ`qUP z4vqs0v)dsn{3@+(968n>qp=4Skw%#_*5Zw5Xc(ar2`{%StogS>pfaEft7&JBFxz~> zzeRm|<1|2p>Mt$9GJ) zvqMf!2j@N7M#8v!cL7vD(xXgz(z!Iy_Ykcj603@K#mdsc8u3)%(~8Gum;}c88;`#D zA^T;J2;JC&9o243&ymCfHOdE1cN2DyGT^c3St4{0`(-0L+Cz*OTuuZdGUrV9REx%1 zZ@t2;RhSxtTT>uh8H>`cC{^}{$r6A=GDDo9&NTSS>6q@$2XylrB0qgMBG#B!%pxF~7mZP<@PvYXchF}60dPen23kOgoo`CXe@036C zarv?JiwKzywNoNgyv8=Mi|jcC!k_5kLLH{kItd-+2OG($cX+vo*Id3c-uW-J{nqm5*zk)RCt@c`|D`WEnqHUj)91Ul+Kvm^fg{^@h}W53W3<8s<*7wq?c z^XTTCd>!F!3QDa*BX5;ox%M;a|Ix(g1 zwEg3n@V8<*try+3A9(=VJEE(~UdtWBUIqp~ie9B12^SFtTppIVP&9gp3U*98`1|d0 z#-WKWRn41jfB5?2WrN1=+`R6reXL&p0PQO9p`D0ShcsZmU%TpCO7*vdXcstEF?5*d z-)1ZU2lod|@dI=2pEDiRTkyo)fcfY**H`H<{WX_*(5NHCxvW)WL@X3{)oznDMkxBv zIyONa`!c0dCsCb;IyU2P#da)ZRXj?&D*BGeeT}JIM~L3QFN(dfz7ydi!hnxnM>!!j zw`z0${nO`FVf$!3&>NL}^6Wa$dr%qZ0{;=|=Rx(uT!gdtg~fNpHEE-h=V9SYNf}=> zQ9q0lcAVG@I-U~!ZLK_@>N!^Es$rM4x9OD14_=ptQX&RYFbky<_xL!fv)qY-@%>%> zitJ-hDap*uNAoeHPVsV{P~DMTC%TqEKWz{F)NYC1tJ-Y7ijDb%e0>rBZ7i=?_NX?V z(ow3WU^?JjQo#pSAX?Ni(nz&AlEyU``6Tswg{XMjM@ z!su*Cl+B|+k1G3O+1^BtsB+L_@ik1G89OX2ijVmWbELzpi}6sgbVPX@WO;hLcSCcN z+FLQs`|PH_2?=@u5y}&WJcNgyhtzE2Pw~zpks|~pk_vE~3LKrDeDE3quJi`J^g@D3 zS_zIPa(|*c;6D}kd*vhhobjf*95miHXIAUf5AztOp+}p?yLEhhHvPR})=<`w@_E;h z@&QZlKX<-bwbYx#qN1+TP}fkSuEmpdK$oYrDWIM__5j+fV5+XHsfdTWz zPejw3(-K{&AAq&Yq}3a!=XuiV^^tHXB|-H<)RRsxAEnnV-{2^Nrgd;@E1jRz|A437 zQo2n3b3DDu_rlYVVW^KTd!UDq^noY@gGyOQ@<+--(30$~QaTu^v`*{(%2bnPb;_YR8>QFt!1zlwBB@0^hlHHF z#pRgfrk%_eZ}fA@jd4jAHAc0<22s5X0(#ojT^?kqlqZBG$x}~HB@#-h;$1gAAIg(s z8_LsbXO3^wYdxgDiS~N^B$j6Fyck1A(u1SqJ*t!Jd8WkI2U3F`H`U9X2lG#0O=%R`Tk#R<=`;T_qPIqV8LC(TYMjYn^Ha{_;s zU8&xVRDfs9MliR7eshpl+1`>mI?{U0M3gDYU9RV=2Py+ya_+^^ItLXWPg=B>#8#hq z)Jo24F0um{XWrJ~D!`H9joDhYUHwCez~LAbG|Av>HpcEk^e37}$@1lRJe%f0a_(l# z-wd7nZDTA7CkaOUN#l^-QLS&I@-8wu6HGZ4>SG+zk&_9VtxOd&39Qug)k)NDvV4gr zj&P*%392q_D7}_Os@6nf=tb#f`T8PP;}^9C&pQ(8Vrw!1+W!UbvB zYMm~Ghpy#Iy08N>t;B_>2yIDzQhK6zIXFsrvw8!V${I-}c=U1EswQ2imC&Ll%lIyq zv_Yd9d?5MI$e~jQJg(D+xPW-ktx97~F8K_3tf0OzyVa>A%R{T_l#)DT5bMST0%CBI z!5@-lI`TBrh0!5cQ(o@8*0Y zL?X0Nr3>JoAkH~R!|H2MVX8%2A2N-^@0bdycM*0{?eK6aN!Gy#s} zYfg1DdI;)Ae;x@!Dv`;fM%$Z=s^jf}-`z&KS7S4A)qK}=@2BN3eO|cP_e#l_4oXxJ-LFpIHhonJrU3Qp#2KC1dL=qjg z_%Jqm@R0Hy6==7G^OYH{brnL&8n;b@;Ny^RnVdq;elM0)>?j{Hn9bpnL z7h%?Bunm*_5k7^3)f2m`Q$(2W;A`6@{k@*UM=;IW43BrybFaKq7Hw6A<2d<_BaL=N z``2zhQQNqi2lJ5KS}CmB78ksE)EDq+sUBeRB%c7-o@n;rPA4$S7qYui^&@CdqK*L;D@9?m~6F$ek$9u%}uv&zR4lATZ1@ zFrVib@6GZ^JA?5=FObS}+hM`W4q2YmEOa}7;$xPl=Q9eV^7MTAoCSPFv!F+aEI=2N z$w6j*l>?`I8aJ>wI+p7Hs$p0Oid&oDiZW2#XeYv%o|bFF8VmF6>a z_08rZoWDGg=we@tcKat^Kx{!iyy#hNW&foSi=u}_N{{V$c-S|`9?mrEe(pe#K*^tk zd`ZY2PTzm^xAON*F0HJr3?GW}A1xmF5B8@{x6H&IRawVG)J@4qYe@C8*7>G;{};~z zSHdyBRrNzL?xT-BqEGqON8+J~EXIED!3Xpy-+Tfk6yxZr7(=&|m#$p7 za{01|y==VXPr9~l`s+{Zb4@VrZ}5wsL1&Wpb@`<$=!gCB^tKw`x4OnoD}*El3*qgc z{q&wUCTM&@S(*5ttc*|Cw28iNbzR1emu(WMc=m+;!f!SHv~~#$q5XVDy96fDE}pig z;hSY%+ivg=TX%-7JIx+BeHuPzH5YB&jK1(C+;T7#s;N-Wh3_gs-00lU#ccgTO(m8`VL=m$>Tp zyvn>P%LK-F>9Wp*C(BgNSKD-yb$D32wAJjwI_E5sqvZb%kN1A+yVZ1FGWkT9&oGi; zw~zF+G<_lxly9qFG?IFyr9I;or)N`lxZ((D%3|s<`kZ}^*E@Gk`{7(M8^r6eL84Oo zK~yrIbLV&z?*E9H9o_p;R7yWUqx_I0KPKyi#a6uFC+CHiDeH_KPNZJe{`2hM^4c3o zo}sdy#nXx>6;Hyll#P8|Q~19( zYR|C!E5*la*DC#WM2cD3Dr{NdBTIm739#MDf7PDd0&GugS?h`+G`x6-VhIJw5uWzj zBwCsxwn?fnzU%x`0RO#0%TUWG%XsK(G%8vWBhxaH5qBav-hmIhyt3m;sr8HQ$h&EJ znv8h!j`ue*XUJrpn@FGNxr<*iBI(Zwed1l+;__qrM(6j4W5K!k4eoj)H^0Y$_}sjP zylZ}L>|J~F^7DV7cYa=eRiA{sc;&vlxW0Sxa`V2+&&&G}PtND%<$sIc{H;C>8s%Ne zjk_~iFEk}wy`AykEvXr*&ol@#AQ|i0UqwToYGssffiAEy`>&r8>qs2=7 zKk!{>q=ihjTv3lHZ3zyg)OS~2;k~3xc0ZHaeXN6aW2%E)jrEPpY&07yo-C%cjOEnq zQr76QomzwC@LrPb0mti^H$Hoe+}^^y4n8ba+31?i(v?RgMmOW+j8(AjCRQ2sx;Ef- z{!cxvH(u`k#L<&|nT=d(OuW3FVU*2^^;LE$(?u_BGbKt;rnzDyu|2c~4D8511?$5a zgV-KgtLmp;|ZBDN#B$A+p#8*B3a| z7s)zbx#iu*@JUaOicA9v!Po&kZa#eb8elv?ECN07 z0lW{fyU0>2MuG)#3TSsVf)wD{*YA(P>(C+k6lc7GB;bIpHWU+qLKRS~1eU^%7Po6x zEHd%QXJ{X+HiIO%ZXj#{VuB%HL17_iaKDIGhuZE(&Fq%AE)H(9_^37?8;(y!8(8f= zA)kGqAD;Swqg`mb*1mSI)*=dLhEIe(5P{akuH&vlN;@^N`c(C&YD-C1PyOn|e5hR? z?>G;2tDv;HE!O%tub1JAv9+NQr9K<;OiLDdy4%T<-Aaz_k>t;gbEEXLjUp52XEHr- zMx^3lTr$H>=qzl0WeB2{oS6#u>M&$a&-yH`RYHqSSuNW)1vs3LBwrkXLb5C9@e~U!pH~KQ^(!dc<^9g!v z6K!+tCP?lnos+!8qZ@m64OCI(|!H9M3t$a!dO zRs_o++A3vbrQ&1Oy0mOy;Z7nR>3&}65KT?Wde*k2jD&evi8`Nz^^1tTUvshMqWZn9 ziL@D7n0|nj-0#LnW6XYj{(=`@n7?3$cmYnwHx@qs!u)wVo_9T9>-Yz$6Z$%v%unME zW@edn`kj^fB(S7DNf7@`I^(qCKW^}JYAzXpN3qEPMOLZskFR~2{0JuqBSGd9D<_E5i;SR(;V7U@19njlRC9e$T^9cxfRz*0jJF zs}G<_Vf9VEs$acHIid3~Og&+uoS2o3tiFhAL>=k5hHwP^d6;Y`U+M{Hq)2Ld%vK>F z*}OSd!S5q?7S1Dvzd1ccK8dI9qqo?+tMg`4i{VH#idbT_E${_wYXP9B{*~dS`1{n28|8cCjIZC`DnKYqkyaA$R{ILK5vDCw03M>Eu#pG-d~N zpPBl)R441?lL2m|(pw82;($O0RUbeWj=lXSltYZ0?FN zV^^;lGj?T%9Si2a@Zy5`&+{AOR;(H`dgY2S^Pk@_Z~hC<*VX%Eq!I8XG;0L3BE8yc zLRCjcblcS^DKvSnl(pv|HkuDf_mkPu^yZz?0~1$Bhv^rJzu8oGlddT-#SD^?^DS&I z_Gf%SpE@FB$#NU{JbBHSH{MjjOpSfluWj3Y{oA(fD~@|6ZERB8zJ1$f_3MjZzvlGK zi(XP^Peg9es_N#69{9n#ZgNhD$S1ql-nvslDa#&HzgJ774h$X9kUdf#s4dVZTWS_Q zxadLHQ}MY_EMc8Dmp}CsEpt8fRQYD5z4prb-o4lJe0;jTUZ;6nSZFw21B06d(Q5O#lNjEm~Qyb8tpb?Xa^7E!_uPa98FJ^m+ zwJ()#Z=aW$d9{;f1M;Sx+@cR}!m4glHs!r3Kal-G^!CD@?cvR2`KJEjw8W6C_nt>! zFS^YhYlWIfS{S5PvPWd-z5V*|VW%Q+?C-$HucQ$8ZTK*6O-K17FmvIR;$Id*h9bOK zW}tSuR+;s0E)((AjJR(`(FnC>%4uWLGHKXwJ?7h~2;NBhF7m5k!@Ubl4$Ra8y~&a@ z1KCUesZ2eh8wE(FA&s>D*g9qIy*g|-ZyfP8Rg$$FHvCki7~ox|4Ca;@$YZads;(KR zHI@qW_A%*ui@H*|L|MoH8zvUFpzmHOTTex5XNM2tUqyUfhrAR*u4m7Mzwr3LO!3&2 zg_(h(Kb2dze@WRfThZ+bA7KjoqHYhUlMa)0FfJk<$T_mAx{fND#UzRAq|1u+wo@bk zZlP{39EHqJFJo6b{ItM@i<-Bn%bBl+6zVbpaV~>v3M4n zj00=+Z+lt|)`gE?}<5>wS@}t+KYv-7c z)he!AmANbk7r&})l?j7W-iA$})xp;6S()3~#wsqWDs#+f!{2YS|4{0a&6PDf^Vauw zENRngO+myL)=pOQ|EuxCd7Jl@m{!XBZIq#^xNLP%v3Ca5BCa)iW?A~?cb*QMEso%W5VpCqv|UQnl_5=!%nQr zh;Vdo6cf}UB-=JQs!{hwoZE+FSsQegWyM)+>PwjM(@Hf6k{07cIiO+^LIWd6t{vUZ z5f;qiQdmY7o<|^7a5ke5Hu1?BSx6Tj7tG=jawRh@gO6&ea@O`xV-^w=)wJ>C{PL*5_(t)!x#c9Hf?X3h=X9m6SCpJ)?qn(-oDc)fVbtv8|J@%|F)BE5Vi zz74TPKzbQb3o;gNr7;P_O#lVM0*IfK8jKz0X{q6$4n2`rT{AIWbB6bKTGf!kzi~yg1RuqM0pGRfFs;n%M(vJYHo%LCl)Kt${vG zoB0GO(-N#KFoaW@KzsA1K1hQ*!GTPT=hh&fX3c$qRV_MPVZOdhjo{o@tsiCeQCNgZ zca(6Z_^9>jtG?MzmH8lvlPf;fhzQlr6{o^{d~iqMb~Pe`GX0U~r>Y641Mo{wxsD%K{$_2KYqfW8 zR>YgNP?V-ERo=9vqBLtELV02mPFP6VJbwM7AAkJl`tf(g@Qhv)#*Z5}enPL*M(iK= zM&0im{^K1{A<;c%KKu0f^G`oJGp~Md#2r8O6pI_D2L`4$RziH0FsI@h#2cjs2V-l0 zkdNvNQ++~M>&EFpL6pF*ggaH4ASj3u_^Qru)fU3qIU4%;HFPL`Di8GILCn#}Zg1pZ zc02bAnFNVMG^9m4H4gmdCnA0Axa$ESWU_px$+7;WuZK2L0t-0TcbY}%w5YJpGn zK1U-TpGFSuV`u&W+zQzr?du!uV7{sn;LmM7qK%1^53mMOO2bqj)lea%!c;q4a7Y$3 zw6s=Vu@+-oh{dST9qVx8EDuS@t7h`q!3A7D2MWZVP5OX8_$7eUoQK;zlG6 z7>dYdnJFyE?nK~v1j(kp3sFZM{ZDQrBjoliQrrZ??t!6afxNzLDYpUoXIcI;rg{oC zrBkcm#E_mt9Z3!2TQ>I1pVaEze)Uy9|JGxZ@*Gj=6Zau@RG5!n17GI!TM*%IbsE?A zgv;yt{!YJ{l*H~|-w#PRLU!oaVZLjOf(Z;QY~zzMOwW+aXCr83@*l5lJ?som8VNdbq7#OG%Eg`(prsdY!Bub(w45Xey( z8)X@R$Vk7yme6B@)s1Qz*%q9!4OpzznP_#kXO(|@h*gU14~b{R_P_DX6vVb#Ou2D` zJq~@Zy(J8J+940Td_B3cltinN80*hs>*Q}emie;KsVrJ-pDQWmNPMnMvyF)seIIq`)Ugi2P8>keXE^zcIE5+ zttWYALV)&=cJ;hyn>?JSM@BZt<`2W=iQsjB@wmkL4>~7;&LOA`5FR}kDjn%_m6ILo zYu~dY1L8%$FGWaD8+J$w$mwqV$AGv7+IynG=b}^G6dn=WszDn2=7uXb$2z1v!B^mG zXIHnWi!ryWhlne%Dp=yUOVPQ{HzlmkS7g(#6*M;l)O8)r3j_vPC&h43-%yWJbyIH?qHn6bA9~YNOPKr-i z%ahBmJ@nAEe{8Ks7u!(d=D9d@4Vo!g5nwFluJf&&*k^$)UA{$rD*XK0O3-^5uQRFAHpr?gGVGglJLODIex znWZ)aokFTfsIgR%pi3o5Qw4=wj8F>;vfB0QH>1DSs$aXT{{8VoNfyul{+oDySWr;z zs!^y;_Yp%aHEf!tX6Rj=b5@NWvohC#=!89TMvua$LIbQ zA;kFv&eS=M z_|rQX4paCPdZ>apREqkv^_Yx*(MFa+XVs)9$>VfDrE~_pkjKYy@FU8i!}jD=sJsg@ zu`YR&CY4N@$op@cI59tOqV{{#mf{&(%8TzSU~FaRQ!{6l_HftKuR8EhGAxz{q! z^04Jm%il3Nz6y-fRH&{tjDJ~~$*~v@F+?VV2gzR(Oc@Rv34V1#P#VR{T4(koYWHNL zSJ5^3#~X*hMDPfhC%^~bai`}p0>S=+7{VSQI+NOn+4bwpgiN%Fo<7lYnaMgc1aHz4 zIlZp=cq{9;Y;9PFldZx#HP?2x=p3GMvP0O~W$d-QMRQz>=Pt}IntylUym^I%^H}fP zHaNlu?}3hhfY8u@0EhWKHBj;Mi?aKuetzHC6@R}-A3H9i#29jU1PqQ)NO=coGE>f!UKPo$r}VwZQ+!$FIdt$N63 zW<-~$69Ubb7j@Et(YtSGJ7wqT8N&W%0U`JxW|D)|a0Hdt3{^7Y#nMo$oCsQ)XB-3Y7 zC&^@H(tAj6B$N;!fC(i)=ry6Y&_R%@fUZ~oK~ODF$c_{cp{I|lWY!k`t%aI5FX|9GMSXcGD=2@S*)VC z@bZhRIA{d=J%4pOMk3+Tsus>2I5u}-)q~C=r~j!6hXgD^KyH$ez?#((NBPr!99N|J zt=8ii9)8)KS4`$BcPOQJIpu zEce&)k#)+o5yx&DI!i%_V%E^xjzz3h){T@KtnH43p7p{&l zdLQ&EKfY4}T!!dk7u%uq@PqI70bzoH$*AwlU%tXOust1q^ZO}WR7+&#Hr4EIA8${s zm|l(&Y?q<4;nXz)E7_$pxHOOO^t(yc(_Gf*xkHz(8b;?K7J3Put7G2`zt{BB_d@1@ zJC;rY7e>1~l5Akl;{(dLYStGTMN0)2qDZ+cA5{f~Z`gby6TW8O;0F9qpFCSWaGot2 ziCX1R`6%xDCCMjI!r${iTA|?v&-JvZjf)89rv`;50g?&L%?~dkB0q6~fXYZRC*elX zq&}mCM;YM}b~Gs$&hcfTk0Z%t)u<5sgV{F55c=C_1UKmGFCY2QssDe9Cz8PEin&D8zKSm4Jfs(Uyyu?5W4)}dgiCyZ zXiIocF@tT7FgB4RBQRIkt2p2b~(5Ri(BoABBR!AYycPE03F;aekHb)$ZO^WOe;jQ5LdAl_#!q~ z13^^l5+et*H9*Vb0yW)PcDGnURX8AAbc5n6kU+chuN3aLuGH(!;6Mi z_=2J;T4F^%1^o^PhEOXSTJRgdC(gO5rkZgBm0BTJuaFQmCx{l0iGJu)^ag3%3p zti?EBo|KAx;=}@*o-ud`aV4fFmW0|( zO#P`UIXBP-T-_pLg+DqNR-U(evx_wvTwMjmMyD5b@fx6Rxe~#KczH?$$7FjrNgA^? zSeG$W#|eKjqWIrK6PJ>z>=spXY<$Y%DksS)56I1l-IYzn%(q#~hjw?~vA!dzcH*4N z<@#vlmg=E~$VjO&$0}7o{ueV$qguvEBeb8AxKu_zX8Sgmu8bqeF=~yG{LX92A2zAD z#NTL5hItk|WHw}rz5E};dS_IV(}L7!q0_Olgy|uFD`GC+$(52Xgi$%{nSd~w|D&+r z^8Kust0QX#|3C+OE2*V4fS^Yi?l%56RK~+oPz}Vb6$P1TdIZDsPNLr ztf5cI8DjNDAh)xnT3SR_tGM-+rXp2Bxizs~cz=E&v*T(X5(U0tF?38KLgPDW&i|l~ zYQV8wNb*QJ$D~n{InJ_2DcumrrM59+8#YE;Ln$nFrl{q)*U)rT* zA$3`)oMDBCORecvgO%n##bz=w_`(P2ur^@e4_+`O$7>;Gt3fVix}#lsuQha*Aw;dz z8q$52$a<|?Z`3*_v55+WR+nZa3N|7s*R0YR(@lvvkxZ1_YfQ|Mn!GWIW+M~DM#{V< zPgpKzL<(Z!9)qplN~K|lJbZLA}t?kw_H(_P|Z zLpy2+sbO}S0wmp*SwJ$G74eB_OhJA@L4I*TZec;5k)Rw@6dBe+l*3wyY*=eH@i{`x zbo_6E?xF%Rq*YW7dl?TqfjY~r4xqtmw>m4l0?DUjNKSCzqyBo3 zqp*eUaB7dRI!9J6Q&U}6SJhZsRaaYWCX**&;>JQVWfDQ0;zkoPx|TaeSMRYTkFJGX91|Kt$e4lOT1$itNrklx zmFa)n7x)fnVfh?ujqi#Brk z*d>{H1%;nwr5^NzPn=*QkRt8r`s%z`2Y8$KS>Z)s) z+$_hy-{RSZ)Iz3w(qweQq$wJL4Fz2=_qDVXL?3Ty`F*7DL`w^qAPdu0)WjWYDcV&OL%C%H@!zwuugkjzbDR zCwgA=3Z$w(i2f{kU-XgaQ_+{AZ$;mW1SH>76Em?ACrN~QDuehjk}$lfni{jY#24_x z6qu>Q0a)Y2NC*v7iV54a} z4Ai9NcTuw}eLZcL+m8b6u%88SU04qfiyLMET%?0Z(I(+Bbb`7dy2k)XF6fqo{|3`X z(qrHean9%GaYnDxhnXIiUyKs-Xf>YTvP+QSI()l3d^s|l<8kzlnfKQjDfPUTTWpIJ zrw5|b%g=jH`Kxm?Ik$gX?y9wcLoQoXQf_(fJs-4Wi34nWj3cc}8`*4nxM2c_a8NUaIuZHz~F-t@3+Zsz@(qtP*^zL8~3Ey*XN@ zRYr3U-#oHBXLL&)pX~Bwq;)38X`SMcR%NqP;Yi3FH?Fp+sVTa$J>axUrOnDk;?yX8 zpuOG4SJt+lc&O1JTpZU?(w>^Abj%I*OY34%9nn%$(oUgBVFH-VT2r-UYTttfRgr7A=Mu94nE`->s!~ z_MleGiZTA_pv5+H$5zVKYxVr#$I!t&_z?kSED63gTDWrHm`Ql{cTGgIn>@H~-Peyy zdUyK+ME7tN^b%j|*U!G&ohD9n-ZST;dg0E$DpW^!MqbaL0!B=%{m4XNe_3jD(CQSI zq^a{P+(qG)Eysn=URXeKw`?;I?Qf=Tto?lJ0Vo+~5!2$ea$-Eq4kTBRq!^>{Y9+HR zubz{CbV@1}US;Rb+v;_Bbi`Bg_mX&5ZnCK?K7q?igVUcFvbO~O2Hvpk!VC_(Ni+p; zfldhXB&aj%q9hthKrs&~Ml6Amc$cR74=TeOi$P)bi!NaiNf~h|Ts1(W<(5L`+ zm{knhD*`ZCt@iuGR;;GGfoHBjita+03(PtzxR!XLrbG3f`jHbh(QEGMfoRJ(E zGX6qS&Be-Tv3bTUQx`|N;SwimfUb8HKNi{sEvz7BREHRX82wqIjiQ@G`!LJg4sGvo zRFHm9bY65(^rYxH(aT5*g4%LHm%#;c9&`r`6xc4e1M;Qa6=d~pmsUsVyC0fiP-%dk zqrNpdx8D(FbLatp9`FvZ*AJqA7cO;UUZR~y?}JGo{9vfoaI=SJl_S80_r{tC{$8N zg8&;g_<#il{`jKpx&ZWm(DbmpDm!wfGkaOzb24US@ph=tZyOn>AdTY+w3fG} z#sr9PTwYRQHfCZAqcBb_7p`#3d~ee&NRxjf&rMCOk&)VR;a-NDTsi(3c_dR#xDDfW zF@O6zPbQU??;;~2YP+oz1yq^hdxl{rjC zd0w`GagGmq(M~%yPy0QuMI!s@<7meFuliT0NyjW=({_?#?Mo zl}Bl;IwRlswghgxq%bQgzAv;-!*`bCt2i^3=n0WJ zqP33bXooi1Aq9sS9h)g`-2;suc*t=WC$sq1Aj+w<;oz=42e{v#WSEm%W{sNN_25?w z^VP-n8-%|Hi6DF6`0)qG*Kk0OyaDfKMT@}ujpX0NmIZn<)O$j7FxVWFUDNqc0#gmt zMJ*$@AF52m)7$+hq8#3!8E44AGpCO%T`GmycEYxP=3Zv)S`;MRHUIV@R4X`ystNg$ z{CwZUiMNd;Cqf@?ym^iADLJ=x|4K6J-jTNryht9Zyy1pHoyK_3-U-~z4P+v|n~0vn9L)32(^!SDe;F7;B(T5| z1t#IQ2fw@^J{L>)kI7DpPl&}QNI)VHo)MoG3(twgBLA_3h(2Y5g}sA8iNdpz@?IfS)hC)}V300i^Gtuf!R^8>h%6Qq6G- z$uYi>$4_Wo2rJJSj$1CY@WVN7I8W|b&T*Z58>sanc>JB=`T3~S)WqROj?9ODk;S^0PNDWT;e$4pv95VUqb#95>9|R6C(^V(# z;LZ!5AFd&aX}!-bonD-*7k+B46lekDA7t}un~ z&`XKo?&rz;-!uqQPqICSmD8uQCwmaYOyjj8uy~q#6jt0u(F7WgPAJDr|NQuVsE{BY zfWBu@sV-B;`T`Jb{g_6nMv;2?g+&Jmlrm@`?g9A*A76yS;8pxAwB&C3Rp7jJgDMax zIZXl}kOw&OD;8~0MZfBFJud0oPr6U+=ZwR`Kj>X?+;FS!c^Zg)0s;nMZ2 z-99vSdR8Pi@a9>PeBdtT#5?A<@AqpsD;L|;WZ-OU*64z*+g^SshP(Me;ln2xW{YNn zjn8gA{Mh;9B>((~);I6SVVRiro%gzq?JVWRWn1<$#PbA&A1j&!d9#~uhd)sVGTl(Q zO9{;tm18hsp>GA#7=&AsulCRzH>b@R`tz^=3ZOhQ|;@CXJqa?abN`3Fm7V? zW=XD7zL`y~ox1sDUOVUU+!@o)y`@(+o$up{O+&p-(qhS9!?#x`W+&CuHk=t%(KCPh z>D#8L_k1G!UHJ2%MAJHFQXsA|;ux?p4n`^uexV zRZqpRhfZ|NR+kE%wH4!+*UdGQ=ib!azI1HPK4?ZTwg-J4Y+;?)AWI6BUKp)VkqQg| zbzBAV0MT9G*nsoUja-!^ZIS?U^x?Y~cHTUTxoORb^>bck4#NdcuNAj1+qdZW2!6NZ z+`C<84S{E7j59ZmU(Z_)_n*6W(TX`YjjLycsl8%7=`z)}AMctd{j-eUxK~CRrziZO zEkAt;V$fq@b2-f&f~7|T{5L^oAktp-si21cV6=g-Vv$yFh$R7pnFH)1w>p-zefssLrGP+Ip_ztG|8!}3`16SNlMtpsL2iZs_u)-&y zFE(-HFG7rX1@3=uA9ii1Wa9=m1%0Pqsq22c~jxkEd>Rerxn%7i<)(0qbV+O zMjc7E7`8U_2>+0%59Vo@CN2M}vM4m5iukQMkBJj&4i(FVXH8~lPrdMpJ^@!U@A;hg z2NLFTIp-7T8D zI)6=sa({tJxYev%Q`?nnG)3G{Cmc0e6b>(>jPK6;^lJ$dE!f`F392&eQnxQDY`dkf~cv|$|IK9onX@UM;@ zJ4WxqyLTO)k)%n5E}J1-gD&Rt#qFWU}RY=(ERK0W$8 zEExO`+Wzt#XglniA*HXGH2lvSzaa8C;d6zSNS`6@e`!4(lh^Fmc`uQgy0*|V&{se3Z1WA;xcTv5KK}Sp1Lpg}i z66QRh3`EDQA+pKB;(PB&_cjt$?_S}|+V&eg6UeHeorUYsn6&NsfpDQs7KlkoA@JUx zO`1}~!w-EpG>(kA{eXlly5|YfPsj~QN#n_9g>QtJ?=-47siKg5oP0vIe`sV|c6~E? zY@~2e7@%x6+I0TPI4+t$3fZ4p3@HSc) z*4|!24d`y!Mwe|#-^6v#y+js2@(8nW(vl@M7Y?l**4*Qm-aKsW65IEVp5|f0hxaZV zK73d+mmg#6z3=3_v5Lo`jC$n4=*Q(9^G@E^Yl|`1`%Xqk7Y}O`iyMb6mPVZHv$u&G zTYDEbH#Idc?ro((QH*H&mHk{XUx@h!xo7 zuj}Y|c-`ubaiJL-H*9$PBFNaR9e;d}S;xHmGTF;cT{mXz*fHzYo@#4*bj4$j_pe{y z|M+7oCM(|{lbDxZnfQj{C-0Xb4}}QYXt65%Y8qD;#G8UXsK?#30wcOMOr2?ynC@$@ z9@p^{dHH3$^1VOqm<2+5@$n5CHqK%Ww~Z9O{PmbIL@}~$?VA%{`3;%Oys4bL;;~D# z8J8Yg0sRewsOo*(IX)detn}UJAc>gvggzK>X$O^je(IHn9wSbKZAsL$f0^4x^`aj9 zsP?7HMz=+%R-GniSFT`Itvq#V1ThJJm`+yC6h3H>h*|q6O1lN5pdHozt#36zj|j4FByk(~<6(J?#u{Di3B&|Zm(K9#(@exv#3CQg zX+j^)o!#8DX-!5-25Kx+}X_WZ+m->ADqi>{l1S(LO>XS9x92m zyaZ{g&mU?FFHBw_1VmlnKR4h9%^cyBXorOvP`sw+rqa1p2$-{`;zig^s$&zf9Sz5 zPN4)UvMSd(a{N334{zaKOvjBsZs#Vg#0?VPg8zinEr4&gQ6gaosPM)Z`-zYUA<&J zS+Hcm0)`>ON?I3?g?$SbwiJ&b*jh4weqU$*Hj=P!U*Bv^SMSM+d2^O7oine3=^I|6 zVru8kUbbxZ+|X%NF?E$3JXg)#)7z^zKVCKJ@(5MvMM-Z&1V5)& zC|Vp-yFXh6oG?OuKg(N17G&E{QGZ#uufV`gW6{79YQnk+xHix;Y9{ab#iJAJ$Cu8V zOrkn?j^#T@)ReiUC$6Xa4!tLw}xSacERGtQxaqnBchR8b_T%LgYT9>R(T<;xus*@&sk`Zby$pb4h!#x$4>x3wr-Nv zzmb@jZerNFZrxVluc2MS`y2cF&f^~!qe)s=UA@??9k@&D>Z_?)n4*r<>DVDU9eABA zQ6_f_uf+GpLhA)C^SX0#3hdT;j>`2IetH#rNys&?O|6U=bS?+&?5mI{B|Hl+xOh?cWPDX6vmtz@k7;Jyo;i*2IJNQO#f|I7Raa5GD}cY=PT+);juKJW zXA})I=(XX-!hssJm?r-T_mgI@WHg33Yyxz;MXyo%44N5mk@D3!F{YKJrP(Ia^Op|n zzHo(|Uo;|j=7bST2e!?fxjIpAQP@%^PJB8s+L$_N?o3@XDfX=@DakdNR+N-6-J4Hd z+<#c8JTRSYD4Nne;RLzk==|;dv;E5gBQ8{Sc|0Sgq-XfEIulci$YW?K+U^xTg0ILj z_@L9MN@&)?Ql1%B4!{}wOEh)Q3YYDLz1oe6wV*;-)H)H~K)j-%5Kb5YI88`wV)AHe zi+Q6zCC4^8JsG;bN%O5)^ZM3}5Hq&Ku_;saG3I6RDN{RJOsW;+%hS+t>AJXOdnU9W zTz=QSj`ou;3r~JiwKJiwfp625-N9`6l8`(0hH{yU-$F@z{Ps{4TYBS-1#2s}g~kaj zj}Ufe4|jlm!!XeUTp#xlG$D36?xBRV`h8bX1rz`W{C2<>fT!XrsMRpeefbTtNtip3 zerEOR2h$17yd{?vEV^e=L6n^2t|4RAj+%4ZyYJpMXVluYQOcU`sW;s;wYx?c1(*?0 z=9P)uLGB4EAv@8Hm>3LTp{N+-W;It~r1~cqQD|NTt(tAC$jfK?`@kz#HkdmJ>l1pOVJj|W+<@KOSn1YI%6`M}v=aKa8E)fSi(um$uy?W-Ry zX!~HOCDPto;Bl*+y$R-#4P_OJ3mY}A#f5H<+Wr;i`e0~+6z3aNuHJZaTllowqjiSw zpyx^dg}AP+%*?K?m_Iq5o)!p9?acIbK3zeYF2r?q`h1<8IR4DEAddU8x}HG{4iSxo ztS|>Uj5zEdYEuHdMa@}aK)qm%HYj4@d88q3)cO6*D{)_KCvu|@B5aKC_4cpgejEGs zHsNa{3_U`~L}c5)j%Dgt;dS8y6!;~o-S7y>VucTd*NKN1S>ZY1i`~NKNM%ak?@7lz z4=*R4+rlk}JZ}M=ZAGkw2&xXyA(*r%U4rqJx-wCZN?K?=JkJmeB7$6AgH|elanP$Q z%n%Hk1}Hr(H!ti!f4aS8Hur{M2?W^AXEf zb(X@}g@rTYqr~E<_?d;+vFNM}E0lcrq3{-QO4W(GhPLc(HZrjpaxt42C@l>n!sRm~ zmN7Q(ZW+2OQ7skTVrNEMqVdxpFoBw2FbfTb0Nx8fx+-|R4uy894}LI*MGpbzTyB`^ z!e1(uXj!OEf7pw~y!ewnYSg=WC94Hdy0&Mhi3oT<)cs}#pf!ZcfDZzk_Ch>v@@WT; zhI>IV2u&Yi+%Uol$+d&DyNHj?{Gq$9^`Z9ah1Z`+FTJ}uQlF^Dk4-t_DN^VY4SJ7( zv2U~bh{2=7F6%RIaTpSHhD3ctY31WqgGY~_w6-@iotd;j_-GT861qR{B+n~Us#vAM zq*lc$#NtmUZ$&7xQW>jI#$u^N&Y|j&uvjR}3Y=HOs#J2ZSopNgp^(W{Dw9$Xr&KDU zWbZaDi-=UjDpe*04l3m=%gUH4y<4Yq>oZhBA7iQnkBOh%6uQLBF*pYbU~YC{{D zpu;kFu0$64m~4o(4Bl2H91vQ`vELudNxRj#bSdF1WCx<7WAOsKScR7fvyIFUL_f!x zX;ZNXJr<3mD%gxuDB{eq5iAor$1FuuFufX|q%uW_nb2+vS-{XI(5vV%hF~ns1dfbH zES(uz5qCJ(t_TtlwHlRfOdU&6H`7glX<5qR9IEaoGKxq7kG1j|CXhz1kuVRTemJ*Lk3na-O_*g z=Ja%S`s~)$*`X)9X3p$NMXfu*3SR0DSH5Gv;vR=oQ6_2zwE@2t<}$*}J0?T?4>KND z(UEfL6g|Moi3c|+>nx!Go8b6qGI!YibXv@zr~^+i%)nYjK+4J`H4x?Dim0*61M|KV$ z9pxkdVT+Prz{ugI0B}p7`va#ik9fo9r+X$azBvDD#ODtrIbKq}MQYooUb1sjt&ob4(K%$l=w5F^^qH%k+TFml% zZiK;lues2k5uNT(S4X!t#Pt}4m!=>BHj;TV0r6L?MP1~yD>*j0VSM)#;UA&cRPV}f zv&J%W6`B}V$wx=qZZO48(oJ~B=QO*GGU1`PWLb>H!+07JhG)k%HeY(AP@9_{F^}E6 z==(`YNrbr>$*84M^G6mU=#Yc%O3eAW$&f?M(5JTpPGJ&smClHRSNEnre{4kZu}WvI?KG?T9=em z*IMuKJR^&aii(y+A%00eAg3ID^1`=sRWhA9yRdLpLXnEwY8C50|^ z*ZyI$rQRvNEa2mhrdK-?WMUlt8I$vK{VLVhonNU{S-E*rvIBmn5p(IIj45=~9Gg+! zu(>8D5QDh$`udvsdRe626v(dG+)$q$XBOsbEGmsft+r@X77a-j(rHq{_9a zu6|Rko|sbQJmbzRD9Cgp?M14I=xaCC*KL9)pzt}Hp-E7y6EtdzN@WS%y=BV|KEgQM z>mBJesACxXi%}b};~j2{;K9`g5J$Biw5&>02i*L>oPDh*|6$c_u9q5942Bc~mv%9! zOle4oF(kuLWuHArjLCXKijfH>>~b1X^fAfC$RV{a+l|QvW3n--X=SLK*&I5>G=xsE zC8XYvq}L}IveZH+lUIxR6SJu!E_8_5Z*&`ybh;!%iZ;~Aw7G10dZE5T9(s=aD%L)D zTb27ZrV3Ts%mpc7jhUz<1LeNHmkXC_Hzd!P@^g!=P5*cVMQLKmX3gx5n1g zj2##;mbx^LeQhIS8aTzCs;e7#f7B>0Wyz9N^A-!vMe|m#p4UrW@13`5$>qPLrqcH_ z@bMM1pMg$hiO`^M7K#66_CVfe7Yz76OdjNjNrDN&N{H27G&n&N*{wyGAar_Tp@U8w z@!m+W$@I>^H*f1c-L$D=(BARni4 zeF=0LKt7(cq$>Hnu902%4Z?5|d>gxY3v_sCm5}xGj_5PO@WhdwRFWq7K#I8TN#)O0g>!ji|@5)b$)iPszL0S1?n=C?UOsJsK zZAF4nC6U<{mzNd98|A9vPgi=WGD@@@dckJCkxJZD!+X`40&8d^wf^K|yk$*F*0Kg$`N<)S#WiHg-Xh69!qhN)*Ta?t1}FD1Tya$ zF6I9mA-vzl^HYe1dGC&F?}c)yfyv8mFO?l0uB6||ik6AiazpthjHmoT>kS!nqoK^v zwXR3chuwYsK{QSi6oYvJf>1AE+F^7(*g>ohdIAYEWirVdvNO)3SAV<1VqOe3){UKjMz_^Rl93yqs@3EA-Ev!5k}=-xu}%GQRJ# zmT_AHSy9aGCx|=$cHzv_p1moO`*Ihpx5mV5Kl1TFv9_ih-$3ANv4(pBFa|pqhB37* z(UyT*L40c%q9pIm4m-n`YujcVn`}BN)bm2-hTALn#z*TC*Nkj?usr{TUx&VB0(ajB z%%IP_-v8)*y^grh6X^Q`IYOdT$Q+Fx|DYl&bWqH+N6n^i%m5q@@x#&I9XifK4r8F#Ik*GyRU?y0My= zOxtsH@_XX)pJ-*uj#12b_LgC~XM;(W%$R1w$-E~vN=J^DJe4V)nOS_#Sh+?VUtY6v z!w~69Dg5}6-6q}MRO_Dd*A1Ble)!!v-s$~X{$yJEJwv79cO}Amu;FyWtK|JVbG#SJ zr2OdZmOFPS9A#MJmT?;hAGLtFlaDg2_Q==`#2B@J+`&t6PR?#{^zYv#d?vghe70*}KRdNx zNdGrP{_VOUh231GZ)sEagxlARO{(sieWBq(@1Z^acy4>qtbNC8N)C3dTJpl(^8=%o zZW9)Iwl+3wZED)u(74rO%`WQitElMfFUq#!gUD==mF?hIrc)~8I|lL=$s1aU-idC0zGc8R&yz~ysWD9+s`vT|PB4{Hak?pFG7V}bFf=0OSMSc@;&NUaVfd~8FHh;)Tlgblr!TK`)%x~$Z)0hhJ7z$$E$Kj? zE}ugUO7OoO+$8=mWF!&c(YCPA6Kp33L!P(fAj{1cdNB(2ejEXQk~4PxAwoLiA81EEV5Cy zXD0kN2j=~W{Zg3G!tg5xRKm%zB;i*Pw7ujc>`NB@1StH~=Q+cEn`#~kDYefD6X0oh zVdOEKix)03nS{t0{sb>n?_nv;bN?bit^#~ zz3=2OYb4pip{(Uxk?V=6L;FFB@+gNr!uxq@4#V zGjx%|hm*L>>H|CGurWS&uiF>H&e?jPIwOu5K0H#NUU_Kik4`Z6kfsD*az;V;vb_hZ zGR(|~5sW#b>fqk+Wd#|@zJw+s^dGFsjH9RGGOG>(reaarmCupqMu{!CC>nO8JXnbl znNEdtKccp%)+6jEWAL$d97OcE4;&u^ew02Eg9)Udrfxr&PqEa)lagvasIe7{>^yS3EzRWhZNJtvhMqslSe#*CT4fsAg=wtvIo_c5}7a#_7H?p3bK+jnbHiwZPb|wx4 zsl~PcEH9nnXxGr*3>b7;*k!@@dNIC(bRL1%8)g(p>@?!dpMbtCqVou-1ig`ZOCl(r z-cEy&iU<^1z*qPOM}uEBXnh91n+FxL(hLrG4W5E~aH*RPl0in0mjJ9;U;v5;4ef^? zoeq;2ys4u}YKlIuR?Mx2|Bj+?i_AVkGc3ulR>uB?T_m%;yidKaN;h1t483q>u{Tdw zY-1i#%;E~vaWf*6m##6baG|n>FR1ue6PyU1V3(}%*&M!6lal$rK&@%v zzEi4MPCCIE@tJ&;n0XB;Y>4nh6tgOFmy~_K`*%GJ&&pr2D06*^h%ecw-!?`k`+Fxe z-<~h!QvPOA#dEs9L_>h@Oi1N8Gbd%lyCR|=C6Quw)nB-gF&t4{(T`!@ma_fuUScPj zBi&;oSFIH5Yt|DbmT{62EB6YW6Z1tO+uiguklsG|&yn}t4D7fsN|K^W_){X@dKwKzlGUedo~%o6BLS6Jc-Qjcm< ztDp-VK|I32V3L)KDqOy3-@a{0T201|8&1ZC&i4)}NYflmsftTYbMNfD*X*&AHj=EZ z)C(KS)@JAUgWaZvhfGTnolfywV|3*-iN9yMFT#^jMM$pjLb}((c95x4Oy?R*ORSuv z;fg4SWTqQY)s=o@ttgUP%f(?v$bfI>2>Okn|AjOa&!FK{f}KG#6l|>j@vFU5UH;Rr zR+8{nGsRyD>(g#j+fDu?TXj*O(bhga)+W6n^p}L#{FFP@$(0II+%RGh?(!#E*w6F( z7Tk2x=0uI!yKVeErqHvC%JWmycP3ZHrlh#Gk3Smcv68~leETe=*{zLps$&~8ipreW z3`=DFhrw*0f3m6WjH%b{aPYH?+KR~$zNy`r5$@#5@3Vzhy=gAC3cs@0;ap$jqv8mz5UeG`0A$0$K4Dg@H!Kz@sg}6>)FbMYN~Os>oH&Hr1Bo_P zC|J61&z>zw8cq6*6Hdg2E-kLePt)8D5T&NNc1*Y@F3|>uu>9oGYN@T%R%2Fu*}Wo7wsd6~jZme@g3p)i3|xP?Q(L>m_g zQn7dMwj_;~k_uDk5lSkwN5Z7Sb<+*^0tJ`{D~9sJs;XL~Q7s0!*OQbMsS%z6)d*0k z5xdlLm1<0l_=xXP(#ch)yN?k-Z0VNK{G_485+cC!eJi%;9~$0 z>Mauv7z*mHYMrlxXV8h{KZ51ojE^yHG$_gIotB(wEG%L8Qcugc&epM=izdYeL$~~I z3CLS%t*NQ4X&0)L(sCDX9$Hb>GH>d{-iXlK*GY)SK1f2QNV2B=GYOeIiIR}T7H*J) zq!}p*0S!ro-_GsaNbp3l;1^&s2fiSQi1j~0;FpI4IYm}H*Yk+*y>PSDT;x5eNvl!D z#**&pMkH)S@a=OI}Vxp^iB7(DL`Xdt4YDh%B@I+>Yhn-KRPmg`H*|fsOOPYj# z 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 literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ufm new file mode 100644 index 0000000..6b2d4ac --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSansMono.ufm @@ -0,0 +1,3284 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans Mono +FontSubfamily Book +UniqueID DejaVu Sans Mono +FullName DejaVu Sans Mono +Version Version 2.37 +PostScriptName DejaVuSansMono +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +Weight Medium +ItalicAngle 0 +IsFixedPitch true +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -558 -375 718 1028 +StartCharMetrics 3377 +U 32 ; WX 602 ; N space ; G 3 +U 33 ; WX 602 ; N exclam ; G 4 +U 34 ; WX 602 ; N quotedbl ; G 5 +U 35 ; WX 602 ; N numbersign ; G 6 +U 36 ; WX 602 ; N dollar ; G 7 +U 37 ; WX 602 ; N percent ; G 8 +U 38 ; WX 602 ; N ampersand ; G 9 +U 39 ; WX 602 ; N quotesingle ; G 10 +U 40 ; WX 602 ; N parenleft ; G 11 +U 41 ; WX 602 ; N parenright ; G 12 +U 42 ; WX 602 ; N asterisk ; G 13 +U 43 ; WX 602 ; N plus ; G 14 +U 44 ; WX 602 ; N comma ; G 15 +U 45 ; WX 602 ; N hyphen ; G 16 +U 46 ; WX 602 ; N period ; G 17 +U 47 ; WX 602 ; N slash ; G 18 +U 48 ; WX 602 ; N zero ; G 19 +U 49 ; WX 602 ; N one ; G 20 +U 50 ; WX 602 ; N two ; G 21 +U 51 ; WX 602 ; N three ; G 22 +U 52 ; WX 602 ; N four ; G 23 +U 53 ; WX 602 ; N five ; G 24 +U 54 ; WX 602 ; N six ; G 25 +U 55 ; WX 602 ; N seven ; G 26 +U 56 ; WX 602 ; N eight ; G 27 +U 57 ; WX 602 ; N nine ; G 28 +U 58 ; WX 602 ; N colon ; G 29 +U 59 ; WX 602 ; N semicolon ; G 30 +U 60 ; WX 602 ; N less ; G 31 +U 61 ; WX 602 ; N equal ; G 32 +U 62 ; WX 602 ; N greater ; G 33 +U 63 ; WX 602 ; N question ; G 34 +U 64 ; WX 602 ; N at ; G 35 +U 65 ; WX 602 ; N A ; G 36 +U 66 ; WX 602 ; N B ; G 37 +U 67 ; WX 602 ; N C ; G 38 +U 68 ; WX 602 ; N D ; G 39 +U 69 ; WX 602 ; N E ; G 40 +U 70 ; WX 602 ; N F ; G 41 +U 71 ; WX 602 ; N G ; G 42 +U 72 ; WX 602 ; N H ; G 43 +U 73 ; WX 602 ; N I ; G 44 +U 74 ; WX 602 ; N J ; G 45 +U 75 ; WX 602 ; N K ; G 46 +U 76 ; WX 602 ; N L ; G 47 +U 77 ; WX 602 ; N M ; G 48 +U 78 ; WX 602 ; N N ; G 49 +U 79 ; WX 602 ; N O ; G 50 +U 80 ; WX 602 ; N P ; G 51 +U 81 ; WX 602 ; N Q ; G 52 +U 82 ; WX 602 ; N R ; G 53 +U 83 ; WX 602 ; N S ; G 54 +U 84 ; WX 602 ; N T ; G 55 +U 85 ; WX 602 ; N U ; G 56 +U 86 ; WX 602 ; N V ; G 57 +U 87 ; WX 602 ; N W ; G 58 +U 88 ; WX 602 ; N X ; G 59 +U 89 ; WX 602 ; N Y ; G 60 +U 90 ; WX 602 ; N Z ; G 61 +U 91 ; WX 602 ; N bracketleft ; G 62 +U 92 ; WX 602 ; N backslash ; G 63 +U 93 ; WX 602 ; N bracketright ; G 64 +U 94 ; WX 602 ; N asciicircum ; G 65 +U 95 ; WX 602 ; N underscore ; G 66 +U 96 ; WX 602 ; N grave ; G 67 +U 97 ; WX 602 ; N a ; G 68 +U 98 ; WX 602 ; N b ; G 69 +U 99 ; WX 602 ; N c ; G 70 +U 100 ; WX 602 ; N d ; G 71 +U 101 ; WX 602 ; N e ; G 72 +U 102 ; WX 602 ; N f ; G 73 +U 103 ; WX 602 ; N g ; G 74 +U 104 ; WX 602 ; N h ; G 75 +U 105 ; WX 602 ; N i ; G 76 +U 106 ; WX 602 ; N j ; G 77 +U 107 ; WX 602 ; N k ; G 78 +U 108 ; WX 602 ; N l ; G 79 +U 109 ; WX 602 ; N m ; G 80 +U 110 ; WX 602 ; N n ; G 81 +U 111 ; WX 602 ; N o ; G 82 +U 112 ; WX 602 ; N p ; G 83 +U 113 ; WX 602 ; N q ; G 84 +U 114 ; WX 602 ; N r ; G 85 +U 115 ; WX 602 ; N s ; G 86 +U 116 ; WX 602 ; N t ; G 87 +U 117 ; WX 602 ; N u ; G 88 +U 118 ; WX 602 ; N v ; G 89 +U 119 ; WX 602 ; N w ; G 90 +U 120 ; WX 602 ; N x ; G 91 +U 121 ; WX 602 ; N y ; G 92 +U 122 ; WX 602 ; N z ; G 93 +U 123 ; WX 602 ; N braceleft ; G 94 +U 124 ; WX 602 ; N bar ; G 95 +U 125 ; WX 602 ; N braceright ; G 96 +U 126 ; WX 602 ; N asciitilde ; G 97 +U 160 ; WX 602 ; N nbspace ; G 98 +U 161 ; WX 602 ; N exclamdown ; G 99 +U 162 ; WX 602 ; N cent ; G 100 +U 163 ; WX 602 ; N sterling ; G 101 +U 164 ; WX 602 ; N currency ; G 102 +U 165 ; WX 602 ; N yen ; G 103 +U 166 ; WX 602 ; N brokenbar ; G 104 +U 167 ; WX 602 ; N section ; G 105 +U 168 ; WX 602 ; N dieresis ; G 106 +U 169 ; WX 602 ; N copyright ; G 107 +U 170 ; WX 602 ; N ordfeminine ; G 108 +U 171 ; WX 602 ; N guillemotleft ; G 109 +U 172 ; WX 602 ; N logicalnot ; G 110 +U 173 ; WX 602 ; N sfthyphen ; G 111 +U 174 ; WX 602 ; N registered ; G 112 +U 175 ; WX 602 ; N macron ; G 113 +U 176 ; WX 602 ; N degree ; G 114 +U 177 ; WX 602 ; N plusminus ; G 115 +U 178 ; WX 602 ; N twosuperior ; G 116 +U 179 ; WX 602 ; N threesuperior ; G 117 +U 180 ; WX 602 ; N acute ; G 118 +U 181 ; WX 602 ; N mu ; G 119 +U 182 ; WX 602 ; N paragraph ; G 120 +U 183 ; WX 602 ; N periodcentered ; G 121 +U 184 ; WX 602 ; N cedilla ; G 122 +U 185 ; WX 602 ; N onesuperior ; G 123 +U 186 ; WX 602 ; N ordmasculine ; G 124 +U 187 ; WX 602 ; N guillemotright ; G 125 +U 188 ; WX 602 ; N onequarter ; G 126 +U 189 ; WX 602 ; N onehalf ; G 127 +U 190 ; WX 602 ; N threequarters ; G 128 +U 191 ; WX 602 ; N questiondown ; G 129 +U 192 ; WX 602 ; N Agrave ; G 130 +U 193 ; WX 602 ; N Aacute ; G 131 +U 194 ; WX 602 ; N Acircumflex ; G 132 +U 195 ; WX 602 ; N Atilde ; G 133 +U 196 ; WX 602 ; N Adieresis ; G 134 +U 197 ; WX 602 ; N Aring ; G 135 +U 198 ; WX 602 ; N AE ; G 136 +U 199 ; WX 602 ; N Ccedilla ; G 137 +U 200 ; WX 602 ; N Egrave ; G 138 +U 201 ; WX 602 ; N Eacute ; G 139 +U 202 ; WX 602 ; N Ecircumflex ; G 140 +U 203 ; WX 602 ; N Edieresis ; G 141 +U 204 ; WX 602 ; N Igrave ; G 142 +U 205 ; WX 602 ; N Iacute ; G 143 +U 206 ; WX 602 ; N Icircumflex ; G 144 +U 207 ; WX 602 ; N Idieresis ; G 145 +U 208 ; WX 602 ; N Eth ; G 146 +U 209 ; WX 602 ; N Ntilde ; G 147 +U 210 ; WX 602 ; N Ograve ; G 148 +U 211 ; WX 602 ; N Oacute ; G 149 +U 212 ; WX 602 ; N Ocircumflex ; G 150 +U 213 ; WX 602 ; N Otilde ; G 151 +U 214 ; WX 602 ; N Odieresis ; G 152 +U 215 ; WX 602 ; N multiply ; G 153 +U 216 ; WX 602 ; N Oslash ; G 154 +U 217 ; WX 602 ; N Ugrave ; G 155 +U 218 ; WX 602 ; N Uacute ; G 156 +U 219 ; WX 602 ; N Ucircumflex ; G 157 +U 220 ; WX 602 ; N Udieresis ; G 158 +U 221 ; WX 602 ; N Yacute ; G 159 +U 222 ; WX 602 ; N Thorn ; G 160 +U 223 ; WX 602 ; N germandbls ; G 161 +U 224 ; WX 602 ; N agrave ; G 162 +U 225 ; WX 602 ; N aacute ; G 163 +U 226 ; WX 602 ; N acircumflex ; G 164 +U 227 ; WX 602 ; N atilde ; G 165 +U 228 ; WX 602 ; N adieresis ; G 166 +U 229 ; WX 602 ; N aring ; G 167 +U 230 ; WX 602 ; N ae ; G 168 +U 231 ; WX 602 ; N ccedilla ; G 169 +U 232 ; WX 602 ; N egrave ; G 170 +U 233 ; WX 602 ; N eacute ; G 171 +U 234 ; WX 602 ; N ecircumflex ; G 172 +U 235 ; WX 602 ; N edieresis ; G 173 +U 236 ; WX 602 ; N igrave ; G 174 +U 237 ; WX 602 ; N iacute ; G 175 +U 238 ; WX 602 ; N icircumflex ; G 176 +U 239 ; WX 602 ; N idieresis ; G 177 +U 240 ; WX 602 ; N eth ; G 178 +U 241 ; WX 602 ; N ntilde ; G 179 +U 242 ; WX 602 ; N ograve ; G 180 +U 243 ; WX 602 ; N oacute ; G 181 +U 244 ; WX 602 ; N ocircumflex ; G 182 +U 245 ; WX 602 ; N otilde ; G 183 +U 246 ; WX 602 ; N odieresis ; G 184 +U 247 ; WX 602 ; N divide ; G 185 +U 248 ; WX 602 ; N oslash ; G 186 +U 249 ; WX 602 ; N ugrave ; G 187 +U 250 ; WX 602 ; N uacute ; G 188 +U 251 ; WX 602 ; N ucircumflex ; G 189 +U 252 ; WX 602 ; N udieresis ; G 190 +U 253 ; WX 602 ; N yacute ; G 191 +U 254 ; WX 602 ; N thorn ; G 192 +U 255 ; WX 602 ; N ydieresis ; G 193 +U 256 ; WX 602 ; N Amacron ; G 194 +U 257 ; WX 602 ; N amacron ; G 195 +U 258 ; WX 602 ; N Abreve ; G 196 +U 259 ; WX 602 ; N abreve ; G 197 +U 260 ; WX 602 ; N Aogonek ; G 198 +U 261 ; WX 602 ; N aogonek ; G 199 +U 262 ; WX 602 ; N Cacute ; G 200 +U 263 ; WX 602 ; N cacute ; G 201 +U 264 ; WX 602 ; N Ccircumflex ; G 202 +U 265 ; WX 602 ; N ccircumflex ; G 203 +U 266 ; WX 602 ; N Cdotaccent ; G 204 +U 267 ; WX 602 ; N cdotaccent ; G 205 +U 268 ; WX 602 ; N Ccaron ; G 206 +U 269 ; WX 602 ; N ccaron ; G 207 +U 270 ; WX 602 ; N Dcaron ; G 208 +U 271 ; WX 602 ; N dcaron ; G 209 +U 272 ; WX 602 ; N Dcroat ; G 210 +U 273 ; WX 602 ; N dmacron ; G 211 +U 274 ; WX 602 ; N Emacron ; G 212 +U 275 ; WX 602 ; N emacron ; G 213 +U 276 ; WX 602 ; N Ebreve ; G 214 +U 277 ; WX 602 ; N ebreve ; G 215 +U 278 ; WX 602 ; N Edotaccent ; G 216 +U 279 ; WX 602 ; N edotaccent ; G 217 +U 280 ; WX 602 ; N Eogonek ; G 218 +U 281 ; WX 602 ; N eogonek ; G 219 +U 282 ; WX 602 ; N Ecaron ; G 220 +U 283 ; WX 602 ; N ecaron ; G 221 +U 284 ; WX 602 ; N Gcircumflex ; G 222 +U 285 ; WX 602 ; N gcircumflex ; G 223 +U 286 ; WX 602 ; N Gbreve ; G 224 +U 287 ; WX 602 ; N gbreve ; G 225 +U 288 ; WX 602 ; N Gdotaccent ; G 226 +U 289 ; WX 602 ; N gdotaccent ; G 227 +U 290 ; WX 602 ; N Gcommaaccent ; G 228 +U 291 ; WX 602 ; N gcommaaccent ; G 229 +U 292 ; WX 602 ; N Hcircumflex ; G 230 +U 293 ; WX 602 ; N hcircumflex ; G 231 +U 294 ; WX 602 ; N Hbar ; G 232 +U 295 ; WX 602 ; N hbar ; G 233 +U 296 ; WX 602 ; N Itilde ; G 234 +U 297 ; WX 602 ; N itilde ; G 235 +U 298 ; WX 602 ; N Imacron ; G 236 +U 299 ; WX 602 ; N imacron ; G 237 +U 300 ; WX 602 ; N Ibreve ; G 238 +U 301 ; WX 602 ; N ibreve ; G 239 +U 302 ; WX 602 ; N Iogonek ; G 240 +U 303 ; WX 602 ; N iogonek ; G 241 +U 304 ; WX 602 ; N Idot ; G 242 +U 305 ; WX 602 ; N dotlessi ; G 243 +U 306 ; WX 602 ; N IJ ; G 244 +U 307 ; WX 602 ; N ij ; G 245 +U 308 ; WX 602 ; N Jcircumflex ; G 246 +U 309 ; WX 602 ; N jcircumflex ; G 247 +U 310 ; WX 602 ; N Kcommaaccent ; G 248 +U 311 ; WX 602 ; N kcommaaccent ; G 249 +U 312 ; WX 602 ; N kgreenlandic ; G 250 +U 313 ; WX 602 ; N Lacute ; G 251 +U 314 ; WX 602 ; N lacute ; G 252 +U 315 ; WX 602 ; N Lcommaaccent ; G 253 +U 316 ; WX 602 ; N lcommaaccent ; G 254 +U 317 ; WX 602 ; N Lcaron ; G 255 +U 318 ; WX 602 ; N lcaron ; G 256 +U 319 ; WX 602 ; N Ldot ; G 257 +U 320 ; WX 602 ; N ldot ; G 258 +U 321 ; WX 602 ; N Lslash ; G 259 +U 322 ; WX 602 ; N lslash ; G 260 +U 323 ; WX 602 ; N Nacute ; G 261 +U 324 ; WX 602 ; N nacute ; G 262 +U 325 ; WX 602 ; N Ncommaaccent ; G 263 +U 326 ; WX 602 ; N ncommaaccent ; G 264 +U 327 ; WX 602 ; N Ncaron ; G 265 +U 328 ; WX 602 ; N ncaron ; G 266 +U 329 ; WX 602 ; N napostrophe ; G 267 +U 330 ; WX 602 ; N Eng ; G 268 +U 331 ; WX 602 ; N eng ; G 269 +U 332 ; WX 602 ; N Omacron ; G 270 +U 333 ; WX 602 ; N omacron ; G 271 +U 334 ; WX 602 ; N Obreve ; G 272 +U 335 ; WX 602 ; N obreve ; G 273 +U 336 ; WX 602 ; N Ohungarumlaut ; G 274 +U 337 ; WX 602 ; N ohungarumlaut ; G 275 +U 338 ; WX 602 ; N OE ; G 276 +U 339 ; WX 602 ; N oe ; G 277 +U 340 ; WX 602 ; N Racute ; G 278 +U 341 ; WX 602 ; N racute ; G 279 +U 342 ; WX 602 ; N Rcommaaccent ; G 280 +U 343 ; WX 602 ; N rcommaaccent ; G 281 +U 344 ; WX 602 ; N Rcaron ; G 282 +U 345 ; WX 602 ; N rcaron ; G 283 +U 346 ; WX 602 ; N Sacute ; G 284 +U 347 ; WX 602 ; N sacute ; G 285 +U 348 ; WX 602 ; N Scircumflex ; G 286 +U 349 ; WX 602 ; N scircumflex ; G 287 +U 350 ; WX 602 ; N Scedilla ; G 288 +U 351 ; WX 602 ; N scedilla ; G 289 +U 352 ; WX 602 ; N Scaron ; G 290 +U 353 ; WX 602 ; N scaron ; G 291 +U 354 ; WX 602 ; N Tcommaaccent ; G 292 +U 355 ; WX 602 ; N tcommaaccent ; G 293 +U 356 ; WX 602 ; N Tcaron ; G 294 +U 357 ; WX 602 ; N tcaron ; G 295 +U 358 ; WX 602 ; N Tbar ; G 296 +U 359 ; WX 602 ; N tbar ; G 297 +U 360 ; WX 602 ; N Utilde ; G 298 +U 361 ; WX 602 ; N utilde ; G 299 +U 362 ; WX 602 ; N Umacron ; G 300 +U 363 ; WX 602 ; N umacron ; G 301 +U 364 ; WX 602 ; N Ubreve ; G 302 +U 365 ; WX 602 ; N ubreve ; G 303 +U 366 ; WX 602 ; N Uring ; G 304 +U 367 ; WX 602 ; N uring ; G 305 +U 368 ; WX 602 ; N Uhungarumlaut ; G 306 +U 369 ; WX 602 ; N uhungarumlaut ; G 307 +U 370 ; WX 602 ; N Uogonek ; G 308 +U 371 ; WX 602 ; N uogonek ; G 309 +U 372 ; WX 602 ; N Wcircumflex ; G 310 +U 373 ; WX 602 ; N wcircumflex ; G 311 +U 374 ; WX 602 ; N Ycircumflex ; G 312 +U 375 ; WX 602 ; N ycircumflex ; G 313 +U 376 ; WX 602 ; N Ydieresis ; G 314 +U 377 ; WX 602 ; N Zacute ; G 315 +U 378 ; WX 602 ; N zacute ; G 316 +U 379 ; WX 602 ; N Zdotaccent ; G 317 +U 380 ; WX 602 ; N zdotaccent ; G 318 +U 381 ; WX 602 ; N Zcaron ; G 319 +U 382 ; WX 602 ; N zcaron ; G 320 +U 383 ; WX 602 ; N longs ; G 321 +U 384 ; WX 602 ; N uni0180 ; G 322 +U 385 ; WX 602 ; N uni0181 ; G 323 +U 386 ; WX 602 ; N uni0182 ; G 324 +U 387 ; WX 602 ; N uni0183 ; G 325 +U 388 ; WX 602 ; N uni0184 ; G 326 +U 389 ; WX 602 ; N uni0185 ; G 327 +U 390 ; WX 602 ; N uni0186 ; G 328 +U 391 ; WX 602 ; N uni0187 ; G 329 +U 392 ; WX 602 ; N uni0188 ; G 330 +U 393 ; WX 602 ; N uni0189 ; G 331 +U 394 ; WX 602 ; N uni018A ; G 332 +U 395 ; WX 602 ; N uni018B ; G 333 +U 396 ; WX 602 ; N uni018C ; G 334 +U 397 ; WX 602 ; N uni018D ; G 335 +U 398 ; WX 602 ; N uni018E ; G 336 +U 399 ; WX 602 ; N uni018F ; G 337 +U 400 ; WX 602 ; N uni0190 ; G 338 +U 401 ; WX 602 ; N uni0191 ; G 339 +U 402 ; WX 602 ; N florin ; G 340 +U 403 ; WX 602 ; N uni0193 ; G 341 +U 404 ; WX 602 ; N uni0194 ; G 342 +U 405 ; WX 602 ; N uni0195 ; G 343 +U 406 ; WX 602 ; N uni0196 ; G 344 +U 407 ; WX 602 ; N uni0197 ; G 345 +U 408 ; WX 602 ; N uni0198 ; G 346 +U 409 ; WX 602 ; N uni0199 ; G 347 +U 410 ; WX 602 ; N uni019A ; G 348 +U 411 ; WX 602 ; N uni019B ; G 349 +U 412 ; WX 602 ; N uni019C ; G 350 +U 413 ; WX 602 ; N uni019D ; G 351 +U 414 ; WX 602 ; N uni019E ; G 352 +U 415 ; WX 602 ; N uni019F ; G 353 +U 416 ; WX 602 ; N Ohorn ; G 354 +U 417 ; WX 602 ; N ohorn ; G 355 +U 418 ; WX 602 ; N uni01A2 ; G 356 +U 419 ; WX 602 ; N uni01A3 ; G 357 +U 420 ; WX 602 ; N uni01A4 ; G 358 +U 421 ; WX 602 ; N uni01A5 ; G 359 +U 422 ; WX 602 ; N uni01A6 ; G 360 +U 423 ; WX 602 ; N uni01A7 ; G 361 +U 424 ; WX 602 ; N uni01A8 ; G 362 +U 425 ; WX 602 ; N uni01A9 ; G 363 +U 426 ; WX 602 ; N uni01AA ; G 364 +U 427 ; WX 602 ; N uni01AB ; G 365 +U 428 ; WX 602 ; N uni01AC ; G 366 +U 429 ; WX 602 ; N uni01AD ; G 367 +U 430 ; WX 602 ; N uni01AE ; G 368 +U 431 ; WX 602 ; N Uhorn ; G 369 +U 432 ; WX 602 ; N uhorn ; G 370 +U 433 ; WX 602 ; N uni01B1 ; G 371 +U 434 ; WX 602 ; N uni01B2 ; G 372 +U 435 ; WX 602 ; N uni01B3 ; G 373 +U 436 ; WX 602 ; N uni01B4 ; G 374 +U 437 ; WX 602 ; N uni01B5 ; G 375 +U 438 ; WX 602 ; N uni01B6 ; G 376 +U 439 ; WX 602 ; N uni01B7 ; G 377 +U 440 ; WX 602 ; N uni01B8 ; G 378 +U 441 ; WX 602 ; N uni01B9 ; G 379 +U 442 ; WX 602 ; N uni01BA ; G 380 +U 443 ; WX 602 ; N uni01BB ; G 381 +U 444 ; WX 602 ; N uni01BC ; G 382 +U 445 ; WX 602 ; N uni01BD ; G 383 +U 446 ; WX 602 ; N uni01BE ; G 384 +U 447 ; WX 602 ; N uni01BF ; G 385 +U 448 ; WX 602 ; N uni01C0 ; G 386 +U 449 ; WX 602 ; N uni01C1 ; G 387 +U 450 ; WX 602 ; N uni01C2 ; G 388 +U 451 ; WX 602 ; N uni01C3 ; G 389 +U 461 ; WX 602 ; N uni01CD ; G 390 +U 462 ; WX 602 ; N uni01CE ; G 391 +U 463 ; WX 602 ; N uni01CF ; G 392 +U 464 ; WX 602 ; N uni01D0 ; G 393 +U 465 ; WX 602 ; N uni01D1 ; G 394 +U 466 ; WX 602 ; N uni01D2 ; G 395 +U 467 ; WX 602 ; N uni01D3 ; G 396 +U 468 ; WX 602 ; N uni01D4 ; G 397 +U 469 ; WX 602 ; N uni01D5 ; G 398 +U 470 ; WX 602 ; N uni01D6 ; G 399 +U 471 ; WX 602 ; N uni01D7 ; G 400 +U 472 ; WX 602 ; N uni01D8 ; G 401 +U 473 ; WX 602 ; N uni01D9 ; G 402 +U 474 ; WX 602 ; N uni01DA ; G 403 +U 475 ; WX 602 ; N uni01DB ; G 404 +U 476 ; WX 602 ; N uni01DC ; G 405 +U 477 ; WX 602 ; N uni01DD ; G 406 +U 478 ; WX 602 ; N uni01DE ; G 407 +U 479 ; WX 602 ; N uni01DF ; G 408 +U 480 ; WX 602 ; N uni01E0 ; G 409 +U 481 ; WX 602 ; N uni01E1 ; G 410 +U 482 ; WX 602 ; N uni01E2 ; G 411 +U 483 ; WX 602 ; N uni01E3 ; G 412 +U 486 ; WX 602 ; N Gcaron ; G 413 +U 487 ; WX 602 ; N gcaron ; G 414 +U 488 ; WX 602 ; N uni01E8 ; G 415 +U 489 ; WX 602 ; N uni01E9 ; G 416 +U 490 ; WX 602 ; N uni01EA ; G 417 +U 491 ; WX 602 ; N uni01EB ; G 418 +U 492 ; WX 602 ; N uni01EC ; G 419 +U 493 ; WX 602 ; N uni01ED ; G 420 +U 494 ; WX 602 ; N uni01EE ; G 421 +U 495 ; WX 602 ; N uni01EF ; G 422 +U 496 ; WX 602 ; N uni01F0 ; G 423 +U 500 ; WX 602 ; N uni01F4 ; G 424 +U 501 ; WX 602 ; N uni01F5 ; G 425 +U 502 ; WX 602 ; N uni01F6 ; G 426 +U 504 ; WX 602 ; N uni01F8 ; G 427 +U 505 ; WX 602 ; N uni01F9 ; G 428 +U 508 ; WX 602 ; N AEacute ; G 429 +U 509 ; WX 602 ; N aeacute ; G 430 +U 510 ; WX 602 ; N Oslashacute ; G 431 +U 511 ; WX 602 ; N oslashacute ; G 432 +U 512 ; WX 602 ; N uni0200 ; G 433 +U 513 ; WX 602 ; N uni0201 ; G 434 +U 514 ; WX 602 ; N uni0202 ; G 435 +U 515 ; WX 602 ; N uni0203 ; G 436 +U 516 ; WX 602 ; N uni0204 ; G 437 +U 517 ; WX 602 ; N uni0205 ; G 438 +U 518 ; WX 602 ; N uni0206 ; G 439 +U 519 ; WX 602 ; N uni0207 ; G 440 +U 520 ; WX 602 ; N uni0208 ; G 441 +U 521 ; WX 602 ; N uni0209 ; G 442 +U 522 ; WX 602 ; N uni020A ; G 443 +U 523 ; WX 602 ; N uni020B ; G 444 +U 524 ; WX 602 ; N uni020C ; G 445 +U 525 ; WX 602 ; N uni020D ; G 446 +U 526 ; WX 602 ; N uni020E ; G 447 +U 527 ; WX 602 ; N uni020F ; G 448 +U 528 ; WX 602 ; N uni0210 ; G 449 +U 529 ; WX 602 ; N uni0211 ; G 450 +U 530 ; WX 602 ; N uni0212 ; G 451 +U 531 ; WX 602 ; N uni0213 ; G 452 +U 532 ; WX 602 ; N uni0214 ; G 453 +U 533 ; WX 602 ; N uni0215 ; G 454 +U 534 ; WX 602 ; N uni0216 ; G 455 +U 535 ; WX 602 ; N uni0217 ; G 456 +U 536 ; WX 602 ; N Scommaaccent ; G 457 +U 537 ; WX 602 ; N scommaaccent ; G 458 +U 538 ; WX 602 ; N uni021A ; G 459 +U 539 ; WX 602 ; N uni021B ; G 460 +U 540 ; WX 602 ; N uni021C ; G 461 +U 541 ; WX 602 ; N uni021D ; G 462 +U 542 ; WX 602 ; N uni021E ; G 463 +U 543 ; WX 602 ; N uni021F ; G 464 +U 544 ; WX 602 ; N uni0220 ; G 465 +U 545 ; WX 602 ; N uni0221 ; G 466 +U 548 ; WX 602 ; N uni0224 ; G 467 +U 549 ; WX 602 ; N uni0225 ; G 468 +U 550 ; WX 602 ; N uni0226 ; G 469 +U 551 ; WX 602 ; N uni0227 ; G 470 +U 552 ; WX 602 ; N uni0228 ; G 471 +U 553 ; WX 602 ; N uni0229 ; G 472 +U 554 ; WX 602 ; N uni022A ; G 473 +U 555 ; WX 602 ; N uni022B ; G 474 +U 556 ; WX 602 ; N uni022C ; G 475 +U 557 ; WX 602 ; N uni022D ; G 476 +U 558 ; WX 602 ; N uni022E ; G 477 +U 559 ; WX 602 ; N uni022F ; G 478 +U 560 ; WX 602 ; N uni0230 ; G 479 +U 561 ; WX 602 ; N uni0231 ; G 480 +U 562 ; WX 602 ; N uni0232 ; G 481 +U 563 ; WX 602 ; N uni0233 ; G 482 +U 564 ; WX 602 ; N uni0234 ; G 483 +U 565 ; WX 602 ; N uni0235 ; G 484 +U 566 ; WX 602 ; N uni0236 ; G 485 +U 567 ; WX 602 ; N dotlessj ; G 486 +U 568 ; WX 602 ; N uni0238 ; G 487 +U 569 ; WX 602 ; N uni0239 ; G 488 +U 570 ; WX 602 ; N uni023A ; G 489 +U 571 ; WX 602 ; N uni023B ; G 490 +U 572 ; WX 602 ; N uni023C ; G 491 +U 573 ; WX 602 ; N uni023D ; G 492 +U 574 ; WX 602 ; N uni023E ; G 493 +U 575 ; WX 602 ; N uni023F ; G 494 +U 576 ; WX 602 ; N uni0240 ; G 495 +U 577 ; WX 602 ; N uni0241 ; G 496 +U 579 ; WX 602 ; N uni0243 ; G 497 +U 580 ; WX 602 ; N uni0244 ; G 498 +U 581 ; WX 602 ; N uni0245 ; G 499 +U 588 ; WX 602 ; N uni024C ; G 500 +U 589 ; WX 602 ; N uni024D ; G 501 +U 592 ; WX 602 ; N uni0250 ; G 502 +U 593 ; WX 602 ; N uni0251 ; G 503 +U 594 ; WX 602 ; N uni0252 ; G 504 +U 595 ; WX 602 ; N uni0253 ; G 505 +U 596 ; WX 602 ; N uni0254 ; G 506 +U 597 ; WX 602 ; N uni0255 ; G 507 +U 598 ; WX 602 ; N uni0256 ; G 508 +U 599 ; WX 602 ; N uni0257 ; G 509 +U 600 ; WX 602 ; N uni0258 ; G 510 +U 601 ; WX 602 ; N uni0259 ; G 511 +U 602 ; WX 602 ; N uni025A ; G 512 +U 603 ; WX 602 ; N uni025B ; G 513 +U 604 ; WX 602 ; N uni025C ; G 514 +U 605 ; WX 602 ; N uni025D ; G 515 +U 606 ; WX 602 ; N uni025E ; G 516 +U 607 ; WX 602 ; N uni025F ; G 517 +U 608 ; WX 602 ; N uni0260 ; G 518 +U 609 ; WX 602 ; N uni0261 ; G 519 +U 610 ; WX 602 ; N uni0262 ; G 520 +U 611 ; WX 602 ; N uni0263 ; G 521 +U 612 ; WX 602 ; N uni0264 ; G 522 +U 613 ; WX 602 ; N uni0265 ; G 523 +U 614 ; WX 602 ; N uni0266 ; G 524 +U 615 ; WX 602 ; N uni0267 ; G 525 +U 616 ; WX 602 ; N uni0268 ; G 526 +U 617 ; WX 602 ; N uni0269 ; G 527 +U 618 ; WX 602 ; N uni026A ; G 528 +U 619 ; WX 602 ; N uni026B ; G 529 +U 620 ; WX 602 ; N uni026C ; G 530 +U 621 ; WX 602 ; N uni026D ; G 531 +U 622 ; WX 602 ; N uni026E ; G 532 +U 623 ; WX 602 ; N uni026F ; G 533 +U 624 ; WX 602 ; N uni0270 ; G 534 +U 625 ; WX 602 ; N uni0271 ; G 535 +U 626 ; WX 602 ; N uni0272 ; G 536 +U 627 ; WX 602 ; N uni0273 ; G 537 +U 628 ; WX 602 ; N uni0274 ; G 538 +U 629 ; WX 602 ; N uni0275 ; G 539 +U 630 ; WX 602 ; N uni0276 ; G 540 +U 631 ; WX 602 ; N uni0277 ; G 541 +U 632 ; WX 602 ; N uni0278 ; G 542 +U 633 ; WX 602 ; N uni0279 ; G 543 +U 634 ; WX 602 ; N uni027A ; G 544 +U 635 ; WX 602 ; N uni027B ; G 545 +U 636 ; WX 602 ; N uni027C ; G 546 +U 637 ; WX 602 ; N uni027D ; G 547 +U 638 ; WX 602 ; N uni027E ; G 548 +U 639 ; WX 602 ; N uni027F ; G 549 +U 640 ; WX 602 ; N uni0280 ; G 550 +U 641 ; WX 602 ; N uni0281 ; G 551 +U 642 ; WX 602 ; N uni0282 ; G 552 +U 643 ; WX 602 ; N uni0283 ; G 553 +U 644 ; WX 602 ; N uni0284 ; G 554 +U 645 ; WX 602 ; N uni0285 ; G 555 +U 646 ; WX 602 ; N uni0286 ; G 556 +U 647 ; WX 602 ; N uni0287 ; G 557 +U 648 ; WX 602 ; N uni0288 ; G 558 +U 649 ; WX 602 ; N uni0289 ; G 559 +U 650 ; WX 602 ; N uni028A ; G 560 +U 651 ; WX 602 ; N uni028B ; G 561 +U 652 ; WX 602 ; N uni028C ; G 562 +U 653 ; WX 602 ; N uni028D ; G 563 +U 654 ; WX 602 ; N uni028E ; G 564 +U 655 ; WX 602 ; N uni028F ; G 565 +U 656 ; WX 602 ; N uni0290 ; G 566 +U 657 ; WX 602 ; N uni0291 ; G 567 +U 658 ; WX 602 ; N uni0292 ; G 568 +U 659 ; WX 602 ; N uni0293 ; G 569 +U 660 ; WX 602 ; N uni0294 ; G 570 +U 661 ; WX 602 ; N uni0295 ; G 571 +U 662 ; WX 602 ; N uni0296 ; G 572 +U 663 ; WX 602 ; N uni0297 ; G 573 +U 664 ; WX 602 ; N uni0298 ; G 574 +U 665 ; WX 602 ; N uni0299 ; G 575 +U 666 ; WX 602 ; N uni029A ; G 576 +U 667 ; WX 602 ; N uni029B ; G 577 +U 668 ; WX 602 ; N uni029C ; G 578 +U 669 ; WX 602 ; N uni029D ; G 579 +U 670 ; WX 602 ; N uni029E ; G 580 +U 671 ; WX 602 ; N uni029F ; G 581 +U 672 ; WX 602 ; N uni02A0 ; G 582 +U 673 ; WX 602 ; N uni02A1 ; G 583 +U 674 ; WX 602 ; N uni02A2 ; G 584 +U 675 ; WX 602 ; N uni02A3 ; G 585 +U 676 ; WX 602 ; N uni02A4 ; G 586 +U 677 ; WX 602 ; N uni02A5 ; G 587 +U 678 ; WX 602 ; N uni02A6 ; G 588 +U 679 ; WX 602 ; N uni02A7 ; G 589 +U 680 ; WX 602 ; N uni02A8 ; G 590 +U 681 ; WX 602 ; N uni02A9 ; G 591 +U 682 ; WX 602 ; N uni02AA ; G 592 +U 683 ; WX 602 ; N uni02AB ; G 593 +U 684 ; WX 602 ; N uni02AC ; G 594 +U 685 ; WX 602 ; N uni02AD ; G 595 +U 686 ; WX 602 ; N uni02AE ; G 596 +U 687 ; WX 602 ; N uni02AF ; G 597 +U 688 ; WX 602 ; N uni02B0 ; G 598 +U 689 ; WX 602 ; N uni02B1 ; G 599 +U 690 ; WX 602 ; N uni02B2 ; G 600 +U 691 ; WX 602 ; N uni02B3 ; G 601 +U 692 ; WX 602 ; N uni02B4 ; G 602 +U 693 ; WX 602 ; N uni02B5 ; G 603 +U 694 ; WX 602 ; N uni02B6 ; G 604 +U 695 ; WX 602 ; N uni02B7 ; G 605 +U 696 ; WX 602 ; N uni02B8 ; G 606 +U 697 ; WX 602 ; N uni02B9 ; G 607 +U 699 ; WX 602 ; N uni02BB ; G 608 +U 700 ; WX 602 ; N uni02BC ; G 609 +U 701 ; WX 602 ; N uni02BD ; G 610 +U 702 ; WX 602 ; N uni02BE ; G 611 +U 703 ; WX 602 ; N uni02BF ; G 612 +U 704 ; WX 602 ; N uni02C0 ; G 613 +U 705 ; WX 602 ; N uni02C1 ; G 614 +U 710 ; WX 602 ; N circumflex ; G 615 +U 711 ; WX 602 ; N caron ; G 616 +U 712 ; WX 602 ; N uni02C8 ; G 617 +U 713 ; WX 602 ; N uni02C9 ; G 618 +U 716 ; WX 602 ; N uni02CC ; G 619 +U 717 ; WX 602 ; N uni02CD ; G 620 +U 718 ; WX 602 ; N uni02CE ; G 621 +U 719 ; WX 602 ; N uni02CF ; G 622 +U 720 ; WX 602 ; N uni02D0 ; G 623 +U 721 ; WX 602 ; N uni02D1 ; G 624 +U 722 ; WX 602 ; N uni02D2 ; G 625 +U 723 ; WX 602 ; N uni02D3 ; G 626 +U 726 ; WX 602 ; N uni02D6 ; G 627 +U 727 ; WX 602 ; N uni02D7 ; G 628 +U 728 ; WX 602 ; N breve ; G 629 +U 729 ; WX 602 ; N dotaccent ; G 630 +U 730 ; WX 602 ; N ring ; G 631 +U 731 ; WX 602 ; N ogonek ; G 632 +U 732 ; WX 602 ; N tilde ; G 633 +U 733 ; WX 602 ; N hungarumlaut ; G 634 +U 734 ; WX 602 ; N uni02DE ; G 635 +U 736 ; WX 602 ; N uni02E0 ; G 636 +U 737 ; WX 602 ; N uni02E1 ; G 637 +U 738 ; WX 602 ; N uni02E2 ; G 638 +U 739 ; WX 602 ; N uni02E3 ; G 639 +U 740 ; WX 602 ; N uni02E4 ; G 640 +U 741 ; WX 602 ; N uni02E5 ; G 641 +U 742 ; WX 602 ; N uni02E6 ; G 642 +U 743 ; WX 602 ; N uni02E7 ; G 643 +U 744 ; WX 602 ; N uni02E8 ; G 644 +U 745 ; WX 602 ; N uni02E9 ; G 645 +U 750 ; WX 602 ; N uni02EE ; G 646 +U 755 ; WX 602 ; N uni02F3 ; G 647 +U 768 ; WX 602 ; N gravecomb ; G 648 +U 769 ; WX 602 ; N acutecomb ; G 649 +U 770 ; WX 602 ; N uni0302 ; G 650 +U 771 ; WX 602 ; N tildecomb ; G 651 +U 772 ; WX 602 ; N uni0304 ; G 652 +U 773 ; WX 602 ; N uni0305 ; G 653 +U 774 ; WX 602 ; N uni0306 ; G 654 +U 775 ; WX 602 ; N uni0307 ; G 655 +U 776 ; WX 602 ; N uni0308 ; G 656 +U 777 ; WX 602 ; N hookabovecomb ; G 657 +U 778 ; WX 602 ; N uni030A ; G 658 +U 779 ; WX 602 ; N uni030B ; G 659 +U 780 ; WX 602 ; N uni030C ; G 660 +U 781 ; WX 602 ; N uni030D ; G 661 +U 782 ; WX 602 ; N uni030E ; G 662 +U 783 ; WX 602 ; N uni030F ; G 663 +U 784 ; WX 602 ; N uni0310 ; G 664 +U 785 ; WX 602 ; N uni0311 ; G 665 +U 786 ; WX 602 ; N uni0312 ; G 666 +U 787 ; WX 602 ; N uni0313 ; G 667 +U 788 ; WX 602 ; N uni0314 ; G 668 +U 789 ; WX 602 ; N uni0315 ; G 669 +U 790 ; WX 602 ; N uni0316 ; G 670 +U 791 ; WX 602 ; N uni0317 ; G 671 +U 792 ; WX 602 ; N uni0318 ; G 672 +U 793 ; WX 602 ; N uni0319 ; G 673 +U 794 ; WX 602 ; N uni031A ; G 674 +U 795 ; WX 602 ; N uni031B ; G 675 +U 796 ; WX 602 ; N uni031C ; G 676 +U 797 ; WX 602 ; N uni031D ; G 677 +U 798 ; WX 602 ; N uni031E ; G 678 +U 799 ; WX 602 ; N uni031F ; G 679 +U 800 ; WX 602 ; N uni0320 ; G 680 +U 801 ; WX 602 ; N uni0321 ; G 681 +U 802 ; WX 602 ; N uni0322 ; G 682 +U 803 ; WX 602 ; N dotbelowcomb ; G 683 +U 804 ; WX 602 ; N uni0324 ; G 684 +U 805 ; WX 602 ; N uni0325 ; G 685 +U 806 ; WX 602 ; N uni0326 ; G 686 +U 807 ; WX 602 ; N uni0327 ; G 687 +U 808 ; WX 602 ; N uni0328 ; G 688 +U 809 ; WX 602 ; N uni0329 ; G 689 +U 810 ; WX 602 ; N uni032A ; G 690 +U 811 ; WX 602 ; N uni032B ; G 691 +U 812 ; WX 602 ; N uni032C ; G 692 +U 813 ; WX 602 ; N uni032D ; G 693 +U 814 ; WX 602 ; N uni032E ; G 694 +U 815 ; WX 602 ; N uni032F ; G 695 +U 816 ; WX 602 ; N uni0330 ; G 696 +U 817 ; WX 602 ; N uni0331 ; G 697 +U 818 ; WX 602 ; N uni0332 ; G 698 +U 819 ; WX 602 ; N uni0333 ; G 699 +U 820 ; WX 602 ; N uni0334 ; G 700 +U 821 ; WX 602 ; N uni0335 ; G 701 +U 822 ; WX 602 ; N uni0336 ; G 702 +U 823 ; WX 602 ; N uni0337 ; G 703 +U 824 ; WX 602 ; N uni0338 ; G 704 +U 825 ; WX 602 ; N uni0339 ; G 705 +U 826 ; WX 602 ; N uni033A ; G 706 +U 827 ; WX 602 ; N uni033B ; G 707 +U 828 ; WX 602 ; N uni033C ; G 708 +U 829 ; WX 602 ; N uni033D ; G 709 +U 830 ; WX 602 ; N uni033E ; G 710 +U 831 ; WX 602 ; N uni033F ; G 711 +U 835 ; WX 602 ; N uni0343 ; G 712 +U 856 ; WX 602 ; N uni0358 ; G 713 +U 865 ; WX 602 ; N uni0361 ; G 714 +U 884 ; WX 602 ; N uni0374 ; G 715 +U 885 ; WX 602 ; N uni0375 ; G 716 +U 886 ; WX 602 ; N uni0376 ; G 717 +U 887 ; WX 602 ; N uni0377 ; G 718 +U 890 ; WX 602 ; N uni037A ; G 719 +U 891 ; WX 602 ; N uni037B ; G 720 +U 892 ; WX 602 ; N uni037C ; G 721 +U 893 ; WX 602 ; N uni037D ; G 722 +U 894 ; WX 602 ; N uni037E ; G 723 +U 895 ; WX 602 ; N uni037F ; G 724 +U 900 ; WX 602 ; N tonos ; G 725 +U 901 ; WX 602 ; N dieresistonos ; G 726 +U 902 ; WX 602 ; N Alphatonos ; G 727 +U 903 ; WX 602 ; N anoteleia ; G 728 +U 904 ; WX 602 ; N Epsilontonos ; G 729 +U 905 ; WX 602 ; N Etatonos ; G 730 +U 906 ; WX 602 ; N Iotatonos ; G 731 +U 908 ; WX 602 ; N Omicrontonos ; G 732 +U 910 ; WX 602 ; N Upsilontonos ; G 733 +U 911 ; WX 602 ; N Omegatonos ; G 734 +U 912 ; WX 602 ; N iotadieresistonos ; G 735 +U 913 ; WX 602 ; N Alpha ; G 736 +U 914 ; WX 602 ; N Beta ; G 737 +U 915 ; WX 602 ; N Gamma ; G 738 +U 916 ; WX 602 ; N uni0394 ; G 739 +U 917 ; WX 602 ; N Epsilon ; G 740 +U 918 ; WX 602 ; N Zeta ; G 741 +U 919 ; WX 602 ; N Eta ; G 742 +U 920 ; WX 602 ; N Theta ; G 743 +U 921 ; WX 602 ; N Iota ; G 744 +U 922 ; WX 602 ; N Kappa ; G 745 +U 923 ; WX 602 ; N Lambda ; G 746 +U 924 ; WX 602 ; N Mu ; G 747 +U 925 ; WX 602 ; N Nu ; G 748 +U 926 ; WX 602 ; N Xi ; G 749 +U 927 ; WX 602 ; N Omicron ; G 750 +U 928 ; WX 602 ; N Pi ; G 751 +U 929 ; WX 602 ; N Rho ; G 752 +U 931 ; WX 602 ; N Sigma ; G 753 +U 932 ; WX 602 ; N Tau ; G 754 +U 933 ; WX 602 ; N Upsilon ; G 755 +U 934 ; WX 602 ; N Phi ; G 756 +U 935 ; WX 602 ; N Chi ; G 757 +U 936 ; WX 602 ; N Psi ; G 758 +U 937 ; WX 602 ; N Omega ; G 759 +U 938 ; WX 602 ; N Iotadieresis ; G 760 +U 939 ; WX 602 ; N Upsilondieresis ; G 761 +U 940 ; WX 602 ; N alphatonos ; G 762 +U 941 ; WX 602 ; N epsilontonos ; G 763 +U 942 ; WX 602 ; N etatonos ; G 764 +U 943 ; WX 602 ; N iotatonos ; G 765 +U 944 ; WX 602 ; N upsilondieresistonos ; G 766 +U 945 ; WX 602 ; N alpha ; G 767 +U 946 ; WX 602 ; N beta ; G 768 +U 947 ; WX 602 ; N gamma ; G 769 +U 948 ; WX 602 ; N delta ; G 770 +U 949 ; WX 602 ; N epsilon ; G 771 +U 950 ; WX 602 ; N zeta ; G 772 +U 951 ; WX 602 ; N eta ; G 773 +U 952 ; WX 602 ; N theta ; G 774 +U 953 ; WX 602 ; N iota ; G 775 +U 954 ; WX 602 ; N kappa ; G 776 +U 955 ; WX 602 ; N lambda ; G 777 +U 956 ; WX 602 ; N uni03BC ; G 778 +U 957 ; WX 602 ; N nu ; G 779 +U 958 ; WX 602 ; N xi ; G 780 +U 959 ; WX 602 ; N omicron ; G 781 +U 960 ; WX 602 ; N pi ; G 782 +U 961 ; WX 602 ; N rho ; G 783 +U 962 ; WX 602 ; N sigma1 ; G 784 +U 963 ; WX 602 ; N sigma ; G 785 +U 964 ; WX 602 ; N tau ; G 786 +U 965 ; WX 602 ; N upsilon ; G 787 +U 966 ; WX 602 ; N phi ; G 788 +U 967 ; WX 602 ; N chi ; G 789 +U 968 ; WX 602 ; N psi ; G 790 +U 969 ; WX 602 ; N omega ; G 791 +U 970 ; WX 602 ; N iotadieresis ; G 792 +U 971 ; WX 602 ; N upsilondieresis ; G 793 +U 972 ; WX 602 ; N omicrontonos ; G 794 +U 973 ; WX 602 ; N upsilontonos ; G 795 +U 974 ; WX 602 ; N omegatonos ; G 796 +U 976 ; WX 602 ; N uni03D0 ; G 797 +U 977 ; WX 602 ; N theta1 ; G 798 +U 978 ; WX 602 ; N Upsilon1 ; G 799 +U 979 ; WX 602 ; N uni03D3 ; G 800 +U 980 ; WX 602 ; N uni03D4 ; G 801 +U 981 ; WX 602 ; N phi1 ; G 802 +U 982 ; WX 602 ; N omega1 ; G 803 +U 983 ; WX 602 ; N uni03D7 ; G 804 +U 984 ; WX 602 ; N uni03D8 ; G 805 +U 985 ; WX 602 ; N uni03D9 ; G 806 +U 986 ; WX 602 ; N uni03DA ; G 807 +U 987 ; WX 602 ; N uni03DB ; G 808 +U 988 ; WX 602 ; N uni03DC ; G 809 +U 989 ; WX 602 ; N uni03DD ; G 810 +U 990 ; WX 602 ; N uni03DE ; G 811 +U 991 ; WX 602 ; N uni03DF ; G 812 +U 992 ; WX 602 ; N uni03E0 ; G 813 +U 993 ; WX 602 ; N uni03E1 ; G 814 +U 1008 ; WX 602 ; N uni03F0 ; G 815 +U 1009 ; WX 602 ; N uni03F1 ; G 816 +U 1010 ; WX 602 ; N uni03F2 ; G 817 +U 1011 ; WX 602 ; N uni03F3 ; G 818 +U 1012 ; WX 602 ; N uni03F4 ; G 819 +U 1013 ; WX 602 ; N uni03F5 ; G 820 +U 1014 ; WX 602 ; N uni03F6 ; G 821 +U 1015 ; WX 602 ; N uni03F7 ; G 822 +U 1016 ; WX 602 ; N uni03F8 ; G 823 +U 1017 ; WX 602 ; N uni03F9 ; G 824 +U 1018 ; WX 602 ; N uni03FA ; G 825 +U 1019 ; WX 602 ; N uni03FB ; G 826 +U 1020 ; WX 602 ; N uni03FC ; G 827 +U 1021 ; WX 602 ; N uni03FD ; G 828 +U 1022 ; WX 602 ; N uni03FE ; G 829 +U 1023 ; WX 602 ; N uni03FF ; G 830 +U 1024 ; WX 602 ; N uni0400 ; G 831 +U 1025 ; WX 602 ; N uni0401 ; G 832 +U 1026 ; WX 602 ; N uni0402 ; G 833 +U 1027 ; WX 602 ; N uni0403 ; G 834 +U 1028 ; WX 602 ; N uni0404 ; G 835 +U 1029 ; WX 602 ; N uni0405 ; G 836 +U 1030 ; WX 602 ; N uni0406 ; G 837 +U 1031 ; WX 602 ; N uni0407 ; G 838 +U 1032 ; WX 602 ; N uni0408 ; G 839 +U 1033 ; WX 602 ; N uni0409 ; G 840 +U 1034 ; WX 602 ; N uni040A ; G 841 +U 1035 ; WX 602 ; N uni040B ; G 842 +U 1036 ; WX 602 ; N uni040C ; G 843 +U 1037 ; WX 602 ; N uni040D ; G 844 +U 1038 ; WX 602 ; N uni040E ; G 845 +U 1039 ; WX 602 ; N uni040F ; G 846 +U 1040 ; WX 602 ; N uni0410 ; G 847 +U 1041 ; WX 602 ; N uni0411 ; G 848 +U 1042 ; WX 602 ; N uni0412 ; G 849 +U 1043 ; WX 602 ; N uni0413 ; G 850 +U 1044 ; WX 602 ; N uni0414 ; G 851 +U 1045 ; WX 602 ; N uni0415 ; G 852 +U 1046 ; WX 602 ; N uni0416 ; G 853 +U 1047 ; WX 602 ; N uni0417 ; G 854 +U 1048 ; WX 602 ; N uni0418 ; G 855 +U 1049 ; WX 602 ; N uni0419 ; G 856 +U 1050 ; WX 602 ; N uni041A ; G 857 +U 1051 ; WX 602 ; N uni041B ; G 858 +U 1052 ; WX 602 ; N uni041C ; G 859 +U 1053 ; WX 602 ; N uni041D ; G 860 +U 1054 ; WX 602 ; N uni041E ; G 861 +U 1055 ; WX 602 ; N uni041F ; G 862 +U 1056 ; WX 602 ; N uni0420 ; G 863 +U 1057 ; WX 602 ; N uni0421 ; G 864 +U 1058 ; WX 602 ; N uni0422 ; G 865 +U 1059 ; WX 602 ; N uni0423 ; G 866 +U 1060 ; WX 602 ; N uni0424 ; G 867 +U 1061 ; WX 602 ; N uni0425 ; G 868 +U 1062 ; WX 602 ; N uni0426 ; G 869 +U 1063 ; WX 602 ; N uni0427 ; G 870 +U 1064 ; WX 602 ; N uni0428 ; G 871 +U 1065 ; WX 602 ; N uni0429 ; G 872 +U 1066 ; WX 602 ; N uni042A ; G 873 +U 1067 ; WX 602 ; N uni042B ; G 874 +U 1068 ; WX 602 ; N uni042C ; G 875 +U 1069 ; WX 602 ; N uni042D ; G 876 +U 1070 ; WX 602 ; N uni042E ; G 877 +U 1071 ; WX 602 ; N uni042F ; G 878 +U 1072 ; WX 602 ; N uni0430 ; G 879 +U 1073 ; WX 602 ; N uni0431 ; G 880 +U 1074 ; WX 602 ; N uni0432 ; G 881 +U 1075 ; WX 602 ; N uni0433 ; G 882 +U 1076 ; WX 602 ; N uni0434 ; G 883 +U 1077 ; WX 602 ; N uni0435 ; G 884 +U 1078 ; WX 602 ; N uni0436 ; G 885 +U 1079 ; WX 602 ; N uni0437 ; G 886 +U 1080 ; WX 602 ; N uni0438 ; G 887 +U 1081 ; WX 602 ; N uni0439 ; G 888 +U 1082 ; WX 602 ; N uni043A ; G 889 +U 1083 ; WX 602 ; N uni043B ; G 890 +U 1084 ; WX 602 ; N uni043C ; G 891 +U 1085 ; WX 602 ; N uni043D ; G 892 +U 1086 ; WX 602 ; N uni043E ; G 893 +U 1087 ; WX 602 ; N uni043F ; G 894 +U 1088 ; WX 602 ; N uni0440 ; G 895 +U 1089 ; WX 602 ; N uni0441 ; G 896 +U 1090 ; WX 602 ; N uni0442 ; G 897 +U 1091 ; WX 602 ; N uni0443 ; G 898 +U 1092 ; WX 602 ; N uni0444 ; G 899 +U 1093 ; WX 602 ; N uni0445 ; G 900 +U 1094 ; WX 602 ; N uni0446 ; G 901 +U 1095 ; WX 602 ; N uni0447 ; G 902 +U 1096 ; WX 602 ; N uni0448 ; G 903 +U 1097 ; WX 602 ; N uni0449 ; G 904 +U 1098 ; WX 602 ; N uni044A ; G 905 +U 1099 ; WX 602 ; N uni044B ; G 906 +U 1100 ; WX 602 ; N uni044C ; G 907 +U 1101 ; WX 602 ; N uni044D ; G 908 +U 1102 ; WX 602 ; N uni044E ; G 909 +U 1103 ; WX 602 ; N uni044F ; G 910 +U 1104 ; WX 602 ; N uni0450 ; G 911 +U 1105 ; WX 602 ; N uni0451 ; G 912 +U 1106 ; WX 602 ; N uni0452 ; G 913 +U 1107 ; WX 602 ; N uni0453 ; G 914 +U 1108 ; WX 602 ; N uni0454 ; G 915 +U 1109 ; WX 602 ; N uni0455 ; G 916 +U 1110 ; WX 602 ; N uni0456 ; G 917 +U 1111 ; WX 602 ; N uni0457 ; G 918 +U 1112 ; WX 602 ; N uni0458 ; G 919 +U 1113 ; WX 602 ; N uni0459 ; G 920 +U 1114 ; WX 602 ; N uni045A ; G 921 +U 1115 ; WX 602 ; N uni045B ; G 922 +U 1116 ; WX 602 ; N uni045C ; G 923 +U 1117 ; WX 602 ; N uni045D ; G 924 +U 1118 ; WX 602 ; N uni045E ; G 925 +U 1119 ; WX 602 ; N uni045F ; G 926 +U 1122 ; WX 602 ; N uni0462 ; G 927 +U 1123 ; WX 602 ; N uni0463 ; G 928 +U 1138 ; WX 602 ; N uni0472 ; G 929 +U 1139 ; WX 602 ; N uni0473 ; G 930 +U 1168 ; WX 602 ; N uni0490 ; G 931 +U 1169 ; WX 602 ; N uni0491 ; G 932 +U 1170 ; WX 602 ; N uni0492 ; G 933 +U 1171 ; WX 602 ; N uni0493 ; G 934 +U 1172 ; WX 602 ; N uni0494 ; G 935 +U 1173 ; WX 602 ; N uni0495 ; G 936 +U 1174 ; WX 602 ; N uni0496 ; G 937 +U 1175 ; WX 602 ; N uni0497 ; G 938 +U 1176 ; WX 602 ; N uni0498 ; G 939 +U 1177 ; WX 602 ; N uni0499 ; G 940 +U 1178 ; WX 602 ; N uni049A ; G 941 +U 1179 ; WX 602 ; N uni049B ; G 942 +U 1186 ; WX 602 ; N uni04A2 ; G 943 +U 1187 ; WX 602 ; N uni04A3 ; G 944 +U 1188 ; WX 602 ; N uni04A4 ; G 945 +U 1189 ; WX 602 ; N uni04A5 ; G 946 +U 1194 ; WX 602 ; N uni04AA ; G 947 +U 1195 ; WX 602 ; N uni04AB ; G 948 +U 1196 ; WX 602 ; N uni04AC ; G 949 +U 1197 ; WX 602 ; N uni04AD ; G 950 +U 1198 ; WX 602 ; N uni04AE ; G 951 +U 1199 ; WX 602 ; N uni04AF ; G 952 +U 1200 ; WX 602 ; N uni04B0 ; G 953 +U 1201 ; WX 602 ; N uni04B1 ; G 954 +U 1202 ; WX 602 ; N uni04B2 ; G 955 +U 1203 ; WX 602 ; N uni04B3 ; G 956 +U 1210 ; WX 602 ; N uni04BA ; G 957 +U 1211 ; WX 602 ; N uni04BB ; G 958 +U 1216 ; WX 602 ; N uni04C0 ; G 959 +U 1217 ; WX 602 ; N uni04C1 ; G 960 +U 1218 ; WX 602 ; N uni04C2 ; G 961 +U 1219 ; WX 602 ; N uni04C3 ; G 962 +U 1220 ; WX 602 ; N uni04C4 ; G 963 +U 1223 ; WX 602 ; N uni04C7 ; G 964 +U 1224 ; WX 602 ; N uni04C8 ; G 965 +U 1227 ; WX 602 ; N uni04CB ; G 966 +U 1228 ; WX 602 ; N uni04CC ; G 967 +U 1231 ; WX 602 ; N uni04CF ; G 968 +U 1232 ; WX 602 ; N uni04D0 ; G 969 +U 1233 ; WX 602 ; N uni04D1 ; G 970 +U 1234 ; WX 602 ; N uni04D2 ; G 971 +U 1235 ; WX 602 ; N uni04D3 ; G 972 +U 1236 ; WX 602 ; N uni04D4 ; G 973 +U 1237 ; WX 602 ; N uni04D5 ; G 974 +U 1238 ; WX 602 ; N uni04D6 ; G 975 +U 1239 ; WX 602 ; N uni04D7 ; G 976 +U 1240 ; WX 602 ; N uni04D8 ; G 977 +U 1241 ; WX 602 ; N uni04D9 ; G 978 +U 1242 ; WX 602 ; N uni04DA ; G 979 +U 1243 ; WX 602 ; N uni04DB ; G 980 +U 1244 ; WX 602 ; N uni04DC ; G 981 +U 1245 ; WX 602 ; N uni04DD ; G 982 +U 1246 ; WX 602 ; N uni04DE ; G 983 +U 1247 ; WX 602 ; N uni04DF ; G 984 +U 1248 ; WX 602 ; N uni04E0 ; G 985 +U 1249 ; WX 602 ; N uni04E1 ; G 986 +U 1250 ; WX 602 ; N uni04E2 ; G 987 +U 1251 ; WX 602 ; N uni04E3 ; G 988 +U 1252 ; WX 602 ; N uni04E4 ; G 989 +U 1253 ; WX 602 ; N uni04E5 ; G 990 +U 1254 ; WX 602 ; N uni04E6 ; G 991 +U 1255 ; WX 602 ; N uni04E7 ; G 992 +U 1256 ; WX 602 ; N uni04E8 ; G 993 +U 1257 ; WX 602 ; N uni04E9 ; G 994 +U 1258 ; WX 602 ; N uni04EA ; G 995 +U 1259 ; WX 602 ; N uni04EB ; G 996 +U 1260 ; WX 602 ; N uni04EC ; G 997 +U 1261 ; WX 602 ; N uni04ED ; G 998 +U 1262 ; WX 602 ; N uni04EE ; G 999 +U 1263 ; WX 602 ; N uni04EF ; G 1000 +U 1264 ; WX 602 ; N uni04F0 ; G 1001 +U 1265 ; WX 602 ; N uni04F1 ; G 1002 +U 1266 ; WX 602 ; N uni04F2 ; G 1003 +U 1267 ; WX 602 ; N uni04F3 ; G 1004 +U 1268 ; WX 602 ; N uni04F4 ; G 1005 +U 1269 ; WX 602 ; N uni04F5 ; G 1006 +U 1270 ; WX 602 ; N uni04F6 ; G 1007 +U 1271 ; WX 602 ; N uni04F7 ; G 1008 +U 1272 ; WX 602 ; N uni04F8 ; G 1009 +U 1273 ; WX 602 ; N uni04F9 ; G 1010 +U 1296 ; WX 602 ; N uni0510 ; G 1011 +U 1297 ; WX 602 ; N uni0511 ; G 1012 +U 1306 ; WX 602 ; N uni051A ; G 1013 +U 1307 ; WX 602 ; N uni051B ; G 1014 +U 1308 ; WX 602 ; N uni051C ; G 1015 +U 1309 ; WX 602 ; N uni051D ; G 1016 +U 1329 ; WX 602 ; N uni0531 ; G 1017 +U 1330 ; WX 602 ; N uni0532 ; G 1018 +U 1331 ; WX 602 ; N uni0533 ; G 1019 +U 1332 ; WX 602 ; N uni0534 ; G 1020 +U 1333 ; WX 602 ; N uni0535 ; G 1021 +U 1334 ; WX 602 ; N uni0536 ; G 1022 +U 1335 ; WX 602 ; N uni0537 ; G 1023 +U 1336 ; WX 602 ; N uni0538 ; G 1024 +U 1337 ; WX 602 ; N uni0539 ; G 1025 +U 1338 ; WX 602 ; N uni053A ; G 1026 +U 1339 ; WX 602 ; N uni053B ; G 1027 +U 1340 ; WX 602 ; N uni053C ; G 1028 +U 1341 ; WX 602 ; N uni053D ; G 1029 +U 1342 ; WX 602 ; N uni053E ; G 1030 +U 1343 ; WX 602 ; N uni053F ; G 1031 +U 1344 ; WX 602 ; N uni0540 ; G 1032 +U 1345 ; WX 602 ; N uni0541 ; G 1033 +U 1346 ; WX 602 ; N uni0542 ; G 1034 +U 1347 ; WX 602 ; N uni0543 ; G 1035 +U 1348 ; WX 602 ; N uni0544 ; G 1036 +U 1349 ; WX 602 ; N uni0545 ; G 1037 +U 1350 ; WX 602 ; N uni0546 ; G 1038 +U 1351 ; WX 602 ; N uni0547 ; G 1039 +U 1352 ; WX 602 ; N uni0548 ; G 1040 +U 1353 ; WX 602 ; N uni0549 ; G 1041 +U 1354 ; WX 602 ; N uni054A ; G 1042 +U 1355 ; WX 602 ; N uni054B ; G 1043 +U 1356 ; WX 602 ; N uni054C ; G 1044 +U 1357 ; WX 602 ; N uni054D ; G 1045 +U 1358 ; WX 602 ; N uni054E ; G 1046 +U 1359 ; WX 602 ; N uni054F ; G 1047 +U 1360 ; WX 602 ; N uni0550 ; G 1048 +U 1361 ; WX 602 ; N uni0551 ; G 1049 +U 1362 ; WX 602 ; N uni0552 ; G 1050 +U 1363 ; WX 602 ; N uni0553 ; G 1051 +U 1364 ; WX 602 ; N uni0554 ; G 1052 +U 1365 ; WX 602 ; N uni0555 ; G 1053 +U 1366 ; WX 602 ; N uni0556 ; G 1054 +U 1369 ; WX 602 ; N uni0559 ; G 1055 +U 1370 ; WX 602 ; N uni055A ; G 1056 +U 1371 ; WX 602 ; N uni055B ; G 1057 +U 1372 ; WX 602 ; N uni055C ; G 1058 +U 1373 ; WX 602 ; N uni055D ; G 1059 +U 1374 ; WX 602 ; N uni055E ; G 1060 +U 1375 ; WX 602 ; N uni055F ; G 1061 +U 1377 ; WX 602 ; N uni0561 ; G 1062 +U 1378 ; WX 602 ; N uni0562 ; G 1063 +U 1379 ; WX 602 ; N uni0563 ; G 1064 +U 1380 ; WX 602 ; N uni0564 ; G 1065 +U 1381 ; WX 602 ; N uni0565 ; G 1066 +U 1382 ; WX 602 ; N uni0566 ; G 1067 +U 1383 ; WX 602 ; N uni0567 ; G 1068 +U 1384 ; WX 602 ; N uni0568 ; G 1069 +U 1385 ; WX 602 ; N uni0569 ; G 1070 +U 1386 ; WX 602 ; N uni056A ; G 1071 +U 1387 ; WX 602 ; N uni056B ; G 1072 +U 1388 ; WX 602 ; N uni056C ; G 1073 +U 1389 ; WX 602 ; N uni056D ; G 1074 +U 1390 ; WX 602 ; N uni056E ; G 1075 +U 1391 ; WX 602 ; N uni056F ; G 1076 +U 1392 ; WX 602 ; N uni0570 ; G 1077 +U 1393 ; WX 602 ; N uni0571 ; G 1078 +U 1394 ; WX 602 ; N uni0572 ; G 1079 +U 1395 ; WX 602 ; N uni0573 ; G 1080 +U 1396 ; WX 602 ; N uni0574 ; G 1081 +U 1397 ; WX 602 ; N uni0575 ; G 1082 +U 1398 ; WX 602 ; N uni0576 ; G 1083 +U 1399 ; WX 602 ; N uni0577 ; G 1084 +U 1400 ; WX 602 ; N uni0578 ; G 1085 +U 1401 ; WX 602 ; N uni0579 ; G 1086 +U 1402 ; WX 602 ; N uni057A ; G 1087 +U 1403 ; WX 602 ; N uni057B ; G 1088 +U 1404 ; WX 602 ; N uni057C ; G 1089 +U 1405 ; WX 602 ; N uni057D ; G 1090 +U 1406 ; WX 602 ; N uni057E ; G 1091 +U 1407 ; WX 602 ; N uni057F ; G 1092 +U 1408 ; WX 602 ; N uni0580 ; G 1093 +U 1409 ; WX 602 ; N uni0581 ; G 1094 +U 1410 ; WX 602 ; N uni0582 ; G 1095 +U 1411 ; WX 602 ; N uni0583 ; G 1096 +U 1412 ; WX 602 ; N uni0584 ; G 1097 +U 1413 ; WX 602 ; N uni0585 ; G 1098 +U 1414 ; WX 602 ; N uni0586 ; G 1099 +U 1415 ; WX 602 ; N uni0587 ; G 1100 +U 1417 ; WX 602 ; N uni0589 ; G 1101 +U 1418 ; WX 602 ; N uni058A ; G 1102 +U 1542 ; WX 602 ; N uni0606 ; G 1103 +U 1543 ; WX 602 ; N uni0607 ; G 1104 +U 1545 ; WX 602 ; N uni0609 ; G 1105 +U 1546 ; WX 602 ; N uni060A ; G 1106 +U 1548 ; WX 602 ; N uni060C ; G 1107 +U 1557 ; WX 602 ; N uni0615 ; G 1108 +U 1563 ; WX 602 ; N uni061B ; G 1109 +U 1567 ; WX 602 ; N uni061F ; G 1110 +U 1569 ; WX 602 ; N uni0621 ; G 1111 +U 1570 ; WX 602 ; N uni0622 ; G 1112 +U 1571 ; WX 602 ; N uni0623 ; G 1113 +U 1572 ; WX 602 ; N uni0624 ; G 1114 +U 1573 ; WX 602 ; N uni0625 ; G 1115 +U 1574 ; WX 602 ; N uni0626 ; G 1116 +U 1575 ; WX 602 ; N uni0627 ; G 1117 +U 1576 ; WX 602 ; N uni0628 ; G 1118 +U 1577 ; WX 602 ; N uni0629 ; G 1119 +U 1578 ; WX 602 ; N uni062A ; G 1120 +U 1579 ; WX 602 ; N uni062B ; G 1121 +U 1580 ; WX 602 ; N uni062C ; G 1122 +U 1581 ; WX 602 ; N uni062D ; G 1123 +U 1582 ; WX 602 ; N uni062E ; G 1124 +U 1583 ; WX 602 ; N uni062F ; G 1125 +U 1584 ; WX 602 ; N uni0630 ; G 1126 +U 1585 ; WX 602 ; N uni0631 ; G 1127 +U 1586 ; WX 602 ; N uni0632 ; G 1128 +U 1587 ; WX 602 ; N uni0633 ; G 1129 +U 1588 ; WX 602 ; N uni0634 ; G 1130 +U 1589 ; WX 602 ; N uni0635 ; G 1131 +U 1590 ; WX 602 ; N uni0636 ; G 1132 +U 1591 ; WX 602 ; N uni0637 ; G 1133 +U 1592 ; WX 602 ; N uni0638 ; G 1134 +U 1593 ; WX 602 ; N uni0639 ; G 1135 +U 1594 ; WX 602 ; N uni063A ; G 1136 +U 1600 ; WX 602 ; N uni0640 ; G 1137 +U 1601 ; WX 602 ; N uni0641 ; G 1138 +U 1602 ; WX 602 ; N uni0642 ; G 1139 +U 1603 ; WX 602 ; N uni0643 ; G 1140 +U 1604 ; WX 602 ; N uni0644 ; G 1141 +U 1605 ; WX 602 ; N uni0645 ; G 1142 +U 1606 ; WX 602 ; N uni0646 ; G 1143 +U 1607 ; WX 602 ; N uni0647 ; G 1144 +U 1608 ; WX 602 ; N uni0648 ; G 1145 +U 1609 ; WX 602 ; N uni0649 ; G 1146 +U 1610 ; WX 602 ; N uni064A ; G 1147 +U 1611 ; WX 602 ; N uni064B ; G 1148 +U 1612 ; WX 602 ; N uni064C ; G 1149 +U 1613 ; WX 602 ; N uni064D ; G 1150 +U 1614 ; WX 602 ; N uni064E ; G 1151 +U 1615 ; WX 602 ; N uni064F ; G 1152 +U 1616 ; WX 602 ; N uni0650 ; G 1153 +U 1617 ; WX 602 ; N uni0651 ; G 1154 +U 1618 ; WX 602 ; N uni0652 ; G 1155 +U 1619 ; WX 602 ; N uni0653 ; G 1156 +U 1620 ; WX 602 ; N uni0654 ; G 1157 +U 1621 ; WX 602 ; N uni0655 ; G 1158 +U 1626 ; WX 602 ; N uni065A ; G 1159 +U 1632 ; WX 602 ; N uni0660 ; G 1160 +U 1633 ; WX 602 ; N uni0661 ; G 1161 +U 1634 ; WX 602 ; N uni0662 ; G 1162 +U 1635 ; WX 602 ; N uni0663 ; G 1163 +U 1636 ; WX 602 ; N uni0664 ; G 1164 +U 1637 ; WX 602 ; N uni0665 ; G 1165 +U 1638 ; WX 602 ; N uni0666 ; G 1166 +U 1639 ; WX 602 ; N uni0667 ; G 1167 +U 1640 ; WX 602 ; N uni0668 ; G 1168 +U 1641 ; WX 602 ; N uni0669 ; G 1169 +U 1642 ; WX 602 ; N uni066A ; G 1170 +U 1643 ; WX 602 ; N uni066B ; G 1171 +U 1644 ; WX 602 ; N uni066C ; G 1172 +U 1645 ; WX 602 ; N uni066D ; G 1173 +U 1652 ; WX 602 ; N uni0674 ; G 1174 +U 1657 ; WX 602 ; N uni0679 ; G 1175 +U 1658 ; WX 602 ; N uni067A ; G 1176 +U 1659 ; WX 602 ; N uni067B ; G 1177 +U 1662 ; WX 602 ; N uni067E ; G 1178 +U 1663 ; WX 602 ; N uni067F ; G 1179 +U 1664 ; WX 602 ; N uni0680 ; G 1180 +U 1667 ; WX 602 ; N uni0683 ; G 1181 +U 1668 ; WX 602 ; N uni0684 ; G 1182 +U 1670 ; WX 602 ; N uni0686 ; G 1183 +U 1671 ; WX 602 ; N uni0687 ; G 1184 +U 1681 ; WX 602 ; N uni0691 ; G 1185 +U 1688 ; WX 602 ; N uni0698 ; G 1186 +U 1700 ; WX 602 ; N uni06A4 ; G 1187 +U 1705 ; WX 602 ; N uni06A9 ; G 1188 +U 1711 ; WX 602 ; N uni06AF ; G 1189 +U 1726 ; WX 602 ; N uni06BE ; G 1190 +U 1740 ; WX 602 ; N uni06CC ; G 1191 +U 1776 ; WX 602 ; N uni06F0 ; G 1192 +U 1777 ; WX 602 ; N uni06F1 ; G 1193 +U 1778 ; WX 602 ; N uni06F2 ; G 1194 +U 1779 ; WX 602 ; N uni06F3 ; G 1195 +U 1780 ; WX 602 ; N uni06F4 ; G 1196 +U 1781 ; WX 602 ; N uni06F5 ; G 1197 +U 1782 ; WX 602 ; N uni06F6 ; G 1198 +U 1783 ; WX 602 ; N uni06F7 ; G 1199 +U 1784 ; WX 602 ; N uni06F8 ; G 1200 +U 1785 ; WX 602 ; N uni06F9 ; G 1201 +U 3647 ; WX 602 ; N uni0E3F ; G 1202 +U 3713 ; WX 602 ; N uni0E81 ; G 1203 +U 3714 ; WX 602 ; N uni0E82 ; G 1204 +U 3716 ; WX 602 ; N uni0E84 ; G 1205 +U 3719 ; WX 602 ; N uni0E87 ; G 1206 +U 3720 ; WX 602 ; N uni0E88 ; G 1207 +U 3722 ; WX 602 ; N uni0E8A ; G 1208 +U 3725 ; WX 602 ; N uni0E8D ; G 1209 +U 3732 ; WX 602 ; N uni0E94 ; G 1210 +U 3733 ; WX 602 ; N uni0E95 ; G 1211 +U 3734 ; WX 602 ; N uni0E96 ; G 1212 +U 3735 ; WX 602 ; N uni0E97 ; G 1213 +U 3737 ; WX 602 ; N uni0E99 ; G 1214 +U 3738 ; WX 602 ; N uni0E9A ; G 1215 +U 3739 ; WX 602 ; N uni0E9B ; G 1216 +U 3740 ; WX 602 ; N uni0E9C ; G 1217 +U 3741 ; WX 602 ; N uni0E9D ; G 1218 +U 3742 ; WX 602 ; N uni0E9E ; G 1219 +U 3743 ; WX 602 ; N uni0E9F ; G 1220 +U 3745 ; WX 602 ; N uni0EA1 ; G 1221 +U 3746 ; WX 602 ; N uni0EA2 ; G 1222 +U 3747 ; WX 602 ; N uni0EA3 ; G 1223 +U 3749 ; WX 602 ; N uni0EA5 ; G 1224 +U 3751 ; WX 602 ; N uni0EA7 ; G 1225 +U 3754 ; WX 602 ; N uni0EAA ; G 1226 +U 3755 ; WX 602 ; N uni0EAB ; G 1227 +U 3757 ; WX 602 ; N uni0EAD ; G 1228 +U 3758 ; WX 602 ; N uni0EAE ; G 1229 +U 3759 ; WX 602 ; N uni0EAF ; G 1230 +U 3760 ; WX 602 ; N uni0EB0 ; G 1231 +U 3761 ; WX 602 ; N uni0EB1 ; G 1232 +U 3762 ; WX 602 ; N uni0EB2 ; G 1233 +U 3763 ; WX 602 ; N uni0EB3 ; G 1234 +U 3764 ; WX 602 ; N uni0EB4 ; G 1235 +U 3765 ; WX 602 ; N uni0EB5 ; G 1236 +U 3766 ; WX 602 ; N uni0EB6 ; G 1237 +U 3767 ; WX 602 ; N uni0EB7 ; G 1238 +U 3768 ; WX 602 ; N uni0EB8 ; G 1239 +U 3769 ; WX 602 ; N uni0EB9 ; G 1240 +U 3771 ; WX 602 ; N uni0EBB ; G 1241 +U 3772 ; WX 602 ; N uni0EBC ; G 1242 +U 3784 ; WX 602 ; N uni0EC8 ; G 1243 +U 3785 ; WX 602 ; N uni0EC9 ; G 1244 +U 3786 ; WX 602 ; N uni0ECA ; G 1245 +U 3787 ; WX 602 ; N uni0ECB ; G 1246 +U 3788 ; WX 602 ; N uni0ECC ; G 1247 +U 3789 ; WX 602 ; N uni0ECD ; G 1248 +U 4304 ; WX 602 ; N uni10D0 ; G 1249 +U 4305 ; WX 602 ; N uni10D1 ; G 1250 +U 4306 ; WX 602 ; N uni10D2 ; G 1251 +U 4307 ; WX 602 ; N uni10D3 ; G 1252 +U 4308 ; WX 602 ; N uni10D4 ; G 1253 +U 4309 ; WX 602 ; N uni10D5 ; G 1254 +U 4310 ; WX 602 ; N uni10D6 ; G 1255 +U 4311 ; WX 602 ; N uni10D7 ; G 1256 +U 4312 ; WX 602 ; N uni10D8 ; G 1257 +U 4313 ; WX 602 ; N uni10D9 ; G 1258 +U 4314 ; WX 602 ; N uni10DA ; G 1259 +U 4315 ; WX 602 ; N uni10DB ; G 1260 +U 4316 ; WX 602 ; N uni10DC ; G 1261 +U 4317 ; WX 602 ; N uni10DD ; G 1262 +U 4318 ; WX 602 ; N uni10DE ; G 1263 +U 4319 ; WX 602 ; N uni10DF ; G 1264 +U 4320 ; WX 602 ; N uni10E0 ; G 1265 +U 4321 ; WX 602 ; N uni10E1 ; G 1266 +U 4322 ; WX 602 ; N uni10E2 ; G 1267 +U 4323 ; WX 602 ; N uni10E3 ; G 1268 +U 4324 ; WX 602 ; N uni10E4 ; G 1269 +U 4325 ; WX 602 ; N uni10E5 ; G 1270 +U 4326 ; WX 602 ; N uni10E6 ; G 1271 +U 4327 ; WX 602 ; N uni10E7 ; G 1272 +U 4328 ; WX 602 ; N uni10E8 ; G 1273 +U 4329 ; WX 602 ; N uni10E9 ; G 1274 +U 4330 ; WX 602 ; N uni10EA ; G 1275 +U 4331 ; WX 602 ; N uni10EB ; G 1276 +U 4332 ; WX 602 ; N uni10EC ; G 1277 +U 4333 ; WX 602 ; N uni10ED ; G 1278 +U 4334 ; WX 602 ; N uni10EE ; G 1279 +U 4335 ; WX 602 ; N uni10EF ; G 1280 +U 4336 ; WX 602 ; N uni10F0 ; G 1281 +U 4337 ; WX 602 ; N uni10F1 ; G 1282 +U 4338 ; WX 602 ; N uni10F2 ; G 1283 +U 4339 ; WX 602 ; N uni10F3 ; G 1284 +U 4340 ; WX 602 ; N uni10F4 ; G 1285 +U 4341 ; WX 602 ; N uni10F5 ; G 1286 +U 4342 ; WX 602 ; N uni10F6 ; G 1287 +U 4343 ; WX 602 ; N uni10F7 ; G 1288 +U 4344 ; WX 602 ; N uni10F8 ; G 1289 +U 4345 ; WX 602 ; N uni10F9 ; G 1290 +U 4346 ; WX 602 ; N uni10FA ; G 1291 +U 4347 ; WX 602 ; N uni10FB ; G 1292 +U 4348 ; WX 602 ; N uni10FC ; G 1293 +U 7426 ; WX 602 ; N uni1D02 ; G 1294 +U 7432 ; WX 602 ; N uni1D08 ; G 1295 +U 7433 ; WX 602 ; N uni1D09 ; G 1296 +U 7444 ; WX 602 ; N uni1D14 ; G 1297 +U 7446 ; WX 602 ; N uni1D16 ; G 1298 +U 7447 ; WX 602 ; N uni1D17 ; G 1299 +U 7453 ; WX 602 ; N uni1D1D ; G 1300 +U 7454 ; WX 602 ; N uni1D1E ; G 1301 +U 7455 ; WX 602 ; N uni1D1F ; G 1302 +U 7468 ; WX 602 ; N uni1D2C ; G 1303 +U 7469 ; WX 602 ; N uni1D2D ; G 1304 +U 7470 ; WX 602 ; N uni1D2E ; G 1305 +U 7472 ; WX 602 ; N uni1D30 ; G 1306 +U 7473 ; WX 602 ; N uni1D31 ; G 1307 +U 7474 ; WX 602 ; N uni1D32 ; G 1308 +U 7475 ; WX 602 ; N uni1D33 ; G 1309 +U 7476 ; WX 602 ; N uni1D34 ; G 1310 +U 7477 ; WX 602 ; N uni1D35 ; G 1311 +U 7478 ; WX 602 ; N uni1D36 ; G 1312 +U 7479 ; WX 602 ; N uni1D37 ; G 1313 +U 7480 ; WX 602 ; N uni1D38 ; G 1314 +U 7481 ; WX 602 ; N uni1D39 ; G 1315 +U 7482 ; WX 602 ; N uni1D3A ; G 1316 +U 7483 ; WX 602 ; N uni1D3B ; G 1317 +U 7484 ; WX 602 ; N uni1D3C ; G 1318 +U 7486 ; WX 602 ; N uni1D3E ; G 1319 +U 7487 ; WX 602 ; N uni1D3F ; G 1320 +U 7488 ; WX 602 ; N uni1D40 ; G 1321 +U 7489 ; WX 602 ; N uni1D41 ; G 1322 +U 7490 ; WX 602 ; N uni1D42 ; G 1323 +U 7491 ; WX 602 ; N uni1D43 ; G 1324 +U 7492 ; WX 602 ; N uni1D44 ; G 1325 +U 7493 ; WX 602 ; N uni1D45 ; G 1326 +U 7494 ; WX 602 ; N uni1D46 ; G 1327 +U 7495 ; WX 602 ; N uni1D47 ; G 1328 +U 7496 ; WX 602 ; N uni1D48 ; G 1329 +U 7497 ; WX 602 ; N uni1D49 ; G 1330 +U 7498 ; WX 602 ; N uni1D4A ; G 1331 +U 7499 ; WX 602 ; N uni1D4B ; G 1332 +U 7500 ; WX 602 ; N uni1D4C ; G 1333 +U 7501 ; WX 602 ; N uni1D4D ; G 1334 +U 7502 ; WX 602 ; N uni1D4E ; G 1335 +U 7503 ; WX 602 ; N uni1D4F ; G 1336 +U 7504 ; WX 602 ; N uni1D50 ; G 1337 +U 7505 ; WX 602 ; N uni1D51 ; G 1338 +U 7506 ; WX 602 ; N uni1D52 ; G 1339 +U 7507 ; WX 602 ; N uni1D53 ; G 1340 +U 7508 ; WX 602 ; N uni1D54 ; G 1341 +U 7509 ; WX 602 ; N uni1D55 ; G 1342 +U 7510 ; WX 602 ; N uni1D56 ; G 1343 +U 7511 ; WX 602 ; N uni1D57 ; G 1344 +U 7512 ; WX 602 ; N uni1D58 ; G 1345 +U 7513 ; WX 602 ; N uni1D59 ; G 1346 +U 7514 ; WX 602 ; N uni1D5A ; G 1347 +U 7515 ; WX 602 ; N uni1D5B ; G 1348 +U 7522 ; WX 602 ; N uni1D62 ; G 1349 +U 7523 ; WX 602 ; N uni1D63 ; G 1350 +U 7524 ; WX 602 ; N uni1D64 ; G 1351 +U 7525 ; WX 602 ; N uni1D65 ; G 1352 +U 7543 ; WX 602 ; N uni1D77 ; G 1353 +U 7544 ; WX 602 ; N uni1D78 ; G 1354 +U 7547 ; WX 602 ; N uni1D7B ; G 1355 +U 7557 ; WX 602 ; N uni1D85 ; G 1356 +U 7579 ; WX 602 ; N uni1D9B ; G 1357 +U 7580 ; WX 602 ; N uni1D9C ; G 1358 +U 7581 ; WX 602 ; N uni1D9D ; G 1359 +U 7582 ; WX 602 ; N uni1D9E ; G 1360 +U 7583 ; WX 602 ; N uni1D9F ; G 1361 +U 7584 ; WX 602 ; N uni1DA0 ; G 1362 +U 7585 ; WX 602 ; N uni1DA1 ; G 1363 +U 7586 ; WX 602 ; N uni1DA2 ; G 1364 +U 7587 ; WX 602 ; N uni1DA3 ; G 1365 +U 7588 ; WX 602 ; N uni1DA4 ; G 1366 +U 7589 ; WX 602 ; N uni1DA5 ; G 1367 +U 7590 ; WX 602 ; N uni1DA6 ; G 1368 +U 7591 ; WX 602 ; N uni1DA7 ; G 1369 +U 7592 ; WX 602 ; N uni1DA8 ; G 1370 +U 7593 ; WX 602 ; N uni1DA9 ; G 1371 +U 7594 ; WX 602 ; N uni1DAA ; G 1372 +U 7595 ; WX 602 ; N uni1DAB ; G 1373 +U 7596 ; WX 602 ; N uni1DAC ; G 1374 +U 7597 ; WX 602 ; N uni1DAD ; G 1375 +U 7598 ; WX 602 ; N uni1DAE ; G 1376 +U 7599 ; WX 602 ; N uni1DAF ; G 1377 +U 7600 ; WX 602 ; N uni1DB0 ; G 1378 +U 7601 ; WX 602 ; N uni1DB1 ; G 1379 +U 7602 ; WX 602 ; N uni1DB2 ; G 1380 +U 7603 ; WX 602 ; N uni1DB3 ; G 1381 +U 7604 ; WX 602 ; N uni1DB4 ; G 1382 +U 7605 ; WX 602 ; N uni1DB5 ; G 1383 +U 7606 ; WX 602 ; N uni1DB6 ; G 1384 +U 7607 ; WX 602 ; N uni1DB7 ; G 1385 +U 7609 ; WX 602 ; N uni1DB9 ; G 1386 +U 7610 ; WX 602 ; N uni1DBA ; G 1387 +U 7611 ; WX 602 ; N uni1DBB ; G 1388 +U 7612 ; WX 602 ; N uni1DBC ; G 1389 +U 7613 ; WX 602 ; N uni1DBD ; G 1390 +U 7614 ; WX 602 ; N uni1DBE ; G 1391 +U 7615 ; WX 602 ; N uni1DBF ; G 1392 +U 7680 ; WX 602 ; N uni1E00 ; G 1393 +U 7681 ; WX 602 ; N uni1E01 ; G 1394 +U 7682 ; WX 602 ; N uni1E02 ; G 1395 +U 7683 ; WX 602 ; N uni1E03 ; G 1396 +U 7684 ; WX 602 ; N uni1E04 ; G 1397 +U 7685 ; WX 602 ; N uni1E05 ; G 1398 +U 7686 ; WX 602 ; N uni1E06 ; G 1399 +U 7687 ; WX 602 ; N uni1E07 ; G 1400 +U 7688 ; WX 602 ; N uni1E08 ; G 1401 +U 7689 ; WX 602 ; N uni1E09 ; G 1402 +U 7690 ; WX 602 ; N uni1E0A ; G 1403 +U 7691 ; WX 602 ; N uni1E0B ; G 1404 +U 7692 ; WX 602 ; N uni1E0C ; G 1405 +U 7693 ; WX 602 ; N uni1E0D ; G 1406 +U 7694 ; WX 602 ; N uni1E0E ; G 1407 +U 7695 ; WX 602 ; N uni1E0F ; G 1408 +U 7696 ; WX 602 ; N uni1E10 ; G 1409 +U 7697 ; WX 602 ; N uni1E11 ; G 1410 +U 7698 ; WX 602 ; N uni1E12 ; G 1411 +U 7699 ; WX 602 ; N uni1E13 ; G 1412 +U 7704 ; WX 602 ; N uni1E18 ; G 1413 +U 7705 ; WX 602 ; N uni1E19 ; G 1414 +U 7706 ; WX 602 ; N uni1E1A ; G 1415 +U 7707 ; WX 602 ; N uni1E1B ; G 1416 +U 7708 ; WX 602 ; N uni1E1C ; G 1417 +U 7709 ; WX 602 ; N uni1E1D ; G 1418 +U 7710 ; WX 602 ; N uni1E1E ; G 1419 +U 7711 ; WX 602 ; N uni1E1F ; G 1420 +U 7712 ; WX 602 ; N uni1E20 ; G 1421 +U 7713 ; WX 602 ; N uni1E21 ; G 1422 +U 7714 ; WX 602 ; N uni1E22 ; G 1423 +U 7715 ; WX 602 ; N uni1E23 ; G 1424 +U 7716 ; WX 602 ; N uni1E24 ; G 1425 +U 7717 ; WX 602 ; N uni1E25 ; G 1426 +U 7718 ; WX 602 ; N uni1E26 ; G 1427 +U 7719 ; WX 602 ; N uni1E27 ; G 1428 +U 7720 ; WX 602 ; N uni1E28 ; G 1429 +U 7721 ; WX 602 ; N uni1E29 ; G 1430 +U 7722 ; WX 602 ; N uni1E2A ; G 1431 +U 7723 ; WX 602 ; N uni1E2B ; G 1432 +U 7724 ; WX 602 ; N uni1E2C ; G 1433 +U 7725 ; WX 602 ; N uni1E2D ; G 1434 +U 7728 ; WX 602 ; N uni1E30 ; G 1435 +U 7729 ; WX 602 ; N uni1E31 ; G 1436 +U 7730 ; WX 602 ; N uni1E32 ; G 1437 +U 7731 ; WX 602 ; N uni1E33 ; G 1438 +U 7732 ; WX 602 ; N uni1E34 ; G 1439 +U 7733 ; WX 602 ; N uni1E35 ; G 1440 +U 7734 ; WX 602 ; N uni1E36 ; G 1441 +U 7735 ; WX 602 ; N uni1E37 ; G 1442 +U 7736 ; WX 602 ; N uni1E38 ; G 1443 +U 7737 ; WX 602 ; N uni1E39 ; G 1444 +U 7738 ; WX 602 ; N uni1E3A ; G 1445 +U 7739 ; WX 602 ; N uni1E3B ; G 1446 +U 7740 ; WX 602 ; N uni1E3C ; G 1447 +U 7741 ; WX 602 ; N uni1E3D ; G 1448 +U 7742 ; WX 602 ; N uni1E3E ; G 1449 +U 7743 ; WX 602 ; N uni1E3F ; G 1450 +U 7744 ; WX 602 ; N uni1E40 ; G 1451 +U 7745 ; WX 602 ; N uni1E41 ; G 1452 +U 7746 ; WX 602 ; N uni1E42 ; G 1453 +U 7747 ; WX 602 ; N uni1E43 ; G 1454 +U 7748 ; WX 602 ; N uni1E44 ; G 1455 +U 7749 ; WX 602 ; N uni1E45 ; G 1456 +U 7750 ; WX 602 ; N uni1E46 ; G 1457 +U 7751 ; WX 602 ; N uni1E47 ; G 1458 +U 7752 ; WX 602 ; N uni1E48 ; G 1459 +U 7753 ; WX 602 ; N uni1E49 ; G 1460 +U 7754 ; WX 602 ; N uni1E4A ; G 1461 +U 7755 ; WX 602 ; N uni1E4B ; G 1462 +U 7756 ; WX 602 ; N uni1E4C ; G 1463 +U 7757 ; WX 602 ; N uni1E4D ; G 1464 +U 7764 ; WX 602 ; N uni1E54 ; G 1465 +U 7765 ; WX 602 ; N uni1E55 ; G 1466 +U 7766 ; WX 602 ; N uni1E56 ; G 1467 +U 7767 ; WX 602 ; N uni1E57 ; G 1468 +U 7768 ; WX 602 ; N uni1E58 ; G 1469 +U 7769 ; WX 602 ; N uni1E59 ; G 1470 +U 7770 ; WX 602 ; N uni1E5A ; G 1471 +U 7771 ; WX 602 ; N uni1E5B ; G 1472 +U 7772 ; WX 602 ; N uni1E5C ; G 1473 +U 7773 ; WX 602 ; N uni1E5D ; G 1474 +U 7774 ; WX 602 ; N uni1E5E ; G 1475 +U 7775 ; WX 602 ; N uni1E5F ; G 1476 +U 7776 ; WX 602 ; N uni1E60 ; G 1477 +U 7777 ; WX 602 ; N uni1E61 ; G 1478 +U 7778 ; WX 602 ; N uni1E62 ; G 1479 +U 7779 ; WX 602 ; N uni1E63 ; G 1480 +U 7784 ; WX 602 ; N uni1E68 ; G 1481 +U 7785 ; WX 602 ; N uni1E69 ; G 1482 +U 7786 ; WX 602 ; N uni1E6A ; G 1483 +U 7787 ; WX 602 ; N uni1E6B ; G 1484 +U 7788 ; WX 602 ; N uni1E6C ; G 1485 +U 7789 ; WX 602 ; N uni1E6D ; G 1486 +U 7790 ; WX 602 ; N uni1E6E ; G 1487 +U 7791 ; WX 602 ; N uni1E6F ; G 1488 +U 7792 ; WX 602 ; N uni1E70 ; G 1489 +U 7793 ; WX 602 ; N uni1E71 ; G 1490 +U 7794 ; WX 602 ; N uni1E72 ; G 1491 +U 7795 ; WX 602 ; N uni1E73 ; G 1492 +U 7796 ; WX 602 ; N uni1E74 ; G 1493 +U 7797 ; WX 602 ; N uni1E75 ; G 1494 +U 7798 ; WX 602 ; N uni1E76 ; G 1495 +U 7799 ; WX 602 ; N uni1E77 ; G 1496 +U 7800 ; WX 602 ; N uni1E78 ; G 1497 +U 7801 ; WX 602 ; N uni1E79 ; G 1498 +U 7804 ; WX 602 ; N uni1E7C ; G 1499 +U 7805 ; WX 602 ; N uni1E7D ; G 1500 +U 7806 ; WX 602 ; N uni1E7E ; G 1501 +U 7807 ; WX 602 ; N uni1E7F ; G 1502 +U 7808 ; WX 602 ; N Wgrave ; G 1503 +U 7809 ; WX 602 ; N wgrave ; G 1504 +U 7810 ; WX 602 ; N Wacute ; G 1505 +U 7811 ; WX 602 ; N wacute ; G 1506 +U 7812 ; WX 602 ; N Wdieresis ; G 1507 +U 7813 ; WX 602 ; N wdieresis ; G 1508 +U 7814 ; WX 602 ; N uni1E86 ; G 1509 +U 7815 ; WX 602 ; N uni1E87 ; G 1510 +U 7816 ; WX 602 ; N uni1E88 ; G 1511 +U 7817 ; WX 602 ; N uni1E89 ; G 1512 +U 7818 ; WX 602 ; N uni1E8A ; G 1513 +U 7819 ; WX 602 ; N uni1E8B ; G 1514 +U 7820 ; WX 602 ; N uni1E8C ; G 1515 +U 7821 ; WX 602 ; N uni1E8D ; G 1516 +U 7822 ; WX 602 ; N uni1E8E ; G 1517 +U 7823 ; WX 602 ; N uni1E8F ; G 1518 +U 7824 ; WX 602 ; N uni1E90 ; G 1519 +U 7825 ; WX 602 ; N uni1E91 ; G 1520 +U 7826 ; WX 602 ; N uni1E92 ; G 1521 +U 7827 ; WX 602 ; N uni1E93 ; G 1522 +U 7828 ; WX 602 ; N uni1E94 ; G 1523 +U 7829 ; WX 602 ; N uni1E95 ; G 1524 +U 7830 ; WX 602 ; N uni1E96 ; G 1525 +U 7831 ; WX 602 ; N uni1E97 ; G 1526 +U 7832 ; WX 602 ; N uni1E98 ; G 1527 +U 7833 ; WX 602 ; N uni1E99 ; G 1528 +U 7835 ; WX 602 ; N uni1E9B ; G 1529 +U 7839 ; WX 602 ; N uni1E9F ; G 1530 +U 7840 ; WX 602 ; N uni1EA0 ; G 1531 +U 7841 ; WX 602 ; N uni1EA1 ; G 1532 +U 7852 ; WX 602 ; N uni1EAC ; G 1533 +U 7853 ; WX 602 ; N uni1EAD ; G 1534 +U 7856 ; WX 602 ; N uni1EB0 ; G 1535 +U 7857 ; WX 602 ; N uni1EB1 ; G 1536 +U 7862 ; WX 602 ; N uni1EB6 ; G 1537 +U 7863 ; WX 602 ; N uni1EB7 ; G 1538 +U 7864 ; WX 602 ; N uni1EB8 ; G 1539 +U 7865 ; WX 602 ; N uni1EB9 ; G 1540 +U 7868 ; WX 602 ; N uni1EBC ; G 1541 +U 7869 ; WX 602 ; N uni1EBD ; G 1542 +U 7878 ; WX 602 ; N uni1EC6 ; G 1543 +U 7879 ; WX 602 ; N uni1EC7 ; G 1544 +U 7882 ; WX 602 ; N uni1ECA ; G 1545 +U 7883 ; WX 602 ; N uni1ECB ; G 1546 +U 7884 ; WX 602 ; N uni1ECC ; G 1547 +U 7885 ; WX 602 ; N uni1ECD ; G 1548 +U 7896 ; WX 602 ; N uni1ED8 ; G 1549 +U 7897 ; WX 602 ; N uni1ED9 ; G 1550 +U 7898 ; WX 602 ; N uni1EDA ; G 1551 +U 7899 ; WX 602 ; N uni1EDB ; G 1552 +U 7900 ; WX 602 ; N uni1EDC ; G 1553 +U 7901 ; WX 602 ; N uni1EDD ; G 1554 +U 7904 ; WX 602 ; N uni1EE0 ; G 1555 +U 7905 ; WX 602 ; N uni1EE1 ; G 1556 +U 7906 ; WX 602 ; N uni1EE2 ; G 1557 +U 7907 ; WX 602 ; N uni1EE3 ; G 1558 +U 7908 ; WX 602 ; N uni1EE4 ; G 1559 +U 7909 ; WX 602 ; N uni1EE5 ; G 1560 +U 7912 ; WX 602 ; N uni1EE8 ; G 1561 +U 7913 ; WX 602 ; N uni1EE9 ; G 1562 +U 7914 ; WX 602 ; N uni1EEA ; G 1563 +U 7915 ; WX 602 ; N uni1EEB ; G 1564 +U 7918 ; WX 602 ; N uni1EEE ; G 1565 +U 7919 ; WX 602 ; N uni1EEF ; G 1566 +U 7920 ; WX 602 ; N uni1EF0 ; G 1567 +U 7921 ; WX 602 ; N uni1EF1 ; G 1568 +U 7922 ; WX 602 ; N Ygrave ; G 1569 +U 7923 ; WX 602 ; N ygrave ; G 1570 +U 7924 ; WX 602 ; N uni1EF4 ; G 1571 +U 7925 ; WX 602 ; N uni1EF5 ; G 1572 +U 7928 ; WX 602 ; N uni1EF8 ; G 1573 +U 7929 ; WX 602 ; N uni1EF9 ; G 1574 +U 7936 ; WX 602 ; N uni1F00 ; G 1575 +U 7937 ; WX 602 ; N uni1F01 ; G 1576 +U 7938 ; WX 602 ; N uni1F02 ; G 1577 +U 7939 ; WX 602 ; N uni1F03 ; G 1578 +U 7940 ; WX 602 ; N uni1F04 ; G 1579 +U 7941 ; WX 602 ; N uni1F05 ; G 1580 +U 7942 ; WX 602 ; N uni1F06 ; G 1581 +U 7943 ; WX 602 ; N uni1F07 ; G 1582 +U 7944 ; WX 602 ; N uni1F08 ; G 1583 +U 7945 ; WX 602 ; N uni1F09 ; G 1584 +U 7946 ; WX 602 ; N uni1F0A ; G 1585 +U 7947 ; WX 602 ; N uni1F0B ; G 1586 +U 7948 ; WX 602 ; N uni1F0C ; G 1587 +U 7949 ; WX 602 ; N uni1F0D ; G 1588 +U 7950 ; WX 602 ; N uni1F0E ; G 1589 +U 7951 ; WX 602 ; N uni1F0F ; G 1590 +U 7952 ; WX 602 ; N uni1F10 ; G 1591 +U 7953 ; WX 602 ; N uni1F11 ; G 1592 +U 7954 ; WX 602 ; N uni1F12 ; G 1593 +U 7955 ; WX 602 ; N uni1F13 ; G 1594 +U 7956 ; WX 602 ; N uni1F14 ; G 1595 +U 7957 ; WX 602 ; N uni1F15 ; G 1596 +U 7960 ; WX 602 ; N uni1F18 ; G 1597 +U 7961 ; WX 602 ; N uni1F19 ; G 1598 +U 7962 ; WX 602 ; N uni1F1A ; G 1599 +U 7963 ; WX 602 ; N uni1F1B ; G 1600 +U 7964 ; WX 602 ; N uni1F1C ; G 1601 +U 7965 ; WX 602 ; N uni1F1D ; G 1602 +U 7968 ; WX 602 ; N uni1F20 ; G 1603 +U 7969 ; WX 602 ; N uni1F21 ; G 1604 +U 7970 ; WX 602 ; N uni1F22 ; G 1605 +U 7971 ; WX 602 ; N uni1F23 ; G 1606 +U 7972 ; WX 602 ; N uni1F24 ; G 1607 +U 7973 ; WX 602 ; N uni1F25 ; G 1608 +U 7974 ; WX 602 ; N uni1F26 ; G 1609 +U 7975 ; WX 602 ; N uni1F27 ; G 1610 +U 7976 ; WX 602 ; N uni1F28 ; G 1611 +U 7977 ; WX 602 ; N uni1F29 ; G 1612 +U 7978 ; WX 602 ; N uni1F2A ; G 1613 +U 7979 ; WX 602 ; N uni1F2B ; G 1614 +U 7980 ; WX 602 ; N uni1F2C ; G 1615 +U 7981 ; WX 602 ; N uni1F2D ; G 1616 +U 7982 ; WX 602 ; N uni1F2E ; G 1617 +U 7983 ; WX 602 ; N uni1F2F ; G 1618 +U 7984 ; WX 602 ; N uni1F30 ; G 1619 +U 7985 ; WX 602 ; N uni1F31 ; G 1620 +U 7986 ; WX 602 ; N uni1F32 ; G 1621 +U 7987 ; WX 602 ; N uni1F33 ; G 1622 +U 7988 ; WX 602 ; N uni1F34 ; G 1623 +U 7989 ; WX 602 ; N uni1F35 ; G 1624 +U 7990 ; WX 602 ; N uni1F36 ; G 1625 +U 7991 ; WX 602 ; N uni1F37 ; G 1626 +U 7992 ; WX 602 ; N uni1F38 ; G 1627 +U 7993 ; WX 602 ; N uni1F39 ; G 1628 +U 7994 ; WX 602 ; N uni1F3A ; G 1629 +U 7995 ; WX 602 ; N uni1F3B ; G 1630 +U 7996 ; WX 602 ; N uni1F3C ; G 1631 +U 7997 ; WX 602 ; N uni1F3D ; G 1632 +U 7998 ; WX 602 ; N uni1F3E ; G 1633 +U 7999 ; WX 602 ; N uni1F3F ; G 1634 +U 8000 ; WX 602 ; N uni1F40 ; G 1635 +U 8001 ; WX 602 ; N uni1F41 ; G 1636 +U 8002 ; WX 602 ; N uni1F42 ; G 1637 +U 8003 ; WX 602 ; N uni1F43 ; G 1638 +U 8004 ; WX 602 ; N uni1F44 ; G 1639 +U 8005 ; WX 602 ; N uni1F45 ; G 1640 +U 8008 ; WX 602 ; N uni1F48 ; G 1641 +U 8009 ; WX 602 ; N uni1F49 ; G 1642 +U 8010 ; WX 602 ; N uni1F4A ; G 1643 +U 8011 ; WX 602 ; N uni1F4B ; G 1644 +U 8012 ; WX 602 ; N uni1F4C ; G 1645 +U 8013 ; WX 602 ; N uni1F4D ; G 1646 +U 8016 ; WX 602 ; N uni1F50 ; G 1647 +U 8017 ; WX 602 ; N uni1F51 ; G 1648 +U 8018 ; WX 602 ; N uni1F52 ; G 1649 +U 8019 ; WX 602 ; N uni1F53 ; G 1650 +U 8020 ; WX 602 ; N uni1F54 ; G 1651 +U 8021 ; WX 602 ; N uni1F55 ; G 1652 +U 8022 ; WX 602 ; N uni1F56 ; G 1653 +U 8023 ; WX 602 ; N uni1F57 ; G 1654 +U 8025 ; WX 602 ; N uni1F59 ; G 1655 +U 8027 ; WX 602 ; N uni1F5B ; G 1656 +U 8029 ; WX 602 ; N uni1F5D ; G 1657 +U 8031 ; WX 602 ; N uni1F5F ; G 1658 +U 8032 ; WX 602 ; N uni1F60 ; G 1659 +U 8033 ; WX 602 ; N uni1F61 ; G 1660 +U 8034 ; WX 602 ; N uni1F62 ; G 1661 +U 8035 ; WX 602 ; N uni1F63 ; G 1662 +U 8036 ; WX 602 ; N uni1F64 ; G 1663 +U 8037 ; WX 602 ; N uni1F65 ; G 1664 +U 8038 ; WX 602 ; N uni1F66 ; G 1665 +U 8039 ; WX 602 ; N uni1F67 ; G 1666 +U 8040 ; WX 602 ; N uni1F68 ; G 1667 +U 8041 ; WX 602 ; N uni1F69 ; G 1668 +U 8042 ; WX 602 ; N uni1F6A ; G 1669 +U 8043 ; WX 602 ; N uni1F6B ; G 1670 +U 8044 ; WX 602 ; N uni1F6C ; G 1671 +U 8045 ; WX 602 ; N uni1F6D ; G 1672 +U 8046 ; WX 602 ; N uni1F6E ; G 1673 +U 8047 ; WX 602 ; N uni1F6F ; G 1674 +U 8048 ; WX 602 ; N uni1F70 ; G 1675 +U 8049 ; WX 602 ; N uni1F71 ; G 1676 +U 8050 ; WX 602 ; N uni1F72 ; G 1677 +U 8051 ; WX 602 ; N uni1F73 ; G 1678 +U 8052 ; WX 602 ; N uni1F74 ; G 1679 +U 8053 ; WX 602 ; N uni1F75 ; G 1680 +U 8054 ; WX 602 ; N uni1F76 ; G 1681 +U 8055 ; WX 602 ; N uni1F77 ; G 1682 +U 8056 ; WX 602 ; N uni1F78 ; G 1683 +U 8057 ; WX 602 ; N uni1F79 ; G 1684 +U 8058 ; WX 602 ; N uni1F7A ; G 1685 +U 8059 ; WX 602 ; N uni1F7B ; G 1686 +U 8060 ; WX 602 ; N uni1F7C ; G 1687 +U 8061 ; WX 602 ; N uni1F7D ; G 1688 +U 8064 ; WX 602 ; N uni1F80 ; G 1689 +U 8065 ; WX 602 ; N uni1F81 ; G 1690 +U 8066 ; WX 602 ; N uni1F82 ; G 1691 +U 8067 ; WX 602 ; N uni1F83 ; G 1692 +U 8068 ; WX 602 ; N uni1F84 ; G 1693 +U 8069 ; WX 602 ; N uni1F85 ; G 1694 +U 8070 ; WX 602 ; N uni1F86 ; G 1695 +U 8071 ; WX 602 ; N uni1F87 ; G 1696 +U 8072 ; WX 602 ; N uni1F88 ; G 1697 +U 8073 ; WX 602 ; N uni1F89 ; G 1698 +U 8074 ; WX 602 ; N uni1F8A ; G 1699 +U 8075 ; WX 602 ; N uni1F8B ; G 1700 +U 8076 ; WX 602 ; N uni1F8C ; G 1701 +U 8077 ; WX 602 ; N uni1F8D ; G 1702 +U 8078 ; WX 602 ; N uni1F8E ; G 1703 +U 8079 ; WX 602 ; N uni1F8F ; G 1704 +U 8080 ; WX 602 ; N uni1F90 ; G 1705 +U 8081 ; WX 602 ; N uni1F91 ; G 1706 +U 8082 ; WX 602 ; N uni1F92 ; G 1707 +U 8083 ; WX 602 ; N uni1F93 ; G 1708 +U 8084 ; WX 602 ; N uni1F94 ; G 1709 +U 8085 ; WX 602 ; N uni1F95 ; G 1710 +U 8086 ; WX 602 ; N uni1F96 ; G 1711 +U 8087 ; WX 602 ; N uni1F97 ; G 1712 +U 8088 ; WX 602 ; N uni1F98 ; G 1713 +U 8089 ; WX 602 ; N uni1F99 ; G 1714 +U 8090 ; WX 602 ; N uni1F9A ; G 1715 +U 8091 ; WX 602 ; N uni1F9B ; G 1716 +U 8092 ; WX 602 ; N uni1F9C ; G 1717 +U 8093 ; WX 602 ; N uni1F9D ; G 1718 +U 8094 ; WX 602 ; N uni1F9E ; G 1719 +U 8095 ; WX 602 ; N uni1F9F ; G 1720 +U 8096 ; WX 602 ; N uni1FA0 ; G 1721 +U 8097 ; WX 602 ; N uni1FA1 ; G 1722 +U 8098 ; WX 602 ; N uni1FA2 ; G 1723 +U 8099 ; WX 602 ; N uni1FA3 ; G 1724 +U 8100 ; WX 602 ; N uni1FA4 ; G 1725 +U 8101 ; WX 602 ; N uni1FA5 ; G 1726 +U 8102 ; WX 602 ; N uni1FA6 ; G 1727 +U 8103 ; WX 602 ; N uni1FA7 ; G 1728 +U 8104 ; WX 602 ; N uni1FA8 ; G 1729 +U 8105 ; WX 602 ; N uni1FA9 ; G 1730 +U 8106 ; WX 602 ; N uni1FAA ; G 1731 +U 8107 ; WX 602 ; N uni1FAB ; G 1732 +U 8108 ; WX 602 ; N uni1FAC ; G 1733 +U 8109 ; WX 602 ; N uni1FAD ; G 1734 +U 8110 ; WX 602 ; N uni1FAE ; G 1735 +U 8111 ; WX 602 ; N uni1FAF ; G 1736 +U 8112 ; WX 602 ; N uni1FB0 ; G 1737 +U 8113 ; WX 602 ; N uni1FB1 ; G 1738 +U 8114 ; WX 602 ; N uni1FB2 ; G 1739 +U 8115 ; WX 602 ; N uni1FB3 ; G 1740 +U 8116 ; WX 602 ; N uni1FB4 ; G 1741 +U 8118 ; WX 602 ; N uni1FB6 ; G 1742 +U 8119 ; WX 602 ; N uni1FB7 ; G 1743 +U 8120 ; WX 602 ; N uni1FB8 ; G 1744 +U 8121 ; WX 602 ; N uni1FB9 ; G 1745 +U 8122 ; WX 602 ; N uni1FBA ; G 1746 +U 8123 ; WX 602 ; N uni1FBB ; G 1747 +U 8124 ; WX 602 ; N uni1FBC ; G 1748 +U 8125 ; WX 602 ; N uni1FBD ; G 1749 +U 8126 ; WX 602 ; N uni1FBE ; G 1750 +U 8127 ; WX 602 ; N uni1FBF ; G 1751 +U 8128 ; WX 602 ; N uni1FC0 ; G 1752 +U 8129 ; WX 602 ; N uni1FC1 ; G 1753 +U 8130 ; WX 602 ; N uni1FC2 ; G 1754 +U 8131 ; WX 602 ; N uni1FC3 ; G 1755 +U 8132 ; WX 602 ; N uni1FC4 ; G 1756 +U 8134 ; WX 602 ; N uni1FC6 ; G 1757 +U 8135 ; WX 602 ; N uni1FC7 ; G 1758 +U 8136 ; WX 602 ; N uni1FC8 ; G 1759 +U 8137 ; WX 602 ; N uni1FC9 ; G 1760 +U 8138 ; WX 602 ; N uni1FCA ; G 1761 +U 8139 ; WX 602 ; N uni1FCB ; G 1762 +U 8140 ; WX 602 ; N uni1FCC ; G 1763 +U 8141 ; WX 602 ; N uni1FCD ; G 1764 +U 8142 ; WX 602 ; N uni1FCE ; G 1765 +U 8143 ; WX 602 ; N uni1FCF ; G 1766 +U 8144 ; WX 602 ; N uni1FD0 ; G 1767 +U 8145 ; WX 602 ; N uni1FD1 ; G 1768 +U 8146 ; WX 602 ; N uni1FD2 ; G 1769 +U 8147 ; WX 602 ; N uni1FD3 ; G 1770 +U 8150 ; WX 602 ; N uni1FD6 ; G 1771 +U 8151 ; WX 602 ; N uni1FD7 ; G 1772 +U 8152 ; WX 602 ; N uni1FD8 ; G 1773 +U 8153 ; WX 602 ; N uni1FD9 ; G 1774 +U 8154 ; WX 602 ; N uni1FDA ; G 1775 +U 8155 ; WX 602 ; N uni1FDB ; G 1776 +U 8157 ; WX 602 ; N uni1FDD ; G 1777 +U 8158 ; WX 602 ; N uni1FDE ; G 1778 +U 8159 ; WX 602 ; N uni1FDF ; G 1779 +U 8160 ; WX 602 ; N uni1FE0 ; G 1780 +U 8161 ; WX 602 ; N uni1FE1 ; G 1781 +U 8162 ; WX 602 ; N uni1FE2 ; G 1782 +U 8163 ; WX 602 ; N uni1FE3 ; G 1783 +U 8164 ; WX 602 ; N uni1FE4 ; G 1784 +U 8165 ; WX 602 ; N uni1FE5 ; G 1785 +U 8166 ; WX 602 ; N uni1FE6 ; G 1786 +U 8167 ; WX 602 ; N uni1FE7 ; G 1787 +U 8168 ; WX 602 ; N uni1FE8 ; G 1788 +U 8169 ; WX 602 ; N uni1FE9 ; G 1789 +U 8170 ; WX 602 ; N uni1FEA ; G 1790 +U 8171 ; WX 602 ; N uni1FEB ; G 1791 +U 8172 ; WX 602 ; N uni1FEC ; G 1792 +U 8173 ; WX 602 ; N uni1FED ; G 1793 +U 8174 ; WX 602 ; N uni1FEE ; G 1794 +U 8175 ; WX 602 ; N uni1FEF ; G 1795 +U 8178 ; WX 602 ; N uni1FF2 ; G 1796 +U 8179 ; WX 602 ; N uni1FF3 ; G 1797 +U 8180 ; WX 602 ; N uni1FF4 ; G 1798 +U 8182 ; WX 602 ; N uni1FF6 ; G 1799 +U 8183 ; WX 602 ; N uni1FF7 ; G 1800 +U 8184 ; WX 602 ; N uni1FF8 ; G 1801 +U 8185 ; WX 602 ; N uni1FF9 ; G 1802 +U 8186 ; WX 602 ; N uni1FFA ; G 1803 +U 8187 ; WX 602 ; N uni1FFB ; G 1804 +U 8188 ; WX 602 ; N uni1FFC ; G 1805 +U 8189 ; WX 602 ; N uni1FFD ; G 1806 +U 8190 ; WX 602 ; N uni1FFE ; G 1807 +U 8192 ; WX 602 ; N uni2000 ; G 1808 +U 8193 ; WX 602 ; N uni2001 ; G 1809 +U 8194 ; WX 602 ; N uni2002 ; G 1810 +U 8195 ; WX 602 ; N uni2003 ; G 1811 +U 8196 ; WX 602 ; N uni2004 ; G 1812 +U 8197 ; WX 602 ; N uni2005 ; G 1813 +U 8198 ; WX 602 ; N uni2006 ; G 1814 +U 8199 ; WX 602 ; N uni2007 ; G 1815 +U 8200 ; WX 602 ; N uni2008 ; G 1816 +U 8201 ; WX 602 ; N uni2009 ; G 1817 +U 8202 ; WX 602 ; N uni200A ; G 1818 +U 8208 ; WX 602 ; N uni2010 ; G 1819 +U 8209 ; WX 602 ; N uni2011 ; G 1820 +U 8210 ; WX 602 ; N figuredash ; G 1821 +U 8211 ; WX 602 ; N endash ; G 1822 +U 8212 ; WX 602 ; N emdash ; G 1823 +U 8213 ; WX 602 ; N uni2015 ; G 1824 +U 8214 ; WX 602 ; N uni2016 ; G 1825 +U 8215 ; WX 602 ; N underscoredbl ; G 1826 +U 8216 ; WX 602 ; N quoteleft ; G 1827 +U 8217 ; WX 602 ; N quoteright ; G 1828 +U 8218 ; WX 602 ; N quotesinglbase ; G 1829 +U 8219 ; WX 602 ; N quotereversed ; G 1830 +U 8220 ; WX 602 ; N quotedblleft ; G 1831 +U 8221 ; WX 602 ; N quotedblright ; G 1832 +U 8222 ; WX 602 ; N quotedblbase ; G 1833 +U 8223 ; WX 602 ; N uni201F ; G 1834 +U 8224 ; WX 602 ; N dagger ; G 1835 +U 8225 ; WX 602 ; N daggerdbl ; G 1836 +U 8226 ; WX 602 ; N bullet ; G 1837 +U 8227 ; WX 602 ; N uni2023 ; G 1838 +U 8230 ; WX 602 ; N ellipsis ; G 1839 +U 8239 ; WX 602 ; N uni202F ; G 1840 +U 8240 ; WX 602 ; N perthousand ; G 1841 +U 8241 ; WX 602 ; N uni2031 ; G 1842 +U 8242 ; WX 602 ; N minute ; G 1843 +U 8243 ; WX 602 ; N second ; G 1844 +U 8244 ; WX 602 ; N uni2034 ; G 1845 +U 8245 ; WX 602 ; N uni2035 ; G 1846 +U 8246 ; WX 602 ; N uni2036 ; G 1847 +U 8247 ; WX 602 ; N uni2037 ; G 1848 +U 8249 ; WX 602 ; N guilsinglleft ; G 1849 +U 8250 ; WX 602 ; N guilsinglright ; G 1850 +U 8252 ; WX 602 ; N exclamdbl ; G 1851 +U 8253 ; WX 602 ; N uni203D ; G 1852 +U 8254 ; WX 602 ; N uni203E ; G 1853 +U 8255 ; WX 602 ; N uni203F ; G 1854 +U 8261 ; WX 602 ; N uni2045 ; G 1855 +U 8262 ; WX 602 ; N uni2046 ; G 1856 +U 8263 ; WX 602 ; N uni2047 ; G 1857 +U 8264 ; WX 602 ; N uni2048 ; G 1858 +U 8265 ; WX 602 ; N uni2049 ; G 1859 +U 8267 ; WX 602 ; N uni204B ; G 1860 +U 8287 ; WX 602 ; N uni205F ; G 1861 +U 8304 ; WX 602 ; N uni2070 ; G 1862 +U 8305 ; WX 602 ; N uni2071 ; G 1863 +U 8308 ; WX 602 ; N uni2074 ; G 1864 +U 8309 ; WX 602 ; N uni2075 ; G 1865 +U 8310 ; WX 602 ; N uni2076 ; G 1866 +U 8311 ; WX 602 ; N uni2077 ; G 1867 +U 8312 ; WX 602 ; N uni2078 ; G 1868 +U 8313 ; WX 602 ; N uni2079 ; G 1869 +U 8314 ; WX 602 ; N uni207A ; G 1870 +U 8315 ; WX 602 ; N uni207B ; G 1871 +U 8316 ; WX 602 ; N uni207C ; G 1872 +U 8317 ; WX 602 ; N uni207D ; G 1873 +U 8318 ; WX 602 ; N uni207E ; G 1874 +U 8319 ; WX 602 ; N uni207F ; G 1875 +U 8320 ; WX 602 ; N uni2080 ; G 1876 +U 8321 ; WX 602 ; N uni2081 ; G 1877 +U 8322 ; WX 602 ; N uni2082 ; G 1878 +U 8323 ; WX 602 ; N uni2083 ; G 1879 +U 8324 ; WX 602 ; N uni2084 ; G 1880 +U 8325 ; WX 602 ; N uni2085 ; G 1881 +U 8326 ; WX 602 ; N uni2086 ; G 1882 +U 8327 ; WX 602 ; N uni2087 ; G 1883 +U 8328 ; WX 602 ; N uni2088 ; G 1884 +U 8329 ; WX 602 ; N uni2089 ; G 1885 +U 8330 ; WX 602 ; N uni208A ; G 1886 +U 8331 ; WX 602 ; N uni208B ; G 1887 +U 8332 ; WX 602 ; N uni208C ; G 1888 +U 8333 ; WX 602 ; N uni208D ; G 1889 +U 8334 ; WX 602 ; N uni208E ; G 1890 +U 8336 ; WX 602 ; N uni2090 ; G 1891 +U 8337 ; WX 602 ; N uni2091 ; G 1892 +U 8338 ; WX 602 ; N uni2092 ; G 1893 +U 8339 ; WX 602 ; N uni2093 ; G 1894 +U 8340 ; WX 602 ; N uni2094 ; G 1895 +U 8341 ; WX 602 ; N uni2095 ; G 1896 +U 8342 ; WX 602 ; N uni2096 ; G 1897 +U 8343 ; WX 602 ; N uni2097 ; G 1898 +U 8344 ; WX 602 ; N uni2098 ; G 1899 +U 8345 ; WX 602 ; N uni2099 ; G 1900 +U 8346 ; WX 602 ; N uni209A ; G 1901 +U 8347 ; WX 602 ; N uni209B ; G 1902 +U 8348 ; WX 602 ; N uni209C ; G 1903 +U 8352 ; WX 602 ; N uni20A0 ; G 1904 +U 8353 ; WX 602 ; N colonmonetary ; G 1905 +U 8354 ; WX 602 ; N uni20A2 ; G 1906 +U 8355 ; WX 602 ; N franc ; G 1907 +U 8356 ; WX 602 ; N lira ; G 1908 +U 8357 ; WX 602 ; N uni20A5 ; G 1909 +U 8358 ; WX 602 ; N uni20A6 ; G 1910 +U 8359 ; WX 602 ; N peseta ; G 1911 +U 8360 ; WX 602 ; N uni20A8 ; G 1912 +U 8361 ; WX 602 ; N uni20A9 ; G 1913 +U 8362 ; WX 602 ; N uni20AA ; G 1914 +U 8363 ; WX 602 ; N dong ; G 1915 +U 8364 ; WX 602 ; N Euro ; G 1916 +U 8365 ; WX 602 ; N uni20AD ; G 1917 +U 8366 ; WX 602 ; N uni20AE ; G 1918 +U 8367 ; WX 602 ; N uni20AF ; G 1919 +U 8368 ; WX 602 ; N uni20B0 ; G 1920 +U 8369 ; WX 602 ; N uni20B1 ; G 1921 +U 8370 ; WX 602 ; N uni20B2 ; G 1922 +U 8371 ; WX 602 ; N uni20B3 ; G 1923 +U 8372 ; WX 602 ; N uni20B4 ; G 1924 +U 8373 ; WX 602 ; N uni20B5 ; G 1925 +U 8376 ; WX 602 ; N uni20B8 ; G 1926 +U 8377 ; WX 602 ; N uni20B9 ; G 1927 +U 8378 ; WX 602 ; N uni20BA ; G 1928 +U 8381 ; WX 602 ; N uni20BD ; G 1929 +U 8450 ; WX 602 ; N uni2102 ; G 1930 +U 8453 ; WX 602 ; N uni2105 ; G 1931 +U 8461 ; WX 602 ; N uni210D ; G 1932 +U 8462 ; WX 602 ; N uni210E ; G 1933 +U 8463 ; WX 602 ; N uni210F ; G 1934 +U 8469 ; WX 602 ; N uni2115 ; G 1935 +U 8470 ; WX 602 ; N uni2116 ; G 1936 +U 8471 ; WX 602 ; N uni2117 ; G 1937 +U 8473 ; WX 602 ; N uni2119 ; G 1938 +U 8474 ; WX 602 ; N uni211A ; G 1939 +U 8477 ; WX 602 ; N uni211D ; G 1940 +U 8482 ; WX 602 ; N trademark ; G 1941 +U 8484 ; WX 602 ; N uni2124 ; G 1942 +U 8486 ; WX 602 ; N uni2126 ; G 1943 +U 8490 ; WX 602 ; N uni212A ; G 1944 +U 8491 ; WX 602 ; N uni212B ; G 1945 +U 8494 ; WX 602 ; N estimated ; G 1946 +U 8520 ; WX 602 ; N uni2148 ; G 1947 +U 8528 ; WX 602 ; N uni2150 ; G 1948 +U 8529 ; WX 602 ; N uni2151 ; G 1949 +U 8531 ; WX 602 ; N onethird ; G 1950 +U 8532 ; WX 602 ; N twothirds ; G 1951 +U 8533 ; WX 602 ; N uni2155 ; G 1952 +U 8534 ; WX 602 ; N uni2156 ; G 1953 +U 8535 ; WX 602 ; N uni2157 ; G 1954 +U 8536 ; WX 602 ; N uni2158 ; G 1955 +U 8537 ; WX 602 ; N uni2159 ; G 1956 +U 8538 ; WX 602 ; N uni215A ; G 1957 +U 8539 ; WX 602 ; N oneeighth ; G 1958 +U 8540 ; WX 602 ; N threeeighths ; G 1959 +U 8541 ; WX 602 ; N fiveeighths ; G 1960 +U 8542 ; WX 602 ; N seveneighths ; G 1961 +U 8543 ; WX 602 ; N uni215F ; G 1962 +U 8585 ; WX 602 ; N uni2189 ; G 1963 +U 8592 ; WX 602 ; N arrowleft ; G 1964 +U 8593 ; WX 602 ; N arrowup ; G 1965 +U 8594 ; WX 602 ; N arrowright ; G 1966 +U 8595 ; WX 602 ; N arrowdown ; G 1967 +U 8596 ; WX 602 ; N arrowboth ; G 1968 +U 8597 ; WX 602 ; N arrowupdn ; G 1969 +U 8598 ; WX 602 ; N uni2196 ; G 1970 +U 8599 ; WX 602 ; N uni2197 ; G 1971 +U 8600 ; WX 602 ; N uni2198 ; G 1972 +U 8601 ; WX 602 ; N uni2199 ; G 1973 +U 8602 ; WX 602 ; N uni219A ; G 1974 +U 8603 ; WX 602 ; N uni219B ; G 1975 +U 8604 ; WX 602 ; N uni219C ; G 1976 +U 8605 ; WX 602 ; N uni219D ; G 1977 +U 8606 ; WX 602 ; N uni219E ; G 1978 +U 8607 ; WX 602 ; N uni219F ; G 1979 +U 8608 ; WX 602 ; N uni21A0 ; G 1980 +U 8609 ; WX 602 ; N uni21A1 ; G 1981 +U 8610 ; WX 602 ; N uni21A2 ; G 1982 +U 8611 ; WX 602 ; N uni21A3 ; G 1983 +U 8612 ; WX 602 ; N uni21A4 ; G 1984 +U 8613 ; WX 602 ; N uni21A5 ; G 1985 +U 8614 ; WX 602 ; N uni21A6 ; G 1986 +U 8615 ; WX 602 ; N uni21A7 ; G 1987 +U 8616 ; WX 602 ; N arrowupdnbse ; G 1988 +U 8617 ; WX 602 ; N uni21A9 ; G 1989 +U 8618 ; WX 602 ; N uni21AA ; G 1990 +U 8619 ; WX 602 ; N uni21AB ; G 1991 +U 8620 ; WX 602 ; N uni21AC ; G 1992 +U 8621 ; WX 602 ; N uni21AD ; G 1993 +U 8622 ; WX 602 ; N uni21AE ; G 1994 +U 8623 ; WX 602 ; N uni21AF ; G 1995 +U 8624 ; WX 602 ; N uni21B0 ; G 1996 +U 8625 ; WX 602 ; N uni21B1 ; G 1997 +U 8626 ; WX 602 ; N uni21B2 ; G 1998 +U 8627 ; WX 602 ; N uni21B3 ; G 1999 +U 8628 ; WX 602 ; N uni21B4 ; G 2000 +U 8629 ; WX 602 ; N carriagereturn ; G 2001 +U 8630 ; WX 602 ; N uni21B6 ; G 2002 +U 8631 ; WX 602 ; N uni21B7 ; G 2003 +U 8632 ; WX 602 ; N uni21B8 ; G 2004 +U 8633 ; WX 602 ; N uni21B9 ; G 2005 +U 8634 ; WX 602 ; N uni21BA ; G 2006 +U 8635 ; WX 602 ; N uni21BB ; G 2007 +U 8636 ; WX 602 ; N uni21BC ; G 2008 +U 8637 ; WX 602 ; N uni21BD ; G 2009 +U 8638 ; WX 602 ; N uni21BE ; G 2010 +U 8639 ; WX 602 ; N uni21BF ; G 2011 +U 8640 ; WX 602 ; N uni21C0 ; G 2012 +U 8641 ; WX 602 ; N uni21C1 ; G 2013 +U 8642 ; WX 602 ; N uni21C2 ; G 2014 +U 8643 ; WX 602 ; N uni21C3 ; G 2015 +U 8644 ; WX 602 ; N uni21C4 ; G 2016 +U 8645 ; WX 602 ; N uni21C5 ; G 2017 +U 8646 ; WX 602 ; N uni21C6 ; G 2018 +U 8647 ; WX 602 ; N uni21C7 ; G 2019 +U 8648 ; WX 602 ; N uni21C8 ; G 2020 +U 8649 ; WX 602 ; N uni21C9 ; G 2021 +U 8650 ; WX 602 ; N uni21CA ; G 2022 +U 8651 ; WX 602 ; N uni21CB ; G 2023 +U 8652 ; WX 602 ; N uni21CC ; G 2024 +U 8653 ; WX 602 ; N uni21CD ; G 2025 +U 8654 ; WX 602 ; N uni21CE ; G 2026 +U 8655 ; WX 602 ; N uni21CF ; G 2027 +U 8656 ; WX 602 ; N arrowdblleft ; G 2028 +U 8657 ; WX 602 ; N arrowdblup ; G 2029 +U 8658 ; WX 602 ; N arrowdblright ; G 2030 +U 8659 ; WX 602 ; N arrowdbldown ; G 2031 +U 8660 ; WX 602 ; N arrowdblboth ; G 2032 +U 8661 ; WX 602 ; N uni21D5 ; G 2033 +U 8662 ; WX 602 ; N uni21D6 ; G 2034 +U 8663 ; WX 602 ; N uni21D7 ; G 2035 +U 8664 ; WX 602 ; N uni21D8 ; G 2036 +U 8665 ; WX 602 ; N uni21D9 ; G 2037 +U 8666 ; WX 602 ; N uni21DA ; G 2038 +U 8667 ; WX 602 ; N uni21DB ; G 2039 +U 8668 ; WX 602 ; N uni21DC ; G 2040 +U 8669 ; WX 602 ; N uni21DD ; G 2041 +U 8670 ; WX 602 ; N uni21DE ; G 2042 +U 8671 ; WX 602 ; N uni21DF ; G 2043 +U 8672 ; WX 602 ; N uni21E0 ; G 2044 +U 8673 ; WX 602 ; N uni21E1 ; G 2045 +U 8674 ; WX 602 ; N uni21E2 ; G 2046 +U 8675 ; WX 602 ; N uni21E3 ; G 2047 +U 8676 ; WX 602 ; N uni21E4 ; G 2048 +U 8677 ; WX 602 ; N uni21E5 ; G 2049 +U 8678 ; WX 602 ; N uni21E6 ; G 2050 +U 8679 ; WX 602 ; N uni21E7 ; G 2051 +U 8680 ; WX 602 ; N uni21E8 ; G 2052 +U 8681 ; WX 602 ; N uni21E9 ; G 2053 +U 8682 ; WX 602 ; N uni21EA ; G 2054 +U 8683 ; WX 602 ; N uni21EB ; G 2055 +U 8684 ; WX 602 ; N uni21EC ; G 2056 +U 8685 ; WX 602 ; N uni21ED ; G 2057 +U 8686 ; WX 602 ; N uni21EE ; G 2058 +U 8687 ; WX 602 ; N uni21EF ; G 2059 +U 8688 ; WX 602 ; N uni21F0 ; G 2060 +U 8689 ; WX 602 ; N uni21F1 ; G 2061 +U 8690 ; WX 602 ; N uni21F2 ; G 2062 +U 8691 ; WX 602 ; N uni21F3 ; G 2063 +U 8692 ; WX 602 ; N uni21F4 ; G 2064 +U 8693 ; WX 602 ; N uni21F5 ; G 2065 +U 8694 ; WX 602 ; N uni21F6 ; G 2066 +U 8695 ; WX 602 ; N uni21F7 ; G 2067 +U 8696 ; WX 602 ; N uni21F8 ; G 2068 +U 8697 ; WX 602 ; N uni21F9 ; G 2069 +U 8698 ; WX 602 ; N uni21FA ; G 2070 +U 8699 ; WX 602 ; N uni21FB ; G 2071 +U 8700 ; WX 602 ; N uni21FC ; G 2072 +U 8701 ; WX 602 ; N uni21FD ; G 2073 +U 8702 ; WX 602 ; N uni21FE ; G 2074 +U 8703 ; WX 602 ; N uni21FF ; G 2075 +U 8704 ; WX 602 ; N universal ; G 2076 +U 8705 ; WX 602 ; N uni2201 ; G 2077 +U 8706 ; WX 602 ; N partialdiff ; G 2078 +U 8707 ; WX 602 ; N existential ; G 2079 +U 8708 ; WX 602 ; N uni2204 ; G 2080 +U 8709 ; WX 602 ; N emptyset ; G 2081 +U 8710 ; WX 602 ; N increment ; G 2082 +U 8711 ; WX 602 ; N gradient ; G 2083 +U 8712 ; WX 602 ; N element ; G 2084 +U 8713 ; WX 602 ; N notelement ; G 2085 +U 8714 ; WX 602 ; N uni220A ; G 2086 +U 8715 ; WX 602 ; N suchthat ; G 2087 +U 8716 ; WX 602 ; N uni220C ; G 2088 +U 8717 ; WX 602 ; N uni220D ; G 2089 +U 8718 ; WX 602 ; N uni220E ; G 2090 +U 8719 ; WX 602 ; N product ; G 2091 +U 8720 ; WX 602 ; N uni2210 ; G 2092 +U 8721 ; WX 602 ; N summation ; G 2093 +U 8722 ; WX 602 ; N minus ; G 2094 +U 8723 ; WX 602 ; N uni2213 ; G 2095 +U 8725 ; WX 602 ; N uni2215 ; G 2096 +U 8727 ; WX 602 ; N asteriskmath ; G 2097 +U 8728 ; WX 602 ; N uni2218 ; G 2098 +U 8729 ; WX 602 ; N uni2219 ; G 2099 +U 8730 ; WX 602 ; N radical ; G 2100 +U 8731 ; WX 602 ; N uni221B ; G 2101 +U 8732 ; WX 602 ; N uni221C ; G 2102 +U 8733 ; WX 602 ; N proportional ; G 2103 +U 8734 ; WX 602 ; N infinity ; G 2104 +U 8735 ; WX 602 ; N orthogonal ; G 2105 +U 8736 ; WX 602 ; N angle ; G 2106 +U 8739 ; WX 602 ; N uni2223 ; G 2107 +U 8743 ; WX 602 ; N logicaland ; G 2108 +U 8744 ; WX 602 ; N logicalor ; G 2109 +U 8745 ; WX 602 ; N intersection ; G 2110 +U 8746 ; WX 602 ; N union ; G 2111 +U 8747 ; WX 602 ; N integral ; G 2112 +U 8748 ; WX 602 ; N uni222C ; G 2113 +U 8749 ; WX 602 ; N uni222D ; G 2114 +U 8756 ; WX 602 ; N therefore ; G 2115 +U 8757 ; WX 602 ; N uni2235 ; G 2116 +U 8758 ; WX 602 ; N uni2236 ; G 2117 +U 8759 ; WX 602 ; N uni2237 ; G 2118 +U 8760 ; WX 602 ; N uni2238 ; G 2119 +U 8761 ; WX 602 ; N uni2239 ; G 2120 +U 8762 ; WX 602 ; N uni223A ; G 2121 +U 8763 ; WX 602 ; N uni223B ; G 2122 +U 8764 ; WX 602 ; N similar ; G 2123 +U 8765 ; WX 602 ; N uni223D ; G 2124 +U 8769 ; WX 602 ; N uni2241 ; G 2125 +U 8770 ; WX 602 ; N uni2242 ; G 2126 +U 8771 ; WX 602 ; N uni2243 ; G 2127 +U 8772 ; WX 602 ; N uni2244 ; G 2128 +U 8773 ; WX 602 ; N congruent ; G 2129 +U 8774 ; WX 602 ; N uni2246 ; G 2130 +U 8775 ; WX 602 ; N uni2247 ; G 2131 +U 8776 ; WX 602 ; N approxequal ; G 2132 +U 8777 ; WX 602 ; N uni2249 ; G 2133 +U 8778 ; WX 602 ; N uni224A ; G 2134 +U 8779 ; WX 602 ; N uni224B ; G 2135 +U 8780 ; WX 602 ; N uni224C ; G 2136 +U 8781 ; WX 602 ; N uni224D ; G 2137 +U 8782 ; WX 602 ; N uni224E ; G 2138 +U 8783 ; WX 602 ; N uni224F ; G 2139 +U 8784 ; WX 602 ; N uni2250 ; G 2140 +U 8785 ; WX 602 ; N uni2251 ; G 2141 +U 8786 ; WX 602 ; N uni2252 ; G 2142 +U 8787 ; WX 602 ; N uni2253 ; G 2143 +U 8788 ; WX 602 ; N uni2254 ; G 2144 +U 8789 ; WX 602 ; N uni2255 ; G 2145 +U 8790 ; WX 602 ; N uni2256 ; G 2146 +U 8791 ; WX 602 ; N uni2257 ; G 2147 +U 8792 ; WX 602 ; N uni2258 ; G 2148 +U 8793 ; WX 602 ; N uni2259 ; G 2149 +U 8794 ; WX 602 ; N uni225A ; G 2150 +U 8795 ; WX 602 ; N uni225B ; G 2151 +U 8796 ; WX 602 ; N uni225C ; G 2152 +U 8797 ; WX 602 ; N uni225D ; G 2153 +U 8798 ; WX 602 ; N uni225E ; G 2154 +U 8799 ; WX 602 ; N uni225F ; G 2155 +U 8800 ; WX 602 ; N notequal ; G 2156 +U 8801 ; WX 602 ; N equivalence ; G 2157 +U 8802 ; WX 602 ; N uni2262 ; G 2158 +U 8803 ; WX 602 ; N uni2263 ; G 2159 +U 8804 ; WX 602 ; N lessequal ; G 2160 +U 8805 ; WX 602 ; N greaterequal ; G 2161 +U 8806 ; WX 602 ; N uni2266 ; G 2162 +U 8807 ; WX 602 ; N uni2267 ; G 2163 +U 8808 ; WX 602 ; N uni2268 ; G 2164 +U 8809 ; WX 602 ; N uni2269 ; G 2165 +U 8813 ; WX 602 ; N uni226D ; G 2166 +U 8814 ; WX 602 ; N uni226E ; G 2167 +U 8815 ; WX 602 ; N uni226F ; G 2168 +U 8816 ; WX 602 ; N uni2270 ; G 2169 +U 8817 ; WX 602 ; N uni2271 ; G 2170 +U 8818 ; WX 602 ; N uni2272 ; G 2171 +U 8819 ; WX 602 ; N uni2273 ; G 2172 +U 8820 ; WX 602 ; N uni2274 ; G 2173 +U 8821 ; WX 602 ; N uni2275 ; G 2174 +U 8822 ; WX 602 ; N uni2276 ; G 2175 +U 8823 ; WX 602 ; N uni2277 ; G 2176 +U 8824 ; WX 602 ; N uni2278 ; G 2177 +U 8825 ; WX 602 ; N uni2279 ; G 2178 +U 8826 ; WX 602 ; N uni227A ; G 2179 +U 8827 ; WX 602 ; N uni227B ; G 2180 +U 8828 ; WX 602 ; N uni227C ; G 2181 +U 8829 ; WX 602 ; N uni227D ; G 2182 +U 8830 ; WX 602 ; N uni227E ; G 2183 +U 8831 ; WX 602 ; N uni227F ; G 2184 +U 8832 ; WX 602 ; N uni2280 ; G 2185 +U 8833 ; WX 602 ; N uni2281 ; G 2186 +U 8834 ; WX 602 ; N propersubset ; G 2187 +U 8835 ; WX 602 ; N propersuperset ; G 2188 +U 8836 ; WX 602 ; N notsubset ; G 2189 +U 8837 ; WX 602 ; N uni2285 ; G 2190 +U 8838 ; WX 602 ; N reflexsubset ; G 2191 +U 8839 ; WX 602 ; N reflexsuperset ; G 2192 +U 8840 ; WX 602 ; N uni2288 ; G 2193 +U 8841 ; WX 602 ; N uni2289 ; G 2194 +U 8842 ; WX 602 ; N uni228A ; G 2195 +U 8843 ; WX 602 ; N uni228B ; G 2196 +U 8845 ; WX 602 ; N uni228D ; G 2197 +U 8846 ; WX 602 ; N uni228E ; G 2198 +U 8847 ; WX 602 ; N uni228F ; G 2199 +U 8848 ; WX 602 ; N uni2290 ; G 2200 +U 8849 ; WX 602 ; N uni2291 ; G 2201 +U 8850 ; WX 602 ; N uni2292 ; G 2202 +U 8851 ; WX 602 ; N uni2293 ; G 2203 +U 8852 ; WX 602 ; N uni2294 ; G 2204 +U 8853 ; WX 602 ; N circleplus ; G 2205 +U 8854 ; WX 602 ; N uni2296 ; G 2206 +U 8855 ; WX 602 ; N circlemultiply ; G 2207 +U 8856 ; WX 602 ; N uni2298 ; G 2208 +U 8857 ; WX 602 ; N uni2299 ; G 2209 +U 8858 ; WX 602 ; N uni229A ; G 2210 +U 8859 ; WX 602 ; N uni229B ; G 2211 +U 8860 ; WX 602 ; N uni229C ; G 2212 +U 8861 ; WX 602 ; N uni229D ; G 2213 +U 8862 ; WX 602 ; N uni229E ; G 2214 +U 8863 ; WX 602 ; N uni229F ; G 2215 +U 8864 ; WX 602 ; N uni22A0 ; G 2216 +U 8865 ; WX 602 ; N uni22A1 ; G 2217 +U 8866 ; WX 602 ; N uni22A2 ; G 2218 +U 8867 ; WX 602 ; N uni22A3 ; G 2219 +U 8868 ; WX 602 ; N uni22A4 ; G 2220 +U 8869 ; WX 602 ; N perpendicular ; G 2221 +U 8882 ; WX 602 ; N uni22B2 ; G 2222 +U 8883 ; WX 602 ; N uni22B3 ; G 2223 +U 8884 ; WX 602 ; N uni22B4 ; G 2224 +U 8885 ; WX 602 ; N uni22B5 ; G 2225 +U 8888 ; WX 602 ; N uni22B8 ; G 2226 +U 8898 ; WX 602 ; N uni22C2 ; G 2227 +U 8899 ; WX 602 ; N uni22C3 ; G 2228 +U 8900 ; WX 602 ; N uni22C4 ; G 2229 +U 8901 ; WX 602 ; N dotmath ; G 2230 +U 8902 ; WX 602 ; N uni22C6 ; G 2231 +U 8909 ; WX 602 ; N uni22CD ; G 2232 +U 8910 ; WX 602 ; N uni22CE ; G 2233 +U 8911 ; WX 602 ; N uni22CF ; G 2234 +U 8912 ; WX 602 ; N uni22D0 ; G 2235 +U 8913 ; WX 602 ; N uni22D1 ; G 2236 +U 8922 ; WX 602 ; N uni22DA ; G 2237 +U 8923 ; WX 602 ; N uni22DB ; G 2238 +U 8924 ; WX 602 ; N uni22DC ; G 2239 +U 8925 ; WX 602 ; N uni22DD ; G 2240 +U 8926 ; WX 602 ; N uni22DE ; G 2241 +U 8927 ; WX 602 ; N uni22DF ; G 2242 +U 8928 ; WX 602 ; N uni22E0 ; G 2243 +U 8929 ; WX 602 ; N uni22E1 ; G 2244 +U 8930 ; WX 602 ; N uni22E2 ; G 2245 +U 8931 ; WX 602 ; N uni22E3 ; G 2246 +U 8932 ; WX 602 ; N uni22E4 ; G 2247 +U 8933 ; WX 602 ; N uni22E5 ; G 2248 +U 8934 ; WX 602 ; N uni22E6 ; G 2249 +U 8935 ; WX 602 ; N uni22E7 ; G 2250 +U 8936 ; WX 602 ; N uni22E8 ; G 2251 +U 8937 ; WX 602 ; N uni22E9 ; G 2252 +U 8943 ; WX 602 ; N uni22EF ; G 2253 +U 8960 ; WX 602 ; N uni2300 ; G 2254 +U 8961 ; WX 602 ; N uni2301 ; G 2255 +U 8962 ; WX 602 ; N house ; G 2256 +U 8963 ; WX 602 ; N uni2303 ; G 2257 +U 8964 ; WX 602 ; N uni2304 ; G 2258 +U 8965 ; WX 602 ; N uni2305 ; G 2259 +U 8966 ; WX 602 ; N uni2306 ; G 2260 +U 8968 ; WX 602 ; N uni2308 ; G 2261 +U 8969 ; WX 602 ; N uni2309 ; G 2262 +U 8970 ; WX 602 ; N uni230A ; G 2263 +U 8971 ; WX 602 ; N uni230B ; G 2264 +U 8972 ; WX 602 ; N uni230C ; G 2265 +U 8973 ; WX 602 ; N uni230D ; G 2266 +U 8974 ; WX 602 ; N uni230E ; G 2267 +U 8975 ; WX 602 ; N uni230F ; G 2268 +U 8976 ; WX 602 ; N revlogicalnot ; G 2269 +U 8977 ; WX 602 ; N uni2311 ; G 2270 +U 8978 ; WX 602 ; N uni2312 ; G 2271 +U 8979 ; WX 602 ; N uni2313 ; G 2272 +U 8980 ; WX 602 ; N uni2314 ; G 2273 +U 8981 ; WX 602 ; N uni2315 ; G 2274 +U 8984 ; WX 602 ; N uni2318 ; G 2275 +U 8985 ; WX 602 ; N uni2319 ; G 2276 +U 8988 ; WX 602 ; N uni231C ; G 2277 +U 8989 ; WX 602 ; N uni231D ; G 2278 +U 8990 ; WX 602 ; N uni231E ; G 2279 +U 8991 ; WX 602 ; N uni231F ; G 2280 +U 8992 ; WX 602 ; N integraltp ; G 2281 +U 8993 ; WX 602 ; N integralbt ; G 2282 +U 8997 ; WX 602 ; N uni2325 ; G 2283 +U 8998 ; WX 602 ; N uni2326 ; G 2284 +U 8999 ; WX 602 ; N uni2327 ; G 2285 +U 9000 ; WX 602 ; N uni2328 ; G 2286 +U 9003 ; WX 602 ; N uni232B ; G 2287 +U 9013 ; WX 602 ; N uni2335 ; G 2288 +U 9014 ; WX 602 ; N uni2336 ; G 2289 +U 9015 ; WX 602 ; N uni2337 ; G 2290 +U 9016 ; WX 602 ; N uni2338 ; G 2291 +U 9017 ; WX 602 ; N uni2339 ; G 2292 +U 9018 ; WX 602 ; N uni233A ; G 2293 +U 9019 ; WX 602 ; N uni233B ; G 2294 +U 9020 ; WX 602 ; N uni233C ; G 2295 +U 9021 ; WX 602 ; N uni233D ; G 2296 +U 9022 ; WX 602 ; N uni233E ; G 2297 +U 9023 ; WX 602 ; N uni233F ; G 2298 +U 9024 ; WX 602 ; N uni2340 ; G 2299 +U 9025 ; WX 602 ; N uni2341 ; G 2300 +U 9026 ; WX 602 ; N uni2342 ; G 2301 +U 9027 ; WX 602 ; N uni2343 ; G 2302 +U 9028 ; WX 602 ; N uni2344 ; G 2303 +U 9029 ; WX 602 ; N uni2345 ; G 2304 +U 9030 ; WX 602 ; N uni2346 ; G 2305 +U 9031 ; WX 602 ; N uni2347 ; G 2306 +U 9032 ; WX 602 ; N uni2348 ; G 2307 +U 9033 ; WX 602 ; N uni2349 ; G 2308 +U 9034 ; WX 602 ; N uni234A ; G 2309 +U 9035 ; WX 602 ; N uni234B ; G 2310 +U 9036 ; WX 602 ; N uni234C ; G 2311 +U 9037 ; WX 602 ; N uni234D ; G 2312 +U 9038 ; WX 602 ; N uni234E ; G 2313 +U 9039 ; WX 602 ; N uni234F ; G 2314 +U 9040 ; WX 602 ; N uni2350 ; G 2315 +U 9041 ; WX 602 ; N uni2351 ; G 2316 +U 9042 ; WX 602 ; N uni2352 ; G 2317 +U 9043 ; WX 602 ; N uni2353 ; G 2318 +U 9044 ; WX 602 ; N uni2354 ; G 2319 +U 9045 ; WX 602 ; N uni2355 ; G 2320 +U 9046 ; WX 602 ; N uni2356 ; G 2321 +U 9047 ; WX 602 ; N uni2357 ; G 2322 +U 9048 ; WX 602 ; N uni2358 ; G 2323 +U 9049 ; WX 602 ; N uni2359 ; G 2324 +U 9050 ; WX 602 ; N uni235A ; G 2325 +U 9051 ; WX 602 ; N uni235B ; G 2326 +U 9052 ; WX 602 ; N uni235C ; G 2327 +U 9053 ; WX 602 ; N uni235D ; G 2328 +U 9054 ; WX 602 ; N uni235E ; G 2329 +U 9055 ; WX 602 ; N uni235F ; G 2330 +U 9056 ; WX 602 ; N uni2360 ; G 2331 +U 9057 ; WX 602 ; N uni2361 ; G 2332 +U 9058 ; WX 602 ; N uni2362 ; G 2333 +U 9059 ; WX 602 ; N uni2363 ; G 2334 +U 9060 ; WX 602 ; N uni2364 ; G 2335 +U 9061 ; WX 602 ; N uni2365 ; G 2336 +U 9062 ; WX 602 ; N uni2366 ; G 2337 +U 9063 ; WX 602 ; N uni2367 ; G 2338 +U 9064 ; WX 602 ; N uni2368 ; G 2339 +U 9065 ; WX 602 ; N uni2369 ; G 2340 +U 9066 ; WX 602 ; N uni236A ; G 2341 +U 9067 ; WX 602 ; N uni236B ; G 2342 +U 9068 ; WX 602 ; N uni236C ; G 2343 +U 9069 ; WX 602 ; N uni236D ; G 2344 +U 9070 ; WX 602 ; N uni236E ; G 2345 +U 9071 ; WX 602 ; N uni236F ; G 2346 +U 9072 ; WX 602 ; N uni2370 ; G 2347 +U 9073 ; WX 602 ; N uni2371 ; G 2348 +U 9074 ; WX 602 ; N uni2372 ; G 2349 +U 9075 ; WX 602 ; N uni2373 ; G 2350 +U 9076 ; WX 602 ; N uni2374 ; G 2351 +U 9077 ; WX 602 ; N uni2375 ; G 2352 +U 9078 ; WX 602 ; N uni2376 ; G 2353 +U 9079 ; WX 602 ; N uni2377 ; G 2354 +U 9080 ; WX 602 ; N uni2378 ; G 2355 +U 9081 ; WX 602 ; N uni2379 ; G 2356 +U 9082 ; WX 602 ; N uni237A ; G 2357 +U 9085 ; WX 602 ; N uni237D ; G 2358 +U 9088 ; WX 602 ; N uni2380 ; G 2359 +U 9089 ; WX 602 ; N uni2381 ; G 2360 +U 9090 ; WX 602 ; N uni2382 ; G 2361 +U 9091 ; WX 602 ; N uni2383 ; G 2362 +U 9096 ; WX 602 ; N uni2388 ; G 2363 +U 9097 ; WX 602 ; N uni2389 ; G 2364 +U 9098 ; WX 602 ; N uni238A ; G 2365 +U 9099 ; WX 602 ; N uni238B ; G 2366 +U 9109 ; WX 602 ; N uni2395 ; G 2367 +U 9115 ; WX 602 ; N uni239B ; G 2368 +U 9116 ; WX 602 ; N uni239C ; G 2369 +U 9117 ; WX 602 ; N uni239D ; G 2370 +U 9118 ; WX 602 ; N uni239E ; G 2371 +U 9119 ; WX 602 ; N uni239F ; G 2372 +U 9120 ; WX 602 ; N uni23A0 ; G 2373 +U 9121 ; WX 602 ; N uni23A1 ; G 2374 +U 9122 ; WX 602 ; N uni23A2 ; G 2375 +U 9123 ; WX 602 ; N uni23A3 ; G 2376 +U 9124 ; WX 602 ; N uni23A4 ; G 2377 +U 9125 ; WX 602 ; N uni23A5 ; G 2378 +U 9126 ; WX 602 ; N uni23A6 ; G 2379 +U 9127 ; WX 602 ; N uni23A7 ; G 2380 +U 9128 ; WX 602 ; N uni23A8 ; G 2381 +U 9129 ; WX 602 ; N uni23A9 ; G 2382 +U 9130 ; WX 602 ; N uni23AA ; G 2383 +U 9131 ; WX 602 ; N uni23AB ; G 2384 +U 9132 ; WX 602 ; N uni23AC ; G 2385 +U 9133 ; WX 602 ; N uni23AD ; G 2386 +U 9134 ; WX 602 ; N uni23AE ; G 2387 +U 9166 ; WX 602 ; N uni23CE ; G 2388 +U 9167 ; WX 602 ; N uni23CF ; G 2389 +U 9251 ; WX 602 ; N uni2423 ; G 2390 +U 9472 ; WX 602 ; N SF100000 ; G 2391 +U 9473 ; WX 602 ; N uni2501 ; G 2392 +U 9474 ; WX 602 ; N SF110000 ; G 2393 +U 9475 ; WX 602 ; N uni2503 ; G 2394 +U 9476 ; WX 602 ; N uni2504 ; G 2395 +U 9477 ; WX 602 ; N uni2505 ; G 2396 +U 9478 ; WX 602 ; N uni2506 ; G 2397 +U 9479 ; WX 602 ; N uni2507 ; G 2398 +U 9480 ; WX 602 ; N uni2508 ; G 2399 +U 9481 ; WX 602 ; N uni2509 ; G 2400 +U 9482 ; WX 602 ; N uni250A ; G 2401 +U 9483 ; WX 602 ; N uni250B ; G 2402 +U 9484 ; WX 602 ; N SF010000 ; G 2403 +U 9485 ; WX 602 ; N uni250D ; G 2404 +U 9486 ; WX 602 ; N uni250E ; G 2405 +U 9487 ; WX 602 ; N uni250F ; G 2406 +U 9488 ; WX 602 ; N SF030000 ; G 2407 +U 9489 ; WX 602 ; N uni2511 ; G 2408 +U 9490 ; WX 602 ; N uni2512 ; G 2409 +U 9491 ; WX 602 ; N uni2513 ; G 2410 +U 9492 ; WX 602 ; N SF020000 ; G 2411 +U 9493 ; WX 602 ; N uni2515 ; G 2412 +U 9494 ; WX 602 ; N uni2516 ; G 2413 +U 9495 ; WX 602 ; N uni2517 ; G 2414 +U 9496 ; WX 602 ; N SF040000 ; G 2415 +U 9497 ; WX 602 ; N uni2519 ; G 2416 +U 9498 ; WX 602 ; N uni251A ; G 2417 +U 9499 ; WX 602 ; N uni251B ; G 2418 +U 9500 ; WX 602 ; N SF080000 ; G 2419 +U 9501 ; WX 602 ; N uni251D ; G 2420 +U 9502 ; WX 602 ; N uni251E ; G 2421 +U 9503 ; WX 602 ; N uni251F ; G 2422 +U 9504 ; WX 602 ; N uni2520 ; G 2423 +U 9505 ; WX 602 ; N uni2521 ; G 2424 +U 9506 ; WX 602 ; N uni2522 ; G 2425 +U 9507 ; WX 602 ; N uni2523 ; G 2426 +U 9508 ; WX 602 ; N SF090000 ; G 2427 +U 9509 ; WX 602 ; N uni2525 ; G 2428 +U 9510 ; WX 602 ; N uni2526 ; G 2429 +U 9511 ; WX 602 ; N uni2527 ; G 2430 +U 9512 ; WX 602 ; N uni2528 ; G 2431 +U 9513 ; WX 602 ; N uni2529 ; G 2432 +U 9514 ; WX 602 ; N uni252A ; G 2433 +U 9515 ; WX 602 ; N uni252B ; G 2434 +U 9516 ; WX 602 ; N SF060000 ; G 2435 +U 9517 ; WX 602 ; N uni252D ; G 2436 +U 9518 ; WX 602 ; N uni252E ; G 2437 +U 9519 ; WX 602 ; N uni252F ; G 2438 +U 9520 ; WX 602 ; N uni2530 ; G 2439 +U 9521 ; WX 602 ; N uni2531 ; G 2440 +U 9522 ; WX 602 ; N uni2532 ; G 2441 +U 9523 ; WX 602 ; N uni2533 ; G 2442 +U 9524 ; WX 602 ; N SF070000 ; G 2443 +U 9525 ; WX 602 ; N uni2535 ; G 2444 +U 9526 ; WX 602 ; N uni2536 ; G 2445 +U 9527 ; WX 602 ; N uni2537 ; G 2446 +U 9528 ; WX 602 ; N uni2538 ; G 2447 +U 9529 ; WX 602 ; N uni2539 ; G 2448 +U 9530 ; WX 602 ; N uni253A ; G 2449 +U 9531 ; WX 602 ; N uni253B ; G 2450 +U 9532 ; WX 602 ; N SF050000 ; G 2451 +U 9533 ; WX 602 ; N uni253D ; G 2452 +U 9534 ; WX 602 ; N uni253E ; G 2453 +U 9535 ; WX 602 ; N uni253F ; G 2454 +U 9536 ; WX 602 ; N uni2540 ; G 2455 +U 9537 ; WX 602 ; N uni2541 ; G 2456 +U 9538 ; WX 602 ; N uni2542 ; G 2457 +U 9539 ; WX 602 ; N uni2543 ; G 2458 +U 9540 ; WX 602 ; N uni2544 ; G 2459 +U 9541 ; WX 602 ; N uni2545 ; G 2460 +U 9542 ; WX 602 ; N uni2546 ; G 2461 +U 9543 ; WX 602 ; N uni2547 ; G 2462 +U 9544 ; WX 602 ; N uni2548 ; G 2463 +U 9545 ; WX 602 ; N uni2549 ; G 2464 +U 9546 ; WX 602 ; N uni254A ; G 2465 +U 9547 ; WX 602 ; N uni254B ; G 2466 +U 9548 ; WX 602 ; N uni254C ; G 2467 +U 9549 ; WX 602 ; N uni254D ; G 2468 +U 9550 ; WX 602 ; N uni254E ; G 2469 +U 9551 ; WX 602 ; N uni254F ; G 2470 +U 9552 ; WX 602 ; N SF430000 ; G 2471 +U 9553 ; WX 602 ; N SF240000 ; G 2472 +U 9554 ; WX 602 ; N SF510000 ; G 2473 +U 9555 ; WX 602 ; N SF520000 ; G 2474 +U 9556 ; WX 602 ; N SF390000 ; G 2475 +U 9557 ; WX 602 ; N SF220000 ; G 2476 +U 9558 ; WX 602 ; N SF210000 ; G 2477 +U 9559 ; WX 602 ; N SF250000 ; G 2478 +U 9560 ; WX 602 ; N SF500000 ; G 2479 +U 9561 ; WX 602 ; N SF490000 ; G 2480 +U 9562 ; WX 602 ; N SF380000 ; G 2481 +U 9563 ; WX 602 ; N SF280000 ; G 2482 +U 9564 ; WX 602 ; N SF270000 ; G 2483 +U 9565 ; WX 602 ; N SF260000 ; G 2484 +U 9566 ; WX 602 ; N SF360000 ; G 2485 +U 9567 ; WX 602 ; N SF370000 ; G 2486 +U 9568 ; WX 602 ; N SF420000 ; G 2487 +U 9569 ; WX 602 ; N SF190000 ; G 2488 +U 9570 ; WX 602 ; N SF200000 ; G 2489 +U 9571 ; WX 602 ; N SF230000 ; G 2490 +U 9572 ; WX 602 ; N SF470000 ; G 2491 +U 9573 ; WX 602 ; N SF480000 ; G 2492 +U 9574 ; WX 602 ; N SF410000 ; G 2493 +U 9575 ; WX 602 ; N SF450000 ; G 2494 +U 9576 ; WX 602 ; N SF460000 ; G 2495 +U 9577 ; WX 602 ; N SF400000 ; G 2496 +U 9578 ; WX 602 ; N SF540000 ; G 2497 +U 9579 ; WX 602 ; N SF530000 ; G 2498 +U 9580 ; WX 602 ; N SF440000 ; G 2499 +U 9581 ; WX 602 ; N uni256D ; G 2500 +U 9582 ; WX 602 ; N uni256E ; G 2501 +U 9583 ; WX 602 ; N uni256F ; G 2502 +U 9584 ; WX 602 ; N uni2570 ; G 2503 +U 9585 ; WX 602 ; N uni2571 ; G 2504 +U 9586 ; WX 602 ; N uni2572 ; G 2505 +U 9587 ; WX 602 ; N uni2573 ; G 2506 +U 9588 ; WX 602 ; N uni2574 ; G 2507 +U 9589 ; WX 602 ; N uni2575 ; G 2508 +U 9590 ; WX 602 ; N uni2576 ; G 2509 +U 9591 ; WX 602 ; N uni2577 ; G 2510 +U 9592 ; WX 602 ; N uni2578 ; G 2511 +U 9593 ; WX 602 ; N uni2579 ; G 2512 +U 9594 ; WX 602 ; N uni257A ; G 2513 +U 9595 ; WX 602 ; N uni257B ; G 2514 +U 9596 ; WX 602 ; N uni257C ; G 2515 +U 9597 ; WX 602 ; N uni257D ; G 2516 +U 9598 ; WX 602 ; N uni257E ; G 2517 +U 9599 ; WX 602 ; N uni257F ; G 2518 +U 9600 ; WX 602 ; N upblock ; G 2519 +U 9601 ; WX 602 ; N uni2581 ; G 2520 +U 9602 ; WX 602 ; N uni2582 ; G 2521 +U 9603 ; WX 602 ; N uni2583 ; G 2522 +U 9604 ; WX 602 ; N dnblock ; G 2523 +U 9605 ; WX 602 ; N uni2585 ; G 2524 +U 9606 ; WX 602 ; N uni2586 ; G 2525 +U 9607 ; WX 602 ; N uni2587 ; G 2526 +U 9608 ; WX 602 ; N block ; G 2527 +U 9609 ; WX 602 ; N uni2589 ; G 2528 +U 9610 ; WX 602 ; N uni258A ; G 2529 +U 9611 ; WX 602 ; N uni258B ; G 2530 +U 9612 ; WX 602 ; N lfblock ; G 2531 +U 9613 ; WX 602 ; N uni258D ; G 2532 +U 9614 ; WX 602 ; N uni258E ; G 2533 +U 9615 ; WX 602 ; N uni258F ; G 2534 +U 9616 ; WX 602 ; N rtblock ; G 2535 +U 9617 ; WX 602 ; N ltshade ; G 2536 +U 9618 ; WX 602 ; N shade ; G 2537 +U 9619 ; WX 602 ; N dkshade ; G 2538 +U 9620 ; WX 602 ; N uni2594 ; G 2539 +U 9621 ; WX 602 ; N uni2595 ; G 2540 +U 9622 ; WX 602 ; N uni2596 ; G 2541 +U 9623 ; WX 602 ; N uni2597 ; G 2542 +U 9624 ; WX 602 ; N uni2598 ; G 2543 +U 9625 ; WX 602 ; N uni2599 ; G 2544 +U 9626 ; WX 602 ; N uni259A ; G 2545 +U 9627 ; WX 602 ; N uni259B ; G 2546 +U 9628 ; WX 602 ; N uni259C ; G 2547 +U 9629 ; WX 602 ; N uni259D ; G 2548 +U 9630 ; WX 602 ; N uni259E ; G 2549 +U 9631 ; WX 602 ; N uni259F ; G 2550 +U 9632 ; WX 602 ; N filledbox ; G 2551 +U 9633 ; WX 602 ; N H22073 ; G 2552 +U 9634 ; WX 602 ; N uni25A2 ; G 2553 +U 9635 ; WX 602 ; N uni25A3 ; G 2554 +U 9636 ; WX 602 ; N uni25A4 ; G 2555 +U 9637 ; WX 602 ; N uni25A5 ; G 2556 +U 9638 ; WX 602 ; N uni25A6 ; G 2557 +U 9639 ; WX 602 ; N uni25A7 ; G 2558 +U 9640 ; WX 602 ; N uni25A8 ; G 2559 +U 9641 ; WX 602 ; N uni25A9 ; G 2560 +U 9642 ; WX 602 ; N H18543 ; G 2561 +U 9643 ; WX 602 ; N H18551 ; G 2562 +U 9644 ; WX 602 ; N filledrect ; G 2563 +U 9645 ; WX 602 ; N uni25AD ; G 2564 +U 9646 ; WX 602 ; N uni25AE ; G 2565 +U 9647 ; WX 602 ; N uni25AF ; G 2566 +U 9648 ; WX 602 ; N uni25B0 ; G 2567 +U 9649 ; WX 602 ; N uni25B1 ; G 2568 +U 9650 ; WX 602 ; N triagup ; G 2569 +U 9651 ; WX 602 ; N uni25B3 ; G 2570 +U 9652 ; WX 602 ; N uni25B4 ; G 2571 +U 9653 ; WX 602 ; N uni25B5 ; G 2572 +U 9654 ; WX 602 ; N uni25B6 ; G 2573 +U 9655 ; WX 602 ; N uni25B7 ; G 2574 +U 9656 ; WX 602 ; N uni25B8 ; G 2575 +U 9657 ; WX 602 ; N uni25B9 ; G 2576 +U 9658 ; WX 602 ; N triagrt ; G 2577 +U 9659 ; WX 602 ; N uni25BB ; G 2578 +U 9660 ; WX 602 ; N triagdn ; G 2579 +U 9661 ; WX 602 ; N uni25BD ; G 2580 +U 9662 ; WX 602 ; N uni25BE ; G 2581 +U 9663 ; WX 602 ; N uni25BF ; G 2582 +U 9664 ; WX 602 ; N uni25C0 ; G 2583 +U 9665 ; WX 602 ; N uni25C1 ; G 2584 +U 9666 ; WX 602 ; N uni25C2 ; G 2585 +U 9667 ; WX 602 ; N uni25C3 ; G 2586 +U 9668 ; WX 602 ; N triaglf ; G 2587 +U 9669 ; WX 602 ; N uni25C5 ; G 2588 +U 9670 ; WX 602 ; N uni25C6 ; G 2589 +U 9671 ; WX 602 ; N uni25C7 ; G 2590 +U 9672 ; WX 602 ; N uni25C8 ; G 2591 +U 9673 ; WX 602 ; N uni25C9 ; G 2592 +U 9674 ; WX 602 ; N lozenge ; G 2593 +U 9675 ; WX 602 ; N circle ; G 2594 +U 9676 ; WX 602 ; N uni25CC ; G 2595 +U 9677 ; WX 602 ; N uni25CD ; G 2596 +U 9678 ; WX 602 ; N uni25CE ; G 2597 +U 9679 ; WX 602 ; N H18533 ; G 2598 +U 9680 ; WX 602 ; N uni25D0 ; G 2599 +U 9681 ; WX 602 ; N uni25D1 ; G 2600 +U 9682 ; WX 602 ; N uni25D2 ; G 2601 +U 9683 ; WX 602 ; N uni25D3 ; G 2602 +U 9684 ; WX 602 ; N uni25D4 ; G 2603 +U 9685 ; WX 602 ; N uni25D5 ; G 2604 +U 9686 ; WX 602 ; N uni25D6 ; G 2605 +U 9687 ; WX 602 ; N uni25D7 ; G 2606 +U 9688 ; WX 602 ; N invbullet ; G 2607 +U 9689 ; WX 602 ; N invcircle ; G 2608 +U 9690 ; WX 602 ; N uni25DA ; G 2609 +U 9691 ; WX 602 ; N uni25DB ; G 2610 +U 9692 ; WX 602 ; N uni25DC ; G 2611 +U 9693 ; WX 602 ; N uni25DD ; G 2612 +U 9694 ; WX 602 ; N uni25DE ; G 2613 +U 9695 ; WX 602 ; N uni25DF ; G 2614 +U 9696 ; WX 602 ; N uni25E0 ; G 2615 +U 9697 ; WX 602 ; N uni25E1 ; G 2616 +U 9698 ; WX 602 ; N uni25E2 ; G 2617 +U 9699 ; WX 602 ; N uni25E3 ; G 2618 +U 9700 ; WX 602 ; N uni25E4 ; G 2619 +U 9701 ; WX 602 ; N uni25E5 ; G 2620 +U 9702 ; WX 602 ; N openbullet ; G 2621 +U 9703 ; WX 602 ; N uni25E7 ; G 2622 +U 9704 ; WX 602 ; N uni25E8 ; G 2623 +U 9705 ; WX 602 ; N uni25E9 ; G 2624 +U 9706 ; WX 602 ; N uni25EA ; G 2625 +U 9707 ; WX 602 ; N uni25EB ; G 2626 +U 9708 ; WX 602 ; N uni25EC ; G 2627 +U 9709 ; WX 602 ; N uni25ED ; G 2628 +U 9710 ; WX 602 ; N uni25EE ; G 2629 +U 9711 ; WX 602 ; N uni25EF ; G 2630 +U 9712 ; WX 602 ; N uni25F0 ; G 2631 +U 9713 ; WX 602 ; N uni25F1 ; G 2632 +U 9714 ; WX 602 ; N uni25F2 ; G 2633 +U 9715 ; WX 602 ; N uni25F3 ; G 2634 +U 9716 ; WX 602 ; N uni25F4 ; G 2635 +U 9717 ; WX 602 ; N uni25F5 ; G 2636 +U 9718 ; WX 602 ; N uni25F6 ; G 2637 +U 9719 ; WX 602 ; N uni25F7 ; G 2638 +U 9720 ; WX 602 ; N uni25F8 ; G 2639 +U 9721 ; WX 602 ; N uni25F9 ; G 2640 +U 9722 ; WX 602 ; N uni25FA ; G 2641 +U 9723 ; WX 602 ; N uni25FB ; G 2642 +U 9724 ; WX 602 ; N uni25FC ; G 2643 +U 9725 ; WX 602 ; N uni25FD ; G 2644 +U 9726 ; WX 602 ; N uni25FE ; G 2645 +U 9727 ; WX 602 ; N uni25FF ; G 2646 +U 9728 ; WX 602 ; N uni2600 ; G 2647 +U 9729 ; WX 602 ; N uni2601 ; G 2648 +U 9730 ; WX 602 ; N uni2602 ; G 2649 +U 9731 ; WX 602 ; N uni2603 ; G 2650 +U 9732 ; WX 602 ; N uni2604 ; G 2651 +U 9733 ; WX 602 ; N uni2605 ; G 2652 +U 9734 ; WX 602 ; N uni2606 ; G 2653 +U 9735 ; WX 602 ; N uni2607 ; G 2654 +U 9736 ; WX 602 ; N uni2608 ; G 2655 +U 9737 ; WX 602 ; N uni2609 ; G 2656 +U 9738 ; WX 602 ; N uni260A ; G 2657 +U 9739 ; WX 602 ; N uni260B ; G 2658 +U 9740 ; WX 602 ; N uni260C ; G 2659 +U 9741 ; WX 602 ; N uni260D ; G 2660 +U 9742 ; WX 602 ; N uni260E ; G 2661 +U 9743 ; WX 602 ; N uni260F ; G 2662 +U 9744 ; WX 602 ; N uni2610 ; G 2663 +U 9745 ; WX 602 ; N uni2611 ; G 2664 +U 9746 ; WX 602 ; N uni2612 ; G 2665 +U 9747 ; WX 602 ; N uni2613 ; G 2666 +U 9748 ; WX 602 ; N uni2614 ; G 2667 +U 9749 ; WX 602 ; N uni2615 ; G 2668 +U 9750 ; WX 602 ; N uni2616 ; G 2669 +U 9751 ; WX 602 ; N uni2617 ; G 2670 +U 9752 ; WX 602 ; N uni2618 ; G 2671 +U 9753 ; WX 602 ; N uni2619 ; G 2672 +U 9754 ; WX 602 ; N uni261A ; G 2673 +U 9755 ; WX 602 ; N uni261B ; G 2674 +U 9756 ; WX 602 ; N uni261C ; G 2675 +U 9757 ; WX 602 ; N uni261D ; G 2676 +U 9758 ; WX 602 ; N uni261E ; G 2677 +U 9759 ; WX 602 ; N uni261F ; G 2678 +U 9760 ; WX 602 ; N uni2620 ; G 2679 +U 9761 ; WX 602 ; N uni2621 ; G 2680 +U 9762 ; WX 602 ; N uni2622 ; G 2681 +U 9763 ; WX 602 ; N uni2623 ; G 2682 +U 9764 ; WX 602 ; N uni2624 ; G 2683 +U 9765 ; WX 602 ; N uni2625 ; G 2684 +U 9766 ; WX 602 ; N uni2626 ; G 2685 +U 9767 ; WX 602 ; N uni2627 ; G 2686 +U 9768 ; WX 602 ; N uni2628 ; G 2687 +U 9769 ; WX 602 ; N uni2629 ; G 2688 +U 9770 ; WX 602 ; N uni262A ; G 2689 +U 9771 ; WX 602 ; N uni262B ; G 2690 +U 9772 ; WX 602 ; N uni262C ; G 2691 +U 9773 ; WX 602 ; N uni262D ; G 2692 +U 9774 ; WX 602 ; N uni262E ; G 2693 +U 9775 ; WX 602 ; N uni262F ; G 2694 +U 9784 ; WX 602 ; N uni2638 ; G 2695 +U 9785 ; WX 602 ; N uni2639 ; G 2696 +U 9786 ; WX 602 ; N smileface ; G 2697 +U 9787 ; WX 602 ; N invsmileface ; G 2698 +U 9788 ; WX 602 ; N sun ; G 2699 +U 9789 ; WX 602 ; N uni263D ; G 2700 +U 9790 ; WX 602 ; N uni263E ; G 2701 +U 9791 ; WX 602 ; N uni263F ; G 2702 +U 9792 ; WX 602 ; N female ; G 2703 +U 9793 ; WX 602 ; N uni2641 ; G 2704 +U 9794 ; WX 602 ; N male ; G 2705 +U 9795 ; WX 602 ; N uni2643 ; G 2706 +U 9796 ; WX 602 ; N uni2644 ; G 2707 +U 9797 ; WX 602 ; N uni2645 ; G 2708 +U 9798 ; WX 602 ; N uni2646 ; G 2709 +U 9799 ; WX 602 ; N uni2647 ; G 2710 +U 9800 ; WX 602 ; N uni2648 ; G 2711 +U 9801 ; WX 602 ; N uni2649 ; G 2712 +U 9802 ; WX 602 ; N uni264A ; G 2713 +U 9803 ; WX 602 ; N uni264B ; G 2714 +U 9804 ; WX 602 ; N uni264C ; G 2715 +U 9805 ; WX 602 ; N uni264D ; G 2716 +U 9806 ; WX 602 ; N uni264E ; G 2717 +U 9807 ; WX 602 ; N uni264F ; G 2718 +U 9808 ; WX 602 ; N uni2650 ; G 2719 +U 9809 ; WX 602 ; N uni2651 ; G 2720 +U 9810 ; WX 602 ; N uni2652 ; G 2721 +U 9811 ; WX 602 ; N uni2653 ; G 2722 +U 9812 ; WX 602 ; N uni2654 ; G 2723 +U 9813 ; WX 602 ; N uni2655 ; G 2724 +U 9814 ; WX 602 ; N uni2656 ; G 2725 +U 9815 ; WX 602 ; N uni2657 ; G 2726 +U 9816 ; WX 602 ; N uni2658 ; G 2727 +U 9817 ; WX 602 ; N uni2659 ; G 2728 +U 9818 ; WX 602 ; N uni265A ; G 2729 +U 9819 ; WX 602 ; N uni265B ; G 2730 +U 9820 ; WX 602 ; N uni265C ; G 2731 +U 9821 ; WX 602 ; N uni265D ; G 2732 +U 9822 ; WX 602 ; N uni265E ; G 2733 +U 9823 ; WX 602 ; N uni265F ; G 2734 +U 9824 ; WX 602 ; N spade ; G 2735 +U 9825 ; WX 602 ; N uni2661 ; G 2736 +U 9826 ; WX 602 ; N uni2662 ; G 2737 +U 9827 ; WX 602 ; N club ; G 2738 +U 9828 ; WX 602 ; N uni2664 ; G 2739 +U 9829 ; WX 602 ; N heart ; G 2740 +U 9830 ; WX 602 ; N diamond ; G 2741 +U 9831 ; WX 602 ; N uni2667 ; G 2742 +U 9832 ; WX 602 ; N uni2668 ; G 2743 +U 9833 ; WX 602 ; N uni2669 ; G 2744 +U 9834 ; WX 602 ; N musicalnote ; G 2745 +U 9835 ; WX 602 ; N musicalnotedbl ; G 2746 +U 9836 ; WX 602 ; N uni266C ; G 2747 +U 9837 ; WX 602 ; N uni266D ; G 2748 +U 9838 ; WX 602 ; N uni266E ; G 2749 +U 9839 ; WX 602 ; N uni266F ; G 2750 +U 9840 ; WX 602 ; N uni2670 ; G 2751 +U 9841 ; WX 602 ; N uni2671 ; G 2752 +U 9842 ; WX 602 ; N uni2672 ; G 2753 +U 9843 ; WX 602 ; N uni2673 ; G 2754 +U 9844 ; WX 602 ; N uni2674 ; G 2755 +U 9845 ; WX 602 ; N uni2675 ; G 2756 +U 9846 ; WX 602 ; N uni2676 ; G 2757 +U 9847 ; WX 602 ; N uni2677 ; G 2758 +U 9848 ; WX 602 ; N uni2678 ; G 2759 +U 9849 ; WX 602 ; N uni2679 ; G 2760 +U 9850 ; WX 602 ; N uni267A ; G 2761 +U 9851 ; WX 602 ; N uni267B ; G 2762 +U 9852 ; WX 602 ; N uni267C ; G 2763 +U 9853 ; WX 602 ; N uni267D ; G 2764 +U 9854 ; WX 602 ; N uni267E ; G 2765 +U 9855 ; WX 602 ; N uni267F ; G 2766 +U 9856 ; WX 602 ; N uni2680 ; G 2767 +U 9857 ; WX 602 ; N uni2681 ; G 2768 +U 9858 ; WX 602 ; N uni2682 ; G 2769 +U 9859 ; WX 602 ; N uni2683 ; G 2770 +U 9860 ; WX 602 ; N uni2684 ; G 2771 +U 9861 ; WX 602 ; N uni2685 ; G 2772 +U 9862 ; WX 602 ; N uni2686 ; G 2773 +U 9863 ; WX 602 ; N uni2687 ; G 2774 +U 9864 ; WX 602 ; N uni2688 ; G 2775 +U 9865 ; WX 602 ; N uni2689 ; G 2776 +U 9866 ; WX 602 ; N uni268A ; G 2777 +U 9867 ; WX 602 ; N uni268B ; G 2778 +U 9872 ; WX 602 ; N uni2690 ; G 2779 +U 9873 ; WX 602 ; N uni2691 ; G 2780 +U 9874 ; WX 602 ; N uni2692 ; G 2781 +U 9875 ; WX 602 ; N uni2693 ; G 2782 +U 9876 ; WX 602 ; N uni2694 ; G 2783 +U 9877 ; WX 602 ; N uni2695 ; G 2784 +U 9878 ; WX 602 ; N uni2696 ; G 2785 +U 9879 ; WX 602 ; N uni2697 ; G 2786 +U 9880 ; WX 602 ; N uni2698 ; G 2787 +U 9881 ; WX 602 ; N uni2699 ; G 2788 +U 9882 ; WX 602 ; N uni269A ; G 2789 +U 9883 ; WX 602 ; N uni269B ; G 2790 +U 9884 ; WX 602 ; N uni269C ; G 2791 +U 9888 ; WX 602 ; N uni26A0 ; G 2792 +U 9889 ; WX 602 ; N uni26A1 ; G 2793 +U 9904 ; WX 602 ; N uni26B0 ; G 2794 +U 9905 ; WX 602 ; N uni26B1 ; G 2795 +U 9985 ; WX 602 ; N uni2701 ; G 2796 +U 9986 ; WX 602 ; N uni2702 ; G 2797 +U 9987 ; WX 602 ; N uni2703 ; G 2798 +U 9988 ; WX 602 ; N uni2704 ; G 2799 +U 9990 ; WX 602 ; N uni2706 ; G 2800 +U 9991 ; WX 602 ; N uni2707 ; G 2801 +U 9992 ; WX 602 ; N uni2708 ; G 2802 +U 9993 ; WX 602 ; N uni2709 ; G 2803 +U 9996 ; WX 602 ; N uni270C ; G 2804 +U 9997 ; WX 602 ; N uni270D ; G 2805 +U 9998 ; WX 602 ; N uni270E ; G 2806 +U 9999 ; WX 602 ; N uni270F ; G 2807 +U 10000 ; WX 602 ; N uni2710 ; G 2808 +U 10001 ; WX 602 ; N uni2711 ; G 2809 +U 10002 ; WX 602 ; N uni2712 ; G 2810 +U 10003 ; WX 602 ; N uni2713 ; G 2811 +U 10004 ; WX 602 ; N uni2714 ; G 2812 +U 10005 ; WX 602 ; N uni2715 ; G 2813 +U 10006 ; WX 602 ; N uni2716 ; G 2814 +U 10007 ; WX 602 ; N uni2717 ; G 2815 +U 10008 ; WX 602 ; N uni2718 ; G 2816 +U 10009 ; WX 602 ; N uni2719 ; G 2817 +U 10010 ; WX 602 ; N uni271A ; G 2818 +U 10011 ; WX 602 ; N uni271B ; G 2819 +U 10012 ; WX 602 ; N uni271C ; G 2820 +U 10013 ; WX 602 ; N uni271D ; G 2821 +U 10014 ; WX 602 ; N uni271E ; G 2822 +U 10015 ; WX 602 ; N uni271F ; G 2823 +U 10016 ; WX 602 ; N uni2720 ; G 2824 +U 10017 ; WX 602 ; N uni2721 ; G 2825 +U 10018 ; WX 602 ; N uni2722 ; G 2826 +U 10019 ; WX 602 ; N uni2723 ; G 2827 +U 10020 ; WX 602 ; N uni2724 ; G 2828 +U 10021 ; WX 602 ; N uni2725 ; G 2829 +U 10022 ; WX 602 ; N uni2726 ; G 2830 +U 10023 ; WX 602 ; N uni2727 ; G 2831 +U 10025 ; WX 602 ; N uni2729 ; G 2832 +U 10026 ; WX 602 ; N uni272A ; G 2833 +U 10027 ; WX 602 ; N uni272B ; G 2834 +U 10028 ; WX 602 ; N uni272C ; G 2835 +U 10029 ; WX 602 ; N uni272D ; G 2836 +U 10030 ; WX 602 ; N uni272E ; G 2837 +U 10031 ; WX 602 ; N uni272F ; G 2838 +U 10032 ; WX 602 ; N uni2730 ; G 2839 +U 10033 ; WX 602 ; N uni2731 ; G 2840 +U 10034 ; WX 602 ; N uni2732 ; G 2841 +U 10035 ; WX 602 ; N uni2733 ; G 2842 +U 10036 ; WX 602 ; N uni2734 ; G 2843 +U 10037 ; WX 602 ; N uni2735 ; G 2844 +U 10038 ; WX 602 ; N uni2736 ; G 2845 +U 10039 ; WX 602 ; N uni2737 ; G 2846 +U 10040 ; WX 602 ; N uni2738 ; G 2847 +U 10041 ; WX 602 ; N uni2739 ; G 2848 +U 10042 ; WX 602 ; N uni273A ; G 2849 +U 10043 ; WX 602 ; N uni273B ; G 2850 +U 10044 ; WX 602 ; N uni273C ; G 2851 +U 10045 ; WX 602 ; N uni273D ; G 2852 +U 10046 ; WX 602 ; N uni273E ; G 2853 +U 10047 ; WX 602 ; N uni273F ; G 2854 +U 10048 ; WX 602 ; N uni2740 ; G 2855 +U 10049 ; WX 602 ; N uni2741 ; G 2856 +U 10050 ; WX 602 ; N uni2742 ; G 2857 +U 10051 ; WX 602 ; N uni2743 ; G 2858 +U 10052 ; WX 602 ; N uni2744 ; G 2859 +U 10053 ; WX 602 ; N uni2745 ; G 2860 +U 10054 ; WX 602 ; N uni2746 ; G 2861 +U 10055 ; WX 602 ; N uni2747 ; G 2862 +U 10056 ; WX 602 ; N uni2748 ; G 2863 +U 10057 ; WX 602 ; N uni2749 ; G 2864 +U 10058 ; WX 602 ; N uni274A ; G 2865 +U 10059 ; WX 602 ; N uni274B ; G 2866 +U 10061 ; WX 602 ; N uni274D ; G 2867 +U 10063 ; WX 602 ; N uni274F ; G 2868 +U 10064 ; WX 602 ; N uni2750 ; G 2869 +U 10065 ; WX 602 ; N uni2751 ; G 2870 +U 10066 ; WX 602 ; N uni2752 ; G 2871 +U 10070 ; WX 602 ; N uni2756 ; G 2872 +U 10072 ; WX 602 ; N uni2758 ; G 2873 +U 10073 ; WX 602 ; N uni2759 ; G 2874 +U 10074 ; WX 602 ; N uni275A ; G 2875 +U 10075 ; WX 602 ; N uni275B ; G 2876 +U 10076 ; WX 602 ; N uni275C ; G 2877 +U 10077 ; WX 602 ; N uni275D ; G 2878 +U 10078 ; WX 602 ; N uni275E ; G 2879 +U 10081 ; WX 602 ; N uni2761 ; G 2880 +U 10082 ; WX 602 ; N uni2762 ; G 2881 +U 10083 ; WX 602 ; N uni2763 ; G 2882 +U 10084 ; WX 602 ; N uni2764 ; G 2883 +U 10085 ; WX 602 ; N uni2765 ; G 2884 +U 10086 ; WX 602 ; N uni2766 ; G 2885 +U 10087 ; WX 602 ; N uni2767 ; G 2886 +U 10088 ; WX 602 ; N uni2768 ; G 2887 +U 10089 ; WX 602 ; N uni2769 ; G 2888 +U 10090 ; WX 602 ; N uni276A ; G 2889 +U 10091 ; WX 602 ; N uni276B ; G 2890 +U 10092 ; WX 602 ; N uni276C ; G 2891 +U 10093 ; WX 602 ; N uni276D ; G 2892 +U 10094 ; WX 602 ; N uni276E ; G 2893 +U 10095 ; WX 602 ; N uni276F ; G 2894 +U 10096 ; WX 602 ; N uni2770 ; G 2895 +U 10097 ; WX 602 ; N uni2771 ; G 2896 +U 10098 ; WX 602 ; N uni2772 ; G 2897 +U 10099 ; WX 602 ; N uni2773 ; G 2898 +U 10100 ; WX 602 ; N uni2774 ; G 2899 +U 10101 ; WX 602 ; N uni2775 ; G 2900 +U 10132 ; WX 602 ; N uni2794 ; G 2901 +U 10136 ; WX 602 ; N uni2798 ; G 2902 +U 10137 ; WX 602 ; N uni2799 ; G 2903 +U 10138 ; WX 602 ; N uni279A ; G 2904 +U 10139 ; WX 602 ; N uni279B ; G 2905 +U 10140 ; WX 602 ; N uni279C ; G 2906 +U 10141 ; WX 602 ; N uni279D ; G 2907 +U 10142 ; WX 602 ; N uni279E ; G 2908 +U 10143 ; WX 602 ; N uni279F ; G 2909 +U 10144 ; WX 602 ; N uni27A0 ; G 2910 +U 10145 ; WX 602 ; N uni27A1 ; G 2911 +U 10146 ; WX 602 ; N uni27A2 ; G 2912 +U 10147 ; WX 602 ; N uni27A3 ; G 2913 +U 10148 ; WX 602 ; N uni27A4 ; G 2914 +U 10149 ; WX 602 ; N uni27A5 ; G 2915 +U 10150 ; WX 602 ; N uni27A6 ; G 2916 +U 10151 ; WX 602 ; N uni27A7 ; G 2917 +U 10152 ; WX 602 ; N uni27A8 ; G 2918 +U 10153 ; WX 602 ; N uni27A9 ; G 2919 +U 10154 ; WX 602 ; N uni27AA ; G 2920 +U 10155 ; WX 602 ; N uni27AB ; G 2921 +U 10156 ; WX 602 ; N uni27AC ; G 2922 +U 10157 ; WX 602 ; N uni27AD ; G 2923 +U 10158 ; WX 602 ; N uni27AE ; G 2924 +U 10159 ; WX 602 ; N uni27AF ; G 2925 +U 10161 ; WX 602 ; N uni27B1 ; G 2926 +U 10162 ; WX 602 ; N uni27B2 ; G 2927 +U 10163 ; WX 602 ; N uni27B3 ; G 2928 +U 10164 ; WX 602 ; N uni27B4 ; G 2929 +U 10165 ; WX 602 ; N uni27B5 ; G 2930 +U 10166 ; WX 602 ; N uni27B6 ; G 2931 +U 10167 ; WX 602 ; N uni27B7 ; G 2932 +U 10168 ; WX 602 ; N uni27B8 ; G 2933 +U 10169 ; WX 602 ; N uni27B9 ; G 2934 +U 10170 ; WX 602 ; N uni27BA ; G 2935 +U 10171 ; WX 602 ; N uni27BB ; G 2936 +U 10172 ; WX 602 ; N uni27BC ; G 2937 +U 10173 ; WX 602 ; N uni27BD ; G 2938 +U 10174 ; WX 602 ; N uni27BE ; G 2939 +U 10178 ; WX 602 ; N uni27C2 ; G 2940 +U 10181 ; WX 602 ; N uni27C5 ; G 2941 +U 10182 ; WX 602 ; N uni27C6 ; G 2942 +U 10204 ; WX 602 ; N uni27DC ; G 2943 +U 10208 ; WX 602 ; N uni27E0 ; G 2944 +U 10214 ; WX 602 ; N uni27E6 ; G 2945 +U 10215 ; WX 602 ; N uni27E7 ; G 2946 +U 10216 ; WX 602 ; N uni27E8 ; G 2947 +U 10217 ; WX 602 ; N uni27E9 ; G 2948 +U 10218 ; WX 602 ; N uni27EA ; G 2949 +U 10219 ; WX 602 ; N uni27EB ; G 2950 +U 10229 ; WX 602 ; N uni27F5 ; G 2951 +U 10230 ; WX 602 ; N uni27F6 ; G 2952 +U 10231 ; WX 602 ; N uni27F7 ; G 2953 +U 10631 ; WX 602 ; N uni2987 ; G 2954 +U 10632 ; WX 602 ; N uni2988 ; G 2955 +U 10647 ; WX 602 ; N uni2997 ; G 2956 +U 10648 ; WX 602 ; N uni2998 ; G 2957 +U 10731 ; WX 602 ; N uni29EB ; G 2958 +U 10746 ; WX 602 ; N uni29FA ; G 2959 +U 10747 ; WX 602 ; N uni29FB ; G 2960 +U 10752 ; WX 602 ; N uni2A00 ; G 2961 +U 10799 ; WX 602 ; N uni2A2F ; G 2962 +U 10858 ; WX 602 ; N uni2A6A ; G 2963 +U 10859 ; WX 602 ; N uni2A6B ; G 2964 +U 11013 ; WX 602 ; N uni2B05 ; G 2965 +U 11014 ; WX 602 ; N uni2B06 ; G 2966 +U 11015 ; WX 602 ; N uni2B07 ; G 2967 +U 11016 ; WX 602 ; N uni2B08 ; G 2968 +U 11017 ; WX 602 ; N uni2B09 ; G 2969 +U 11018 ; WX 602 ; N uni2B0A ; G 2970 +U 11019 ; WX 602 ; N uni2B0B ; G 2971 +U 11020 ; WX 602 ; N uni2B0C ; G 2972 +U 11021 ; WX 602 ; N uni2B0D ; G 2973 +U 11026 ; WX 602 ; N uni2B12 ; G 2974 +U 11027 ; WX 602 ; N uni2B13 ; G 2975 +U 11028 ; WX 602 ; N uni2B14 ; G 2976 +U 11029 ; WX 602 ; N uni2B15 ; G 2977 +U 11030 ; WX 602 ; N uni2B16 ; G 2978 +U 11031 ; WX 602 ; N uni2B17 ; G 2979 +U 11032 ; WX 602 ; N uni2B18 ; G 2980 +U 11033 ; WX 602 ; N uni2B19 ; G 2981 +U 11034 ; WX 602 ; N uni2B1A ; G 2982 +U 11364 ; WX 602 ; N uni2C64 ; G 2983 +U 11373 ; WX 602 ; N uni2C6D ; G 2984 +U 11374 ; WX 602 ; N uni2C6E ; G 2985 +U 11375 ; WX 602 ; N uni2C6F ; G 2986 +U 11376 ; WX 602 ; N uni2C70 ; G 2987 +U 11381 ; WX 602 ; N uni2C75 ; G 2988 +U 11382 ; WX 602 ; N uni2C76 ; G 2989 +U 11383 ; WX 602 ; N uni2C77 ; G 2990 +U 11385 ; WX 602 ; N uni2C79 ; G 2991 +U 11386 ; WX 602 ; N uni2C7A ; G 2992 +U 11388 ; WX 602 ; N uni2C7C ; G 2993 +U 11389 ; WX 602 ; N uni2C7D ; G 2994 +U 11390 ; WX 602 ; N uni2C7E ; G 2995 +U 11391 ; WX 602 ; N uni2C7F ; G 2996 +U 11800 ; WX 602 ; N uni2E18 ; G 2997 +U 11807 ; WX 602 ; N uni2E1F ; G 2998 +U 11810 ; WX 602 ; N uni2E22 ; G 2999 +U 11811 ; WX 602 ; N uni2E23 ; G 3000 +U 11812 ; WX 602 ; N uni2E24 ; G 3001 +U 11813 ; WX 602 ; N uni2E25 ; G 3002 +U 11822 ; WX 602 ; N uni2E2E ; G 3003 +U 42760 ; WX 602 ; N uniA708 ; G 3004 +U 42761 ; WX 602 ; N uniA709 ; G 3005 +U 42762 ; WX 602 ; N uniA70A ; G 3006 +U 42763 ; WX 602 ; N uniA70B ; G 3007 +U 42764 ; WX 602 ; N uniA70C ; G 3008 +U 42765 ; WX 602 ; N uniA70D ; G 3009 +U 42766 ; WX 602 ; N uniA70E ; G 3010 +U 42767 ; WX 602 ; N uniA70F ; G 3011 +U 42768 ; WX 602 ; N uniA710 ; G 3012 +U 42769 ; WX 602 ; N uniA711 ; G 3013 +U 42770 ; WX 602 ; N uniA712 ; G 3014 +U 42771 ; WX 602 ; N uniA713 ; G 3015 +U 42772 ; WX 602 ; N uniA714 ; G 3016 +U 42773 ; WX 602 ; N uniA715 ; G 3017 +U 42774 ; WX 602 ; N uniA716 ; G 3018 +U 42779 ; WX 602 ; N uniA71B ; G 3019 +U 42780 ; WX 602 ; N uniA71C ; G 3020 +U 42781 ; WX 602 ; N uniA71D ; G 3021 +U 42782 ; WX 602 ; N uniA71E ; G 3022 +U 42783 ; WX 602 ; N uniA71F ; G 3023 +U 42786 ; WX 602 ; N uniA722 ; G 3024 +U 42787 ; WX 602 ; N uniA723 ; G 3025 +U 42788 ; WX 602 ; N uniA724 ; G 3026 +U 42789 ; WX 602 ; N uniA725 ; G 3027 +U 42790 ; WX 602 ; N uniA726 ; G 3028 +U 42791 ; WX 602 ; N uniA727 ; G 3029 +U 42889 ; WX 602 ; N uniA789 ; G 3030 +U 42890 ; WX 602 ; N uniA78A ; G 3031 +U 42891 ; WX 602 ; N uniA78B ; G 3032 +U 42892 ; WX 602 ; N uniA78C ; G 3033 +U 42893 ; WX 602 ; N uniA78D ; G 3034 +U 42894 ; WX 602 ; N uniA78E ; G 3035 +U 42896 ; WX 602 ; N uniA790 ; G 3036 +U 42897 ; WX 602 ; N uniA791 ; G 3037 +U 42922 ; WX 602 ; N uniA7AA ; G 3038 +U 43000 ; WX 602 ; N uniA7F8 ; G 3039 +U 43001 ; WX 602 ; N uniA7F9 ; G 3040 +U 63173 ; WX 602 ; N uniF6C5 ; G 3041 +U 64257 ; WX 602 ; N fi ; G 3042 +U 64258 ; WX 602 ; N fl ; G 3043 +U 64338 ; WX 602 ; N uniFB52 ; G 3044 +U 64339 ; WX 602 ; N uniFB53 ; G 3045 +U 64340 ; WX 602 ; N uniFB54 ; G 3046 +U 64341 ; WX 602 ; N uniFB55 ; G 3047 +U 64342 ; WX 602 ; N uniFB56 ; G 3048 +U 64343 ; WX 602 ; N uniFB57 ; G 3049 +U 64344 ; WX 602 ; N uniFB58 ; G 3050 +U 64345 ; WX 602 ; N uniFB59 ; G 3051 +U 64346 ; WX 602 ; N uniFB5A ; G 3052 +U 64347 ; WX 602 ; N uniFB5B ; G 3053 +U 64348 ; WX 602 ; N uniFB5C ; G 3054 +U 64349 ; WX 602 ; N uniFB5D ; G 3055 +U 64350 ; WX 602 ; N uniFB5E ; G 3056 +U 64351 ; WX 602 ; N uniFB5F ; G 3057 +U 64352 ; WX 602 ; N uniFB60 ; G 3058 +U 64353 ; WX 602 ; N uniFB61 ; G 3059 +U 64354 ; WX 602 ; N uniFB62 ; G 3060 +U 64355 ; WX 602 ; N uniFB63 ; G 3061 +U 64356 ; WX 602 ; N uniFB64 ; G 3062 +U 64357 ; WX 602 ; N uniFB65 ; G 3063 +U 64358 ; WX 602 ; N uniFB66 ; G 3064 +U 64359 ; WX 602 ; N uniFB67 ; G 3065 +U 64360 ; WX 602 ; N uniFB68 ; G 3066 +U 64361 ; WX 602 ; N uniFB69 ; G 3067 +U 64362 ; WX 602 ; N uniFB6A ; G 3068 +U 64363 ; WX 602 ; N uniFB6B ; G 3069 +U 64364 ; WX 602 ; N uniFB6C ; G 3070 +U 64365 ; WX 602 ; N uniFB6D ; G 3071 +U 64366 ; WX 602 ; N uniFB6E ; G 3072 +U 64367 ; WX 602 ; N uniFB6F ; G 3073 +U 64368 ; WX 602 ; N uniFB70 ; G 3074 +U 64369 ; WX 602 ; N uniFB71 ; G 3075 +U 64370 ; WX 602 ; N uniFB72 ; G 3076 +U 64371 ; WX 602 ; N uniFB73 ; G 3077 +U 64372 ; WX 602 ; N uniFB74 ; G 3078 +U 64373 ; WX 602 ; N uniFB75 ; G 3079 +U 64374 ; WX 602 ; N uniFB76 ; G 3080 +U 64375 ; WX 602 ; N uniFB77 ; G 3081 +U 64376 ; WX 602 ; N uniFB78 ; G 3082 +U 64377 ; WX 602 ; N uniFB79 ; G 3083 +U 64378 ; WX 602 ; N uniFB7A ; G 3084 +U 64379 ; WX 602 ; N uniFB7B ; G 3085 +U 64380 ; WX 602 ; N uniFB7C ; G 3086 +U 64381 ; WX 602 ; N uniFB7D ; G 3087 +U 64382 ; WX 602 ; N uniFB7E ; G 3088 +U 64383 ; WX 602 ; N uniFB7F ; G 3089 +U 64384 ; WX 602 ; N uniFB80 ; G 3090 +U 64385 ; WX 602 ; N uniFB81 ; G 3091 +U 64394 ; WX 602 ; N uniFB8A ; G 3092 +U 64395 ; WX 602 ; N uniFB8B ; G 3093 +U 64396 ; WX 602 ; N uniFB8C ; G 3094 +U 64397 ; WX 602 ; N uniFB8D ; G 3095 +U 64398 ; WX 602 ; N uniFB8E ; G 3096 +U 64399 ; WX 602 ; N uniFB8F ; G 3097 +U 64400 ; WX 602 ; N uniFB90 ; G 3098 +U 64401 ; WX 602 ; N uniFB91 ; G 3099 +U 64402 ; WX 602 ; N uniFB92 ; G 3100 +U 64403 ; WX 602 ; N uniFB93 ; G 3101 +U 64404 ; WX 602 ; N uniFB94 ; G 3102 +U 64405 ; WX 602 ; N uniFB95 ; G 3103 +U 64414 ; WX 602 ; N uniFB9E ; G 3104 +U 64415 ; WX 602 ; N uniFB9F ; G 3105 +U 64426 ; WX 602 ; N uniFBAA ; G 3106 +U 64427 ; WX 602 ; N uniFBAB ; G 3107 +U 64428 ; WX 602 ; N uniFBAC ; G 3108 +U 64429 ; WX 602 ; N uniFBAD ; G 3109 +U 64488 ; WX 602 ; N uniFBE8 ; G 3110 +U 64489 ; WX 602 ; N uniFBE9 ; G 3111 +U 64508 ; WX 602 ; N uniFBFC ; G 3112 +U 64509 ; WX 602 ; N uniFBFD ; G 3113 +U 64510 ; WX 602 ; N uniFBFE ; G 3114 +U 64511 ; WX 602 ; N uniFBFF ; G 3115 +U 65136 ; WX 602 ; N uniFE70 ; G 3116 +U 65137 ; WX 602 ; N uniFE71 ; G 3117 +U 65138 ; WX 602 ; N uniFE72 ; G 3118 +U 65139 ; WX 602 ; N uniFE73 ; G 3119 +U 65140 ; WX 602 ; N uniFE74 ; G 3120 +U 65142 ; WX 602 ; N uniFE76 ; G 3121 +U 65143 ; WX 602 ; N uniFE77 ; G 3122 +U 65144 ; WX 602 ; N uniFE78 ; G 3123 +U 65145 ; WX 602 ; N uniFE79 ; G 3124 +U 65146 ; WX 602 ; N uniFE7A ; G 3125 +U 65147 ; WX 602 ; N uniFE7B ; G 3126 +U 65148 ; WX 602 ; N uniFE7C ; G 3127 +U 65149 ; WX 602 ; N uniFE7D ; G 3128 +U 65150 ; WX 602 ; N uniFE7E ; G 3129 +U 65151 ; WX 602 ; N uniFE7F ; G 3130 +U 65152 ; WX 602 ; N uniFE80 ; G 3131 +U 65153 ; WX 602 ; N uniFE81 ; G 3132 +U 65154 ; WX 602 ; N uniFE82 ; G 3133 +U 65155 ; WX 602 ; N uniFE83 ; G 3134 +U 65156 ; WX 602 ; N uniFE84 ; G 3135 +U 65157 ; WX 602 ; N uniFE85 ; G 3136 +U 65158 ; WX 602 ; N uniFE86 ; G 3137 +U 65159 ; WX 602 ; N uniFE87 ; G 3138 +U 65160 ; WX 602 ; N uniFE88 ; G 3139 +U 65161 ; WX 602 ; N uniFE89 ; G 3140 +U 65162 ; WX 602 ; N uniFE8A ; G 3141 +U 65163 ; WX 602 ; N uniFE8B ; G 3142 +U 65164 ; WX 602 ; N uniFE8C ; G 3143 +U 65165 ; WX 602 ; N uniFE8D ; G 3144 +U 65166 ; WX 602 ; N uniFE8E ; G 3145 +U 65167 ; WX 602 ; N uniFE8F ; G 3146 +U 65168 ; WX 602 ; N uniFE90 ; G 3147 +U 65169 ; WX 602 ; N uniFE91 ; G 3148 +U 65170 ; WX 602 ; N uniFE92 ; G 3149 +U 65171 ; WX 602 ; N uniFE93 ; G 3150 +U 65172 ; WX 602 ; N uniFE94 ; G 3151 +U 65173 ; WX 602 ; N uniFE95 ; G 3152 +U 65174 ; WX 602 ; N uniFE96 ; G 3153 +U 65175 ; WX 602 ; N uniFE97 ; G 3154 +U 65176 ; WX 602 ; N uniFE98 ; G 3155 +U 65177 ; WX 602 ; N uniFE99 ; G 3156 +U 65178 ; WX 602 ; N uniFE9A ; G 3157 +U 65179 ; WX 602 ; N uniFE9B ; G 3158 +U 65180 ; WX 602 ; N uniFE9C ; G 3159 +U 65181 ; WX 602 ; N uniFE9D ; G 3160 +U 65182 ; WX 602 ; N uniFE9E ; G 3161 +U 65183 ; WX 602 ; N uniFE9F ; G 3162 +U 65184 ; WX 602 ; N uniFEA0 ; G 3163 +U 65185 ; WX 602 ; N uniFEA1 ; G 3164 +U 65186 ; WX 602 ; N uniFEA2 ; G 3165 +U 65187 ; WX 602 ; N uniFEA3 ; G 3166 +U 65188 ; WX 602 ; N uniFEA4 ; G 3167 +U 65189 ; WX 602 ; N uniFEA5 ; G 3168 +U 65190 ; WX 602 ; N uniFEA6 ; G 3169 +U 65191 ; WX 602 ; N uniFEA7 ; G 3170 +U 65192 ; WX 602 ; N uniFEA8 ; G 3171 +U 65193 ; WX 602 ; N uniFEA9 ; G 3172 +U 65194 ; WX 602 ; N uniFEAA ; G 3173 +U 65195 ; WX 602 ; N uniFEAB ; G 3174 +U 65196 ; WX 602 ; N uniFEAC ; G 3175 +U 65197 ; WX 602 ; N uniFEAD ; G 3176 +U 65198 ; WX 602 ; N uniFEAE ; G 3177 +U 65199 ; WX 602 ; N uniFEAF ; G 3178 +U 65200 ; WX 602 ; N uniFEB0 ; G 3179 +U 65201 ; WX 602 ; N uniFEB1 ; G 3180 +U 65202 ; WX 602 ; N uniFEB2 ; G 3181 +U 65203 ; WX 602 ; N uniFEB3 ; G 3182 +U 65204 ; WX 602 ; N uniFEB4 ; G 3183 +U 65205 ; WX 602 ; N uniFEB5 ; G 3184 +U 65206 ; WX 602 ; N uniFEB6 ; G 3185 +U 65207 ; WX 602 ; N uniFEB7 ; G 3186 +U 65208 ; WX 602 ; N uniFEB8 ; G 3187 +U 65209 ; WX 602 ; N uniFEB9 ; G 3188 +U 65210 ; WX 602 ; N uniFEBA ; G 3189 +U 65211 ; WX 602 ; N uniFEBB ; G 3190 +U 65212 ; WX 602 ; N uniFEBC ; G 3191 +U 65213 ; WX 602 ; N uniFEBD ; G 3192 +U 65214 ; WX 602 ; N uniFEBE ; G 3193 +U 65215 ; WX 602 ; N uniFEBF ; G 3194 +U 65216 ; WX 602 ; N uniFEC0 ; G 3195 +U 65217 ; WX 602 ; N uniFEC1 ; G 3196 +U 65218 ; WX 602 ; N uniFEC2 ; G 3197 +U 65219 ; WX 602 ; N uniFEC3 ; G 3198 +U 65220 ; WX 602 ; N uniFEC4 ; G 3199 +U 65221 ; WX 602 ; N uniFEC5 ; G 3200 +U 65222 ; WX 602 ; N uniFEC6 ; G 3201 +U 65223 ; WX 602 ; N uniFEC7 ; G 3202 +U 65224 ; WX 602 ; N uniFEC8 ; G 3203 +U 65225 ; WX 602 ; N uniFEC9 ; G 3204 +U 65226 ; WX 602 ; N uniFECA ; G 3205 +U 65227 ; WX 602 ; N uniFECB ; G 3206 +U 65228 ; WX 602 ; N uniFECC ; G 3207 +U 65229 ; WX 602 ; N uniFECD ; G 3208 +U 65230 ; WX 602 ; N uniFECE ; G 3209 +U 65231 ; WX 602 ; N uniFECF ; G 3210 +U 65232 ; WX 602 ; N uniFED0 ; G 3211 +U 65233 ; WX 602 ; N uniFED1 ; G 3212 +U 65234 ; WX 602 ; N uniFED2 ; G 3213 +U 65235 ; WX 602 ; N uniFED3 ; G 3214 +U 65236 ; WX 602 ; N uniFED4 ; G 3215 +U 65237 ; WX 602 ; N uniFED5 ; G 3216 +U 65238 ; WX 602 ; N uniFED6 ; G 3217 +U 65239 ; WX 602 ; N uniFED7 ; G 3218 +U 65240 ; WX 602 ; N uniFED8 ; G 3219 +U 65241 ; WX 602 ; N uniFED9 ; G 3220 +U 65242 ; WX 602 ; N uniFEDA ; G 3221 +U 65243 ; WX 602 ; N uniFEDB ; G 3222 +U 65244 ; WX 602 ; N uniFEDC ; G 3223 +U 65245 ; WX 602 ; N uniFEDD ; G 3224 +U 65246 ; WX 602 ; N uniFEDE ; G 3225 +U 65247 ; WX 602 ; N uniFEDF ; G 3226 +U 65248 ; WX 602 ; N uniFEE0 ; G 3227 +U 65249 ; WX 602 ; N uniFEE1 ; G 3228 +U 65250 ; WX 602 ; N uniFEE2 ; G 3229 +U 65251 ; WX 602 ; N uniFEE3 ; G 3230 +U 65252 ; WX 602 ; N uniFEE4 ; G 3231 +U 65253 ; WX 602 ; N uniFEE5 ; G 3232 +U 65254 ; WX 602 ; N uniFEE6 ; G 3233 +U 65255 ; WX 602 ; N uniFEE7 ; G 3234 +U 65256 ; WX 602 ; N uniFEE8 ; G 3235 +U 65257 ; WX 602 ; N uniFEE9 ; G 3236 +U 65258 ; WX 602 ; N uniFEEA ; G 3237 +U 65259 ; WX 602 ; N uniFEEB ; G 3238 +U 65260 ; WX 602 ; N uniFEEC ; G 3239 +U 65261 ; WX 602 ; N uniFEED ; G 3240 +U 65262 ; WX 602 ; N uniFEEE ; G 3241 +U 65263 ; WX 602 ; N uniFEEF ; G 3242 +U 65264 ; WX 602 ; N uniFEF0 ; G 3243 +U 65265 ; WX 602 ; N uniFEF1 ; G 3244 +U 65266 ; WX 602 ; N uniFEF2 ; G 3245 +U 65267 ; WX 602 ; N uniFEF3 ; G 3246 +U 65268 ; WX 602 ; N uniFEF4 ; G 3247 +U 65269 ; WX 602 ; N uniFEF5 ; G 3248 +U 65270 ; WX 602 ; N uniFEF6 ; G 3249 +U 65271 ; WX 602 ; N uniFEF7 ; G 3250 +U 65272 ; WX 602 ; N uniFEF8 ; G 3251 +U 65273 ; WX 602 ; N uniFEF9 ; G 3252 +U 65274 ; WX 602 ; N uniFEFA ; G 3253 +U 65275 ; WX 602 ; N uniFEFB ; G 3254 +U 65276 ; WX 602 ; N uniFEFC ; G 3255 +U 65279 ; WX 602 ; N uniFEFF ; G 3256 +U 65529 ; WX 602 ; N uniFFF9 ; G 3257 +U 65530 ; WX 602 ; N uniFFFA ; G 3258 +U 65531 ; WX 602 ; N uniFFFB ; G 3259 +U 65532 ; WX 602 ; N uniFFFC ; G 3260 +U 65533 ; WX 602 ; N uniFFFD ; G 3261 +EndCharMetrics +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..3bb755fa1eab7ac6d8a6ab65e565c5d281cde857 GIT binary patch literal 356088 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 IJ*3b70dp)e4FCWD literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ufm new file mode 100644 index 0000000..7420dab --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Bold.ufm @@ -0,0 +1,4013 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Serif +FontSubfamily Bold +UniqueID DejaVu Serif Bold +FullName DejaVu Serif Bold +Version Version 2.37 +PostScriptName DejaVuSerif-Bold +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +PreferredFamily DejaVu Serif +PreferredSubfamily Bold +Weight Bold +ItalicAngle 0 +IsFixedPitch false +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 939 +Descender -236 +FontBBox -836 -389 1854 1145 +StartCharMetrics 3506 +U 32 ; WX 348 ; N space ; G 3 +U 33 ; WX 439 ; N exclam ; G 4 +U 34 ; WX 521 ; N quotedbl ; G 5 +U 35 ; WX 838 ; N numbersign ; G 6 +U 36 ; WX 696 ; N dollar ; G 7 +U 37 ; WX 950 ; N percent ; G 8 +U 38 ; WX 903 ; N ampersand ; G 9 +U 39 ; WX 306 ; N quotesingle ; G 10 +U 40 ; WX 473 ; N parenleft ; G 11 +U 41 ; WX 473 ; N parenright ; G 12 +U 42 ; WX 523 ; N asterisk ; G 13 +U 43 ; WX 838 ; N plus ; G 14 +U 44 ; WX 348 ; N comma ; G 15 +U 45 ; WX 415 ; N hyphen ; G 16 +U 46 ; WX 348 ; N period ; G 17 +U 47 ; WX 365 ; N slash ; G 18 +U 48 ; WX 696 ; N zero ; G 19 +U 49 ; WX 696 ; N one ; G 20 +U 50 ; WX 696 ; N two ; G 21 +U 51 ; WX 696 ; N three ; G 22 +U 52 ; WX 696 ; N four ; G 23 +U 53 ; WX 696 ; N five ; G 24 +U 54 ; WX 696 ; N six ; G 25 +U 55 ; WX 696 ; N seven ; G 26 +U 56 ; WX 696 ; N eight ; G 27 +U 57 ; WX 696 ; N nine ; G 28 +U 58 ; WX 369 ; N colon ; G 29 +U 59 ; WX 369 ; N semicolon ; G 30 +U 60 ; WX 838 ; N less ; G 31 +U 61 ; WX 838 ; N equal ; G 32 +U 62 ; WX 838 ; N greater ; G 33 +U 63 ; WX 586 ; N question ; G 34 +U 64 ; WX 1000 ; N at ; G 35 +U 65 ; WX 776 ; N A ; G 36 +U 66 ; WX 845 ; N B ; G 37 +U 67 ; WX 796 ; N C ; G 38 +U 68 ; WX 867 ; N D ; G 39 +U 69 ; WX 762 ; N E ; G 40 +U 70 ; WX 710 ; N F ; G 41 +U 71 ; WX 854 ; N G ; G 42 +U 72 ; WX 945 ; N H ; G 43 +U 73 ; WX 468 ; N I ; G 44 +U 74 ; WX 473 ; N J ; G 45 +U 75 ; WX 869 ; N K ; G 46 +U 76 ; WX 703 ; N L ; G 47 +U 77 ; WX 1107 ; N M ; G 48 +U 78 ; WX 914 ; N N ; G 49 +U 79 ; WX 871 ; N O ; G 50 +U 80 ; WX 752 ; N P ; G 51 +U 81 ; WX 871 ; N Q ; G 52 +U 82 ; WX 831 ; N R ; G 53 +U 83 ; WX 722 ; N S ; G 54 +U 84 ; WX 744 ; N T ; G 55 +U 85 ; WX 872 ; N U ; G 56 +U 86 ; WX 776 ; N V ; G 57 +U 87 ; WX 1123 ; N W ; G 58 +U 88 ; WX 776 ; N X ; G 59 +U 89 ; WX 714 ; N Y ; G 60 +U 90 ; WX 730 ; N Z ; G 61 +U 91 ; WX 473 ; N bracketleft ; G 62 +U 92 ; WX 365 ; N backslash ; G 63 +U 93 ; WX 473 ; N bracketright ; G 64 +U 94 ; WX 838 ; N asciicircum ; G 65 +U 95 ; WX 500 ; N underscore ; G 66 +U 96 ; WX 500 ; N grave ; G 67 +U 97 ; WX 648 ; N a ; G 68 +U 98 ; WX 699 ; N b ; G 69 +U 99 ; WX 609 ; N c ; G 70 +U 100 ; WX 699 ; N d ; G 71 +U 101 ; WX 636 ; N e ; G 72 +U 102 ; WX 430 ; N f ; G 73 +U 103 ; WX 699 ; N g ; G 74 +U 104 ; WX 727 ; N h ; G 75 +U 105 ; WX 380 ; N i ; G 76 +U 106 ; WX 362 ; N j ; G 77 +U 107 ; WX 693 ; N k ; G 78 +U 108 ; WX 380 ; N l ; G 79 +U 109 ; WX 1058 ; N m ; G 80 +U 110 ; WX 727 ; N n ; G 81 +U 111 ; WX 667 ; N o ; G 82 +U 112 ; WX 699 ; N p ; G 83 +U 113 ; WX 699 ; N q ; G 84 +U 114 ; WX 527 ; N r ; G 85 +U 115 ; WX 563 ; N s ; G 86 +U 116 ; WX 462 ; N t ; G 87 +U 117 ; WX 727 ; N u ; G 88 +U 118 ; WX 581 ; N v ; G 89 +U 119 ; WX 861 ; N w ; G 90 +U 120 ; WX 596 ; N x ; G 91 +U 121 ; WX 581 ; N y ; G 92 +U 122 ; WX 568 ; N z ; G 93 +U 123 ; WX 643 ; N braceleft ; G 94 +U 124 ; WX 364 ; N bar ; G 95 +U 125 ; WX 643 ; N braceright ; G 96 +U 126 ; WX 838 ; N asciitilde ; G 97 +U 160 ; WX 348 ; N nbspace ; G 98 +U 161 ; WX 439 ; N exclamdown ; G 99 +U 162 ; WX 696 ; N cent ; G 100 +U 163 ; WX 696 ; N sterling ; G 101 +U 164 ; WX 636 ; N currency ; G 102 +U 165 ; WX 696 ; N yen ; G 103 +U 166 ; WX 364 ; N brokenbar ; G 104 +U 167 ; WX 523 ; N section ; G 105 +U 168 ; WX 500 ; N dieresis ; G 106 +U 169 ; WX 1000 ; N copyright ; G 107 +U 170 ; WX 487 ; N ordfeminine ; G 108 +U 171 ; WX 625 ; N guillemotleft ; G 109 +U 172 ; WX 838 ; N logicalnot ; G 110 +U 173 ; WX 415 ; N sfthyphen ; G 111 +U 174 ; WX 1000 ; N registered ; G 112 +U 175 ; WX 500 ; N macron ; G 113 +U 176 ; WX 500 ; N degree ; G 114 +U 177 ; WX 838 ; N plusminus ; G 115 +U 178 ; WX 438 ; N twosuperior ; G 116 +U 179 ; WX 438 ; N threesuperior ; G 117 +U 180 ; WX 500 ; N acute ; G 118 +U 181 ; WX 732 ; N mu ; G 119 +U 182 ; WX 636 ; N paragraph ; G 120 +U 183 ; WX 348 ; N periodcentered ; G 121 +U 184 ; WX 500 ; N cedilla ; G 122 +U 185 ; WX 438 ; N onesuperior ; G 123 +U 186 ; WX 500 ; N ordmasculine ; G 124 +U 187 ; WX 625 ; N guillemotright ; G 125 +U 188 ; WX 1043 ; N onequarter ; G 126 +U 189 ; WX 1043 ; N onehalf ; G 127 +U 190 ; WX 1043 ; N threequarters ; G 128 +U 191 ; WX 586 ; N questiondown ; G 129 +U 192 ; WX 776 ; N Agrave ; G 130 +U 193 ; WX 776 ; N Aacute ; G 131 +U 194 ; WX 776 ; N Acircumflex ; G 132 +U 195 ; WX 776 ; N Atilde ; G 133 +U 196 ; WX 776 ; N Adieresis ; G 134 +U 197 ; WX 776 ; N Aring ; G 135 +U 198 ; WX 1034 ; N AE ; G 136 +U 199 ; WX 796 ; N Ccedilla ; G 137 +U 200 ; WX 762 ; N Egrave ; G 138 +U 201 ; WX 762 ; N Eacute ; G 139 +U 202 ; WX 762 ; N Ecircumflex ; G 140 +U 203 ; WX 762 ; N Edieresis ; G 141 +U 204 ; WX 468 ; N Igrave ; G 142 +U 205 ; WX 468 ; N Iacute ; G 143 +U 206 ; WX 468 ; N Icircumflex ; G 144 +U 207 ; WX 468 ; N Idieresis ; G 145 +U 208 ; WX 874 ; N Eth ; G 146 +U 209 ; WX 914 ; N Ntilde ; G 147 +U 210 ; WX 871 ; N Ograve ; G 148 +U 211 ; WX 871 ; N Oacute ; G 149 +U 212 ; WX 871 ; N Ocircumflex ; G 150 +U 213 ; WX 871 ; N Otilde ; G 151 +U 214 ; WX 871 ; N Odieresis ; G 152 +U 215 ; WX 838 ; N multiply ; G 153 +U 216 ; WX 871 ; N Oslash ; G 154 +U 217 ; WX 872 ; N Ugrave ; G 155 +U 218 ; WX 872 ; N Uacute ; G 156 +U 219 ; WX 872 ; N Ucircumflex ; G 157 +U 220 ; WX 872 ; N Udieresis ; G 158 +U 221 ; WX 714 ; N Yacute ; G 159 +U 222 ; WX 757 ; N Thorn ; G 160 +U 223 ; WX 760 ; N germandbls ; G 161 +U 224 ; WX 648 ; N agrave ; G 162 +U 225 ; WX 648 ; N aacute ; G 163 +U 226 ; WX 648 ; N acircumflex ; G 164 +U 227 ; WX 648 ; N atilde ; G 165 +U 228 ; WX 648 ; N adieresis ; G 166 +U 229 ; WX 648 ; N aring ; G 167 +U 230 ; WX 975 ; N ae ; G 168 +U 231 ; WX 609 ; N ccedilla ; G 169 +U 232 ; WX 636 ; N egrave ; G 170 +U 233 ; WX 636 ; N eacute ; G 171 +U 234 ; WX 636 ; N ecircumflex ; G 172 +U 235 ; WX 636 ; N edieresis ; G 173 +U 236 ; WX 380 ; N igrave ; G 174 +U 237 ; WX 380 ; N iacute ; G 175 +U 238 ; WX 380 ; N icircumflex ; G 176 +U 239 ; WX 380 ; N idieresis ; G 177 +U 240 ; WX 667 ; N eth ; G 178 +U 241 ; WX 727 ; N ntilde ; G 179 +U 242 ; WX 667 ; N ograve ; G 180 +U 243 ; WX 667 ; N oacute ; G 181 +U 244 ; WX 667 ; N ocircumflex ; G 182 +U 245 ; WX 667 ; N otilde ; G 183 +U 246 ; WX 667 ; N odieresis ; G 184 +U 247 ; WX 838 ; N divide ; G 185 +U 248 ; WX 667 ; N oslash ; G 186 +U 249 ; WX 727 ; N ugrave ; G 187 +U 250 ; WX 727 ; N uacute ; G 188 +U 251 ; WX 727 ; N ucircumflex ; G 189 +U 252 ; WX 727 ; N udieresis ; G 190 +U 253 ; WX 581 ; N yacute ; G 191 +U 254 ; WX 699 ; N thorn ; G 192 +U 255 ; WX 581 ; N ydieresis ; G 193 +U 256 ; WX 776 ; N Amacron ; G 194 +U 257 ; WX 648 ; N amacron ; G 195 +U 258 ; WX 776 ; N Abreve ; G 196 +U 259 ; WX 648 ; N abreve ; G 197 +U 260 ; WX 776 ; N Aogonek ; G 198 +U 261 ; WX 648 ; N aogonek ; G 199 +U 262 ; WX 796 ; N Cacute ; G 200 +U 263 ; WX 609 ; N cacute ; G 201 +U 264 ; WX 796 ; N Ccircumflex ; G 202 +U 265 ; WX 609 ; N ccircumflex ; G 203 +U 266 ; WX 796 ; N Cdotaccent ; G 204 +U 267 ; WX 609 ; N cdotaccent ; G 205 +U 268 ; WX 796 ; N Ccaron ; G 206 +U 269 ; WX 609 ; N ccaron ; G 207 +U 270 ; WX 867 ; N Dcaron ; G 208 +U 271 ; WX 699 ; N dcaron ; G 209 +U 272 ; WX 874 ; N Dcroat ; G 210 +U 273 ; WX 699 ; N dmacron ; G 211 +U 274 ; WX 762 ; N Emacron ; G 212 +U 275 ; WX 636 ; N emacron ; G 213 +U 276 ; WX 762 ; N Ebreve ; G 214 +U 277 ; WX 636 ; N ebreve ; G 215 +U 278 ; WX 762 ; N Edotaccent ; G 216 +U 279 ; WX 636 ; N edotaccent ; G 217 +U 280 ; WX 762 ; N Eogonek ; G 218 +U 281 ; WX 636 ; N eogonek ; G 219 +U 282 ; WX 762 ; N Ecaron ; G 220 +U 283 ; WX 636 ; N ecaron ; G 221 +U 284 ; WX 854 ; N Gcircumflex ; G 222 +U 285 ; WX 699 ; N gcircumflex ; G 223 +U 286 ; WX 854 ; N Gbreve ; G 224 +U 287 ; WX 699 ; N gbreve ; G 225 +U 288 ; WX 854 ; N Gdotaccent ; G 226 +U 289 ; WX 699 ; N gdotaccent ; G 227 +U 290 ; WX 854 ; N Gcommaaccent ; G 228 +U 291 ; WX 699 ; N gcommaaccent ; G 229 +U 292 ; WX 945 ; N Hcircumflex ; G 230 +U 293 ; WX 727 ; N hcircumflex ; G 231 +U 294 ; WX 945 ; N Hbar ; G 232 +U 295 ; WX 727 ; N hbar ; G 233 +U 296 ; WX 468 ; N Itilde ; G 234 +U 297 ; WX 380 ; N itilde ; G 235 +U 298 ; WX 468 ; N Imacron ; G 236 +U 299 ; WX 380 ; N imacron ; G 237 +U 300 ; WX 468 ; N Ibreve ; G 238 +U 301 ; WX 380 ; N ibreve ; G 239 +U 302 ; WX 468 ; N Iogonek ; G 240 +U 303 ; WX 380 ; N iogonek ; G 241 +U 304 ; WX 468 ; N Idot ; G 242 +U 305 ; WX 380 ; N dotlessi ; G 243 +U 306 ; WX 942 ; N IJ ; G 244 +U 307 ; WX 751 ; N ij ; G 245 +U 308 ; WX 473 ; N Jcircumflex ; G 246 +U 309 ; WX 362 ; N jcircumflex ; G 247 +U 310 ; WX 869 ; N Kcommaaccent ; G 248 +U 311 ; WX 693 ; N kcommaaccent ; G 249 +U 312 ; WX 693 ; N kgreenlandic ; G 250 +U 313 ; WX 703 ; N Lacute ; G 251 +U 314 ; WX 380 ; N lacute ; G 252 +U 315 ; WX 703 ; N Lcommaaccent ; G 253 +U 316 ; WX 380 ; N lcommaaccent ; G 254 +U 317 ; WX 703 ; N Lcaron ; G 255 +U 318 ; WX 380 ; N lcaron ; G 256 +U 319 ; WX 703 ; N Ldot ; G 257 +U 320 ; WX 380 ; N ldot ; G 258 +U 321 ; WX 710 ; N Lslash ; G 259 +U 322 ; WX 385 ; N lslash ; G 260 +U 323 ; WX 914 ; N Nacute ; G 261 +U 324 ; WX 727 ; N nacute ; G 262 +U 325 ; WX 914 ; N Ncommaaccent ; G 263 +U 326 ; WX 727 ; N ncommaaccent ; G 264 +U 327 ; WX 914 ; N Ncaron ; G 265 +U 328 ; WX 727 ; N ncaron ; G 266 +U 329 ; WX 1008 ; N napostrophe ; G 267 +U 330 ; WX 872 ; N Eng ; G 268 +U 331 ; WX 727 ; N eng ; G 269 +U 332 ; WX 871 ; N Omacron ; G 270 +U 333 ; WX 667 ; N omacron ; G 271 +U 334 ; WX 871 ; N Obreve ; G 272 +U 335 ; WX 667 ; N obreve ; G 273 +U 336 ; WX 871 ; N Ohungarumlaut ; G 274 +U 337 ; WX 667 ; N ohungarumlaut ; G 275 +U 338 ; WX 1180 ; N OE ; G 276 +U 339 ; WX 1028 ; N oe ; G 277 +U 340 ; WX 831 ; N Racute ; G 278 +U 341 ; WX 527 ; N racute ; G 279 +U 342 ; WX 831 ; N Rcommaaccent ; G 280 +U 343 ; WX 527 ; N rcommaaccent ; G 281 +U 344 ; WX 831 ; N Rcaron ; G 282 +U 345 ; WX 527 ; N rcaron ; G 283 +U 346 ; WX 722 ; N Sacute ; G 284 +U 347 ; WX 563 ; N sacute ; G 285 +U 348 ; WX 722 ; N Scircumflex ; G 286 +U 349 ; WX 563 ; N scircumflex ; G 287 +U 350 ; WX 722 ; N Scedilla ; G 288 +U 351 ; WX 563 ; N scedilla ; G 289 +U 352 ; WX 722 ; N Scaron ; G 290 +U 353 ; WX 563 ; N scaron ; G 291 +U 354 ; WX 744 ; N Tcommaaccent ; G 292 +U 355 ; WX 462 ; N tcommaaccent ; G 293 +U 356 ; WX 744 ; N Tcaron ; G 294 +U 357 ; WX 462 ; N tcaron ; G 295 +U 358 ; WX 744 ; N Tbar ; G 296 +U 359 ; WX 462 ; N tbar ; G 297 +U 360 ; WX 872 ; N Utilde ; G 298 +U 361 ; WX 727 ; N utilde ; G 299 +U 362 ; WX 872 ; N Umacron ; G 300 +U 363 ; WX 727 ; N umacron ; G 301 +U 364 ; WX 872 ; N Ubreve ; G 302 +U 365 ; WX 727 ; N ubreve ; G 303 +U 366 ; WX 872 ; N Uring ; G 304 +U 367 ; WX 727 ; N uring ; G 305 +U 368 ; WX 872 ; N Uhungarumlaut ; G 306 +U 369 ; WX 727 ; N uhungarumlaut ; G 307 +U 370 ; WX 872 ; N Uogonek ; G 308 +U 371 ; WX 727 ; N uogonek ; G 309 +U 372 ; WX 1123 ; N Wcircumflex ; G 310 +U 373 ; WX 861 ; N wcircumflex ; G 311 +U 374 ; WX 714 ; N Ycircumflex ; G 312 +U 375 ; WX 581 ; N ycircumflex ; G 313 +U 376 ; WX 714 ; N Ydieresis ; G 314 +U 377 ; WX 730 ; N Zacute ; G 315 +U 378 ; WX 568 ; N zacute ; G 316 +U 379 ; WX 730 ; N Zdotaccent ; G 317 +U 380 ; WX 568 ; N zdotaccent ; G 318 +U 381 ; WX 730 ; N Zcaron ; G 319 +U 382 ; WX 568 ; N zcaron ; G 320 +U 383 ; WX 430 ; N longs ; G 321 +U 384 ; WX 699 ; N uni0180 ; G 322 +U 385 ; WX 845 ; N uni0181 ; G 323 +U 386 ; WX 854 ; N uni0182 ; G 324 +U 387 ; WX 699 ; N uni0183 ; G 325 +U 388 ; WX 854 ; N uni0184 ; G 326 +U 389 ; WX 699 ; N uni0185 ; G 327 +U 390 ; WX 796 ; N uni0186 ; G 328 +U 391 ; WX 796 ; N uni0187 ; G 329 +U 392 ; WX 609 ; N uni0188 ; G 330 +U 393 ; WX 874 ; N uni0189 ; G 331 +U 394 ; WX 867 ; N uni018A ; G 332 +U 395 ; WX 854 ; N uni018B ; G 333 +U 396 ; WX 699 ; N uni018C ; G 334 +U 397 ; WX 667 ; N uni018D ; G 335 +U 398 ; WX 762 ; N uni018E ; G 336 +U 399 ; WX 871 ; N uni018F ; G 337 +U 400 ; WX 721 ; N uni0190 ; G 338 +U 401 ; WX 710 ; N uni0191 ; G 339 +U 402 ; WX 430 ; N florin ; G 340 +U 403 ; WX 854 ; N uni0193 ; G 341 +U 404 ; WX 771 ; N uni0194 ; G 342 +U 405 ; WX 1043 ; N uni0195 ; G 343 +U 406 ; WX 468 ; N uni0196 ; G 344 +U 407 ; WX 468 ; N uni0197 ; G 345 +U 408 ; WX 869 ; N uni0198 ; G 346 +U 409 ; WX 693 ; N uni0199 ; G 347 +U 410 ; WX 380 ; N uni019A ; G 348 +U 411 ; WX 701 ; N uni019B ; G 349 +U 412 ; WX 1058 ; N uni019C ; G 350 +U 413 ; WX 914 ; N uni019D ; G 351 +U 414 ; WX 727 ; N uni019E ; G 352 +U 415 ; WX 871 ; N uni019F ; G 353 +U 416 ; WX 871 ; N Ohorn ; G 354 +U 417 ; WX 667 ; N ohorn ; G 355 +U 418 ; WX 1200 ; N uni01A2 ; G 356 +U 419 ; WX 943 ; N uni01A3 ; G 357 +U 420 ; WX 752 ; N uni01A4 ; G 358 +U 421 ; WX 699 ; N uni01A5 ; G 359 +U 422 ; WX 831 ; N uni01A6 ; G 360 +U 423 ; WX 722 ; N uni01A7 ; G 361 +U 424 ; WX 563 ; N uni01A8 ; G 362 +U 425 ; WX 707 ; N uni01A9 ; G 363 +U 426 ; WX 331 ; N uni01AA ; G 364 +U 427 ; WX 462 ; N uni01AB ; G 365 +U 428 ; WX 744 ; N uni01AC ; G 366 +U 429 ; WX 462 ; N uni01AD ; G 367 +U 430 ; WX 744 ; N uni01AE ; G 368 +U 431 ; WX 872 ; N Uhorn ; G 369 +U 432 ; WX 727 ; N uhorn ; G 370 +U 433 ; WX 890 ; N uni01B1 ; G 371 +U 434 ; WX 890 ; N uni01B2 ; G 372 +U 435 ; WX 714 ; N uni01B3 ; G 373 +U 436 ; WX 708 ; N uni01B4 ; G 374 +U 437 ; WX 730 ; N uni01B5 ; G 375 +U 438 ; WX 568 ; N uni01B6 ; G 376 +U 439 ; WX 657 ; N uni01B7 ; G 377 +U 440 ; WX 657 ; N uni01B8 ; G 378 +U 441 ; WX 657 ; N uni01B9 ; G 379 +U 442 ; WX 657 ; N uni01BA ; G 380 +U 443 ; WX 696 ; N uni01BB ; G 381 +U 444 ; WX 754 ; N uni01BC ; G 382 +U 445 ; WX 568 ; N uni01BD ; G 383 +U 446 ; WX 536 ; N uni01BE ; G 384 +U 447 ; WX 716 ; N uni01BF ; G 385 +U 448 ; WX 295 ; N uni01C0 ; G 386 +U 449 ; WX 492 ; N uni01C1 ; G 387 +U 450 ; WX 459 ; N uni01C2 ; G 388 +U 451 ; WX 295 ; N uni01C3 ; G 389 +U 452 ; WX 1597 ; N uni01C4 ; G 390 +U 453 ; WX 1435 ; N uni01C5 ; G 391 +U 454 ; WX 1267 ; N uni01C6 ; G 392 +U 455 ; WX 1176 ; N uni01C7 ; G 393 +U 456 ; WX 1065 ; N uni01C8 ; G 394 +U 457 ; WX 742 ; N uni01C9 ; G 395 +U 458 ; WX 1387 ; N uni01CA ; G 396 +U 459 ; WX 1276 ; N uni01CB ; G 397 +U 460 ; WX 1089 ; N uni01CC ; G 398 +U 461 ; WX 776 ; N uni01CD ; G 399 +U 462 ; WX 648 ; N uni01CE ; G 400 +U 463 ; WX 468 ; N uni01CF ; G 401 +U 464 ; WX 380 ; N uni01D0 ; G 402 +U 465 ; WX 871 ; N uni01D1 ; G 403 +U 466 ; WX 667 ; N uni01D2 ; G 404 +U 467 ; WX 872 ; N uni01D3 ; G 405 +U 468 ; WX 727 ; N uni01D4 ; G 406 +U 469 ; WX 872 ; N uni01D5 ; G 407 +U 470 ; WX 727 ; N uni01D6 ; G 408 +U 471 ; WX 872 ; N uni01D7 ; G 409 +U 472 ; WX 727 ; N uni01D8 ; G 410 +U 473 ; WX 872 ; N uni01D9 ; G 411 +U 474 ; WX 727 ; N uni01DA ; G 412 +U 475 ; WX 872 ; N uni01DB ; G 413 +U 476 ; WX 727 ; N uni01DC ; G 414 +U 477 ; WX 636 ; N uni01DD ; G 415 +U 478 ; WX 776 ; N uni01DE ; G 416 +U 479 ; WX 648 ; N uni01DF ; G 417 +U 480 ; WX 776 ; N uni01E0 ; G 418 +U 481 ; WX 648 ; N uni01E1 ; G 419 +U 482 ; WX 1034 ; N uni01E2 ; G 420 +U 483 ; WX 975 ; N uni01E3 ; G 421 +U 484 ; WX 896 ; N uni01E4 ; G 422 +U 485 ; WX 699 ; N uni01E5 ; G 423 +U 486 ; WX 854 ; N Gcaron ; G 424 +U 487 ; WX 699 ; N gcaron ; G 425 +U 488 ; WX 869 ; N uni01E8 ; G 426 +U 489 ; WX 693 ; N uni01E9 ; G 427 +U 490 ; WX 871 ; N uni01EA ; G 428 +U 491 ; WX 667 ; N uni01EB ; G 429 +U 492 ; WX 871 ; N uni01EC ; G 430 +U 493 ; WX 667 ; N uni01ED ; G 431 +U 494 ; WX 657 ; N uni01EE ; G 432 +U 495 ; WX 568 ; N uni01EF ; G 433 +U 496 ; WX 380 ; N uni01F0 ; G 434 +U 497 ; WX 1597 ; N uni01F1 ; G 435 +U 498 ; WX 1435 ; N uni01F2 ; G 436 +U 499 ; WX 1267 ; N uni01F3 ; G 437 +U 500 ; WX 854 ; N uni01F4 ; G 438 +U 501 ; WX 699 ; N uni01F5 ; G 439 +U 502 ; WX 1221 ; N uni01F6 ; G 440 +U 503 ; WX 787 ; N uni01F7 ; G 441 +U 504 ; WX 914 ; N uni01F8 ; G 442 +U 505 ; WX 727 ; N uni01F9 ; G 443 +U 506 ; WX 776 ; N Aringacute ; G 444 +U 507 ; WX 648 ; N aringacute ; G 445 +U 508 ; WX 1034 ; N AEacute ; G 446 +U 509 ; WX 975 ; N aeacute ; G 447 +U 510 ; WX 871 ; N Oslashacute ; G 448 +U 511 ; WX 667 ; N oslashacute ; G 449 +U 512 ; WX 776 ; N uni0200 ; G 450 +U 513 ; WX 648 ; N uni0201 ; G 451 +U 514 ; WX 776 ; N uni0202 ; G 452 +U 515 ; WX 648 ; N uni0203 ; G 453 +U 516 ; WX 762 ; N uni0204 ; G 454 +U 517 ; WX 636 ; N uni0205 ; G 455 +U 518 ; WX 762 ; N uni0206 ; G 456 +U 519 ; WX 636 ; N uni0207 ; G 457 +U 520 ; WX 468 ; N uni0208 ; G 458 +U 521 ; WX 380 ; N uni0209 ; G 459 +U 522 ; WX 468 ; N uni020A ; G 460 +U 523 ; WX 380 ; N uni020B ; G 461 +U 524 ; WX 871 ; N uni020C ; G 462 +U 525 ; WX 667 ; N uni020D ; G 463 +U 526 ; WX 871 ; N uni020E ; G 464 +U 527 ; WX 667 ; N uni020F ; G 465 +U 528 ; WX 831 ; N uni0210 ; G 466 +U 529 ; WX 527 ; N uni0211 ; G 467 +U 530 ; WX 831 ; N uni0212 ; G 468 +U 531 ; WX 527 ; N uni0213 ; G 469 +U 532 ; WX 872 ; N uni0214 ; G 470 +U 533 ; WX 727 ; N uni0215 ; G 471 +U 534 ; WX 872 ; N uni0216 ; G 472 +U 535 ; WX 727 ; N uni0217 ; G 473 +U 536 ; WX 722 ; N Scommaaccent ; G 474 +U 537 ; WX 563 ; N scommaaccent ; G 475 +U 538 ; WX 744 ; N uni021A ; G 476 +U 539 ; WX 462 ; N uni021B ; G 477 +U 540 ; WX 690 ; N uni021C ; G 478 +U 541 ; WX 607 ; N uni021D ; G 479 +U 542 ; WX 945 ; N uni021E ; G 480 +U 543 ; WX 727 ; N uni021F ; G 481 +U 544 ; WX 872 ; N uni0220 ; G 482 +U 545 ; WX 791 ; N uni0221 ; G 483 +U 546 ; WX 703 ; N uni0222 ; G 484 +U 547 ; WX 616 ; N uni0223 ; G 485 +U 548 ; WX 730 ; N uni0224 ; G 486 +U 549 ; WX 568 ; N uni0225 ; G 487 +U 550 ; WX 776 ; N uni0226 ; G 488 +U 551 ; WX 648 ; N uni0227 ; G 489 +U 552 ; WX 762 ; N uni0228 ; G 490 +U 553 ; WX 636 ; N uni0229 ; G 491 +U 554 ; WX 871 ; N uni022A ; G 492 +U 555 ; WX 667 ; N uni022B ; G 493 +U 556 ; WX 871 ; N uni022C ; G 494 +U 557 ; WX 667 ; N uni022D ; G 495 +U 558 ; WX 871 ; N uni022E ; G 496 +U 559 ; WX 667 ; N uni022F ; G 497 +U 560 ; WX 871 ; N uni0230 ; G 498 +U 561 ; WX 667 ; N uni0231 ; G 499 +U 562 ; WX 714 ; N uni0232 ; G 500 +U 563 ; WX 581 ; N uni0233 ; G 501 +U 564 ; WX 573 ; N uni0234 ; G 502 +U 565 ; WX 922 ; N uni0235 ; G 503 +U 566 ; WX 564 ; N uni0236 ; G 504 +U 567 ; WX 362 ; N dotlessj ; G 505 +U 568 ; WX 1031 ; N uni0238 ; G 506 +U 569 ; WX 1031 ; N uni0239 ; G 507 +U 570 ; WX 776 ; N uni023A ; G 508 +U 571 ; WX 796 ; N uni023B ; G 509 +U 572 ; WX 609 ; N uni023C ; G 510 +U 573 ; WX 703 ; N uni023D ; G 511 +U 574 ; WX 744 ; N uni023E ; G 512 +U 575 ; WX 563 ; N uni023F ; G 513 +U 576 ; WX 568 ; N uni0240 ; G 514 +U 577 ; WX 660 ; N uni0241 ; G 515 +U 578 ; WX 547 ; N uni0242 ; G 516 +U 579 ; WX 845 ; N uni0243 ; G 517 +U 580 ; WX 872 ; N uni0244 ; G 518 +U 581 ; WX 776 ; N uni0245 ; G 519 +U 582 ; WX 762 ; N uni0246 ; G 520 +U 583 ; WX 636 ; N uni0247 ; G 521 +U 584 ; WX 473 ; N uni0248 ; G 522 +U 585 ; WX 387 ; N uni0249 ; G 523 +U 586 ; WX 848 ; N uni024A ; G 524 +U 587 ; WX 699 ; N uni024B ; G 525 +U 588 ; WX 831 ; N uni024C ; G 526 +U 589 ; WX 527 ; N uni024D ; G 527 +U 590 ; WX 714 ; N uni024E ; G 528 +U 591 ; WX 581 ; N uni024F ; G 529 +U 592 ; WX 648 ; N uni0250 ; G 530 +U 593 ; WX 699 ; N uni0251 ; G 531 +U 594 ; WX 699 ; N uni0252 ; G 532 +U 595 ; WX 699 ; N uni0253 ; G 533 +U 596 ; WX 609 ; N uni0254 ; G 534 +U 597 ; WX 609 ; N uni0255 ; G 535 +U 598 ; WX 699 ; N uni0256 ; G 536 +U 599 ; WX 730 ; N uni0257 ; G 537 +U 600 ; WX 636 ; N uni0258 ; G 538 +U 601 ; WX 636 ; N uni0259 ; G 539 +U 602 ; WX 907 ; N uni025A ; G 540 +U 603 ; WX 608 ; N uni025B ; G 541 +U 604 ; WX 562 ; N uni025C ; G 542 +U 605 ; WX 907 ; N uni025D ; G 543 +U 606 ; WX 714 ; N uni025E ; G 544 +U 607 ; WX 387 ; N uni025F ; G 545 +U 608 ; WX 699 ; N uni0260 ; G 546 +U 609 ; WX 699 ; N uni0261 ; G 547 +U 610 ; WX 638 ; N uni0262 ; G 548 +U 611 ; WX 601 ; N uni0263 ; G 549 +U 612 ; WX 627 ; N uni0264 ; G 550 +U 613 ; WX 727 ; N uni0265 ; G 551 +U 614 ; WX 727 ; N uni0266 ; G 552 +U 615 ; WX 727 ; N uni0267 ; G 553 +U 616 ; WX 380 ; N uni0268 ; G 554 +U 617 ; WX 380 ; N uni0269 ; G 555 +U 618 ; WX 380 ; N uni026A ; G 556 +U 619 ; WX 409 ; N uni026B ; G 557 +U 620 ; WX 514 ; N uni026C ; G 558 +U 621 ; WX 380 ; N uni026D ; G 559 +U 622 ; WX 795 ; N uni026E ; G 560 +U 623 ; WX 1058 ; N uni026F ; G 561 +U 624 ; WX 1058 ; N uni0270 ; G 562 +U 625 ; WX 1058 ; N uni0271 ; G 563 +U 626 ; WX 727 ; N uni0272 ; G 564 +U 627 ; WX 727 ; N uni0273 ; G 565 +U 628 ; WX 712 ; N uni0274 ; G 566 +U 629 ; WX 667 ; N uni0275 ; G 567 +U 630 ; WX 1061 ; N uni0276 ; G 568 +U 631 ; WX 944 ; N uni0277 ; G 569 +U 632 ; WX 797 ; N uni0278 ; G 570 +U 633 ; WX 571 ; N uni0279 ; G 571 +U 634 ; WX 571 ; N uni027A ; G 572 +U 635 ; WX 571 ; N uni027B ; G 573 +U 636 ; WX 527 ; N uni027C ; G 574 +U 637 ; WX 527 ; N uni027D ; G 575 +U 638 ; WX 452 ; N uni027E ; G 576 +U 639 ; WX 487 ; N uni027F ; G 577 +U 640 ; WX 694 ; N uni0280 ; G 578 +U 641 ; WX 694 ; N uni0281 ; G 579 +U 642 ; WX 563 ; N uni0282 ; G 580 +U 643 ; WX 331 ; N uni0283 ; G 581 +U 644 ; WX 430 ; N uni0284 ; G 582 +U 645 ; WX 540 ; N uni0285 ; G 583 +U 646 ; WX 331 ; N uni0286 ; G 584 +U 647 ; WX 492 ; N uni0287 ; G 585 +U 648 ; WX 462 ; N uni0288 ; G 586 +U 649 ; WX 727 ; N uni0289 ; G 587 +U 650 ; WX 679 ; N uni028A ; G 588 +U 651 ; WX 694 ; N uni028B ; G 589 +U 652 ; WX 641 ; N uni028C ; G 590 +U 653 ; WX 907 ; N uni028D ; G 591 +U 654 ; WX 635 ; N uni028E ; G 592 +U 655 ; WX 727 ; N uni028F ; G 593 +U 656 ; WX 568 ; N uni0290 ; G 594 +U 657 ; WX 568 ; N uni0291 ; G 595 +U 658 ; WX 568 ; N uni0292 ; G 596 +U 659 ; WX 568 ; N uni0293 ; G 597 +U 660 ; WX 551 ; N uni0294 ; G 598 +U 661 ; WX 551 ; N uni0295 ; G 599 +U 662 ; WX 551 ; N uni0296 ; G 600 +U 663 ; WX 545 ; N uni0297 ; G 601 +U 664 ; WX 871 ; N uni0298 ; G 602 +U 665 ; WX 695 ; N uni0299 ; G 603 +U 666 ; WX 714 ; N uni029A ; G 604 +U 667 ; WX 689 ; N uni029B ; G 605 +U 668 ; WX 732 ; N uni029C ; G 606 +U 669 ; WX 384 ; N uni029D ; G 607 +U 670 ; WX 740 ; N uni029E ; G 608 +U 671 ; WX 617 ; N uni029F ; G 609 +U 672 ; WX 699 ; N uni02A0 ; G 610 +U 673 ; WX 551 ; N uni02A1 ; G 611 +U 674 ; WX 551 ; N uni02A2 ; G 612 +U 675 ; WX 1117 ; N uni02A3 ; G 613 +U 676 ; WX 1179 ; N uni02A4 ; G 614 +U 677 ; WX 1117 ; N uni02A5 ; G 615 +U 678 ; WX 938 ; N uni02A6 ; G 616 +U 679 ; WX 715 ; N uni02A7 ; G 617 +U 680 ; WX 946 ; N uni02A8 ; G 618 +U 681 ; WX 1039 ; N uni02A9 ; G 619 +U 682 ; WX 870 ; N uni02AA ; G 620 +U 683 ; WX 795 ; N uni02AB ; G 621 +U 684 ; WX 662 ; N uni02AC ; G 622 +U 685 ; WX 443 ; N uni02AD ; G 623 +U 686 ; WX 613 ; N uni02AE ; G 624 +U 687 ; WX 717 ; N uni02AF ; G 625 +U 688 ; WX 521 ; N uni02B0 ; G 626 +U 689 ; WX 519 ; N uni02B1 ; G 627 +U 690 ; WX 313 ; N uni02B2 ; G 628 +U 691 ; WX 414 ; N uni02B3 ; G 629 +U 692 ; WX 414 ; N uni02B4 ; G 630 +U 693 ; WX 480 ; N uni02B5 ; G 631 +U 694 ; WX 527 ; N uni02B6 ; G 632 +U 695 ; WX 662 ; N uni02B7 ; G 633 +U 696 ; WX 485 ; N uni02B8 ; G 634 +U 697 ; WX 302 ; N uni02B9 ; G 635 +U 698 ; WX 521 ; N uni02BA ; G 636 +U 699 ; WX 348 ; N uni02BB ; G 637 +U 700 ; WX 348 ; N uni02BC ; G 638 +U 701 ; WX 348 ; N uni02BD ; G 639 +U 702 ; WX 366 ; N uni02BE ; G 640 +U 703 ; WX 366 ; N uni02BF ; G 641 +U 704 ; WX 313 ; N uni02C0 ; G 642 +U 705 ; WX 313 ; N uni02C1 ; G 643 +U 706 ; WX 500 ; N uni02C2 ; G 644 +U 707 ; WX 500 ; N uni02C3 ; G 645 +U 708 ; WX 500 ; N uni02C4 ; G 646 +U 709 ; WX 500 ; N uni02C5 ; G 647 +U 710 ; WX 500 ; N circumflex ; G 648 +U 711 ; WX 500 ; N caron ; G 649 +U 712 ; WX 282 ; N uni02C8 ; G 650 +U 713 ; WX 500 ; N uni02C9 ; G 651 +U 714 ; WX 500 ; N uni02CA ; G 652 +U 715 ; WX 500 ; N uni02CB ; G 653 +U 716 ; WX 282 ; N uni02CC ; G 654 +U 717 ; WX 500 ; N uni02CD ; G 655 +U 720 ; WX 369 ; N uni02D0 ; G 656 +U 721 ; WX 369 ; N uni02D1 ; G 657 +U 722 ; WX 366 ; N uni02D2 ; G 658 +U 723 ; WX 366 ; N uni02D3 ; G 659 +U 726 ; WX 392 ; N uni02D6 ; G 660 +U 727 ; WX 392 ; N uni02D7 ; G 661 +U 728 ; WX 500 ; N breve ; G 662 +U 729 ; WX 500 ; N dotaccent ; G 663 +U 730 ; WX 500 ; N ring ; G 664 +U 731 ; WX 500 ; N ogonek ; G 665 +U 732 ; WX 500 ; N tilde ; G 666 +U 733 ; WX 500 ; N hungarumlaut ; G 667 +U 734 ; WX 417 ; N uni02DE ; G 668 +U 736 ; WX 378 ; N uni02E0 ; G 669 +U 737 ; WX 292 ; N uni02E1 ; G 670 +U 738 ; WX 395 ; N uni02E2 ; G 671 +U 739 ; WX 475 ; N uni02E3 ; G 672 +U 740 ; WX 313 ; N uni02E4 ; G 673 +U 741 ; WX 500 ; N uni02E5 ; G 674 +U 742 ; WX 500 ; N uni02E6 ; G 675 +U 743 ; WX 500 ; N uni02E7 ; G 676 +U 744 ; WX 500 ; N uni02E8 ; G 677 +U 745 ; WX 500 ; N uni02E9 ; G 678 +U 748 ; WX 500 ; N uni02EC ; G 679 +U 750 ; WX 553 ; N uni02EE ; G 680 +U 751 ; WX 500 ; N uni02EF ; G 681 +U 752 ; WX 500 ; N uni02F0 ; G 682 +U 755 ; WX 500 ; N uni02F3 ; G 683 +U 759 ; WX 500 ; N uni02F7 ; G 684 +U 768 ; WX 0 ; N gravecomb ; G 685 +U 769 ; WX 0 ; N acutecomb ; G 686 +U 770 ; WX 0 ; N uni0302 ; G 687 +U 771 ; WX 0 ; N tildecomb ; G 688 +U 772 ; WX 0 ; N uni0304 ; G 689 +U 773 ; WX 0 ; N uni0305 ; G 690 +U 774 ; WX 0 ; N uni0306 ; G 691 +U 775 ; WX 0 ; N uni0307 ; G 692 +U 776 ; WX 0 ; N uni0308 ; G 693 +U 777 ; WX 0 ; N hookabovecomb ; G 694 +U 778 ; WX 0 ; N uni030A ; G 695 +U 779 ; WX 0 ; N uni030B ; G 696 +U 780 ; WX 0 ; N uni030C ; G 697 +U 781 ; WX 0 ; N uni030D ; G 698 +U 782 ; WX 0 ; N uni030E ; G 699 +U 783 ; WX 0 ; N uni030F ; G 700 +U 784 ; WX 0 ; N uni0310 ; G 701 +U 785 ; WX 0 ; N uni0311 ; G 702 +U 786 ; WX 0 ; N uni0312 ; G 703 +U 787 ; WX 0 ; N uni0313 ; G 704 +U 788 ; WX 0 ; N uni0314 ; G 705 +U 789 ; WX 0 ; N uni0315 ; G 706 +U 790 ; WX 0 ; N uni0316 ; G 707 +U 791 ; WX 0 ; N uni0317 ; G 708 +U 792 ; WX 0 ; N uni0318 ; G 709 +U 793 ; WX 0 ; N uni0319 ; G 710 +U 794 ; WX 0 ; N uni031A ; G 711 +U 795 ; WX 0 ; N uni031B ; G 712 +U 796 ; WX 0 ; N uni031C ; G 713 +U 797 ; WX 0 ; N uni031D ; G 714 +U 798 ; WX 0 ; N uni031E ; G 715 +U 799 ; WX 0 ; N uni031F ; G 716 +U 800 ; WX 0 ; N uni0320 ; G 717 +U 801 ; WX 0 ; N uni0321 ; G 718 +U 802 ; WX 0 ; N uni0322 ; G 719 +U 803 ; WX 0 ; N dotbelowcomb ; G 720 +U 804 ; WX 0 ; N uni0324 ; G 721 +U 805 ; WX 0 ; N uni0325 ; G 722 +U 806 ; WX 0 ; N uni0326 ; G 723 +U 807 ; WX 0 ; N uni0327 ; G 724 +U 808 ; WX 0 ; N uni0328 ; G 725 +U 809 ; WX 0 ; N uni0329 ; G 726 +U 810 ; WX 0 ; N uni032A ; G 727 +U 811 ; WX 0 ; N uni032B ; G 728 +U 812 ; WX 0 ; N uni032C ; G 729 +U 813 ; WX 0 ; N uni032D ; G 730 +U 814 ; WX 0 ; N uni032E ; G 731 +U 815 ; WX 0 ; N uni032F ; G 732 +U 816 ; WX 0 ; N uni0330 ; G 733 +U 817 ; WX 0 ; N uni0331 ; G 734 +U 818 ; WX 0 ; N uni0332 ; G 735 +U 819 ; WX 0 ; N uni0333 ; G 736 +U 820 ; WX 0 ; N uni0334 ; G 737 +U 821 ; WX 0 ; N uni0335 ; G 738 +U 822 ; WX 0 ; N uni0336 ; G 739 +U 823 ; WX 0 ; N uni0337 ; G 740 +U 824 ; WX 0 ; N uni0338 ; G 741 +U 825 ; WX 0 ; N uni0339 ; G 742 +U 826 ; WX 0 ; N uni033A ; G 743 +U 827 ; WX 0 ; N uni033B ; G 744 +U 828 ; WX 0 ; N uni033C ; G 745 +U 829 ; WX 0 ; N uni033D ; G 746 +U 830 ; WX 0 ; N uni033E ; G 747 +U 831 ; WX 0 ; N uni033F ; G 748 +U 835 ; WX 0 ; N uni0343 ; G 749 +U 847 ; WX 0 ; N uni034F ; G 750 +U 856 ; WX 0 ; N uni0358 ; G 751 +U 864 ; WX 0 ; N uni0360 ; G 752 +U 865 ; WX 0 ; N uni0361 ; G 753 +U 880 ; WX 779 ; N uni0370 ; G 754 +U 881 ; WX 576 ; N uni0371 ; G 755 +U 882 ; WX 803 ; N uni0372 ; G 756 +U 883 ; WX 777 ; N uni0373 ; G 757 +U 884 ; WX 302 ; N uni0374 ; G 758 +U 885 ; WX 302 ; N uni0375 ; G 759 +U 886 ; WX 963 ; N uni0376 ; G 760 +U 887 ; WX 737 ; N uni0377 ; G 761 +U 890 ; WX 500 ; N uni037A ; G 762 +U 891 ; WX 609 ; N uni037B ; G 763 +U 892 ; WX 609 ; N uni037C ; G 764 +U 893 ; WX 609 ; N uni037D ; G 765 +U 894 ; WX 369 ; N uni037E ; G 766 +U 895 ; WX 473 ; N uni037F ; G 767 +U 900 ; WX 500 ; N tonos ; G 768 +U 901 ; WX 500 ; N dieresistonos ; G 769 +U 902 ; WX 776 ; N Alphatonos ; G 770 +U 903 ; WX 348 ; N anoteleia ; G 771 +U 904 ; WX 947 ; N Epsilontonos ; G 772 +U 905 ; WX 1118 ; N Etatonos ; G 773 +U 906 ; WX 662 ; N Iotatonos ; G 774 +U 908 ; WX 887 ; N Omicrontonos ; G 775 +U 910 ; WX 953 ; N Upsilontonos ; G 776 +U 911 ; WX 911 ; N Omegatonos ; G 777 +U 912 ; WX 484 ; N iotadieresistonos ; G 778 +U 913 ; WX 776 ; N Alpha ; G 779 +U 914 ; WX 845 ; N Beta ; G 780 +U 915 ; WX 710 ; N Gamma ; G 781 +U 916 ; WX 776 ; N uni0394 ; G 782 +U 917 ; WX 762 ; N Epsilon ; G 783 +U 918 ; WX 730 ; N Zeta ; G 784 +U 919 ; WX 945 ; N Eta ; G 785 +U 920 ; WX 871 ; N Theta ; G 786 +U 921 ; WX 468 ; N Iota ; G 787 +U 922 ; WX 869 ; N Kappa ; G 788 +U 923 ; WX 776 ; N Lambda ; G 789 +U 924 ; WX 1107 ; N Mu ; G 790 +U 925 ; WX 914 ; N Nu ; G 791 +U 926 ; WX 704 ; N Xi ; G 792 +U 927 ; WX 871 ; N Omicron ; G 793 +U 928 ; WX 944 ; N Pi ; G 794 +U 929 ; WX 752 ; N Rho ; G 795 +U 931 ; WX 707 ; N Sigma ; G 796 +U 932 ; WX 744 ; N Tau ; G 797 +U 933 ; WX 714 ; N Upsilon ; G 798 +U 934 ; WX 871 ; N Phi ; G 799 +U 935 ; WX 776 ; N Chi ; G 800 +U 936 ; WX 913 ; N Psi ; G 801 +U 937 ; WX 890 ; N Omega ; G 802 +U 938 ; WX 468 ; N Iotadieresis ; G 803 +U 939 ; WX 714 ; N Upsilondieresis ; G 804 +U 940 ; WX 770 ; N alphatonos ; G 805 +U 941 ; WX 608 ; N epsilontonos ; G 806 +U 942 ; WX 727 ; N etatonos ; G 807 +U 943 ; WX 484 ; N iotatonos ; G 808 +U 944 ; WX 694 ; N upsilondieresistonos ; G 809 +U 945 ; WX 770 ; N alpha ; G 810 +U 946 ; WX 664 ; N beta ; G 811 +U 947 ; WX 660 ; N gamma ; G 812 +U 948 ; WX 667 ; N delta ; G 813 +U 949 ; WX 608 ; N epsilon ; G 814 +U 950 ; WX 592 ; N zeta ; G 815 +U 951 ; WX 727 ; N eta ; G 816 +U 952 ; WX 667 ; N theta ; G 817 +U 953 ; WX 484 ; N iota ; G 818 +U 954 ; WX 750 ; N kappa ; G 819 +U 955 ; WX 701 ; N lambda ; G 820 +U 956 ; WX 732 ; N uni03BC ; G 821 +U 957 ; WX 694 ; N nu ; G 822 +U 958 ; WX 592 ; N xi ; G 823 +U 959 ; WX 667 ; N omicron ; G 824 +U 960 ; WX 732 ; N pi ; G 825 +U 961 ; WX 665 ; N rho ; G 826 +U 962 ; WX 609 ; N sigma1 ; G 827 +U 963 ; WX 737 ; N sigma ; G 828 +U 964 ; WX 673 ; N tau ; G 829 +U 965 ; WX 694 ; N upsilon ; G 830 +U 966 ; WX 905 ; N phi ; G 831 +U 967 ; WX 658 ; N chi ; G 832 +U 968 ; WX 941 ; N psi ; G 833 +U 969 ; WX 952 ; N omega ; G 834 +U 970 ; WX 484 ; N iotadieresis ; G 835 +U 971 ; WX 694 ; N upsilondieresis ; G 836 +U 972 ; WX 667 ; N omicrontonos ; G 837 +U 973 ; WX 694 ; N upsilontonos ; G 838 +U 974 ; WX 952 ; N omegatonos ; G 839 +U 975 ; WX 869 ; N uni03CF ; G 840 +U 976 ; WX 667 ; N uni03D0 ; G 841 +U 977 ; WX 849 ; N theta1 ; G 842 +U 978 ; WX 764 ; N Upsilon1 ; G 843 +U 979 ; WX 969 ; N uni03D3 ; G 844 +U 980 ; WX 764 ; N uni03D4 ; G 845 +U 981 ; WX 941 ; N phi1 ; G 846 +U 982 ; WX 952 ; N omega1 ; G 847 +U 983 ; WX 655 ; N uni03D7 ; G 848 +U 984 ; WX 871 ; N uni03D8 ; G 849 +U 985 ; WX 667 ; N uni03D9 ; G 850 +U 986 ; WX 796 ; N uni03DA ; G 851 +U 987 ; WX 609 ; N uni03DB ; G 852 +U 988 ; WX 710 ; N uni03DC ; G 853 +U 989 ; WX 527 ; N uni03DD ; G 854 +U 990 ; WX 590 ; N uni03DE ; G 855 +U 991 ; WX 660 ; N uni03DF ; G 856 +U 992 ; WX 796 ; N uni03E0 ; G 857 +U 993 ; WX 667 ; N uni03E1 ; G 858 +U 1008 ; WX 655 ; N uni03F0 ; G 859 +U 1009 ; WX 665 ; N uni03F1 ; G 860 +U 1010 ; WX 609 ; N uni03F2 ; G 861 +U 1011 ; WX 362 ; N uni03F3 ; G 862 +U 1012 ; WX 871 ; N uni03F4 ; G 863 +U 1013 ; WX 609 ; N uni03F5 ; G 864 +U 1014 ; WX 609 ; N uni03F6 ; G 865 +U 1015 ; WX 757 ; N uni03F7 ; G 866 +U 1016 ; WX 699 ; N uni03F8 ; G 867 +U 1017 ; WX 796 ; N uni03F9 ; G 868 +U 1018 ; WX 1107 ; N uni03FA ; G 869 +U 1019 ; WX 860 ; N uni03FB ; G 870 +U 1020 ; WX 692 ; N uni03FC ; G 871 +U 1021 ; WX 796 ; N uni03FD ; G 872 +U 1022 ; WX 796 ; N uni03FE ; G 873 +U 1023 ; WX 796 ; N uni03FF ; G 874 +U 1024 ; WX 762 ; N uni0400 ; G 875 +U 1025 ; WX 762 ; N uni0401 ; G 876 +U 1026 ; WX 901 ; N uni0402 ; G 877 +U 1027 ; WX 690 ; N uni0403 ; G 878 +U 1028 ; WX 795 ; N uni0404 ; G 879 +U 1029 ; WX 722 ; N uni0405 ; G 880 +U 1030 ; WX 468 ; N uni0406 ; G 881 +U 1031 ; WX 468 ; N uni0407 ; G 882 +U 1032 ; WX 473 ; N uni0408 ; G 883 +U 1033 ; WX 1202 ; N uni0409 ; G 884 +U 1034 ; WX 1262 ; N uni040A ; G 885 +U 1035 ; WX 963 ; N uni040B ; G 886 +U 1036 ; WX 910 ; N uni040C ; G 887 +U 1037 ; WX 945 ; N uni040D ; G 888 +U 1038 ; WX 812 ; N uni040E ; G 889 +U 1039 ; WX 945 ; N uni040F ; G 890 +U 1040 ; WX 814 ; N uni0410 ; G 891 +U 1041 ; WX 854 ; N uni0411 ; G 892 +U 1042 ; WX 845 ; N uni0412 ; G 893 +U 1043 ; WX 690 ; N uni0413 ; G 894 +U 1044 ; WX 889 ; N uni0414 ; G 895 +U 1045 ; WX 762 ; N uni0415 ; G 896 +U 1046 ; WX 1312 ; N uni0416 ; G 897 +U 1047 ; WX 721 ; N uni0417 ; G 898 +U 1048 ; WX 945 ; N uni0418 ; G 899 +U 1049 ; WX 945 ; N uni0419 ; G 900 +U 1050 ; WX 910 ; N uni041A ; G 901 +U 1051 ; WX 884 ; N uni041B ; G 902 +U 1052 ; WX 1107 ; N uni041C ; G 903 +U 1053 ; WX 945 ; N uni041D ; G 904 +U 1054 ; WX 871 ; N uni041E ; G 905 +U 1055 ; WX 944 ; N uni041F ; G 906 +U 1056 ; WX 752 ; N uni0420 ; G 907 +U 1057 ; WX 796 ; N uni0421 ; G 908 +U 1058 ; WX 744 ; N uni0422 ; G 909 +U 1059 ; WX 812 ; N uni0423 ; G 910 +U 1060 ; WX 949 ; N uni0424 ; G 911 +U 1061 ; WX 776 ; N uni0425 ; G 912 +U 1062 ; WX 966 ; N uni0426 ; G 913 +U 1063 ; WX 913 ; N uni0427 ; G 914 +U 1064 ; WX 1268 ; N uni0428 ; G 915 +U 1065 ; WX 1293 ; N uni0429 ; G 916 +U 1066 ; WX 957 ; N uni042A ; G 917 +U 1067 ; WX 1202 ; N uni042B ; G 918 +U 1068 ; WX 825 ; N uni042C ; G 919 +U 1069 ; WX 795 ; N uni042D ; G 920 +U 1070 ; WX 1287 ; N uni042E ; G 921 +U 1071 ; WX 882 ; N uni042F ; G 922 +U 1072 ; WX 648 ; N uni0430 ; G 923 +U 1073 ; WX 667 ; N uni0431 ; G 924 +U 1074 ; WX 695 ; N uni0432 ; G 925 +U 1075 ; WX 613 ; N uni0433 ; G 926 +U 1076 ; WX 667 ; N uni0434 ; G 927 +U 1077 ; WX 636 ; N uni0435 ; G 928 +U 1078 ; WX 1010 ; N uni0436 ; G 929 +U 1079 ; WX 638 ; N uni0437 ; G 930 +U 1080 ; WX 742 ; N uni0438 ; G 931 +U 1081 ; WX 742 ; N uni0439 ; G 932 +U 1082 ; WX 722 ; N uni043A ; G 933 +U 1083 ; WX 705 ; N uni043B ; G 934 +U 1084 ; WX 869 ; N uni043C ; G 935 +U 1085 ; WX 732 ; N uni043D ; G 936 +U 1086 ; WX 667 ; N uni043E ; G 937 +U 1087 ; WX 732 ; N uni043F ; G 938 +U 1088 ; WX 699 ; N uni0440 ; G 939 +U 1089 ; WX 609 ; N uni0441 ; G 940 +U 1090 ; WX 620 ; N uni0442 ; G 941 +U 1091 ; WX 640 ; N uni0443 ; G 942 +U 1092 ; WX 902 ; N uni0444 ; G 943 +U 1093 ; WX 596 ; N uni0445 ; G 944 +U 1094 ; WX 739 ; N uni0446 ; G 945 +U 1095 ; WX 732 ; N uni0447 ; G 946 +U 1096 ; WX 1075 ; N uni0448 ; G 947 +U 1097 ; WX 1082 ; N uni0449 ; G 948 +U 1098 ; WX 767 ; N uni044A ; G 949 +U 1099 ; WX 1002 ; N uni044B ; G 950 +U 1100 ; WX 679 ; N uni044C ; G 951 +U 1101 ; WX 609 ; N uni044D ; G 952 +U 1102 ; WX 1025 ; N uni044E ; G 953 +U 1103 ; WX 739 ; N uni044F ; G 954 +U 1104 ; WX 636 ; N uni0450 ; G 955 +U 1105 ; WX 636 ; N uni0451 ; G 956 +U 1106 ; WX 719 ; N uni0452 ; G 957 +U 1107 ; WX 613 ; N uni0453 ; G 958 +U 1108 ; WX 609 ; N uni0454 ; G 959 +U 1109 ; WX 563 ; N uni0455 ; G 960 +U 1110 ; WX 380 ; N uni0456 ; G 961 +U 1111 ; WX 380 ; N uni0457 ; G 962 +U 1112 ; WX 362 ; N uni0458 ; G 963 +U 1113 ; WX 988 ; N uni0459 ; G 964 +U 1114 ; WX 1015 ; N uni045A ; G 965 +U 1115 ; WX 727 ; N uni045B ; G 966 +U 1116 ; WX 722 ; N uni045C ; G 967 +U 1117 ; WX 742 ; N uni045D ; G 968 +U 1118 ; WX 640 ; N uni045E ; G 969 +U 1119 ; WX 732 ; N uni045F ; G 970 +U 1122 ; WX 880 ; N uni0462 ; G 971 +U 1123 ; WX 703 ; N uni0463 ; G 972 +U 1124 ; WX 1195 ; N uni0464 ; G 973 +U 1125 ; WX 963 ; N uni0465 ; G 974 +U 1130 ; WX 1312 ; N uni046A ; G 975 +U 1131 ; WX 1010 ; N uni046B ; G 976 +U 1132 ; WX 1630 ; N uni046C ; G 977 +U 1133 ; WX 1297 ; N uni046D ; G 978 +U 1136 ; WX 1096 ; N uni0470 ; G 979 +U 1137 ; WX 1105 ; N uni0471 ; G 980 +U 1138 ; WX 871 ; N uni0472 ; G 981 +U 1139 ; WX 652 ; N uni0473 ; G 982 +U 1140 ; WX 916 ; N uni0474 ; G 983 +U 1141 ; WX 749 ; N uni0475 ; G 984 +U 1142 ; WX 916 ; N uni0476 ; G 985 +U 1143 ; WX 749 ; N uni0477 ; G 986 +U 1164 ; WX 846 ; N uni048C ; G 987 +U 1165 ; WX 673 ; N uni048D ; G 988 +U 1168 ; WX 700 ; N uni0490 ; G 989 +U 1169 ; WX 618 ; N uni0491 ; G 990 +U 1170 ; WX 690 ; N uni0492 ; G 991 +U 1171 ; WX 613 ; N uni0493 ; G 992 +U 1172 ; WX 868 ; N uni0494 ; G 993 +U 1173 ; WX 716 ; N uni0495 ; G 994 +U 1174 ; WX 1312 ; N uni0496 ; G 995 +U 1175 ; WX 1010 ; N uni0497 ; G 996 +U 1176 ; WX 721 ; N uni0498 ; G 997 +U 1177 ; WX 638 ; N uni0499 ; G 998 +U 1178 ; WX 947 ; N uni049A ; G 999 +U 1179 ; WX 744 ; N uni049B ; G 1000 +U 1182 ; WX 910 ; N uni049E ; G 1001 +U 1183 ; WX 722 ; N uni049F ; G 1002 +U 1184 ; WX 1041 ; N uni04A0 ; G 1003 +U 1185 ; WX 827 ; N uni04A1 ; G 1004 +U 1186 ; WX 966 ; N uni04A2 ; G 1005 +U 1187 ; WX 739 ; N uni04A3 ; G 1006 +U 1188 ; WX 1167 ; N uni04A4 ; G 1007 +U 1189 ; WX 956 ; N uni04A5 ; G 1008 +U 1190 ; WX 1345 ; N uni04A6 ; G 1009 +U 1191 ; WX 1059 ; N uni04A7 ; G 1010 +U 1194 ; WX 796 ; N uni04AA ; G 1011 +U 1195 ; WX 609 ; N uni04AB ; G 1012 +U 1196 ; WX 744 ; N uni04AC ; G 1013 +U 1197 ; WX 620 ; N uni04AD ; G 1014 +U 1198 ; WX 714 ; N uni04AE ; G 1015 +U 1199 ; WX 581 ; N uni04AF ; G 1016 +U 1200 ; WX 714 ; N uni04B0 ; G 1017 +U 1201 ; WX 581 ; N uni04B1 ; G 1018 +U 1202 ; WX 866 ; N uni04B2 ; G 1019 +U 1203 ; WX 649 ; N uni04B3 ; G 1020 +U 1204 ; WX 1022 ; N uni04B4 ; G 1021 +U 1205 ; WX 807 ; N uni04B5 ; G 1022 +U 1206 ; WX 928 ; N uni04B6 ; G 1023 +U 1207 ; WX 739 ; N uni04B7 ; G 1024 +U 1210 ; WX 910 ; N uni04BA ; G 1025 +U 1211 ; WX 727 ; N uni04BB ; G 1026 +U 1216 ; WX 468 ; N uni04C0 ; G 1027 +U 1217 ; WX 1312 ; N uni04C1 ; G 1028 +U 1218 ; WX 1010 ; N uni04C2 ; G 1029 +U 1219 ; WX 869 ; N uni04C3 ; G 1030 +U 1220 ; WX 693 ; N uni04C4 ; G 1031 +U 1223 ; WX 945 ; N uni04C7 ; G 1032 +U 1224 ; WX 732 ; N uni04C8 ; G 1033 +U 1227 ; WX 913 ; N uni04CB ; G 1034 +U 1228 ; WX 732 ; N uni04CC ; G 1035 +U 1231 ; WX 380 ; N uni04CF ; G 1036 +U 1232 ; WX 814 ; N uni04D0 ; G 1037 +U 1233 ; WX 648 ; N uni04D1 ; G 1038 +U 1234 ; WX 814 ; N uni04D2 ; G 1039 +U 1235 ; WX 648 ; N uni04D3 ; G 1040 +U 1236 ; WX 1034 ; N uni04D4 ; G 1041 +U 1237 ; WX 975 ; N uni04D5 ; G 1042 +U 1238 ; WX 762 ; N uni04D6 ; G 1043 +U 1239 ; WX 636 ; N uni04D7 ; G 1044 +U 1240 ; WX 871 ; N uni04D8 ; G 1045 +U 1241 ; WX 636 ; N uni04D9 ; G 1046 +U 1242 ; WX 871 ; N uni04DA ; G 1047 +U 1243 ; WX 636 ; N uni04DB ; G 1048 +U 1244 ; WX 1312 ; N uni04DC ; G 1049 +U 1245 ; WX 1010 ; N uni04DD ; G 1050 +U 1246 ; WX 721 ; N uni04DE ; G 1051 +U 1247 ; WX 638 ; N uni04DF ; G 1052 +U 1248 ; WX 657 ; N uni04E0 ; G 1053 +U 1249 ; WX 568 ; N uni04E1 ; G 1054 +U 1250 ; WX 945 ; N uni04E2 ; G 1055 +U 1251 ; WX 742 ; N uni04E3 ; G 1056 +U 1252 ; WX 945 ; N uni04E4 ; G 1057 +U 1253 ; WX 742 ; N uni04E5 ; G 1058 +U 1254 ; WX 871 ; N uni04E6 ; G 1059 +U 1255 ; WX 667 ; N uni04E7 ; G 1060 +U 1256 ; WX 871 ; N uni04E8 ; G 1061 +U 1257 ; WX 667 ; N uni04E9 ; G 1062 +U 1258 ; WX 871 ; N uni04EA ; G 1063 +U 1259 ; WX 667 ; N uni04EB ; G 1064 +U 1260 ; WX 795 ; N uni04EC ; G 1065 +U 1261 ; WX 609 ; N uni04ED ; G 1066 +U 1262 ; WX 812 ; N uni04EE ; G 1067 +U 1263 ; WX 640 ; N uni04EF ; G 1068 +U 1264 ; WX 812 ; N uni04F0 ; G 1069 +U 1265 ; WX 640 ; N uni04F1 ; G 1070 +U 1266 ; WX 812 ; N uni04F2 ; G 1071 +U 1267 ; WX 640 ; N uni04F3 ; G 1072 +U 1268 ; WX 913 ; N uni04F4 ; G 1073 +U 1269 ; WX 732 ; N uni04F5 ; G 1074 +U 1270 ; WX 690 ; N uni04F6 ; G 1075 +U 1271 ; WX 613 ; N uni04F7 ; G 1076 +U 1272 ; WX 1202 ; N uni04F8 ; G 1077 +U 1273 ; WX 1002 ; N uni04F9 ; G 1078 +U 1296 ; WX 721 ; N uni0510 ; G 1079 +U 1297 ; WX 638 ; N uni0511 ; G 1080 +U 1298 ; WX 884 ; N uni0512 ; G 1081 +U 1299 ; WX 705 ; N uni0513 ; G 1082 +U 1300 ; WX 1248 ; N uni0514 ; G 1083 +U 1301 ; WX 945 ; N uni0515 ; G 1084 +U 1306 ; WX 820 ; N uni051A ; G 1085 +U 1307 ; WX 640 ; N uni051B ; G 1086 +U 1308 ; WX 1028 ; N uni051C ; G 1087 +U 1309 ; WX 856 ; N uni051D ; G 1088 +U 1329 ; WX 942 ; N uni0531 ; G 1089 +U 1330 ; WX 832 ; N uni0532 ; G 1090 +U 1331 ; WX 894 ; N uni0533 ; G 1091 +U 1332 ; WX 909 ; N uni0534 ; G 1092 +U 1333 ; WX 822 ; N uni0535 ; G 1093 +U 1334 ; WX 821 ; N uni0536 ; G 1094 +U 1335 ; WX 747 ; N uni0537 ; G 1095 +U 1336 ; WX 832 ; N uni0538 ; G 1096 +U 1337 ; WX 1125 ; N uni0539 ; G 1097 +U 1338 ; WX 894 ; N uni053A ; G 1098 +U 1339 ; WX 803 ; N uni053B ; G 1099 +U 1340 ; WX 722 ; N uni053C ; G 1100 +U 1341 ; WX 1188 ; N uni053D ; G 1101 +U 1342 ; WX 887 ; N uni053E ; G 1102 +U 1343 ; WX 842 ; N uni053F ; G 1103 +U 1344 ; WX 737 ; N uni0540 ; G 1104 +U 1345 ; WX 863 ; N uni0541 ; G 1105 +U 1346 ; WX 918 ; N uni0542 ; G 1106 +U 1347 ; WX 851 ; N uni0543 ; G 1107 +U 1348 ; WX 977 ; N uni0544 ; G 1108 +U 1349 ; WX 833 ; N uni0545 ; G 1109 +U 1350 ; WX 914 ; N uni0546 ; G 1110 +U 1351 ; WX 843 ; N uni0547 ; G 1111 +U 1352 ; WX 871 ; N uni0548 ; G 1112 +U 1353 ; WX 818 ; N uni0549 ; G 1113 +U 1354 ; WX 1034 ; N uni054A ; G 1114 +U 1355 ; WX 846 ; N uni054B ; G 1115 +U 1356 ; WX 964 ; N uni054C ; G 1116 +U 1357 ; WX 871 ; N uni054D ; G 1117 +U 1358 ; WX 914 ; N uni054E ; G 1118 +U 1359 ; WX 808 ; N uni054F ; G 1119 +U 1360 ; WX 808 ; N uni0550 ; G 1120 +U 1361 ; WX 836 ; N uni0551 ; G 1121 +U 1362 ; WX 710 ; N uni0552 ; G 1122 +U 1363 ; WX 955 ; N uni0553 ; G 1123 +U 1364 ; WX 891 ; N uni0554 ; G 1124 +U 1365 ; WX 871 ; N uni0555 ; G 1125 +U 1366 ; WX 963 ; N uni0556 ; G 1126 +U 1369 ; WX 307 ; N uni0559 ; G 1127 +U 1370 ; WX 264 ; N uni055A ; G 1128 +U 1371 ; WX 293 ; N uni055B ; G 1129 +U 1372 ; WX 391 ; N uni055C ; G 1130 +U 1373 ; WX 323 ; N uni055D ; G 1131 +U 1374 ; WX 439 ; N uni055E ; G 1132 +U 1375 ; WX 500 ; N uni055F ; G 1133 +U 1377 ; WX 1055 ; N uni0561 ; G 1134 +U 1378 ; WX 695 ; N uni0562 ; G 1135 +U 1379 ; WX 776 ; N uni0563 ; G 1136 +U 1380 ; WX 801 ; N uni0564 ; G 1137 +U 1381 ; WX 729 ; N uni0565 ; G 1138 +U 1382 ; WX 742 ; N uni0566 ; G 1139 +U 1383 ; WX 599 ; N uni0567 ; G 1140 +U 1384 ; WX 733 ; N uni0568 ; G 1141 +U 1385 ; WX 909 ; N uni0569 ; G 1142 +U 1386 ; WX 768 ; N uni056A ; G 1143 +U 1387 ; WX 724 ; N uni056B ; G 1144 +U 1388 ; WX 398 ; N uni056C ; G 1145 +U 1389 ; WX 1087 ; N uni056D ; G 1146 +U 1390 ; WX 695 ; N uni056E ; G 1147 +U 1391 ; WX 719 ; N uni056F ; G 1148 +U 1392 ; WX 737 ; N uni0570 ; G 1149 +U 1393 ; WX 684 ; N uni0571 ; G 1150 +U 1394 ; WX 738 ; N uni0572 ; G 1151 +U 1395 ; WX 703 ; N uni0573 ; G 1152 +U 1396 ; WX 724 ; N uni0574 ; G 1153 +U 1397 ; WX 359 ; N uni0575 ; G 1154 +U 1398 ; WX 719 ; N uni0576 ; G 1155 +U 1399 ; WX 496 ; N uni0577 ; G 1156 +U 1400 ; WX 738 ; N uni0578 ; G 1157 +U 1401 ; WX 428 ; N uni0579 ; G 1158 +U 1402 ; WX 1059 ; N uni057A ; G 1159 +U 1403 ; WX 668 ; N uni057B ; G 1160 +U 1404 ; WX 744 ; N uni057C ; G 1161 +U 1405 ; WX 724 ; N uni057D ; G 1162 +U 1406 ; WX 724 ; N uni057E ; G 1163 +U 1407 ; WX 1040 ; N uni057F ; G 1164 +U 1408 ; WX 724 ; N uni0580 ; G 1165 +U 1409 ; WX 713 ; N uni0581 ; G 1166 +U 1410 ; WX 493 ; N uni0582 ; G 1167 +U 1411 ; WX 1040 ; N uni0583 ; G 1168 +U 1412 ; WX 734 ; N uni0584 ; G 1169 +U 1413 ; WX 693 ; N uni0585 ; G 1170 +U 1414 ; WX 956 ; N uni0586 ; G 1171 +U 1415 ; WX 833 ; N uni0587 ; G 1172 +U 1417 ; WX 340 ; N uni0589 ; G 1173 +U 1418 ; WX 388 ; N uni058A ; G 1174 +U 3647 ; WX 696 ; N uni0E3F ; G 1175 +U 4256 ; WX 755 ; N uni10A0 ; G 1176 +U 4257 ; WX 936 ; N uni10A1 ; G 1177 +U 4258 ; WX 866 ; N uni10A2 ; G 1178 +U 4259 ; WX 874 ; N uni10A3 ; G 1179 +U 4260 ; WX 781 ; N uni10A4 ; G 1180 +U 4261 ; WX 1078 ; N uni10A5 ; G 1181 +U 4262 ; WX 1014 ; N uni10A6 ; G 1182 +U 4263 ; WX 1213 ; N uni10A7 ; G 1183 +U 4264 ; WX 643 ; N uni10A8 ; G 1184 +U 4265 ; WX 818 ; N uni10A9 ; G 1185 +U 4266 ; WX 1051 ; N uni10AA ; G 1186 +U 4267 ; WX 1051 ; N uni10AB ; G 1187 +U 4268 ; WX 796 ; N uni10AC ; G 1188 +U 4269 ; WX 1135 ; N uni10AD ; G 1189 +U 4270 ; WX 969 ; N uni10AE ; G 1190 +U 4271 ; WX 902 ; N uni10AF ; G 1191 +U 4272 ; WX 1109 ; N uni10B0 ; G 1192 +U 4273 ; WX 792 ; N uni10B1 ; G 1193 +U 4274 ; WX 756 ; N uni10B2 ; G 1194 +U 4275 ; WX 1076 ; N uni10B3 ; G 1195 +U 4276 ; WX 976 ; N uni10B4 ; G 1196 +U 4277 ; WX 1066 ; N uni10B5 ; G 1197 +U 4278 ; WX 811 ; N uni10B6 ; G 1198 +U 4279 ; WX 833 ; N uni10B7 ; G 1199 +U 4280 ; WX 821 ; N uni10B8 ; G 1200 +U 4281 ; WX 833 ; N uni10B9 ; G 1201 +U 4282 ; WX 908 ; N uni10BA ; G 1202 +U 4283 ; WX 1077 ; N uni10BB ; G 1203 +U 4284 ; WX 769 ; N uni10BC ; G 1204 +U 4285 ; WX 822 ; N uni10BD ; G 1205 +U 4286 ; WX 813 ; N uni10BE ; G 1206 +U 4287 ; WX 1111 ; N uni10BF ; G 1207 +U 4288 ; WX 1123 ; N uni10C0 ; G 1208 +U 4289 ; WX 802 ; N uni10C1 ; G 1209 +U 4290 ; WX 892 ; N uni10C2 ; G 1210 +U 4291 ; WX 802 ; N uni10C3 ; G 1211 +U 4292 ; WX 880 ; N uni10C4 ; G 1212 +U 4293 ; WX 1063 ; N uni10C5 ; G 1213 +U 4304 ; WX 594 ; N uni10D0 ; G 1214 +U 4305 ; WX 625 ; N uni10D1 ; G 1215 +U 4306 ; WX 643 ; N uni10D2 ; G 1216 +U 4307 ; WX 887 ; N uni10D3 ; G 1217 +U 4308 ; WX 615 ; N uni10D4 ; G 1218 +U 4309 ; WX 611 ; N uni10D5 ; G 1219 +U 4310 ; WX 667 ; N uni10D6 ; G 1220 +U 4311 ; WX 915 ; N uni10D7 ; G 1221 +U 4312 ; WX 613 ; N uni10D8 ; G 1222 +U 4313 ; WX 600 ; N uni10D9 ; G 1223 +U 4314 ; WX 1120 ; N uni10DA ; G 1224 +U 4315 ; WX 640 ; N uni10DB ; G 1225 +U 4316 ; WX 640 ; N uni10DC ; G 1226 +U 4317 ; WX 879 ; N uni10DD ; G 1227 +U 4318 ; WX 624 ; N uni10DE ; G 1228 +U 4319 ; WX 634 ; N uni10DF ; G 1229 +U 4320 ; WX 877 ; N uni10E0 ; G 1230 +U 4321 ; WX 666 ; N uni10E1 ; G 1231 +U 4322 ; WX 780 ; N uni10E2 ; G 1232 +U 4323 ; WX 751 ; N uni10E3 ; G 1233 +U 4324 ; WX 869 ; N uni10E4 ; G 1234 +U 4325 ; WX 639 ; N uni10E5 ; G 1235 +U 4326 ; WX 912 ; N uni10E6 ; G 1236 +U 4327 ; WX 622 ; N uni10E7 ; G 1237 +U 4328 ; WX 647 ; N uni10E8 ; G 1238 +U 4329 ; WX 640 ; N uni10E9 ; G 1239 +U 4330 ; WX 729 ; N uni10EA ; G 1240 +U 4331 ; WX 641 ; N uni10EB ; G 1241 +U 4332 ; WX 630 ; N uni10EC ; G 1242 +U 4333 ; WX 629 ; N uni10ED ; G 1243 +U 4334 ; WX 670 ; N uni10EE ; G 1244 +U 4335 ; WX 753 ; N uni10EF ; G 1245 +U 4336 ; WX 625 ; N uni10F0 ; G 1246 +U 4337 ; WX 657 ; N uni10F1 ; G 1247 +U 4338 ; WX 625 ; N uni10F2 ; G 1248 +U 4339 ; WX 625 ; N uni10F3 ; G 1249 +U 4340 ; WX 624 ; N uni10F4 ; G 1250 +U 4341 ; WX 670 ; N uni10F5 ; G 1251 +U 4342 ; WX 940 ; N uni10F6 ; G 1252 +U 4343 ; WX 680 ; N uni10F7 ; G 1253 +U 4344 ; WX 636 ; N uni10F8 ; G 1254 +U 4345 ; WX 672 ; N uni10F9 ; G 1255 +U 4346 ; WX 625 ; N uni10FA ; G 1256 +U 4347 ; WX 588 ; N uni10FB ; G 1257 +U 4348 ; WX 354 ; N uni10FC ; G 1258 +U 7424 ; WX 641 ; N uni1D00 ; G 1259 +U 7425 ; WX 892 ; N uni1D01 ; G 1260 +U 7426 ; WX 940 ; N uni1D02 ; G 1261 +U 7427 ; WX 695 ; N uni1D03 ; G 1262 +U 7428 ; WX 609 ; N uni1D04 ; G 1263 +U 7429 ; WX 675 ; N uni1D05 ; G 1264 +U 7430 ; WX 675 ; N uni1D06 ; G 1265 +U 7431 ; WX 617 ; N uni1D07 ; G 1266 +U 7432 ; WX 509 ; N uni1D08 ; G 1267 +U 7433 ; WX 320 ; N uni1D09 ; G 1268 +U 7434 ; WX 561 ; N uni1D0A ; G 1269 +U 7435 ; WX 722 ; N uni1D0B ; G 1270 +U 7436 ; WX 617 ; N uni1D0C ; G 1271 +U 7437 ; WX 869 ; N uni1D0D ; G 1272 +U 7438 ; WX 737 ; N uni1D0E ; G 1273 +U 7439 ; WX 667 ; N uni1D0F ; G 1274 +U 7440 ; WX 609 ; N uni1D10 ; G 1275 +U 7441 ; WX 628 ; N uni1D11 ; G 1276 +U 7442 ; WX 628 ; N uni1D12 ; G 1277 +U 7443 ; WX 667 ; N uni1D13 ; G 1278 +U 7444 ; WX 989 ; N uni1D14 ; G 1279 +U 7445 ; WX 598 ; N uni1D15 ; G 1280 +U 7446 ; WX 667 ; N uni1D16 ; G 1281 +U 7447 ; WX 667 ; N uni1D17 ; G 1282 +U 7448 ; WX 586 ; N uni1D18 ; G 1283 +U 7449 ; WX 801 ; N uni1D19 ; G 1284 +U 7450 ; WX 801 ; N uni1D1A ; G 1285 +U 7451 ; WX 620 ; N uni1D1B ; G 1286 +U 7452 ; WX 647 ; N uni1D1C ; G 1287 +U 7453 ; WX 664 ; N uni1D1D ; G 1288 +U 7454 ; WX 923 ; N uni1D1E ; G 1289 +U 7455 ; WX 655 ; N uni1D1F ; G 1290 +U 7456 ; WX 581 ; N uni1D20 ; G 1291 +U 7457 ; WX 861 ; N uni1D21 ; G 1292 +U 7458 ; WX 568 ; N uni1D22 ; G 1293 +U 7459 ; WX 568 ; N uni1D23 ; G 1294 +U 7460 ; WX 588 ; N uni1D24 ; G 1295 +U 7461 ; WX 802 ; N uni1D25 ; G 1296 +U 7462 ; WX 586 ; N uni1D26 ; G 1297 +U 7463 ; WX 641 ; N uni1D27 ; G 1298 +U 7464 ; WX 732 ; N uni1D28 ; G 1299 +U 7465 ; WX 586 ; N uni1D29 ; G 1300 +U 7466 ; WX 854 ; N uni1D2A ; G 1301 +U 7467 ; WX 705 ; N uni1D2B ; G 1302 +U 7468 ; WX 489 ; N uni1D2C ; G 1303 +U 7469 ; WX 651 ; N uni1D2D ; G 1304 +U 7470 ; WX 532 ; N uni1D2E ; G 1305 +U 7471 ; WX 532 ; N uni1D2F ; G 1306 +U 7472 ; WX 546 ; N uni1D30 ; G 1307 +U 7473 ; WX 480 ; N uni1D31 ; G 1308 +U 7474 ; WX 480 ; N uni1D32 ; G 1309 +U 7475 ; WX 538 ; N uni1D33 ; G 1310 +U 7476 ; WX 595 ; N uni1D34 ; G 1311 +U 7477 ; WX 294 ; N uni1D35 ; G 1312 +U 7478 ; WX 298 ; N uni1D36 ; G 1313 +U 7479 ; WX 547 ; N uni1D37 ; G 1314 +U 7480 ; WX 443 ; N uni1D38 ; G 1315 +U 7481 ; WX 697 ; N uni1D39 ; G 1316 +U 7482 ; WX 576 ; N uni1D3A ; G 1317 +U 7483 ; WX 606 ; N uni1D3B ; G 1318 +U 7484 ; WX 548 ; N uni1D3C ; G 1319 +U 7485 ; WX 442 ; N uni1D3D ; G 1320 +U 7486 ; WX 474 ; N uni1D3E ; G 1321 +U 7487 ; WX 523 ; N uni1D3F ; G 1322 +U 7488 ; WX 455 ; N uni1D40 ; G 1323 +U 7489 ; WX 469 ; N uni1D41 ; G 1324 +U 7490 ; WX 549 ; N uni1D42 ; G 1325 +U 7491 ; WX 466 ; N uni1D43 ; G 1326 +U 7492 ; WX 466 ; N uni1D44 ; G 1327 +U 7493 ; WX 498 ; N uni1D45 ; G 1328 +U 7494 ; WX 657 ; N uni1D46 ; G 1329 +U 7495 ; WX 499 ; N uni1D47 ; G 1330 +U 7496 ; WX 498 ; N uni1D48 ; G 1331 +U 7497 ; WX 444 ; N uni1D49 ; G 1332 +U 7498 ; WX 444 ; N uni1D4A ; G 1333 +U 7499 ; WX 412 ; N uni1D4B ; G 1334 +U 7500 ; WX 412 ; N uni1D4C ; G 1335 +U 7501 ; WX 498 ; N uni1D4D ; G 1336 +U 7502 ; WX 300 ; N uni1D4E ; G 1337 +U 7503 ; WX 523 ; N uni1D4F ; G 1338 +U 7504 ; WX 729 ; N uni1D50 ; G 1339 +U 7505 ; WX 473 ; N uni1D51 ; G 1340 +U 7506 ; WX 467 ; N uni1D52 ; G 1341 +U 7507 ; WX 427 ; N uni1D53 ; G 1342 +U 7508 ; WX 467 ; N uni1D54 ; G 1343 +U 7509 ; WX 467 ; N uni1D55 ; G 1344 +U 7510 ; WX 499 ; N uni1D56 ; G 1345 +U 7511 ; WX 371 ; N uni1D57 ; G 1346 +U 7512 ; WX 520 ; N uni1D58 ; G 1347 +U 7513 ; WX 418 ; N uni1D59 ; G 1348 +U 7514 ; WX 729 ; N uni1D5A ; G 1349 +U 7515 ; WX 491 ; N uni1D5B ; G 1350 +U 7516 ; WX 505 ; N uni1D5C ; G 1351 +U 7517 ; WX 418 ; N uni1D5D ; G 1352 +U 7518 ; WX 416 ; N uni1D5E ; G 1353 +U 7519 ; WX 420 ; N uni1D5F ; G 1354 +U 7520 ; WX 570 ; N uni1D60 ; G 1355 +U 7521 ; WX 414 ; N uni1D61 ; G 1356 +U 7522 ; WX 239 ; N uni1D62 ; G 1357 +U 7523 ; WX 414 ; N uni1D63 ; G 1358 +U 7524 ; WX 520 ; N uni1D64 ; G 1359 +U 7525 ; WX 491 ; N uni1D65 ; G 1360 +U 7526 ; WX 418 ; N uni1D66 ; G 1361 +U 7527 ; WX 416 ; N uni1D67 ; G 1362 +U 7528 ; WX 419 ; N uni1D68 ; G 1363 +U 7529 ; WX 570 ; N uni1D69 ; G 1364 +U 7530 ; WX 414 ; N uni1D6A ; G 1365 +U 7531 ; WX 1041 ; N uni1D6B ; G 1366 +U 7543 ; WX 640 ; N uni1D77 ; G 1367 +U 7544 ; WX 595 ; N uni1D78 ; G 1368 +U 7547 ; WX 380 ; N uni1D7B ; G 1369 +U 7548 ; WX 380 ; N uni1D7C ; G 1370 +U 7549 ; WX 699 ; N uni1D7D ; G 1371 +U 7550 ; WX 647 ; N uni1D7E ; G 1372 +U 7551 ; WX 679 ; N uni1D7F ; G 1373 +U 7557 ; WX 380 ; N uni1D85 ; G 1374 +U 7579 ; WX 498 ; N uni1D9B ; G 1375 +U 7580 ; WX 427 ; N uni1D9C ; G 1376 +U 7581 ; WX 427 ; N uni1D9D ; G 1377 +U 7582 ; WX 467 ; N uni1D9E ; G 1378 +U 7583 ; WX 412 ; N uni1D9F ; G 1379 +U 7584 ; WX 383 ; N uni1DA0 ; G 1380 +U 7585 ; WX 373 ; N uni1DA1 ; G 1381 +U 7586 ; WX 498 ; N uni1DA2 ; G 1382 +U 7587 ; WX 522 ; N uni1DA3 ; G 1383 +U 7588 ; WX 300 ; N uni1DA4 ; G 1384 +U 7589 ; WX 307 ; N uni1DA5 ; G 1385 +U 7590 ; WX 300 ; N uni1DA6 ; G 1386 +U 7591 ; WX 300 ; N uni1DA7 ; G 1387 +U 7592 ; WX 370 ; N uni1DA8 ; G 1388 +U 7593 ; WX 368 ; N uni1DA9 ; G 1389 +U 7594 ; WX 321 ; N uni1DAA ; G 1390 +U 7595 ; WX 430 ; N uni1DAB ; G 1391 +U 7596 ; WX 682 ; N uni1DAC ; G 1392 +U 7597 ; WX 729 ; N uni1DAD ; G 1393 +U 7598 ; WX 588 ; N uni1DAE ; G 1394 +U 7599 ; WX 587 ; N uni1DAF ; G 1395 +U 7600 ; WX 472 ; N uni1DB0 ; G 1396 +U 7601 ; WX 467 ; N uni1DB1 ; G 1397 +U 7602 ; WX 522 ; N uni1DB2 ; G 1398 +U 7603 ; WX 400 ; N uni1DB3 ; G 1399 +U 7604 ; WX 387 ; N uni1DB4 ; G 1400 +U 7605 ; WX 371 ; N uni1DB5 ; G 1401 +U 7606 ; WX 520 ; N uni1DB6 ; G 1402 +U 7607 ; WX 475 ; N uni1DB7 ; G 1403 +U 7608 ; WX 408 ; N uni1DB8 ; G 1404 +U 7609 ; WX 489 ; N uni1DB9 ; G 1405 +U 7610 ; WX 491 ; N uni1DBA ; G 1406 +U 7611 ; WX 412 ; N uni1DBB ; G 1407 +U 7612 ; WX 527 ; N uni1DBC ; G 1408 +U 7613 ; WX 412 ; N uni1DBD ; G 1409 +U 7614 ; WX 452 ; N uni1DBE ; G 1410 +U 7615 ; WX 467 ; N uni1DBF ; G 1411 +U 7620 ; WX 0 ; N uni1DC4 ; G 1412 +U 7621 ; WX 0 ; N uni1DC5 ; G 1413 +U 7622 ; WX 0 ; N uni1DC6 ; G 1414 +U 7623 ; WX 0 ; N uni1DC7 ; G 1415 +U 7624 ; WX 0 ; N uni1DC8 ; G 1416 +U 7625 ; WX 0 ; N uni1DC9 ; G 1417 +U 7680 ; WX 776 ; N uni1E00 ; G 1418 +U 7681 ; WX 648 ; N uni1E01 ; G 1419 +U 7682 ; WX 845 ; N uni1E02 ; G 1420 +U 7683 ; WX 699 ; N uni1E03 ; G 1421 +U 7684 ; WX 845 ; N uni1E04 ; G 1422 +U 7685 ; WX 699 ; N uni1E05 ; G 1423 +U 7686 ; WX 845 ; N uni1E06 ; G 1424 +U 7687 ; WX 699 ; N uni1E07 ; G 1425 +U 7688 ; WX 796 ; N uni1E08 ; G 1426 +U 7689 ; WX 609 ; N uni1E09 ; G 1427 +U 7690 ; WX 867 ; N uni1E0A ; G 1428 +U 7691 ; WX 699 ; N uni1E0B ; G 1429 +U 7692 ; WX 867 ; N uni1E0C ; G 1430 +U 7693 ; WX 699 ; N uni1E0D ; G 1431 +U 7694 ; WX 867 ; N uni1E0E ; G 1432 +U 7695 ; WX 699 ; N uni1E0F ; G 1433 +U 7696 ; WX 867 ; N uni1E10 ; G 1434 +U 7697 ; WX 699 ; N uni1E11 ; G 1435 +U 7698 ; WX 867 ; N uni1E12 ; G 1436 +U 7699 ; WX 699 ; N uni1E13 ; G 1437 +U 7700 ; WX 762 ; N uni1E14 ; G 1438 +U 7701 ; WX 636 ; N uni1E15 ; G 1439 +U 7702 ; WX 762 ; N uni1E16 ; G 1440 +U 7703 ; WX 636 ; N uni1E17 ; G 1441 +U 7704 ; WX 762 ; N uni1E18 ; G 1442 +U 7705 ; WX 636 ; N uni1E19 ; G 1443 +U 7706 ; WX 762 ; N uni1E1A ; G 1444 +U 7707 ; WX 636 ; N uni1E1B ; G 1445 +U 7708 ; WX 762 ; N uni1E1C ; G 1446 +U 7709 ; WX 636 ; N uni1E1D ; G 1447 +U 7710 ; WX 710 ; N uni1E1E ; G 1448 +U 7711 ; WX 430 ; N uni1E1F ; G 1449 +U 7712 ; WX 854 ; N uni1E20 ; G 1450 +U 7713 ; WX 699 ; N uni1E21 ; G 1451 +U 7714 ; WX 945 ; N uni1E22 ; G 1452 +U 7715 ; WX 727 ; N uni1E23 ; G 1453 +U 7716 ; WX 945 ; N uni1E24 ; G 1454 +U 7717 ; WX 727 ; N uni1E25 ; G 1455 +U 7718 ; WX 945 ; N uni1E26 ; G 1456 +U 7719 ; WX 727 ; N uni1E27 ; G 1457 +U 7720 ; WX 945 ; N uni1E28 ; G 1458 +U 7721 ; WX 727 ; N uni1E29 ; G 1459 +U 7722 ; WX 945 ; N uni1E2A ; G 1460 +U 7723 ; WX 727 ; N uni1E2B ; G 1461 +U 7724 ; WX 468 ; N uni1E2C ; G 1462 +U 7725 ; WX 380 ; N uni1E2D ; G 1463 +U 7726 ; WX 468 ; N uni1E2E ; G 1464 +U 7727 ; WX 380 ; N uni1E2F ; G 1465 +U 7728 ; WX 869 ; N uni1E30 ; G 1466 +U 7729 ; WX 693 ; N uni1E31 ; G 1467 +U 7730 ; WX 869 ; N uni1E32 ; G 1468 +U 7731 ; WX 693 ; N uni1E33 ; G 1469 +U 7732 ; WX 869 ; N uni1E34 ; G 1470 +U 7733 ; WX 693 ; N uni1E35 ; G 1471 +U 7734 ; WX 703 ; N uni1E36 ; G 1472 +U 7735 ; WX 380 ; N uni1E37 ; G 1473 +U 7736 ; WX 703 ; N uni1E38 ; G 1474 +U 7737 ; WX 380 ; N uni1E39 ; G 1475 +U 7738 ; WX 703 ; N uni1E3A ; G 1476 +U 7739 ; WX 380 ; N uni1E3B ; G 1477 +U 7740 ; WX 703 ; N uni1E3C ; G 1478 +U 7741 ; WX 380 ; N uni1E3D ; G 1479 +U 7742 ; WX 1107 ; N uni1E3E ; G 1480 +U 7743 ; WX 1058 ; N uni1E3F ; G 1481 +U 7744 ; WX 1107 ; N uni1E40 ; G 1482 +U 7745 ; WX 1058 ; N uni1E41 ; G 1483 +U 7746 ; WX 1107 ; N uni1E42 ; G 1484 +U 7747 ; WX 1058 ; N uni1E43 ; G 1485 +U 7748 ; WX 914 ; N uni1E44 ; G 1486 +U 7749 ; WX 727 ; N uni1E45 ; G 1487 +U 7750 ; WX 914 ; N uni1E46 ; G 1488 +U 7751 ; WX 727 ; N uni1E47 ; G 1489 +U 7752 ; WX 914 ; N uni1E48 ; G 1490 +U 7753 ; WX 727 ; N uni1E49 ; G 1491 +U 7754 ; WX 914 ; N uni1E4A ; G 1492 +U 7755 ; WX 727 ; N uni1E4B ; G 1493 +U 7756 ; WX 871 ; N uni1E4C ; G 1494 +U 7757 ; WX 667 ; N uni1E4D ; G 1495 +U 7758 ; WX 871 ; N uni1E4E ; G 1496 +U 7759 ; WX 667 ; N uni1E4F ; G 1497 +U 7760 ; WX 871 ; N uni1E50 ; G 1498 +U 7761 ; WX 667 ; N uni1E51 ; G 1499 +U 7762 ; WX 871 ; N uni1E52 ; G 1500 +U 7763 ; WX 667 ; N uni1E53 ; G 1501 +U 7764 ; WX 752 ; N uni1E54 ; G 1502 +U 7765 ; WX 699 ; N uni1E55 ; G 1503 +U 7766 ; WX 752 ; N uni1E56 ; G 1504 +U 7767 ; WX 699 ; N uni1E57 ; G 1505 +U 7768 ; WX 831 ; N uni1E58 ; G 1506 +U 7769 ; WX 527 ; N uni1E59 ; G 1507 +U 7770 ; WX 831 ; N uni1E5A ; G 1508 +U 7771 ; WX 527 ; N uni1E5B ; G 1509 +U 7772 ; WX 831 ; N uni1E5C ; G 1510 +U 7773 ; WX 527 ; N uni1E5D ; G 1511 +U 7774 ; WX 831 ; N uni1E5E ; G 1512 +U 7775 ; WX 527 ; N uni1E5F ; G 1513 +U 7776 ; WX 722 ; N uni1E60 ; G 1514 +U 7777 ; WX 563 ; N uni1E61 ; G 1515 +U 7778 ; WX 722 ; N uni1E62 ; G 1516 +U 7779 ; WX 563 ; N uni1E63 ; G 1517 +U 7780 ; WX 722 ; N uni1E64 ; G 1518 +U 7781 ; WX 563 ; N uni1E65 ; G 1519 +U 7782 ; WX 722 ; N uni1E66 ; G 1520 +U 7783 ; WX 563 ; N uni1E67 ; G 1521 +U 7784 ; WX 722 ; N uni1E68 ; G 1522 +U 7785 ; WX 563 ; N uni1E69 ; G 1523 +U 7786 ; WX 744 ; N uni1E6A ; G 1524 +U 7787 ; WX 462 ; N uni1E6B ; G 1525 +U 7788 ; WX 744 ; N uni1E6C ; G 1526 +U 7789 ; WX 462 ; N uni1E6D ; G 1527 +U 7790 ; WX 744 ; N uni1E6E ; G 1528 +U 7791 ; WX 462 ; N uni1E6F ; G 1529 +U 7792 ; WX 744 ; N uni1E70 ; G 1530 +U 7793 ; WX 462 ; N uni1E71 ; G 1531 +U 7794 ; WX 872 ; N uni1E72 ; G 1532 +U 7795 ; WX 727 ; N uni1E73 ; G 1533 +U 7796 ; WX 872 ; N uni1E74 ; G 1534 +U 7797 ; WX 727 ; N uni1E75 ; G 1535 +U 7798 ; WX 872 ; N uni1E76 ; G 1536 +U 7799 ; WX 727 ; N uni1E77 ; G 1537 +U 7800 ; WX 872 ; N uni1E78 ; G 1538 +U 7801 ; WX 727 ; N uni1E79 ; G 1539 +U 7802 ; WX 872 ; N uni1E7A ; G 1540 +U 7803 ; WX 727 ; N uni1E7B ; G 1541 +U 7804 ; WX 776 ; N uni1E7C ; G 1542 +U 7805 ; WX 581 ; N uni1E7D ; G 1543 +U 7806 ; WX 776 ; N uni1E7E ; G 1544 +U 7807 ; WX 581 ; N uni1E7F ; G 1545 +U 7808 ; WX 1123 ; N Wgrave ; G 1546 +U 7809 ; WX 861 ; N wgrave ; G 1547 +U 7810 ; WX 1123 ; N Wacute ; G 1548 +U 7811 ; WX 861 ; N wacute ; G 1549 +U 7812 ; WX 1123 ; N Wdieresis ; G 1550 +U 7813 ; WX 861 ; N wdieresis ; G 1551 +U 7814 ; WX 1123 ; N uni1E86 ; G 1552 +U 7815 ; WX 861 ; N uni1E87 ; G 1553 +U 7816 ; WX 1123 ; N uni1E88 ; G 1554 +U 7817 ; WX 861 ; N uni1E89 ; G 1555 +U 7818 ; WX 776 ; N uni1E8A ; G 1556 +U 7819 ; WX 596 ; N uni1E8B ; G 1557 +U 7820 ; WX 776 ; N uni1E8C ; G 1558 +U 7821 ; WX 596 ; N uni1E8D ; G 1559 +U 7822 ; WX 714 ; N uni1E8E ; G 1560 +U 7823 ; WX 581 ; N uni1E8F ; G 1561 +U 7824 ; WX 730 ; N uni1E90 ; G 1562 +U 7825 ; WX 568 ; N uni1E91 ; G 1563 +U 7826 ; WX 730 ; N uni1E92 ; G 1564 +U 7827 ; WX 568 ; N uni1E93 ; G 1565 +U 7828 ; WX 730 ; N uni1E94 ; G 1566 +U 7829 ; WX 568 ; N uni1E95 ; G 1567 +U 7830 ; WX 727 ; N uni1E96 ; G 1568 +U 7831 ; WX 462 ; N uni1E97 ; G 1569 +U 7832 ; WX 861 ; N uni1E98 ; G 1570 +U 7833 ; WX 581 ; N uni1E99 ; G 1571 +U 7834 ; WX 1014 ; N uni1E9A ; G 1572 +U 7835 ; WX 430 ; N uni1E9B ; G 1573 +U 7836 ; WX 430 ; N uni1E9C ; G 1574 +U 7837 ; WX 430 ; N uni1E9D ; G 1575 +U 7838 ; WX 947 ; N uni1E9E ; G 1576 +U 7839 ; WX 667 ; N uni1E9F ; G 1577 +U 7840 ; WX 776 ; N uni1EA0 ; G 1578 +U 7841 ; WX 648 ; N uni1EA1 ; G 1579 +U 7842 ; WX 776 ; N uni1EA2 ; G 1580 +U 7843 ; WX 648 ; N uni1EA3 ; G 1581 +U 7844 ; WX 776 ; N uni1EA4 ; G 1582 +U 7845 ; WX 648 ; N uni1EA5 ; G 1583 +U 7846 ; WX 776 ; N uni1EA6 ; G 1584 +U 7847 ; WX 648 ; N uni1EA7 ; G 1585 +U 7848 ; WX 776 ; N uni1EA8 ; G 1586 +U 7849 ; WX 648 ; N uni1EA9 ; G 1587 +U 7850 ; WX 776 ; N uni1EAA ; G 1588 +U 7851 ; WX 648 ; N uni1EAB ; G 1589 +U 7852 ; WX 776 ; N uni1EAC ; G 1590 +U 7853 ; WX 648 ; N uni1EAD ; G 1591 +U 7854 ; WX 776 ; N uni1EAE ; G 1592 +U 7855 ; WX 648 ; N uni1EAF ; G 1593 +U 7856 ; WX 776 ; N uni1EB0 ; G 1594 +U 7857 ; WX 648 ; N uni1EB1 ; G 1595 +U 7858 ; WX 776 ; N uni1EB2 ; G 1596 +U 7859 ; WX 648 ; N uni1EB3 ; G 1597 +U 7860 ; WX 776 ; N uni1EB4 ; G 1598 +U 7861 ; WX 648 ; N uni1EB5 ; G 1599 +U 7862 ; WX 776 ; N uni1EB6 ; G 1600 +U 7863 ; WX 648 ; N uni1EB7 ; G 1601 +U 7864 ; WX 762 ; N uni1EB8 ; G 1602 +U 7865 ; WX 636 ; N uni1EB9 ; G 1603 +U 7866 ; WX 762 ; N uni1EBA ; G 1604 +U 7867 ; WX 636 ; N uni1EBB ; G 1605 +U 7868 ; WX 762 ; N uni1EBC ; G 1606 +U 7869 ; WX 636 ; N uni1EBD ; G 1607 +U 7870 ; WX 762 ; N uni1EBE ; G 1608 +U 7871 ; WX 636 ; N uni1EBF ; G 1609 +U 7872 ; WX 762 ; N uni1EC0 ; G 1610 +U 7873 ; WX 636 ; N uni1EC1 ; G 1611 +U 7874 ; WX 762 ; N uni1EC2 ; G 1612 +U 7875 ; WX 636 ; N uni1EC3 ; G 1613 +U 7876 ; WX 762 ; N uni1EC4 ; G 1614 +U 7877 ; WX 636 ; N uni1EC5 ; G 1615 +U 7878 ; WX 762 ; N uni1EC6 ; G 1616 +U 7879 ; WX 636 ; N uni1EC7 ; G 1617 +U 7880 ; WX 468 ; N uni1EC8 ; G 1618 +U 7881 ; WX 380 ; N uni1EC9 ; G 1619 +U 7882 ; WX 468 ; N uni1ECA ; G 1620 +U 7883 ; WX 380 ; N uni1ECB ; G 1621 +U 7884 ; WX 871 ; N uni1ECC ; G 1622 +U 7885 ; WX 667 ; N uni1ECD ; G 1623 +U 7886 ; WX 871 ; N uni1ECE ; G 1624 +U 7887 ; WX 667 ; N uni1ECF ; G 1625 +U 7888 ; WX 871 ; N uni1ED0 ; G 1626 +U 7889 ; WX 667 ; N uni1ED1 ; G 1627 +U 7890 ; WX 871 ; N uni1ED2 ; G 1628 +U 7891 ; WX 667 ; N uni1ED3 ; G 1629 +U 7892 ; WX 871 ; N uni1ED4 ; G 1630 +U 7893 ; WX 667 ; N uni1ED5 ; G 1631 +U 7894 ; WX 871 ; N uni1ED6 ; G 1632 +U 7895 ; WX 667 ; N uni1ED7 ; G 1633 +U 7896 ; WX 871 ; N uni1ED8 ; G 1634 +U 7897 ; WX 667 ; N uni1ED9 ; G 1635 +U 7898 ; WX 871 ; N uni1EDA ; G 1636 +U 7899 ; WX 667 ; N uni1EDB ; G 1637 +U 7900 ; WX 871 ; N uni1EDC ; G 1638 +U 7901 ; WX 667 ; N uni1EDD ; G 1639 +U 7902 ; WX 871 ; N uni1EDE ; G 1640 +U 7903 ; WX 667 ; N uni1EDF ; G 1641 +U 7904 ; WX 871 ; N uni1EE0 ; G 1642 +U 7905 ; WX 667 ; N uni1EE1 ; G 1643 +U 7906 ; WX 871 ; N uni1EE2 ; G 1644 +U 7907 ; WX 667 ; N uni1EE3 ; G 1645 +U 7908 ; WX 872 ; N uni1EE4 ; G 1646 +U 7909 ; WX 727 ; N uni1EE5 ; G 1647 +U 7910 ; WX 872 ; N uni1EE6 ; G 1648 +U 7911 ; WX 727 ; N uni1EE7 ; G 1649 +U 7912 ; WX 872 ; N uni1EE8 ; G 1650 +U 7913 ; WX 727 ; N uni1EE9 ; G 1651 +U 7914 ; WX 872 ; N uni1EEA ; G 1652 +U 7915 ; WX 727 ; N uni1EEB ; G 1653 +U 7916 ; WX 872 ; N uni1EEC ; G 1654 +U 7917 ; WX 727 ; N uni1EED ; G 1655 +U 7918 ; WX 872 ; N uni1EEE ; G 1656 +U 7919 ; WX 727 ; N uni1EEF ; G 1657 +U 7920 ; WX 872 ; N uni1EF0 ; G 1658 +U 7921 ; WX 727 ; N uni1EF1 ; G 1659 +U 7922 ; WX 714 ; N Ygrave ; G 1660 +U 7923 ; WX 581 ; N ygrave ; G 1661 +U 7924 ; WX 714 ; N uni1EF4 ; G 1662 +U 7925 ; WX 581 ; N uni1EF5 ; G 1663 +U 7926 ; WX 714 ; N uni1EF6 ; G 1664 +U 7927 ; WX 581 ; N uni1EF7 ; G 1665 +U 7928 ; WX 714 ; N uni1EF8 ; G 1666 +U 7929 ; WX 581 ; N uni1EF9 ; G 1667 +U 7930 ; WX 1078 ; N uni1EFA ; G 1668 +U 7931 ; WX 701 ; N uni1EFB ; G 1669 +U 7936 ; WX 770 ; N uni1F00 ; G 1670 +U 7937 ; WX 770 ; N uni1F01 ; G 1671 +U 7938 ; WX 770 ; N uni1F02 ; G 1672 +U 7939 ; WX 770 ; N uni1F03 ; G 1673 +U 7940 ; WX 770 ; N uni1F04 ; G 1674 +U 7941 ; WX 770 ; N uni1F05 ; G 1675 +U 7942 ; WX 770 ; N uni1F06 ; G 1676 +U 7943 ; WX 770 ; N uni1F07 ; G 1677 +U 7944 ; WX 776 ; N uni1F08 ; G 1678 +U 7945 ; WX 776 ; N uni1F09 ; G 1679 +U 7946 ; WX 978 ; N uni1F0A ; G 1680 +U 7947 ; WX 978 ; N uni1F0B ; G 1681 +U 7948 ; WX 832 ; N uni1F0C ; G 1682 +U 7949 ; WX 849 ; N uni1F0D ; G 1683 +U 7950 ; WX 776 ; N uni1F0E ; G 1684 +U 7951 ; WX 776 ; N uni1F0F ; G 1685 +U 7952 ; WX 608 ; N uni1F10 ; G 1686 +U 7953 ; WX 608 ; N uni1F11 ; G 1687 +U 7954 ; WX 608 ; N uni1F12 ; G 1688 +U 7955 ; WX 608 ; N uni1F13 ; G 1689 +U 7956 ; WX 608 ; N uni1F14 ; G 1690 +U 7957 ; WX 608 ; N uni1F15 ; G 1691 +U 7960 ; WX 917 ; N uni1F18 ; G 1692 +U 7961 ; WX 909 ; N uni1F19 ; G 1693 +U 7962 ; WX 1169 ; N uni1F1A ; G 1694 +U 7963 ; WX 1169 ; N uni1F1B ; G 1695 +U 7964 ; WX 1093 ; N uni1F1C ; G 1696 +U 7965 ; WX 1120 ; N uni1F1D ; G 1697 +U 7968 ; WX 727 ; N uni1F20 ; G 1698 +U 7969 ; WX 727 ; N uni1F21 ; G 1699 +U 7970 ; WX 727 ; N uni1F22 ; G 1700 +U 7971 ; WX 727 ; N uni1F23 ; G 1701 +U 7972 ; WX 727 ; N uni1F24 ; G 1702 +U 7973 ; WX 727 ; N uni1F25 ; G 1703 +U 7974 ; WX 727 ; N uni1F26 ; G 1704 +U 7975 ; WX 727 ; N uni1F27 ; G 1705 +U 7976 ; WX 1100 ; N uni1F28 ; G 1706 +U 7977 ; WX 1094 ; N uni1F29 ; G 1707 +U 7978 ; WX 1358 ; N uni1F2A ; G 1708 +U 7979 ; WX 1361 ; N uni1F2B ; G 1709 +U 7980 ; WX 1279 ; N uni1F2C ; G 1710 +U 7981 ; WX 1308 ; N uni1F2D ; G 1711 +U 7982 ; WX 1197 ; N uni1F2E ; G 1712 +U 7983 ; WX 1194 ; N uni1F2F ; G 1713 +U 7984 ; WX 484 ; N uni1F30 ; G 1714 +U 7985 ; WX 484 ; N uni1F31 ; G 1715 +U 7986 ; WX 484 ; N uni1F32 ; G 1716 +U 7987 ; WX 484 ; N uni1F33 ; G 1717 +U 7988 ; WX 484 ; N uni1F34 ; G 1718 +U 7989 ; WX 484 ; N uni1F35 ; G 1719 +U 7990 ; WX 484 ; N uni1F36 ; G 1720 +U 7991 ; WX 484 ; N uni1F37 ; G 1721 +U 7992 ; WX 629 ; N uni1F38 ; G 1722 +U 7993 ; WX 617 ; N uni1F39 ; G 1723 +U 7994 ; WX 878 ; N uni1F3A ; G 1724 +U 7995 ; WX 881 ; N uni1F3B ; G 1725 +U 7996 ; WX 799 ; N uni1F3C ; G 1726 +U 7997 ; WX 831 ; N uni1F3D ; G 1727 +U 7998 ; WX 723 ; N uni1F3E ; G 1728 +U 7999 ; WX 714 ; N uni1F3F ; G 1729 +U 8000 ; WX 667 ; N uni1F40 ; G 1730 +U 8001 ; WX 667 ; N uni1F41 ; G 1731 +U 8002 ; WX 667 ; N uni1F42 ; G 1732 +U 8003 ; WX 667 ; N uni1F43 ; G 1733 +U 8004 ; WX 667 ; N uni1F44 ; G 1734 +U 8005 ; WX 667 ; N uni1F45 ; G 1735 +U 8008 ; WX 900 ; N uni1F48 ; G 1736 +U 8009 ; WX 935 ; N uni1F49 ; G 1737 +U 8010 ; WX 1240 ; N uni1F4A ; G 1738 +U 8011 ; WX 1237 ; N uni1F4B ; G 1739 +U 8012 ; WX 1035 ; N uni1F4C ; G 1740 +U 8013 ; WX 1066 ; N uni1F4D ; G 1741 +U 8016 ; WX 694 ; N uni1F50 ; G 1742 +U 8017 ; WX 694 ; N uni1F51 ; G 1743 +U 8018 ; WX 694 ; N uni1F52 ; G 1744 +U 8019 ; WX 694 ; N uni1F53 ; G 1745 +U 8020 ; WX 694 ; N uni1F54 ; G 1746 +U 8021 ; WX 694 ; N uni1F55 ; G 1747 +U 8022 ; WX 694 ; N uni1F56 ; G 1748 +U 8023 ; WX 694 ; N uni1F57 ; G 1749 +U 8025 ; WX 922 ; N uni1F59 ; G 1750 +U 8027 ; WX 1186 ; N uni1F5B ; G 1751 +U 8029 ; WX 1133 ; N uni1F5D ; G 1752 +U 8031 ; WX 1019 ; N uni1F5F ; G 1753 +U 8032 ; WX 952 ; N uni1F60 ; G 1754 +U 8033 ; WX 952 ; N uni1F61 ; G 1755 +U 8034 ; WX 952 ; N uni1F62 ; G 1756 +U 8035 ; WX 952 ; N uni1F63 ; G 1757 +U 8036 ; WX 952 ; N uni1F64 ; G 1758 +U 8037 ; WX 952 ; N uni1F65 ; G 1759 +U 8038 ; WX 952 ; N uni1F66 ; G 1760 +U 8039 ; WX 952 ; N uni1F67 ; G 1761 +U 8040 ; WX 931 ; N uni1F68 ; G 1762 +U 8041 ; WX 963 ; N uni1F69 ; G 1763 +U 8042 ; WX 1268 ; N uni1F6A ; G 1764 +U 8043 ; WX 1274 ; N uni1F6B ; G 1765 +U 8044 ; WX 1054 ; N uni1F6C ; G 1766 +U 8045 ; WX 1088 ; N uni1F6D ; G 1767 +U 8046 ; WX 1023 ; N uni1F6E ; G 1768 +U 8047 ; WX 1060 ; N uni1F6F ; G 1769 +U 8048 ; WX 770 ; N uni1F70 ; G 1770 +U 8049 ; WX 770 ; N uni1F71 ; G 1771 +U 8050 ; WX 608 ; N uni1F72 ; G 1772 +U 8051 ; WX 608 ; N uni1F73 ; G 1773 +U 8052 ; WX 727 ; N uni1F74 ; G 1774 +U 8053 ; WX 727 ; N uni1F75 ; G 1775 +U 8054 ; WX 484 ; N uni1F76 ; G 1776 +U 8055 ; WX 484 ; N uni1F77 ; G 1777 +U 8056 ; WX 667 ; N uni1F78 ; G 1778 +U 8057 ; WX 667 ; N uni1F79 ; G 1779 +U 8058 ; WX 694 ; N uni1F7A ; G 1780 +U 8059 ; WX 694 ; N uni1F7B ; G 1781 +U 8060 ; WX 952 ; N uni1F7C ; G 1782 +U 8061 ; WX 952 ; N uni1F7D ; G 1783 +U 8064 ; WX 770 ; N uni1F80 ; G 1784 +U 8065 ; WX 770 ; N uni1F81 ; G 1785 +U 8066 ; WX 770 ; N uni1F82 ; G 1786 +U 8067 ; WX 770 ; N uni1F83 ; G 1787 +U 8068 ; WX 770 ; N uni1F84 ; G 1788 +U 8069 ; WX 770 ; N uni1F85 ; G 1789 +U 8070 ; WX 770 ; N uni1F86 ; G 1790 +U 8071 ; WX 770 ; N uni1F87 ; G 1791 +U 8072 ; WX 776 ; N uni1F88 ; G 1792 +U 8073 ; WX 776 ; N uni1F89 ; G 1793 +U 8074 ; WX 978 ; N uni1F8A ; G 1794 +U 8075 ; WX 978 ; N uni1F8B ; G 1795 +U 8076 ; WX 832 ; N uni1F8C ; G 1796 +U 8077 ; WX 849 ; N uni1F8D ; G 1797 +U 8078 ; WX 776 ; N uni1F8E ; G 1798 +U 8079 ; WX 776 ; N uni1F8F ; G 1799 +U 8080 ; WX 727 ; N uni1F90 ; G 1800 +U 8081 ; WX 727 ; N uni1F91 ; G 1801 +U 8082 ; WX 727 ; N uni1F92 ; G 1802 +U 8083 ; WX 727 ; N uni1F93 ; G 1803 +U 8084 ; WX 727 ; N uni1F94 ; G 1804 +U 8085 ; WX 727 ; N uni1F95 ; G 1805 +U 8086 ; WX 727 ; N uni1F96 ; G 1806 +U 8087 ; WX 727 ; N uni1F97 ; G 1807 +U 8088 ; WX 1100 ; N uni1F98 ; G 1808 +U 8089 ; WX 1094 ; N uni1F99 ; G 1809 +U 8090 ; WX 1358 ; N uni1F9A ; G 1810 +U 8091 ; WX 1361 ; N uni1F9B ; G 1811 +U 8092 ; WX 1279 ; N uni1F9C ; G 1812 +U 8093 ; WX 1308 ; N uni1F9D ; G 1813 +U 8094 ; WX 1197 ; N uni1F9E ; G 1814 +U 8095 ; WX 1194 ; N uni1F9F ; G 1815 +U 8096 ; WX 952 ; N uni1FA0 ; G 1816 +U 8097 ; WX 952 ; N uni1FA1 ; G 1817 +U 8098 ; WX 952 ; N uni1FA2 ; G 1818 +U 8099 ; WX 952 ; N uni1FA3 ; G 1819 +U 8100 ; WX 952 ; N uni1FA4 ; G 1820 +U 8101 ; WX 952 ; N uni1FA5 ; G 1821 +U 8102 ; WX 952 ; N uni1FA6 ; G 1822 +U 8103 ; WX 952 ; N uni1FA7 ; G 1823 +U 8104 ; WX 931 ; N uni1FA8 ; G 1824 +U 8105 ; WX 963 ; N uni1FA9 ; G 1825 +U 8106 ; WX 1268 ; N uni1FAA ; G 1826 +U 8107 ; WX 1274 ; N uni1FAB ; G 1827 +U 8108 ; WX 1054 ; N uni1FAC ; G 1828 +U 8109 ; WX 1088 ; N uni1FAD ; G 1829 +U 8110 ; WX 1023 ; N uni1FAE ; G 1830 +U 8111 ; WX 1060 ; N uni1FAF ; G 1831 +U 8112 ; WX 770 ; N uni1FB0 ; G 1832 +U 8113 ; WX 770 ; N uni1FB1 ; G 1833 +U 8114 ; WX 770 ; N uni1FB2 ; G 1834 +U 8115 ; WX 770 ; N uni1FB3 ; G 1835 +U 8116 ; WX 770 ; N uni1FB4 ; G 1836 +U 8118 ; WX 770 ; N uni1FB6 ; G 1837 +U 8119 ; WX 770 ; N uni1FB7 ; G 1838 +U 8120 ; WX 776 ; N uni1FB8 ; G 1839 +U 8121 ; WX 776 ; N uni1FB9 ; G 1840 +U 8122 ; WX 811 ; N uni1FBA ; G 1841 +U 8123 ; WX 776 ; N uni1FBB ; G 1842 +U 8124 ; WX 776 ; N uni1FBC ; G 1843 +U 8125 ; WX 500 ; N uni1FBD ; G 1844 +U 8126 ; WX 500 ; N uni1FBE ; G 1845 +U 8127 ; WX 500 ; N uni1FBF ; G 1846 +U 8128 ; WX 500 ; N uni1FC0 ; G 1847 +U 8129 ; WX 500 ; N uni1FC1 ; G 1848 +U 8130 ; WX 727 ; N uni1FC2 ; G 1849 +U 8131 ; WX 727 ; N uni1FC3 ; G 1850 +U 8132 ; WX 727 ; N uni1FC4 ; G 1851 +U 8134 ; WX 727 ; N uni1FC6 ; G 1852 +U 8135 ; WX 727 ; N uni1FC7 ; G 1853 +U 8136 ; WX 1000 ; N uni1FC8 ; G 1854 +U 8137 ; WX 947 ; N uni1FC9 ; G 1855 +U 8138 ; WX 1191 ; N uni1FCA ; G 1856 +U 8139 ; WX 1118 ; N uni1FCB ; G 1857 +U 8140 ; WX 945 ; N uni1FCC ; G 1858 +U 8141 ; WX 500 ; N uni1FCD ; G 1859 +U 8142 ; WX 500 ; N uni1FCE ; G 1860 +U 8143 ; WX 500 ; N uni1FCF ; G 1861 +U 8144 ; WX 484 ; N uni1FD0 ; G 1862 +U 8145 ; WX 484 ; N uni1FD1 ; G 1863 +U 8146 ; WX 484 ; N uni1FD2 ; G 1864 +U 8147 ; WX 484 ; N uni1FD3 ; G 1865 +U 8150 ; WX 484 ; N uni1FD6 ; G 1866 +U 8151 ; WX 484 ; N uni1FD7 ; G 1867 +U 8152 ; WX 468 ; N uni1FD8 ; G 1868 +U 8153 ; WX 468 ; N uni1FD9 ; G 1869 +U 8154 ; WX 714 ; N uni1FDA ; G 1870 +U 8155 ; WX 662 ; N uni1FDB ; G 1871 +U 8157 ; WX 500 ; N uni1FDD ; G 1872 +U 8158 ; WX 500 ; N uni1FDE ; G 1873 +U 8159 ; WX 500 ; N uni1FDF ; G 1874 +U 8160 ; WX 694 ; N uni1FE0 ; G 1875 +U 8161 ; WX 694 ; N uni1FE1 ; G 1876 +U 8162 ; WX 694 ; N uni1FE2 ; G 1877 +U 8163 ; WX 694 ; N uni1FE3 ; G 1878 +U 8164 ; WX 665 ; N uni1FE4 ; G 1879 +U 8165 ; WX 665 ; N uni1FE5 ; G 1880 +U 8166 ; WX 694 ; N uni1FE6 ; G 1881 +U 8167 ; WX 694 ; N uni1FE7 ; G 1882 +U 8168 ; WX 714 ; N uni1FE8 ; G 1883 +U 8169 ; WX 714 ; N uni1FE9 ; G 1884 +U 8170 ; WX 1019 ; N uni1FEA ; G 1885 +U 8171 ; WX 953 ; N uni1FEB ; G 1886 +U 8172 ; WX 910 ; N uni1FEC ; G 1887 +U 8173 ; WX 500 ; N uni1FED ; G 1888 +U 8174 ; WX 500 ; N uni1FEE ; G 1889 +U 8175 ; WX 500 ; N uni1FEF ; G 1890 +U 8178 ; WX 952 ; N uni1FF2 ; G 1891 +U 8179 ; WX 952 ; N uni1FF3 ; G 1892 +U 8180 ; WX 952 ; N uni1FF4 ; G 1893 +U 8182 ; WX 952 ; N uni1FF6 ; G 1894 +U 8183 ; WX 952 ; N uni1FF7 ; G 1895 +U 8184 ; WX 1069 ; N uni1FF8 ; G 1896 +U 8185 ; WX 887 ; N uni1FF9 ; G 1897 +U 8186 ; WX 1101 ; N uni1FFA ; G 1898 +U 8187 ; WX 911 ; N uni1FFB ; G 1899 +U 8188 ; WX 890 ; N uni1FFC ; G 1900 +U 8189 ; WX 500 ; N uni1FFD ; G 1901 +U 8190 ; WX 500 ; N uni1FFE ; G 1902 +U 8192 ; WX 500 ; N uni2000 ; G 1903 +U 8193 ; WX 1000 ; N uni2001 ; G 1904 +U 8194 ; WX 500 ; N uni2002 ; G 1905 +U 8195 ; WX 1000 ; N uni2003 ; G 1906 +U 8196 ; WX 330 ; N uni2004 ; G 1907 +U 8197 ; WX 250 ; N uni2005 ; G 1908 +U 8198 ; WX 167 ; N uni2006 ; G 1909 +U 8199 ; WX 696 ; N uni2007 ; G 1910 +U 8200 ; WX 348 ; N uni2008 ; G 1911 +U 8201 ; WX 200 ; N uni2009 ; G 1912 +U 8202 ; WX 100 ; N uni200A ; G 1913 +U 8203 ; WX 0 ; N uni200B ; G 1914 +U 8204 ; WX 0 ; N uni200C ; G 1915 +U 8205 ; WX 0 ; N uni200D ; G 1916 +U 8206 ; WX 0 ; N uni200E ; G 1917 +U 8207 ; WX 0 ; N uni200F ; G 1918 +U 8208 ; WX 415 ; N uni2010 ; G 1919 +U 8209 ; WX 415 ; N uni2011 ; G 1920 +U 8210 ; WX 696 ; N figuredash ; G 1921 +U 8211 ; WX 500 ; N endash ; G 1922 +U 8212 ; WX 1000 ; N emdash ; G 1923 +U 8213 ; WX 1000 ; N uni2015 ; G 1924 +U 8214 ; WX 500 ; N uni2016 ; G 1925 +U 8215 ; WX 500 ; N underscoredbl ; G 1926 +U 8216 ; WX 348 ; N quoteleft ; G 1927 +U 8217 ; WX 348 ; N quoteright ; G 1928 +U 8218 ; WX 348 ; N quotesinglbase ; G 1929 +U 8219 ; WX 348 ; N quotereversed ; G 1930 +U 8220 ; WX 575 ; N quotedblleft ; G 1931 +U 8221 ; WX 575 ; N quotedblright ; G 1932 +U 8222 ; WX 575 ; N quotedblbase ; G 1933 +U 8223 ; WX 575 ; N uni201F ; G 1934 +U 8224 ; WX 523 ; N dagger ; G 1935 +U 8225 ; WX 523 ; N daggerdbl ; G 1936 +U 8226 ; WX 639 ; N bullet ; G 1937 +U 8227 ; WX 639 ; N uni2023 ; G 1938 +U 8228 ; WX 348 ; N onedotenleader ; G 1939 +U 8229 ; WX 674 ; N twodotenleader ; G 1940 +U 8230 ; WX 1000 ; N ellipsis ; G 1941 +U 8234 ; WX 0 ; N uni202A ; G 1942 +U 8235 ; WX 0 ; N uni202B ; G 1943 +U 8236 ; WX 0 ; N uni202C ; G 1944 +U 8237 ; WX 0 ; N uni202D ; G 1945 +U 8238 ; WX 0 ; N uni202E ; G 1946 +U 8239 ; WX 200 ; N uni202F ; G 1947 +U 8240 ; WX 1385 ; N perthousand ; G 1948 +U 8241 ; WX 1820 ; N uni2031 ; G 1949 +U 8242 ; WX 264 ; N minute ; G 1950 +U 8243 ; WX 447 ; N second ; G 1951 +U 8244 ; WX 630 ; N uni2034 ; G 1952 +U 8245 ; WX 264 ; N uni2035 ; G 1953 +U 8246 ; WX 447 ; N uni2036 ; G 1954 +U 8247 ; WX 630 ; N uni2037 ; G 1955 +U 8248 ; WX 733 ; N uni2038 ; G 1956 +U 8249 ; WX 400 ; N guilsinglleft ; G 1957 +U 8250 ; WX 400 ; N guilsinglright ; G 1958 +U 8252 ; WX 629 ; N exclamdbl ; G 1959 +U 8253 ; WX 586 ; N uni203D ; G 1960 +U 8254 ; WX 500 ; N uni203E ; G 1961 +U 8258 ; WX 1023 ; N uni2042 ; G 1962 +U 8260 ; WX 167 ; N fraction ; G 1963 +U 8261 ; WX 473 ; N uni2045 ; G 1964 +U 8262 ; WX 473 ; N uni2046 ; G 1965 +U 8263 ; WX 1082 ; N uni2047 ; G 1966 +U 8264 ; WX 856 ; N uni2048 ; G 1967 +U 8265 ; WX 856 ; N uni2049 ; G 1968 +U 8267 ; WX 636 ; N uni204B ; G 1969 +U 8268 ; WX 500 ; N uni204C ; G 1970 +U 8269 ; WX 500 ; N uni204D ; G 1971 +U 8270 ; WX 523 ; N uni204E ; G 1972 +U 8271 ; WX 369 ; N uni204F ; G 1973 +U 8273 ; WX 523 ; N uni2051 ; G 1974 +U 8274 ; WX 556 ; N uni2052 ; G 1975 +U 8275 ; WX 1000 ; N uni2053 ; G 1976 +U 8279 ; WX 813 ; N uni2057 ; G 1977 +U 8287 ; WX 222 ; N uni205F ; G 1978 +U 8288 ; WX 0 ; N uni2060 ; G 1979 +U 8289 ; WX 0 ; N uni2061 ; G 1980 +U 8290 ; WX 0 ; N uni2062 ; G 1981 +U 8291 ; WX 0 ; N uni2063 ; G 1982 +U 8292 ; WX 0 ; N uni2064 ; G 1983 +U 8298 ; WX 0 ; N uni206A ; G 1984 +U 8299 ; WX 0 ; N uni206B ; G 1985 +U 8300 ; WX 0 ; N uni206C ; G 1986 +U 8301 ; WX 0 ; N uni206D ; G 1987 +U 8302 ; WX 0 ; N uni206E ; G 1988 +U 8303 ; WX 0 ; N uni206F ; G 1989 +U 8304 ; WX 438 ; N uni2070 ; G 1990 +U 8305 ; WX 239 ; N uni2071 ; G 1991 +U 8308 ; WX 438 ; N uni2074 ; G 1992 +U 8309 ; WX 438 ; N uni2075 ; G 1993 +U 8310 ; WX 438 ; N uni2076 ; G 1994 +U 8311 ; WX 438 ; N uni2077 ; G 1995 +U 8312 ; WX 438 ; N uni2078 ; G 1996 +U 8313 ; WX 438 ; N uni2079 ; G 1997 +U 8314 ; WX 528 ; N uni207A ; G 1998 +U 8315 ; WX 528 ; N uni207B ; G 1999 +U 8316 ; WX 528 ; N uni207C ; G 2000 +U 8317 ; WX 298 ; N uni207D ; G 2001 +U 8318 ; WX 298 ; N uni207E ; G 2002 +U 8319 ; WX 519 ; N uni207F ; G 2003 +U 8320 ; WX 438 ; N uni2080 ; G 2004 +U 8321 ; WX 438 ; N uni2081 ; G 2005 +U 8322 ; WX 438 ; N uni2082 ; G 2006 +U 8323 ; WX 438 ; N uni2083 ; G 2007 +U 8324 ; WX 438 ; N uni2084 ; G 2008 +U 8325 ; WX 438 ; N uni2085 ; G 2009 +U 8326 ; WX 438 ; N uni2086 ; G 2010 +U 8327 ; WX 438 ; N uni2087 ; G 2011 +U 8328 ; WX 438 ; N uni2088 ; G 2012 +U 8329 ; WX 438 ; N uni2089 ; G 2013 +U 8330 ; WX 528 ; N uni208A ; G 2014 +U 8331 ; WX 528 ; N uni208B ; G 2015 +U 8332 ; WX 528 ; N uni208C ; G 2016 +U 8333 ; WX 298 ; N uni208D ; G 2017 +U 8334 ; WX 298 ; N uni208E ; G 2018 +U 8336 ; WX 466 ; N uni2090 ; G 2019 +U 8337 ; WX 444 ; N uni2091 ; G 2020 +U 8338 ; WX 467 ; N uni2092 ; G 2021 +U 8339 ; WX 475 ; N uni2093 ; G 2022 +U 8340 ; WX 444 ; N uni2094 ; G 2023 +U 8341 ; WX 521 ; N uni2095 ; G 2024 +U 8342 ; WX 523 ; N uni2096 ; G 2025 +U 8343 ; WX 292 ; N uni2097 ; G 2026 +U 8344 ; WX 729 ; N uni2098 ; G 2027 +U 8345 ; WX 519 ; N uni2099 ; G 2028 +U 8346 ; WX 499 ; N uni209A ; G 2029 +U 8347 ; WX 395 ; N uni209B ; G 2030 +U 8348 ; WX 371 ; N uni209C ; G 2031 +U 8358 ; WX 696 ; N uni20A6 ; G 2032 +U 8364 ; WX 696 ; N Euro ; G 2033 +U 8367 ; WX 1155 ; N uni20AF ; G 2034 +U 8369 ; WX 790 ; N uni20B1 ; G 2035 +U 8372 ; WX 876 ; N uni20B4 ; G 2036 +U 8373 ; WX 696 ; N uni20B5 ; G 2037 +U 8376 ; WX 696 ; N uni20B8 ; G 2038 +U 8377 ; WX 696 ; N uni20B9 ; G 2039 +U 8378 ; WX 696 ; N uni20BA ; G 2040 +U 8381 ; WX 696 ; N uni20BD ; G 2041 +U 8451 ; WX 1198 ; N uni2103 ; G 2042 +U 8457 ; WX 1112 ; N uni2109 ; G 2043 +U 8462 ; WX 727 ; N uni210E ; G 2044 +U 8463 ; WX 727 ; N uni210F ; G 2045 +U 8470 ; WX 1087 ; N uni2116 ; G 2046 +U 8482 ; WX 1000 ; N trademark ; G 2047 +U 8486 ; WX 890 ; N uni2126 ; G 2048 +U 8487 ; WX 890 ; N uni2127 ; G 2049 +U 8490 ; WX 869 ; N uni212A ; G 2050 +U 8491 ; WX 776 ; N uni212B ; G 2051 +U 8498 ; WX 710 ; N uni2132 ; G 2052 +U 8513 ; WX 775 ; N uni2141 ; G 2053 +U 8514 ; WX 557 ; N uni2142 ; G 2054 +U 8515 ; WX 637 ; N uni2143 ; G 2055 +U 8516 ; WX 760 ; N uni2144 ; G 2056 +U 8523 ; WX 903 ; N uni214B ; G 2057 +U 8526 ; WX 592 ; N uni214E ; G 2058 +U 8528 ; WX 1035 ; N uni2150 ; G 2059 +U 8529 ; WX 1035 ; N uni2151 ; G 2060 +U 8530 ; WX 1473 ; N uni2152 ; G 2061 +U 8531 ; WX 1035 ; N onethird ; G 2062 +U 8532 ; WX 1035 ; N twothirds ; G 2063 +U 8533 ; WX 1035 ; N uni2155 ; G 2064 +U 8534 ; WX 1035 ; N uni2156 ; G 2065 +U 8535 ; WX 1035 ; N uni2157 ; G 2066 +U 8536 ; WX 1035 ; N uni2158 ; G 2067 +U 8537 ; WX 1035 ; N uni2159 ; G 2068 +U 8538 ; WX 1035 ; N uni215A ; G 2069 +U 8539 ; WX 1035 ; N oneeighth ; G 2070 +U 8540 ; WX 1035 ; N threeeighths ; G 2071 +U 8541 ; WX 1035 ; N fiveeighths ; G 2072 +U 8542 ; WX 1035 ; N seveneighths ; G 2073 +U 8543 ; WX 615 ; N uni215F ; G 2074 +U 8544 ; WX 468 ; N uni2160 ; G 2075 +U 8545 ; WX 843 ; N uni2161 ; G 2076 +U 8546 ; WX 1218 ; N uni2162 ; G 2077 +U 8547 ; WX 1135 ; N uni2163 ; G 2078 +U 8548 ; WX 776 ; N uni2164 ; G 2079 +U 8549 ; WX 1150 ; N uni2165 ; G 2080 +U 8550 ; WX 1525 ; N uni2166 ; G 2081 +U 8551 ; WX 1900 ; N uni2167 ; G 2082 +U 8552 ; WX 1126 ; N uni2168 ; G 2083 +U 8553 ; WX 776 ; N uni2169 ; G 2084 +U 8554 ; WX 1127 ; N uni216A ; G 2085 +U 8555 ; WX 1502 ; N uni216B ; G 2086 +U 8556 ; WX 703 ; N uni216C ; G 2087 +U 8557 ; WX 796 ; N uni216D ; G 2088 +U 8558 ; WX 867 ; N uni216E ; G 2089 +U 8559 ; WX 1107 ; N uni216F ; G 2090 +U 8560 ; WX 380 ; N uni2170 ; G 2091 +U 8561 ; WX 760 ; N uni2171 ; G 2092 +U 8562 ; WX 1140 ; N uni2172 ; G 2093 +U 8563 ; WX 961 ; N uni2173 ; G 2094 +U 8564 ; WX 581 ; N uni2174 ; G 2095 +U 8565 ; WX 961 ; N uni2175 ; G 2096 +U 8566 ; WX 1341 ; N uni2176 ; G 2097 +U 8567 ; WX 1721 ; N uni2177 ; G 2098 +U 8568 ; WX 976 ; N uni2178 ; G 2099 +U 8569 ; WX 596 ; N uni2179 ; G 2100 +U 8570 ; WX 976 ; N uni217A ; G 2101 +U 8571 ; WX 1356 ; N uni217B ; G 2102 +U 8572 ; WX 380 ; N uni217C ; G 2103 +U 8573 ; WX 609 ; N uni217D ; G 2104 +U 8574 ; WX 699 ; N uni217E ; G 2105 +U 8575 ; WX 1058 ; N uni217F ; G 2106 +U 8576 ; WX 1255 ; N uni2180 ; G 2107 +U 8577 ; WX 867 ; N uni2181 ; G 2108 +U 8578 ; WX 1268 ; N uni2182 ; G 2109 +U 8579 ; WX 796 ; N uni2183 ; G 2110 +U 8580 ; WX 609 ; N uni2184 ; G 2111 +U 8581 ; WX 796 ; N uni2185 ; G 2112 +U 8585 ; WX 1035 ; N uni2189 ; G 2113 +U 8592 ; WX 838 ; N arrowleft ; G 2114 +U 8593 ; WX 838 ; N arrowup ; G 2115 +U 8594 ; WX 838 ; N arrowright ; G 2116 +U 8595 ; WX 838 ; N arrowdown ; G 2117 +U 8596 ; WX 838 ; N arrowboth ; G 2118 +U 8597 ; WX 838 ; N arrowupdn ; G 2119 +U 8598 ; WX 838 ; N uni2196 ; G 2120 +U 8599 ; WX 838 ; N uni2197 ; G 2121 +U 8600 ; WX 838 ; N uni2198 ; G 2122 +U 8601 ; WX 838 ; N uni2199 ; G 2123 +U 8602 ; WX 838 ; N uni219A ; G 2124 +U 8603 ; WX 838 ; N uni219B ; G 2125 +U 8604 ; WX 838 ; N uni219C ; G 2126 +U 8605 ; WX 838 ; N uni219D ; G 2127 +U 8606 ; WX 838 ; N uni219E ; G 2128 +U 8607 ; WX 838 ; N uni219F ; G 2129 +U 8608 ; WX 838 ; N uni21A0 ; G 2130 +U 8609 ; WX 838 ; N uni21A1 ; G 2131 +U 8610 ; WX 838 ; N uni21A2 ; G 2132 +U 8611 ; WX 838 ; N uni21A3 ; G 2133 +U 8612 ; WX 838 ; N uni21A4 ; G 2134 +U 8613 ; WX 838 ; N uni21A5 ; G 2135 +U 8614 ; WX 838 ; N uni21A6 ; G 2136 +U 8615 ; WX 838 ; N uni21A7 ; G 2137 +U 8616 ; WX 838 ; N arrowupdnbse ; G 2138 +U 8617 ; WX 838 ; N uni21A9 ; G 2139 +U 8618 ; WX 838 ; N uni21AA ; G 2140 +U 8619 ; WX 838 ; N uni21AB ; G 2141 +U 8620 ; WX 838 ; N uni21AC ; G 2142 +U 8621 ; WX 838 ; N uni21AD ; G 2143 +U 8622 ; WX 838 ; N uni21AE ; G 2144 +U 8623 ; WX 850 ; N uni21AF ; G 2145 +U 8624 ; WX 838 ; N uni21B0 ; G 2146 +U 8625 ; WX 838 ; N uni21B1 ; G 2147 +U 8626 ; WX 838 ; N uni21B2 ; G 2148 +U 8627 ; WX 838 ; N uni21B3 ; G 2149 +U 8628 ; WX 838 ; N uni21B4 ; G 2150 +U 8629 ; WX 838 ; N carriagereturn ; G 2151 +U 8630 ; WX 838 ; N uni21B6 ; G 2152 +U 8631 ; WX 838 ; N uni21B7 ; G 2153 +U 8632 ; WX 838 ; N uni21B8 ; G 2154 +U 8633 ; WX 838 ; N uni21B9 ; G 2155 +U 8634 ; WX 838 ; N uni21BA ; G 2156 +U 8635 ; WX 838 ; N uni21BB ; G 2157 +U 8636 ; WX 838 ; N uni21BC ; G 2158 +U 8637 ; WX 838 ; N uni21BD ; G 2159 +U 8638 ; WX 838 ; N uni21BE ; G 2160 +U 8639 ; WX 838 ; N uni21BF ; G 2161 +U 8640 ; WX 838 ; N uni21C0 ; G 2162 +U 8641 ; WX 838 ; N uni21C1 ; G 2163 +U 8642 ; WX 838 ; N uni21C2 ; G 2164 +U 8643 ; WX 838 ; N uni21C3 ; G 2165 +U 8644 ; WX 838 ; N uni21C4 ; G 2166 +U 8645 ; WX 838 ; N uni21C5 ; G 2167 +U 8646 ; WX 838 ; N uni21C6 ; G 2168 +U 8647 ; WX 838 ; N uni21C7 ; G 2169 +U 8648 ; WX 838 ; N uni21C8 ; G 2170 +U 8649 ; WX 838 ; N uni21C9 ; G 2171 +U 8650 ; WX 838 ; N uni21CA ; G 2172 +U 8651 ; WX 838 ; N uni21CB ; G 2173 +U 8652 ; WX 838 ; N uni21CC ; G 2174 +U 8653 ; WX 838 ; N uni21CD ; G 2175 +U 8654 ; WX 838 ; N uni21CE ; G 2176 +U 8655 ; WX 838 ; N uni21CF ; G 2177 +U 8656 ; WX 838 ; N arrowdblleft ; G 2178 +U 8657 ; WX 838 ; N arrowdblup ; G 2179 +U 8658 ; WX 838 ; N arrowdblright ; G 2180 +U 8659 ; WX 838 ; N arrowdbldown ; G 2181 +U 8660 ; WX 838 ; N arrowdblboth ; G 2182 +U 8661 ; WX 838 ; N uni21D5 ; G 2183 +U 8662 ; WX 838 ; N uni21D6 ; G 2184 +U 8663 ; WX 838 ; N uni21D7 ; G 2185 +U 8664 ; WX 838 ; N uni21D8 ; G 2186 +U 8665 ; WX 838 ; N uni21D9 ; G 2187 +U 8666 ; WX 838 ; N uni21DA ; G 2188 +U 8667 ; WX 838 ; N uni21DB ; G 2189 +U 8668 ; WX 838 ; N uni21DC ; G 2190 +U 8669 ; WX 838 ; N uni21DD ; G 2191 +U 8670 ; WX 838 ; N uni21DE ; G 2192 +U 8671 ; WX 838 ; N uni21DF ; G 2193 +U 8672 ; WX 838 ; N uni21E0 ; G 2194 +U 8673 ; WX 838 ; N uni21E1 ; G 2195 +U 8674 ; WX 838 ; N uni21E2 ; G 2196 +U 8675 ; WX 838 ; N uni21E3 ; G 2197 +U 8676 ; WX 838 ; N uni21E4 ; G 2198 +U 8677 ; WX 838 ; N uni21E5 ; G 2199 +U 8678 ; WX 838 ; N uni21E6 ; G 2200 +U 8679 ; WX 838 ; N uni21E7 ; G 2201 +U 8680 ; WX 838 ; N uni21E8 ; G 2202 +U 8681 ; WX 838 ; N uni21E9 ; G 2203 +U 8682 ; WX 838 ; N uni21EA ; G 2204 +U 8683 ; WX 838 ; N uni21EB ; G 2205 +U 8684 ; WX 838 ; N uni21EC ; G 2206 +U 8685 ; WX 838 ; N uni21ED ; G 2207 +U 8686 ; WX 838 ; N uni21EE ; G 2208 +U 8687 ; WX 838 ; N uni21EF ; G 2209 +U 8688 ; WX 838 ; N uni21F0 ; G 2210 +U 8689 ; WX 838 ; N uni21F1 ; G 2211 +U 8690 ; WX 838 ; N uni21F2 ; G 2212 +U 8691 ; WX 838 ; N uni21F3 ; G 2213 +U 8692 ; WX 838 ; N uni21F4 ; G 2214 +U 8693 ; WX 838 ; N uni21F5 ; G 2215 +U 8694 ; WX 838 ; N uni21F6 ; G 2216 +U 8695 ; WX 838 ; N uni21F7 ; G 2217 +U 8696 ; WX 838 ; N uni21F8 ; G 2218 +U 8697 ; WX 838 ; N uni21F9 ; G 2219 +U 8698 ; WX 838 ; N uni21FA ; G 2220 +U 8699 ; WX 838 ; N uni21FB ; G 2221 +U 8700 ; WX 838 ; N uni21FC ; G 2222 +U 8701 ; WX 838 ; N uni21FD ; G 2223 +U 8702 ; WX 838 ; N uni21FE ; G 2224 +U 8703 ; WX 838 ; N uni21FF ; G 2225 +U 8704 ; WX 641 ; N universal ; G 2226 +U 8706 ; WX 534 ; N partialdiff ; G 2227 +U 8707 ; WX 620 ; N existential ; G 2228 +U 8708 ; WX 620 ; N uni2204 ; G 2229 +U 8710 ; WX 753 ; N increment ; G 2230 +U 8711 ; WX 753 ; N gradient ; G 2231 +U 8712 ; WX 740 ; N element ; G 2232 +U 8713 ; WX 740 ; N notelement ; G 2233 +U 8715 ; WX 740 ; N suchthat ; G 2234 +U 8716 ; WX 740 ; N uni220C ; G 2235 +U 8719 ; WX 842 ; N product ; G 2236 +U 8720 ; WX 842 ; N uni2210 ; G 2237 +U 8721 ; WX 753 ; N summation ; G 2238 +U 8722 ; WX 838 ; N minus ; G 2239 +U 8723 ; WX 838 ; N uni2213 ; G 2240 +U 8724 ; WX 838 ; N uni2214 ; G 2241 +U 8725 ; WX 365 ; N uni2215 ; G 2242 +U 8727 ; WX 691 ; N asteriskmath ; G 2243 +U 8728 ; WX 519 ; N uni2218 ; G 2244 +U 8729 ; WX 519 ; N uni2219 ; G 2245 +U 8730 ; WX 657 ; N radical ; G 2246 +U 8731 ; WX 657 ; N uni221B ; G 2247 +U 8732 ; WX 657 ; N uni221C ; G 2248 +U 8733 ; WX 672 ; N proportional ; G 2249 +U 8734 ; WX 833 ; N infinity ; G 2250 +U 8735 ; WX 838 ; N orthogonal ; G 2251 +U 8736 ; WX 838 ; N angle ; G 2252 +U 8739 ; WX 324 ; N uni2223 ; G 2253 +U 8740 ; WX 607 ; N uni2224 ; G 2254 +U 8741 ; WX 529 ; N uni2225 ; G 2255 +U 8742 ; WX 773 ; N uni2226 ; G 2256 +U 8743 ; WX 812 ; N logicaland ; G 2257 +U 8744 ; WX 812 ; N logicalor ; G 2258 +U 8745 ; WX 838 ; N intersection ; G 2259 +U 8746 ; WX 838 ; N union ; G 2260 +U 8747 ; WX 579 ; N integral ; G 2261 +U 8748 ; WX 1000 ; N uni222C ; G 2262 +U 8749 ; WX 1391 ; N uni222D ; G 2263 +U 8760 ; WX 838 ; N uni2238 ; G 2264 +U 8761 ; WX 838 ; N uni2239 ; G 2265 +U 8762 ; WX 838 ; N uni223A ; G 2266 +U 8763 ; WX 838 ; N uni223B ; G 2267 +U 8764 ; WX 838 ; N similar ; G 2268 +U 8765 ; WX 838 ; N uni223D ; G 2269 +U 8770 ; WX 838 ; N uni2242 ; G 2270 +U 8771 ; WX 838 ; N uni2243 ; G 2271 +U 8776 ; WX 838 ; N approxequal ; G 2272 +U 8784 ; WX 838 ; N uni2250 ; G 2273 +U 8785 ; WX 838 ; N uni2251 ; G 2274 +U 8786 ; WX 838 ; N uni2252 ; G 2275 +U 8787 ; WX 838 ; N uni2253 ; G 2276 +U 8788 ; WX 1082 ; N uni2254 ; G 2277 +U 8789 ; WX 1082 ; N uni2255 ; G 2278 +U 8800 ; WX 838 ; N notequal ; G 2279 +U 8801 ; WX 838 ; N equivalence ; G 2280 +U 8804 ; WX 838 ; N lessequal ; G 2281 +U 8805 ; WX 838 ; N greaterequal ; G 2282 +U 8834 ; WX 838 ; N propersubset ; G 2283 +U 8835 ; WX 838 ; N propersuperset ; G 2284 +U 8836 ; WX 838 ; N notsubset ; G 2285 +U 8837 ; WX 838 ; N uni2285 ; G 2286 +U 8838 ; WX 838 ; N reflexsubset ; G 2287 +U 8839 ; WX 838 ; N reflexsuperset ; G 2288 +U 8844 ; WX 838 ; N uni228C ; G 2289 +U 8845 ; WX 838 ; N uni228D ; G 2290 +U 8846 ; WX 838 ; N uni228E ; G 2291 +U 8847 ; WX 838 ; N uni228F ; G 2292 +U 8848 ; WX 838 ; N uni2290 ; G 2293 +U 8849 ; WX 838 ; N uni2291 ; G 2294 +U 8850 ; WX 838 ; N uni2292 ; G 2295 +U 8851 ; WX 838 ; N uni2293 ; G 2296 +U 8852 ; WX 838 ; N uni2294 ; G 2297 +U 8853 ; WX 838 ; N circleplus ; G 2298 +U 8854 ; WX 838 ; N uni2296 ; G 2299 +U 8855 ; WX 838 ; N circlemultiply ; G 2300 +U 8856 ; WX 838 ; N uni2298 ; G 2301 +U 8857 ; WX 838 ; N uni2299 ; G 2302 +U 8858 ; WX 838 ; N uni229A ; G 2303 +U 8859 ; WX 838 ; N uni229B ; G 2304 +U 8860 ; WX 838 ; N uni229C ; G 2305 +U 8861 ; WX 838 ; N uni229D ; G 2306 +U 8862 ; WX 838 ; N uni229E ; G 2307 +U 8863 ; WX 838 ; N uni229F ; G 2308 +U 8864 ; WX 838 ; N uni22A0 ; G 2309 +U 8865 ; WX 838 ; N uni22A1 ; G 2310 +U 8866 ; WX 884 ; N uni22A2 ; G 2311 +U 8867 ; WX 884 ; N uni22A3 ; G 2312 +U 8868 ; WX 960 ; N uni22A4 ; G 2313 +U 8869 ; WX 960 ; N perpendicular ; G 2314 +U 8870 ; WX 616 ; N uni22A6 ; G 2315 +U 8871 ; WX 616 ; N uni22A7 ; G 2316 +U 8872 ; WX 884 ; N uni22A8 ; G 2317 +U 8873 ; WX 884 ; N uni22A9 ; G 2318 +U 8874 ; WX 884 ; N uni22AA ; G 2319 +U 8875 ; WX 1080 ; N uni22AB ; G 2320 +U 8876 ; WX 884 ; N uni22AC ; G 2321 +U 8877 ; WX 884 ; N uni22AD ; G 2322 +U 8878 ; WX 884 ; N uni22AE ; G 2323 +U 8879 ; WX 1080 ; N uni22AF ; G 2324 +U 8900 ; WX 626 ; N uni22C4 ; G 2325 +U 8901 ; WX 398 ; N dotmath ; G 2326 +U 8962 ; WX 834 ; N house ; G 2327 +U 8968 ; WX 473 ; N uni2308 ; G 2328 +U 8969 ; WX 473 ; N uni2309 ; G 2329 +U 8970 ; WX 473 ; N uni230A ; G 2330 +U 8971 ; WX 473 ; N uni230B ; G 2331 +U 8976 ; WX 838 ; N revlogicalnot ; G 2332 +U 8977 ; WX 539 ; N uni2311 ; G 2333 +U 8984 ; WX 928 ; N uni2318 ; G 2334 +U 8985 ; WX 838 ; N uni2319 ; G 2335 +U 8992 ; WX 579 ; N integraltp ; G 2336 +U 8993 ; WX 579 ; N integralbt ; G 2337 +U 8997 ; WX 1000 ; N uni2325 ; G 2338 +U 9000 ; WX 1443 ; N uni2328 ; G 2339 +U 9085 ; WX 1008 ; N uni237D ; G 2340 +U 9115 ; WX 500 ; N uni239B ; G 2341 +U 9116 ; WX 500 ; N uni239C ; G 2342 +U 9117 ; WX 500 ; N uni239D ; G 2343 +U 9118 ; WX 500 ; N uni239E ; G 2344 +U 9119 ; WX 500 ; N uni239F ; G 2345 +U 9120 ; WX 500 ; N uni23A0 ; G 2346 +U 9121 ; WX 500 ; N uni23A1 ; G 2347 +U 9122 ; WX 500 ; N uni23A2 ; G 2348 +U 9123 ; WX 500 ; N uni23A3 ; G 2349 +U 9124 ; WX 500 ; N uni23A4 ; G 2350 +U 9125 ; WX 500 ; N uni23A5 ; G 2351 +U 9126 ; WX 500 ; N uni23A6 ; G 2352 +U 9127 ; WX 750 ; N uni23A7 ; G 2353 +U 9128 ; WX 750 ; N uni23A8 ; G 2354 +U 9129 ; WX 750 ; N uni23A9 ; G 2355 +U 9130 ; WX 750 ; N uni23AA ; G 2356 +U 9131 ; WX 750 ; N uni23AB ; G 2357 +U 9132 ; WX 750 ; N uni23AC ; G 2358 +U 9133 ; WX 750 ; N uni23AD ; G 2359 +U 9134 ; WX 579 ; N uni23AE ; G 2360 +U 9167 ; WX 945 ; N uni23CF ; G 2361 +U 9251 ; WX 834 ; N uni2423 ; G 2362 +U 9472 ; WX 602 ; N SF100000 ; G 2363 +U 9473 ; WX 602 ; N uni2501 ; G 2364 +U 9474 ; WX 602 ; N SF110000 ; G 2365 +U 9475 ; WX 602 ; N uni2503 ; G 2366 +U 9476 ; WX 602 ; N uni2504 ; G 2367 +U 9477 ; WX 602 ; N uni2505 ; G 2368 +U 9478 ; WX 602 ; N uni2506 ; G 2369 +U 9479 ; WX 602 ; N uni2507 ; G 2370 +U 9480 ; WX 602 ; N uni2508 ; G 2371 +U 9481 ; WX 602 ; N uni2509 ; G 2372 +U 9482 ; WX 602 ; N uni250A ; G 2373 +U 9483 ; WX 602 ; N uni250B ; G 2374 +U 9484 ; WX 602 ; N SF010000 ; G 2375 +U 9485 ; WX 602 ; N uni250D ; G 2376 +U 9486 ; WX 602 ; N uni250E ; G 2377 +U 9487 ; WX 602 ; N uni250F ; G 2378 +U 9488 ; WX 602 ; N SF030000 ; G 2379 +U 9489 ; WX 602 ; N uni2511 ; G 2380 +U 9490 ; WX 602 ; N uni2512 ; G 2381 +U 9491 ; WX 602 ; N uni2513 ; G 2382 +U 9492 ; WX 602 ; N SF020000 ; G 2383 +U 9493 ; WX 602 ; N uni2515 ; G 2384 +U 9494 ; WX 602 ; N uni2516 ; G 2385 +U 9495 ; WX 602 ; N uni2517 ; G 2386 +U 9496 ; WX 602 ; N SF040000 ; G 2387 +U 9497 ; WX 602 ; N uni2519 ; G 2388 +U 9498 ; WX 602 ; N uni251A ; G 2389 +U 9499 ; WX 602 ; N uni251B ; G 2390 +U 9500 ; WX 602 ; N SF080000 ; G 2391 +U 9501 ; WX 602 ; N uni251D ; G 2392 +U 9502 ; WX 602 ; N uni251E ; G 2393 +U 9503 ; WX 602 ; N uni251F ; G 2394 +U 9504 ; WX 602 ; N uni2520 ; G 2395 +U 9505 ; WX 602 ; N uni2521 ; G 2396 +U 9506 ; WX 602 ; N uni2522 ; G 2397 +U 9507 ; WX 602 ; N uni2523 ; G 2398 +U 9508 ; WX 602 ; N SF090000 ; G 2399 +U 9509 ; WX 602 ; N uni2525 ; G 2400 +U 9510 ; WX 602 ; N uni2526 ; G 2401 +U 9511 ; WX 602 ; N uni2527 ; G 2402 +U 9512 ; WX 602 ; N uni2528 ; G 2403 +U 9513 ; WX 602 ; N uni2529 ; G 2404 +U 9514 ; WX 602 ; N uni252A ; G 2405 +U 9515 ; WX 602 ; N uni252B ; G 2406 +U 9516 ; WX 602 ; N SF060000 ; G 2407 +U 9517 ; WX 602 ; N uni252D ; G 2408 +U 9518 ; WX 602 ; N uni252E ; G 2409 +U 9519 ; WX 602 ; N uni252F ; G 2410 +U 9520 ; WX 602 ; N uni2530 ; G 2411 +U 9521 ; WX 602 ; N uni2531 ; G 2412 +U 9522 ; WX 602 ; N uni2532 ; G 2413 +U 9523 ; WX 602 ; N uni2533 ; G 2414 +U 9524 ; WX 602 ; N SF070000 ; G 2415 +U 9525 ; WX 602 ; N uni2535 ; G 2416 +U 9526 ; WX 602 ; N uni2536 ; G 2417 +U 9527 ; WX 602 ; N uni2537 ; G 2418 +U 9528 ; WX 602 ; N uni2538 ; G 2419 +U 9529 ; WX 602 ; N uni2539 ; G 2420 +U 9530 ; WX 602 ; N uni253A ; G 2421 +U 9531 ; WX 602 ; N uni253B ; G 2422 +U 9532 ; WX 602 ; N SF050000 ; G 2423 +U 9533 ; WX 602 ; N uni253D ; G 2424 +U 9534 ; WX 602 ; N uni253E ; G 2425 +U 9535 ; WX 602 ; N uni253F ; G 2426 +U 9536 ; WX 602 ; N uni2540 ; G 2427 +U 9537 ; WX 602 ; N uni2541 ; G 2428 +U 9538 ; WX 602 ; N uni2542 ; G 2429 +U 9539 ; WX 602 ; N uni2543 ; G 2430 +U 9540 ; WX 602 ; N uni2544 ; G 2431 +U 9541 ; WX 602 ; N uni2545 ; G 2432 +U 9542 ; WX 602 ; N uni2546 ; G 2433 +U 9543 ; WX 602 ; N uni2547 ; G 2434 +U 9544 ; WX 602 ; N uni2548 ; G 2435 +U 9545 ; WX 602 ; N uni2549 ; G 2436 +U 9546 ; WX 602 ; N uni254A ; G 2437 +U 9547 ; WX 602 ; N uni254B ; G 2438 +U 9548 ; WX 602 ; N uni254C ; G 2439 +U 9549 ; WX 602 ; N uni254D ; G 2440 +U 9550 ; WX 602 ; N uni254E ; G 2441 +U 9551 ; WX 602 ; N uni254F ; G 2442 +U 9552 ; WX 602 ; N SF430000 ; G 2443 +U 9553 ; WX 602 ; N SF240000 ; G 2444 +U 9554 ; WX 602 ; N SF510000 ; G 2445 +U 9555 ; WX 602 ; N SF520000 ; G 2446 +U 9556 ; WX 602 ; N SF390000 ; G 2447 +U 9557 ; WX 602 ; N SF220000 ; G 2448 +U 9558 ; WX 602 ; N SF210000 ; G 2449 +U 9559 ; WX 602 ; N SF250000 ; G 2450 +U 9560 ; WX 602 ; N SF500000 ; G 2451 +U 9561 ; WX 602 ; N SF490000 ; G 2452 +U 9562 ; WX 602 ; N SF380000 ; G 2453 +U 9563 ; WX 602 ; N SF280000 ; G 2454 +U 9564 ; WX 602 ; N SF270000 ; G 2455 +U 9565 ; WX 602 ; N SF260000 ; G 2456 +U 9566 ; WX 602 ; N SF360000 ; G 2457 +U 9567 ; WX 602 ; N SF370000 ; G 2458 +U 9568 ; WX 602 ; N SF420000 ; G 2459 +U 9569 ; WX 602 ; N SF190000 ; G 2460 +U 9570 ; WX 602 ; N SF200000 ; G 2461 +U 9571 ; WX 602 ; N SF230000 ; G 2462 +U 9572 ; WX 602 ; N SF470000 ; G 2463 +U 9573 ; WX 602 ; N SF480000 ; G 2464 +U 9574 ; WX 602 ; N SF410000 ; G 2465 +U 9575 ; WX 602 ; N SF450000 ; G 2466 +U 9576 ; WX 602 ; N SF460000 ; G 2467 +U 9577 ; WX 602 ; N SF400000 ; G 2468 +U 9578 ; WX 602 ; N SF540000 ; G 2469 +U 9579 ; WX 602 ; N SF530000 ; G 2470 +U 9580 ; WX 602 ; N SF440000 ; G 2471 +U 9581 ; WX 602 ; N uni256D ; G 2472 +U 9582 ; WX 602 ; N uni256E ; G 2473 +U 9583 ; WX 602 ; N uni256F ; G 2474 +U 9584 ; WX 602 ; N uni2570 ; G 2475 +U 9585 ; WX 602 ; N uni2571 ; G 2476 +U 9586 ; WX 602 ; N uni2572 ; G 2477 +U 9587 ; WX 602 ; N uni2573 ; G 2478 +U 9588 ; WX 602 ; N uni2574 ; G 2479 +U 9589 ; WX 602 ; N uni2575 ; G 2480 +U 9590 ; WX 602 ; N uni2576 ; G 2481 +U 9591 ; WX 602 ; N uni2577 ; G 2482 +U 9592 ; WX 602 ; N uni2578 ; G 2483 +U 9593 ; WX 602 ; N uni2579 ; G 2484 +U 9594 ; WX 602 ; N uni257A ; G 2485 +U 9595 ; WX 602 ; N uni257B ; G 2486 +U 9596 ; WX 602 ; N uni257C ; G 2487 +U 9597 ; WX 602 ; N uni257D ; G 2488 +U 9598 ; WX 602 ; N uni257E ; G 2489 +U 9599 ; WX 602 ; N uni257F ; G 2490 +U 9600 ; WX 769 ; N upblock ; G 2491 +U 9601 ; WX 769 ; N uni2581 ; G 2492 +U 9602 ; WX 769 ; N uni2582 ; G 2493 +U 9603 ; WX 769 ; N uni2583 ; G 2494 +U 9604 ; WX 769 ; N dnblock ; G 2495 +U 9605 ; WX 769 ; N uni2585 ; G 2496 +U 9606 ; WX 769 ; N uni2586 ; G 2497 +U 9607 ; WX 769 ; N uni2587 ; G 2498 +U 9608 ; WX 769 ; N block ; G 2499 +U 9609 ; WX 769 ; N uni2589 ; G 2500 +U 9610 ; WX 769 ; N uni258A ; G 2501 +U 9611 ; WX 769 ; N uni258B ; G 2502 +U 9612 ; WX 769 ; N lfblock ; G 2503 +U 9613 ; WX 769 ; N uni258D ; G 2504 +U 9614 ; WX 769 ; N uni258E ; G 2505 +U 9615 ; WX 769 ; N uni258F ; G 2506 +U 9616 ; WX 769 ; N rtblock ; G 2507 +U 9617 ; WX 769 ; N ltshade ; G 2508 +U 9618 ; WX 769 ; N shade ; G 2509 +U 9619 ; WX 769 ; N dkshade ; G 2510 +U 9620 ; WX 769 ; N uni2594 ; G 2511 +U 9621 ; WX 769 ; N uni2595 ; G 2512 +U 9622 ; WX 769 ; N uni2596 ; G 2513 +U 9623 ; WX 769 ; N uni2597 ; G 2514 +U 9624 ; WX 769 ; N uni2598 ; G 2515 +U 9625 ; WX 769 ; N uni2599 ; G 2516 +U 9626 ; WX 769 ; N uni259A ; G 2517 +U 9627 ; WX 769 ; N uni259B ; G 2518 +U 9628 ; WX 769 ; N uni259C ; G 2519 +U 9629 ; WX 769 ; N uni259D ; G 2520 +U 9630 ; WX 769 ; N uni259E ; G 2521 +U 9631 ; WX 769 ; N uni259F ; G 2522 +U 9632 ; WX 945 ; N filledbox ; G 2523 +U 9633 ; WX 945 ; N H22073 ; G 2524 +U 9634 ; WX 945 ; N uni25A2 ; G 2525 +U 9635 ; WX 945 ; N uni25A3 ; G 2526 +U 9636 ; WX 945 ; N uni25A4 ; G 2527 +U 9637 ; WX 945 ; N uni25A5 ; G 2528 +U 9638 ; WX 945 ; N uni25A6 ; G 2529 +U 9639 ; WX 945 ; N uni25A7 ; G 2530 +U 9640 ; WX 945 ; N uni25A8 ; G 2531 +U 9641 ; WX 945 ; N uni25A9 ; G 2532 +U 9642 ; WX 678 ; N H18543 ; G 2533 +U 9643 ; WX 678 ; N H18551 ; G 2534 +U 9644 ; WX 945 ; N filledrect ; G 2535 +U 9645 ; WX 945 ; N uni25AD ; G 2536 +U 9646 ; WX 550 ; N uni25AE ; G 2537 +U 9647 ; WX 550 ; N uni25AF ; G 2538 +U 9648 ; WX 769 ; N uni25B0 ; G 2539 +U 9649 ; WX 769 ; N uni25B1 ; G 2540 +U 9650 ; WX 769 ; N triagup ; G 2541 +U 9651 ; WX 769 ; N uni25B3 ; G 2542 +U 9652 ; WX 502 ; N uni25B4 ; G 2543 +U 9653 ; WX 502 ; N uni25B5 ; G 2544 +U 9654 ; WX 769 ; N uni25B6 ; G 2545 +U 9655 ; WX 769 ; N uni25B7 ; G 2546 +U 9656 ; WX 502 ; N uni25B8 ; G 2547 +U 9657 ; WX 502 ; N uni25B9 ; G 2548 +U 9658 ; WX 769 ; N triagrt ; G 2549 +U 9659 ; WX 769 ; N uni25BB ; G 2550 +U 9660 ; WX 769 ; N triagdn ; G 2551 +U 9661 ; WX 769 ; N uni25BD ; G 2552 +U 9662 ; WX 502 ; N uni25BE ; G 2553 +U 9663 ; WX 502 ; N uni25BF ; G 2554 +U 9664 ; WX 769 ; N uni25C0 ; G 2555 +U 9665 ; WX 769 ; N uni25C1 ; G 2556 +U 9666 ; WX 502 ; N uni25C2 ; G 2557 +U 9667 ; WX 502 ; N uni25C3 ; G 2558 +U 9668 ; WX 769 ; N triaglf ; G 2559 +U 9669 ; WX 769 ; N uni25C5 ; G 2560 +U 9670 ; WX 769 ; N uni25C6 ; G 2561 +U 9671 ; WX 769 ; N uni25C7 ; G 2562 +U 9672 ; WX 769 ; N uni25C8 ; G 2563 +U 9673 ; WX 873 ; N uni25C9 ; G 2564 +U 9674 ; WX 494 ; N lozenge ; G 2565 +U 9675 ; WX 873 ; N circle ; G 2566 +U 9676 ; WX 873 ; N uni25CC ; G 2567 +U 9677 ; WX 873 ; N uni25CD ; G 2568 +U 9678 ; WX 873 ; N uni25CE ; G 2569 +U 9679 ; WX 873 ; N H18533 ; G 2570 +U 9680 ; WX 873 ; N uni25D0 ; G 2571 +U 9681 ; WX 873 ; N uni25D1 ; G 2572 +U 9682 ; WX 873 ; N uni25D2 ; G 2573 +U 9683 ; WX 873 ; N uni25D3 ; G 2574 +U 9684 ; WX 873 ; N uni25D4 ; G 2575 +U 9685 ; WX 873 ; N uni25D5 ; G 2576 +U 9686 ; WX 527 ; N uni25D6 ; G 2577 +U 9687 ; WX 527 ; N uni25D7 ; G 2578 +U 9688 ; WX 791 ; N invbullet ; G 2579 +U 9689 ; WX 970 ; N invcircle ; G 2580 +U 9690 ; WX 970 ; N uni25DA ; G 2581 +U 9691 ; WX 970 ; N uni25DB ; G 2582 +U 9692 ; WX 387 ; N uni25DC ; G 2583 +U 9693 ; WX 387 ; N uni25DD ; G 2584 +U 9694 ; WX 387 ; N uni25DE ; G 2585 +U 9695 ; WX 387 ; N uni25DF ; G 2586 +U 9696 ; WX 873 ; N uni25E0 ; G 2587 +U 9697 ; WX 873 ; N uni25E1 ; G 2588 +U 9698 ; WX 769 ; N uni25E2 ; G 2589 +U 9699 ; WX 769 ; N uni25E3 ; G 2590 +U 9700 ; WX 769 ; N uni25E4 ; G 2591 +U 9701 ; WX 769 ; N uni25E5 ; G 2592 +U 9702 ; WX 590 ; N openbullet ; G 2593 +U 9703 ; WX 945 ; N uni25E7 ; G 2594 +U 9704 ; WX 945 ; N uni25E8 ; G 2595 +U 9705 ; WX 945 ; N uni25E9 ; G 2596 +U 9706 ; WX 945 ; N uni25EA ; G 2597 +U 9707 ; WX 945 ; N uni25EB ; G 2598 +U 9708 ; WX 769 ; N uni25EC ; G 2599 +U 9709 ; WX 769 ; N uni25ED ; G 2600 +U 9710 ; WX 769 ; N uni25EE ; G 2601 +U 9711 ; WX 1119 ; N uni25EF ; G 2602 +U 9712 ; WX 945 ; N uni25F0 ; G 2603 +U 9713 ; WX 945 ; N uni25F1 ; G 2604 +U 9714 ; WX 945 ; N uni25F2 ; G 2605 +U 9715 ; WX 945 ; N uni25F3 ; G 2606 +U 9716 ; WX 873 ; N uni25F4 ; G 2607 +U 9717 ; WX 873 ; N uni25F5 ; G 2608 +U 9718 ; WX 873 ; N uni25F6 ; G 2609 +U 9719 ; WX 873 ; N uni25F7 ; G 2610 +U 9720 ; WX 769 ; N uni25F8 ; G 2611 +U 9721 ; WX 769 ; N uni25F9 ; G 2612 +U 9722 ; WX 769 ; N uni25FA ; G 2613 +U 9723 ; WX 830 ; N uni25FB ; G 2614 +U 9724 ; WX 830 ; N uni25FC ; G 2615 +U 9725 ; WX 732 ; N uni25FD ; G 2616 +U 9726 ; WX 732 ; N uni25FE ; G 2617 +U 9727 ; WX 769 ; N uni25FF ; G 2618 +U 9728 ; WX 896 ; N uni2600 ; G 2619 +U 9784 ; WX 896 ; N uni2638 ; G 2620 +U 9785 ; WX 896 ; N uni2639 ; G 2621 +U 9786 ; WX 896 ; N smileface ; G 2622 +U 9787 ; WX 896 ; N invsmileface ; G 2623 +U 9788 ; WX 896 ; N sun ; G 2624 +U 9791 ; WX 614 ; N uni263F ; G 2625 +U 9792 ; WX 731 ; N female ; G 2626 +U 9793 ; WX 731 ; N uni2641 ; G 2627 +U 9794 ; WX 896 ; N male ; G 2628 +U 9795 ; WX 896 ; N uni2643 ; G 2629 +U 9796 ; WX 896 ; N uni2644 ; G 2630 +U 9797 ; WX 896 ; N uni2645 ; G 2631 +U 9798 ; WX 896 ; N uni2646 ; G 2632 +U 9799 ; WX 896 ; N uni2647 ; G 2633 +U 9824 ; WX 896 ; N spade ; G 2634 +U 9825 ; WX 896 ; N uni2661 ; G 2635 +U 9826 ; WX 896 ; N uni2662 ; G 2636 +U 9827 ; WX 896 ; N club ; G 2637 +U 9828 ; WX 896 ; N uni2664 ; G 2638 +U 9829 ; WX 896 ; N heart ; G 2639 +U 9830 ; WX 896 ; N diamond ; G 2640 +U 9831 ; WX 896 ; N uni2667 ; G 2641 +U 9833 ; WX 472 ; N uni2669 ; G 2642 +U 9834 ; WX 638 ; N musicalnote ; G 2643 +U 9835 ; WX 896 ; N musicalnotedbl ; G 2644 +U 9836 ; WX 896 ; N uni266C ; G 2645 +U 9837 ; WX 472 ; N uni266D ; G 2646 +U 9838 ; WX 357 ; N uni266E ; G 2647 +U 9839 ; WX 484 ; N uni266F ; G 2648 +U 10145 ; WX 838 ; N uni27A1 ; G 2649 +U 10181 ; WX 457 ; N uni27C5 ; G 2650 +U 10182 ; WX 457 ; N uni27C6 ; G 2651 +U 10208 ; WX 494 ; N uni27E0 ; G 2652 +U 10216 ; WX 457 ; N uni27E8 ; G 2653 +U 10217 ; WX 457 ; N uni27E9 ; G 2654 +U 10224 ; WX 838 ; N uni27F0 ; G 2655 +U 10225 ; WX 838 ; N uni27F1 ; G 2656 +U 10226 ; WX 838 ; N uni27F2 ; G 2657 +U 10227 ; WX 838 ; N uni27F3 ; G 2658 +U 10228 ; WX 1033 ; N uni27F4 ; G 2659 +U 10229 ; WX 1434 ; N uni27F5 ; G 2660 +U 10230 ; WX 1434 ; N uni27F6 ; G 2661 +U 10231 ; WX 1434 ; N uni27F7 ; G 2662 +U 10232 ; WX 1434 ; N uni27F8 ; G 2663 +U 10233 ; WX 1434 ; N uni27F9 ; G 2664 +U 10234 ; WX 1434 ; N uni27FA ; G 2665 +U 10235 ; WX 1434 ; N uni27FB ; G 2666 +U 10236 ; WX 1434 ; N uni27FC ; G 2667 +U 10237 ; WX 1434 ; N uni27FD ; G 2668 +U 10238 ; WX 1434 ; N uni27FE ; G 2669 +U 10239 ; WX 1434 ; N uni27FF ; G 2670 +U 10240 ; WX 781 ; N uni2800 ; G 2671 +U 10241 ; WX 781 ; N uni2801 ; G 2672 +U 10242 ; WX 781 ; N uni2802 ; G 2673 +U 10243 ; WX 781 ; N uni2803 ; G 2674 +U 10244 ; WX 781 ; N uni2804 ; G 2675 +U 10245 ; WX 781 ; N uni2805 ; G 2676 +U 10246 ; WX 781 ; N uni2806 ; G 2677 +U 10247 ; WX 781 ; N uni2807 ; G 2678 +U 10248 ; WX 781 ; N uni2808 ; G 2679 +U 10249 ; WX 781 ; N uni2809 ; G 2680 +U 10250 ; WX 781 ; N uni280A ; G 2681 +U 10251 ; WX 781 ; N uni280B ; G 2682 +U 10252 ; WX 781 ; N uni280C ; G 2683 +U 10253 ; WX 781 ; N uni280D ; G 2684 +U 10254 ; WX 781 ; N uni280E ; G 2685 +U 10255 ; WX 781 ; N uni280F ; G 2686 +U 10256 ; WX 781 ; N uni2810 ; G 2687 +U 10257 ; WX 781 ; N uni2811 ; G 2688 +U 10258 ; WX 781 ; N uni2812 ; G 2689 +U 10259 ; WX 781 ; N uni2813 ; G 2690 +U 10260 ; WX 781 ; N uni2814 ; G 2691 +U 10261 ; WX 781 ; N uni2815 ; G 2692 +U 10262 ; WX 781 ; N uni2816 ; G 2693 +U 10263 ; WX 781 ; N uni2817 ; G 2694 +U 10264 ; WX 781 ; N uni2818 ; G 2695 +U 10265 ; WX 781 ; N uni2819 ; G 2696 +U 10266 ; WX 781 ; N uni281A ; G 2697 +U 10267 ; WX 781 ; N uni281B ; G 2698 +U 10268 ; WX 781 ; N uni281C ; G 2699 +U 10269 ; WX 781 ; N uni281D ; G 2700 +U 10270 ; WX 781 ; N uni281E ; G 2701 +U 10271 ; WX 781 ; N uni281F ; G 2702 +U 10272 ; WX 781 ; N uni2820 ; G 2703 +U 10273 ; WX 781 ; N uni2821 ; G 2704 +U 10274 ; WX 781 ; N uni2822 ; G 2705 +U 10275 ; WX 781 ; N uni2823 ; G 2706 +U 10276 ; WX 781 ; N uni2824 ; G 2707 +U 10277 ; WX 781 ; N uni2825 ; G 2708 +U 10278 ; WX 781 ; N uni2826 ; G 2709 +U 10279 ; WX 781 ; N uni2827 ; G 2710 +U 10280 ; WX 781 ; N uni2828 ; G 2711 +U 10281 ; WX 781 ; N uni2829 ; G 2712 +U 10282 ; WX 781 ; N uni282A ; G 2713 +U 10283 ; WX 781 ; N uni282B ; G 2714 +U 10284 ; WX 781 ; N uni282C ; G 2715 +U 10285 ; WX 781 ; N uni282D ; G 2716 +U 10286 ; WX 781 ; N uni282E ; G 2717 +U 10287 ; WX 781 ; N uni282F ; G 2718 +U 10288 ; WX 781 ; N uni2830 ; G 2719 +U 10289 ; WX 781 ; N uni2831 ; G 2720 +U 10290 ; WX 781 ; N uni2832 ; G 2721 +U 10291 ; WX 781 ; N uni2833 ; G 2722 +U 10292 ; WX 781 ; N uni2834 ; G 2723 +U 10293 ; WX 781 ; N uni2835 ; G 2724 +U 10294 ; WX 781 ; N uni2836 ; G 2725 +U 10295 ; WX 781 ; N uni2837 ; G 2726 +U 10296 ; WX 781 ; N uni2838 ; G 2727 +U 10297 ; WX 781 ; N uni2839 ; G 2728 +U 10298 ; WX 781 ; N uni283A ; G 2729 +U 10299 ; WX 781 ; N uni283B ; G 2730 +U 10300 ; WX 781 ; N uni283C ; G 2731 +U 10301 ; WX 781 ; N uni283D ; G 2732 +U 10302 ; WX 781 ; N uni283E ; G 2733 +U 10303 ; WX 781 ; N uni283F ; G 2734 +U 10304 ; WX 781 ; N uni2840 ; G 2735 +U 10305 ; WX 781 ; N uni2841 ; G 2736 +U 10306 ; WX 781 ; N uni2842 ; G 2737 +U 10307 ; WX 781 ; N uni2843 ; G 2738 +U 10308 ; WX 781 ; N uni2844 ; G 2739 +U 10309 ; WX 781 ; N uni2845 ; G 2740 +U 10310 ; WX 781 ; N uni2846 ; G 2741 +U 10311 ; WX 781 ; N uni2847 ; G 2742 +U 10312 ; WX 781 ; N uni2848 ; G 2743 +U 10313 ; WX 781 ; N uni2849 ; G 2744 +U 10314 ; WX 781 ; N uni284A ; G 2745 +U 10315 ; WX 781 ; N uni284B ; G 2746 +U 10316 ; WX 781 ; N uni284C ; G 2747 +U 10317 ; WX 781 ; N uni284D ; G 2748 +U 10318 ; WX 781 ; N uni284E ; G 2749 +U 10319 ; WX 781 ; N uni284F ; G 2750 +U 10320 ; WX 781 ; N uni2850 ; G 2751 +U 10321 ; WX 781 ; N uni2851 ; G 2752 +U 10322 ; WX 781 ; N uni2852 ; G 2753 +U 10323 ; WX 781 ; N uni2853 ; G 2754 +U 10324 ; WX 781 ; N uni2854 ; G 2755 +U 10325 ; WX 781 ; N uni2855 ; G 2756 +U 10326 ; WX 781 ; N uni2856 ; G 2757 +U 10327 ; WX 781 ; N uni2857 ; G 2758 +U 10328 ; WX 781 ; N uni2858 ; G 2759 +U 10329 ; WX 781 ; N uni2859 ; G 2760 +U 10330 ; WX 781 ; N uni285A ; G 2761 +U 10331 ; WX 781 ; N uni285B ; G 2762 +U 10332 ; WX 781 ; N uni285C ; G 2763 +U 10333 ; WX 781 ; N uni285D ; G 2764 +U 10334 ; WX 781 ; N uni285E ; G 2765 +U 10335 ; WX 781 ; N uni285F ; G 2766 +U 10336 ; WX 781 ; N uni2860 ; G 2767 +U 10337 ; WX 781 ; N uni2861 ; G 2768 +U 10338 ; WX 781 ; N uni2862 ; G 2769 +U 10339 ; WX 781 ; N uni2863 ; G 2770 +U 10340 ; WX 781 ; N uni2864 ; G 2771 +U 10341 ; WX 781 ; N uni2865 ; G 2772 +U 10342 ; WX 781 ; N uni2866 ; G 2773 +U 10343 ; WX 781 ; N uni2867 ; G 2774 +U 10344 ; WX 781 ; N uni2868 ; G 2775 +U 10345 ; WX 781 ; N uni2869 ; G 2776 +U 10346 ; WX 781 ; N uni286A ; G 2777 +U 10347 ; WX 781 ; N uni286B ; G 2778 +U 10348 ; WX 781 ; N uni286C ; G 2779 +U 10349 ; WX 781 ; N uni286D ; G 2780 +U 10350 ; WX 781 ; N uni286E ; G 2781 +U 10351 ; WX 781 ; N uni286F ; G 2782 +U 10352 ; WX 781 ; N uni2870 ; G 2783 +U 10353 ; WX 781 ; N uni2871 ; G 2784 +U 10354 ; WX 781 ; N uni2872 ; G 2785 +U 10355 ; WX 781 ; N uni2873 ; G 2786 +U 10356 ; WX 781 ; N uni2874 ; G 2787 +U 10357 ; WX 781 ; N uni2875 ; G 2788 +U 10358 ; WX 781 ; N uni2876 ; G 2789 +U 10359 ; WX 781 ; N uni2877 ; G 2790 +U 10360 ; WX 781 ; N uni2878 ; G 2791 +U 10361 ; WX 781 ; N uni2879 ; G 2792 +U 10362 ; WX 781 ; N uni287A ; G 2793 +U 10363 ; WX 781 ; N uni287B ; G 2794 +U 10364 ; WX 781 ; N uni287C ; G 2795 +U 10365 ; WX 781 ; N uni287D ; G 2796 +U 10366 ; WX 781 ; N uni287E ; G 2797 +U 10367 ; WX 781 ; N uni287F ; G 2798 +U 10368 ; WX 781 ; N uni2880 ; G 2799 +U 10369 ; WX 781 ; N uni2881 ; G 2800 +U 10370 ; WX 781 ; N uni2882 ; G 2801 +U 10371 ; WX 781 ; N uni2883 ; G 2802 +U 10372 ; WX 781 ; N uni2884 ; G 2803 +U 10373 ; WX 781 ; N uni2885 ; G 2804 +U 10374 ; WX 781 ; N uni2886 ; G 2805 +U 10375 ; WX 781 ; N uni2887 ; G 2806 +U 10376 ; WX 781 ; N uni2888 ; G 2807 +U 10377 ; WX 781 ; N uni2889 ; G 2808 +U 10378 ; WX 781 ; N uni288A ; G 2809 +U 10379 ; WX 781 ; N uni288B ; G 2810 +U 10380 ; WX 781 ; N uni288C ; G 2811 +U 10381 ; WX 781 ; N uni288D ; G 2812 +U 10382 ; WX 781 ; N uni288E ; G 2813 +U 10383 ; WX 781 ; N uni288F ; G 2814 +U 10384 ; WX 781 ; N uni2890 ; G 2815 +U 10385 ; WX 781 ; N uni2891 ; G 2816 +U 10386 ; WX 781 ; N uni2892 ; G 2817 +U 10387 ; WX 781 ; N uni2893 ; G 2818 +U 10388 ; WX 781 ; N uni2894 ; G 2819 +U 10389 ; WX 781 ; N uni2895 ; G 2820 +U 10390 ; WX 781 ; N uni2896 ; G 2821 +U 10391 ; WX 781 ; N uni2897 ; G 2822 +U 10392 ; WX 781 ; N uni2898 ; G 2823 +U 10393 ; WX 781 ; N uni2899 ; G 2824 +U 10394 ; WX 781 ; N uni289A ; G 2825 +U 10395 ; WX 781 ; N uni289B ; G 2826 +U 10396 ; WX 781 ; N uni289C ; G 2827 +U 10397 ; WX 781 ; N uni289D ; G 2828 +U 10398 ; WX 781 ; N uni289E ; G 2829 +U 10399 ; WX 781 ; N uni289F ; G 2830 +U 10400 ; WX 781 ; N uni28A0 ; G 2831 +U 10401 ; WX 781 ; N uni28A1 ; G 2832 +U 10402 ; WX 781 ; N uni28A2 ; G 2833 +U 10403 ; WX 781 ; N uni28A3 ; G 2834 +U 10404 ; WX 781 ; N uni28A4 ; G 2835 +U 10405 ; WX 781 ; N uni28A5 ; G 2836 +U 10406 ; WX 781 ; N uni28A6 ; G 2837 +U 10407 ; WX 781 ; N uni28A7 ; G 2838 +U 10408 ; WX 781 ; N uni28A8 ; G 2839 +U 10409 ; WX 781 ; N uni28A9 ; G 2840 +U 10410 ; WX 781 ; N uni28AA ; G 2841 +U 10411 ; WX 781 ; N uni28AB ; G 2842 +U 10412 ; WX 781 ; N uni28AC ; G 2843 +U 10413 ; WX 781 ; N uni28AD ; G 2844 +U 10414 ; WX 781 ; N uni28AE ; G 2845 +U 10415 ; WX 781 ; N uni28AF ; G 2846 +U 10416 ; WX 781 ; N uni28B0 ; G 2847 +U 10417 ; WX 781 ; N uni28B1 ; G 2848 +U 10418 ; WX 781 ; N uni28B2 ; G 2849 +U 10419 ; WX 781 ; N uni28B3 ; G 2850 +U 10420 ; WX 781 ; N uni28B4 ; G 2851 +U 10421 ; WX 781 ; N uni28B5 ; G 2852 +U 10422 ; WX 781 ; N uni28B6 ; G 2853 +U 10423 ; WX 781 ; N uni28B7 ; G 2854 +U 10424 ; WX 781 ; N uni28B8 ; G 2855 +U 10425 ; WX 781 ; N uni28B9 ; G 2856 +U 10426 ; WX 781 ; N uni28BA ; G 2857 +U 10427 ; WX 781 ; N uni28BB ; G 2858 +U 10428 ; WX 781 ; N uni28BC ; G 2859 +U 10429 ; WX 781 ; N uni28BD ; G 2860 +U 10430 ; WX 781 ; N uni28BE ; G 2861 +U 10431 ; WX 781 ; N uni28BF ; G 2862 +U 10432 ; WX 781 ; N uni28C0 ; G 2863 +U 10433 ; WX 781 ; N uni28C1 ; G 2864 +U 10434 ; WX 781 ; N uni28C2 ; G 2865 +U 10435 ; WX 781 ; N uni28C3 ; G 2866 +U 10436 ; WX 781 ; N uni28C4 ; G 2867 +U 10437 ; WX 781 ; N uni28C5 ; G 2868 +U 10438 ; WX 781 ; N uni28C6 ; G 2869 +U 10439 ; WX 781 ; N uni28C7 ; G 2870 +U 10440 ; WX 781 ; N uni28C8 ; G 2871 +U 10441 ; WX 781 ; N uni28C9 ; G 2872 +U 10442 ; WX 781 ; N uni28CA ; G 2873 +U 10443 ; WX 781 ; N uni28CB ; G 2874 +U 10444 ; WX 781 ; N uni28CC ; G 2875 +U 10445 ; WX 781 ; N uni28CD ; G 2876 +U 10446 ; WX 781 ; N uni28CE ; G 2877 +U 10447 ; WX 781 ; N uni28CF ; G 2878 +U 10448 ; WX 781 ; N uni28D0 ; G 2879 +U 10449 ; WX 781 ; N uni28D1 ; G 2880 +U 10450 ; WX 781 ; N uni28D2 ; G 2881 +U 10451 ; WX 781 ; N uni28D3 ; G 2882 +U 10452 ; WX 781 ; N uni28D4 ; G 2883 +U 10453 ; WX 781 ; N uni28D5 ; G 2884 +U 10454 ; WX 781 ; N uni28D6 ; G 2885 +U 10455 ; WX 781 ; N uni28D7 ; G 2886 +U 10456 ; WX 781 ; N uni28D8 ; G 2887 +U 10457 ; WX 781 ; N uni28D9 ; G 2888 +U 10458 ; WX 781 ; N uni28DA ; G 2889 +U 10459 ; WX 781 ; N uni28DB ; G 2890 +U 10460 ; WX 781 ; N uni28DC ; G 2891 +U 10461 ; WX 781 ; N uni28DD ; G 2892 +U 10462 ; WX 781 ; N uni28DE ; G 2893 +U 10463 ; WX 781 ; N uni28DF ; G 2894 +U 10464 ; WX 781 ; N uni28E0 ; G 2895 +U 10465 ; WX 781 ; N uni28E1 ; G 2896 +U 10466 ; WX 781 ; N uni28E2 ; G 2897 +U 10467 ; WX 781 ; N uni28E3 ; G 2898 +U 10468 ; WX 781 ; N uni28E4 ; G 2899 +U 10469 ; WX 781 ; N uni28E5 ; G 2900 +U 10470 ; WX 781 ; N uni28E6 ; G 2901 +U 10471 ; WX 781 ; N uni28E7 ; G 2902 +U 10472 ; WX 781 ; N uni28E8 ; G 2903 +U 10473 ; WX 781 ; N uni28E9 ; G 2904 +U 10474 ; WX 781 ; N uni28EA ; G 2905 +U 10475 ; WX 781 ; N uni28EB ; G 2906 +U 10476 ; WX 781 ; N uni28EC ; G 2907 +U 10477 ; WX 781 ; N uni28ED ; G 2908 +U 10478 ; WX 781 ; N uni28EE ; G 2909 +U 10479 ; WX 781 ; N uni28EF ; G 2910 +U 10480 ; WX 781 ; N uni28F0 ; G 2911 +U 10481 ; WX 781 ; N uni28F1 ; G 2912 +U 10482 ; WX 781 ; N uni28F2 ; G 2913 +U 10483 ; WX 781 ; N uni28F3 ; G 2914 +U 10484 ; WX 781 ; N uni28F4 ; G 2915 +U 10485 ; WX 781 ; N uni28F5 ; G 2916 +U 10486 ; WX 781 ; N uni28F6 ; G 2917 +U 10487 ; WX 781 ; N uni28F7 ; G 2918 +U 10488 ; WX 781 ; N uni28F8 ; G 2919 +U 10489 ; WX 781 ; N uni28F9 ; G 2920 +U 10490 ; WX 781 ; N uni28FA ; G 2921 +U 10491 ; WX 781 ; N uni28FB ; G 2922 +U 10492 ; WX 781 ; N uni28FC ; G 2923 +U 10493 ; WX 781 ; N uni28FD ; G 2924 +U 10494 ; WX 781 ; N uni28FE ; G 2925 +U 10495 ; WX 781 ; N uni28FF ; G 2926 +U 10496 ; WX 838 ; N uni2900 ; G 2927 +U 10497 ; WX 838 ; N uni2901 ; G 2928 +U 10498 ; WX 838 ; N uni2902 ; G 2929 +U 10499 ; WX 838 ; N uni2903 ; G 2930 +U 10500 ; WX 838 ; N uni2904 ; G 2931 +U 10501 ; WX 838 ; N uni2905 ; G 2932 +U 10502 ; WX 838 ; N uni2906 ; G 2933 +U 10503 ; WX 838 ; N uni2907 ; G 2934 +U 10504 ; WX 838 ; N uni2908 ; G 2935 +U 10505 ; WX 838 ; N uni2909 ; G 2936 +U 10506 ; WX 838 ; N uni290A ; G 2937 +U 10507 ; WX 838 ; N uni290B ; G 2938 +U 10508 ; WX 838 ; N uni290C ; G 2939 +U 10509 ; WX 838 ; N uni290D ; G 2940 +U 10510 ; WX 838 ; N uni290E ; G 2941 +U 10511 ; WX 838 ; N uni290F ; G 2942 +U 10512 ; WX 838 ; N uni2910 ; G 2943 +U 10513 ; WX 838 ; N uni2911 ; G 2944 +U 10514 ; WX 838 ; N uni2912 ; G 2945 +U 10515 ; WX 838 ; N uni2913 ; G 2946 +U 10516 ; WX 838 ; N uni2914 ; G 2947 +U 10517 ; WX 838 ; N uni2915 ; G 2948 +U 10518 ; WX 838 ; N uni2916 ; G 2949 +U 10519 ; WX 838 ; N uni2917 ; G 2950 +U 10520 ; WX 838 ; N uni2918 ; G 2951 +U 10521 ; WX 838 ; N uni2919 ; G 2952 +U 10522 ; WX 838 ; N uni291A ; G 2953 +U 10523 ; WX 838 ; N uni291B ; G 2954 +U 10524 ; WX 838 ; N uni291C ; G 2955 +U 10525 ; WX 838 ; N uni291D ; G 2956 +U 10526 ; WX 838 ; N uni291E ; G 2957 +U 10527 ; WX 838 ; N uni291F ; G 2958 +U 10528 ; WX 838 ; N uni2920 ; G 2959 +U 10529 ; WX 838 ; N uni2921 ; G 2960 +U 10530 ; WX 838 ; N uni2922 ; G 2961 +U 10531 ; WX 838 ; N uni2923 ; G 2962 +U 10532 ; WX 838 ; N uni2924 ; G 2963 +U 10533 ; WX 838 ; N uni2925 ; G 2964 +U 10534 ; WX 838 ; N uni2926 ; G 2965 +U 10535 ; WX 838 ; N uni2927 ; G 2966 +U 10536 ; WX 838 ; N uni2928 ; G 2967 +U 10537 ; WX 838 ; N uni2929 ; G 2968 +U 10538 ; WX 838 ; N uni292A ; G 2969 +U 10539 ; WX 838 ; N uni292B ; G 2970 +U 10540 ; WX 838 ; N uni292C ; G 2971 +U 10541 ; WX 838 ; N uni292D ; G 2972 +U 10542 ; WX 838 ; N uni292E ; G 2973 +U 10543 ; WX 838 ; N uni292F ; G 2974 +U 10544 ; WX 838 ; N uni2930 ; G 2975 +U 10545 ; WX 838 ; N uni2931 ; G 2976 +U 10546 ; WX 838 ; N uni2932 ; G 2977 +U 10547 ; WX 838 ; N uni2933 ; G 2978 +U 10548 ; WX 838 ; N uni2934 ; G 2979 +U 10549 ; WX 838 ; N uni2935 ; G 2980 +U 10550 ; WX 838 ; N uni2936 ; G 2981 +U 10551 ; WX 838 ; N uni2937 ; G 2982 +U 10552 ; WX 838 ; N uni2938 ; G 2983 +U 10553 ; WX 838 ; N uni2939 ; G 2984 +U 10554 ; WX 838 ; N uni293A ; G 2985 +U 10555 ; WX 838 ; N uni293B ; G 2986 +U 10556 ; WX 838 ; N uni293C ; G 2987 +U 10557 ; WX 838 ; N uni293D ; G 2988 +U 10558 ; WX 838 ; N uni293E ; G 2989 +U 10559 ; WX 838 ; N uni293F ; G 2990 +U 10560 ; WX 838 ; N uni2940 ; G 2991 +U 10561 ; WX 838 ; N uni2941 ; G 2992 +U 10562 ; WX 838 ; N uni2942 ; G 2993 +U 10563 ; WX 838 ; N uni2943 ; G 2994 +U 10564 ; WX 838 ; N uni2944 ; G 2995 +U 10565 ; WX 838 ; N uni2945 ; G 2996 +U 10566 ; WX 838 ; N uni2946 ; G 2997 +U 10567 ; WX 838 ; N uni2947 ; G 2998 +U 10568 ; WX 838 ; N uni2948 ; G 2999 +U 10569 ; WX 838 ; N uni2949 ; G 3000 +U 10570 ; WX 838 ; N uni294A ; G 3001 +U 10571 ; WX 838 ; N uni294B ; G 3002 +U 10572 ; WX 838 ; N uni294C ; G 3003 +U 10573 ; WX 838 ; N uni294D ; G 3004 +U 10574 ; WX 838 ; N uni294E ; G 3005 +U 10575 ; WX 838 ; N uni294F ; G 3006 +U 10576 ; WX 838 ; N uni2950 ; G 3007 +U 10577 ; WX 838 ; N uni2951 ; G 3008 +U 10578 ; WX 838 ; N uni2952 ; G 3009 +U 10579 ; WX 838 ; N uni2953 ; G 3010 +U 10580 ; WX 838 ; N uni2954 ; G 3011 +U 10581 ; WX 838 ; N uni2955 ; G 3012 +U 10582 ; WX 838 ; N uni2956 ; G 3013 +U 10583 ; WX 838 ; N uni2957 ; G 3014 +U 10584 ; WX 838 ; N uni2958 ; G 3015 +U 10585 ; WX 838 ; N uni2959 ; G 3016 +U 10586 ; WX 838 ; N uni295A ; G 3017 +U 10587 ; WX 838 ; N uni295B ; G 3018 +U 10588 ; WX 838 ; N uni295C ; G 3019 +U 10589 ; WX 838 ; N uni295D ; G 3020 +U 10590 ; WX 838 ; N uni295E ; G 3021 +U 10591 ; WX 838 ; N uni295F ; G 3022 +U 10592 ; WX 838 ; N uni2960 ; G 3023 +U 10593 ; WX 838 ; N uni2961 ; G 3024 +U 10594 ; WX 838 ; N uni2962 ; G 3025 +U 10595 ; WX 838 ; N uni2963 ; G 3026 +U 10596 ; WX 838 ; N uni2964 ; G 3027 +U 10597 ; WX 838 ; N uni2965 ; G 3028 +U 10598 ; WX 838 ; N uni2966 ; G 3029 +U 10599 ; WX 838 ; N uni2967 ; G 3030 +U 10600 ; WX 838 ; N uni2968 ; G 3031 +U 10601 ; WX 838 ; N uni2969 ; G 3032 +U 10602 ; WX 838 ; N uni296A ; G 3033 +U 10603 ; WX 838 ; N uni296B ; G 3034 +U 10604 ; WX 838 ; N uni296C ; G 3035 +U 10605 ; WX 838 ; N uni296D ; G 3036 +U 10606 ; WX 838 ; N uni296E ; G 3037 +U 10607 ; WX 838 ; N uni296F ; G 3038 +U 10608 ; WX 838 ; N uni2970 ; G 3039 +U 10609 ; WX 838 ; N uni2971 ; G 3040 +U 10610 ; WX 838 ; N uni2972 ; G 3041 +U 10611 ; WX 838 ; N uni2973 ; G 3042 +U 10612 ; WX 838 ; N uni2974 ; G 3043 +U 10613 ; WX 838 ; N uni2975 ; G 3044 +U 10614 ; WX 838 ; N uni2976 ; G 3045 +U 10615 ; WX 1032 ; N uni2977 ; G 3046 +U 10616 ; WX 838 ; N uni2978 ; G 3047 +U 10617 ; WX 838 ; N uni2979 ; G 3048 +U 10618 ; WX 960 ; N uni297A ; G 3049 +U 10619 ; WX 838 ; N uni297B ; G 3050 +U 10620 ; WX 838 ; N uni297C ; G 3051 +U 10621 ; WX 838 ; N uni297D ; G 3052 +U 10622 ; WX 838 ; N uni297E ; G 3053 +U 10623 ; WX 838 ; N uni297F ; G 3054 +U 10731 ; WX 494 ; N uni29EB ; G 3055 +U 10764 ; WX 1782 ; N uni2A0C ; G 3056 +U 10765 ; WX 610 ; N uni2A0D ; G 3057 +U 10766 ; WX 610 ; N uni2A0E ; G 3058 +U 10799 ; WX 838 ; N uni2A2F ; G 3059 +U 10858 ; WX 838 ; N uni2A6A ; G 3060 +U 10859 ; WX 838 ; N uni2A6B ; G 3061 +U 11008 ; WX 838 ; N uni2B00 ; G 3062 +U 11009 ; WX 838 ; N uni2B01 ; G 3063 +U 11010 ; WX 838 ; N uni2B02 ; G 3064 +U 11011 ; WX 838 ; N uni2B03 ; G 3065 +U 11012 ; WX 838 ; N uni2B04 ; G 3066 +U 11013 ; WX 838 ; N uni2B05 ; G 3067 +U 11014 ; WX 838 ; N uni2B06 ; G 3068 +U 11015 ; WX 838 ; N uni2B07 ; G 3069 +U 11016 ; WX 838 ; N uni2B08 ; G 3070 +U 11017 ; WX 838 ; N uni2B09 ; G 3071 +U 11018 ; WX 838 ; N uni2B0A ; G 3072 +U 11019 ; WX 838 ; N uni2B0B ; G 3073 +U 11020 ; WX 838 ; N uni2B0C ; G 3074 +U 11021 ; WX 838 ; N uni2B0D ; G 3075 +U 11022 ; WX 838 ; N uni2B0E ; G 3076 +U 11023 ; WX 838 ; N uni2B0F ; G 3077 +U 11024 ; WX 838 ; N uni2B10 ; G 3078 +U 11025 ; WX 838 ; N uni2B11 ; G 3079 +U 11026 ; WX 945 ; N uni2B12 ; G 3080 +U 11027 ; WX 945 ; N uni2B13 ; G 3081 +U 11028 ; WX 945 ; N uni2B14 ; G 3082 +U 11029 ; WX 945 ; N uni2B15 ; G 3083 +U 11030 ; WX 769 ; N uni2B16 ; G 3084 +U 11031 ; WX 769 ; N uni2B17 ; G 3085 +U 11032 ; WX 769 ; N uni2B18 ; G 3086 +U 11033 ; WX 769 ; N uni2B19 ; G 3087 +U 11034 ; WX 945 ; N uni2B1A ; G 3088 +U 11360 ; WX 703 ; N uni2C60 ; G 3089 +U 11361 ; WX 380 ; N uni2C61 ; G 3090 +U 11363 ; WX 752 ; N uni2C63 ; G 3091 +U 11364 ; WX 831 ; N uni2C64 ; G 3092 +U 11367 ; WX 945 ; N uni2C67 ; G 3093 +U 11368 ; WX 727 ; N uni2C68 ; G 3094 +U 11369 ; WX 869 ; N uni2C69 ; G 3095 +U 11370 ; WX 693 ; N uni2C6A ; G 3096 +U 11371 ; WX 730 ; N uni2C6B ; G 3097 +U 11372 ; WX 568 ; N uni2C6C ; G 3098 +U 11373 ; WX 848 ; N uni2C6D ; G 3099 +U 11374 ; WX 1107 ; N uni2C6E ; G 3100 +U 11375 ; WX 776 ; N uni2C6F ; G 3101 +U 11376 ; WX 848 ; N uni2C70 ; G 3102 +U 11377 ; WX 709 ; N uni2C71 ; G 3103 +U 11378 ; WX 1221 ; N uni2C72 ; G 3104 +U 11379 ; WX 984 ; N uni2C73 ; G 3105 +U 11381 ; WX 779 ; N uni2C75 ; G 3106 +U 11382 ; WX 601 ; N uni2C76 ; G 3107 +U 11383 ; WX 905 ; N uni2C77 ; G 3108 +U 11385 ; WX 571 ; N uni2C79 ; G 3109 +U 11386 ; WX 667 ; N uni2C7A ; G 3110 +U 11387 ; WX 617 ; N uni2C7B ; G 3111 +U 11388 ; WX 313 ; N uni2C7C ; G 3112 +U 11389 ; WX 489 ; N uni2C7D ; G 3113 +U 11390 ; WX 722 ; N uni2C7E ; G 3114 +U 11391 ; WX 730 ; N uni2C7F ; G 3115 +U 11520 ; WX 773 ; N uni2D00 ; G 3116 +U 11521 ; WX 635 ; N uni2D01 ; G 3117 +U 11522 ; WX 804 ; N uni2D02 ; G 3118 +U 11523 ; WX 658 ; N uni2D03 ; G 3119 +U 11524 ; WX 788 ; N uni2D04 ; G 3120 +U 11525 ; WX 962 ; N uni2D05 ; G 3121 +U 11526 ; WX 756 ; N uni2D06 ; G 3122 +U 11527 ; WX 960 ; N uni2D07 ; G 3123 +U 11528 ; WX 617 ; N uni2D08 ; G 3124 +U 11529 ; WX 646 ; N uni2D09 ; G 3125 +U 11530 ; WX 962 ; N uni2D0A ; G 3126 +U 11531 ; WX 631 ; N uni2D0B ; G 3127 +U 11532 ; WX 646 ; N uni2D0C ; G 3128 +U 11533 ; WX 962 ; N uni2D0D ; G 3129 +U 11534 ; WX 846 ; N uni2D0E ; G 3130 +U 11535 ; WX 866 ; N uni2D0F ; G 3131 +U 11536 ; WX 961 ; N uni2D10 ; G 3132 +U 11537 ; WX 645 ; N uni2D11 ; G 3133 +U 11538 ; WX 645 ; N uni2D12 ; G 3134 +U 11539 ; WX 959 ; N uni2D13 ; G 3135 +U 11540 ; WX 945 ; N uni2D14 ; G 3136 +U 11541 ; WX 863 ; N uni2D15 ; G 3137 +U 11542 ; WX 644 ; N uni2D16 ; G 3138 +U 11543 ; WX 646 ; N uni2D17 ; G 3139 +U 11544 ; WX 645 ; N uni2D18 ; G 3140 +U 11545 ; WX 649 ; N uni2D19 ; G 3141 +U 11546 ; WX 688 ; N uni2D1A ; G 3142 +U 11547 ; WX 936 ; N uni2D1B ; G 3143 +U 11548 ; WX 982 ; N uni2D1C ; G 3144 +U 11549 ; WX 681 ; N uni2D1D ; G 3145 +U 11550 ; WX 676 ; N uni2D1E ; G 3146 +U 11551 ; WX 852 ; N uni2D1F ; G 3147 +U 11552 ; WX 1113 ; N uni2D20 ; G 3148 +U 11553 ; WX 632 ; N uni2D21 ; G 3149 +U 11554 ; WX 645 ; N uni2D22 ; G 3150 +U 11555 ; WX 646 ; N uni2D23 ; G 3151 +U 11556 ; WX 749 ; N uni2D24 ; G 3152 +U 11557 ; WX 914 ; N uni2D25 ; G 3153 +U 11800 ; WX 586 ; N uni2E18 ; G 3154 +U 11807 ; WX 838 ; N uni2E1F ; G 3155 +U 11810 ; WX 473 ; N uni2E22 ; G 3156 +U 11811 ; WX 473 ; N uni2E23 ; G 3157 +U 11812 ; WX 473 ; N uni2E24 ; G 3158 +U 11813 ; WX 473 ; N uni2E25 ; G 3159 +U 11822 ; WX 586 ; N uni2E2E ; G 3160 +U 42564 ; WX 722 ; N uniA644 ; G 3161 +U 42565 ; WX 563 ; N uniA645 ; G 3162 +U 42566 ; WX 468 ; N uniA646 ; G 3163 +U 42567 ; WX 380 ; N uniA647 ; G 3164 +U 42576 ; WX 1333 ; N uniA650 ; G 3165 +U 42577 ; WX 1092 ; N uniA651 ; G 3166 +U 42580 ; WX 1287 ; N uniA654 ; G 3167 +U 42581 ; WX 1025 ; N uniA655 ; G 3168 +U 42582 ; WX 1287 ; N uniA656 ; G 3169 +U 42583 ; WX 1039 ; N uniA657 ; G 3170 +U 42648 ; WX 1448 ; N uniA698 ; G 3171 +U 42649 ; WX 1060 ; N uniA699 ; G 3172 +U 42760 ; WX 500 ; N uniA708 ; G 3173 +U 42761 ; WX 500 ; N uniA709 ; G 3174 +U 42762 ; WX 500 ; N uniA70A ; G 3175 +U 42763 ; WX 500 ; N uniA70B ; G 3176 +U 42764 ; WX 500 ; N uniA70C ; G 3177 +U 42765 ; WX 500 ; N uniA70D ; G 3178 +U 42766 ; WX 500 ; N uniA70E ; G 3179 +U 42767 ; WX 500 ; N uniA70F ; G 3180 +U 42768 ; WX 500 ; N uniA710 ; G 3181 +U 42769 ; WX 500 ; N uniA711 ; G 3182 +U 42770 ; WX 500 ; N uniA712 ; G 3183 +U 42771 ; WX 500 ; N uniA713 ; G 3184 +U 42772 ; WX 500 ; N uniA714 ; G 3185 +U 42773 ; WX 500 ; N uniA715 ; G 3186 +U 42774 ; WX 500 ; N uniA716 ; G 3187 +U 42779 ; WX 384 ; N uniA71B ; G 3188 +U 42780 ; WX 384 ; N uniA71C ; G 3189 +U 42781 ; WX 276 ; N uniA71D ; G 3190 +U 42782 ; WX 276 ; N uniA71E ; G 3191 +U 42783 ; WX 276 ; N uniA71F ; G 3192 +U 42790 ; WX 945 ; N uniA726 ; G 3193 +U 42791 ; WX 712 ; N uniA727 ; G 3194 +U 42792 ; WX 1003 ; N uniA728 ; G 3195 +U 42793 ; WX 909 ; N uniA729 ; G 3196 +U 42794 ; WX 696 ; N uniA72A ; G 3197 +U 42795 ; WX 609 ; N uniA72B ; G 3198 +U 42796 ; WX 634 ; N uniA72C ; G 3199 +U 42797 ; WX 598 ; N uniA72D ; G 3200 +U 42798 ; WX 741 ; N uniA72E ; G 3201 +U 42799 ; WX 706 ; N uniA72F ; G 3202 +U 42800 ; WX 592 ; N uniA730 ; G 3203 +U 42801 ; WX 563 ; N uniA731 ; G 3204 +U 42802 ; WX 1301 ; N uniA732 ; G 3205 +U 42803 ; WX 986 ; N uniA733 ; G 3206 +U 42804 ; WX 1261 ; N uniA734 ; G 3207 +U 42805 ; WX 1004 ; N uniA735 ; G 3208 +U 42806 ; WX 1168 ; N uniA736 ; G 3209 +U 42807 ; WX 1008 ; N uniA737 ; G 3210 +U 42808 ; WX 1016 ; N uniA738 ; G 3211 +U 42809 ; WX 813 ; N uniA739 ; G 3212 +U 42810 ; WX 1016 ; N uniA73A ; G 3213 +U 42811 ; WX 813 ; N uniA73B ; G 3214 +U 42812 ; WX 994 ; N uniA73C ; G 3215 +U 42813 ; WX 847 ; N uniA73D ; G 3216 +U 42814 ; WX 796 ; N uniA73E ; G 3217 +U 42815 ; WX 609 ; N uniA73F ; G 3218 +U 42816 ; WX 910 ; N uniA740 ; G 3219 +U 42817 ; WX 722 ; N uniA741 ; G 3220 +U 42822 ; WX 916 ; N uniA746 ; G 3221 +U 42823 ; WX 581 ; N uniA747 ; G 3222 +U 42826 ; WX 1010 ; N uniA74A ; G 3223 +U 42827 ; WX 770 ; N uniA74B ; G 3224 +U 42830 ; WX 1448 ; N uniA74E ; G 3225 +U 42831 ; WX 1060 ; N uniA74F ; G 3226 +U 42856 ; WX 787 ; N uniA768 ; G 3227 +U 42857 ; WX 716 ; N uniA769 ; G 3228 +U 42875 ; WX 694 ; N uniA77B ; G 3229 +U 42876 ; WX 527 ; N uniA77C ; G 3230 +U 42880 ; WX 703 ; N uniA780 ; G 3231 +U 42881 ; WX 380 ; N uniA781 ; G 3232 +U 42882 ; WX 872 ; N uniA782 ; G 3233 +U 42883 ; WX 727 ; N uniA783 ; G 3234 +U 42884 ; WX 694 ; N uniA784 ; G 3235 +U 42885 ; WX 527 ; N uniA785 ; G 3236 +U 42886 ; WX 796 ; N uniA786 ; G 3237 +U 42887 ; WX 609 ; N uniA787 ; G 3238 +U 42891 ; WX 439 ; N uniA78B ; G 3239 +U 42892 ; WX 306 ; N uniA78C ; G 3240 +U 42893 ; WX 913 ; N uniA78D ; G 3241 +U 42896 ; WX 914 ; N uniA790 ; G 3242 +U 42897 ; WX 727 ; N uniA791 ; G 3243 +U 42922 ; WX 945 ; N uniA7AA ; G 3244 +U 43000 ; WX 595 ; N uniA7F8 ; G 3245 +U 43001 ; WX 647 ; N uniA7F9 ; G 3246 +U 43002 ; WX 1069 ; N uniA7FA ; G 3247 +U 43003 ; WX 710 ; N uniA7FB ; G 3248 +U 43004 ; WX 752 ; N uniA7FC ; G 3249 +U 43005 ; WX 1107 ; N uniA7FD ; G 3250 +U 43006 ; WX 468 ; N uniA7FE ; G 3251 +U 43007 ; WX 1286 ; N uniA7FF ; G 3252 +U 62464 ; WX 705 ; N uniF400 ; G 3253 +U 62465 ; WX 716 ; N uniF401 ; G 3254 +U 62466 ; WX 765 ; N uniF402 ; G 3255 +U 62467 ; WX 999 ; N uniF403 ; G 3256 +U 62468 ; WX 716 ; N uniF404 ; G 3257 +U 62469 ; WX 710 ; N uniF405 ; G 3258 +U 62470 ; WX 776 ; N uniF406 ; G 3259 +U 62471 ; WX 1038 ; N uniF407 ; G 3260 +U 62472 ; WX 716 ; N uniF408 ; G 3261 +U 62473 ; WX 716 ; N uniF409 ; G 3262 +U 62474 ; WX 1309 ; N uniF40A ; G 3263 +U 62475 ; WX 734 ; N uniF40B ; G 3264 +U 62476 ; WX 733 ; N uniF40C ; G 3265 +U 62477 ; WX 1004 ; N uniF40D ; G 3266 +U 62478 ; WX 716 ; N uniF40E ; G 3267 +U 62479 ; WX 733 ; N uniF40F ; G 3268 +U 62480 ; WX 1050 ; N uniF410 ; G 3269 +U 62481 ; WX 797 ; N uniF411 ; G 3270 +U 62482 ; WX 850 ; N uniF412 ; G 3271 +U 62483 ; WX 799 ; N uniF413 ; G 3272 +U 62484 ; WX 996 ; N uniF414 ; G 3273 +U 62485 ; WX 732 ; N uniF415 ; G 3274 +U 62486 ; WX 987 ; N uniF416 ; G 3275 +U 62487 ; WX 731 ; N uniF417 ; G 3276 +U 62488 ; WX 739 ; N uniF418 ; G 3277 +U 62489 ; WX 733 ; N uniF419 ; G 3278 +U 62490 ; WX 780 ; N uniF41A ; G 3279 +U 62491 ; WX 733 ; N uniF41B ; G 3280 +U 62492 ; WX 739 ; N uniF41C ; G 3281 +U 62493 ; WX 717 ; N uniF41D ; G 3282 +U 62494 ; WX 780 ; N uniF41E ; G 3283 +U 62495 ; WX 936 ; N uniF41F ; G 3284 +U 62496 ; WX 716 ; N uniF420 ; G 3285 +U 62497 ; WX 826 ; N uniF421 ; G 3286 +U 62498 ; WX 717 ; N uniF422 ; G 3287 +U 62499 ; WX 716 ; N uniF423 ; G 3288 +U 62500 ; WX 716 ; N uniF424 ; G 3289 +U 62501 ; WX 773 ; N uniF425 ; G 3290 +U 62502 ; WX 1013 ; N uniF426 ; G 3291 +U 62504 ; WX 904 ; N uniF428 ; G 3292 +U 63173 ; WX 667 ; N uniF6C5 ; G 3293 +U 63185 ; WX 500 ; N cyrBreve ; G 3294 +U 63188 ; WX 500 ; N cyrbreve ; G 3295 +U 64256 ; WX 821 ; N uniFB00 ; G 3296 +U 64257 ; WX 727 ; N fi ; G 3297 +U 64258 ; WX 727 ; N fl ; G 3298 +U 64259 ; WX 1120 ; N uniFB03 ; G 3299 +U 64260 ; WX 1117 ; N uniFB04 ; G 3300 +U 64261 ; WX 871 ; N uniFB05 ; G 3301 +U 64262 ; WX 971 ; N uniFB06 ; G 3302 +U 65024 ; WX 0 ; N uniFE00 ; G 3303 +U 65025 ; WX 0 ; N uniFE01 ; G 3304 +U 65026 ; WX 0 ; N uniFE02 ; G 3305 +U 65027 ; WX 0 ; N uniFE03 ; G 3306 +U 65028 ; WX 0 ; N uniFE04 ; G 3307 +U 65029 ; WX 0 ; N uniFE05 ; G 3308 +U 65030 ; WX 0 ; N uniFE06 ; G 3309 +U 65031 ; WX 0 ; N uniFE07 ; G 3310 +U 65032 ; WX 0 ; N uniFE08 ; G 3311 +U 65033 ; WX 0 ; N uniFE09 ; G 3312 +U 65034 ; WX 0 ; N uniFE0A ; G 3313 +U 65035 ; WX 0 ; N uniFE0B ; G 3314 +U 65036 ; WX 0 ; N uniFE0C ; G 3315 +U 65037 ; WX 0 ; N uniFE0D ; G 3316 +U 65038 ; WX 0 ; N uniFE0E ; G 3317 +U 65039 ; WX 0 ; N uniFE0F ; G 3318 +U 65529 ; WX 0 ; N uniFFF9 ; G 3319 +U 65530 ; WX 0 ; N uniFFFA ; G 3320 +U 65531 ; WX 0 ; N uniFFFB ; G 3321 +U 65532 ; WX 0 ; N uniFFFC ; G 3322 +U 65533 ; WX 1113 ; N uniFFFD ; G 3323 +EndCharMetrics +StartKernData +StartKernPairs 1408 + +KPX dollar seven -112 +KPX dollar nine -149 +KPX dollar colon -102 +KPX dollar less -102 +KPX dollar I -36 +KPX dollar W -36 +KPX dollar Y -83 +KPX dollar Z -83 +KPX dollar backslash -83 +KPX dollar questiondown -83 +KPX dollar Aacute -83 +KPX dollar Hcircumflex -112 +KPX dollar hcircumflex -36 +KPX dollar Hbar -112 +KPX dollar hbar -36 +KPX dollar Kcommaaccent -102 +KPX dollar kcommaaccent -83 +KPX dollar kgreenlandic -102 +KPX dollar Lacute -83 +KPX dollar lacute -102 +KPX dollar uni01DC -112 +KPX dollar uni01DD -36 +KPX dollar uni01F4 -102 +KPX dollar uni01F5 -83 + +KPX percent ampersand 38 +KPX percent asterisk 38 +KPX percent two 38 +KPX percent less -36 +KPX percent Egrave 38 +KPX percent Ecircumflex 38 +KPX percent Igrave 38 +KPX percent Icircumflex 38 +KPX percent Thorn 38 +KPX percent agrave 38 +KPX percent acircumflex 38 +KPX percent adieresis 38 +KPX percent Dcaron 38 +KPX percent Dcroat 38 +KPX percent Emacron 38 +KPX percent Ebreve 38 +KPX percent kgreenlandic -36 +KPX percent lacute -36 +KPX percent uni01AC 38 +KPX percent uni01AE 38 +KPX percent uni01F0 38 +KPX percent uni01F4 -36 + + +KPX quotesingle nine -36 + + +KPX parenright dollar -120 +KPX parenright D -112 +KPX parenright H -112 +KPX parenright R -112 +KPX parenright U -36 +KPX parenright X -36 +KPX parenright cent -112 +KPX parenright sterling -112 +KPX parenright currency -112 +KPX parenright yen -112 +KPX parenright brokenbar -112 +KPX parenright section -112 +KPX parenright dieresis -112 +KPX parenright ordfeminine -112 +KPX parenright guillemotleft -112 +KPX parenright logicalnot -112 +KPX parenright sfthyphen -112 +KPX parenright acute -112 +KPX parenright mu -112 +KPX parenright paragraph -112 +KPX parenright periodcentered -112 +KPX parenright cedilla -112 +KPX parenright ordmasculine -112 +KPX parenright guillemotright -36 +KPX parenright onequarter -36 +KPX parenright onehalf -36 +KPX parenright threequarters -36 +KPX parenright Acircumflex -120 +KPX parenright Atilde -112 +KPX parenright Adieresis -120 +KPX parenright Aring -112 +KPX parenright AE -120 +KPX parenright Ccedilla -112 +KPX parenright Otilde -112 +KPX parenright multiply -112 +KPX parenright Ugrave -112 +KPX parenright Ucircumflex -112 +KPX parenright Yacute -112 +KPX parenright dcaron -112 +KPX parenright dmacron -112 +KPX parenright emacron -112 +KPX parenright ebreve -112 +KPX parenright edotaccent -36 +KPX parenright eogonek -36 +KPX parenright ecaron -36 +KPX parenright imacron -36 +KPX parenright ibreve -36 +KPX parenright iogonek -36 +KPX parenright dotlessi -36 +KPX parenright ij -36 +KPX parenright jcircumflex -36 +KPX parenright uni01A5 -112 +KPX parenright uni01AD -112 +KPX parenright Uhorn -112 +KPX parenright uni01F1 -112 + + + +KPX period dollar -83 +KPX period ampersand -55 +KPX period two -55 +KPX period eight -73 +KPX period colon -73 +KPX period less -55 +KPX period H -45 +KPX period R -45 +KPX period X -45 +KPX period backslash -92 +KPX period ordfeminine -45 +KPX period guillemotleft -45 +KPX period logicalnot -45 +KPX period sfthyphen -45 +KPX period acute -45 +KPX period mu -45 +KPX period paragraph -45 +KPX period periodcentered -45 +KPX period cedilla -45 +KPX period ordmasculine -36 +KPX period guillemotright -45 +KPX period onequarter -45 +KPX period onehalf -45 +KPX period threequarters -45 +KPX period questiondown -92 +KPX period Aacute -92 +KPX period Egrave -55 +KPX period Icircumflex -55 +KPX period Yacute -45 +KPX period Ebreve -55 +KPX period ebreve -45 +KPX period Idot -73 +KPX period dotlessi -45 +KPX period lacute -55 + +KPX slash seven -167 +KPX slash eight -112 +KPX slash nine -243 +KPX slash colon -139 +KPX slash less -131 +KPX slash backslash -73 +KPX slash questiondown -73 +KPX slash Aacute -73 +KPX slash Hbar -167 +KPX slash Idot -112 +KPX slash lacute -131 + + +KPX two nine -36 +KPX two semicolon -36 + +KPX three dollar -149 +KPX three D -55 +KPX three H -55 +KPX three R -55 +KPX three cent -55 +KPX three sterling -55 +KPX three currency -55 +KPX three yen -55 +KPX three brokenbar -55 +KPX three section -55 +KPX three dieresis -55 +KPX three ordfeminine -55 +KPX three guillemotleft -55 +KPX three logicalnot -55 +KPX three sfthyphen -55 +KPX three acute -55 +KPX three mu -55 +KPX three paragraph -55 +KPX three periodcentered -55 +KPX three cedilla -55 +KPX three ordmasculine -55 +KPX three Yacute -55 +KPX three ebreve -55 + + +KPX five seven -36 +KPX five nine -73 +KPX five colon -45 +KPX five less -63 +KPX five D 47 +KPX five backslash -36 +KPX five cent 47 +KPX five sterling 47 +KPX five currency 47 +KPX five yen 47 +KPX five brokenbar 47 +KPX five section 47 +KPX five dieresis 47 +KPX five ordmasculine 38 +KPX five questiondown -36 +KPX five Aacute -36 +KPX five Hbar -36 +KPX five lacute -63 + +KPX six six -45 +KPX six Gdotaccent -45 +KPX six Gcommaaccent -45 + +KPX seven dollar -112 +KPX seven seven -73 +KPX seven D -196 +KPX seven F -235 +KPX seven H -235 +KPX seven R -235 +KPX seven U -149 +KPX seven V -188 +KPX seven X -188 +KPX seven Z -225 +KPX seven backslash -225 +KPX seven m -149 +KPX seven braceright -149 +KPX seven cent -96 +KPX seven sterling -196 +KPX seven currency -96 +KPX seven yen -96 +KPX seven brokenbar -96 +KPX seven section -96 +KPX seven dieresis -159 +KPX seven copyright -235 +KPX seven ordfeminine -175 +KPX seven guillemotleft -235 +KPX seven logicalnot -175 +KPX seven sfthyphen -175 +KPX seven acute -155 +KPX seven mu -235 +KPX seven paragraph -155 +KPX seven periodcentered -155 +KPX seven cedilla -155 +KPX seven ordmasculine -159 +KPX seven guillemotright -158 +KPX seven onequarter -188 +KPX seven onehalf -158 +KPX seven threequarters -158 +KPX seven questiondown -225 +KPX seven Aacute -225 +KPX seven Eacute -235 +KPX seven Idieresis -235 +KPX seven Yacute -235 +KPX seven ebreve -159 +KPX seven edotaccent -149 +KPX seven ecaron -149 +KPX seven gdotaccent -188 +KPX seven gcommaaccent -188 +KPX seven Hbar -73 +KPX seven dotlessi -188 + +KPX eight dollar -63 + +KPX nine dollar -159 +KPX nine two -36 +KPX nine D -188 +KPX nine H -188 +KPX nine L -36 +KPX nine R -188 +KPX nine X -131 +KPX nine backslash -83 +KPX nine cent -188 +KPX nine sterling -188 +KPX nine currency -188 +KPX nine yen -188 +KPX nine brokenbar -188 +KPX nine section -188 +KPX nine dieresis -188 +KPX nine ordfeminine -188 +KPX nine guillemotleft -188 +KPX nine logicalnot -188 +KPX nine sfthyphen -188 +KPX nine acute -188 +KPX nine mu -188 +KPX nine paragraph -188 +KPX nine periodcentered -188 +KPX nine cedilla -188 +KPX nine ordmasculine -188 +KPX nine guillemotright -131 +KPX nine onequarter -131 +KPX nine onehalf -131 +KPX nine threequarters -131 +KPX nine questiondown -83 +KPX nine Aacute -83 +KPX nine Yacute -188 +KPX nine Ebreve -36 +KPX nine ebreve -188 +KPX nine dotlessi -131 + +KPX colon dollar -131 +KPX colon D -178 +KPX colon H -167 +KPX colon L -36 +KPX colon R -167 +KPX colon U -92 +KPX colon X -83 +KPX colon backslash -45 +KPX colon cent -178 +KPX colon sterling -178 +KPX colon currency -178 +KPX colon yen -178 +KPX colon brokenbar -178 +KPX colon section -178 +KPX colon dieresis -139 +KPX colon ordfeminine -167 +KPX colon guillemotleft -167 +KPX colon logicalnot -167 +KPX colon sfthyphen -167 +KPX colon acute -167 +KPX colon mu -167 +KPX colon paragraph -167 +KPX colon periodcentered -167 +KPX colon cedilla -167 +KPX colon ordmasculine -167 +KPX colon guillemotright -83 +KPX colon onequarter -83 +KPX colon onehalf -83 +KPX colon threequarters -83 +KPX colon questiondown -45 +KPX colon Aacute -45 +KPX colon Yacute -167 +KPX colon ebreve -167 +KPX colon edotaccent -92 +KPX colon ecaron -92 +KPX colon dotlessi -83 + +KPX semicolon dollar -73 +KPX semicolon ampersand -36 +KPX semicolon two -36 +KPX semicolon Egrave -36 +KPX semicolon Icircumflex -36 +KPX semicolon Ebreve -36 + +KPX less dollar -131 +KPX less ampersand -36 +KPX less D -159 +KPX less H -178 +KPX less L -36 +KPX less R -178 +KPX less X -178 +KPX less cent -159 +KPX less sterling -159 +KPX less currency -159 +KPX less yen -159 +KPX less brokenbar -159 +KPX less section -159 +KPX less dieresis -159 +KPX less ordfeminine -178 +KPX less guillemotleft -178 +KPX less logicalnot -178 +KPX less sfthyphen -178 +KPX less acute -178 +KPX less mu -178 +KPX less paragraph -178 +KPX less periodcentered -178 +KPX less cedilla -178 +KPX less ordmasculine -178 +KPX less guillemotright -178 +KPX less onequarter -178 +KPX less onehalf -178 +KPX less threequarters -178 +KPX less Egrave -36 +KPX less Icircumflex -36 +KPX less Yacute -178 +KPX less ebreve -178 +KPX less dotlessi -178 + + + + + + + + + + +KPX m hyphen -73 +KPX m seven -149 +KPX m Hbar -149 + +KPX braceright hyphen -73 +KPX braceright seven -149 +KPX braceright Hbar -149 + + + + + + + + + + + + +KPX Acircumflex seven -112 +KPX Acircumflex nine -149 +KPX Acircumflex colon -102 +KPX Acircumflex less -102 +KPX Acircumflex I -36 +KPX Acircumflex W -36 +KPX Acircumflex Y -83 +KPX Acircumflex Z -83 +KPX Acircumflex backslash -83 +KPX Acircumflex questiondown -83 +KPX Acircumflex Aacute -83 +KPX Acircumflex Hcircumflex -112 +KPX Acircumflex hcircumflex -36 +KPX Acircumflex Hbar -112 +KPX Acircumflex hbar -36 +KPX Acircumflex Kcommaaccent -102 +KPX Acircumflex kcommaaccent -83 +KPX Acircumflex kgreenlandic -102 +KPX Acircumflex Lacute -83 +KPX Acircumflex lacute -102 +KPX Acircumflex uni01DC -112 +KPX Acircumflex uni01DD -36 +KPX Acircumflex uni01F4 -102 +KPX Acircumflex uni01F5 -83 + +KPX Adieresis seven -112 +KPX Adieresis nine -149 +KPX Adieresis colon -102 +KPX Adieresis less -102 +KPX Adieresis I -36 +KPX Adieresis W -36 +KPX Adieresis Y -83 +KPX Adieresis Z -83 +KPX Adieresis backslash -83 +KPX Adieresis questiondown -83 +KPX Adieresis Aacute -83 +KPX Adieresis Hcircumflex -112 +KPX Adieresis hcircumflex -36 +KPX Adieresis Hbar -112 +KPX Adieresis hbar -36 +KPX Adieresis Kcommaaccent -102 +KPX Adieresis kcommaaccent -83 +KPX Adieresis kgreenlandic -102 +KPX Adieresis Lacute -83 +KPX Adieresis lacute -102 +KPX Adieresis uni01DC -112 +KPX Adieresis uni01DD -36 +KPX Adieresis uni01F4 -102 +KPX Adieresis uni01F5 -83 + +KPX AE seven -112 +KPX AE nine -149 +KPX AE colon -102 +KPX AE less -102 +KPX AE I -36 +KPX AE W -36 +KPX AE Y -83 +KPX AE Z -83 +KPX AE backslash -83 +KPX AE questiondown -83 +KPX AE Aacute -83 +KPX AE Hcircumflex -112 +KPX AE hcircumflex -36 +KPX AE Hbar -112 +KPX AE hbar -36 +KPX AE Kcommaaccent -102 +KPX AE kcommaaccent -83 +KPX AE kgreenlandic -102 +KPX AE Lacute -83 +KPX AE lacute -102 +KPX AE uni01DC -112 +KPX AE uni01DD -36 +KPX AE uni01F4 -102 +KPX AE uni01F5 -83 + + + + + +KPX Eth nine -36 + +KPX Ograve nine -36 + + + +KPX ucircumflex seven -167 +KPX ucircumflex eight -112 +KPX ucircumflex nine -243 +KPX ucircumflex colon -139 +KPX ucircumflex less -131 +KPX ucircumflex backslash -73 +KPX ucircumflex questiondown -73 +KPX ucircumflex Aacute -73 +KPX ucircumflex Hbar -167 +KPX ucircumflex Idot -112 +KPX ucircumflex lacute -131 + +KPX ydieresis seven -167 +KPX ydieresis eight -112 +KPX ydieresis nine -243 +KPX ydieresis colon -139 +KPX ydieresis less -131 +KPX ydieresis backslash -73 +KPX ydieresis questiondown -73 +KPX ydieresis Aacute -73 +KPX ydieresis Hbar -167 +KPX ydieresis Idot -112 +KPX ydieresis lacute -131 + +KPX Abreve O -241 + +KPX abreve seven -167 +KPX abreve eight -112 +KPX abreve nine -243 +KPX abreve colon -139 +KPX abreve less -131 +KPX abreve backslash -73 +KPX abreve questiondown -73 +KPX abreve Aacute -73 +KPX abreve Hbar -167 +KPX abreve Idot -112 +KPX abreve lacute -131 + + + +KPX Edotaccent seven -36 +KPX Edotaccent nine -73 +KPX Edotaccent colon -45 +KPX Edotaccent less -63 +KPX Edotaccent D 47 +KPX Edotaccent backslash -36 +KPX Edotaccent cent 47 +KPX Edotaccent sterling 47 +KPX Edotaccent currency 47 +KPX Edotaccent yen 47 +KPX Edotaccent brokenbar 47 +KPX Edotaccent section 47 +KPX Edotaccent dieresis 47 +KPX Edotaccent ordmasculine 38 +KPX Edotaccent questiondown -36 +KPX Edotaccent Aacute -36 +KPX Edotaccent Hbar -36 +KPX Edotaccent lacute -63 + + +KPX Ecaron seven -36 +KPX Ecaron nine -73 +KPX Ecaron colon -45 +KPX Ecaron less -63 +KPX Ecaron D 47 +KPX Ecaron backslash -36 +KPX Ecaron cent 47 +KPX Ecaron sterling 47 +KPX Ecaron currency 47 +KPX Ecaron yen 47 +KPX Ecaron brokenbar 47 +KPX Ecaron section 47 +KPX Ecaron dieresis 47 +KPX Ecaron ordmasculine 38 +KPX Ecaron questiondown -36 +KPX Ecaron Aacute -36 +KPX Ecaron Hbar -36 +KPX Ecaron lacute -63 + + +KPX Gdotaccent six -45 +KPX Gdotaccent Gdotaccent -45 +KPX Gdotaccent Gcommaaccent -45 + +KPX Gcommaaccent six -45 +KPX Gcommaaccent Gdotaccent -45 +KPX Gcommaaccent Gcommaaccent -45 + +KPX Hbar dollar -112 +KPX Hbar seven -73 +KPX Hbar D -196 +KPX Hbar F -235 +KPX Hbar H -235 +KPX Hbar R -235 +KPX Hbar U -149 +KPX Hbar V -188 +KPX Hbar X -188 +KPX Hbar Z -225 +KPX Hbar backslash -225 +KPX Hbar m -149 +KPX Hbar braceright -149 +KPX Hbar cent -196 +KPX Hbar sterling -196 +KPX Hbar currency -196 +KPX Hbar yen -196 +KPX Hbar brokenbar -196 +KPX Hbar section -196 +KPX Hbar dieresis -159 +KPX Hbar copyright -235 +KPX Hbar ordfeminine -235 +KPX Hbar guillemotleft -235 +KPX Hbar logicalnot -235 +KPX Hbar sfthyphen -235 +KPX Hbar acute -235 +KPX Hbar mu -235 +KPX Hbar paragraph -235 +KPX Hbar periodcentered -235 +KPX Hbar cedilla -235 +KPX Hbar ordmasculine -159 +KPX Hbar guillemotright -188 +KPX Hbar onequarter -188 +KPX Hbar onehalf -188 +KPX Hbar threequarters -188 +KPX Hbar questiondown -225 +KPX Hbar Aacute -225 +KPX Hbar Eacute -235 +KPX Hbar Idieresis -235 +KPX Hbar Yacute -235 +KPX Hbar ebreve -159 +KPX Hbar edotaccent -149 +KPX Hbar ecaron -149 +KPX Hbar gdotaccent -188 +KPX Hbar gcommaaccent -188 +KPX Hbar Hbar -73 +KPX Hbar dotlessi -188 + +KPX Idot dollar -63 + +KPX lacute dollar -131 +KPX lacute ampersand -36 +KPX lacute D -159 +KPX lacute H -178 +KPX lacute L -36 +KPX lacute R -178 +KPX lacute X -178 +KPX lacute cent -159 +KPX lacute sterling -159 +KPX lacute currency -159 +KPX lacute yen -159 +KPX lacute brokenbar -159 +KPX lacute section -159 +KPX lacute dieresis -159 +KPX lacute ordfeminine -178 +KPX lacute guillemotleft -178 +KPX lacute logicalnot -178 +KPX lacute sfthyphen -178 +KPX lacute acute -178 +KPX lacute mu -178 +KPX lacute paragraph -178 +KPX lacute periodcentered -178 +KPX lacute cedilla -178 +KPX lacute ordmasculine -178 +KPX lacute guillemotright -178 +KPX lacute onequarter -178 +KPX lacute onehalf -178 +KPX lacute threequarters -178 +KPX lacute Egrave -36 +KPX lacute Icircumflex -36 +KPX lacute Yacute -178 +KPX lacute ebreve -178 +KPX lacute dotlessi -178 + + +KPX uni027D dollar -282 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a36dd4b70a833b3cf1247dc2ac7e54371e40893d GIT binary patch literal 347460 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

^7?h-i{AepG<}~j_?6d?#me>CD}yuE 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%0D$mqY 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 R^ZHVmj|Y``eW}dHgUYFo%>7fDU%yo5{;ACS zh05GNmHG8WCH(XCOOFA-KVQFO!#`iYWWzsSzhuKd;|SUC&p1Lh{PXoqHvIGTO*Z^9 zj?m)=@Xt6xHvBV=kPZJlAIRo**Kj;V%k}y58jh#P=K9st$7a)luDZ%<*2+fy2K9tuy zbFO4_58*jivbl$_;yA;KV=DQ38DCjsm-SwHD!eA@Q}2G5d?zU(Ehu z_7}6inEl1H8bm$1Kt{Uz)#VSfqxOW0q+{u1_=u)l=;CG0QB{Sjza zno=s}{s^+!%Ker6++WGh{gwROU&+t?mHgaa$y|8ncLDAKcz8(*11&Po87l^7QZH5ZacJ}PcfpEKTFEX zKdacZEbhPT`nu(xyEEE4=oRez*WjWRWt+F^hpqo%wHfq-7$azTjNaH%DeUQ8jrk4D z4*HoVsvf-zZp64T<$RkKQ##zy2ROdwzqXfux3Yiv@s;fa$5+0)e4CbJSC?eo zKPLLg&kv&&p?Rn6JED6|Q>Q*ZFYNsNoV=O8s=^a@EstmF=jqT__apP#2H<__<}`*)igoW#VaDJkduy?u*Bkibt1< zNB$HKFA)ze6AvsC_un^4-oHrPH%i=FE$&$)?smk|W#X=7;?8B_j=thHTim*)xMgE; zvn_5OsoiwrKzZXpal`ck(HlDL+NYlnzyO5$oqTy?f{V ztX(leTz=MIdHFJN*`@vEWrM_}{lz60Z!RxcDlYCBBro1vTtvl1OT~p343rlx6Bi5= z=X>J3bC=5VmWgxE*+ZVYRGhn5JLl|;FG-aqnR z?aY4S3|E{nQagQ+SmKD&mWWe5amqU4}eapDP%JaG+if+J2CsU3fu zCy!r49OsE+kFn*kzBtAfM-LK59l1yzwM-mI-#BuSINTA34Hk!zai}j2Ie2w>$TD&8 zzJ2AvtBb`4dUEkHaiAv-9H|{ZM;x$BEZTp4xoDZ#e|@pv!liP*Wn$riJ>|={r%fw7u%p9rB7$RC0iRNWunJv4_)F z?y*el)=%uR^B}p)7Gmc?Vwx{@a>SI$1Lc$@V)8&SX`t9~;#zXYjl{%0tI3ILi3wCp zSX+!Ax1JooNQ`Unv|6A2D*Vw*9ul z_(*MYOKi5WDK{G=hIwMxNNv+i`pHd~h)rnUCjG=FBeji9u@RkOqorcQ)rZIphlvfS z*kG9$N+%q;L=34ixh2Kr(h zUksp+2P_k7uQg1rJzK0r)>^~Fn)I9GYYrA`3=peRC$Bz4^r!FkUnKfbllpBTR-@io zZJFpxpY>f&^jS^xS*&@~IPXv4I>H^PIempqhuTYpHAtAo>e5^)jMarsr`6XG(iU>0 zriuPiTU*dC!V9IZ6#a!5sj0N3E+bngi?u=@q1>S~A9kFw`Tsxv75=|d?LmeA1ydti Ag#Z8m literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ufm new file mode 100644 index 0000000..f6db21d --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-BoldItalic.ufm @@ -0,0 +1,3892 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Serif +FontSubfamily Bold Italic +UniqueID DejaVu Serif Bold Italic +FullName DejaVu Serif Bold Italic +Version Version 2.37 +PostScriptName DejaVuSerif-BoldItalic +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +PreferredFamily DejaVu Serif +PreferredSubfamily Bold Italic +Weight Bold +ItalicAngle -11 +IsFixedPitch false +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 939 +Descender -236 +FontBBox -906 -389 1925 1145 +StartCharMetrics 3506 +U 32 ; WX 348 ; N space ; G 3 +U 33 ; WX 439 ; N exclam ; G 4 +U 34 ; WX 521 ; N quotedbl ; G 5 +U 35 ; WX 838 ; N numbersign ; G 6 +U 36 ; WX 696 ; N dollar ; G 7 +U 37 ; WX 950 ; N percent ; G 8 +U 38 ; WX 903 ; N ampersand ; G 9 +U 39 ; WX 306 ; N quotesingle ; G 10 +U 40 ; WX 473 ; N parenleft ; G 11 +U 41 ; WX 473 ; N parenright ; G 12 +U 42 ; WX 523 ; N asterisk ; G 13 +U 43 ; WX 838 ; N plus ; G 14 +U 44 ; WX 348 ; N comma ; G 15 +U 45 ; WX 415 ; N hyphen ; G 16 +U 46 ; WX 348 ; N period ; G 17 +U 47 ; WX 365 ; N slash ; G 18 +U 48 ; WX 696 ; N zero ; G 19 +U 49 ; WX 696 ; N one ; G 20 +U 50 ; WX 696 ; N two ; G 21 +U 51 ; WX 696 ; N three ; G 22 +U 52 ; WX 696 ; N four ; G 23 +U 53 ; WX 696 ; N five ; G 24 +U 54 ; WX 696 ; N six ; G 25 +U 55 ; WX 696 ; N seven ; G 26 +U 56 ; WX 696 ; N eight ; G 27 +U 57 ; WX 696 ; N nine ; G 28 +U 58 ; WX 369 ; N colon ; G 29 +U 59 ; WX 369 ; N semicolon ; G 30 +U 60 ; WX 838 ; N less ; G 31 +U 61 ; WX 838 ; N equal ; G 32 +U 62 ; WX 838 ; N greater ; G 33 +U 63 ; WX 586 ; N question ; G 34 +U 64 ; WX 1000 ; N at ; G 35 +U 65 ; WX 776 ; N A ; G 36 +U 66 ; WX 845 ; N B ; G 37 +U 67 ; WX 796 ; N C ; G 38 +U 68 ; WX 867 ; N D ; G 39 +U 69 ; WX 762 ; N E ; G 40 +U 70 ; WX 710 ; N F ; G 41 +U 71 ; WX 854 ; N G ; G 42 +U 72 ; WX 945 ; N H ; G 43 +U 73 ; WX 468 ; N I ; G 44 +U 74 ; WX 473 ; N J ; G 45 +U 75 ; WX 869 ; N K ; G 46 +U 76 ; WX 703 ; N L ; G 47 +U 77 ; WX 1107 ; N M ; G 48 +U 78 ; WX 914 ; N N ; G 49 +U 79 ; WX 871 ; N O ; G 50 +U 80 ; WX 752 ; N P ; G 51 +U 81 ; WX 871 ; N Q ; G 52 +U 82 ; WX 831 ; N R ; G 53 +U 83 ; WX 722 ; N S ; G 54 +U 84 ; WX 744 ; N T ; G 55 +U 85 ; WX 872 ; N U ; G 56 +U 86 ; WX 776 ; N V ; G 57 +U 87 ; WX 1123 ; N W ; G 58 +U 88 ; WX 776 ; N X ; G 59 +U 89 ; WX 714 ; N Y ; G 60 +U 90 ; WX 730 ; N Z ; G 61 +U 91 ; WX 473 ; N bracketleft ; G 62 +U 92 ; WX 365 ; N backslash ; G 63 +U 93 ; WX 473 ; N bracketright ; G 64 +U 94 ; WX 838 ; N asciicircum ; G 65 +U 95 ; WX 500 ; N underscore ; G 66 +U 96 ; WX 500 ; N grave ; G 67 +U 97 ; WX 648 ; N a ; G 68 +U 98 ; WX 699 ; N b ; G 69 +U 99 ; WX 609 ; N c ; G 70 +U 100 ; WX 699 ; N d ; G 71 +U 101 ; WX 636 ; N e ; G 72 +U 102 ; WX 430 ; N f ; G 73 +U 103 ; WX 699 ; N g ; G 74 +U 104 ; WX 727 ; N h ; G 75 +U 105 ; WX 380 ; N i ; G 76 +U 106 ; WX 362 ; N j ; G 77 +U 107 ; WX 693 ; N k ; G 78 +U 108 ; WX 380 ; N l ; G 79 +U 109 ; WX 1058 ; N m ; G 80 +U 110 ; WX 727 ; N n ; G 81 +U 111 ; WX 667 ; N o ; G 82 +U 112 ; WX 699 ; N p ; G 83 +U 113 ; WX 699 ; N q ; G 84 +U 114 ; WX 527 ; N r ; G 85 +U 115 ; WX 563 ; N s ; G 86 +U 116 ; WX 462 ; N t ; G 87 +U 117 ; WX 727 ; N u ; G 88 +U 118 ; WX 581 ; N v ; G 89 +U 119 ; WX 861 ; N w ; G 90 +U 120 ; WX 596 ; N x ; G 91 +U 121 ; WX 581 ; N y ; G 92 +U 122 ; WX 568 ; N z ; G 93 +U 123 ; WX 643 ; N braceleft ; G 94 +U 124 ; WX 364 ; N bar ; G 95 +U 125 ; WX 643 ; N braceright ; G 96 +U 126 ; WX 838 ; N asciitilde ; G 97 +U 160 ; WX 348 ; N nbspace ; G 98 +U 161 ; WX 439 ; N exclamdown ; G 99 +U 162 ; WX 696 ; N cent ; G 100 +U 163 ; WX 696 ; N sterling ; G 101 +U 164 ; WX 636 ; N currency ; G 102 +U 165 ; WX 696 ; N yen ; G 103 +U 166 ; WX 364 ; N brokenbar ; G 104 +U 167 ; WX 523 ; N section ; G 105 +U 168 ; WX 500 ; N dieresis ; G 106 +U 169 ; WX 1000 ; N copyright ; G 107 +U 170 ; WX 487 ; N ordfeminine ; G 108 +U 171 ; WX 625 ; N guillemotleft ; G 109 +U 172 ; WX 838 ; N logicalnot ; G 110 +U 173 ; WX 415 ; N sfthyphen ; G 111 +U 174 ; WX 1000 ; N registered ; G 112 +U 175 ; WX 500 ; N macron ; G 113 +U 176 ; WX 500 ; N degree ; G 114 +U 177 ; WX 838 ; N plusminus ; G 115 +U 178 ; WX 438 ; N twosuperior ; G 116 +U 179 ; WX 438 ; N threesuperior ; G 117 +U 180 ; WX 500 ; N acute ; G 118 +U 181 ; WX 732 ; N mu ; G 119 +U 182 ; WX 636 ; N paragraph ; G 120 +U 183 ; WX 348 ; N periodcentered ; G 121 +U 184 ; WX 500 ; N cedilla ; G 122 +U 185 ; WX 438 ; N onesuperior ; G 123 +U 186 ; WX 500 ; N ordmasculine ; G 124 +U 187 ; WX 625 ; N guillemotright ; G 125 +U 188 ; WX 1043 ; N onequarter ; G 126 +U 189 ; WX 1043 ; N onehalf ; G 127 +U 190 ; WX 1043 ; N threequarters ; G 128 +U 191 ; WX 586 ; N questiondown ; G 129 +U 192 ; WX 776 ; N Agrave ; G 130 +U 193 ; WX 776 ; N Aacute ; G 131 +U 194 ; WX 776 ; N Acircumflex ; G 132 +U 195 ; WX 776 ; N Atilde ; G 133 +U 196 ; WX 776 ; N Adieresis ; G 134 +U 197 ; WX 776 ; N Aring ; G 135 +U 198 ; WX 1034 ; N AE ; G 136 +U 199 ; WX 796 ; N Ccedilla ; G 137 +U 200 ; WX 762 ; N Egrave ; G 138 +U 201 ; WX 762 ; N Eacute ; G 139 +U 202 ; WX 762 ; N Ecircumflex ; G 140 +U 203 ; WX 762 ; N Edieresis ; G 141 +U 204 ; WX 468 ; N Igrave ; G 142 +U 205 ; WX 468 ; N Iacute ; G 143 +U 206 ; WX 468 ; N Icircumflex ; G 144 +U 207 ; WX 468 ; N Idieresis ; G 145 +U 208 ; WX 874 ; N Eth ; G 146 +U 209 ; WX 914 ; N Ntilde ; G 147 +U 210 ; WX 871 ; N Ograve ; G 148 +U 211 ; WX 871 ; N Oacute ; G 149 +U 212 ; WX 871 ; N Ocircumflex ; G 150 +U 213 ; WX 871 ; N Otilde ; G 151 +U 214 ; WX 871 ; N Odieresis ; G 152 +U 215 ; WX 838 ; N multiply ; G 153 +U 216 ; WX 871 ; N Oslash ; G 154 +U 217 ; WX 872 ; N Ugrave ; G 155 +U 218 ; WX 872 ; N Uacute ; G 156 +U 219 ; WX 872 ; N Ucircumflex ; G 157 +U 220 ; WX 872 ; N Udieresis ; G 158 +U 221 ; WX 714 ; N Yacute ; G 159 +U 222 ; WX 757 ; N Thorn ; G 160 +U 223 ; WX 760 ; N germandbls ; G 161 +U 224 ; WX 648 ; N agrave ; G 162 +U 225 ; WX 648 ; N aacute ; G 163 +U 226 ; WX 648 ; N acircumflex ; G 164 +U 227 ; WX 648 ; N atilde ; G 165 +U 228 ; WX 648 ; N adieresis ; G 166 +U 229 ; WX 648 ; N aring ; G 167 +U 230 ; WX 932 ; N ae ; G 168 +U 231 ; WX 609 ; N ccedilla ; G 169 +U 232 ; WX 636 ; N egrave ; G 170 +U 233 ; WX 636 ; N eacute ; G 171 +U 234 ; WX 636 ; N ecircumflex ; G 172 +U 235 ; WX 636 ; N edieresis ; G 173 +U 236 ; WX 380 ; N igrave ; G 174 +U 237 ; WX 380 ; N iacute ; G 175 +U 238 ; WX 380 ; N icircumflex ; G 176 +U 239 ; WX 380 ; N idieresis ; G 177 +U 240 ; WX 667 ; N eth ; G 178 +U 241 ; WX 727 ; N ntilde ; G 179 +U 242 ; WX 667 ; N ograve ; G 180 +U 243 ; WX 667 ; N oacute ; G 181 +U 244 ; WX 667 ; N ocircumflex ; G 182 +U 245 ; WX 667 ; N otilde ; G 183 +U 246 ; WX 667 ; N odieresis ; G 184 +U 247 ; WX 838 ; N divide ; G 185 +U 248 ; WX 667 ; N oslash ; G 186 +U 249 ; WX 727 ; N ugrave ; G 187 +U 250 ; WX 727 ; N uacute ; G 188 +U 251 ; WX 727 ; N ucircumflex ; G 189 +U 252 ; WX 727 ; N udieresis ; G 190 +U 253 ; WX 581 ; N yacute ; G 191 +U 254 ; WX 699 ; N thorn ; G 192 +U 255 ; WX 581 ; N ydieresis ; G 193 +U 256 ; WX 776 ; N Amacron ; G 194 +U 257 ; WX 648 ; N amacron ; G 195 +U 258 ; WX 776 ; N Abreve ; G 196 +U 259 ; WX 648 ; N abreve ; G 197 +U 260 ; WX 776 ; N Aogonek ; G 198 +U 261 ; WX 648 ; N aogonek ; G 199 +U 262 ; WX 796 ; N Cacute ; G 200 +U 263 ; WX 609 ; N cacute ; G 201 +U 264 ; WX 796 ; N Ccircumflex ; G 202 +U 265 ; WX 609 ; N ccircumflex ; G 203 +U 266 ; WX 796 ; N Cdotaccent ; G 204 +U 267 ; WX 609 ; N cdotaccent ; G 205 +U 268 ; WX 796 ; N Ccaron ; G 206 +U 269 ; WX 609 ; N ccaron ; G 207 +U 270 ; WX 867 ; N Dcaron ; G 208 +U 271 ; WX 699 ; N dcaron ; G 209 +U 272 ; WX 874 ; N Dcroat ; G 210 +U 273 ; WX 699 ; N dmacron ; G 211 +U 274 ; WX 762 ; N Emacron ; G 212 +U 275 ; WX 636 ; N emacron ; G 213 +U 276 ; WX 762 ; N Ebreve ; G 214 +U 277 ; WX 636 ; N ebreve ; G 215 +U 278 ; WX 762 ; N Edotaccent ; G 216 +U 279 ; WX 636 ; N edotaccent ; G 217 +U 280 ; WX 762 ; N Eogonek ; G 218 +U 281 ; WX 636 ; N eogonek ; G 219 +U 282 ; WX 762 ; N Ecaron ; G 220 +U 283 ; WX 636 ; N ecaron ; G 221 +U 284 ; WX 854 ; N Gcircumflex ; G 222 +U 285 ; WX 699 ; N gcircumflex ; G 223 +U 286 ; WX 854 ; N Gbreve ; G 224 +U 287 ; WX 699 ; N gbreve ; G 225 +U 288 ; WX 854 ; N Gdotaccent ; G 226 +U 289 ; WX 699 ; N gdotaccent ; G 227 +U 290 ; WX 854 ; N Gcommaaccent ; G 228 +U 291 ; WX 699 ; N gcommaaccent ; G 229 +U 292 ; WX 945 ; N Hcircumflex ; G 230 +U 293 ; WX 727 ; N hcircumflex ; G 231 +U 294 ; WX 945 ; N Hbar ; G 232 +U 295 ; WX 727 ; N hbar ; G 233 +U 296 ; WX 468 ; N Itilde ; G 234 +U 297 ; WX 380 ; N itilde ; G 235 +U 298 ; WX 468 ; N Imacron ; G 236 +U 299 ; WX 380 ; N imacron ; G 237 +U 300 ; WX 468 ; N Ibreve ; G 238 +U 301 ; WX 380 ; N ibreve ; G 239 +U 302 ; WX 468 ; N Iogonek ; G 240 +U 303 ; WX 380 ; N iogonek ; G 241 +U 304 ; WX 468 ; N Idot ; G 242 +U 305 ; WX 380 ; N dotlessi ; G 243 +U 306 ; WX 942 ; N IJ ; G 244 +U 307 ; WX 751 ; N ij ; G 245 +U 308 ; WX 473 ; N Jcircumflex ; G 246 +U 309 ; WX 362 ; N jcircumflex ; G 247 +U 310 ; WX 869 ; N Kcommaaccent ; G 248 +U 311 ; WX 693 ; N kcommaaccent ; G 249 +U 312 ; WX 693 ; N kgreenlandic ; G 250 +U 313 ; WX 703 ; N Lacute ; G 251 +U 314 ; WX 380 ; N lacute ; G 252 +U 315 ; WX 703 ; N Lcommaaccent ; G 253 +U 316 ; WX 380 ; N lcommaaccent ; G 254 +U 317 ; WX 703 ; N Lcaron ; G 255 +U 318 ; WX 508 ; N lcaron ; G 256 +U 319 ; WX 703 ; N Ldot ; G 257 +U 320 ; WX 557 ; N ldot ; G 258 +U 321 ; WX 710 ; N Lslash ; G 259 +U 322 ; WX 385 ; N lslash ; G 260 +U 323 ; WX 914 ; N Nacute ; G 261 +U 324 ; WX 727 ; N nacute ; G 262 +U 325 ; WX 914 ; N Ncommaaccent ; G 263 +U 326 ; WX 727 ; N ncommaaccent ; G 264 +U 327 ; WX 914 ; N Ncaron ; G 265 +U 328 ; WX 727 ; N ncaron ; G 266 +U 329 ; WX 1008 ; N napostrophe ; G 267 +U 330 ; WX 872 ; N Eng ; G 268 +U 331 ; WX 727 ; N eng ; G 269 +U 332 ; WX 871 ; N Omacron ; G 270 +U 333 ; WX 667 ; N omacron ; G 271 +U 334 ; WX 871 ; N Obreve ; G 272 +U 335 ; WX 667 ; N obreve ; G 273 +U 336 ; WX 871 ; N Ohungarumlaut ; G 274 +U 337 ; WX 667 ; N ohungarumlaut ; G 275 +U 338 ; WX 1180 ; N OE ; G 276 +U 339 ; WX 1028 ; N oe ; G 277 +U 340 ; WX 831 ; N Racute ; G 278 +U 341 ; WX 527 ; N racute ; G 279 +U 342 ; WX 831 ; N Rcommaaccent ; G 280 +U 343 ; WX 527 ; N rcommaaccent ; G 281 +U 344 ; WX 831 ; N Rcaron ; G 282 +U 345 ; WX 527 ; N rcaron ; G 283 +U 346 ; WX 722 ; N Sacute ; G 284 +U 347 ; WX 563 ; N sacute ; G 285 +U 348 ; WX 722 ; N Scircumflex ; G 286 +U 349 ; WX 563 ; N scircumflex ; G 287 +U 350 ; WX 722 ; N Scedilla ; G 288 +U 351 ; WX 563 ; N scedilla ; G 289 +U 352 ; WX 722 ; N Scaron ; G 290 +U 353 ; WX 563 ; N scaron ; G 291 +U 354 ; WX 744 ; N Tcommaaccent ; G 292 +U 355 ; WX 462 ; N tcommaaccent ; G 293 +U 356 ; WX 744 ; N Tcaron ; G 294 +U 357 ; WX 462 ; N tcaron ; G 295 +U 358 ; WX 744 ; N Tbar ; G 296 +U 359 ; WX 462 ; N tbar ; G 297 +U 360 ; WX 872 ; N Utilde ; G 298 +U 361 ; WX 727 ; N utilde ; G 299 +U 362 ; WX 872 ; N Umacron ; G 300 +U 363 ; WX 727 ; N umacron ; G 301 +U 364 ; WX 872 ; N Ubreve ; G 302 +U 365 ; WX 727 ; N ubreve ; G 303 +U 366 ; WX 872 ; N Uring ; G 304 +U 367 ; WX 727 ; N uring ; G 305 +U 368 ; WX 872 ; N Uhungarumlaut ; G 306 +U 369 ; WX 727 ; N uhungarumlaut ; G 307 +U 370 ; WX 872 ; N Uogonek ; G 308 +U 371 ; WX 727 ; N uogonek ; G 309 +U 372 ; WX 1123 ; N Wcircumflex ; G 310 +U 373 ; WX 861 ; N wcircumflex ; G 311 +U 374 ; WX 714 ; N Ycircumflex ; G 312 +U 375 ; WX 581 ; N ycircumflex ; G 313 +U 376 ; WX 714 ; N Ydieresis ; G 314 +U 377 ; WX 730 ; N Zacute ; G 315 +U 378 ; WX 568 ; N zacute ; G 316 +U 379 ; WX 730 ; N Zdotaccent ; G 317 +U 380 ; WX 568 ; N zdotaccent ; G 318 +U 381 ; WX 730 ; N Zcaron ; G 319 +U 382 ; WX 568 ; N zcaron ; G 320 +U 383 ; WX 430 ; N longs ; G 321 +U 384 ; WX 699 ; N uni0180 ; G 322 +U 385 ; WX 845 ; N uni0181 ; G 323 +U 386 ; WX 854 ; N uni0182 ; G 324 +U 387 ; WX 699 ; N uni0183 ; G 325 +U 388 ; WX 854 ; N uni0184 ; G 326 +U 389 ; WX 699 ; N uni0185 ; G 327 +U 390 ; WX 796 ; N uni0186 ; G 328 +U 391 ; WX 796 ; N uni0187 ; G 329 +U 392 ; WX 609 ; N uni0188 ; G 330 +U 393 ; WX 874 ; N uni0189 ; G 331 +U 394 ; WX 867 ; N uni018A ; G 332 +U 395 ; WX 854 ; N uni018B ; G 333 +U 396 ; WX 699 ; N uni018C ; G 334 +U 397 ; WX 667 ; N uni018D ; G 335 +U 398 ; WX 762 ; N uni018E ; G 336 +U 399 ; WX 871 ; N uni018F ; G 337 +U 400 ; WX 721 ; N uni0190 ; G 338 +U 401 ; WX 710 ; N uni0191 ; G 339 +U 402 ; WX 430 ; N florin ; G 340 +U 403 ; WX 854 ; N uni0193 ; G 341 +U 404 ; WX 771 ; N uni0194 ; G 342 +U 405 ; WX 1043 ; N uni0195 ; G 343 +U 406 ; WX 468 ; N uni0196 ; G 344 +U 407 ; WX 468 ; N uni0197 ; G 345 +U 408 ; WX 869 ; N uni0198 ; G 346 +U 409 ; WX 693 ; N uni0199 ; G 347 +U 410 ; WX 380 ; N uni019A ; G 348 +U 411 ; WX 701 ; N uni019B ; G 349 +U 412 ; WX 1058 ; N uni019C ; G 350 +U 413 ; WX 914 ; N uni019D ; G 351 +U 414 ; WX 727 ; N uni019E ; G 352 +U 415 ; WX 871 ; N uni019F ; G 353 +U 416 ; WX 871 ; N Ohorn ; G 354 +U 417 ; WX 667 ; N ohorn ; G 355 +U 418 ; WX 1200 ; N uni01A2 ; G 356 +U 419 ; WX 943 ; N uni01A3 ; G 357 +U 420 ; WX 752 ; N uni01A4 ; G 358 +U 421 ; WX 699 ; N uni01A5 ; G 359 +U 422 ; WX 831 ; N uni01A6 ; G 360 +U 423 ; WX 722 ; N uni01A7 ; G 361 +U 424 ; WX 563 ; N uni01A8 ; G 362 +U 425 ; WX 707 ; N uni01A9 ; G 363 +U 426 ; WX 331 ; N uni01AA ; G 364 +U 427 ; WX 462 ; N uni01AB ; G 365 +U 428 ; WX 744 ; N uni01AC ; G 366 +U 429 ; WX 462 ; N uni01AD ; G 367 +U 430 ; WX 744 ; N uni01AE ; G 368 +U 431 ; WX 872 ; N Uhorn ; G 369 +U 432 ; WX 727 ; N uhorn ; G 370 +U 433 ; WX 890 ; N uni01B1 ; G 371 +U 434 ; WX 890 ; N uni01B2 ; G 372 +U 435 ; WX 714 ; N uni01B3 ; G 373 +U 436 ; WX 699 ; N uni01B4 ; G 374 +U 437 ; WX 730 ; N uni01B5 ; G 375 +U 438 ; WX 568 ; N uni01B6 ; G 376 +U 439 ; WX 657 ; N uni01B7 ; G 377 +U 440 ; WX 657 ; N uni01B8 ; G 378 +U 441 ; WX 657 ; N uni01B9 ; G 379 +U 442 ; WX 657 ; N uni01BA ; G 380 +U 443 ; WX 696 ; N uni01BB ; G 381 +U 444 ; WX 754 ; N uni01BC ; G 382 +U 445 ; WX 568 ; N uni01BD ; G 383 +U 446 ; WX 536 ; N uni01BE ; G 384 +U 447 ; WX 716 ; N uni01BF ; G 385 +U 448 ; WX 295 ; N uni01C0 ; G 386 +U 449 ; WX 492 ; N uni01C1 ; G 387 +U 450 ; WX 459 ; N uni01C2 ; G 388 +U 451 ; WX 295 ; N uni01C3 ; G 389 +U 452 ; WX 1597 ; N uni01C4 ; G 390 +U 453 ; WX 1435 ; N uni01C5 ; G 391 +U 454 ; WX 1267 ; N uni01C6 ; G 392 +U 455 ; WX 1176 ; N uni01C7 ; G 393 +U 456 ; WX 1065 ; N uni01C8 ; G 394 +U 457 ; WX 742 ; N uni01C9 ; G 395 +U 458 ; WX 1387 ; N uni01CA ; G 396 +U 459 ; WX 1276 ; N uni01CB ; G 397 +U 460 ; WX 1089 ; N uni01CC ; G 398 +U 461 ; WX 776 ; N uni01CD ; G 399 +U 462 ; WX 648 ; N uni01CE ; G 400 +U 463 ; WX 468 ; N uni01CF ; G 401 +U 464 ; WX 380 ; N uni01D0 ; G 402 +U 465 ; WX 871 ; N uni01D1 ; G 403 +U 466 ; WX 667 ; N uni01D2 ; G 404 +U 467 ; WX 872 ; N uni01D3 ; G 405 +U 468 ; WX 727 ; N uni01D4 ; G 406 +U 469 ; WX 872 ; N uni01D5 ; G 407 +U 470 ; WX 727 ; N uni01D6 ; G 408 +U 471 ; WX 872 ; N uni01D7 ; G 409 +U 472 ; WX 727 ; N uni01D8 ; G 410 +U 473 ; WX 872 ; N uni01D9 ; G 411 +U 474 ; WX 727 ; N uni01DA ; G 412 +U 475 ; WX 872 ; N uni01DB ; G 413 +U 476 ; WX 727 ; N uni01DC ; G 414 +U 477 ; WX 636 ; N uni01DD ; G 415 +U 478 ; WX 776 ; N uni01DE ; G 416 +U 479 ; WX 648 ; N uni01DF ; G 417 +U 480 ; WX 776 ; N uni01E0 ; G 418 +U 481 ; WX 648 ; N uni01E1 ; G 419 +U 482 ; WX 1034 ; N uni01E2 ; G 420 +U 483 ; WX 975 ; N uni01E3 ; G 421 +U 484 ; WX 896 ; N uni01E4 ; G 422 +U 485 ; WX 699 ; N uni01E5 ; G 423 +U 486 ; WX 854 ; N Gcaron ; G 424 +U 487 ; WX 699 ; N gcaron ; G 425 +U 488 ; WX 869 ; N uni01E8 ; G 426 +U 489 ; WX 693 ; N uni01E9 ; G 427 +U 490 ; WX 871 ; N uni01EA ; G 428 +U 491 ; WX 667 ; N uni01EB ; G 429 +U 492 ; WX 871 ; N uni01EC ; G 430 +U 493 ; WX 667 ; N uni01ED ; G 431 +U 494 ; WX 657 ; N uni01EE ; G 432 +U 495 ; WX 568 ; N uni01EF ; G 433 +U 496 ; WX 362 ; N uni01F0 ; G 434 +U 497 ; WX 1597 ; N uni01F1 ; G 435 +U 498 ; WX 1435 ; N uni01F2 ; G 436 +U 499 ; WX 1267 ; N uni01F3 ; G 437 +U 500 ; WX 854 ; N uni01F4 ; G 438 +U 501 ; WX 699 ; N uni01F5 ; G 439 +U 502 ; WX 1221 ; N uni01F6 ; G 440 +U 503 ; WX 787 ; N uni01F7 ; G 441 +U 504 ; WX 914 ; N uni01F8 ; G 442 +U 505 ; WX 727 ; N uni01F9 ; G 443 +U 506 ; WX 776 ; N Aringacute ; G 444 +U 507 ; WX 648 ; N aringacute ; G 445 +U 508 ; WX 1034 ; N AEacute ; G 446 +U 509 ; WX 932 ; N aeacute ; G 447 +U 510 ; WX 871 ; N Oslashacute ; G 448 +U 511 ; WX 667 ; N oslashacute ; G 449 +U 512 ; WX 776 ; N uni0200 ; G 450 +U 513 ; WX 648 ; N uni0201 ; G 451 +U 514 ; WX 776 ; N uni0202 ; G 452 +U 515 ; WX 648 ; N uni0203 ; G 453 +U 516 ; WX 762 ; N uni0204 ; G 454 +U 517 ; WX 636 ; N uni0205 ; G 455 +U 518 ; WX 762 ; N uni0206 ; G 456 +U 519 ; WX 636 ; N uni0207 ; G 457 +U 520 ; WX 468 ; N uni0208 ; G 458 +U 521 ; WX 380 ; N uni0209 ; G 459 +U 522 ; WX 468 ; N uni020A ; G 460 +U 523 ; WX 380 ; N uni020B ; G 461 +U 524 ; WX 871 ; N uni020C ; G 462 +U 525 ; WX 667 ; N uni020D ; G 463 +U 526 ; WX 871 ; N uni020E ; G 464 +U 527 ; WX 667 ; N uni020F ; G 465 +U 528 ; WX 831 ; N uni0210 ; G 466 +U 529 ; WX 527 ; N uni0211 ; G 467 +U 530 ; WX 831 ; N uni0212 ; G 468 +U 531 ; WX 527 ; N uni0213 ; G 469 +U 532 ; WX 872 ; N uni0214 ; G 470 +U 533 ; WX 727 ; N uni0215 ; G 471 +U 534 ; WX 872 ; N uni0216 ; G 472 +U 535 ; WX 727 ; N uni0217 ; G 473 +U 536 ; WX 722 ; N Scommaaccent ; G 474 +U 537 ; WX 563 ; N scommaaccent ; G 475 +U 538 ; WX 744 ; N uni021A ; G 476 +U 539 ; WX 462 ; N uni021B ; G 477 +U 540 ; WX 690 ; N uni021C ; G 478 +U 541 ; WX 607 ; N uni021D ; G 479 +U 542 ; WX 945 ; N uni021E ; G 480 +U 543 ; WX 727 ; N uni021F ; G 481 +U 544 ; WX 872 ; N uni0220 ; G 482 +U 545 ; WX 791 ; N uni0221 ; G 483 +U 546 ; WX 703 ; N uni0222 ; G 484 +U 547 ; WX 616 ; N uni0223 ; G 485 +U 548 ; WX 730 ; N uni0224 ; G 486 +U 549 ; WX 568 ; N uni0225 ; G 487 +U 550 ; WX 776 ; N uni0226 ; G 488 +U 551 ; WX 648 ; N uni0227 ; G 489 +U 552 ; WX 762 ; N uni0228 ; G 490 +U 553 ; WX 636 ; N uni0229 ; G 491 +U 554 ; WX 871 ; N uni022A ; G 492 +U 555 ; WX 667 ; N uni022B ; G 493 +U 556 ; WX 871 ; N uni022C ; G 494 +U 557 ; WX 667 ; N uni022D ; G 495 +U 558 ; WX 871 ; N uni022E ; G 496 +U 559 ; WX 667 ; N uni022F ; G 497 +U 560 ; WX 871 ; N uni0230 ; G 498 +U 561 ; WX 667 ; N uni0231 ; G 499 +U 562 ; WX 714 ; N uni0232 ; G 500 +U 563 ; WX 581 ; N uni0233 ; G 501 +U 564 ; WX 573 ; N uni0234 ; G 502 +U 565 ; WX 922 ; N uni0235 ; G 503 +U 566 ; WX 564 ; N uni0236 ; G 504 +U 567 ; WX 362 ; N dotlessj ; G 505 +U 568 ; WX 1031 ; N uni0238 ; G 506 +U 569 ; WX 1031 ; N uni0239 ; G 507 +U 570 ; WX 776 ; N uni023A ; G 508 +U 571 ; WX 796 ; N uni023B ; G 509 +U 572 ; WX 609 ; N uni023C ; G 510 +U 573 ; WX 703 ; N uni023D ; G 511 +U 574 ; WX 744 ; N uni023E ; G 512 +U 575 ; WX 563 ; N uni023F ; G 513 +U 576 ; WX 568 ; N uni0240 ; G 514 +U 577 ; WX 660 ; N uni0241 ; G 515 +U 578 ; WX 547 ; N uni0242 ; G 516 +U 579 ; WX 845 ; N uni0243 ; G 517 +U 580 ; WX 872 ; N uni0244 ; G 518 +U 581 ; WX 776 ; N uni0245 ; G 519 +U 582 ; WX 762 ; N uni0246 ; G 520 +U 583 ; WX 636 ; N uni0247 ; G 521 +U 584 ; WX 473 ; N uni0248 ; G 522 +U 585 ; WX 387 ; N uni0249 ; G 523 +U 586 ; WX 848 ; N uni024A ; G 524 +U 587 ; WX 699 ; N uni024B ; G 525 +U 588 ; WX 831 ; N uni024C ; G 526 +U 589 ; WX 527 ; N uni024D ; G 527 +U 590 ; WX 714 ; N uni024E ; G 528 +U 591 ; WX 581 ; N uni024F ; G 529 +U 592 ; WX 648 ; N uni0250 ; G 530 +U 593 ; WX 770 ; N uni0251 ; G 531 +U 594 ; WX 770 ; N uni0252 ; G 532 +U 595 ; WX 699 ; N uni0253 ; G 533 +U 596 ; WX 609 ; N uni0254 ; G 534 +U 597 ; WX 609 ; N uni0255 ; G 535 +U 598 ; WX 699 ; N uni0256 ; G 536 +U 599 ; WX 730 ; N uni0257 ; G 537 +U 600 ; WX 636 ; N uni0258 ; G 538 +U 601 ; WX 636 ; N uni0259 ; G 539 +U 602 ; WX 907 ; N uni025A ; G 540 +U 603 ; WX 608 ; N uni025B ; G 541 +U 604 ; WX 562 ; N uni025C ; G 542 +U 605 ; WX 907 ; N uni025D ; G 543 +U 606 ; WX 714 ; N uni025E ; G 544 +U 607 ; WX 387 ; N uni025F ; G 545 +U 608 ; WX 699 ; N uni0260 ; G 546 +U 609 ; WX 699 ; N uni0261 ; G 547 +U 610 ; WX 638 ; N uni0262 ; G 548 +U 611 ; WX 601 ; N uni0263 ; G 549 +U 612 ; WX 627 ; N uni0264 ; G 550 +U 613 ; WX 727 ; N uni0265 ; G 551 +U 614 ; WX 727 ; N uni0266 ; G 552 +U 615 ; WX 727 ; N uni0267 ; G 553 +U 616 ; WX 380 ; N uni0268 ; G 554 +U 617 ; WX 380 ; N uni0269 ; G 555 +U 618 ; WX 380 ; N uni026A ; G 556 +U 619 ; WX 409 ; N uni026B ; G 557 +U 620 ; WX 514 ; N uni026C ; G 558 +U 621 ; WX 380 ; N uni026D ; G 559 +U 622 ; WX 795 ; N uni026E ; G 560 +U 623 ; WX 1058 ; N uni026F ; G 561 +U 624 ; WX 1058 ; N uni0270 ; G 562 +U 625 ; WX 1058 ; N uni0271 ; G 563 +U 626 ; WX 727 ; N uni0272 ; G 564 +U 627 ; WX 727 ; N uni0273 ; G 565 +U 628 ; WX 712 ; N uni0274 ; G 566 +U 629 ; WX 667 ; N uni0275 ; G 567 +U 630 ; WX 1061 ; N uni0276 ; G 568 +U 631 ; WX 944 ; N uni0277 ; G 569 +U 632 ; WX 797 ; N uni0278 ; G 570 +U 633 ; WX 571 ; N uni0279 ; G 571 +U 634 ; WX 571 ; N uni027A ; G 572 +U 635 ; WX 571 ; N uni027B ; G 573 +U 636 ; WX 527 ; N uni027C ; G 574 +U 637 ; WX 527 ; N uni027D ; G 575 +U 638 ; WX 452 ; N uni027E ; G 576 +U 639 ; WX 487 ; N uni027F ; G 577 +U 640 ; WX 694 ; N uni0280 ; G 578 +U 641 ; WX 694 ; N uni0281 ; G 579 +U 642 ; WX 563 ; N uni0282 ; G 580 +U 643 ; WX 331 ; N uni0283 ; G 581 +U 644 ; WX 430 ; N uni0284 ; G 582 +U 645 ; WX 540 ; N uni0285 ; G 583 +U 646 ; WX 331 ; N uni0286 ; G 584 +U 647 ; WX 492 ; N uni0287 ; G 585 +U 648 ; WX 462 ; N uni0288 ; G 586 +U 649 ; WX 727 ; N uni0289 ; G 587 +U 650 ; WX 679 ; N uni028A ; G 588 +U 651 ; WX 694 ; N uni028B ; G 589 +U 652 ; WX 581 ; N uni028C ; G 590 +U 653 ; WX 861 ; N uni028D ; G 591 +U 654 ; WX 635 ; N uni028E ; G 592 +U 655 ; WX 727 ; N uni028F ; G 593 +U 656 ; WX 568 ; N uni0290 ; G 594 +U 657 ; WX 568 ; N uni0291 ; G 595 +U 658 ; WX 568 ; N uni0292 ; G 596 +U 659 ; WX 568 ; N uni0293 ; G 597 +U 660 ; WX 551 ; N uni0294 ; G 598 +U 661 ; WX 551 ; N uni0295 ; G 599 +U 662 ; WX 551 ; N uni0296 ; G 600 +U 663 ; WX 545 ; N uni0297 ; G 601 +U 664 ; WX 871 ; N uni0298 ; G 602 +U 665 ; WX 695 ; N uni0299 ; G 603 +U 666 ; WX 714 ; N uni029A ; G 604 +U 667 ; WX 689 ; N uni029B ; G 605 +U 668 ; WX 732 ; N uni029C ; G 606 +U 669 ; WX 384 ; N uni029D ; G 607 +U 670 ; WX 740 ; N uni029E ; G 608 +U 671 ; WX 617 ; N uni029F ; G 609 +U 672 ; WX 699 ; N uni02A0 ; G 610 +U 673 ; WX 551 ; N uni02A1 ; G 611 +U 674 ; WX 551 ; N uni02A2 ; G 612 +U 675 ; WX 1117 ; N uni02A3 ; G 613 +U 676 ; WX 1179 ; N uni02A4 ; G 614 +U 677 ; WX 1117 ; N uni02A5 ; G 615 +U 678 ; WX 938 ; N uni02A6 ; G 616 +U 679 ; WX 715 ; N uni02A7 ; G 617 +U 680 ; WX 946 ; N uni02A8 ; G 618 +U 681 ; WX 1039 ; N uni02A9 ; G 619 +U 682 ; WX 870 ; N uni02AA ; G 620 +U 683 ; WX 795 ; N uni02AB ; G 621 +U 684 ; WX 662 ; N uni02AC ; G 622 +U 685 ; WX 443 ; N uni02AD ; G 623 +U 686 ; WX 613 ; N uni02AE ; G 624 +U 687 ; WX 717 ; N uni02AF ; G 625 +U 688 ; WX 521 ; N uni02B0 ; G 626 +U 689 ; WX 519 ; N uni02B1 ; G 627 +U 690 ; WX 313 ; N uni02B2 ; G 628 +U 691 ; WX 414 ; N uni02B3 ; G 629 +U 692 ; WX 414 ; N uni02B4 ; G 630 +U 693 ; WX 480 ; N uni02B5 ; G 631 +U 694 ; WX 527 ; N uni02B6 ; G 632 +U 695 ; WX 542 ; N uni02B7 ; G 633 +U 696 ; WX 366 ; N uni02B8 ; G 634 +U 697 ; WX 302 ; N uni02B9 ; G 635 +U 698 ; WX 521 ; N uni02BA ; G 636 +U 699 ; WX 348 ; N uni02BB ; G 637 +U 700 ; WX 348 ; N uni02BC ; G 638 +U 701 ; WX 348 ; N uni02BD ; G 639 +U 702 ; WX 366 ; N uni02BE ; G 640 +U 703 ; WX 366 ; N uni02BF ; G 641 +U 704 ; WX 313 ; N uni02C0 ; G 642 +U 705 ; WX 313 ; N uni02C1 ; G 643 +U 706 ; WX 500 ; N uni02C2 ; G 644 +U 707 ; WX 500 ; N uni02C3 ; G 645 +U 708 ; WX 500 ; N uni02C4 ; G 646 +U 709 ; WX 500 ; N uni02C5 ; G 647 +U 710 ; WX 500 ; N circumflex ; G 648 +U 711 ; WX 500 ; N caron ; G 649 +U 712 ; WX 282 ; N uni02C8 ; G 650 +U 713 ; WX 500 ; N uni02C9 ; G 651 +U 714 ; WX 500 ; N uni02CA ; G 652 +U 715 ; WX 500 ; N uni02CB ; G 653 +U 716 ; WX 282 ; N uni02CC ; G 654 +U 717 ; WX 500 ; N uni02CD ; G 655 +U 720 ; WX 369 ; N uni02D0 ; G 656 +U 721 ; WX 369 ; N uni02D1 ; G 657 +U 722 ; WX 366 ; N uni02D2 ; G 658 +U 723 ; WX 366 ; N uni02D3 ; G 659 +U 726 ; WX 392 ; N uni02D6 ; G 660 +U 727 ; WX 392 ; N uni02D7 ; G 661 +U 728 ; WX 500 ; N breve ; G 662 +U 729 ; WX 500 ; N dotaccent ; G 663 +U 730 ; WX 500 ; N ring ; G 664 +U 731 ; WX 500 ; N ogonek ; G 665 +U 732 ; WX 500 ; N tilde ; G 666 +U 733 ; WX 500 ; N hungarumlaut ; G 667 +U 734 ; WX 417 ; N uni02DE ; G 668 +U 736 ; WX 378 ; N uni02E0 ; G 669 +U 737 ; WX 292 ; N uni02E1 ; G 670 +U 738 ; WX 395 ; N uni02E2 ; G 671 +U 739 ; WX 375 ; N uni02E3 ; G 672 +U 740 ; WX 313 ; N uni02E4 ; G 673 +U 741 ; WX 500 ; N uni02E5 ; G 674 +U 742 ; WX 500 ; N uni02E6 ; G 675 +U 743 ; WX 500 ; N uni02E7 ; G 676 +U 744 ; WX 500 ; N uni02E8 ; G 677 +U 745 ; WX 500 ; N uni02E9 ; G 678 +U 748 ; WX 500 ; N uni02EC ; G 679 +U 750 ; WX 553 ; N uni02EE ; G 680 +U 751 ; WX 500 ; N uni02EF ; G 681 +U 752 ; WX 500 ; N uni02F0 ; G 682 +U 755 ; WX 500 ; N uni02F3 ; G 683 +U 759 ; WX 500 ; N uni02F7 ; G 684 +U 768 ; WX 0 ; N gravecomb ; G 685 +U 769 ; WX 0 ; N acutecomb ; G 686 +U 770 ; WX 0 ; N uni0302 ; G 687 +U 771 ; WX 0 ; N tildecomb ; G 688 +U 772 ; WX 0 ; N uni0304 ; G 689 +U 773 ; WX 0 ; N uni0305 ; G 690 +U 774 ; WX 0 ; N uni0306 ; G 691 +U 775 ; WX 0 ; N uni0307 ; G 692 +U 776 ; WX 0 ; N uni0308 ; G 693 +U 777 ; WX 0 ; N hookabovecomb ; G 694 +U 778 ; WX 0 ; N uni030A ; G 695 +U 779 ; WX 0 ; N uni030B ; G 696 +U 780 ; WX 0 ; N uni030C ; G 697 +U 781 ; WX 0 ; N uni030D ; G 698 +U 782 ; WX 0 ; N uni030E ; G 699 +U 783 ; WX 0 ; N uni030F ; G 700 +U 784 ; WX 0 ; N uni0310 ; G 701 +U 785 ; WX 0 ; N uni0311 ; G 702 +U 786 ; WX 0 ; N uni0312 ; G 703 +U 787 ; WX 0 ; N uni0313 ; G 704 +U 788 ; WX 0 ; N uni0314 ; G 705 +U 789 ; WX 0 ; N uni0315 ; G 706 +U 790 ; WX 0 ; N uni0316 ; G 707 +U 791 ; WX 0 ; N uni0317 ; G 708 +U 792 ; WX 0 ; N uni0318 ; G 709 +U 793 ; WX 0 ; N uni0319 ; G 710 +U 794 ; WX 0 ; N uni031A ; G 711 +U 795 ; WX 0 ; N uni031B ; G 712 +U 796 ; WX 0 ; N uni031C ; G 713 +U 797 ; WX 0 ; N uni031D ; G 714 +U 798 ; WX 0 ; N uni031E ; G 715 +U 799 ; WX 0 ; N uni031F ; G 716 +U 800 ; WX 0 ; N uni0320 ; G 717 +U 801 ; WX 0 ; N uni0321 ; G 718 +U 802 ; WX 0 ; N uni0322 ; G 719 +U 803 ; WX 0 ; N dotbelowcomb ; G 720 +U 804 ; WX 0 ; N uni0324 ; G 721 +U 805 ; WX 0 ; N uni0325 ; G 722 +U 806 ; WX 0 ; N uni0326 ; G 723 +U 807 ; WX 0 ; N uni0327 ; G 724 +U 808 ; WX 0 ; N uni0328 ; G 725 +U 809 ; WX 0 ; N uni0329 ; G 726 +U 810 ; WX 0 ; N uni032A ; G 727 +U 811 ; WX 0 ; N uni032B ; G 728 +U 812 ; WX 0 ; N uni032C ; G 729 +U 813 ; WX 0 ; N uni032D ; G 730 +U 814 ; WX 0 ; N uni032E ; G 731 +U 815 ; WX 0 ; N uni032F ; G 732 +U 816 ; WX 0 ; N uni0330 ; G 733 +U 817 ; WX 0 ; N uni0331 ; G 734 +U 818 ; WX 0 ; N uni0332 ; G 735 +U 819 ; WX 0 ; N uni0333 ; G 736 +U 820 ; WX 0 ; N uni0334 ; G 737 +U 821 ; WX 0 ; N uni0335 ; G 738 +U 822 ; WX 0 ; N uni0336 ; G 739 +U 823 ; WX 0 ; N uni0337 ; G 740 +U 824 ; WX 0 ; N uni0338 ; G 741 +U 825 ; WX 0 ; N uni0339 ; G 742 +U 826 ; WX 0 ; N uni033A ; G 743 +U 827 ; WX 0 ; N uni033B ; G 744 +U 828 ; WX 0 ; N uni033C ; G 745 +U 829 ; WX 0 ; N uni033D ; G 746 +U 830 ; WX 0 ; N uni033E ; G 747 +U 831 ; WX 0 ; N uni033F ; G 748 +U 835 ; WX 0 ; N uni0343 ; G 749 +U 847 ; WX 0 ; N uni034F ; G 750 +U 856 ; WX 0 ; N uni0358 ; G 751 +U 864 ; WX 0 ; N uni0360 ; G 752 +U 865 ; WX 0 ; N uni0361 ; G 753 +U 880 ; WX 779 ; N uni0370 ; G 754 +U 881 ; WX 576 ; N uni0371 ; G 755 +U 882 ; WX 803 ; N uni0372 ; G 756 +U 883 ; WX 777 ; N uni0373 ; G 757 +U 884 ; WX 302 ; N uni0374 ; G 758 +U 885 ; WX 302 ; N uni0375 ; G 759 +U 886 ; WX 963 ; N uni0376 ; G 760 +U 887 ; WX 737 ; N uni0377 ; G 761 +U 890 ; WX 500 ; N uni037A ; G 762 +U 891 ; WX 609 ; N uni037B ; G 763 +U 892 ; WX 609 ; N uni037C ; G 764 +U 893 ; WX 609 ; N uni037D ; G 765 +U 894 ; WX 369 ; N uni037E ; G 766 +U 895 ; WX 473 ; N uni037F ; G 767 +U 900 ; WX 500 ; N tonos ; G 768 +U 901 ; WX 500 ; N dieresistonos ; G 769 +U 902 ; WX 776 ; N Alphatonos ; G 770 +U 903 ; WX 348 ; N anoteleia ; G 771 +U 904 ; WX 947 ; N Epsilontonos ; G 772 +U 905 ; WX 1136 ; N Etatonos ; G 773 +U 906 ; WX 662 ; N Iotatonos ; G 774 +U 908 ; WX 887 ; N Omicrontonos ; G 775 +U 910 ; WX 953 ; N Upsilontonos ; G 776 +U 911 ; WX 911 ; N Omegatonos ; G 777 +U 912 ; WX 484 ; N iotadieresistonos ; G 778 +U 913 ; WX 776 ; N Alpha ; G 779 +U 914 ; WX 845 ; N Beta ; G 780 +U 915 ; WX 710 ; N Gamma ; G 781 +U 916 ; WX 776 ; N uni0394 ; G 782 +U 917 ; WX 762 ; N Epsilon ; G 783 +U 918 ; WX 730 ; N Zeta ; G 784 +U 919 ; WX 945 ; N Eta ; G 785 +U 920 ; WX 871 ; N Theta ; G 786 +U 921 ; WX 468 ; N Iota ; G 787 +U 922 ; WX 869 ; N Kappa ; G 788 +U 923 ; WX 776 ; N Lambda ; G 789 +U 924 ; WX 1107 ; N Mu ; G 790 +U 925 ; WX 914 ; N Nu ; G 791 +U 926 ; WX 704 ; N Xi ; G 792 +U 927 ; WX 871 ; N Omicron ; G 793 +U 928 ; WX 945 ; N Pi ; G 794 +U 929 ; WX 752 ; N Rho ; G 795 +U 931 ; WX 707 ; N Sigma ; G 796 +U 932 ; WX 744 ; N Tau ; G 797 +U 933 ; WX 714 ; N Upsilon ; G 798 +U 934 ; WX 871 ; N Phi ; G 799 +U 935 ; WX 776 ; N Chi ; G 800 +U 936 ; WX 913 ; N Psi ; G 801 +U 937 ; WX 890 ; N Omega ; G 802 +U 938 ; WX 468 ; N Iotadieresis ; G 803 +U 939 ; WX 714 ; N Upsilondieresis ; G 804 +U 940 ; WX 770 ; N alphatonos ; G 805 +U 941 ; WX 608 ; N epsilontonos ; G 806 +U 942 ; WX 727 ; N etatonos ; G 807 +U 943 ; WX 484 ; N iotatonos ; G 808 +U 944 ; WX 694 ; N upsilondieresistonos ; G 809 +U 945 ; WX 770 ; N alpha ; G 810 +U 946 ; WX 664 ; N beta ; G 811 +U 947 ; WX 660 ; N gamma ; G 812 +U 948 ; WX 667 ; N delta ; G 813 +U 949 ; WX 608 ; N epsilon ; G 814 +U 950 ; WX 592 ; N zeta ; G 815 +U 951 ; WX 727 ; N eta ; G 816 +U 952 ; WX 667 ; N theta ; G 817 +U 953 ; WX 484 ; N iota ; G 818 +U 954 ; WX 750 ; N kappa ; G 819 +U 955 ; WX 701 ; N lambda ; G 820 +U 956 ; WX 732 ; N uni03BC ; G 821 +U 957 ; WX 694 ; N nu ; G 822 +U 958 ; WX 592 ; N xi ; G 823 +U 959 ; WX 667 ; N omicron ; G 824 +U 960 ; WX 732 ; N pi ; G 825 +U 961 ; WX 665 ; N rho ; G 826 +U 962 ; WX 609 ; N sigma1 ; G 827 +U 963 ; WX 737 ; N sigma ; G 828 +U 964 ; WX 673 ; N tau ; G 829 +U 965 ; WX 694 ; N upsilon ; G 830 +U 966 ; WX 905 ; N phi ; G 831 +U 967 ; WX 658 ; N chi ; G 832 +U 968 ; WX 941 ; N psi ; G 833 +U 969 ; WX 952 ; N omega ; G 834 +U 970 ; WX 484 ; N iotadieresis ; G 835 +U 971 ; WX 694 ; N upsilondieresis ; G 836 +U 972 ; WX 667 ; N omicrontonos ; G 837 +U 973 ; WX 694 ; N upsilontonos ; G 838 +U 974 ; WX 952 ; N omegatonos ; G 839 +U 975 ; WX 869 ; N uni03CF ; G 840 +U 976 ; WX 667 ; N uni03D0 ; G 841 +U 977 ; WX 849 ; N theta1 ; G 842 +U 978 ; WX 764 ; N Upsilon1 ; G 843 +U 979 ; WX 969 ; N uni03D3 ; G 844 +U 980 ; WX 764 ; N uni03D4 ; G 845 +U 981 ; WX 941 ; N phi1 ; G 846 +U 982 ; WX 952 ; N omega1 ; G 847 +U 983 ; WX 655 ; N uni03D7 ; G 848 +U 984 ; WX 871 ; N uni03D8 ; G 849 +U 985 ; WX 667 ; N uni03D9 ; G 850 +U 986 ; WX 796 ; N uni03DA ; G 851 +U 987 ; WX 609 ; N uni03DB ; G 852 +U 988 ; WX 710 ; N uni03DC ; G 853 +U 989 ; WX 527 ; N uni03DD ; G 854 +U 990 ; WX 590 ; N uni03DE ; G 855 +U 991 ; WX 660 ; N uni03DF ; G 856 +U 992 ; WX 796 ; N uni03E0 ; G 857 +U 993 ; WX 667 ; N uni03E1 ; G 858 +U 1008 ; WX 655 ; N uni03F0 ; G 859 +U 1009 ; WX 665 ; N uni03F1 ; G 860 +U 1010 ; WX 609 ; N uni03F2 ; G 861 +U 1011 ; WX 362 ; N uni03F3 ; G 862 +U 1012 ; WX 871 ; N uni03F4 ; G 863 +U 1013 ; WX 609 ; N uni03F5 ; G 864 +U 1014 ; WX 609 ; N uni03F6 ; G 865 +U 1015 ; WX 757 ; N uni03F7 ; G 866 +U 1016 ; WX 699 ; N uni03F8 ; G 867 +U 1017 ; WX 796 ; N uni03F9 ; G 868 +U 1018 ; WX 1107 ; N uni03FA ; G 869 +U 1019 ; WX 860 ; N uni03FB ; G 870 +U 1020 ; WX 692 ; N uni03FC ; G 871 +U 1021 ; WX 796 ; N uni03FD ; G 872 +U 1022 ; WX 796 ; N uni03FE ; G 873 +U 1023 ; WX 796 ; N uni03FF ; G 874 +U 1024 ; WX 762 ; N uni0400 ; G 875 +U 1025 ; WX 762 ; N uni0401 ; G 876 +U 1026 ; WX 901 ; N uni0402 ; G 877 +U 1027 ; WX 690 ; N uni0403 ; G 878 +U 1028 ; WX 795 ; N uni0404 ; G 879 +U 1029 ; WX 722 ; N uni0405 ; G 880 +U 1030 ; WX 468 ; N uni0406 ; G 881 +U 1031 ; WX 468 ; N uni0407 ; G 882 +U 1032 ; WX 473 ; N uni0408 ; G 883 +U 1033 ; WX 1202 ; N uni0409 ; G 884 +U 1034 ; WX 1262 ; N uni040A ; G 885 +U 1035 ; WX 963 ; N uni040B ; G 886 +U 1036 ; WX 910 ; N uni040C ; G 887 +U 1037 ; WX 945 ; N uni040D ; G 888 +U 1038 ; WX 812 ; N uni040E ; G 889 +U 1039 ; WX 945 ; N uni040F ; G 890 +U 1040 ; WX 814 ; N uni0410 ; G 891 +U 1041 ; WX 854 ; N uni0411 ; G 892 +U 1042 ; WX 845 ; N uni0412 ; G 893 +U 1043 ; WX 690 ; N uni0413 ; G 894 +U 1044 ; WX 889 ; N uni0414 ; G 895 +U 1045 ; WX 762 ; N uni0415 ; G 896 +U 1046 ; WX 1312 ; N uni0416 ; G 897 +U 1047 ; WX 721 ; N uni0417 ; G 898 +U 1048 ; WX 945 ; N uni0418 ; G 899 +U 1049 ; WX 945 ; N uni0419 ; G 900 +U 1050 ; WX 910 ; N uni041A ; G 901 +U 1051 ; WX 884 ; N uni041B ; G 902 +U 1052 ; WX 1107 ; N uni041C ; G 903 +U 1053 ; WX 945 ; N uni041D ; G 904 +U 1054 ; WX 871 ; N uni041E ; G 905 +U 1055 ; WX 945 ; N uni041F ; G 906 +U 1056 ; WX 752 ; N uni0420 ; G 907 +U 1057 ; WX 796 ; N uni0421 ; G 908 +U 1058 ; WX 744 ; N uni0422 ; G 909 +U 1059 ; WX 812 ; N uni0423 ; G 910 +U 1060 ; WX 949 ; N uni0424 ; G 911 +U 1061 ; WX 776 ; N uni0425 ; G 912 +U 1062 ; WX 966 ; N uni0426 ; G 913 +U 1063 ; WX 913 ; N uni0427 ; G 914 +U 1064 ; WX 1268 ; N uni0428 ; G 915 +U 1065 ; WX 1293 ; N uni0429 ; G 916 +U 1066 ; WX 957 ; N uni042A ; G 917 +U 1067 ; WX 1202 ; N uni042B ; G 918 +U 1068 ; WX 825 ; N uni042C ; G 919 +U 1069 ; WX 795 ; N uni042D ; G 920 +U 1070 ; WX 1287 ; N uni042E ; G 921 +U 1071 ; WX 882 ; N uni042F ; G 922 +U 1072 ; WX 648 ; N uni0430 ; G 923 +U 1073 ; WX 722 ; N uni0431 ; G 924 +U 1074 ; WX 657 ; N uni0432 ; G 925 +U 1075 ; WX 563 ; N uni0433 ; G 926 +U 1076 ; WX 695 ; N uni0434 ; G 927 +U 1077 ; WX 636 ; N uni0435 ; G 928 +U 1078 ; WX 1306 ; N uni0436 ; G 929 +U 1079 ; WX 638 ; N uni0437 ; G 930 +U 1080 ; WX 727 ; N uni0438 ; G 931 +U 1081 ; WX 727 ; N uni0439 ; G 932 +U 1082 ; WX 677 ; N uni043A ; G 933 +U 1083 ; WX 732 ; N uni043B ; G 934 +U 1084 ; WX 951 ; N uni043C ; G 935 +U 1085 ; WX 729 ; N uni043D ; G 936 +U 1086 ; WX 667 ; N uni043E ; G 937 +U 1087 ; WX 727 ; N uni043F ; G 938 +U 1088 ; WX 699 ; N uni0440 ; G 939 +U 1089 ; WX 609 ; N uni0441 ; G 940 +U 1090 ; WX 1058 ; N uni0442 ; G 941 +U 1091 ; WX 598 ; N uni0443 ; G 942 +U 1092 ; WX 902 ; N uni0444 ; G 943 +U 1093 ; WX 596 ; N uni0445 ; G 944 +U 1094 ; WX 803 ; N uni0446 ; G 945 +U 1095 ; WX 715 ; N uni0447 ; G 946 +U 1096 ; WX 1058 ; N uni0448 ; G 947 +U 1097 ; WX 1134 ; N uni0449 ; G 948 +U 1098 ; WX 727 ; N uni044A ; G 949 +U 1099 ; WX 1018 ; N uni044B ; G 950 +U 1100 ; WX 660 ; N uni044C ; G 951 +U 1101 ; WX 645 ; N uni044D ; G 952 +U 1102 ; WX 1001 ; N uni044E ; G 953 +U 1103 ; WX 796 ; N uni044F ; G 954 +U 1104 ; WX 636 ; N uni0450 ; G 955 +U 1105 ; WX 636 ; N uni0451 ; G 956 +U 1106 ; WX 719 ; N uni0452 ; G 957 +U 1107 ; WX 563 ; N uni0453 ; G 958 +U 1108 ; WX 609 ; N uni0454 ; G 959 +U 1109 ; WX 563 ; N uni0455 ; G 960 +U 1110 ; WX 380 ; N uni0456 ; G 961 +U 1111 ; WX 380 ; N uni0457 ; G 962 +U 1112 ; WX 362 ; N uni0458 ; G 963 +U 1113 ; WX 1014 ; N uni0459 ; G 964 +U 1114 ; WX 1011 ; N uni045A ; G 965 +U 1115 ; WX 727 ; N uni045B ; G 966 +U 1116 ; WX 677 ; N uni045C ; G 967 +U 1117 ; WX 727 ; N uni045D ; G 968 +U 1118 ; WX 598 ; N uni045E ; G 969 +U 1119 ; WX 727 ; N uni045F ; G 970 +U 1122 ; WX 880 ; N uni0462 ; G 971 +U 1123 ; WX 1050 ; N uni0463 ; G 972 +U 1124 ; WX 1195 ; N uni0464 ; G 973 +U 1125 ; WX 963 ; N uni0465 ; G 974 +U 1130 ; WX 1312 ; N uni046A ; G 975 +U 1131 ; WX 1010 ; N uni046B ; G 976 +U 1132 ; WX 1630 ; N uni046C ; G 977 +U 1133 ; WX 1247 ; N uni046D ; G 978 +U 1136 ; WX 1096 ; N uni0470 ; G 979 +U 1137 ; WX 1105 ; N uni0471 ; G 980 +U 1138 ; WX 871 ; N uni0472 ; G 981 +U 1139 ; WX 652 ; N uni0473 ; G 982 +U 1140 ; WX 916 ; N uni0474 ; G 983 +U 1141 ; WX 749 ; N uni0475 ; G 984 +U 1142 ; WX 916 ; N uni0476 ; G 985 +U 1143 ; WX 749 ; N uni0477 ; G 986 +U 1164 ; WX 846 ; N uni048C ; G 987 +U 1165 ; WX 673 ; N uni048D ; G 988 +U 1168 ; WX 700 ; N uni0490 ; G 989 +U 1169 ; WX 618 ; N uni0491 ; G 990 +U 1170 ; WX 690 ; N uni0492 ; G 991 +U 1171 ; WX 563 ; N uni0493 ; G 992 +U 1172 ; WX 854 ; N uni0494 ; G 993 +U 1173 ; WX 705 ; N uni0495 ; G 994 +U 1174 ; WX 1312 ; N uni0496 ; G 995 +U 1175 ; WX 1306 ; N uni0497 ; G 996 +U 1176 ; WX 721 ; N uni0498 ; G 997 +U 1177 ; WX 638 ; N uni0499 ; G 998 +U 1178 ; WX 902 ; N uni049A ; G 999 +U 1179 ; WX 703 ; N uni049B ; G 1000 +U 1182 ; WX 910 ; N uni049E ; G 1001 +U 1183 ; WX 677 ; N uni049F ; G 1002 +U 1184 ; WX 1041 ; N uni04A0 ; G 1003 +U 1185 ; WX 760 ; N uni04A1 ; G 1004 +U 1186 ; WX 952 ; N uni04A2 ; G 1005 +U 1187 ; WX 805 ; N uni04A3 ; G 1006 +U 1188 ; WX 1167 ; N uni04A4 ; G 1007 +U 1189 ; WX 955 ; N uni04A5 ; G 1008 +U 1190 ; WX 1324 ; N uni04A6 ; G 1009 +U 1191 ; WX 1013 ; N uni04A7 ; G 1010 +U 1194 ; WX 796 ; N uni04AA ; G 1011 +U 1195 ; WX 609 ; N uni04AB ; G 1012 +U 1196 ; WX 744 ; N uni04AC ; G 1013 +U 1197 ; WX 1142 ; N uni04AD ; G 1014 +U 1198 ; WX 714 ; N uni04AE ; G 1015 +U 1199 ; WX 572 ; N uni04AF ; G 1016 +U 1200 ; WX 713 ; N uni04B0 ; G 1017 +U 1201 ; WX 572 ; N uni04B1 ; G 1018 +U 1202 ; WX 789 ; N uni04B2 ; G 1019 +U 1203 ; WX 596 ; N uni04B3 ; G 1020 +U 1204 ; WX 1010 ; N uni04B4 ; G 1021 +U 1205 ; WX 833 ; N uni04B5 ; G 1022 +U 1206 ; WX 913 ; N uni04B6 ; G 1023 +U 1207 ; WX 792 ; N uni04B7 ; G 1024 +U 1210 ; WX 910 ; N uni04BA ; G 1025 +U 1211 ; WX 727 ; N uni04BB ; G 1026 +U 1216 ; WX 468 ; N uni04C0 ; G 1027 +U 1217 ; WX 1312 ; N uni04C1 ; G 1028 +U 1218 ; WX 1306 ; N uni04C2 ; G 1029 +U 1219 ; WX 869 ; N uni04C3 ; G 1030 +U 1220 ; WX 693 ; N uni04C4 ; G 1031 +U 1223 ; WX 945 ; N uni04C7 ; G 1032 +U 1224 ; WX 732 ; N uni04C8 ; G 1033 +U 1227 ; WX 984 ; N uni04CB ; G 1034 +U 1228 ; WX 732 ; N uni04CC ; G 1035 +U 1231 ; WX 380 ; N uni04CF ; G 1036 +U 1232 ; WX 814 ; N uni04D0 ; G 1037 +U 1233 ; WX 648 ; N uni04D1 ; G 1038 +U 1234 ; WX 814 ; N uni04D2 ; G 1039 +U 1235 ; WX 648 ; N uni04D3 ; G 1040 +U 1236 ; WX 1034 ; N uni04D4 ; G 1041 +U 1237 ; WX 975 ; N uni04D5 ; G 1042 +U 1238 ; WX 762 ; N uni04D6 ; G 1043 +U 1239 ; WX 636 ; N uni04D7 ; G 1044 +U 1240 ; WX 871 ; N uni04D8 ; G 1045 +U 1241 ; WX 636 ; N uni04D9 ; G 1046 +U 1242 ; WX 871 ; N uni04DA ; G 1047 +U 1243 ; WX 636 ; N uni04DB ; G 1048 +U 1244 ; WX 1312 ; N uni04DC ; G 1049 +U 1245 ; WX 1306 ; N uni04DD ; G 1050 +U 1246 ; WX 721 ; N uni04DE ; G 1051 +U 1247 ; WX 638 ; N uni04DF ; G 1052 +U 1248 ; WX 657 ; N uni04E0 ; G 1053 +U 1249 ; WX 568 ; N uni04E1 ; G 1054 +U 1250 ; WX 945 ; N uni04E2 ; G 1055 +U 1251 ; WX 727 ; N uni04E3 ; G 1056 +U 1252 ; WX 945 ; N uni04E4 ; G 1057 +U 1253 ; WX 727 ; N uni04E5 ; G 1058 +U 1254 ; WX 871 ; N uni04E6 ; G 1059 +U 1255 ; WX 667 ; N uni04E7 ; G 1060 +U 1256 ; WX 871 ; N uni04E8 ; G 1061 +U 1257 ; WX 667 ; N uni04E9 ; G 1062 +U 1258 ; WX 871 ; N uni04EA ; G 1063 +U 1259 ; WX 667 ; N uni04EB ; G 1064 +U 1260 ; WX 795 ; N uni04EC ; G 1065 +U 1261 ; WX 645 ; N uni04ED ; G 1066 +U 1262 ; WX 812 ; N uni04EE ; G 1067 +U 1263 ; WX 598 ; N uni04EF ; G 1068 +U 1264 ; WX 812 ; N uni04F0 ; G 1069 +U 1265 ; WX 598 ; N uni04F1 ; G 1070 +U 1266 ; WX 812 ; N uni04F2 ; G 1071 +U 1267 ; WX 598 ; N uni04F3 ; G 1072 +U 1268 ; WX 913 ; N uni04F4 ; G 1073 +U 1269 ; WX 715 ; N uni04F5 ; G 1074 +U 1270 ; WX 690 ; N uni04F6 ; G 1075 +U 1271 ; WX 563 ; N uni04F7 ; G 1076 +U 1272 ; WX 1202 ; N uni04F8 ; G 1077 +U 1273 ; WX 1018 ; N uni04F9 ; G 1078 +U 1296 ; WX 721 ; N uni0510 ; G 1079 +U 1297 ; WX 638 ; N uni0511 ; G 1080 +U 1298 ; WX 884 ; N uni0512 ; G 1081 +U 1299 ; WX 732 ; N uni0513 ; G 1082 +U 1300 ; WX 1248 ; N uni0514 ; G 1083 +U 1301 ; WX 1005 ; N uni0515 ; G 1084 +U 1306 ; WX 820 ; N uni051A ; G 1085 +U 1307 ; WX 640 ; N uni051B ; G 1086 +U 1308 ; WX 1028 ; N uni051C ; G 1087 +U 1309 ; WX 856 ; N uni051D ; G 1088 +U 1329 ; WX 942 ; N uni0531 ; G 1089 +U 1330 ; WX 832 ; N uni0532 ; G 1090 +U 1331 ; WX 894 ; N uni0533 ; G 1091 +U 1332 ; WX 909 ; N uni0534 ; G 1092 +U 1333 ; WX 822 ; N uni0535 ; G 1093 +U 1334 ; WX 821 ; N uni0536 ; G 1094 +U 1335 ; WX 747 ; N uni0537 ; G 1095 +U 1336 ; WX 832 ; N uni0538 ; G 1096 +U 1337 ; WX 1125 ; N uni0539 ; G 1097 +U 1338 ; WX 894 ; N uni053A ; G 1098 +U 1339 ; WX 803 ; N uni053B ; G 1099 +U 1340 ; WX 722 ; N uni053C ; G 1100 +U 1341 ; WX 1188 ; N uni053D ; G 1101 +U 1342 ; WX 887 ; N uni053E ; G 1102 +U 1343 ; WX 842 ; N uni053F ; G 1103 +U 1344 ; WX 737 ; N uni0540 ; G 1104 +U 1345 ; WX 863 ; N uni0541 ; G 1105 +U 1346 ; WX 918 ; N uni0542 ; G 1106 +U 1347 ; WX 851 ; N uni0543 ; G 1107 +U 1348 ; WX 977 ; N uni0544 ; G 1108 +U 1349 ; WX 833 ; N uni0545 ; G 1109 +U 1350 ; WX 914 ; N uni0546 ; G 1110 +U 1351 ; WX 843 ; N uni0547 ; G 1111 +U 1352 ; WX 871 ; N uni0548 ; G 1112 +U 1353 ; WX 818 ; N uni0549 ; G 1113 +U 1354 ; WX 1034 ; N uni054A ; G 1114 +U 1355 ; WX 846 ; N uni054B ; G 1115 +U 1356 ; WX 964 ; N uni054C ; G 1116 +U 1357 ; WX 871 ; N uni054D ; G 1117 +U 1358 ; WX 914 ; N uni054E ; G 1118 +U 1359 ; WX 808 ; N uni054F ; G 1119 +U 1360 ; WX 808 ; N uni0550 ; G 1120 +U 1361 ; WX 836 ; N uni0551 ; G 1121 +U 1362 ; WX 710 ; N uni0552 ; G 1122 +U 1363 ; WX 955 ; N uni0553 ; G 1123 +U 1364 ; WX 891 ; N uni0554 ; G 1124 +U 1365 ; WX 871 ; N uni0555 ; G 1125 +U 1366 ; WX 963 ; N uni0556 ; G 1126 +U 1369 ; WX 307 ; N uni0559 ; G 1127 +U 1370 ; WX 264 ; N uni055A ; G 1128 +U 1371 ; WX 293 ; N uni055B ; G 1129 +U 1372 ; WX 391 ; N uni055C ; G 1130 +U 1373 ; WX 323 ; N uni055D ; G 1131 +U 1374 ; WX 439 ; N uni055E ; G 1132 +U 1375 ; WX 500 ; N uni055F ; G 1133 +U 1377 ; WX 1055 ; N uni0561 ; G 1134 +U 1378 ; WX 695 ; N uni0562 ; G 1135 +U 1379 ; WX 776 ; N uni0563 ; G 1136 +U 1380 ; WX 801 ; N uni0564 ; G 1137 +U 1381 ; WX 729 ; N uni0565 ; G 1138 +U 1382 ; WX 742 ; N uni0566 ; G 1139 +U 1383 ; WX 599 ; N uni0567 ; G 1140 +U 1384 ; WX 733 ; N uni0568 ; G 1141 +U 1385 ; WX 909 ; N uni0569 ; G 1142 +U 1386 ; WX 768 ; N uni056A ; G 1143 +U 1387 ; WX 724 ; N uni056B ; G 1144 +U 1388 ; WX 398 ; N uni056C ; G 1145 +U 1389 ; WX 1087 ; N uni056D ; G 1146 +U 1390 ; WX 695 ; N uni056E ; G 1147 +U 1391 ; WX 719 ; N uni056F ; G 1148 +U 1392 ; WX 737 ; N uni0570 ; G 1149 +U 1393 ; WX 684 ; N uni0571 ; G 1150 +U 1394 ; WX 738 ; N uni0572 ; G 1151 +U 1395 ; WX 703 ; N uni0573 ; G 1152 +U 1396 ; WX 724 ; N uni0574 ; G 1153 +U 1397 ; WX 359 ; N uni0575 ; G 1154 +U 1398 ; WX 719 ; N uni0576 ; G 1155 +U 1399 ; WX 496 ; N uni0577 ; G 1156 +U 1400 ; WX 738 ; N uni0578 ; G 1157 +U 1401 ; WX 428 ; N uni0579 ; G 1158 +U 1402 ; WX 1059 ; N uni057A ; G 1159 +U 1403 ; WX 668 ; N uni057B ; G 1160 +U 1404 ; WX 744 ; N uni057C ; G 1161 +U 1405 ; WX 724 ; N uni057D ; G 1162 +U 1406 ; WX 724 ; N uni057E ; G 1163 +U 1407 ; WX 1040 ; N uni057F ; G 1164 +U 1408 ; WX 724 ; N uni0580 ; G 1165 +U 1409 ; WX 713 ; N uni0581 ; G 1166 +U 1410 ; WX 493 ; N uni0582 ; G 1167 +U 1411 ; WX 1040 ; N uni0583 ; G 1168 +U 1412 ; WX 734 ; N uni0584 ; G 1169 +U 1413 ; WX 693 ; N uni0585 ; G 1170 +U 1414 ; WX 956 ; N uni0586 ; G 1171 +U 1415 ; WX 833 ; N uni0587 ; G 1172 +U 1417 ; WX 340 ; N uni0589 ; G 1173 +U 1418 ; WX 388 ; N uni058A ; G 1174 +U 3647 ; WX 696 ; N uni0E3F ; G 1175 +U 4256 ; WX 765 ; N uni10A0 ; G 1176 +U 4257 ; WX 945 ; N uni10A1 ; G 1177 +U 4258 ; WX 876 ; N uni10A2 ; G 1178 +U 4259 ; WX 884 ; N uni10A3 ; G 1179 +U 4260 ; WX 791 ; N uni10A4 ; G 1180 +U 4261 ; WX 1087 ; N uni10A5 ; G 1181 +U 4262 ; WX 1024 ; N uni10A6 ; G 1182 +U 4263 ; WX 1223 ; N uni10A7 ; G 1183 +U 4264 ; WX 653 ; N uni10A8 ; G 1184 +U 4265 ; WX 828 ; N uni10A9 ; G 1185 +U 4266 ; WX 1061 ; N uni10AA ; G 1186 +U 4267 ; WX 1061 ; N uni10AB ; G 1187 +U 4268 ; WX 806 ; N uni10AC ; G 1188 +U 4269 ; WX 1145 ; N uni10AD ; G 1189 +U 4270 ; WX 979 ; N uni10AE ; G 1190 +U 4271 ; WX 912 ; N uni10AF ; G 1191 +U 4272 ; WX 1119 ; N uni10B0 ; G 1192 +U 4273 ; WX 802 ; N uni10B1 ; G 1193 +U 4274 ; WX 766 ; N uni10B2 ; G 1194 +U 4275 ; WX 1085 ; N uni10B3 ; G 1195 +U 4276 ; WX 986 ; N uni10B4 ; G 1196 +U 4277 ; WX 1076 ; N uni10B5 ; G 1197 +U 4278 ; WX 820 ; N uni10B6 ; G 1198 +U 4279 ; WX 843 ; N uni10B7 ; G 1199 +U 4280 ; WX 831 ; N uni10B8 ; G 1200 +U 4281 ; WX 843 ; N uni10B9 ; G 1201 +U 4282 ; WX 918 ; N uni10BA ; G 1202 +U 4283 ; WX 1086 ; N uni10BB ; G 1203 +U 4284 ; WX 779 ; N uni10BC ; G 1204 +U 4285 ; WX 832 ; N uni10BD ; G 1205 +U 4286 ; WX 822 ; N uni10BE ; G 1206 +U 4287 ; WX 1121 ; N uni10BF ; G 1207 +U 4288 ; WX 1132 ; N uni10C0 ; G 1208 +U 4289 ; WX 812 ; N uni10C1 ; G 1209 +U 4290 ; WX 902 ; N uni10C2 ; G 1210 +U 4291 ; WX 812 ; N uni10C3 ; G 1211 +U 4292 ; WX 890 ; N uni10C4 ; G 1212 +U 4293 ; WX 1073 ; N uni10C5 ; G 1213 +U 4304 ; WX 594 ; N uni10D0 ; G 1214 +U 4305 ; WX 625 ; N uni10D1 ; G 1215 +U 4306 ; WX 643 ; N uni10D2 ; G 1216 +U 4307 ; WX 887 ; N uni10D3 ; G 1217 +U 4308 ; WX 615 ; N uni10D4 ; G 1218 +U 4309 ; WX 611 ; N uni10D5 ; G 1219 +U 4310 ; WX 666 ; N uni10D6 ; G 1220 +U 4311 ; WX 915 ; N uni10D7 ; G 1221 +U 4312 ; WX 613 ; N uni10D8 ; G 1222 +U 4313 ; WX 600 ; N uni10D9 ; G 1223 +U 4314 ; WX 1120 ; N uni10DA ; G 1224 +U 4315 ; WX 654 ; N uni10DB ; G 1225 +U 4316 ; WX 640 ; N uni10DC ; G 1226 +U 4317 ; WX 879 ; N uni10DD ; G 1227 +U 4318 ; WX 624 ; N uni10DE ; G 1228 +U 4319 ; WX 634 ; N uni10DF ; G 1229 +U 4320 ; WX 877 ; N uni10E0 ; G 1230 +U 4321 ; WX 657 ; N uni10E1 ; G 1231 +U 4322 ; WX 802 ; N uni10E2 ; G 1232 +U 4323 ; WX 751 ; N uni10E3 ; G 1233 +U 4324 ; WX 869 ; N uni10E4 ; G 1234 +U 4325 ; WX 639 ; N uni10E5 ; G 1235 +U 4326 ; WX 912 ; N uni10E6 ; G 1236 +U 4327 ; WX 622 ; N uni10E7 ; G 1237 +U 4328 ; WX 647 ; N uni10E8 ; G 1238 +U 4329 ; WX 640 ; N uni10E9 ; G 1239 +U 4330 ; WX 729 ; N uni10EA ; G 1240 +U 4331 ; WX 641 ; N uni10EB ; G 1241 +U 4332 ; WX 639 ; N uni10EC ; G 1242 +U 4333 ; WX 629 ; N uni10ED ; G 1243 +U 4334 ; WX 674 ; N uni10EE ; G 1244 +U 4335 ; WX 737 ; N uni10EF ; G 1245 +U 4336 ; WX 625 ; N uni10F0 ; G 1246 +U 4337 ; WX 657 ; N uni10F1 ; G 1247 +U 4338 ; WX 625 ; N uni10F2 ; G 1248 +U 4339 ; WX 625 ; N uni10F3 ; G 1249 +U 4340 ; WX 624 ; N uni10F4 ; G 1250 +U 4341 ; WX 670 ; N uni10F5 ; G 1251 +U 4342 ; WX 940 ; N uni10F6 ; G 1252 +U 4343 ; WX 680 ; N uni10F7 ; G 1253 +U 4344 ; WX 636 ; N uni10F8 ; G 1254 +U 4345 ; WX 672 ; N uni10F9 ; G 1255 +U 4346 ; WX 625 ; N uni10FA ; G 1256 +U 4347 ; WX 446 ; N uni10FB ; G 1257 +U 4348 ; WX 363 ; N uni10FC ; G 1258 +U 7424 ; WX 641 ; N uni1D00 ; G 1259 +U 7425 ; WX 892 ; N uni1D01 ; G 1260 +U 7426 ; WX 932 ; N uni1D02 ; G 1261 +U 7427 ; WX 695 ; N uni1D03 ; G 1262 +U 7428 ; WX 609 ; N uni1D04 ; G 1263 +U 7429 ; WX 675 ; N uni1D05 ; G 1264 +U 7430 ; WX 675 ; N uni1D06 ; G 1265 +U 7431 ; WX 617 ; N uni1D07 ; G 1266 +U 7432 ; WX 509 ; N uni1D08 ; G 1267 +U 7433 ; WX 320 ; N uni1D09 ; G 1268 +U 7434 ; WX 561 ; N uni1D0A ; G 1269 +U 7435 ; WX 722 ; N uni1D0B ; G 1270 +U 7436 ; WX 617 ; N uni1D0C ; G 1271 +U 7437 ; WX 869 ; N uni1D0D ; G 1272 +U 7438 ; WX 737 ; N uni1D0E ; G 1273 +U 7439 ; WX 667 ; N uni1D0F ; G 1274 +U 7440 ; WX 609 ; N uni1D10 ; G 1275 +U 7441 ; WX 628 ; N uni1D11 ; G 1276 +U 7442 ; WX 628 ; N uni1D12 ; G 1277 +U 7443 ; WX 667 ; N uni1D13 ; G 1278 +U 7444 ; WX 1028 ; N uni1D14 ; G 1279 +U 7445 ; WX 598 ; N uni1D15 ; G 1280 +U 7446 ; WX 667 ; N uni1D16 ; G 1281 +U 7447 ; WX 667 ; N uni1D17 ; G 1282 +U 7448 ; WX 586 ; N uni1D18 ; G 1283 +U 7449 ; WX 801 ; N uni1D19 ; G 1284 +U 7450 ; WX 801 ; N uni1D1A ; G 1285 +U 7451 ; WX 620 ; N uni1D1B ; G 1286 +U 7452 ; WX 647 ; N uni1D1C ; G 1287 +U 7453 ; WX 664 ; N uni1D1D ; G 1288 +U 7454 ; WX 923 ; N uni1D1E ; G 1289 +U 7455 ; WX 655 ; N uni1D1F ; G 1290 +U 7456 ; WX 581 ; N uni1D20 ; G 1291 +U 7457 ; WX 861 ; N uni1D21 ; G 1292 +U 7458 ; WX 568 ; N uni1D22 ; G 1293 +U 7459 ; WX 568 ; N uni1D23 ; G 1294 +U 7460 ; WX 588 ; N uni1D24 ; G 1295 +U 7461 ; WX 802 ; N uni1D25 ; G 1296 +U 7462 ; WX 586 ; N uni1D26 ; G 1297 +U 7463 ; WX 641 ; N uni1D27 ; G 1298 +U 7464 ; WX 732 ; N uni1D28 ; G 1299 +U 7465 ; WX 586 ; N uni1D29 ; G 1300 +U 7466 ; WX 854 ; N uni1D2A ; G 1301 +U 7467 ; WX 705 ; N uni1D2B ; G 1302 +U 7468 ; WX 489 ; N uni1D2C ; G 1303 +U 7469 ; WX 651 ; N uni1D2D ; G 1304 +U 7470 ; WX 532 ; N uni1D2E ; G 1305 +U 7471 ; WX 532 ; N uni1D2F ; G 1306 +U 7472 ; WX 546 ; N uni1D30 ; G 1307 +U 7473 ; WX 480 ; N uni1D31 ; G 1308 +U 7474 ; WX 480 ; N uni1D32 ; G 1309 +U 7475 ; WX 538 ; N uni1D33 ; G 1310 +U 7476 ; WX 595 ; N uni1D34 ; G 1311 +U 7477 ; WX 294 ; N uni1D35 ; G 1312 +U 7478 ; WX 298 ; N uni1D36 ; G 1313 +U 7479 ; WX 547 ; N uni1D37 ; G 1314 +U 7480 ; WX 443 ; N uni1D38 ; G 1315 +U 7481 ; WX 697 ; N uni1D39 ; G 1316 +U 7482 ; WX 576 ; N uni1D3A ; G 1317 +U 7483 ; WX 606 ; N uni1D3B ; G 1318 +U 7484 ; WX 548 ; N uni1D3C ; G 1319 +U 7485 ; WX 442 ; N uni1D3D ; G 1320 +U 7486 ; WX 474 ; N uni1D3E ; G 1321 +U 7487 ; WX 523 ; N uni1D3F ; G 1322 +U 7488 ; WX 469 ; N uni1D40 ; G 1323 +U 7489 ; WX 549 ; N uni1D41 ; G 1324 +U 7490 ; WX 708 ; N uni1D42 ; G 1325 +U 7491 ; WX 408 ; N uni1D43 ; G 1326 +U 7492 ; WX 408 ; N uni1D44 ; G 1327 +U 7493 ; WX 484 ; N uni1D45 ; G 1328 +U 7494 ; WX 587 ; N uni1D46 ; G 1329 +U 7495 ; WX 499 ; N uni1D47 ; G 1330 +U 7496 ; WX 498 ; N uni1D48 ; G 1331 +U 7497 ; WX 444 ; N uni1D49 ; G 1332 +U 7498 ; WX 444 ; N uni1D4A ; G 1333 +U 7499 ; WX 412 ; N uni1D4B ; G 1334 +U 7500 ; WX 412 ; N uni1D4C ; G 1335 +U 7501 ; WX 498 ; N uni1D4D ; G 1336 +U 7502 ; WX 300 ; N uni1D4E ; G 1337 +U 7503 ; WX 523 ; N uni1D4F ; G 1338 +U 7504 ; WX 729 ; N uni1D50 ; G 1339 +U 7505 ; WX 473 ; N uni1D51 ; G 1340 +U 7506 ; WX 467 ; N uni1D52 ; G 1341 +U 7507 ; WX 427 ; N uni1D53 ; G 1342 +U 7508 ; WX 467 ; N uni1D54 ; G 1343 +U 7509 ; WX 467 ; N uni1D55 ; G 1344 +U 7510 ; WX 499 ; N uni1D56 ; G 1345 +U 7511 ; WX 371 ; N uni1D57 ; G 1346 +U 7512 ; WX 520 ; N uni1D58 ; G 1347 +U 7513 ; WX 418 ; N uni1D59 ; G 1348 +U 7514 ; WX 729 ; N uni1D5A ; G 1349 +U 7515 ; WX 491 ; N uni1D5B ; G 1350 +U 7516 ; WX 505 ; N uni1D5C ; G 1351 +U 7517 ; WX 418 ; N uni1D5D ; G 1352 +U 7518 ; WX 416 ; N uni1D5E ; G 1353 +U 7519 ; WX 420 ; N uni1D5F ; G 1354 +U 7520 ; WX 570 ; N uni1D60 ; G 1355 +U 7521 ; WX 414 ; N uni1D61 ; G 1356 +U 7522 ; WX 239 ; N uni1D62 ; G 1357 +U 7523 ; WX 414 ; N uni1D63 ; G 1358 +U 7524 ; WX 520 ; N uni1D64 ; G 1359 +U 7525 ; WX 491 ; N uni1D65 ; G 1360 +U 7526 ; WX 418 ; N uni1D66 ; G 1361 +U 7527 ; WX 416 ; N uni1D67 ; G 1362 +U 7528 ; WX 419 ; N uni1D68 ; G 1363 +U 7529 ; WX 570 ; N uni1D69 ; G 1364 +U 7530 ; WX 414 ; N uni1D6A ; G 1365 +U 7531 ; WX 1042 ; N uni1D6B ; G 1366 +U 7543 ; WX 640 ; N uni1D77 ; G 1367 +U 7544 ; WX 595 ; N uni1D78 ; G 1368 +U 7547 ; WX 380 ; N uni1D7B ; G 1369 +U 7548 ; WX 380 ; N uni1D7C ; G 1370 +U 7549 ; WX 699 ; N uni1D7D ; G 1371 +U 7550 ; WX 647 ; N uni1D7E ; G 1372 +U 7551 ; WX 679 ; N uni1D7F ; G 1373 +U 7557 ; WX 380 ; N uni1D85 ; G 1374 +U 7579 ; WX 484 ; N uni1D9B ; G 1375 +U 7580 ; WX 427 ; N uni1D9C ; G 1376 +U 7581 ; WX 427 ; N uni1D9D ; G 1377 +U 7582 ; WX 467 ; N uni1D9E ; G 1378 +U 7583 ; WX 412 ; N uni1D9F ; G 1379 +U 7584 ; WX 271 ; N uni1DA0 ; G 1380 +U 7585 ; WX 373 ; N uni1DA1 ; G 1381 +U 7586 ; WX 498 ; N uni1DA2 ; G 1382 +U 7587 ; WX 522 ; N uni1DA3 ; G 1383 +U 7588 ; WX 300 ; N uni1DA4 ; G 1384 +U 7589 ; WX 307 ; N uni1DA5 ; G 1385 +U 7590 ; WX 300 ; N uni1DA6 ; G 1386 +U 7591 ; WX 300 ; N uni1DA7 ; G 1387 +U 7592 ; WX 370 ; N uni1DA8 ; G 1388 +U 7593 ; WX 368 ; N uni1DA9 ; G 1389 +U 7594 ; WX 321 ; N uni1DAA ; G 1390 +U 7595 ; WX 430 ; N uni1DAB ; G 1391 +U 7596 ; WX 682 ; N uni1DAC ; G 1392 +U 7597 ; WX 729 ; N uni1DAD ; G 1393 +U 7598 ; WX 588 ; N uni1DAE ; G 1394 +U 7599 ; WX 587 ; N uni1DAF ; G 1395 +U 7600 ; WX 472 ; N uni1DB0 ; G 1396 +U 7601 ; WX 467 ; N uni1DB1 ; G 1397 +U 7602 ; WX 522 ; N uni1DB2 ; G 1398 +U 7603 ; WX 400 ; N uni1DB3 ; G 1399 +U 7604 ; WX 387 ; N uni1DB4 ; G 1400 +U 7605 ; WX 371 ; N uni1DB5 ; G 1401 +U 7606 ; WX 520 ; N uni1DB6 ; G 1402 +U 7607 ; WX 475 ; N uni1DB7 ; G 1403 +U 7608 ; WX 408 ; N uni1DB8 ; G 1404 +U 7609 ; WX 489 ; N uni1DB9 ; G 1405 +U 7610 ; WX 366 ; N uni1DBA ; G 1406 +U 7611 ; WX 357 ; N uni1DBB ; G 1407 +U 7612 ; WX 527 ; N uni1DBC ; G 1408 +U 7613 ; WX 412 ; N uni1DBD ; G 1409 +U 7614 ; WX 452 ; N uni1DBE ; G 1410 +U 7615 ; WX 467 ; N uni1DBF ; G 1411 +U 7620 ; WX 0 ; N uni1DC4 ; G 1412 +U 7621 ; WX 0 ; N uni1DC5 ; G 1413 +U 7622 ; WX 0 ; N uni1DC6 ; G 1414 +U 7623 ; WX 0 ; N uni1DC7 ; G 1415 +U 7624 ; WX 0 ; N uni1DC8 ; G 1416 +U 7625 ; WX 0 ; N uni1DC9 ; G 1417 +U 7680 ; WX 776 ; N uni1E00 ; G 1418 +U 7681 ; WX 648 ; N uni1E01 ; G 1419 +U 7682 ; WX 845 ; N uni1E02 ; G 1420 +U 7683 ; WX 699 ; N uni1E03 ; G 1421 +U 7684 ; WX 845 ; N uni1E04 ; G 1422 +U 7685 ; WX 699 ; N uni1E05 ; G 1423 +U 7686 ; WX 845 ; N uni1E06 ; G 1424 +U 7687 ; WX 699 ; N uni1E07 ; G 1425 +U 7688 ; WX 796 ; N uni1E08 ; G 1426 +U 7689 ; WX 609 ; N uni1E09 ; G 1427 +U 7690 ; WX 867 ; N uni1E0A ; G 1428 +U 7691 ; WX 699 ; N uni1E0B ; G 1429 +U 7692 ; WX 867 ; N uni1E0C ; G 1430 +U 7693 ; WX 699 ; N uni1E0D ; G 1431 +U 7694 ; WX 867 ; N uni1E0E ; G 1432 +U 7695 ; WX 699 ; N uni1E0F ; G 1433 +U 7696 ; WX 867 ; N uni1E10 ; G 1434 +U 7697 ; WX 699 ; N uni1E11 ; G 1435 +U 7698 ; WX 867 ; N uni1E12 ; G 1436 +U 7699 ; WX 699 ; N uni1E13 ; G 1437 +U 7700 ; WX 762 ; N uni1E14 ; G 1438 +U 7701 ; WX 636 ; N uni1E15 ; G 1439 +U 7702 ; WX 762 ; N uni1E16 ; G 1440 +U 7703 ; WX 636 ; N uni1E17 ; G 1441 +U 7704 ; WX 762 ; N uni1E18 ; G 1442 +U 7705 ; WX 636 ; N uni1E19 ; G 1443 +U 7706 ; WX 762 ; N uni1E1A ; G 1444 +U 7707 ; WX 636 ; N uni1E1B ; G 1445 +U 7708 ; WX 762 ; N uni1E1C ; G 1446 +U 7709 ; WX 636 ; N uni1E1D ; G 1447 +U 7710 ; WX 710 ; N uni1E1E ; G 1448 +U 7711 ; WX 430 ; N uni1E1F ; G 1449 +U 7712 ; WX 854 ; N uni1E20 ; G 1450 +U 7713 ; WX 699 ; N uni1E21 ; G 1451 +U 7714 ; WX 945 ; N uni1E22 ; G 1452 +U 7715 ; WX 727 ; N uni1E23 ; G 1453 +U 7716 ; WX 945 ; N uni1E24 ; G 1454 +U 7717 ; WX 727 ; N uni1E25 ; G 1455 +U 7718 ; WX 945 ; N uni1E26 ; G 1456 +U 7719 ; WX 727 ; N uni1E27 ; G 1457 +U 7720 ; WX 945 ; N uni1E28 ; G 1458 +U 7721 ; WX 727 ; N uni1E29 ; G 1459 +U 7722 ; WX 945 ; N uni1E2A ; G 1460 +U 7723 ; WX 727 ; N uni1E2B ; G 1461 +U 7724 ; WX 468 ; N uni1E2C ; G 1462 +U 7725 ; WX 380 ; N uni1E2D ; G 1463 +U 7726 ; WX 468 ; N uni1E2E ; G 1464 +U 7727 ; WX 380 ; N uni1E2F ; G 1465 +U 7728 ; WX 869 ; N uni1E30 ; G 1466 +U 7729 ; WX 693 ; N uni1E31 ; G 1467 +U 7730 ; WX 869 ; N uni1E32 ; G 1468 +U 7731 ; WX 693 ; N uni1E33 ; G 1469 +U 7732 ; WX 869 ; N uni1E34 ; G 1470 +U 7733 ; WX 693 ; N uni1E35 ; G 1471 +U 7734 ; WX 703 ; N uni1E36 ; G 1472 +U 7735 ; WX 380 ; N uni1E37 ; G 1473 +U 7736 ; WX 703 ; N uni1E38 ; G 1474 +U 7737 ; WX 380 ; N uni1E39 ; G 1475 +U 7738 ; WX 703 ; N uni1E3A ; G 1476 +U 7739 ; WX 380 ; N uni1E3B ; G 1477 +U 7740 ; WX 703 ; N uni1E3C ; G 1478 +U 7741 ; WX 380 ; N uni1E3D ; G 1479 +U 7742 ; WX 1107 ; N uni1E3E ; G 1480 +U 7743 ; WX 1058 ; N uni1E3F ; G 1481 +U 7744 ; WX 1107 ; N uni1E40 ; G 1482 +U 7745 ; WX 1058 ; N uni1E41 ; G 1483 +U 7746 ; WX 1107 ; N uni1E42 ; G 1484 +U 7747 ; WX 1058 ; N uni1E43 ; G 1485 +U 7748 ; WX 914 ; N uni1E44 ; G 1486 +U 7749 ; WX 727 ; N uni1E45 ; G 1487 +U 7750 ; WX 914 ; N uni1E46 ; G 1488 +U 7751 ; WX 727 ; N uni1E47 ; G 1489 +U 7752 ; WX 914 ; N uni1E48 ; G 1490 +U 7753 ; WX 727 ; N uni1E49 ; G 1491 +U 7754 ; WX 914 ; N uni1E4A ; G 1492 +U 7755 ; WX 727 ; N uni1E4B ; G 1493 +U 7756 ; WX 871 ; N uni1E4C ; G 1494 +U 7757 ; WX 667 ; N uni1E4D ; G 1495 +U 7758 ; WX 871 ; N uni1E4E ; G 1496 +U 7759 ; WX 667 ; N uni1E4F ; G 1497 +U 7760 ; WX 871 ; N uni1E50 ; G 1498 +U 7761 ; WX 667 ; N uni1E51 ; G 1499 +U 7762 ; WX 871 ; N uni1E52 ; G 1500 +U 7763 ; WX 667 ; N uni1E53 ; G 1501 +U 7764 ; WX 752 ; N uni1E54 ; G 1502 +U 7765 ; WX 699 ; N uni1E55 ; G 1503 +U 7766 ; WX 752 ; N uni1E56 ; G 1504 +U 7767 ; WX 699 ; N uni1E57 ; G 1505 +U 7768 ; WX 831 ; N uni1E58 ; G 1506 +U 7769 ; WX 527 ; N uni1E59 ; G 1507 +U 7770 ; WX 831 ; N uni1E5A ; G 1508 +U 7771 ; WX 527 ; N uni1E5B ; G 1509 +U 7772 ; WX 831 ; N uni1E5C ; G 1510 +U 7773 ; WX 527 ; N uni1E5D ; G 1511 +U 7774 ; WX 831 ; N uni1E5E ; G 1512 +U 7775 ; WX 527 ; N uni1E5F ; G 1513 +U 7776 ; WX 722 ; N uni1E60 ; G 1514 +U 7777 ; WX 563 ; N uni1E61 ; G 1515 +U 7778 ; WX 722 ; N uni1E62 ; G 1516 +U 7779 ; WX 563 ; N uni1E63 ; G 1517 +U 7780 ; WX 722 ; N uni1E64 ; G 1518 +U 7781 ; WX 563 ; N uni1E65 ; G 1519 +U 7782 ; WX 722 ; N uni1E66 ; G 1520 +U 7783 ; WX 563 ; N uni1E67 ; G 1521 +U 7784 ; WX 722 ; N uni1E68 ; G 1522 +U 7785 ; WX 563 ; N uni1E69 ; G 1523 +U 7786 ; WX 744 ; N uni1E6A ; G 1524 +U 7787 ; WX 462 ; N uni1E6B ; G 1525 +U 7788 ; WX 744 ; N uni1E6C ; G 1526 +U 7789 ; WX 462 ; N uni1E6D ; G 1527 +U 7790 ; WX 744 ; N uni1E6E ; G 1528 +U 7791 ; WX 462 ; N uni1E6F ; G 1529 +U 7792 ; WX 744 ; N uni1E70 ; G 1530 +U 7793 ; WX 462 ; N uni1E71 ; G 1531 +U 7794 ; WX 872 ; N uni1E72 ; G 1532 +U 7795 ; WX 727 ; N uni1E73 ; G 1533 +U 7796 ; WX 872 ; N uni1E74 ; G 1534 +U 7797 ; WX 727 ; N uni1E75 ; G 1535 +U 7798 ; WX 872 ; N uni1E76 ; G 1536 +U 7799 ; WX 727 ; N uni1E77 ; G 1537 +U 7800 ; WX 872 ; N uni1E78 ; G 1538 +U 7801 ; WX 727 ; N uni1E79 ; G 1539 +U 7802 ; WX 872 ; N uni1E7A ; G 1540 +U 7803 ; WX 727 ; N uni1E7B ; G 1541 +U 7804 ; WX 776 ; N uni1E7C ; G 1542 +U 7805 ; WX 581 ; N uni1E7D ; G 1543 +U 7806 ; WX 776 ; N uni1E7E ; G 1544 +U 7807 ; WX 581 ; N uni1E7F ; G 1545 +U 7808 ; WX 1123 ; N Wgrave ; G 1546 +U 7809 ; WX 861 ; N wgrave ; G 1547 +U 7810 ; WX 1123 ; N Wacute ; G 1548 +U 7811 ; WX 861 ; N wacute ; G 1549 +U 7812 ; WX 1123 ; N Wdieresis ; G 1550 +U 7813 ; WX 861 ; N wdieresis ; G 1551 +U 7814 ; WX 1123 ; N uni1E86 ; G 1552 +U 7815 ; WX 861 ; N uni1E87 ; G 1553 +U 7816 ; WX 1123 ; N uni1E88 ; G 1554 +U 7817 ; WX 861 ; N uni1E89 ; G 1555 +U 7818 ; WX 776 ; N uni1E8A ; G 1556 +U 7819 ; WX 596 ; N uni1E8B ; G 1557 +U 7820 ; WX 776 ; N uni1E8C ; G 1558 +U 7821 ; WX 596 ; N uni1E8D ; G 1559 +U 7822 ; WX 714 ; N uni1E8E ; G 1560 +U 7823 ; WX 581 ; N uni1E8F ; G 1561 +U 7824 ; WX 730 ; N uni1E90 ; G 1562 +U 7825 ; WX 568 ; N uni1E91 ; G 1563 +U 7826 ; WX 730 ; N uni1E92 ; G 1564 +U 7827 ; WX 568 ; N uni1E93 ; G 1565 +U 7828 ; WX 730 ; N uni1E94 ; G 1566 +U 7829 ; WX 568 ; N uni1E95 ; G 1567 +U 7830 ; WX 727 ; N uni1E96 ; G 1568 +U 7831 ; WX 462 ; N uni1E97 ; G 1569 +U 7832 ; WX 861 ; N uni1E98 ; G 1570 +U 7833 ; WX 581 ; N uni1E99 ; G 1571 +U 7834 ; WX 1014 ; N uni1E9A ; G 1572 +U 7835 ; WX 430 ; N uni1E9B ; G 1573 +U 7836 ; WX 430 ; N uni1E9C ; G 1574 +U 7837 ; WX 430 ; N uni1E9D ; G 1575 +U 7838 ; WX 947 ; N uni1E9E ; G 1576 +U 7839 ; WX 667 ; N uni1E9F ; G 1577 +U 7840 ; WX 776 ; N uni1EA0 ; G 1578 +U 7841 ; WX 648 ; N uni1EA1 ; G 1579 +U 7842 ; WX 776 ; N uni1EA2 ; G 1580 +U 7843 ; WX 648 ; N uni1EA3 ; G 1581 +U 7844 ; WX 776 ; N uni1EA4 ; G 1582 +U 7845 ; WX 648 ; N uni1EA5 ; G 1583 +U 7846 ; WX 776 ; N uni1EA6 ; G 1584 +U 7847 ; WX 648 ; N uni1EA7 ; G 1585 +U 7848 ; WX 776 ; N uni1EA8 ; G 1586 +U 7849 ; WX 648 ; N uni1EA9 ; G 1587 +U 7850 ; WX 776 ; N uni1EAA ; G 1588 +U 7851 ; WX 648 ; N uni1EAB ; G 1589 +U 7852 ; WX 776 ; N uni1EAC ; G 1590 +U 7853 ; WX 648 ; N uni1EAD ; G 1591 +U 7854 ; WX 776 ; N uni1EAE ; G 1592 +U 7855 ; WX 648 ; N uni1EAF ; G 1593 +U 7856 ; WX 776 ; N uni1EB0 ; G 1594 +U 7857 ; WX 648 ; N uni1EB1 ; G 1595 +U 7858 ; WX 776 ; N uni1EB2 ; G 1596 +U 7859 ; WX 648 ; N uni1EB3 ; G 1597 +U 7860 ; WX 776 ; N uni1EB4 ; G 1598 +U 7861 ; WX 648 ; N uni1EB5 ; G 1599 +U 7862 ; WX 776 ; N uni1EB6 ; G 1600 +U 7863 ; WX 648 ; N uni1EB7 ; G 1601 +U 7864 ; WX 762 ; N uni1EB8 ; G 1602 +U 7865 ; WX 636 ; N uni1EB9 ; G 1603 +U 7866 ; WX 762 ; N uni1EBA ; G 1604 +U 7867 ; WX 636 ; N uni1EBB ; G 1605 +U 7868 ; WX 762 ; N uni1EBC ; G 1606 +U 7869 ; WX 636 ; N uni1EBD ; G 1607 +U 7870 ; WX 762 ; N uni1EBE ; G 1608 +U 7871 ; WX 636 ; N uni1EBF ; G 1609 +U 7872 ; WX 762 ; N uni1EC0 ; G 1610 +U 7873 ; WX 636 ; N uni1EC1 ; G 1611 +U 7874 ; WX 762 ; N uni1EC2 ; G 1612 +U 7875 ; WX 636 ; N uni1EC3 ; G 1613 +U 7876 ; WX 762 ; N uni1EC4 ; G 1614 +U 7877 ; WX 636 ; N uni1EC5 ; G 1615 +U 7878 ; WX 762 ; N uni1EC6 ; G 1616 +U 7879 ; WX 636 ; N uni1EC7 ; G 1617 +U 7880 ; WX 468 ; N uni1EC8 ; G 1618 +U 7881 ; WX 380 ; N uni1EC9 ; G 1619 +U 7882 ; WX 468 ; N uni1ECA ; G 1620 +U 7883 ; WX 380 ; N uni1ECB ; G 1621 +U 7884 ; WX 871 ; N uni1ECC ; G 1622 +U 7885 ; WX 667 ; N uni1ECD ; G 1623 +U 7886 ; WX 871 ; N uni1ECE ; G 1624 +U 7887 ; WX 667 ; N uni1ECF ; G 1625 +U 7888 ; WX 871 ; N uni1ED0 ; G 1626 +U 7889 ; WX 667 ; N uni1ED1 ; G 1627 +U 7890 ; WX 871 ; N uni1ED2 ; G 1628 +U 7891 ; WX 667 ; N uni1ED3 ; G 1629 +U 7892 ; WX 871 ; N uni1ED4 ; G 1630 +U 7893 ; WX 667 ; N uni1ED5 ; G 1631 +U 7894 ; WX 871 ; N uni1ED6 ; G 1632 +U 7895 ; WX 667 ; N uni1ED7 ; G 1633 +U 7896 ; WX 871 ; N uni1ED8 ; G 1634 +U 7897 ; WX 667 ; N uni1ED9 ; G 1635 +U 7898 ; WX 871 ; N uni1EDA ; G 1636 +U 7899 ; WX 667 ; N uni1EDB ; G 1637 +U 7900 ; WX 871 ; N uni1EDC ; G 1638 +U 7901 ; WX 667 ; N uni1EDD ; G 1639 +U 7902 ; WX 871 ; N uni1EDE ; G 1640 +U 7903 ; WX 667 ; N uni1EDF ; G 1641 +U 7904 ; WX 871 ; N uni1EE0 ; G 1642 +U 7905 ; WX 667 ; N uni1EE1 ; G 1643 +U 7906 ; WX 871 ; N uni1EE2 ; G 1644 +U 7907 ; WX 667 ; N uni1EE3 ; G 1645 +U 7908 ; WX 872 ; N uni1EE4 ; G 1646 +U 7909 ; WX 727 ; N uni1EE5 ; G 1647 +U 7910 ; WX 872 ; N uni1EE6 ; G 1648 +U 7911 ; WX 727 ; N uni1EE7 ; G 1649 +U 7912 ; WX 872 ; N uni1EE8 ; G 1650 +U 7913 ; WX 727 ; N uni1EE9 ; G 1651 +U 7914 ; WX 872 ; N uni1EEA ; G 1652 +U 7915 ; WX 727 ; N uni1EEB ; G 1653 +U 7916 ; WX 872 ; N uni1EEC ; G 1654 +U 7917 ; WX 727 ; N uni1EED ; G 1655 +U 7918 ; WX 872 ; N uni1EEE ; G 1656 +U 7919 ; WX 727 ; N uni1EEF ; G 1657 +U 7920 ; WX 872 ; N uni1EF0 ; G 1658 +U 7921 ; WX 727 ; N uni1EF1 ; G 1659 +U 7922 ; WX 714 ; N Ygrave ; G 1660 +U 7923 ; WX 581 ; N ygrave ; G 1661 +U 7924 ; WX 714 ; N uni1EF4 ; G 1662 +U 7925 ; WX 581 ; N uni1EF5 ; G 1663 +U 7926 ; WX 714 ; N uni1EF6 ; G 1664 +U 7927 ; WX 581 ; N uni1EF7 ; G 1665 +U 7928 ; WX 714 ; N uni1EF8 ; G 1666 +U 7929 ; WX 581 ; N uni1EF9 ; G 1667 +U 7930 ; WX 1078 ; N uni1EFA ; G 1668 +U 7931 ; WX 701 ; N uni1EFB ; G 1669 +U 7936 ; WX 770 ; N uni1F00 ; G 1670 +U 7937 ; WX 770 ; N uni1F01 ; G 1671 +U 7938 ; WX 770 ; N uni1F02 ; G 1672 +U 7939 ; WX 770 ; N uni1F03 ; G 1673 +U 7940 ; WX 770 ; N uni1F04 ; G 1674 +U 7941 ; WX 770 ; N uni1F05 ; G 1675 +U 7942 ; WX 770 ; N uni1F06 ; G 1676 +U 7943 ; WX 770 ; N uni1F07 ; G 1677 +U 7944 ; WX 776 ; N uni1F08 ; G 1678 +U 7945 ; WX 776 ; N uni1F09 ; G 1679 +U 7946 ; WX 978 ; N uni1F0A ; G 1680 +U 7947 ; WX 978 ; N uni1F0B ; G 1681 +U 7948 ; WX 832 ; N uni1F0C ; G 1682 +U 7949 ; WX 849 ; N uni1F0D ; G 1683 +U 7950 ; WX 776 ; N uni1F0E ; G 1684 +U 7951 ; WX 776 ; N uni1F0F ; G 1685 +U 7952 ; WX 608 ; N uni1F10 ; G 1686 +U 7953 ; WX 608 ; N uni1F11 ; G 1687 +U 7954 ; WX 608 ; N uni1F12 ; G 1688 +U 7955 ; WX 608 ; N uni1F13 ; G 1689 +U 7956 ; WX 608 ; N uni1F14 ; G 1690 +U 7957 ; WX 608 ; N uni1F15 ; G 1691 +U 7960 ; WX 917 ; N uni1F18 ; G 1692 +U 7961 ; WX 909 ; N uni1F19 ; G 1693 +U 7962 ; WX 1169 ; N uni1F1A ; G 1694 +U 7963 ; WX 1169 ; N uni1F1B ; G 1695 +U 7964 ; WX 1093 ; N uni1F1C ; G 1696 +U 7965 ; WX 1120 ; N uni1F1D ; G 1697 +U 7968 ; WX 727 ; N uni1F20 ; G 1698 +U 7969 ; WX 727 ; N uni1F21 ; G 1699 +U 7970 ; WX 727 ; N uni1F22 ; G 1700 +U 7971 ; WX 727 ; N uni1F23 ; G 1701 +U 7972 ; WX 727 ; N uni1F24 ; G 1702 +U 7973 ; WX 727 ; N uni1F25 ; G 1703 +U 7974 ; WX 727 ; N uni1F26 ; G 1704 +U 7975 ; WX 727 ; N uni1F27 ; G 1705 +U 7976 ; WX 1100 ; N uni1F28 ; G 1706 +U 7977 ; WX 1094 ; N uni1F29 ; G 1707 +U 7978 ; WX 1358 ; N uni1F2A ; G 1708 +U 7979 ; WX 1361 ; N uni1F2B ; G 1709 +U 7980 ; WX 1279 ; N uni1F2C ; G 1710 +U 7981 ; WX 1308 ; N uni1F2D ; G 1711 +U 7982 ; WX 1197 ; N uni1F2E ; G 1712 +U 7983 ; WX 1194 ; N uni1F2F ; G 1713 +U 7984 ; WX 484 ; N uni1F30 ; G 1714 +U 7985 ; WX 484 ; N uni1F31 ; G 1715 +U 7986 ; WX 484 ; N uni1F32 ; G 1716 +U 7987 ; WX 484 ; N uni1F33 ; G 1717 +U 7988 ; WX 484 ; N uni1F34 ; G 1718 +U 7989 ; WX 484 ; N uni1F35 ; G 1719 +U 7990 ; WX 484 ; N uni1F36 ; G 1720 +U 7991 ; WX 484 ; N uni1F37 ; G 1721 +U 7992 ; WX 629 ; N uni1F38 ; G 1722 +U 7993 ; WX 617 ; N uni1F39 ; G 1723 +U 7994 ; WX 878 ; N uni1F3A ; G 1724 +U 7995 ; WX 881 ; N uni1F3B ; G 1725 +U 7996 ; WX 799 ; N uni1F3C ; G 1726 +U 7997 ; WX 831 ; N uni1F3D ; G 1727 +U 7998 ; WX 723 ; N uni1F3E ; G 1728 +U 7999 ; WX 714 ; N uni1F3F ; G 1729 +U 8000 ; WX 667 ; N uni1F40 ; G 1730 +U 8001 ; WX 667 ; N uni1F41 ; G 1731 +U 8002 ; WX 667 ; N uni1F42 ; G 1732 +U 8003 ; WX 667 ; N uni1F43 ; G 1733 +U 8004 ; WX 667 ; N uni1F44 ; G 1734 +U 8005 ; WX 667 ; N uni1F45 ; G 1735 +U 8008 ; WX 900 ; N uni1F48 ; G 1736 +U 8009 ; WX 935 ; N uni1F49 ; G 1737 +U 8010 ; WX 1240 ; N uni1F4A ; G 1738 +U 8011 ; WX 1237 ; N uni1F4B ; G 1739 +U 8012 ; WX 1035 ; N uni1F4C ; G 1740 +U 8013 ; WX 1066 ; N uni1F4D ; G 1741 +U 8016 ; WX 694 ; N uni1F50 ; G 1742 +U 8017 ; WX 694 ; N uni1F51 ; G 1743 +U 8018 ; WX 694 ; N uni1F52 ; G 1744 +U 8019 ; WX 694 ; N uni1F53 ; G 1745 +U 8020 ; WX 694 ; N uni1F54 ; G 1746 +U 8021 ; WX 694 ; N uni1F55 ; G 1747 +U 8022 ; WX 694 ; N uni1F56 ; G 1748 +U 8023 ; WX 694 ; N uni1F57 ; G 1749 +U 8025 ; WX 922 ; N uni1F59 ; G 1750 +U 8027 ; WX 1186 ; N uni1F5B ; G 1751 +U 8029 ; WX 1133 ; N uni1F5D ; G 1752 +U 8031 ; WX 1019 ; N uni1F5F ; G 1753 +U 8032 ; WX 952 ; N uni1F60 ; G 1754 +U 8033 ; WX 952 ; N uni1F61 ; G 1755 +U 8034 ; WX 952 ; N uni1F62 ; G 1756 +U 8035 ; WX 952 ; N uni1F63 ; G 1757 +U 8036 ; WX 952 ; N uni1F64 ; G 1758 +U 8037 ; WX 952 ; N uni1F65 ; G 1759 +U 8038 ; WX 952 ; N uni1F66 ; G 1760 +U 8039 ; WX 952 ; N uni1F67 ; G 1761 +U 8040 ; WX 931 ; N uni1F68 ; G 1762 +U 8041 ; WX 963 ; N uni1F69 ; G 1763 +U 8042 ; WX 1268 ; N uni1F6A ; G 1764 +U 8043 ; WX 1274 ; N uni1F6B ; G 1765 +U 8044 ; WX 1054 ; N uni1F6C ; G 1766 +U 8045 ; WX 1088 ; N uni1F6D ; G 1767 +U 8046 ; WX 1023 ; N uni1F6E ; G 1768 +U 8047 ; WX 1060 ; N uni1F6F ; G 1769 +U 8048 ; WX 770 ; N uni1F70 ; G 1770 +U 8049 ; WX 770 ; N uni1F71 ; G 1771 +U 8050 ; WX 608 ; N uni1F72 ; G 1772 +U 8051 ; WX 608 ; N uni1F73 ; G 1773 +U 8052 ; WX 727 ; N uni1F74 ; G 1774 +U 8053 ; WX 727 ; N uni1F75 ; G 1775 +U 8054 ; WX 484 ; N uni1F76 ; G 1776 +U 8055 ; WX 484 ; N uni1F77 ; G 1777 +U 8056 ; WX 667 ; N uni1F78 ; G 1778 +U 8057 ; WX 667 ; N uni1F79 ; G 1779 +U 8058 ; WX 694 ; N uni1F7A ; G 1780 +U 8059 ; WX 694 ; N uni1F7B ; G 1781 +U 8060 ; WX 952 ; N uni1F7C ; G 1782 +U 8061 ; WX 952 ; N uni1F7D ; G 1783 +U 8064 ; WX 770 ; N uni1F80 ; G 1784 +U 8065 ; WX 770 ; N uni1F81 ; G 1785 +U 8066 ; WX 770 ; N uni1F82 ; G 1786 +U 8067 ; WX 770 ; N uni1F83 ; G 1787 +U 8068 ; WX 770 ; N uni1F84 ; G 1788 +U 8069 ; WX 770 ; N uni1F85 ; G 1789 +U 8070 ; WX 770 ; N uni1F86 ; G 1790 +U 8071 ; WX 770 ; N uni1F87 ; G 1791 +U 8072 ; WX 776 ; N uni1F88 ; G 1792 +U 8073 ; WX 776 ; N uni1F89 ; G 1793 +U 8074 ; WX 978 ; N uni1F8A ; G 1794 +U 8075 ; WX 978 ; N uni1F8B ; G 1795 +U 8076 ; WX 832 ; N uni1F8C ; G 1796 +U 8077 ; WX 849 ; N uni1F8D ; G 1797 +U 8078 ; WX 776 ; N uni1F8E ; G 1798 +U 8079 ; WX 776 ; N uni1F8F ; G 1799 +U 8080 ; WX 727 ; N uni1F90 ; G 1800 +U 8081 ; WX 727 ; N uni1F91 ; G 1801 +U 8082 ; WX 727 ; N uni1F92 ; G 1802 +U 8083 ; WX 727 ; N uni1F93 ; G 1803 +U 8084 ; WX 727 ; N uni1F94 ; G 1804 +U 8085 ; WX 727 ; N uni1F95 ; G 1805 +U 8086 ; WX 727 ; N uni1F96 ; G 1806 +U 8087 ; WX 727 ; N uni1F97 ; G 1807 +U 8088 ; WX 1100 ; N uni1F98 ; G 1808 +U 8089 ; WX 1094 ; N uni1F99 ; G 1809 +U 8090 ; WX 1358 ; N uni1F9A ; G 1810 +U 8091 ; WX 1361 ; N uni1F9B ; G 1811 +U 8092 ; WX 1279 ; N uni1F9C ; G 1812 +U 8093 ; WX 1308 ; N uni1F9D ; G 1813 +U 8094 ; WX 1197 ; N uni1F9E ; G 1814 +U 8095 ; WX 1194 ; N uni1F9F ; G 1815 +U 8096 ; WX 952 ; N uni1FA0 ; G 1816 +U 8097 ; WX 952 ; N uni1FA1 ; G 1817 +U 8098 ; WX 952 ; N uni1FA2 ; G 1818 +U 8099 ; WX 952 ; N uni1FA3 ; G 1819 +U 8100 ; WX 952 ; N uni1FA4 ; G 1820 +U 8101 ; WX 952 ; N uni1FA5 ; G 1821 +U 8102 ; WX 952 ; N uni1FA6 ; G 1822 +U 8103 ; WX 952 ; N uni1FA7 ; G 1823 +U 8104 ; WX 931 ; N uni1FA8 ; G 1824 +U 8105 ; WX 963 ; N uni1FA9 ; G 1825 +U 8106 ; WX 1268 ; N uni1FAA ; G 1826 +U 8107 ; WX 1274 ; N uni1FAB ; G 1827 +U 8108 ; WX 1054 ; N uni1FAC ; G 1828 +U 8109 ; WX 1088 ; N uni1FAD ; G 1829 +U 8110 ; WX 1023 ; N uni1FAE ; G 1830 +U 8111 ; WX 1060 ; N uni1FAF ; G 1831 +U 8112 ; WX 770 ; N uni1FB0 ; G 1832 +U 8113 ; WX 770 ; N uni1FB1 ; G 1833 +U 8114 ; WX 770 ; N uni1FB2 ; G 1834 +U 8115 ; WX 770 ; N uni1FB3 ; G 1835 +U 8116 ; WX 770 ; N uni1FB4 ; G 1836 +U 8118 ; WX 770 ; N uni1FB6 ; G 1837 +U 8119 ; WX 770 ; N uni1FB7 ; G 1838 +U 8120 ; WX 776 ; N uni1FB8 ; G 1839 +U 8121 ; WX 776 ; N uni1FB9 ; G 1840 +U 8122 ; WX 811 ; N uni1FBA ; G 1841 +U 8123 ; WX 776 ; N uni1FBB ; G 1842 +U 8124 ; WX 776 ; N uni1FBC ; G 1843 +U 8125 ; WX 500 ; N uni1FBD ; G 1844 +U 8126 ; WX 500 ; N uni1FBE ; G 1845 +U 8127 ; WX 500 ; N uni1FBF ; G 1846 +U 8128 ; WX 500 ; N uni1FC0 ; G 1847 +U 8129 ; WX 500 ; N uni1FC1 ; G 1848 +U 8130 ; WX 727 ; N uni1FC2 ; G 1849 +U 8131 ; WX 727 ; N uni1FC3 ; G 1850 +U 8132 ; WX 727 ; N uni1FC4 ; G 1851 +U 8134 ; WX 727 ; N uni1FC6 ; G 1852 +U 8135 ; WX 727 ; N uni1FC7 ; G 1853 +U 8136 ; WX 1000 ; N uni1FC8 ; G 1854 +U 8137 ; WX 947 ; N uni1FC9 ; G 1855 +U 8138 ; WX 1191 ; N uni1FCA ; G 1856 +U 8139 ; WX 1118 ; N uni1FCB ; G 1857 +U 8140 ; WX 945 ; N uni1FCC ; G 1858 +U 8141 ; WX 500 ; N uni1FCD ; G 1859 +U 8142 ; WX 500 ; N uni1FCE ; G 1860 +U 8143 ; WX 500 ; N uni1FCF ; G 1861 +U 8144 ; WX 484 ; N uni1FD0 ; G 1862 +U 8145 ; WX 484 ; N uni1FD1 ; G 1863 +U 8146 ; WX 484 ; N uni1FD2 ; G 1864 +U 8147 ; WX 484 ; N uni1FD3 ; G 1865 +U 8150 ; WX 484 ; N uni1FD6 ; G 1866 +U 8151 ; WX 484 ; N uni1FD7 ; G 1867 +U 8152 ; WX 468 ; N uni1FD8 ; G 1868 +U 8153 ; WX 468 ; N uni1FD9 ; G 1869 +U 8154 ; WX 714 ; N uni1FDA ; G 1870 +U 8155 ; WX 662 ; N uni1FDB ; G 1871 +U 8157 ; WX 500 ; N uni1FDD ; G 1872 +U 8158 ; WX 500 ; N uni1FDE ; G 1873 +U 8159 ; WX 500 ; N uni1FDF ; G 1874 +U 8160 ; WX 694 ; N uni1FE0 ; G 1875 +U 8161 ; WX 694 ; N uni1FE1 ; G 1876 +U 8162 ; WX 694 ; N uni1FE2 ; G 1877 +U 8163 ; WX 694 ; N uni1FE3 ; G 1878 +U 8164 ; WX 665 ; N uni1FE4 ; G 1879 +U 8165 ; WX 665 ; N uni1FE5 ; G 1880 +U 8166 ; WX 694 ; N uni1FE6 ; G 1881 +U 8167 ; WX 694 ; N uni1FE7 ; G 1882 +U 8168 ; WX 714 ; N uni1FE8 ; G 1883 +U 8169 ; WX 714 ; N uni1FE9 ; G 1884 +U 8170 ; WX 1019 ; N uni1FEA ; G 1885 +U 8171 ; WX 953 ; N uni1FEB ; G 1886 +U 8172 ; WX 910 ; N uni1FEC ; G 1887 +U 8173 ; WX 500 ; N uni1FED ; G 1888 +U 8174 ; WX 500 ; N uni1FEE ; G 1889 +U 8175 ; WX 500 ; N uni1FEF ; G 1890 +U 8178 ; WX 952 ; N uni1FF2 ; G 1891 +U 8179 ; WX 952 ; N uni1FF3 ; G 1892 +U 8180 ; WX 952 ; N uni1FF4 ; G 1893 +U 8182 ; WX 952 ; N uni1FF6 ; G 1894 +U 8183 ; WX 952 ; N uni1FF7 ; G 1895 +U 8184 ; WX 1069 ; N uni1FF8 ; G 1896 +U 8185 ; WX 887 ; N uni1FF9 ; G 1897 +U 8186 ; WX 1101 ; N uni1FFA ; G 1898 +U 8187 ; WX 911 ; N uni1FFB ; G 1899 +U 8188 ; WX 890 ; N uni1FFC ; G 1900 +U 8189 ; WX 500 ; N uni1FFD ; G 1901 +U 8190 ; WX 500 ; N uni1FFE ; G 1902 +U 8192 ; WX 500 ; N uni2000 ; G 1903 +U 8193 ; WX 1000 ; N uni2001 ; G 1904 +U 8194 ; WX 500 ; N uni2002 ; G 1905 +U 8195 ; WX 1000 ; N uni2003 ; G 1906 +U 8196 ; WX 330 ; N uni2004 ; G 1907 +U 8197 ; WX 250 ; N uni2005 ; G 1908 +U 8198 ; WX 167 ; N uni2006 ; G 1909 +U 8199 ; WX 696 ; N uni2007 ; G 1910 +U 8200 ; WX 348 ; N uni2008 ; G 1911 +U 8201 ; WX 200 ; N uni2009 ; G 1912 +U 8202 ; WX 100 ; N uni200A ; G 1913 +U 8203 ; WX 0 ; N uni200B ; G 1914 +U 8204 ; WX 0 ; N uni200C ; G 1915 +U 8205 ; WX 0 ; N uni200D ; G 1916 +U 8206 ; WX 0 ; N uni200E ; G 1917 +U 8207 ; WX 0 ; N uni200F ; G 1918 +U 8208 ; WX 415 ; N uni2010 ; G 1919 +U 8209 ; WX 415 ; N uni2011 ; G 1920 +U 8210 ; WX 696 ; N figuredash ; G 1921 +U 8211 ; WX 500 ; N endash ; G 1922 +U 8212 ; WX 1000 ; N emdash ; G 1923 +U 8213 ; WX 1000 ; N uni2015 ; G 1924 +U 8214 ; WX 500 ; N uni2016 ; G 1925 +U 8215 ; WX 500 ; N underscoredbl ; G 1926 +U 8216 ; WX 348 ; N quoteleft ; G 1927 +U 8217 ; WX 348 ; N quoteright ; G 1928 +U 8218 ; WX 348 ; N quotesinglbase ; G 1929 +U 8219 ; WX 348 ; N quotereversed ; G 1930 +U 8220 ; WX 575 ; N quotedblleft ; G 1931 +U 8221 ; WX 575 ; N quotedblright ; G 1932 +U 8222 ; WX 575 ; N quotedblbase ; G 1933 +U 8223 ; WX 575 ; N uni201F ; G 1934 +U 8224 ; WX 523 ; N dagger ; G 1935 +U 8225 ; WX 523 ; N daggerdbl ; G 1936 +U 8226 ; WX 639 ; N bullet ; G 1937 +U 8227 ; WX 639 ; N uni2023 ; G 1938 +U 8228 ; WX 348 ; N onedotenleader ; G 1939 +U 8229 ; WX 674 ; N twodotenleader ; G 1940 +U 8230 ; WX 1000 ; N ellipsis ; G 1941 +U 8234 ; WX 0 ; N uni202A ; G 1942 +U 8235 ; WX 0 ; N uni202B ; G 1943 +U 8236 ; WX 0 ; N uni202C ; G 1944 +U 8237 ; WX 0 ; N uni202D ; G 1945 +U 8238 ; WX 0 ; N uni202E ; G 1946 +U 8239 ; WX 200 ; N uni202F ; G 1947 +U 8240 ; WX 1385 ; N perthousand ; G 1948 +U 8241 ; WX 1813 ; N uni2031 ; G 1949 +U 8242 ; WX 264 ; N minute ; G 1950 +U 8243 ; WX 447 ; N second ; G 1951 +U 8244 ; WX 630 ; N uni2034 ; G 1952 +U 8245 ; WX 264 ; N uni2035 ; G 1953 +U 8246 ; WX 447 ; N uni2036 ; G 1954 +U 8247 ; WX 630 ; N uni2037 ; G 1955 +U 8248 ; WX 733 ; N uni2038 ; G 1956 +U 8249 ; WX 400 ; N guilsinglleft ; G 1957 +U 8250 ; WX 400 ; N guilsinglright ; G 1958 +U 8252 ; WX 629 ; N exclamdbl ; G 1959 +U 8253 ; WX 586 ; N uni203D ; G 1960 +U 8254 ; WX 500 ; N uni203E ; G 1961 +U 8258 ; WX 1023 ; N uni2042 ; G 1962 +U 8260 ; WX 167 ; N fraction ; G 1963 +U 8261 ; WX 473 ; N uni2045 ; G 1964 +U 8262 ; WX 473 ; N uni2046 ; G 1965 +U 8263 ; WX 1082 ; N uni2047 ; G 1966 +U 8264 ; WX 856 ; N uni2048 ; G 1967 +U 8265 ; WX 856 ; N uni2049 ; G 1968 +U 8267 ; WX 636 ; N uni204B ; G 1969 +U 8268 ; WX 500 ; N uni204C ; G 1970 +U 8269 ; WX 500 ; N uni204D ; G 1971 +U 8270 ; WX 523 ; N uni204E ; G 1972 +U 8271 ; WX 369 ; N uni204F ; G 1973 +U 8273 ; WX 523 ; N uni2051 ; G 1974 +U 8274 ; WX 556 ; N uni2052 ; G 1975 +U 8275 ; WX 1000 ; N uni2053 ; G 1976 +U 8279 ; WX 813 ; N uni2057 ; G 1977 +U 8287 ; WX 222 ; N uni205F ; G 1978 +U 8288 ; WX 0 ; N uni2060 ; G 1979 +U 8289 ; WX 0 ; N uni2061 ; G 1980 +U 8290 ; WX 0 ; N uni2062 ; G 1981 +U 8291 ; WX 0 ; N uni2063 ; G 1982 +U 8292 ; WX 0 ; N uni2064 ; G 1983 +U 8298 ; WX 0 ; N uni206A ; G 1984 +U 8299 ; WX 0 ; N uni206B ; G 1985 +U 8300 ; WX 0 ; N uni206C ; G 1986 +U 8301 ; WX 0 ; N uni206D ; G 1987 +U 8302 ; WX 0 ; N uni206E ; G 1988 +U 8303 ; WX 0 ; N uni206F ; G 1989 +U 8304 ; WX 438 ; N uni2070 ; G 1990 +U 8305 ; WX 239 ; N uni2071 ; G 1991 +U 8308 ; WX 438 ; N uni2074 ; G 1992 +U 8309 ; WX 438 ; N uni2075 ; G 1993 +U 8310 ; WX 438 ; N uni2076 ; G 1994 +U 8311 ; WX 438 ; N uni2077 ; G 1995 +U 8312 ; WX 438 ; N uni2078 ; G 1996 +U 8313 ; WX 438 ; N uni2079 ; G 1997 +U 8314 ; WX 528 ; N uni207A ; G 1998 +U 8315 ; WX 528 ; N uni207B ; G 1999 +U 8316 ; WX 528 ; N uni207C ; G 2000 +U 8317 ; WX 298 ; N uni207D ; G 2001 +U 8318 ; WX 298 ; N uni207E ; G 2002 +U 8319 ; WX 458 ; N uni207F ; G 2003 +U 8320 ; WX 438 ; N uni2080 ; G 2004 +U 8321 ; WX 438 ; N uni2081 ; G 2005 +U 8322 ; WX 438 ; N uni2082 ; G 2006 +U 8323 ; WX 438 ; N uni2083 ; G 2007 +U 8324 ; WX 438 ; N uni2084 ; G 2008 +U 8325 ; WX 438 ; N uni2085 ; G 2009 +U 8326 ; WX 438 ; N uni2086 ; G 2010 +U 8327 ; WX 438 ; N uni2087 ; G 2011 +U 8328 ; WX 438 ; N uni2088 ; G 2012 +U 8329 ; WX 438 ; N uni2089 ; G 2013 +U 8330 ; WX 528 ; N uni208A ; G 2014 +U 8331 ; WX 528 ; N uni208B ; G 2015 +U 8332 ; WX 528 ; N uni208C ; G 2016 +U 8333 ; WX 298 ; N uni208D ; G 2017 +U 8334 ; WX 298 ; N uni208E ; G 2018 +U 8336 ; WX 408 ; N uni2090 ; G 2019 +U 8337 ; WX 444 ; N uni2091 ; G 2020 +U 8338 ; WX 467 ; N uni2092 ; G 2021 +U 8339 ; WX 375 ; N uni2093 ; G 2022 +U 8340 ; WX 444 ; N uni2094 ; G 2023 +U 8341 ; WX 521 ; N uni2095 ; G 2024 +U 8342 ; WX 523 ; N uni2096 ; G 2025 +U 8343 ; WX 292 ; N uni2097 ; G 2026 +U 8344 ; WX 729 ; N uni2098 ; G 2027 +U 8345 ; WX 458 ; N uni2099 ; G 2028 +U 8346 ; WX 499 ; N uni209A ; G 2029 +U 8347 ; WX 395 ; N uni209B ; G 2030 +U 8348 ; WX 371 ; N uni209C ; G 2031 +U 8358 ; WX 696 ; N uni20A6 ; G 2032 +U 8364 ; WX 696 ; N Euro ; G 2033 +U 8367 ; WX 1155 ; N uni20AF ; G 2034 +U 8369 ; WX 790 ; N uni20B1 ; G 2035 +U 8372 ; WX 876 ; N uni20B4 ; G 2036 +U 8373 ; WX 696 ; N uni20B5 ; G 2037 +U 8376 ; WX 696 ; N uni20B8 ; G 2038 +U 8377 ; WX 696 ; N uni20B9 ; G 2039 +U 8378 ; WX 696 ; N uni20BA ; G 2040 +U 8381 ; WX 696 ; N uni20BD ; G 2041 +U 8451 ; WX 1198 ; N uni2103 ; G 2042 +U 8457 ; WX 1112 ; N uni2109 ; G 2043 +U 8462 ; WX 727 ; N uni210E ; G 2044 +U 8463 ; WX 727 ; N uni210F ; G 2045 +U 8470 ; WX 1087 ; N uni2116 ; G 2046 +U 8482 ; WX 1000 ; N trademark ; G 2047 +U 8486 ; WX 890 ; N uni2126 ; G 2048 +U 8487 ; WX 890 ; N uni2127 ; G 2049 +U 8490 ; WX 869 ; N uni212A ; G 2050 +U 8491 ; WX 776 ; N uni212B ; G 2051 +U 8498 ; WX 710 ; N uni2132 ; G 2052 +U 8513 ; WX 786 ; N uni2141 ; G 2053 +U 8514 ; WX 576 ; N uni2142 ; G 2054 +U 8515 ; WX 637 ; N uni2143 ; G 2055 +U 8516 ; WX 760 ; N uni2144 ; G 2056 +U 8523 ; WX 903 ; N uni214B ; G 2057 +U 8526 ; WX 592 ; N uni214E ; G 2058 +U 8528 ; WX 1035 ; N uni2150 ; G 2059 +U 8529 ; WX 1035 ; N uni2151 ; G 2060 +U 8530 ; WX 1473 ; N uni2152 ; G 2061 +U 8531 ; WX 1035 ; N onethird ; G 2062 +U 8532 ; WX 1035 ; N twothirds ; G 2063 +U 8533 ; WX 1035 ; N uni2155 ; G 2064 +U 8534 ; WX 1035 ; N uni2156 ; G 2065 +U 8535 ; WX 1035 ; N uni2157 ; G 2066 +U 8536 ; WX 1035 ; N uni2158 ; G 2067 +U 8537 ; WX 1035 ; N uni2159 ; G 2068 +U 8538 ; WX 1035 ; N uni215A ; G 2069 +U 8539 ; WX 1035 ; N oneeighth ; G 2070 +U 8540 ; WX 1035 ; N threeeighths ; G 2071 +U 8541 ; WX 1035 ; N fiveeighths ; G 2072 +U 8542 ; WX 1035 ; N seveneighths ; G 2073 +U 8543 ; WX 615 ; N uni215F ; G 2074 +U 8544 ; WX 468 ; N uni2160 ; G 2075 +U 8545 ; WX 843 ; N uni2161 ; G 2076 +U 8546 ; WX 1218 ; N uni2162 ; G 2077 +U 8547 ; WX 1135 ; N uni2163 ; G 2078 +U 8548 ; WX 776 ; N uni2164 ; G 2079 +U 8549 ; WX 1150 ; N uni2165 ; G 2080 +U 8550 ; WX 1525 ; N uni2166 ; G 2081 +U 8551 ; WX 1900 ; N uni2167 ; G 2082 +U 8552 ; WX 1126 ; N uni2168 ; G 2083 +U 8553 ; WX 776 ; N uni2169 ; G 2084 +U 8554 ; WX 1127 ; N uni216A ; G 2085 +U 8555 ; WX 1502 ; N uni216B ; G 2086 +U 8556 ; WX 703 ; N uni216C ; G 2087 +U 8557 ; WX 796 ; N uni216D ; G 2088 +U 8558 ; WX 867 ; N uni216E ; G 2089 +U 8559 ; WX 1107 ; N uni216F ; G 2090 +U 8560 ; WX 380 ; N uni2170 ; G 2091 +U 8561 ; WX 760 ; N uni2171 ; G 2092 +U 8562 ; WX 1140 ; N uni2172 ; G 2093 +U 8563 ; WX 961 ; N uni2173 ; G 2094 +U 8564 ; WX 581 ; N uni2174 ; G 2095 +U 8565 ; WX 961 ; N uni2175 ; G 2096 +U 8566 ; WX 1341 ; N uni2176 ; G 2097 +U 8567 ; WX 1721 ; N uni2177 ; G 2098 +U 8568 ; WX 976 ; N uni2178 ; G 2099 +U 8569 ; WX 596 ; N uni2179 ; G 2100 +U 8570 ; WX 976 ; N uni217A ; G 2101 +U 8571 ; WX 1356 ; N uni217B ; G 2102 +U 8572 ; WX 380 ; N uni217C ; G 2103 +U 8573 ; WX 609 ; N uni217D ; G 2104 +U 8574 ; WX 699 ; N uni217E ; G 2105 +U 8575 ; WX 1058 ; N uni217F ; G 2106 +U 8576 ; WX 1255 ; N uni2180 ; G 2107 +U 8577 ; WX 867 ; N uni2181 ; G 2108 +U 8578 ; WX 1268 ; N uni2182 ; G 2109 +U 8579 ; WX 796 ; N uni2183 ; G 2110 +U 8580 ; WX 609 ; N uni2184 ; G 2111 +U 8581 ; WX 796 ; N uni2185 ; G 2112 +U 8585 ; WX 1035 ; N uni2189 ; G 2113 +U 8592 ; WX 838 ; N arrowleft ; G 2114 +U 8593 ; WX 838 ; N arrowup ; G 2115 +U 8594 ; WX 838 ; N arrowright ; G 2116 +U 8595 ; WX 838 ; N arrowdown ; G 2117 +U 8596 ; WX 838 ; N arrowboth ; G 2118 +U 8597 ; WX 838 ; N arrowupdn ; G 2119 +U 8598 ; WX 838 ; N uni2196 ; G 2120 +U 8599 ; WX 838 ; N uni2197 ; G 2121 +U 8600 ; WX 838 ; N uni2198 ; G 2122 +U 8601 ; WX 838 ; N uni2199 ; G 2123 +U 8602 ; WX 838 ; N uni219A ; G 2124 +U 8603 ; WX 838 ; N uni219B ; G 2125 +U 8604 ; WX 838 ; N uni219C ; G 2126 +U 8605 ; WX 838 ; N uni219D ; G 2127 +U 8606 ; WX 838 ; N uni219E ; G 2128 +U 8607 ; WX 838 ; N uni219F ; G 2129 +U 8608 ; WX 838 ; N uni21A0 ; G 2130 +U 8609 ; WX 838 ; N uni21A1 ; G 2131 +U 8610 ; WX 838 ; N uni21A2 ; G 2132 +U 8611 ; WX 838 ; N uni21A3 ; G 2133 +U 8612 ; WX 838 ; N uni21A4 ; G 2134 +U 8613 ; WX 838 ; N uni21A5 ; G 2135 +U 8614 ; WX 838 ; N uni21A6 ; G 2136 +U 8615 ; WX 838 ; N uni21A7 ; G 2137 +U 8616 ; WX 838 ; N arrowupdnbse ; G 2138 +U 8617 ; WX 838 ; N uni21A9 ; G 2139 +U 8618 ; WX 838 ; N uni21AA ; G 2140 +U 8619 ; WX 838 ; N uni21AB ; G 2141 +U 8620 ; WX 838 ; N uni21AC ; G 2142 +U 8621 ; WX 838 ; N uni21AD ; G 2143 +U 8622 ; WX 838 ; N uni21AE ; G 2144 +U 8623 ; WX 850 ; N uni21AF ; G 2145 +U 8624 ; WX 838 ; N uni21B0 ; G 2146 +U 8625 ; WX 838 ; N uni21B1 ; G 2147 +U 8626 ; WX 838 ; N uni21B2 ; G 2148 +U 8627 ; WX 838 ; N uni21B3 ; G 2149 +U 8628 ; WX 838 ; N uni21B4 ; G 2150 +U 8629 ; WX 838 ; N carriagereturn ; G 2151 +U 8630 ; WX 838 ; N uni21B6 ; G 2152 +U 8631 ; WX 838 ; N uni21B7 ; G 2153 +U 8632 ; WX 838 ; N uni21B8 ; G 2154 +U 8633 ; WX 838 ; N uni21B9 ; G 2155 +U 8634 ; WX 838 ; N uni21BA ; G 2156 +U 8635 ; WX 838 ; N uni21BB ; G 2157 +U 8636 ; WX 838 ; N uni21BC ; G 2158 +U 8637 ; WX 838 ; N uni21BD ; G 2159 +U 8638 ; WX 838 ; N uni21BE ; G 2160 +U 8639 ; WX 838 ; N uni21BF ; G 2161 +U 8640 ; WX 838 ; N uni21C0 ; G 2162 +U 8641 ; WX 838 ; N uni21C1 ; G 2163 +U 8642 ; WX 838 ; N uni21C2 ; G 2164 +U 8643 ; WX 838 ; N uni21C3 ; G 2165 +U 8644 ; WX 838 ; N uni21C4 ; G 2166 +U 8645 ; WX 838 ; N uni21C5 ; G 2167 +U 8646 ; WX 838 ; N uni21C6 ; G 2168 +U 8647 ; WX 838 ; N uni21C7 ; G 2169 +U 8648 ; WX 838 ; N uni21C8 ; G 2170 +U 8649 ; WX 838 ; N uni21C9 ; G 2171 +U 8650 ; WX 838 ; N uni21CA ; G 2172 +U 8651 ; WX 838 ; N uni21CB ; G 2173 +U 8652 ; WX 838 ; N uni21CC ; G 2174 +U 8653 ; WX 838 ; N uni21CD ; G 2175 +U 8654 ; WX 838 ; N uni21CE ; G 2176 +U 8655 ; WX 838 ; N uni21CF ; G 2177 +U 8656 ; WX 838 ; N arrowdblleft ; G 2178 +U 8657 ; WX 838 ; N arrowdblup ; G 2179 +U 8658 ; WX 838 ; N arrowdblright ; G 2180 +U 8659 ; WX 838 ; N arrowdbldown ; G 2181 +U 8660 ; WX 838 ; N arrowdblboth ; G 2182 +U 8661 ; WX 838 ; N uni21D5 ; G 2183 +U 8662 ; WX 838 ; N uni21D6 ; G 2184 +U 8663 ; WX 838 ; N uni21D7 ; G 2185 +U 8664 ; WX 838 ; N uni21D8 ; G 2186 +U 8665 ; WX 838 ; N uni21D9 ; G 2187 +U 8666 ; WX 838 ; N uni21DA ; G 2188 +U 8667 ; WX 838 ; N uni21DB ; G 2189 +U 8668 ; WX 838 ; N uni21DC ; G 2190 +U 8669 ; WX 838 ; N uni21DD ; G 2191 +U 8670 ; WX 838 ; N uni21DE ; G 2192 +U 8671 ; WX 838 ; N uni21DF ; G 2193 +U 8672 ; WX 838 ; N uni21E0 ; G 2194 +U 8673 ; WX 838 ; N uni21E1 ; G 2195 +U 8674 ; WX 838 ; N uni21E2 ; G 2196 +U 8675 ; WX 838 ; N uni21E3 ; G 2197 +U 8676 ; WX 838 ; N uni21E4 ; G 2198 +U 8677 ; WX 838 ; N uni21E5 ; G 2199 +U 8678 ; WX 838 ; N uni21E6 ; G 2200 +U 8679 ; WX 838 ; N uni21E7 ; G 2201 +U 8680 ; WX 838 ; N uni21E8 ; G 2202 +U 8681 ; WX 838 ; N uni21E9 ; G 2203 +U 8682 ; WX 838 ; N uni21EA ; G 2204 +U 8683 ; WX 838 ; N uni21EB ; G 2205 +U 8684 ; WX 838 ; N uni21EC ; G 2206 +U 8685 ; WX 838 ; N uni21ED ; G 2207 +U 8686 ; WX 838 ; N uni21EE ; G 2208 +U 8687 ; WX 838 ; N uni21EF ; G 2209 +U 8688 ; WX 838 ; N uni21F0 ; G 2210 +U 8689 ; WX 838 ; N uni21F1 ; G 2211 +U 8690 ; WX 838 ; N uni21F2 ; G 2212 +U 8691 ; WX 838 ; N uni21F3 ; G 2213 +U 8692 ; WX 838 ; N uni21F4 ; G 2214 +U 8693 ; WX 838 ; N uni21F5 ; G 2215 +U 8694 ; WX 838 ; N uni21F6 ; G 2216 +U 8695 ; WX 838 ; N uni21F7 ; G 2217 +U 8696 ; WX 838 ; N uni21F8 ; G 2218 +U 8697 ; WX 838 ; N uni21F9 ; G 2219 +U 8698 ; WX 838 ; N uni21FA ; G 2220 +U 8699 ; WX 838 ; N uni21FB ; G 2221 +U 8700 ; WX 838 ; N uni21FC ; G 2222 +U 8701 ; WX 838 ; N uni21FD ; G 2223 +U 8702 ; WX 838 ; N uni21FE ; G 2224 +U 8703 ; WX 838 ; N uni21FF ; G 2225 +U 8704 ; WX 641 ; N universal ; G 2226 +U 8706 ; WX 534 ; N partialdiff ; G 2227 +U 8707 ; WX 620 ; N existential ; G 2228 +U 8708 ; WX 620 ; N uni2204 ; G 2229 +U 8710 ; WX 753 ; N increment ; G 2230 +U 8711 ; WX 753 ; N gradient ; G 2231 +U 8712 ; WX 740 ; N element ; G 2232 +U 8713 ; WX 740 ; N notelement ; G 2233 +U 8715 ; WX 740 ; N suchthat ; G 2234 +U 8716 ; WX 740 ; N uni220C ; G 2235 +U 8719 ; WX 842 ; N product ; G 2236 +U 8720 ; WX 842 ; N uni2210 ; G 2237 +U 8721 ; WX 753 ; N summation ; G 2238 +U 8722 ; WX 838 ; N minus ; G 2239 +U 8723 ; WX 838 ; N uni2213 ; G 2240 +U 8724 ; WX 838 ; N uni2214 ; G 2241 +U 8725 ; WX 365 ; N uni2215 ; G 2242 +U 8727 ; WX 691 ; N asteriskmath ; G 2243 +U 8728 ; WX 519 ; N uni2218 ; G 2244 +U 8729 ; WX 519 ; N uni2219 ; G 2245 +U 8730 ; WX 657 ; N radical ; G 2246 +U 8731 ; WX 657 ; N uni221B ; G 2247 +U 8732 ; WX 657 ; N uni221C ; G 2248 +U 8733 ; WX 672 ; N proportional ; G 2249 +U 8734 ; WX 833 ; N infinity ; G 2250 +U 8735 ; WX 838 ; N orthogonal ; G 2251 +U 8736 ; WX 838 ; N angle ; G 2252 +U 8739 ; WX 324 ; N uni2223 ; G 2253 +U 8740 ; WX 607 ; N uni2224 ; G 2254 +U 8741 ; WX 529 ; N uni2225 ; G 2255 +U 8742 ; WX 773 ; N uni2226 ; G 2256 +U 8743 ; WX 812 ; N logicaland ; G 2257 +U 8744 ; WX 812 ; N logicalor ; G 2258 +U 8745 ; WX 838 ; N intersection ; G 2259 +U 8746 ; WX 838 ; N union ; G 2260 +U 8747 ; WX 579 ; N integral ; G 2261 +U 8748 ; WX 1000 ; N uni222C ; G 2262 +U 8749 ; WX 1391 ; N uni222D ; G 2263 +U 8760 ; WX 838 ; N uni2238 ; G 2264 +U 8761 ; WX 838 ; N uni2239 ; G 2265 +U 8762 ; WX 838 ; N uni223A ; G 2266 +U 8763 ; WX 838 ; N uni223B ; G 2267 +U 8764 ; WX 838 ; N similar ; G 2268 +U 8765 ; WX 838 ; N uni223D ; G 2269 +U 8770 ; WX 838 ; N uni2242 ; G 2270 +U 8771 ; WX 838 ; N uni2243 ; G 2271 +U 8776 ; WX 838 ; N approxequal ; G 2272 +U 8784 ; WX 838 ; N uni2250 ; G 2273 +U 8785 ; WX 838 ; N uni2251 ; G 2274 +U 8786 ; WX 838 ; N uni2252 ; G 2275 +U 8787 ; WX 838 ; N uni2253 ; G 2276 +U 8788 ; WX 1082 ; N uni2254 ; G 2277 +U 8789 ; WX 1082 ; N uni2255 ; G 2278 +U 8800 ; WX 838 ; N notequal ; G 2279 +U 8801 ; WX 838 ; N equivalence ; G 2280 +U 8804 ; WX 838 ; N lessequal ; G 2281 +U 8805 ; WX 838 ; N greaterequal ; G 2282 +U 8834 ; WX 838 ; N propersubset ; G 2283 +U 8835 ; WX 838 ; N propersuperset ; G 2284 +U 8836 ; WX 838 ; N notsubset ; G 2285 +U 8837 ; WX 838 ; N uni2285 ; G 2286 +U 8838 ; WX 838 ; N reflexsubset ; G 2287 +U 8839 ; WX 838 ; N reflexsuperset ; G 2288 +U 8844 ; WX 838 ; N uni228C ; G 2289 +U 8845 ; WX 838 ; N uni228D ; G 2290 +U 8846 ; WX 838 ; N uni228E ; G 2291 +U 8847 ; WX 838 ; N uni228F ; G 2292 +U 8848 ; WX 838 ; N uni2290 ; G 2293 +U 8849 ; WX 838 ; N uni2291 ; G 2294 +U 8850 ; WX 838 ; N uni2292 ; G 2295 +U 8851 ; WX 838 ; N uni2293 ; G 2296 +U 8852 ; WX 838 ; N uni2294 ; G 2297 +U 8853 ; WX 838 ; N circleplus ; G 2298 +U 8854 ; WX 838 ; N uni2296 ; G 2299 +U 8855 ; WX 838 ; N circlemultiply ; G 2300 +U 8856 ; WX 838 ; N uni2298 ; G 2301 +U 8857 ; WX 838 ; N uni2299 ; G 2302 +U 8858 ; WX 838 ; N uni229A ; G 2303 +U 8859 ; WX 838 ; N uni229B ; G 2304 +U 8860 ; WX 838 ; N uni229C ; G 2305 +U 8861 ; WX 838 ; N uni229D ; G 2306 +U 8862 ; WX 838 ; N uni229E ; G 2307 +U 8863 ; WX 838 ; N uni229F ; G 2308 +U 8864 ; WX 838 ; N uni22A0 ; G 2309 +U 8865 ; WX 838 ; N uni22A1 ; G 2310 +U 8866 ; WX 884 ; N uni22A2 ; G 2311 +U 8867 ; WX 884 ; N uni22A3 ; G 2312 +U 8868 ; WX 960 ; N uni22A4 ; G 2313 +U 8869 ; WX 960 ; N perpendicular ; G 2314 +U 8870 ; WX 616 ; N uni22A6 ; G 2315 +U 8871 ; WX 616 ; N uni22A7 ; G 2316 +U 8872 ; WX 884 ; N uni22A8 ; G 2317 +U 8873 ; WX 884 ; N uni22A9 ; G 2318 +U 8874 ; WX 884 ; N uni22AA ; G 2319 +U 8875 ; WX 1080 ; N uni22AB ; G 2320 +U 8876 ; WX 884 ; N uni22AC ; G 2321 +U 8877 ; WX 884 ; N uni22AD ; G 2322 +U 8878 ; WX 884 ; N uni22AE ; G 2323 +U 8879 ; WX 1080 ; N uni22AF ; G 2324 +U 8900 ; WX 626 ; N uni22C4 ; G 2325 +U 8901 ; WX 398 ; N dotmath ; G 2326 +U 8962 ; WX 834 ; N house ; G 2327 +U 8968 ; WX 473 ; N uni2308 ; G 2328 +U 8969 ; WX 473 ; N uni2309 ; G 2329 +U 8970 ; WX 473 ; N uni230A ; G 2330 +U 8971 ; WX 473 ; N uni230B ; G 2331 +U 8976 ; WX 838 ; N revlogicalnot ; G 2332 +U 8977 ; WX 539 ; N uni2311 ; G 2333 +U 8984 ; WX 928 ; N uni2318 ; G 2334 +U 8985 ; WX 838 ; N uni2319 ; G 2335 +U 8992 ; WX 579 ; N integraltp ; G 2336 +U 8993 ; WX 579 ; N integralbt ; G 2337 +U 8997 ; WX 1000 ; N uni2325 ; G 2338 +U 9000 ; WX 1443 ; N uni2328 ; G 2339 +U 9085 ; WX 1008 ; N uni237D ; G 2340 +U 9115 ; WX 500 ; N uni239B ; G 2341 +U 9116 ; WX 500 ; N uni239C ; G 2342 +U 9117 ; WX 500 ; N uni239D ; G 2343 +U 9118 ; WX 500 ; N uni239E ; G 2344 +U 9119 ; WX 500 ; N uni239F ; G 2345 +U 9120 ; WX 500 ; N uni23A0 ; G 2346 +U 9121 ; WX 500 ; N uni23A1 ; G 2347 +U 9122 ; WX 500 ; N uni23A2 ; G 2348 +U 9123 ; WX 500 ; N uni23A3 ; G 2349 +U 9124 ; WX 500 ; N uni23A4 ; G 2350 +U 9125 ; WX 500 ; N uni23A5 ; G 2351 +U 9126 ; WX 500 ; N uni23A6 ; G 2352 +U 9127 ; WX 750 ; N uni23A7 ; G 2353 +U 9128 ; WX 750 ; N uni23A8 ; G 2354 +U 9129 ; WX 750 ; N uni23A9 ; G 2355 +U 9130 ; WX 750 ; N uni23AA ; G 2356 +U 9131 ; WX 750 ; N uni23AB ; G 2357 +U 9132 ; WX 750 ; N uni23AC ; G 2358 +U 9133 ; WX 750 ; N uni23AD ; G 2359 +U 9134 ; WX 579 ; N uni23AE ; G 2360 +U 9167 ; WX 945 ; N uni23CF ; G 2361 +U 9251 ; WX 834 ; N uni2423 ; G 2362 +U 9472 ; WX 602 ; N SF100000 ; G 2363 +U 9473 ; WX 602 ; N uni2501 ; G 2364 +U 9474 ; WX 602 ; N SF110000 ; G 2365 +U 9475 ; WX 602 ; N uni2503 ; G 2366 +U 9476 ; WX 602 ; N uni2504 ; G 2367 +U 9477 ; WX 602 ; N uni2505 ; G 2368 +U 9478 ; WX 602 ; N uni2506 ; G 2369 +U 9479 ; WX 602 ; N uni2507 ; G 2370 +U 9480 ; WX 602 ; N uni2508 ; G 2371 +U 9481 ; WX 602 ; N uni2509 ; G 2372 +U 9482 ; WX 602 ; N uni250A ; G 2373 +U 9483 ; WX 602 ; N uni250B ; G 2374 +U 9484 ; WX 602 ; N SF010000 ; G 2375 +U 9485 ; WX 602 ; N uni250D ; G 2376 +U 9486 ; WX 602 ; N uni250E ; G 2377 +U 9487 ; WX 602 ; N uni250F ; G 2378 +U 9488 ; WX 602 ; N SF030000 ; G 2379 +U 9489 ; WX 602 ; N uni2511 ; G 2380 +U 9490 ; WX 602 ; N uni2512 ; G 2381 +U 9491 ; WX 602 ; N uni2513 ; G 2382 +U 9492 ; WX 602 ; N SF020000 ; G 2383 +U 9493 ; WX 602 ; N uni2515 ; G 2384 +U 9494 ; WX 602 ; N uni2516 ; G 2385 +U 9495 ; WX 602 ; N uni2517 ; G 2386 +U 9496 ; WX 602 ; N SF040000 ; G 2387 +U 9497 ; WX 602 ; N uni2519 ; G 2388 +U 9498 ; WX 602 ; N uni251A ; G 2389 +U 9499 ; WX 602 ; N uni251B ; G 2390 +U 9500 ; WX 602 ; N SF080000 ; G 2391 +U 9501 ; WX 602 ; N uni251D ; G 2392 +U 9502 ; WX 602 ; N uni251E ; G 2393 +U 9503 ; WX 602 ; N uni251F ; G 2394 +U 9504 ; WX 602 ; N uni2520 ; G 2395 +U 9505 ; WX 602 ; N uni2521 ; G 2396 +U 9506 ; WX 602 ; N uni2522 ; G 2397 +U 9507 ; WX 602 ; N uni2523 ; G 2398 +U 9508 ; WX 602 ; N SF090000 ; G 2399 +U 9509 ; WX 602 ; N uni2525 ; G 2400 +U 9510 ; WX 602 ; N uni2526 ; G 2401 +U 9511 ; WX 602 ; N uni2527 ; G 2402 +U 9512 ; WX 602 ; N uni2528 ; G 2403 +U 9513 ; WX 602 ; N uni2529 ; G 2404 +U 9514 ; WX 602 ; N uni252A ; G 2405 +U 9515 ; WX 602 ; N uni252B ; G 2406 +U 9516 ; WX 602 ; N SF060000 ; G 2407 +U 9517 ; WX 602 ; N uni252D ; G 2408 +U 9518 ; WX 602 ; N uni252E ; G 2409 +U 9519 ; WX 602 ; N uni252F ; G 2410 +U 9520 ; WX 602 ; N uni2530 ; G 2411 +U 9521 ; WX 602 ; N uni2531 ; G 2412 +U 9522 ; WX 602 ; N uni2532 ; G 2413 +U 9523 ; WX 602 ; N uni2533 ; G 2414 +U 9524 ; WX 602 ; N SF070000 ; G 2415 +U 9525 ; WX 602 ; N uni2535 ; G 2416 +U 9526 ; WX 602 ; N uni2536 ; G 2417 +U 9527 ; WX 602 ; N uni2537 ; G 2418 +U 9528 ; WX 602 ; N uni2538 ; G 2419 +U 9529 ; WX 602 ; N uni2539 ; G 2420 +U 9530 ; WX 602 ; N uni253A ; G 2421 +U 9531 ; WX 602 ; N uni253B ; G 2422 +U 9532 ; WX 602 ; N SF050000 ; G 2423 +U 9533 ; WX 602 ; N uni253D ; G 2424 +U 9534 ; WX 602 ; N uni253E ; G 2425 +U 9535 ; WX 602 ; N uni253F ; G 2426 +U 9536 ; WX 602 ; N uni2540 ; G 2427 +U 9537 ; WX 602 ; N uni2541 ; G 2428 +U 9538 ; WX 602 ; N uni2542 ; G 2429 +U 9539 ; WX 602 ; N uni2543 ; G 2430 +U 9540 ; WX 602 ; N uni2544 ; G 2431 +U 9541 ; WX 602 ; N uni2545 ; G 2432 +U 9542 ; WX 602 ; N uni2546 ; G 2433 +U 9543 ; WX 602 ; N uni2547 ; G 2434 +U 9544 ; WX 602 ; N uni2548 ; G 2435 +U 9545 ; WX 602 ; N uni2549 ; G 2436 +U 9546 ; WX 602 ; N uni254A ; G 2437 +U 9547 ; WX 602 ; N uni254B ; G 2438 +U 9548 ; WX 602 ; N uni254C ; G 2439 +U 9549 ; WX 602 ; N uni254D ; G 2440 +U 9550 ; WX 602 ; N uni254E ; G 2441 +U 9551 ; WX 602 ; N uni254F ; G 2442 +U 9552 ; WX 602 ; N SF430000 ; G 2443 +U 9553 ; WX 602 ; N SF240000 ; G 2444 +U 9554 ; WX 602 ; N SF510000 ; G 2445 +U 9555 ; WX 602 ; N SF520000 ; G 2446 +U 9556 ; WX 602 ; N SF390000 ; G 2447 +U 9557 ; WX 602 ; N SF220000 ; G 2448 +U 9558 ; WX 602 ; N SF210000 ; G 2449 +U 9559 ; WX 602 ; N SF250000 ; G 2450 +U 9560 ; WX 602 ; N SF500000 ; G 2451 +U 9561 ; WX 602 ; N SF490000 ; G 2452 +U 9562 ; WX 602 ; N SF380000 ; G 2453 +U 9563 ; WX 602 ; N SF280000 ; G 2454 +U 9564 ; WX 602 ; N SF270000 ; G 2455 +U 9565 ; WX 602 ; N SF260000 ; G 2456 +U 9566 ; WX 602 ; N SF360000 ; G 2457 +U 9567 ; WX 602 ; N SF370000 ; G 2458 +U 9568 ; WX 602 ; N SF420000 ; G 2459 +U 9569 ; WX 602 ; N SF190000 ; G 2460 +U 9570 ; WX 602 ; N SF200000 ; G 2461 +U 9571 ; WX 602 ; N SF230000 ; G 2462 +U 9572 ; WX 602 ; N SF470000 ; G 2463 +U 9573 ; WX 602 ; N SF480000 ; G 2464 +U 9574 ; WX 602 ; N SF410000 ; G 2465 +U 9575 ; WX 602 ; N SF450000 ; G 2466 +U 9576 ; WX 602 ; N SF460000 ; G 2467 +U 9577 ; WX 602 ; N SF400000 ; G 2468 +U 9578 ; WX 602 ; N SF540000 ; G 2469 +U 9579 ; WX 602 ; N SF530000 ; G 2470 +U 9580 ; WX 602 ; N SF440000 ; G 2471 +U 9581 ; WX 602 ; N uni256D ; G 2472 +U 9582 ; WX 602 ; N uni256E ; G 2473 +U 9583 ; WX 602 ; N uni256F ; G 2474 +U 9584 ; WX 602 ; N uni2570 ; G 2475 +U 9585 ; WX 602 ; N uni2571 ; G 2476 +U 9586 ; WX 602 ; N uni2572 ; G 2477 +U 9587 ; WX 602 ; N uni2573 ; G 2478 +U 9588 ; WX 602 ; N uni2574 ; G 2479 +U 9589 ; WX 602 ; N uni2575 ; G 2480 +U 9590 ; WX 602 ; N uni2576 ; G 2481 +U 9591 ; WX 602 ; N uni2577 ; G 2482 +U 9592 ; WX 602 ; N uni2578 ; G 2483 +U 9593 ; WX 602 ; N uni2579 ; G 2484 +U 9594 ; WX 602 ; N uni257A ; G 2485 +U 9595 ; WX 602 ; N uni257B ; G 2486 +U 9596 ; WX 602 ; N uni257C ; G 2487 +U 9597 ; WX 602 ; N uni257D ; G 2488 +U 9598 ; WX 602 ; N uni257E ; G 2489 +U 9599 ; WX 602 ; N uni257F ; G 2490 +U 9600 ; WX 769 ; N upblock ; G 2491 +U 9601 ; WX 769 ; N uni2581 ; G 2492 +U 9602 ; WX 769 ; N uni2582 ; G 2493 +U 9603 ; WX 769 ; N uni2583 ; G 2494 +U 9604 ; WX 769 ; N dnblock ; G 2495 +U 9605 ; WX 769 ; N uni2585 ; G 2496 +U 9606 ; WX 769 ; N uni2586 ; G 2497 +U 9607 ; WX 769 ; N uni2587 ; G 2498 +U 9608 ; WX 769 ; N block ; G 2499 +U 9609 ; WX 769 ; N uni2589 ; G 2500 +U 9610 ; WX 769 ; N uni258A ; G 2501 +U 9611 ; WX 769 ; N uni258B ; G 2502 +U 9612 ; WX 769 ; N lfblock ; G 2503 +U 9613 ; WX 769 ; N uni258D ; G 2504 +U 9614 ; WX 769 ; N uni258E ; G 2505 +U 9615 ; WX 769 ; N uni258F ; G 2506 +U 9616 ; WX 769 ; N rtblock ; G 2507 +U 9617 ; WX 769 ; N ltshade ; G 2508 +U 9618 ; WX 769 ; N shade ; G 2509 +U 9619 ; WX 769 ; N dkshade ; G 2510 +U 9620 ; WX 769 ; N uni2594 ; G 2511 +U 9621 ; WX 769 ; N uni2595 ; G 2512 +U 9622 ; WX 769 ; N uni2596 ; G 2513 +U 9623 ; WX 769 ; N uni2597 ; G 2514 +U 9624 ; WX 769 ; N uni2598 ; G 2515 +U 9625 ; WX 769 ; N uni2599 ; G 2516 +U 9626 ; WX 769 ; N uni259A ; G 2517 +U 9627 ; WX 769 ; N uni259B ; G 2518 +U 9628 ; WX 769 ; N uni259C ; G 2519 +U 9629 ; WX 769 ; N uni259D ; G 2520 +U 9630 ; WX 769 ; N uni259E ; G 2521 +U 9631 ; WX 769 ; N uni259F ; G 2522 +U 9632 ; WX 945 ; N filledbox ; G 2523 +U 9633 ; WX 945 ; N H22073 ; G 2524 +U 9634 ; WX 945 ; N uni25A2 ; G 2525 +U 9635 ; WX 945 ; N uni25A3 ; G 2526 +U 9636 ; WX 945 ; N uni25A4 ; G 2527 +U 9637 ; WX 945 ; N uni25A5 ; G 2528 +U 9638 ; WX 945 ; N uni25A6 ; G 2529 +U 9639 ; WX 945 ; N uni25A7 ; G 2530 +U 9640 ; WX 945 ; N uni25A8 ; G 2531 +U 9641 ; WX 945 ; N uni25A9 ; G 2532 +U 9642 ; WX 678 ; N H18543 ; G 2533 +U 9643 ; WX 678 ; N H18551 ; G 2534 +U 9644 ; WX 945 ; N filledrect ; G 2535 +U 9645 ; WX 945 ; N uni25AD ; G 2536 +U 9646 ; WX 550 ; N uni25AE ; G 2537 +U 9647 ; WX 550 ; N uni25AF ; G 2538 +U 9648 ; WX 769 ; N uni25B0 ; G 2539 +U 9649 ; WX 769 ; N uni25B1 ; G 2540 +U 9650 ; WX 769 ; N triagup ; G 2541 +U 9651 ; WX 769 ; N uni25B3 ; G 2542 +U 9652 ; WX 502 ; N uni25B4 ; G 2543 +U 9653 ; WX 502 ; N uni25B5 ; G 2544 +U 9654 ; WX 769 ; N uni25B6 ; G 2545 +U 9655 ; WX 769 ; N uni25B7 ; G 2546 +U 9656 ; WX 502 ; N uni25B8 ; G 2547 +U 9657 ; WX 502 ; N uni25B9 ; G 2548 +U 9658 ; WX 769 ; N triagrt ; G 2549 +U 9659 ; WX 769 ; N uni25BB ; G 2550 +U 9660 ; WX 769 ; N triagdn ; G 2551 +U 9661 ; WX 769 ; N uni25BD ; G 2552 +U 9662 ; WX 502 ; N uni25BE ; G 2553 +U 9663 ; WX 502 ; N uni25BF ; G 2554 +U 9664 ; WX 769 ; N uni25C0 ; G 2555 +U 9665 ; WX 769 ; N uni25C1 ; G 2556 +U 9666 ; WX 502 ; N uni25C2 ; G 2557 +U 9667 ; WX 502 ; N uni25C3 ; G 2558 +U 9668 ; WX 769 ; N triaglf ; G 2559 +U 9669 ; WX 769 ; N uni25C5 ; G 2560 +U 9670 ; WX 769 ; N uni25C6 ; G 2561 +U 9671 ; WX 769 ; N uni25C7 ; G 2562 +U 9672 ; WX 769 ; N uni25C8 ; G 2563 +U 9673 ; WX 873 ; N uni25C9 ; G 2564 +U 9674 ; WX 494 ; N lozenge ; G 2565 +U 9675 ; WX 873 ; N circle ; G 2566 +U 9676 ; WX 873 ; N uni25CC ; G 2567 +U 9677 ; WX 873 ; N uni25CD ; G 2568 +U 9678 ; WX 873 ; N uni25CE ; G 2569 +U 9679 ; WX 873 ; N H18533 ; G 2570 +U 9680 ; WX 873 ; N uni25D0 ; G 2571 +U 9681 ; WX 873 ; N uni25D1 ; G 2572 +U 9682 ; WX 873 ; N uni25D2 ; G 2573 +U 9683 ; WX 873 ; N uni25D3 ; G 2574 +U 9684 ; WX 873 ; N uni25D4 ; G 2575 +U 9685 ; WX 873 ; N uni25D5 ; G 2576 +U 9686 ; WX 527 ; N uni25D6 ; G 2577 +U 9687 ; WX 527 ; N uni25D7 ; G 2578 +U 9688 ; WX 791 ; N invbullet ; G 2579 +U 9689 ; WX 970 ; N invcircle ; G 2580 +U 9690 ; WX 970 ; N uni25DA ; G 2581 +U 9691 ; WX 970 ; N uni25DB ; G 2582 +U 9692 ; WX 387 ; N uni25DC ; G 2583 +U 9693 ; WX 387 ; N uni25DD ; G 2584 +U 9694 ; WX 387 ; N uni25DE ; G 2585 +U 9695 ; WX 387 ; N uni25DF ; G 2586 +U 9696 ; WX 873 ; N uni25E0 ; G 2587 +U 9697 ; WX 873 ; N uni25E1 ; G 2588 +U 9698 ; WX 769 ; N uni25E2 ; G 2589 +U 9699 ; WX 769 ; N uni25E3 ; G 2590 +U 9700 ; WX 769 ; N uni25E4 ; G 2591 +U 9701 ; WX 769 ; N uni25E5 ; G 2592 +U 9702 ; WX 590 ; N openbullet ; G 2593 +U 9703 ; WX 945 ; N uni25E7 ; G 2594 +U 9704 ; WX 945 ; N uni25E8 ; G 2595 +U 9705 ; WX 945 ; N uni25E9 ; G 2596 +U 9706 ; WX 945 ; N uni25EA ; G 2597 +U 9707 ; WX 945 ; N uni25EB ; G 2598 +U 9708 ; WX 769 ; N uni25EC ; G 2599 +U 9709 ; WX 769 ; N uni25ED ; G 2600 +U 9710 ; WX 769 ; N uni25EE ; G 2601 +U 9711 ; WX 1119 ; N uni25EF ; G 2602 +U 9712 ; WX 945 ; N uni25F0 ; G 2603 +U 9713 ; WX 945 ; N uni25F1 ; G 2604 +U 9714 ; WX 945 ; N uni25F2 ; G 2605 +U 9715 ; WX 945 ; N uni25F3 ; G 2606 +U 9716 ; WX 873 ; N uni25F4 ; G 2607 +U 9717 ; WX 873 ; N uni25F5 ; G 2608 +U 9718 ; WX 873 ; N uni25F6 ; G 2609 +U 9719 ; WX 873 ; N uni25F7 ; G 2610 +U 9720 ; WX 769 ; N uni25F8 ; G 2611 +U 9721 ; WX 769 ; N uni25F9 ; G 2612 +U 9722 ; WX 769 ; N uni25FA ; G 2613 +U 9723 ; WX 830 ; N uni25FB ; G 2614 +U 9724 ; WX 830 ; N uni25FC ; G 2615 +U 9725 ; WX 732 ; N uni25FD ; G 2616 +U 9726 ; WX 732 ; N uni25FE ; G 2617 +U 9727 ; WX 769 ; N uni25FF ; G 2618 +U 9728 ; WX 896 ; N uni2600 ; G 2619 +U 9784 ; WX 896 ; N uni2638 ; G 2620 +U 9785 ; WX 896 ; N uni2639 ; G 2621 +U 9786 ; WX 896 ; N smileface ; G 2622 +U 9787 ; WX 896 ; N invsmileface ; G 2623 +U 9788 ; WX 896 ; N sun ; G 2624 +U 9791 ; WX 614 ; N uni263F ; G 2625 +U 9792 ; WX 731 ; N female ; G 2626 +U 9793 ; WX 731 ; N uni2641 ; G 2627 +U 9794 ; WX 896 ; N male ; G 2628 +U 9795 ; WX 896 ; N uni2643 ; G 2629 +U 9796 ; WX 896 ; N uni2644 ; G 2630 +U 9797 ; WX 896 ; N uni2645 ; G 2631 +U 9798 ; WX 896 ; N uni2646 ; G 2632 +U 9799 ; WX 896 ; N uni2647 ; G 2633 +U 9824 ; WX 896 ; N spade ; G 2634 +U 9825 ; WX 896 ; N uni2661 ; G 2635 +U 9826 ; WX 896 ; N uni2662 ; G 2636 +U 9827 ; WX 896 ; N club ; G 2637 +U 9828 ; WX 896 ; N uni2664 ; G 2638 +U 9829 ; WX 896 ; N heart ; G 2639 +U 9830 ; WX 896 ; N diamond ; G 2640 +U 9831 ; WX 896 ; N uni2667 ; G 2641 +U 9833 ; WX 472 ; N uni2669 ; G 2642 +U 9834 ; WX 638 ; N musicalnote ; G 2643 +U 9835 ; WX 896 ; N musicalnotedbl ; G 2644 +U 9836 ; WX 896 ; N uni266C ; G 2645 +U 9837 ; WX 472 ; N uni266D ; G 2646 +U 9838 ; WX 357 ; N uni266E ; G 2647 +U 9839 ; WX 484 ; N uni266F ; G 2648 +U 10145 ; WX 838 ; N uni27A1 ; G 2649 +U 10181 ; WX 457 ; N uni27C5 ; G 2650 +U 10182 ; WX 457 ; N uni27C6 ; G 2651 +U 10208 ; WX 494 ; N uni27E0 ; G 2652 +U 10216 ; WX 457 ; N uni27E8 ; G 2653 +U 10217 ; WX 457 ; N uni27E9 ; G 2654 +U 10224 ; WX 838 ; N uni27F0 ; G 2655 +U 10225 ; WX 838 ; N uni27F1 ; G 2656 +U 10226 ; WX 838 ; N uni27F2 ; G 2657 +U 10227 ; WX 838 ; N uni27F3 ; G 2658 +U 10228 ; WX 1033 ; N uni27F4 ; G 2659 +U 10229 ; WX 1434 ; N uni27F5 ; G 2660 +U 10230 ; WX 1434 ; N uni27F6 ; G 2661 +U 10231 ; WX 1434 ; N uni27F7 ; G 2662 +U 10232 ; WX 1434 ; N uni27F8 ; G 2663 +U 10233 ; WX 1434 ; N uni27F9 ; G 2664 +U 10234 ; WX 1434 ; N uni27FA ; G 2665 +U 10235 ; WX 1434 ; N uni27FB ; G 2666 +U 10236 ; WX 1434 ; N uni27FC ; G 2667 +U 10237 ; WX 1434 ; N uni27FD ; G 2668 +U 10238 ; WX 1434 ; N uni27FE ; G 2669 +U 10239 ; WX 1434 ; N uni27FF ; G 2670 +U 10240 ; WX 781 ; N uni2800 ; G 2671 +U 10241 ; WX 781 ; N uni2801 ; G 2672 +U 10242 ; WX 781 ; N uni2802 ; G 2673 +U 10243 ; WX 781 ; N uni2803 ; G 2674 +U 10244 ; WX 781 ; N uni2804 ; G 2675 +U 10245 ; WX 781 ; N uni2805 ; G 2676 +U 10246 ; WX 781 ; N uni2806 ; G 2677 +U 10247 ; WX 781 ; N uni2807 ; G 2678 +U 10248 ; WX 781 ; N uni2808 ; G 2679 +U 10249 ; WX 781 ; N uni2809 ; G 2680 +U 10250 ; WX 781 ; N uni280A ; G 2681 +U 10251 ; WX 781 ; N uni280B ; G 2682 +U 10252 ; WX 781 ; N uni280C ; G 2683 +U 10253 ; WX 781 ; N uni280D ; G 2684 +U 10254 ; WX 781 ; N uni280E ; G 2685 +U 10255 ; WX 781 ; N uni280F ; G 2686 +U 10256 ; WX 781 ; N uni2810 ; G 2687 +U 10257 ; WX 781 ; N uni2811 ; G 2688 +U 10258 ; WX 781 ; N uni2812 ; G 2689 +U 10259 ; WX 781 ; N uni2813 ; G 2690 +U 10260 ; WX 781 ; N uni2814 ; G 2691 +U 10261 ; WX 781 ; N uni2815 ; G 2692 +U 10262 ; WX 781 ; N uni2816 ; G 2693 +U 10263 ; WX 781 ; N uni2817 ; G 2694 +U 10264 ; WX 781 ; N uni2818 ; G 2695 +U 10265 ; WX 781 ; N uni2819 ; G 2696 +U 10266 ; WX 781 ; N uni281A ; G 2697 +U 10267 ; WX 781 ; N uni281B ; G 2698 +U 10268 ; WX 781 ; N uni281C ; G 2699 +U 10269 ; WX 781 ; N uni281D ; G 2700 +U 10270 ; WX 781 ; N uni281E ; G 2701 +U 10271 ; WX 781 ; N uni281F ; G 2702 +U 10272 ; WX 781 ; N uni2820 ; G 2703 +U 10273 ; WX 781 ; N uni2821 ; G 2704 +U 10274 ; WX 781 ; N uni2822 ; G 2705 +U 10275 ; WX 781 ; N uni2823 ; G 2706 +U 10276 ; WX 781 ; N uni2824 ; G 2707 +U 10277 ; WX 781 ; N uni2825 ; G 2708 +U 10278 ; WX 781 ; N uni2826 ; G 2709 +U 10279 ; WX 781 ; N uni2827 ; G 2710 +U 10280 ; WX 781 ; N uni2828 ; G 2711 +U 10281 ; WX 781 ; N uni2829 ; G 2712 +U 10282 ; WX 781 ; N uni282A ; G 2713 +U 10283 ; WX 781 ; N uni282B ; G 2714 +U 10284 ; WX 781 ; N uni282C ; G 2715 +U 10285 ; WX 781 ; N uni282D ; G 2716 +U 10286 ; WX 781 ; N uni282E ; G 2717 +U 10287 ; WX 781 ; N uni282F ; G 2718 +U 10288 ; WX 781 ; N uni2830 ; G 2719 +U 10289 ; WX 781 ; N uni2831 ; G 2720 +U 10290 ; WX 781 ; N uni2832 ; G 2721 +U 10291 ; WX 781 ; N uni2833 ; G 2722 +U 10292 ; WX 781 ; N uni2834 ; G 2723 +U 10293 ; WX 781 ; N uni2835 ; G 2724 +U 10294 ; WX 781 ; N uni2836 ; G 2725 +U 10295 ; WX 781 ; N uni2837 ; G 2726 +U 10296 ; WX 781 ; N uni2838 ; G 2727 +U 10297 ; WX 781 ; N uni2839 ; G 2728 +U 10298 ; WX 781 ; N uni283A ; G 2729 +U 10299 ; WX 781 ; N uni283B ; G 2730 +U 10300 ; WX 781 ; N uni283C ; G 2731 +U 10301 ; WX 781 ; N uni283D ; G 2732 +U 10302 ; WX 781 ; N uni283E ; G 2733 +U 10303 ; WX 781 ; N uni283F ; G 2734 +U 10304 ; WX 781 ; N uni2840 ; G 2735 +U 10305 ; WX 781 ; N uni2841 ; G 2736 +U 10306 ; WX 781 ; N uni2842 ; G 2737 +U 10307 ; WX 781 ; N uni2843 ; G 2738 +U 10308 ; WX 781 ; N uni2844 ; G 2739 +U 10309 ; WX 781 ; N uni2845 ; G 2740 +U 10310 ; WX 781 ; N uni2846 ; G 2741 +U 10311 ; WX 781 ; N uni2847 ; G 2742 +U 10312 ; WX 781 ; N uni2848 ; G 2743 +U 10313 ; WX 781 ; N uni2849 ; G 2744 +U 10314 ; WX 781 ; N uni284A ; G 2745 +U 10315 ; WX 781 ; N uni284B ; G 2746 +U 10316 ; WX 781 ; N uni284C ; G 2747 +U 10317 ; WX 781 ; N uni284D ; G 2748 +U 10318 ; WX 781 ; N uni284E ; G 2749 +U 10319 ; WX 781 ; N uni284F ; G 2750 +U 10320 ; WX 781 ; N uni2850 ; G 2751 +U 10321 ; WX 781 ; N uni2851 ; G 2752 +U 10322 ; WX 781 ; N uni2852 ; G 2753 +U 10323 ; WX 781 ; N uni2853 ; G 2754 +U 10324 ; WX 781 ; N uni2854 ; G 2755 +U 10325 ; WX 781 ; N uni2855 ; G 2756 +U 10326 ; WX 781 ; N uni2856 ; G 2757 +U 10327 ; WX 781 ; N uni2857 ; G 2758 +U 10328 ; WX 781 ; N uni2858 ; G 2759 +U 10329 ; WX 781 ; N uni2859 ; G 2760 +U 10330 ; WX 781 ; N uni285A ; G 2761 +U 10331 ; WX 781 ; N uni285B ; G 2762 +U 10332 ; WX 781 ; N uni285C ; G 2763 +U 10333 ; WX 781 ; N uni285D ; G 2764 +U 10334 ; WX 781 ; N uni285E ; G 2765 +U 10335 ; WX 781 ; N uni285F ; G 2766 +U 10336 ; WX 781 ; N uni2860 ; G 2767 +U 10337 ; WX 781 ; N uni2861 ; G 2768 +U 10338 ; WX 781 ; N uni2862 ; G 2769 +U 10339 ; WX 781 ; N uni2863 ; G 2770 +U 10340 ; WX 781 ; N uni2864 ; G 2771 +U 10341 ; WX 781 ; N uni2865 ; G 2772 +U 10342 ; WX 781 ; N uni2866 ; G 2773 +U 10343 ; WX 781 ; N uni2867 ; G 2774 +U 10344 ; WX 781 ; N uni2868 ; G 2775 +U 10345 ; WX 781 ; N uni2869 ; G 2776 +U 10346 ; WX 781 ; N uni286A ; G 2777 +U 10347 ; WX 781 ; N uni286B ; G 2778 +U 10348 ; WX 781 ; N uni286C ; G 2779 +U 10349 ; WX 781 ; N uni286D ; G 2780 +U 10350 ; WX 781 ; N uni286E ; G 2781 +U 10351 ; WX 781 ; N uni286F ; G 2782 +U 10352 ; WX 781 ; N uni2870 ; G 2783 +U 10353 ; WX 781 ; N uni2871 ; G 2784 +U 10354 ; WX 781 ; N uni2872 ; G 2785 +U 10355 ; WX 781 ; N uni2873 ; G 2786 +U 10356 ; WX 781 ; N uni2874 ; G 2787 +U 10357 ; WX 781 ; N uni2875 ; G 2788 +U 10358 ; WX 781 ; N uni2876 ; G 2789 +U 10359 ; WX 781 ; N uni2877 ; G 2790 +U 10360 ; WX 781 ; N uni2878 ; G 2791 +U 10361 ; WX 781 ; N uni2879 ; G 2792 +U 10362 ; WX 781 ; N uni287A ; G 2793 +U 10363 ; WX 781 ; N uni287B ; G 2794 +U 10364 ; WX 781 ; N uni287C ; G 2795 +U 10365 ; WX 781 ; N uni287D ; G 2796 +U 10366 ; WX 781 ; N uni287E ; G 2797 +U 10367 ; WX 781 ; N uni287F ; G 2798 +U 10368 ; WX 781 ; N uni2880 ; G 2799 +U 10369 ; WX 781 ; N uni2881 ; G 2800 +U 10370 ; WX 781 ; N uni2882 ; G 2801 +U 10371 ; WX 781 ; N uni2883 ; G 2802 +U 10372 ; WX 781 ; N uni2884 ; G 2803 +U 10373 ; WX 781 ; N uni2885 ; G 2804 +U 10374 ; WX 781 ; N uni2886 ; G 2805 +U 10375 ; WX 781 ; N uni2887 ; G 2806 +U 10376 ; WX 781 ; N uni2888 ; G 2807 +U 10377 ; WX 781 ; N uni2889 ; G 2808 +U 10378 ; WX 781 ; N uni288A ; G 2809 +U 10379 ; WX 781 ; N uni288B ; G 2810 +U 10380 ; WX 781 ; N uni288C ; G 2811 +U 10381 ; WX 781 ; N uni288D ; G 2812 +U 10382 ; WX 781 ; N uni288E ; G 2813 +U 10383 ; WX 781 ; N uni288F ; G 2814 +U 10384 ; WX 781 ; N uni2890 ; G 2815 +U 10385 ; WX 781 ; N uni2891 ; G 2816 +U 10386 ; WX 781 ; N uni2892 ; G 2817 +U 10387 ; WX 781 ; N uni2893 ; G 2818 +U 10388 ; WX 781 ; N uni2894 ; G 2819 +U 10389 ; WX 781 ; N uni2895 ; G 2820 +U 10390 ; WX 781 ; N uni2896 ; G 2821 +U 10391 ; WX 781 ; N uni2897 ; G 2822 +U 10392 ; WX 781 ; N uni2898 ; G 2823 +U 10393 ; WX 781 ; N uni2899 ; G 2824 +U 10394 ; WX 781 ; N uni289A ; G 2825 +U 10395 ; WX 781 ; N uni289B ; G 2826 +U 10396 ; WX 781 ; N uni289C ; G 2827 +U 10397 ; WX 781 ; N uni289D ; G 2828 +U 10398 ; WX 781 ; N uni289E ; G 2829 +U 10399 ; WX 781 ; N uni289F ; G 2830 +U 10400 ; WX 781 ; N uni28A0 ; G 2831 +U 10401 ; WX 781 ; N uni28A1 ; G 2832 +U 10402 ; WX 781 ; N uni28A2 ; G 2833 +U 10403 ; WX 781 ; N uni28A3 ; G 2834 +U 10404 ; WX 781 ; N uni28A4 ; G 2835 +U 10405 ; WX 781 ; N uni28A5 ; G 2836 +U 10406 ; WX 781 ; N uni28A6 ; G 2837 +U 10407 ; WX 781 ; N uni28A7 ; G 2838 +U 10408 ; WX 781 ; N uni28A8 ; G 2839 +U 10409 ; WX 781 ; N uni28A9 ; G 2840 +U 10410 ; WX 781 ; N uni28AA ; G 2841 +U 10411 ; WX 781 ; N uni28AB ; G 2842 +U 10412 ; WX 781 ; N uni28AC ; G 2843 +U 10413 ; WX 781 ; N uni28AD ; G 2844 +U 10414 ; WX 781 ; N uni28AE ; G 2845 +U 10415 ; WX 781 ; N uni28AF ; G 2846 +U 10416 ; WX 781 ; N uni28B0 ; G 2847 +U 10417 ; WX 781 ; N uni28B1 ; G 2848 +U 10418 ; WX 781 ; N uni28B2 ; G 2849 +U 10419 ; WX 781 ; N uni28B3 ; G 2850 +U 10420 ; WX 781 ; N uni28B4 ; G 2851 +U 10421 ; WX 781 ; N uni28B5 ; G 2852 +U 10422 ; WX 781 ; N uni28B6 ; G 2853 +U 10423 ; WX 781 ; N uni28B7 ; G 2854 +U 10424 ; WX 781 ; N uni28B8 ; G 2855 +U 10425 ; WX 781 ; N uni28B9 ; G 2856 +U 10426 ; WX 781 ; N uni28BA ; G 2857 +U 10427 ; WX 781 ; N uni28BB ; G 2858 +U 10428 ; WX 781 ; N uni28BC ; G 2859 +U 10429 ; WX 781 ; N uni28BD ; G 2860 +U 10430 ; WX 781 ; N uni28BE ; G 2861 +U 10431 ; WX 781 ; N uni28BF ; G 2862 +U 10432 ; WX 781 ; N uni28C0 ; G 2863 +U 10433 ; WX 781 ; N uni28C1 ; G 2864 +U 10434 ; WX 781 ; N uni28C2 ; G 2865 +U 10435 ; WX 781 ; N uni28C3 ; G 2866 +U 10436 ; WX 781 ; N uni28C4 ; G 2867 +U 10437 ; WX 781 ; N uni28C5 ; G 2868 +U 10438 ; WX 781 ; N uni28C6 ; G 2869 +U 10439 ; WX 781 ; N uni28C7 ; G 2870 +U 10440 ; WX 781 ; N uni28C8 ; G 2871 +U 10441 ; WX 781 ; N uni28C9 ; G 2872 +U 10442 ; WX 781 ; N uni28CA ; G 2873 +U 10443 ; WX 781 ; N uni28CB ; G 2874 +U 10444 ; WX 781 ; N uni28CC ; G 2875 +U 10445 ; WX 781 ; N uni28CD ; G 2876 +U 10446 ; WX 781 ; N uni28CE ; G 2877 +U 10447 ; WX 781 ; N uni28CF ; G 2878 +U 10448 ; WX 781 ; N uni28D0 ; G 2879 +U 10449 ; WX 781 ; N uni28D1 ; G 2880 +U 10450 ; WX 781 ; N uni28D2 ; G 2881 +U 10451 ; WX 781 ; N uni28D3 ; G 2882 +U 10452 ; WX 781 ; N uni28D4 ; G 2883 +U 10453 ; WX 781 ; N uni28D5 ; G 2884 +U 10454 ; WX 781 ; N uni28D6 ; G 2885 +U 10455 ; WX 781 ; N uni28D7 ; G 2886 +U 10456 ; WX 781 ; N uni28D8 ; G 2887 +U 10457 ; WX 781 ; N uni28D9 ; G 2888 +U 10458 ; WX 781 ; N uni28DA ; G 2889 +U 10459 ; WX 781 ; N uni28DB ; G 2890 +U 10460 ; WX 781 ; N uni28DC ; G 2891 +U 10461 ; WX 781 ; N uni28DD ; G 2892 +U 10462 ; WX 781 ; N uni28DE ; G 2893 +U 10463 ; WX 781 ; N uni28DF ; G 2894 +U 10464 ; WX 781 ; N uni28E0 ; G 2895 +U 10465 ; WX 781 ; N uni28E1 ; G 2896 +U 10466 ; WX 781 ; N uni28E2 ; G 2897 +U 10467 ; WX 781 ; N uni28E3 ; G 2898 +U 10468 ; WX 781 ; N uni28E4 ; G 2899 +U 10469 ; WX 781 ; N uni28E5 ; G 2900 +U 10470 ; WX 781 ; N uni28E6 ; G 2901 +U 10471 ; WX 781 ; N uni28E7 ; G 2902 +U 10472 ; WX 781 ; N uni28E8 ; G 2903 +U 10473 ; WX 781 ; N uni28E9 ; G 2904 +U 10474 ; WX 781 ; N uni28EA ; G 2905 +U 10475 ; WX 781 ; N uni28EB ; G 2906 +U 10476 ; WX 781 ; N uni28EC ; G 2907 +U 10477 ; WX 781 ; N uni28ED ; G 2908 +U 10478 ; WX 781 ; N uni28EE ; G 2909 +U 10479 ; WX 781 ; N uni28EF ; G 2910 +U 10480 ; WX 781 ; N uni28F0 ; G 2911 +U 10481 ; WX 781 ; N uni28F1 ; G 2912 +U 10482 ; WX 781 ; N uni28F2 ; G 2913 +U 10483 ; WX 781 ; N uni28F3 ; G 2914 +U 10484 ; WX 781 ; N uni28F4 ; G 2915 +U 10485 ; WX 781 ; N uni28F5 ; G 2916 +U 10486 ; WX 781 ; N uni28F6 ; G 2917 +U 10487 ; WX 781 ; N uni28F7 ; G 2918 +U 10488 ; WX 781 ; N uni28F8 ; G 2919 +U 10489 ; WX 781 ; N uni28F9 ; G 2920 +U 10490 ; WX 781 ; N uni28FA ; G 2921 +U 10491 ; WX 781 ; N uni28FB ; G 2922 +U 10492 ; WX 781 ; N uni28FC ; G 2923 +U 10493 ; WX 781 ; N uni28FD ; G 2924 +U 10494 ; WX 781 ; N uni28FE ; G 2925 +U 10495 ; WX 781 ; N uni28FF ; G 2926 +U 10496 ; WX 838 ; N uni2900 ; G 2927 +U 10497 ; WX 838 ; N uni2901 ; G 2928 +U 10498 ; WX 838 ; N uni2902 ; G 2929 +U 10499 ; WX 838 ; N uni2903 ; G 2930 +U 10500 ; WX 838 ; N uni2904 ; G 2931 +U 10501 ; WX 838 ; N uni2905 ; G 2932 +U 10502 ; WX 838 ; N uni2906 ; G 2933 +U 10503 ; WX 838 ; N uni2907 ; G 2934 +U 10504 ; WX 838 ; N uni2908 ; G 2935 +U 10505 ; WX 838 ; N uni2909 ; G 2936 +U 10506 ; WX 838 ; N uni290A ; G 2937 +U 10507 ; WX 838 ; N uni290B ; G 2938 +U 10508 ; WX 838 ; N uni290C ; G 2939 +U 10509 ; WX 838 ; N uni290D ; G 2940 +U 10510 ; WX 838 ; N uni290E ; G 2941 +U 10511 ; WX 838 ; N uni290F ; G 2942 +U 10512 ; WX 838 ; N uni2910 ; G 2943 +U 10513 ; WX 838 ; N uni2911 ; G 2944 +U 10514 ; WX 838 ; N uni2912 ; G 2945 +U 10515 ; WX 838 ; N uni2913 ; G 2946 +U 10516 ; WX 838 ; N uni2914 ; G 2947 +U 10517 ; WX 838 ; N uni2915 ; G 2948 +U 10518 ; WX 838 ; N uni2916 ; G 2949 +U 10519 ; WX 838 ; N uni2917 ; G 2950 +U 10520 ; WX 838 ; N uni2918 ; G 2951 +U 10521 ; WX 838 ; N uni2919 ; G 2952 +U 10522 ; WX 838 ; N uni291A ; G 2953 +U 10523 ; WX 838 ; N uni291B ; G 2954 +U 10524 ; WX 838 ; N uni291C ; G 2955 +U 10525 ; WX 838 ; N uni291D ; G 2956 +U 10526 ; WX 838 ; N uni291E ; G 2957 +U 10527 ; WX 838 ; N uni291F ; G 2958 +U 10528 ; WX 838 ; N uni2920 ; G 2959 +U 10529 ; WX 838 ; N uni2921 ; G 2960 +U 10530 ; WX 838 ; N uni2922 ; G 2961 +U 10531 ; WX 838 ; N uni2923 ; G 2962 +U 10532 ; WX 838 ; N uni2924 ; G 2963 +U 10533 ; WX 838 ; N uni2925 ; G 2964 +U 10534 ; WX 838 ; N uni2926 ; G 2965 +U 10535 ; WX 838 ; N uni2927 ; G 2966 +U 10536 ; WX 838 ; N uni2928 ; G 2967 +U 10537 ; WX 838 ; N uni2929 ; G 2968 +U 10538 ; WX 838 ; N uni292A ; G 2969 +U 10539 ; WX 838 ; N uni292B ; G 2970 +U 10540 ; WX 838 ; N uni292C ; G 2971 +U 10541 ; WX 838 ; N uni292D ; G 2972 +U 10542 ; WX 838 ; N uni292E ; G 2973 +U 10543 ; WX 838 ; N uni292F ; G 2974 +U 10544 ; WX 838 ; N uni2930 ; G 2975 +U 10545 ; WX 838 ; N uni2931 ; G 2976 +U 10546 ; WX 838 ; N uni2932 ; G 2977 +U 10547 ; WX 838 ; N uni2933 ; G 2978 +U 10548 ; WX 838 ; N uni2934 ; G 2979 +U 10549 ; WX 838 ; N uni2935 ; G 2980 +U 10550 ; WX 838 ; N uni2936 ; G 2981 +U 10551 ; WX 838 ; N uni2937 ; G 2982 +U 10552 ; WX 838 ; N uni2938 ; G 2983 +U 10553 ; WX 838 ; N uni2939 ; G 2984 +U 10554 ; WX 838 ; N uni293A ; G 2985 +U 10555 ; WX 838 ; N uni293B ; G 2986 +U 10556 ; WX 838 ; N uni293C ; G 2987 +U 10557 ; WX 838 ; N uni293D ; G 2988 +U 10558 ; WX 838 ; N uni293E ; G 2989 +U 10559 ; WX 838 ; N uni293F ; G 2990 +U 10560 ; WX 838 ; N uni2940 ; G 2991 +U 10561 ; WX 838 ; N uni2941 ; G 2992 +U 10562 ; WX 838 ; N uni2942 ; G 2993 +U 10563 ; WX 838 ; N uni2943 ; G 2994 +U 10564 ; WX 838 ; N uni2944 ; G 2995 +U 10565 ; WX 838 ; N uni2945 ; G 2996 +U 10566 ; WX 838 ; N uni2946 ; G 2997 +U 10567 ; WX 838 ; N uni2947 ; G 2998 +U 10568 ; WX 838 ; N uni2948 ; G 2999 +U 10569 ; WX 838 ; N uni2949 ; G 3000 +U 10570 ; WX 838 ; N uni294A ; G 3001 +U 10571 ; WX 838 ; N uni294B ; G 3002 +U 10572 ; WX 838 ; N uni294C ; G 3003 +U 10573 ; WX 838 ; N uni294D ; G 3004 +U 10574 ; WX 838 ; N uni294E ; G 3005 +U 10575 ; WX 838 ; N uni294F ; G 3006 +U 10576 ; WX 838 ; N uni2950 ; G 3007 +U 10577 ; WX 838 ; N uni2951 ; G 3008 +U 10578 ; WX 838 ; N uni2952 ; G 3009 +U 10579 ; WX 838 ; N uni2953 ; G 3010 +U 10580 ; WX 838 ; N uni2954 ; G 3011 +U 10581 ; WX 838 ; N uni2955 ; G 3012 +U 10582 ; WX 838 ; N uni2956 ; G 3013 +U 10583 ; WX 838 ; N uni2957 ; G 3014 +U 10584 ; WX 838 ; N uni2958 ; G 3015 +U 10585 ; WX 838 ; N uni2959 ; G 3016 +U 10586 ; WX 838 ; N uni295A ; G 3017 +U 10587 ; WX 838 ; N uni295B ; G 3018 +U 10588 ; WX 838 ; N uni295C ; G 3019 +U 10589 ; WX 838 ; N uni295D ; G 3020 +U 10590 ; WX 838 ; N uni295E ; G 3021 +U 10591 ; WX 838 ; N uni295F ; G 3022 +U 10592 ; WX 838 ; N uni2960 ; G 3023 +U 10593 ; WX 838 ; N uni2961 ; G 3024 +U 10594 ; WX 838 ; N uni2962 ; G 3025 +U 10595 ; WX 838 ; N uni2963 ; G 3026 +U 10596 ; WX 838 ; N uni2964 ; G 3027 +U 10597 ; WX 838 ; N uni2965 ; G 3028 +U 10598 ; WX 838 ; N uni2966 ; G 3029 +U 10599 ; WX 838 ; N uni2967 ; G 3030 +U 10600 ; WX 838 ; N uni2968 ; G 3031 +U 10601 ; WX 838 ; N uni2969 ; G 3032 +U 10602 ; WX 838 ; N uni296A ; G 3033 +U 10603 ; WX 838 ; N uni296B ; G 3034 +U 10604 ; WX 838 ; N uni296C ; G 3035 +U 10605 ; WX 838 ; N uni296D ; G 3036 +U 10606 ; WX 838 ; N uni296E ; G 3037 +U 10607 ; WX 838 ; N uni296F ; G 3038 +U 10608 ; WX 838 ; N uni2970 ; G 3039 +U 10609 ; WX 838 ; N uni2971 ; G 3040 +U 10610 ; WX 838 ; N uni2972 ; G 3041 +U 10611 ; WX 838 ; N uni2973 ; G 3042 +U 10612 ; WX 838 ; N uni2974 ; G 3043 +U 10613 ; WX 838 ; N uni2975 ; G 3044 +U 10614 ; WX 838 ; N uni2976 ; G 3045 +U 10615 ; WX 1032 ; N uni2977 ; G 3046 +U 10616 ; WX 838 ; N uni2978 ; G 3047 +U 10617 ; WX 838 ; N uni2979 ; G 3048 +U 10618 ; WX 960 ; N uni297A ; G 3049 +U 10619 ; WX 838 ; N uni297B ; G 3050 +U 10620 ; WX 838 ; N uni297C ; G 3051 +U 10621 ; WX 838 ; N uni297D ; G 3052 +U 10622 ; WX 838 ; N uni297E ; G 3053 +U 10623 ; WX 838 ; N uni297F ; G 3054 +U 10731 ; WX 494 ; N uni29EB ; G 3055 +U 10764 ; WX 1782 ; N uni2A0C ; G 3056 +U 10765 ; WX 610 ; N uni2A0D ; G 3057 +U 10766 ; WX 610 ; N uni2A0E ; G 3058 +U 10799 ; WX 838 ; N uni2A2F ; G 3059 +U 10858 ; WX 838 ; N uni2A6A ; G 3060 +U 10859 ; WX 838 ; N uni2A6B ; G 3061 +U 11008 ; WX 838 ; N uni2B00 ; G 3062 +U 11009 ; WX 838 ; N uni2B01 ; G 3063 +U 11010 ; WX 838 ; N uni2B02 ; G 3064 +U 11011 ; WX 838 ; N uni2B03 ; G 3065 +U 11012 ; WX 838 ; N uni2B04 ; G 3066 +U 11013 ; WX 838 ; N uni2B05 ; G 3067 +U 11014 ; WX 838 ; N uni2B06 ; G 3068 +U 11015 ; WX 838 ; N uni2B07 ; G 3069 +U 11016 ; WX 838 ; N uni2B08 ; G 3070 +U 11017 ; WX 838 ; N uni2B09 ; G 3071 +U 11018 ; WX 838 ; N uni2B0A ; G 3072 +U 11019 ; WX 838 ; N uni2B0B ; G 3073 +U 11020 ; WX 838 ; N uni2B0C ; G 3074 +U 11021 ; WX 838 ; N uni2B0D ; G 3075 +U 11022 ; WX 838 ; N uni2B0E ; G 3076 +U 11023 ; WX 838 ; N uni2B0F ; G 3077 +U 11024 ; WX 838 ; N uni2B10 ; G 3078 +U 11025 ; WX 838 ; N uni2B11 ; G 3079 +U 11026 ; WX 945 ; N uni2B12 ; G 3080 +U 11027 ; WX 945 ; N uni2B13 ; G 3081 +U 11028 ; WX 945 ; N uni2B14 ; G 3082 +U 11029 ; WX 945 ; N uni2B15 ; G 3083 +U 11030 ; WX 769 ; N uni2B16 ; G 3084 +U 11031 ; WX 769 ; N uni2B17 ; G 3085 +U 11032 ; WX 769 ; N uni2B18 ; G 3086 +U 11033 ; WX 769 ; N uni2B19 ; G 3087 +U 11034 ; WX 945 ; N uni2B1A ; G 3088 +U 11360 ; WX 703 ; N uni2C60 ; G 3089 +U 11361 ; WX 380 ; N uni2C61 ; G 3090 +U 11363 ; WX 752 ; N uni2C63 ; G 3091 +U 11364 ; WX 831 ; N uni2C64 ; G 3092 +U 11367 ; WX 945 ; N uni2C67 ; G 3093 +U 11368 ; WX 727 ; N uni2C68 ; G 3094 +U 11369 ; WX 869 ; N uni2C69 ; G 3095 +U 11370 ; WX 693 ; N uni2C6A ; G 3096 +U 11371 ; WX 730 ; N uni2C6B ; G 3097 +U 11372 ; WX 568 ; N uni2C6C ; G 3098 +U 11373 ; WX 848 ; N uni2C6D ; G 3099 +U 11374 ; WX 1107 ; N uni2C6E ; G 3100 +U 11375 ; WX 776 ; N uni2C6F ; G 3101 +U 11376 ; WX 848 ; N uni2C70 ; G 3102 +U 11377 ; WX 709 ; N uni2C71 ; G 3103 +U 11378 ; WX 1221 ; N uni2C72 ; G 3104 +U 11379 ; WX 984 ; N uni2C73 ; G 3105 +U 11381 ; WX 779 ; N uni2C75 ; G 3106 +U 11382 ; WX 576 ; N uni2C76 ; G 3107 +U 11383 ; WX 905 ; N uni2C77 ; G 3108 +U 11385 ; WX 571 ; N uni2C79 ; G 3109 +U 11386 ; WX 667 ; N uni2C7A ; G 3110 +U 11387 ; WX 617 ; N uni2C7B ; G 3111 +U 11388 ; WX 313 ; N uni2C7C ; G 3112 +U 11389 ; WX 489 ; N uni2C7D ; G 3113 +U 11390 ; WX 722 ; N uni2C7E ; G 3114 +U 11391 ; WX 730 ; N uni2C7F ; G 3115 +U 11520 ; WX 773 ; N uni2D00 ; G 3116 +U 11521 ; WX 635 ; N uni2D01 ; G 3117 +U 11522 ; WX 804 ; N uni2D02 ; G 3118 +U 11523 ; WX 658 ; N uni2D03 ; G 3119 +U 11524 ; WX 788 ; N uni2D04 ; G 3120 +U 11525 ; WX 962 ; N uni2D05 ; G 3121 +U 11526 ; WX 756 ; N uni2D06 ; G 3122 +U 11527 ; WX 960 ; N uni2D07 ; G 3123 +U 11528 ; WX 617 ; N uni2D08 ; G 3124 +U 11529 ; WX 646 ; N uni2D09 ; G 3125 +U 11530 ; WX 962 ; N uni2D0A ; G 3126 +U 11531 ; WX 631 ; N uni2D0B ; G 3127 +U 11532 ; WX 646 ; N uni2D0C ; G 3128 +U 11533 ; WX 962 ; N uni2D0D ; G 3129 +U 11534 ; WX 846 ; N uni2D0E ; G 3130 +U 11535 ; WX 866 ; N uni2D0F ; G 3131 +U 11536 ; WX 961 ; N uni2D10 ; G 3132 +U 11537 ; WX 645 ; N uni2D11 ; G 3133 +U 11538 ; WX 645 ; N uni2D12 ; G 3134 +U 11539 ; WX 959 ; N uni2D13 ; G 3135 +U 11540 ; WX 945 ; N uni2D14 ; G 3136 +U 11541 ; WX 863 ; N uni2D15 ; G 3137 +U 11542 ; WX 644 ; N uni2D16 ; G 3138 +U 11543 ; WX 646 ; N uni2D17 ; G 3139 +U 11544 ; WX 645 ; N uni2D18 ; G 3140 +U 11545 ; WX 649 ; N uni2D19 ; G 3141 +U 11546 ; WX 688 ; N uni2D1A ; G 3142 +U 11547 ; WX 936 ; N uni2D1B ; G 3143 +U 11548 ; WX 982 ; N uni2D1C ; G 3144 +U 11549 ; WX 681 ; N uni2D1D ; G 3145 +U 11550 ; WX 676 ; N uni2D1E ; G 3146 +U 11551 ; WX 852 ; N uni2D1F ; G 3147 +U 11552 ; WX 1113 ; N uni2D20 ; G 3148 +U 11553 ; WX 632 ; N uni2D21 ; G 3149 +U 11554 ; WX 645 ; N uni2D22 ; G 3150 +U 11555 ; WX 646 ; N uni2D23 ; G 3151 +U 11556 ; WX 749 ; N uni2D24 ; G 3152 +U 11557 ; WX 914 ; N uni2D25 ; G 3153 +U 11800 ; WX 586 ; N uni2E18 ; G 3154 +U 11807 ; WX 838 ; N uni2E1F ; G 3155 +U 11810 ; WX 473 ; N uni2E22 ; G 3156 +U 11811 ; WX 473 ; N uni2E23 ; G 3157 +U 11812 ; WX 473 ; N uni2E24 ; G 3158 +U 11813 ; WX 473 ; N uni2E25 ; G 3159 +U 11822 ; WX 586 ; N uni2E2E ; G 3160 +U 42564 ; WX 722 ; N uniA644 ; G 3161 +U 42565 ; WX 563 ; N uniA645 ; G 3162 +U 42566 ; WX 468 ; N uniA646 ; G 3163 +U 42567 ; WX 380 ; N uniA647 ; G 3164 +U 42576 ; WX 1333 ; N uniA650 ; G 3165 +U 42577 ; WX 1085 ; N uniA651 ; G 3166 +U 42580 ; WX 1287 ; N uniA654 ; G 3167 +U 42581 ; WX 1025 ; N uniA655 ; G 3168 +U 42582 ; WX 1287 ; N uniA656 ; G 3169 +U 42583 ; WX 1029 ; N uniA657 ; G 3170 +U 42648 ; WX 1448 ; N uniA698 ; G 3171 +U 42649 ; WX 1060 ; N uniA699 ; G 3172 +U 42760 ; WX 500 ; N uniA708 ; G 3173 +U 42761 ; WX 500 ; N uniA709 ; G 3174 +U 42762 ; WX 500 ; N uniA70A ; G 3175 +U 42763 ; WX 500 ; N uniA70B ; G 3176 +U 42764 ; WX 500 ; N uniA70C ; G 3177 +U 42765 ; WX 500 ; N uniA70D ; G 3178 +U 42766 ; WX 500 ; N uniA70E ; G 3179 +U 42767 ; WX 500 ; N uniA70F ; G 3180 +U 42768 ; WX 500 ; N uniA710 ; G 3181 +U 42769 ; WX 500 ; N uniA711 ; G 3182 +U 42770 ; WX 500 ; N uniA712 ; G 3183 +U 42771 ; WX 500 ; N uniA713 ; G 3184 +U 42772 ; WX 500 ; N uniA714 ; G 3185 +U 42773 ; WX 500 ; N uniA715 ; G 3186 +U 42774 ; WX 500 ; N uniA716 ; G 3187 +U 42779 ; WX 384 ; N uniA71B ; G 3188 +U 42780 ; WX 384 ; N uniA71C ; G 3189 +U 42781 ; WX 276 ; N uniA71D ; G 3190 +U 42782 ; WX 276 ; N uniA71E ; G 3191 +U 42783 ; WX 276 ; N uniA71F ; G 3192 +U 42790 ; WX 945 ; N uniA726 ; G 3193 +U 42791 ; WX 712 ; N uniA727 ; G 3194 +U 42792 ; WX 1003 ; N uniA728 ; G 3195 +U 42793 ; WX 909 ; N uniA729 ; G 3196 +U 42794 ; WX 696 ; N uniA72A ; G 3197 +U 42795 ; WX 609 ; N uniA72B ; G 3198 +U 42796 ; WX 634 ; N uniA72C ; G 3199 +U 42797 ; WX 598 ; N uniA72D ; G 3200 +U 42798 ; WX 741 ; N uniA72E ; G 3201 +U 42799 ; WX 706 ; N uniA72F ; G 3202 +U 42800 ; WX 592 ; N uniA730 ; G 3203 +U 42801 ; WX 563 ; N uniA731 ; G 3204 +U 42802 ; WX 1301 ; N uniA732 ; G 3205 +U 42803 ; WX 983 ; N uniA733 ; G 3206 +U 42804 ; WX 1261 ; N uniA734 ; G 3207 +U 42805 ; WX 985 ; N uniA735 ; G 3208 +U 42806 ; WX 1168 ; N uniA736 ; G 3209 +U 42807 ; WX 1007 ; N uniA737 ; G 3210 +U 42808 ; WX 1016 ; N uniA738 ; G 3211 +U 42809 ; WX 832 ; N uniA739 ; G 3212 +U 42810 ; WX 1016 ; N uniA73A ; G 3213 +U 42811 ; WX 832 ; N uniA73B ; G 3214 +U 42812 ; WX 994 ; N uniA73C ; G 3215 +U 42813 ; WX 746 ; N uniA73D ; G 3216 +U 42814 ; WX 796 ; N uniA73E ; G 3217 +U 42815 ; WX 609 ; N uniA73F ; G 3218 +U 42816 ; WX 869 ; N uniA740 ; G 3219 +U 42817 ; WX 693 ; N uniA741 ; G 3220 +U 42822 ; WX 916 ; N uniA746 ; G 3221 +U 42823 ; WX 581 ; N uniA747 ; G 3222 +U 42826 ; WX 1010 ; N uniA74A ; G 3223 +U 42827 ; WX 770 ; N uniA74B ; G 3224 +U 42830 ; WX 1448 ; N uniA74E ; G 3225 +U 42831 ; WX 1060 ; N uniA74F ; G 3226 +U 42856 ; WX 787 ; N uniA768 ; G 3227 +U 42857 ; WX 716 ; N uniA769 ; G 3228 +U 42875 ; WX 694 ; N uniA77B ; G 3229 +U 42876 ; WX 527 ; N uniA77C ; G 3230 +U 42880 ; WX 703 ; N uniA780 ; G 3231 +U 42881 ; WX 380 ; N uniA781 ; G 3232 +U 42882 ; WX 872 ; N uniA782 ; G 3233 +U 42883 ; WX 727 ; N uniA783 ; G 3234 +U 42884 ; WX 694 ; N uniA784 ; G 3235 +U 42885 ; WX 527 ; N uniA785 ; G 3236 +U 42886 ; WX 796 ; N uniA786 ; G 3237 +U 42887 ; WX 609 ; N uniA787 ; G 3238 +U 42891 ; WX 439 ; N uniA78B ; G 3239 +U 42892 ; WX 306 ; N uniA78C ; G 3240 +U 42893 ; WX 913 ; N uniA78D ; G 3241 +U 42896 ; WX 914 ; N uniA790 ; G 3242 +U 42897 ; WX 812 ; N uniA791 ; G 3243 +U 42922 ; WX 945 ; N uniA7AA ; G 3244 +U 43000 ; WX 595 ; N uniA7F8 ; G 3245 +U 43001 ; WX 647 ; N uniA7F9 ; G 3246 +U 43002 ; WX 1068 ; N uniA7FA ; G 3247 +U 43003 ; WX 710 ; N uniA7FB ; G 3248 +U 43004 ; WX 752 ; N uniA7FC ; G 3249 +U 43005 ; WX 1107 ; N uniA7FD ; G 3250 +U 43006 ; WX 468 ; N uniA7FE ; G 3251 +U 43007 ; WX 1286 ; N uniA7FF ; G 3252 +U 62464 ; WX 726 ; N uniF400 ; G 3253 +U 62465 ; WX 737 ; N uniF401 ; G 3254 +U 62466 ; WX 786 ; N uniF402 ; G 3255 +U 62467 ; WX 1019 ; N uniF403 ; G 3256 +U 62468 ; WX 737 ; N uniF404 ; G 3257 +U 62469 ; WX 731 ; N uniF405 ; G 3258 +U 62470 ; WX 796 ; N uniF406 ; G 3259 +U 62471 ; WX 1058 ; N uniF407 ; G 3260 +U 62472 ; WX 737 ; N uniF408 ; G 3261 +U 62473 ; WX 737 ; N uniF409 ; G 3262 +U 62474 ; WX 1329 ; N uniF40A ; G 3263 +U 62475 ; WX 754 ; N uniF40B ; G 3264 +U 62476 ; WX 753 ; N uniF40C ; G 3265 +U 62477 ; WX 1024 ; N uniF40D ; G 3266 +U 62478 ; WX 737 ; N uniF40E ; G 3267 +U 62479 ; WX 753 ; N uniF40F ; G 3268 +U 62480 ; WX 1070 ; N uniF410 ; G 3269 +U 62481 ; WX 818 ; N uniF411 ; G 3270 +U 62482 ; WX 870 ; N uniF412 ; G 3271 +U 62483 ; WX 819 ; N uniF413 ; G 3272 +U 62484 ; WX 1016 ; N uniF414 ; G 3273 +U 62485 ; WX 753 ; N uniF415 ; G 3274 +U 62486 ; WX 1008 ; N uniF416 ; G 3275 +U 62487 ; WX 752 ; N uniF417 ; G 3276 +U 62488 ; WX 760 ; N uniF418 ; G 3277 +U 62489 ; WX 753 ; N uniF419 ; G 3278 +U 62490 ; WX 800 ; N uniF41A ; G 3279 +U 62491 ; WX 753 ; N uniF41B ; G 3280 +U 62492 ; WX 760 ; N uniF41C ; G 3281 +U 62493 ; WX 738 ; N uniF41D ; G 3282 +U 62494 ; WX 801 ; N uniF41E ; G 3283 +U 62495 ; WX 956 ; N uniF41F ; G 3284 +U 62496 ; WX 736 ; N uniF420 ; G 3285 +U 62497 ; WX 847 ; N uniF421 ; G 3286 +U 62498 ; WX 737 ; N uniF422 ; G 3287 +U 62499 ; WX 737 ; N uniF423 ; G 3288 +U 62500 ; WX 737 ; N uniF424 ; G 3289 +U 62501 ; WX 793 ; N uniF425 ; G 3290 +U 62502 ; WX 1033 ; N uniF426 ; G 3291 +U 62504 ; WX 904 ; N uniF428 ; G 3292 +U 63172 ; WX 380 ; N uniF6C4 ; G 3293 +U 63173 ; WX 667 ; N uniF6C5 ; G 3294 +U 63174 ; WX 699 ; N uniF6C6 ; G 3295 +U 63175 ; WX 727 ; N uniF6C7 ; G 3296 +U 63176 ; WX 1058 ; N uniF6C8 ; G 3297 +U 63185 ; WX 500 ; N cyrBreve ; G 3298 +U 63188 ; WX 500 ; N cyrbreve ; G 3299 +U 64256 ; WX 827 ; N uniFB00 ; G 3300 +U 64257 ; WX 727 ; N fi ; G 3301 +U 64258 ; WX 727 ; N fl ; G 3302 +U 64259 ; WX 1108 ; N uniFB03 ; G 3303 +U 64260 ; WX 1146 ; N uniFB04 ; G 3304 +U 64261 ; WX 879 ; N uniFB05 ; G 3305 +U 64262 ; WX 971 ; N uniFB06 ; G 3306 +U 65024 ; WX 0 ; N uniFE00 ; G 3307 +U 65025 ; WX 0 ; N uniFE01 ; G 3308 +U 65026 ; WX 0 ; N uniFE02 ; G 3309 +U 65027 ; WX 0 ; N uniFE03 ; G 3310 +U 65028 ; WX 0 ; N uniFE04 ; G 3311 +U 65029 ; WX 0 ; N uniFE05 ; G 3312 +U 65030 ; WX 0 ; N uniFE06 ; G 3313 +U 65031 ; WX 0 ; N uniFE07 ; G 3314 +U 65032 ; WX 0 ; N uniFE08 ; G 3315 +U 65033 ; WX 0 ; N uniFE09 ; G 3316 +U 65034 ; WX 0 ; N uniFE0A ; G 3317 +U 65035 ; WX 0 ; N uniFE0B ; G 3318 +U 65036 ; WX 0 ; N uniFE0C ; G 3319 +U 65037 ; WX 0 ; N uniFE0D ; G 3320 +U 65038 ; WX 0 ; N uniFE0E ; G 3321 +U 65039 ; WX 0 ; N uniFE0F ; G 3322 +U 65529 ; WX 0 ; N uniFFF9 ; G 3323 +U 65530 ; WX 0 ; N uniFFFA ; G 3324 +U 65531 ; WX 0 ; N uniFFFB ; G 3325 +U 65532 ; WX 0 ; N uniFFFC ; G 3326 +U 65533 ; WX 1113 ; N uniFFFD ; G 3327 +EndCharMetrics +StartKernData +StartKernPairs 1153 + +KPX dollar seven -112 +KPX dollar nine -149 +KPX dollar colon -102 +KPX dollar less -102 +KPX dollar I -36 +KPX dollar W -36 +KPX dollar Y -83 +KPX dollar Z -83 +KPX dollar backslash -83 +KPX dollar questiondown -83 +KPX dollar Aacute -83 +KPX dollar Hbar -112 +KPX dollar hbar -36 +KPX dollar lacute -102 + +KPX percent ampersand 38 +KPX percent asterisk 38 +KPX percent two 38 +KPX percent less -36 +KPX percent Egrave 38 +KPX percent Icircumflex 38 +KPX percent agrave 38 +KPX percent Ebreve 38 +KPX percent lacute -36 + + +KPX quotesingle nine -36 + + +KPX parenright dollar -120 +KPX parenright D -112 +KPX parenright H -112 +KPX parenright R -112 +KPX parenright U -36 +KPX parenright X -36 +KPX parenright cent -112 +KPX parenright sterling -112 +KPX parenright currency -112 +KPX parenright yen -112 +KPX parenright brokenbar -112 +KPX parenright section -112 +KPX parenright dieresis -112 +KPX parenright ordfeminine -112 +KPX parenright guillemotleft -112 +KPX parenright logicalnot -112 +KPX parenright sfthyphen -112 +KPX parenright acute -112 +KPX parenright mu -112 +KPX parenright paragraph -112 +KPX parenright periodcentered -112 +KPX parenright cedilla -112 +KPX parenright ordmasculine -112 +KPX parenright guillemotright -36 +KPX parenright onequarter -36 +KPX parenright onehalf -36 +KPX parenright threequarters -36 +KPX parenright Yacute -112 +KPX parenright ebreve -112 +KPX parenright edotaccent -36 +KPX parenright ecaron -36 +KPX parenright dotlessi -36 + + + +KPX period dollar -83 +KPX period ampersand -55 +KPX period two -55 +KPX period eight -73 +KPX period colon -73 +KPX period less -55 +KPX period H -45 +KPX period R -45 +KPX period X -45 +KPX period backslash -92 +KPX period ordfeminine -45 +KPX period guillemotleft -45 +KPX period logicalnot -45 +KPX period sfthyphen -45 +KPX period acute -45 +KPX period mu -45 +KPX period paragraph -45 +KPX period periodcentered -45 +KPX period cedilla -45 +KPX period ordmasculine -36 +KPX period guillemotright -45 +KPX period onequarter -45 +KPX period onehalf -45 +KPX period threequarters -45 +KPX period questiondown -92 +KPX period Aacute -92 +KPX period Egrave -55 +KPX period Icircumflex -55 +KPX period Yacute -45 +KPX period Ebreve -55 +KPX period ebreve -45 +KPX period Idot -73 +KPX period dotlessi -45 +KPX period lacute -55 + +KPX slash seven -167 +KPX slash eight -112 +KPX slash nine -243 +KPX slash colon -139 +KPX slash less -131 +KPX slash backslash -73 +KPX slash questiondown -73 +KPX slash Aacute -73 +KPX slash Hbar -167 +KPX slash Idot -112 +KPX slash lacute -131 + + +KPX two nine -36 +KPX two semicolon -36 + +KPX three dollar -149 +KPX three D -55 +KPX three H -55 +KPX three R -55 +KPX three cent -55 +KPX three sterling -55 +KPX three currency -55 +KPX three yen -55 +KPX three brokenbar -55 +KPX three section -55 +KPX three dieresis -55 +KPX three ordfeminine -55 +KPX three guillemotleft -55 +KPX three logicalnot -55 +KPX three sfthyphen -55 +KPX three acute -55 +KPX three mu -55 +KPX three paragraph -55 +KPX three periodcentered -55 +KPX three cedilla -55 +KPX three ordmasculine -55 +KPX three Yacute -55 +KPX three ebreve -55 + + +KPX five seven -36 +KPX five nine -73 +KPX five colon -45 +KPX five less -63 +KPX five D 47 +KPX five backslash -36 +KPX five cent 47 +KPX five sterling 47 +KPX five currency 47 +KPX five yen 47 +KPX five brokenbar 47 +KPX five section 47 +KPX five dieresis 47 +KPX five ordmasculine 38 +KPX five questiondown -36 +KPX five Aacute -36 +KPX five Hbar -36 +KPX five lacute -63 + +KPX six six -45 +KPX six Gdotaccent -45 +KPX six Gcommaaccent -45 + +KPX seven dollar -112 +KPX seven seven -73 +KPX seven D -196 +KPX seven F -235 +KPX seven H -235 +KPX seven R -235 +KPX seven U -149 +KPX seven V -188 +KPX seven X -188 +KPX seven Z -225 +KPX seven backslash -225 +KPX seven m -149 +KPX seven braceright -149 +KPX seven cent -196 +KPX seven sterling -196 +KPX seven currency -196 +KPX seven yen -196 +KPX seven brokenbar -196 +KPX seven section -196 +KPX seven dieresis -159 +KPX seven copyright -235 +KPX seven ordfeminine -235 +KPX seven guillemotleft -235 +KPX seven logicalnot -235 +KPX seven sfthyphen -235 +KPX seven acute -235 +KPX seven mu -235 +KPX seven paragraph -235 +KPX seven periodcentered -235 +KPX seven cedilla -235 +KPX seven ordmasculine -159 +KPX seven guillemotright -188 +KPX seven onequarter -188 +KPX seven onehalf -188 +KPX seven threequarters -188 +KPX seven questiondown -225 +KPX seven Aacute -225 +KPX seven Eacute -235 +KPX seven Idieresis -235 +KPX seven Yacute -235 +KPX seven ebreve -159 +KPX seven edotaccent -149 +KPX seven ecaron -149 +KPX seven gdotaccent -188 +KPX seven gcommaaccent -188 +KPX seven Hbar -73 +KPX seven dotlessi -188 + +KPX eight dollar -63 + +KPX nine dollar -159 +KPX nine two -36 +KPX nine D -188 +KPX nine H -188 +KPX nine L -36 +KPX nine R -188 +KPX nine X -131 +KPX nine backslash -83 +KPX nine cent -188 +KPX nine sterling -188 +KPX nine currency -188 +KPX nine yen -188 +KPX nine brokenbar -188 +KPX nine section -188 +KPX nine dieresis -188 +KPX nine ordfeminine -188 +KPX nine guillemotleft -188 +KPX nine logicalnot -188 +KPX nine sfthyphen -188 +KPX nine acute -188 +KPX nine mu -188 +KPX nine paragraph -188 +KPX nine periodcentered -188 +KPX nine cedilla -188 +KPX nine ordmasculine -188 +KPX nine guillemotright -131 +KPX nine onequarter -131 +KPX nine onehalf -131 +KPX nine threequarters -131 +KPX nine questiondown -83 +KPX nine Aacute -83 +KPX nine Yacute -188 +KPX nine Ebreve -36 +KPX nine ebreve -188 +KPX nine dotlessi -131 + +KPX colon dollar -131 +KPX colon D -178 +KPX colon H -167 +KPX colon L -36 +KPX colon R -167 +KPX colon U -92 +KPX colon X -83 +KPX colon backslash -45 +KPX colon cent -178 +KPX colon sterling -178 +KPX colon currency -178 +KPX colon yen -178 +KPX colon brokenbar -178 +KPX colon section -178 +KPX colon dieresis -139 +KPX colon ordfeminine -167 +KPX colon guillemotleft -167 +KPX colon logicalnot -167 +KPX colon sfthyphen -167 +KPX colon acute -167 +KPX colon mu -167 +KPX colon paragraph -167 +KPX colon periodcentered -167 +KPX colon cedilla -167 +KPX colon ordmasculine -167 +KPX colon guillemotright -83 +KPX colon onequarter -83 +KPX colon onehalf -83 +KPX colon threequarters -83 +KPX colon questiondown -45 +KPX colon Aacute -45 +KPX colon Yacute -167 +KPX colon ebreve -167 +KPX colon edotaccent -92 +KPX colon ecaron -92 +KPX colon dotlessi -83 + +KPX semicolon dollar -73 +KPX semicolon ampersand -36 +KPX semicolon two -36 +KPX semicolon Egrave -36 +KPX semicolon Icircumflex -36 +KPX semicolon Ebreve -36 + +KPX less dollar -131 +KPX less ampersand -36 +KPX less D -159 +KPX less H -178 +KPX less L -36 +KPX less R -178 +KPX less X -178 +KPX less cent -159 +KPX less sterling -159 +KPX less currency -159 +KPX less yen -159 +KPX less brokenbar -159 +KPX less section -159 +KPX less dieresis -159 +KPX less ordfeminine -178 +KPX less guillemotleft -178 +KPX less logicalnot -178 +KPX less sfthyphen -178 +KPX less acute -178 +KPX less mu -178 +KPX less paragraph -178 +KPX less periodcentered -178 +KPX less cedilla -178 +KPX less ordmasculine -178 +KPX less guillemotright -178 +KPX less onequarter -178 +KPX less onehalf -178 +KPX less threequarters -178 +KPX less Egrave -36 +KPX less Icircumflex -36 +KPX less Yacute -178 +KPX less ebreve -178 +KPX less dotlessi -178 + + + + + + + + + + +KPX m hyphen -73 +KPX m seven -149 +KPX m Hbar -149 + +KPX braceright hyphen -73 +KPX braceright seven -149 +KPX braceright Hbar -149 + + + + + + + + + + + + + + +KPX Eth nine -36 + + + +KPX ucircumflex seven -167 +KPX ucircumflex eight -112 +KPX ucircumflex nine -243 +KPX ucircumflex colon -139 +KPX ucircumflex less -131 +KPX ucircumflex backslash -73 +KPX ucircumflex questiondown -73 +KPX ucircumflex Aacute -73 +KPX ucircumflex Hbar -167 +KPX ucircumflex Idot -112 +KPX ucircumflex lacute -131 + +KPX ydieresis seven -167 +KPX ydieresis eight -112 +KPX ydieresis nine -243 +KPX ydieresis colon -139 +KPX ydieresis less -131 +KPX ydieresis backslash -73 +KPX ydieresis questiondown -73 +KPX ydieresis Aacute -73 +KPX ydieresis Hbar -167 +KPX ydieresis Idot -112 +KPX ydieresis lacute -131 + +KPX Abreve O -241 + +KPX abreve seven -167 +KPX abreve eight -112 +KPX abreve nine -243 +KPX abreve colon -139 +KPX abreve less -131 +KPX abreve backslash -73 +KPX abreve questiondown -73 +KPX abreve Aacute -73 +KPX abreve Hbar -167 +KPX abreve Idot -112 +KPX abreve lacute -131 + + + +KPX Edotaccent seven -36 +KPX Edotaccent nine -73 +KPX Edotaccent colon -45 +KPX Edotaccent less -63 +KPX Edotaccent D 47 +KPX Edotaccent backslash -36 +KPX Edotaccent cent 47 +KPX Edotaccent sterling 47 +KPX Edotaccent currency 47 +KPX Edotaccent yen 47 +KPX Edotaccent brokenbar 47 +KPX Edotaccent section 47 +KPX Edotaccent dieresis 47 +KPX Edotaccent ordmasculine 38 +KPX Edotaccent questiondown -36 +KPX Edotaccent Aacute -36 +KPX Edotaccent Hbar -36 +KPX Edotaccent lacute -63 + + +KPX Ecaron seven -36 +KPX Ecaron nine -73 +KPX Ecaron colon -45 +KPX Ecaron less -63 +KPX Ecaron D 47 +KPX Ecaron backslash -36 +KPX Ecaron cent 47 +KPX Ecaron sterling 47 +KPX Ecaron currency 47 +KPX Ecaron yen 47 +KPX Ecaron brokenbar 47 +KPX Ecaron section 47 +KPX Ecaron dieresis 47 +KPX Ecaron ordmasculine 38 +KPX Ecaron questiondown -36 +KPX Ecaron Aacute -36 +KPX Ecaron Hbar -36 +KPX Ecaron lacute -63 + + +KPX Gdotaccent six -45 +KPX Gdotaccent Gdotaccent -45 +KPX Gdotaccent Gcommaaccent -45 + +KPX Gcommaaccent six -45 +KPX Gcommaaccent Gdotaccent -45 +KPX Gcommaaccent Gcommaaccent -45 + +KPX Hbar dollar -112 +KPX Hbar seven -73 +KPX Hbar D -196 +KPX Hbar F -235 +KPX Hbar H -235 +KPX Hbar R -235 +KPX Hbar U -149 +KPX Hbar V -188 +KPX Hbar X -188 +KPX Hbar Z -225 +KPX Hbar backslash -225 +KPX Hbar m -149 +KPX Hbar braceright -149 +KPX Hbar cent -196 +KPX Hbar sterling -196 +KPX Hbar currency -196 +KPX Hbar yen -196 +KPX Hbar brokenbar -196 +KPX Hbar section -196 +KPX Hbar dieresis -159 +KPX Hbar copyright -235 +KPX Hbar ordfeminine -235 +KPX Hbar guillemotleft -235 +KPX Hbar logicalnot -235 +KPX Hbar sfthyphen -235 +KPX Hbar acute -235 +KPX Hbar mu -235 +KPX Hbar paragraph -235 +KPX Hbar periodcentered -235 +KPX Hbar cedilla -235 +KPX Hbar ordmasculine -159 +KPX Hbar guillemotright -188 +KPX Hbar onequarter -188 +KPX Hbar onehalf -188 +KPX Hbar threequarters -188 +KPX Hbar questiondown -225 +KPX Hbar Aacute -225 +KPX Hbar Eacute -235 +KPX Hbar Idieresis -235 +KPX Hbar Yacute -235 +KPX Hbar ebreve -159 +KPX Hbar edotaccent -149 +KPX Hbar ecaron -149 +KPX Hbar gdotaccent -188 +KPX Hbar gcommaaccent -188 +KPX Hbar Hbar -73 +KPX Hbar dotlessi -188 + +KPX Idot dollar -63 + +KPX lacute dollar -131 +KPX lacute ampersand -36 +KPX lacute D -159 +KPX lacute H -178 +KPX lacute L -36 +KPX lacute R -178 +KPX lacute X -178 +KPX lacute cent -159 +KPX lacute sterling -159 +KPX lacute currency -159 +KPX lacute yen -159 +KPX lacute brokenbar -159 +KPX lacute section -159 +KPX lacute dieresis -159 +KPX lacute ordfeminine -178 +KPX lacute guillemotleft -178 +KPX lacute logicalnot -178 +KPX lacute sfthyphen -178 +KPX lacute acute -178 +KPX lacute mu -178 +KPX lacute paragraph -178 +KPX lacute periodcentered -178 +KPX lacute cedilla -178 +KPX lacute ordmasculine -178 +KPX lacute guillemotright -178 +KPX lacute onequarter -178 +KPX lacute onehalf -178 +KPX lacute threequarters -178 +KPX lacute Egrave -36 +KPX lacute Icircumflex -36 +KPX lacute Yacute -178 +KPX lacute ebreve -178 +KPX lacute dotlessi -178 + + +KPX uni027D dollar -282 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Italic.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSerif-Italic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..805daf2228b999aa48c4e10f5e8ddcf154107feb GIT binary patch literal 345996 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 t~a@iz{CvRtjkd+>WQG8xd!fPaNBj;erf%$Oa^ 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%0A6)5fz^b{+9WlpW(OXq}w{QV`9e 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

h-1mI`j?mn@#k|La->TpE!0$!%8zdVs3AcoHeV~ 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⪻^aYFO!99beHFX-Akj_(lfyO_-YO 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 + [ + 'normal' => $distFontDir . '/Helvetica', + 'bold' => $distFontDir . '/Helvetica-Bold', + 'italic' => $distFontDir . '/Helvetica-Oblique', + 'bold_italic' => $distFontDir . '/Helvetica-BoldOblique' + ], + 'times' => + [ + 'normal' => $distFontDir . '/Times-Roman', + 'bold' => $distFontDir . '/Times-Bold', + 'italic' => $distFontDir . '/Times-Italic', + 'bold_italic' => $distFontDir . '/Times-BoldItalic' + ], + 'times-roman' => + [ + 'normal' => $distFontDir . '/Times-Roman', + 'bold' => $distFontDir . '/Times-Bold', + 'italic' => $distFontDir . '/Times-Italic', + 'bold_italic' => $distFontDir . '/Times-BoldItalic' + ], + 'courier' => + [ + 'normal' => $distFontDir . '/Courier', + 'bold' => $distFontDir . '/Courier-Bold', + 'italic' => $distFontDir . '/Courier-Oblique', + 'bold_italic' => $distFontDir . '/Courier-BoldOblique' + ], + 'helvetica' => + [ + 'normal' => $distFontDir . '/Helvetica', + 'bold' => $distFontDir . '/Helvetica-Bold', + 'italic' => $distFontDir . '/Helvetica-Oblique', + 'bold_italic' => $distFontDir . '/Helvetica-BoldOblique' + ], + 'zapfdingbats' => + [ + 'normal' => $distFontDir . '/ZapfDingbats', + 'bold' => $distFontDir . '/ZapfDingbats', + 'italic' => $distFontDir . '/ZapfDingbats', + 'bold_italic' => $distFontDir . '/ZapfDingbats' + ], + 'symbol' => + [ + 'normal' => $distFontDir . '/Symbol', + 'bold' => $distFontDir . '/Symbol', + 'italic' => $distFontDir . '/Symbol', + 'bold_italic' => $distFontDir . '/Symbol' + ], + 'serif' => + [ + 'normal' => $distFontDir . '/Times-Roman', + 'bold' => $distFontDir . '/Times-Bold', + 'italic' => $distFontDir . '/Times-Italic', + 'bold_italic' => $distFontDir . '/Times-BoldItalic' + ], + 'monospace' => + [ + 'normal' => $distFontDir . '/Courier', + 'bold' => $distFontDir . '/Courier-Bold', + 'italic' => $distFontDir . '/Courier-Oblique', + 'bold_italic' => $distFontDir . '/Courier-BoldOblique' + ], + 'fixed' => + [ + 'normal' => $distFontDir . '/Courier', + 'bold' => $distFontDir . '/Courier-Bold', + 'italic' => $distFontDir . '/Courier-Oblique', + 'bold_italic' => $distFontDir . '/Courier-BoldOblique' + ], + 'dejavu sans' => + [ + 'bold' => $distFontDir . '/DejaVuSans-Bold', + 'bold_italic' => $distFontDir . '/DejaVuSans-BoldOblique', + 'italic' => $distFontDir . '/DejaVuSans-Oblique', + 'normal' => $distFontDir . '/DejaVuSans' + ], + 'dejavu sans mono' => + [ + 'bold' => $distFontDir . '/DejaVuSansMono-Bold', + 'bold_italic' => $distFontDir . '/DejaVuSansMono-BoldOblique', + 'italic' => $distFontDir . '/DejaVuSansMono-Oblique', + 'normal' => $distFontDir . '/DejaVuSansMono' + ], + 'dejavu serif' => + [ + 'bold' => $distFontDir . '/DejaVuSerif-Bold', + 'bold_italic' => $distFontDir . '/DejaVuSerif-BoldItalic', + 'italic' => $distFontDir . '/DejaVuSerif-Italic', + 'normal' => $distFontDir . '/DejaVuSerif' + ] +]; \ No newline at end of file diff --git a/vendor/dompdf/dompdf/lib/fonts/mustRead.html b/vendor/dompdf/dompdf/lib/fonts/mustRead.html new file mode 100644 index 0000000..b9f4ba2 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/mustRead.html @@ -0,0 +1,17 @@ + + + + + Core 14 AFM Files - ReadMe + + + or + + + + + +
This file and the 14 PostScript(R) AFM files it accompanies may be used, copied, and distributed for any purpose and without charge, with or without modification, provided that all copyright notices are retained; that the AFM files are not distributed without this file; that all modifications to this file or any of the AFM files are prominently noted in the modified file(s); and that this paragraph is not modified. Adobe Systems has no responsibility or obligation to support the use of the AFM files. Col
+

Source http://www.adobe.com/devnet/font/#pcfi

+ + \ No newline at end of file diff --git a/vendor/dompdf/dompdf/lib/html5lib/Data.php b/vendor/dompdf/dompdf/lib/html5lib/Data.php new file mode 100644 index 0000000..609e996 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/html5lib/Data.php @@ -0,0 +1,123 @@ + 0xFFFD, // REPLACEMENT CHARACTER + 0x0D => 0x000A, // LINE FEED (LF) + 0x80 => 0x20AC, // EURO SIGN ('€') + 0x81 => 0x0081, // + 0x82 => 0x201A, // SINGLE LOW-9 QUOTATION MARK ('‚') + 0x83 => 0x0192, // LATIN SMALL LETTER F WITH HOOK ('Æ’') + 0x84 => 0x201E, // DOUBLE LOW-9 QUOTATION MARK ('„') + 0x85 => 0x2026, // HORIZONTAL ELLIPSIS ('…') + 0x86 => 0x2020, // DAGGER ('†') + 0x87 => 0x2021, // DOUBLE DAGGER ('‡') + 0x88 => 0x02C6, // MODIFIER LETTER CIRCUMFLEX ACCENT ('ˆ') + 0x89 => 0x2030, // PER MILLE SIGN ('‰') + 0x8A => 0x0160, // LATIN CAPITAL LETTER S WITH CARON ('Å ') + 0x8B => 0x2039, // SINGLE LEFT-POINTING ANGLE QUOTATION MARK ('‹') + 0x8C => 0x0152, // LATIN CAPITAL LIGATURE OE ('Å’') + 0x8D => 0x008D, // + 0x8E => 0x017D, // LATIN CAPITAL LETTER Z WITH CARON ('Ž') + 0x8F => 0x008F, // + 0x90 => 0x0090, // + 0x91 => 0x2018, // LEFT SINGLE QUOTATION MARK ('‘') + 0x92 => 0x2019, // RIGHT SINGLE QUOTATION MARK ('’') + 0x93 => 0x201C, // LEFT DOUBLE QUOTATION MARK ('“') + 0x94 => 0x201D, // RIGHT DOUBLE QUOTATION MARK ('â€') + 0x95 => 0x2022, // BULLET ('•') + 0x96 => 0x2013, // EN DASH ('–') + 0x97 => 0x2014, // EM DASH ('—') + 0x98 => 0x02DC, // SMALL TILDE ('Ëœ') + 0x99 => 0x2122, // TRADE MARK SIGN ('â„¢') + 0x9A => 0x0161, // LATIN SMALL LETTER S WITH CARON ('Å¡') + 0x9B => 0x203A, // SINGLE RIGHT-POINTING ANGLE QUOTATION MARK ('›') + 0x9C => 0x0153, // LATIN SMALL LIGATURE OE ('Å“') + 0x9D => 0x009D, // + 0x9E => 0x017E, // LATIN SMALL LETTER Z WITH CARON ('ž') + 0x9F => 0x0178, // LATIN CAPITAL LETTER Y WITH DIAERESIS ('Ÿ') + ]; + + protected static $namedCharacterReferences; + + protected static $namedCharacterReferenceMaxLength; + + /** + * Returns the "real" Unicode codepoint of a malformed character + * reference. + */ + public static function getRealCodepoint($ref) { + if (!isset(self::$realCodepointTable[$ref])) { + return false; + } else { + return self::$realCodepointTable[$ref]; + } + } + + public static function getNamedCharacterReferences() { + if (!self::$namedCharacterReferences) { + self::$namedCharacterReferences = unserialize( + file_get_contents(dirname(__FILE__) . '/named-character-references.ser')); + } + return self::$namedCharacterReferences; + } + + /** + * Converts a Unicode codepoint to sequence of UTF-8 bytes. + * @note Shamelessly stolen from HTML Purifier, which is also + * shamelessly stolen from Feyd (which is in public domain). + */ + public static function utf8chr($code) { + /* We don't care: we live dangerously + * if($code > 0x10FFFF or $code < 0x0 or + ($code >= 0xD800 and $code <= 0xDFFF) ) { + // bits are set outside the "valid" range as defined + // by UNICODE 4.1.0 + return "\xEF\xBF\xBD"; + }*/ + + $y = $z = $w = 0; + if ($code < 0x80) { + // regular ASCII character + $x = $code; + } else { + // set up bits for UTF-8 + $x = ($code & 0x3F) | 0x80; + if ($code < 0x800) { + $y = (($code & 0x7FF) >> 6) | 0xC0; + } else { + $y = (($code & 0xFC0) >> 6) | 0x80; + if ($code < 0x10000) { + $z = (($code >> 12) & 0x0F) | 0xE0; + } else { + $z = (($code >> 12) & 0x3F) | 0x80; + $w = (($code >> 18) & 0x07) | 0xF0; + } + } + } + // set up the actual character + $ret = ''; + if ($w) { + $ret .= chr($w); + } + if ($z) { + $ret .= chr($z); + } + if ($y) { + $ret .= chr($y); + } + $ret .= chr($x); + + return $ret; + } + +} diff --git a/vendor/dompdf/dompdf/lib/html5lib/InputStream.php b/vendor/dompdf/dompdf/lib/html5lib/InputStream.php new file mode 100644 index 0000000..dde7194 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/html5lib/InputStream.php @@ -0,0 +1,299 @@ + + +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. + +*/ + +// Some conventions: +// /* */ indicates verbatim text from the HTML 5 specification +// // indicates regular comments + +class HTML5_InputStream { + /** + * The string data we're parsing. + */ + private $data; + + /** + * The current integer byte position we are in $data + */ + private $char; + + /** + * Length of $data; when $char === $data, we are at the end-of-file. + */ + private $EOF; + + /** + * Parse errors. + */ + public $errors = []; + + /** + * @param $data | Data to parse + * @throws Exception + */ + public function __construct($data) { + + /* Given an encoding, the bytes in the input stream must be + converted to Unicode characters for the tokeniser, as + described by the rules for that encoding, except that the + leading U+FEFF BYTE ORDER MARK character, if any, must not + be stripped by the encoding layer (it is stripped by the rule below). + + Bytes or sequences of bytes in the original byte stream that + could not be converted to Unicode characters must be converted + to U+FFFD REPLACEMENT CHARACTER code points. */ + + // XXX currently assuming input data is UTF-8; once we + // build encoding detection this will no longer be the case + // + // We previously had an mbstring implementation here, but that + // implementation is heavily non-conforming, so it's been + // omitted. + if (extension_loaded('iconv')) { + // non-conforming + $data = @iconv('UTF-8', 'UTF-8//IGNORE', $data); + } else { + // we can make a conforming native implementation + throw new Exception('Not implemented, please install iconv'); + } + + /* One leading U+FEFF BYTE ORDER MARK character must be + ignored if any are present. */ + if (substr($data, 0, 3) === "\xEF\xBB\xBF") { + $data = substr($data, 3); + } + + /* All U+0000 NULL characters in the input must be replaced + by U+FFFD REPLACEMENT CHARACTERs. Any occurrences of such + characters is a parse error. */ + for ($i = 0, $count = substr_count($data, "\0"); $i < $count; $i++) { + $this->errors[] = [ + 'type' => HTML5_Tokenizer::PARSEERROR, + 'data' => 'null-character' + ]; + } + /* U+000D CARRIAGE RETURN (CR) characters and U+000A LINE FEED + (LF) characters are treated specially. Any CR characters + that are followed by LF characters must be removed, and any + CR characters not followed by LF characters must be converted + to LF characters. Thus, newlines in HTML DOMs are represented + by LF characters, and there are never any CR characters in the + input to the tokenization stage. */ + $data = str_replace( + [ + "\0", + "\r\n", + "\r" + ], + [ + "\xEF\xBF\xBD", + "\n", + "\n" + ], + $data + ); + + /* Any occurrences of any characters in the ranges U+0001 to + U+0008, U+000B, U+000E to U+001F, U+007F to U+009F, + U+D800 to U+DFFF , U+FDD0 to U+FDEF, and + characters U+FFFE, U+FFFF, U+1FFFE, U+1FFFF, U+2FFFE, U+2FFFF, + U+3FFFE, U+3FFFF, U+4FFFE, U+4FFFF, U+5FFFE, U+5FFFF, U+6FFFE, + U+6FFFF, U+7FFFE, U+7FFFF, U+8FFFE, U+8FFFF, U+9FFFE, U+9FFFF, + U+AFFFE, U+AFFFF, U+BFFFE, U+BFFFF, U+CFFFE, U+CFFFF, U+DFFFE, + U+DFFFF, U+EFFFE, U+EFFFF, U+FFFFE, U+FFFFF, U+10FFFE, and + U+10FFFF are parse errors. (These are all control characters + or permanently undefined Unicode characters.) */ + // Check PCRE is loaded. + if (extension_loaded('pcre')) { + $count = preg_match_all( + '/(?: + [\x01-\x08\x0B\x0E-\x1F\x7F] # U+0001 to U+0008, U+000B, U+000E to U+001F and U+007F + | + \xC2[\x80-\x9F] # U+0080 to U+009F + | + \xED(?:\xA0[\x80-\xFF]|[\xA1-\xBE][\x00-\xFF]|\xBF[\x00-\xBF]) # U+D800 to U+DFFFF + | + \xEF\xB7[\x90-\xAF] # U+FDD0 to U+FDEF + | + \xEF\xBF[\xBE\xBF] # U+FFFE and U+FFFF + | + [\xF0-\xF4][\x8F-\xBF]\xBF[\xBE\xBF] # U+nFFFE and U+nFFFF (1 <= n <= 10_{16}) + )/x', + $data, + $matches + ); + for ($i = 0; $i < $count; $i++) { + $this->errors[] = [ + 'type' => HTML5_Tokenizer::PARSEERROR, + 'data' => 'invalid-codepoint' + ]; + } + } else { + // XXX: Need non-PCRE impl, probably using substr_count + } + + $this->data = $data; + $this->char = 0; + $this->EOF = strlen($data); + } + + /** + * Returns the current line that the tokenizer is at. + * + * @return int + */ + public function getCurrentLine() { + // Check the string isn't empty + if ($this->EOF) { + // Add one to $this->char because we want the number for the next + // byte to be processed. + return substr_count($this->data, "\n", 0, min($this->char, $this->EOF)) + 1; + } else { + // If the string is empty, we are on the first line (sorta). + return 1; + } + } + + /** + * Returns the current column of the current line that the tokenizer is at. + * + * @return int + */ + public function getColumnOffset() { + // strrpos is weird, and the offset needs to be negative for what we + // want (i.e., the last \n before $this->char). This needs to not have + // one (to make it point to the next character, the one we want the + // position of) added to it because strrpos's behaviour includes the + // final offset byte. + $lastLine = strrpos($this->data, "\n", $this->char - 1 - strlen($this->data)); + + // However, for here we want the length up until the next byte to be + // processed, so add one to the current byte ($this->char). + if ($lastLine !== false) { + $findLengthOf = substr($this->data, $lastLine + 1, $this->char - 1 - $lastLine); + } else { + $findLengthOf = substr($this->data, 0, $this->char); + } + + // Get the length for the string we need. + if (extension_loaded('iconv')) { + return iconv_strlen($findLengthOf, 'utf-8'); + } elseif (extension_loaded('mbstring')) { + return mb_strlen($findLengthOf, 'utf-8'); + } elseif (extension_loaded('xml')) { + return strlen(utf8_decode($findLengthOf)); + } else { + $count = count_chars($findLengthOf); + // 0x80 = 0x7F - 0 + 1 (one added to get inclusive range) + // 0x33 = 0xF4 - 0x2C + 1 (one added to get inclusive range) + return array_sum(array_slice($count, 0, 0x80)) + + array_sum(array_slice($count, 0xC2, 0x33)); + } + } + + /** + * Retrieve the currently consume character. + * @note This performs bounds checking + * + * @return bool|string + */ + public function char() { + return ($this->char++ < $this->EOF) + ? $this->data[$this->char - 1] + : false; + } + + /** + * Get all characters until EOF. + * @note This performs bounds checking + * + * @return string|bool + */ + public function remainingChars() { + if ($this->char < $this->EOF) { + $data = substr($this->data, $this->char); + $this->char = $this->EOF; + return $data; + } else { + return false; + } + } + + /** + * Matches as far as possible until we reach a certain set of bytes + * and returns the matched substring. + * + * @param $bytes | Bytes to match. + * @param null $max + * @return bool|string + */ + public function charsUntil($bytes, $max = null) { + if ($this->char < $this->EOF) { + if ($max === 0 || $max) { + $len = strcspn($this->data, $bytes, $this->char, $max); + } else { + $len = strcspn($this->data, $bytes, $this->char); + } + $string = (string) substr($this->data, $this->char, $len); + $this->char += $len; + return $string; + } else { + return false; + } + } + + /** + * Matches as far as possible with a certain set of bytes + * and returns the matched substring. + * + * @param $bytes | Bytes to match. + * @param null $max + * @return bool|string + */ + public function charsWhile($bytes, $max = null) { + if ($this->char < $this->EOF) { + if ($max === 0 || $max) { + $len = strspn($this->data, $bytes, $this->char, $max); + } else { + $len = strspn($this->data, $bytes, $this->char); + } + $string = (string) substr($this->data, $this->char, $len); + $this->char += $len; + return $string; + } else { + return false; + } + } + + /** + * Unconsume one character. + */ + public function unget() { + if ($this->char <= $this->EOF) { + $this->char--; + } + } +} diff --git a/vendor/dompdf/dompdf/lib/html5lib/Parser.php b/vendor/dompdf/dompdf/lib/html5lib/Parser.php new file mode 100644 index 0000000..b48ce68 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/html5lib/Parser.php @@ -0,0 +1,37 @@ +parse(); + return $tokenizer->save(); + } + + /** + * Parses an HTML fragment. + * @param $text | HTML text to parse + * @param $context String name of context element to pretend parsing is in. + * @param $builder | Custom builder implementation + * @return DOMDocument|DOMNodeList Parsed HTML as DOMDocument + */ + public static function parseFragment($text, $context = null, $builder = null) { + $tokenizer = new HTML5_Tokenizer($text, $builder); + $tokenizer->parseFragment($context); + return $tokenizer->save(); + } +} diff --git a/vendor/dompdf/dompdf/lib/html5lib/Tokenizer.php b/vendor/dompdf/dompdf/lib/html5lib/Tokenizer.php new file mode 100644 index 0000000..9f1f3ae --- /dev/null +++ b/vendor/dompdf/dompdf/lib/html5lib/Tokenizer.php @@ -0,0 +1,2470 @@ + +Copyright 2008 Edward Z. Yang +Copyright 2009 Geoffrey Sneddon + +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. + +*/ + +// Some conventions: +// /* */ indicates verbatim text from the HTML 5 specification +// // indicates regular comments + +// all flags are in hyphenated form + +class HTML5_Tokenizer { + /** + * @var HTML5_InputStream + * + * Points to an InputStream object. + */ + protected $stream; + + /** + * @var HTML5_TreeBuilder + * + * Tree builder that the tokenizer emits token to. + */ + private $tree; + + /** + * @var int + * + * Current content model we are parsing as. + */ + protected $content_model; + + /** + * Current token that is being built, but not yet emitted. Also + * is the last token emitted, if applicable. + */ + protected $token; + + // These are constants describing the content model + const PCDATA = 0; + const RCDATA = 1; + const CDATA = 2; + const PLAINTEXT = 3; + + // These are constants describing tokens + // XXX should probably be moved somewhere else, probably the + // HTML5 class. + const DOCTYPE = 0; + const STARTTAG = 1; + const ENDTAG = 2; + const COMMENT = 3; + const CHARACTER = 4; + const SPACECHARACTER = 5; + const EOF = 6; + const PARSEERROR = 7; + + // These are constants representing bunches of characters. + const ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; + const UPPER_ALPHA = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'; + const LOWER_ALPHA = 'abcdefghijklmnopqrstuvwxyz'; + const DIGIT = '0123456789'; + const HEX = '0123456789ABCDEFabcdef'; + const WHITESPACE = "\t\n\x0c "; + + /** + * @param $data | Data to parse + * @param HTML5_TreeBuilder|null $builder + */ + public function __construct($data, $builder = null) { + $this->stream = new HTML5_InputStream($data); + if (!$builder) { + $this->tree = new HTML5_TreeBuilder; + } else { + $this->tree = $builder; + } + $this->content_model = self::PCDATA; + } + + /** + * @param null $context + */ + public function parseFragment($context = null) { + $this->tree->setupContext($context); + if ($this->tree->content_model) { + $this->content_model = $this->tree->content_model; + $this->tree->content_model = null; + } + $this->parse(); + } + + // XXX maybe convert this into an iterator? regardless, this function + // and the save function should go into a Parser facade of some sort + /** + * Performs the actual parsing of the document. + */ + public function parse() { + // Current state + $state = 'data'; + // This is used to avoid having to have look-behind in the data state. + $lastFourChars = ''; + /** + * Escape flag as specified by the HTML5 specification: "used to + * control the behavior of the tokeniser. It is either true or + * false, and initially must be set to the false state." + */ + $escape = false; + //echo "\n\n"; + while($state !== null) { + + /*echo $state . ' '; + switch ($this->content_model) { + case self::PCDATA: echo 'PCDATA'; break; + case self::RCDATA: echo 'RCDATA'; break; + case self::CDATA: echo 'CDATA'; break; + case self::PLAINTEXT: echo 'PLAINTEXT'; break; + } + if ($escape) echo " escape"; + echo "\n";*/ + + switch($state) { + case 'data': + + /* Consume the next input character */ + $char = $this->stream->char(); + $lastFourChars .= $char; + if (strlen($lastFourChars) > 4) { + $lastFourChars = substr($lastFourChars, -4); + } + + // see below for meaning + $hyp_cond = + !$escape && + ( + $this->content_model === self::RCDATA || + $this->content_model === self::CDATA + ); + $amp_cond = + !$escape && + ( + $this->content_model === self::PCDATA || + $this->content_model === self::RCDATA + ); + $lt_cond = + $this->content_model === self::PCDATA || + ( + ( + $this->content_model === self::RCDATA || + $this->content_model === self::CDATA + ) && + !$escape + ); + $gt_cond = + $escape && + ( + $this->content_model === self::RCDATA || + $this->content_model === self::CDATA + ); + + if ($char === '&' && $amp_cond === true) { + /* U+0026 AMPERSAND (&) + When the content model flag is set to one of the PCDATA or RCDATA + states and the escape flag is false: switch to the + character reference data state. Otherwise: treat it as per + the "anything else" entry below. */ + $state = 'character reference data'; + + } elseif ( + $char === '-' && + $hyp_cond === true && + $lastFourChars === '' + ) { + /* If the content model flag is set to either the RCDATA state or + the CDATA state, and the escape flag is true, and the last three + characters in the input stream including this one are U+002D + HYPHEN-MINUS, U+002D HYPHEN-MINUS, U+003E GREATER-THAN SIGN ("-->"), + set the escape flag to false. */ + $escape = false; + + /* In any case, emit the input character as a character token. + Stay in the data state. */ + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => '>' + ]); + // We do the "any case" part as part of "anything else". + + } elseif ($char === false) { + /* EOF + Emit an end-of-file token. */ + $state = null; + $this->tree->emitToken([ + 'type' => self::EOF + ]); + + } elseif ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + // Directly after emitting a token you switch back to the "data + // state". At that point spaceCharacters are important so they are + // emitted separately. + $chars = $this->stream->charsWhile(self::WHITESPACE); + $this->emitToken([ + 'type' => self::SPACECHARACTER, + 'data' => $char . $chars + ]); + $lastFourChars .= $chars; + if (strlen($lastFourChars) > 4) { + $lastFourChars = substr($lastFourChars, -4); + } + } else { + /* Anything else + THIS IS AN OPTIMIZATION: Get as many character that + otherwise would also be treated as a character token and emit it + as a single character token. Stay in the data state. */ + + $mask = ''; + if ($hyp_cond === true) { + $mask .= '-'; + } + if ($amp_cond === true) { + $mask .= '&'; + } + if ($lt_cond === true) { + $mask .= '<'; + } + if ($gt_cond === true) { + $mask .= '>'; + } + + if ($mask === '') { + $chars = $this->stream->remainingChars(); + } else { + $chars = $this->stream->charsUntil($mask); + } + + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => $char . $chars + ]); + + $lastFourChars .= $chars; + if (strlen($lastFourChars) > 4) { + $lastFourChars = substr($lastFourChars, -4); + } + + $state = 'data'; + } + break; + + case 'character reference data': + /* (This cannot happen if the content model flag + is set to the CDATA state.) */ + + /* Attempt to consume a character reference, with no + additional allowed character. */ + $entity = $this->consumeCharacterReference(); + + /* If nothing is returned, emit a U+0026 AMPERSAND + character token. Otherwise, emit the character token that + was returned. */ + // This is all done when consuming the character reference. + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => $entity + ]); + + /* Finally, switch to the data state. */ + $state = 'data'; + break; + + case 'tag open': + $char = $this->stream->char(); + + switch ($this->content_model) { + case self::RCDATA: + case self::CDATA: + /* Consume the next input character. If it is a + U+002F SOLIDUS (/) character, switch to the close + tag open state. Otherwise, emit a U+003C LESS-THAN + SIGN character token and reconsume the current input + character in the data state. */ + // We consumed above. + + if ($char === '/') { + $state = 'close tag open'; + } else { + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => '<' + ]); + + $this->stream->unget(); + + $state = 'data'; + } + break; + + case self::PCDATA: + /* If the content model flag is set to the PCDATA state + Consume the next input character: */ + // We consumed above. + + if ($char === '!') { + /* U+0021 EXCLAMATION MARK (!) + Switch to the markup declaration open state. */ + $state = 'markup declaration open'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the close tag open state. */ + $state = 'close tag open'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new start tag token, set its tag name to the lowercase + version of the input character (add 0x0020 to the character's code + point), then switch to the tag name state. (Don't emit the token + yet; further details will be filled in before it is emitted.) */ + $this->token = [ + 'name' => strtolower($char), + 'type' => self::STARTTAG, + 'attr' => [] + ]; + + $state = 'tag name'; + + } elseif ('a' <= $char && $char <= 'z') { + /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z + Create a new start tag token, set its tag name to the input + character, then switch to the tag name state. (Don't emit + the token yet; further details will be filled in before it + is emitted.) */ + $this->token = [ + 'name' => $char, + 'type' => self::STARTTAG, + 'attr' => [] + ]; + + $state = 'tag name'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit a U+003C LESS-THAN SIGN character token and a + U+003E GREATER-THAN SIGN character token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-tag-name-but-got-right-bracket' + ]); + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => '<>' + ]); + + $state = 'data'; + + } elseif ($char === '?') { + /* U+003F QUESTION MARK (?) + Parse error. Switch to the bogus comment state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-tag-name-but-got-question-mark' + ]); + $this->token = [ + 'data' => '?', + 'type' => self::COMMENT + ]; + $state = 'bogus comment'; + + } else { + /* Anything else + Parse error. Emit a U+003C LESS-THAN SIGN character token and + reconsume the current input character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-tag-name' + ]); + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => '<' + ]); + + $state = 'data'; + $this->stream->unget(); + } + break; + } + break; + + case 'close tag open': + if ( + $this->content_model === self::RCDATA || + $this->content_model === self::CDATA + ) { + /* If the content model flag is set to the RCDATA or CDATA + states... */ + $name = strtolower($this->stream->charsWhile(self::ALPHA)); + $following = $this->stream->char(); + $this->stream->unget(); + if ( + !$this->token || + $this->token['name'] !== $name || + $this->token['name'] === $name && !in_array($following, ["\x09", "\x0A", "\x0C", "\x20", "\x3E", "\x2F", false]) + ) { + /* if no start tag token has ever been emitted by this instance + of the tokenizer (fragment case), or, if the next few + characters do not match the tag name of the last start tag + token emitted (compared in an ASCII case-insensitive manner), + or if they do but they are not immediately followed by one of + the following characters: + + * U+0009 CHARACTER TABULATION + * U+000A LINE FEED (LF) + * U+000C FORM FEED (FF) + * U+0020 SPACE + * U+003E GREATER-THAN SIGN (>) + * U+002F SOLIDUS (/) + * EOF + + ...then emit a U+003C LESS-THAN SIGN character token, a + U+002F SOLIDUS character token, and switch to the data + state to process the next input character. */ + // XXX: Probably ought to replace in_array with $following === x ||... + + // We also need to emit $name now we've consumed that, as we + // know it'll just be emitted as a character token. + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => 'token = [ + 'name' => $name, + 'type' => self::ENDTAG + ]; + + // Change to tag name state. + $state = 'tag name'; + } + } elseif ($this->content_model === self::PCDATA) { + /* Otherwise, if the content model flag is set to the PCDATA + state [...]: */ + $char = $this->stream->char(); + + if ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN LETTER A through to U+005A LATIN LETTER Z + Create a new end tag token, set its tag name to the lowercase version + of the input character (add 0x0020 to the character's code point), then + switch to the tag name state. (Don't emit the token yet; further details + will be filled in before it is emitted.) */ + $this->token = [ + 'name' => strtolower($char), + 'type' => self::ENDTAG + ]; + + $state = 'tag name'; + + } elseif ('a' <= $char && $char <= 'z') { + /* U+0061 LATIN SMALL LETTER A through to U+007A LATIN SMALL LETTER Z + Create a new end tag token, set its tag name to the + input character, then switch to the tag name state. + (Don't emit the token yet; further details will be + filled in before it is emitted.) */ + $this->token = [ + 'name' => $char, + 'type' => self::ENDTAG + ]; + + $state = 'tag name'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-closing-tag-but-got-right-bracket' + ]); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Emit a U+003C LESS-THAN SIGN character token and a U+002F + SOLIDUS character token. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-closing-tag-but-got-eof' + ]); + $this->emitToken([ + 'type' => self::CHARACTER, + 'data' => 'stream->unget(); + $state = 'data'; + + } else { + /* Parse error. Switch to the bogus comment state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-closing-tag-but-got-char' + ]); + $this->token = [ + 'data' => $char, + 'type' => self::COMMENT + ]; + $state = 'bogus comment'; + } + } + break; + + case 'tag name': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $state = 'before attribute name'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the self-closing start tag state. */ + $state = 'self-closing start tag'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Append the lowercase version of the current input + character (add 0x0020 to the character's code point) to + the current tag token's tag name. Stay in the tag name state. */ + $chars = $this->stream->charsWhile(self::UPPER_ALPHA); + + $this->token['name'] .= strtolower($char . $chars); + $state = 'tag name'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-tag-name' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append the current input character to the current tag token's tag name. + Stay in the tag name state. */ + $chars = $this->stream->charsUntil("\t\n\x0C />" . self::UPPER_ALPHA); + + $this->token['name'] .= $char . $chars; + $state = 'tag name'; + } + break; + + case 'before attribute name': + /* Consume the next input character: */ + $char = $this->stream->char(); + + // this conditional is optimized, check bottom + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute name state. */ + $state = 'before attribute name'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the self-closing start tag state. */ + $state = 'self-closing start tag'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Start a new attribute in the current tag token. Set that + attribute's name to the lowercase version of the current + input character (add 0x0020 to the character's code + point), and its value to the empty string. Switch to the + attribute name state.*/ + $this->token['attr'][] = [ + 'name' => strtolower($char), + 'value' => '' + ]; + + $state = 'attribute name'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-attribute-name-but-got-eof' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* U+0022 QUOTATION MARK (") + U+0027 APOSTROPHE (') + U+003C LESS-THAN SIGN (<) + U+003D EQUALS SIGN (=) + Parse error. Treat it as per the "anything else" entry + below. */ + if ($char === '"' || $char === "'" || $char === '<' || $char === '=') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'invalid-character-in-attribute-name' + ]); + } + + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = [ + 'name' => $char, + 'value' => '' + ]; + + $state = 'attribute name'; + } + break; + + case 'attribute name': + // Consume the next input character: + $char = $this->stream->char(); + + // this conditional is optimized, check bottom + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the after attribute name state. */ + $state = 'after attribute name'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the self-closing start tag state. */ + $state = 'self-closing start tag'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $state = 'before attribute value'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Append the lowercase version of the current input + character (add 0x0020 to the character's code point) to + the current attribute's name. Stay in the attribute name + state. */ + $chars = $this->stream->charsWhile(self::UPPER_ALPHA); + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['name'] .= strtolower($char . $chars); + + $state = 'attribute name'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-attribute-name' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* U+0022 QUOTATION MARK (") + U+0027 APOSTROPHE (') + U+003C LESS-THAN SIGN (<) + Parse error. Treat it as per the "anything else" + entry below. */ + if ($char === '"' || $char === "'" || $char === '<') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'invalid-character-in-attribute-name' + ]); + } + + /* Anything else + Append the current input character to the current attribute's name. + Stay in the attribute name state. */ + $chars = $this->stream->charsUntil("\t\n\x0C /=>\"'" . self::UPPER_ALPHA); + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['name'] .= $char . $chars; + + $state = 'attribute name'; + } + + /* When the user agent leaves the attribute name state + (and before emitting the tag token, if appropriate), the + complete attribute's name must be compared to the other + attributes on the same token; if there is already an + attribute on the token with the exact same name, then this + is a parse error and the new attribute must be dropped, along + with the value that gets associated with it (if any). */ + // this might be implemented in the emitToken method + break; + + case 'after attribute name': + // Consume the next input character: + $char = $this->stream->char(); + + // this is an optimized conditional, check the bottom + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after attribute name state. */ + $state = 'after attribute name'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the self-closing start tag state. */ + $state = 'self-closing start tag'; + + } elseif ($char === '=') { + /* U+003D EQUALS SIGN (=) + Switch to the before attribute value state. */ + $state = 'before attribute value'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Start a new attribute in the current tag token. Set that + attribute's name to the lowercase version of the current + input character (add 0x0020 to the character's code + point), and its value to the empty string. Switch to the + attribute name state. */ + $this->token['attr'][] = [ + 'name' => strtolower($char), + 'value' => '' + ]; + + $state = 'attribute name'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-end-of-tag-but-got-eof' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* U+0022 QUOTATION MARK (") + U+0027 APOSTROPHE (') + U+003C LESS-THAN SIGN(<) + Parse error. Treat it as per the "anything else" + entry below. */ + if ($char === '"' || $char === "'" || $char === "<") { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'invalid-character-after-attribute-name' + ]); + } + + /* Anything else + Start a new attribute in the current tag token. Set that attribute's + name to the current input character, and its value to the empty string. + Switch to the attribute name state. */ + $this->token['attr'][] = [ + 'name' => $char, + 'value' => '' + ]; + + $state = 'attribute name'; + } + break; + + case 'before attribute value': + // Consume the next input character: + $char = $this->stream->char(); + + // this is an optimized conditional + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before attribute value state. */ + $state = 'before attribute value'; + + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the attribute value (double-quoted) state. */ + $state = 'attribute value (double-quoted)'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the attribute value (unquoted) state and reconsume + this input character. */ + $this->stream->unget(); + $state = 'attribute value (unquoted)'; + + } elseif ($char === '\'') { + /* U+0027 APOSTROPHE (') + Switch to the attribute value (single-quoted) state. */ + $state = 'attribute value (single-quoted)'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit the current tag token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-attribute-value-but-got-right-bracket' + ]); + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-attribute-value-but-got-eof' + ]); + $this->stream->unget(); + $state = 'data'; + + } else { + /* U+003D EQUALS SIGN (=) + * U+003C LESS-THAN SIGN (<) + Parse error. Treat it as per the "anything else" entry below. */ + if ($char === '=' || $char === '<') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'equals-in-unquoted-attribute-value' + ]); + } + + /* Anything else + Append the current input character to the current attribute's value. + Switch to the attribute value (unquoted) state. */ + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + $state = 'attribute value (unquoted)'; + } + break; + + case 'attribute value (double-quoted)': + // Consume the next input character: + $char = $this->stream->char(); + + if ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the after attribute value (quoted) state. */ + $state = 'after attribute value (quoted)'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the character reference in attribute value + state, with the additional allowed character + being U+0022 QUOTATION MARK ("). */ + $this->characterReferenceInAttributeValue('"'); + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-attribute-value-double-quote' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (double-quoted) state. */ + $chars = $this->stream->charsUntil('"&'); + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char . $chars; + + $state = 'attribute value (double-quoted)'; + } + break; + + case 'attribute value (single-quoted)': + // Consume the next input character: + $char = $this->stream->char(); + + if ($char === "'") { + /* U+0022 QUOTATION MARK (') + Switch to the after attribute value state. */ + $state = 'after attribute value (quoted)'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state. */ + $this->characterReferenceInAttributeValue("'"); + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-attribute-value-single-quote' + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (single-quoted) state. */ + $chars = $this->stream->charsUntil("'&"); + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char . $chars; + + $state = 'attribute value (single-quoted)'; + } + break; + + case 'attribute value (unquoted)': + // Consume the next input character: + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $state = 'before attribute name'; + + } elseif ($char === '&') { + /* U+0026 AMPERSAND (&) + Switch to the entity in attribute value state, with the + additional allowed character being U+003E + GREATER-THAN SIGN (>). */ + $this->characterReferenceInAttributeValue('>'); + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-attribute-value-no-quotes' + ]); + $this->stream->unget(); + $state = 'data'; + + } else { + /* U+0022 QUOTATION MARK (") + U+0027 APOSTROPHE (') + U+003C LESS-THAN SIGN (<) + U+003D EQUALS SIGN (=) + Parse error. Treat it as per the "anything else" + entry below. */ + if ($char === '"' || $char === "'" || $char === '=' || $char == '<') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-character-in-unquoted-attribute-value' + ]); + } + + /* Anything else + Append the current input character to the current attribute's value. + Stay in the attribute value (unquoted) state. */ + $chars = $this->stream->charsUntil("\t\n\x0c &>\"'="); + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char . $chars; + + $state = 'attribute value (unquoted)'; + } + break; + + case 'after attribute value (quoted)': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before attribute name state. */ + $state = 'before attribute name'; + + } elseif ($char === '/') { + /* U+002F SOLIDUS (/) + Switch to the self-closing start tag state. */ + $state = 'self-closing start tag'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current tag token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-EOF-after-attribute-value' + ]); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Parse error. Reconsume the character in the before attribute + name state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-character-after-attribute-value' + ]); + $this->stream->unget(); + $state = 'before attribute name'; + } + break; + + case 'self-closing start tag': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Set the self-closing flag of the current tag token. + Emit the current tag token. Switch to the data state. */ + // not sure if this is the name we want + $this->token['self-closing'] = true; + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Reconsume the EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-eof-after-self-closing' + ]); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Parse error. Reconsume the character in the before attribute name state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-character-after-self-closing' + ]); + $this->stream->unget(); + $state = 'before attribute name'; + } + break; + + case 'bogus comment': + /* (This can only happen if the content model flag is set to the PCDATA state.) */ + /* Consume every character up to the first U+003E GREATER-THAN SIGN + character (>) or the end of the file (EOF), whichever comes first. Emit + a comment token whose data is the concatenation of all the characters + starting from and including the character that caused the state machine + to switch into the bogus comment state, up to and including the last + consumed character before the U+003E character, if any, or up to the + end of the file otherwise. (If the comment was started by the end of + the file (EOF), the token is empty.) */ + $this->token['data'] .= (string) $this->stream->charsUntil('>'); + $this->stream->char(); + + $this->emitToken($this->token); + + /* Switch to the data state. */ + $state = 'data'; + break; + + case 'markup declaration open': + // Consume for below + $hyphens = $this->stream->charsWhile('-', 2); + if ($hyphens === '-') { + $this->stream->unget(); + } + if ($hyphens !== '--') { + $alpha = $this->stream->charsWhile(self::ALPHA, 7); + } + + /* If the next two characters are both U+002D HYPHEN-MINUS (-) + characters, consume those two characters, create a comment token whose + data is the empty string, and switch to the comment state. */ + if ($hyphens === '--') { + $state = 'comment start'; + $this->token = [ + 'data' => '', + 'type' => self::COMMENT + ]; + + /* Otherwise if the next seven characters are a case-insensitive match + for the word "DOCTYPE", then consume those characters and switch to the + DOCTYPE state. */ + } elseif (strtoupper($alpha) === 'DOCTYPE') { + $state = 'DOCTYPE'; + + // XXX not implemented + /* Otherwise, if the insertion mode is "in foreign content" + and the current node is not an element in the HTML namespace + and the next seven characters are an ASCII case-sensitive + match for the string "[CDATA[" (the five uppercase letters + "CDATA" with a U+005B LEFT SQUARE BRACKET character before + and after), then consume those characters and switch to the + CDATA section state (which is unrelated to the content model + flag's CDATA state). */ + + /* Otherwise, is is a parse error. Switch to the bogus comment state. + The next character that is consumed, if any, is the first character + that will be in the comment. */ + } else { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-dashes-or-doctype' + ]); + $this->token = [ + 'data' => (string) $alpha, + 'type' => self::COMMENT + ]; + $state = 'bogus comment'; + } + break; + + case 'comment start': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '-') { + /* U+002D HYPHEN-MINUS (-) + Switch to the comment start dash state. */ + $state = 'comment start dash'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit the comment token. Switch to the + data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'incorrect-comment' + ]); + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* EOF + Parse error. Emit the comment token. Reconsume the + EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Append the input character to the comment token's + data. Switch to the comment state. */ + $this->token['data'] .= $char; + $state = 'comment'; + } + break; + + case 'comment start dash': + /* Consume the next input character: */ + $char = $this->stream->char(); + if ($char === '-') { + /* U+002D HYPHEN-MINUS (-) + Switch to the comment end state */ + $state = 'comment end'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Emit the comment token. Switch to the + data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'incorrect-comment' + ]); + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* Parse error. Emit the comment token. Reconsume the + EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + $this->token['data'] .= '-' . $char; + $state = 'comment'; + } + break; + + case 'comment': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '-') { + /* U+002D HYPHEN-MINUS (-) + Switch to the comment end dash state */ + $state = 'comment end dash'; + + } elseif ($char === false) { + /* EOF + Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append the input character to the comment token's data. Stay in + the comment state. */ + $chars = $this->stream->charsUntil('-'); + + $this->token['data'] .= $char . $chars; + } + break; + + case 'comment end dash': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '-') { + /* U+002D HYPHEN-MINUS (-) + Switch to the comment end state */ + $state = 'comment end'; + + } elseif ($char === false) { + /* EOF + Parse error. Emit the comment token. Reconsume the EOF character + in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment-end-dash' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append a U+002D HYPHEN-MINUS (-) character and the input + character to the comment token's data. Switch to the comment state. */ + $this->token['data'] .= '-'.$char; + $state = 'comment'; + } + break; + + case 'comment end': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the comment token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === '-') { + /* U+002D HYPHEN-MINUS (-) + Parse error. Append a U+002D HYPHEN-MINUS (-) character + to the comment token's data. Stay in the comment end + state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-dash-after-double-dash-in-comment' + ]); + $this->token['data'] .= '-'; + + } elseif ($char === "\t" || $char === "\n" || $char === "\x0a" || $char === ' ') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-space-after-double-dash-in-comment' + ]); + $this->token['data'] .= '--' . $char; + $state = 'comment end space'; + + } elseif ($char === '!') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-bang-after-double-dash-in-comment' + ]); + $state = 'comment end bang'; + + } elseif ($char === false) { + /* EOF + Parse error. Emit the comment token. Reconsume the + EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment-double-dash' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Parse error. Append two U+002D HYPHEN-MINUS (-) + characters and the input character to the comment token's + data. Switch to the comment state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-comment' + ]); + $this->token['data'] .= '--'.$char; + $state = 'comment'; + } + break; + + case 'comment end bang': + $char = $this->stream->char(); + if ($char === '>') { + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === "-") { + $this->token['data'] .= '--!'; + $state = 'comment end dash'; + } elseif ($char === false) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-comment-end-bang' + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + $this->token['data'] .= '--!' . $char; + $state = 'comment'; + } + break; + + case 'comment end space': + $char = $this->stream->char(); + if ($char === '>') { + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === '-') { + $state = 'comment end dash'; + } elseif ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + $this->token['data'] .= $char; + } elseif ($char === false) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-eof-in-comment-end-space', + ]); + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + $this->token['data'] .= $char; + $state = 'comment'; + } + break; + + case 'DOCTYPE': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the before DOCTYPE name state. */ + $state = 'before DOCTYPE name'; + + } elseif ($char === false) { + /* EOF + Parse error. Create a new DOCTYPE token. Set its + force-quirks flag to on. Emit the token. Reconsume the + EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'need-space-after-doctype-but-got-eof' + ]); + $this->emitToken([ + 'name' => '', + 'type' => self::DOCTYPE, + 'force-quirks' => true, + 'error' => true + ]); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Parse error. Reconsume the current character in the + before DOCTYPE name state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'need-space-after-doctype' + ]); + $this->stream->unget(); + $state = 'before DOCTYPE name'; + } + break; + + case 'before DOCTYPE name': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before DOCTYPE name state. */ + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Create a new DOCTYPE token. Set its + force-quirks flag to on. Emit the token. Switch to the + data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-doctype-name-but-got-right-bracket' + ]); + $this->emitToken([ + 'name' => '', + 'type' => self::DOCTYPE, + 'force-quirks' => true, + 'error' => true + ]); + + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Create a new DOCTYPE token. Set the token's name to the + lowercase version of the input character (add 0x0020 to + the character's code point). Switch to the DOCTYPE name + state. */ + $this->token = [ + 'name' => strtolower($char), + 'type' => self::DOCTYPE, + 'error' => true + ]; + + $state = 'DOCTYPE name'; + + } elseif ($char === false) { + /* EOF + Parse error. Create a new DOCTYPE token. Set its + force-quirks flag to on. Emit the token. Reconsume the + EOF character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-doctype-name-but-got-eof' + ]); + $this->emitToken([ + 'name' => '', + 'type' => self::DOCTYPE, + 'force-quirks' => true, + 'error' => true + ]); + + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Create a new DOCTYPE token. Set the token's name to the + current input character. Switch to the DOCTYPE name state. */ + $this->token = [ + 'name' => $char, + 'type' => self::DOCTYPE, + 'error' => true + ]; + + $state = 'DOCTYPE name'; + } + break; + + case 'DOCTYPE name': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Switch to the after DOCTYPE name state. */ + $state = 'after DOCTYPE name'; + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current DOCTYPE token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ('A' <= $char && $char <= 'Z') { + /* U+0041 LATIN CAPITAL LETTER A through to U+005A LATIN CAPITAL LETTER Z + Append the lowercase version of the input character + (add 0x0020 to the character's code point) to the current + DOCTYPE token's name. Stay in the DOCTYPE name state. */ + $this->token['name'] .= strtolower($char); + + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype-name' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Append the current input character to the current + DOCTYPE token's name. Stay in the DOCTYPE name state. */ + $this->token['name'] .= $char; + } + + // XXX this is probably some sort of quirks mode designation, + // check tree-builder to be sure. In general 'error' needs + // to be specc'ified, this probably means removing it at the end + $this->token['error'] = ($this->token['name'] === 'HTML') + ? false + : true; + break; + + case 'after DOCTYPE name': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after DOCTYPE name state. */ + + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current DOCTYPE token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else */ + + $nextSix = strtoupper($char . $this->stream->charsWhile(self::ALPHA, 5)); + if ($nextSix === 'PUBLIC') { + /* If the next six characters are an ASCII + case-insensitive match for the word "PUBLIC", then + consume those characters and switch to the before + DOCTYPE public identifier state. */ + $state = 'before DOCTYPE public identifier'; + + } elseif ($nextSix === 'SYSTEM') { + /* Otherwise, if the next six characters are an ASCII + case-insensitive match for the word "SYSTEM", then + consume those characters and switch to the before + DOCTYPE system identifier state. */ + $state = 'before DOCTYPE system identifier'; + + } else { + /* Otherwise, this is the parse error. Set the DOCTYPE + token's force-quirks flag to on. Switch to the bogus + DOCTYPE state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-space-or-right-bracket-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->token['error'] = true; + $state = 'bogus DOCTYPE'; + } + } + break; + + case 'before DOCTYPE public identifier': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before DOCTYPE public identifier state. */ + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Set the DOCTYPE token's public identifier to the empty + string (not missing), then switch to the DOCTYPE public + identifier (double-quoted) state. */ + $this->token['public'] = ''; + $state = 'DOCTYPE public identifier (double-quoted)'; + } elseif ($char === "'") { + /* U+0027 APOSTROPHE (') + Set the DOCTYPE token's public identifier to the empty + string (not missing), then switch to the DOCTYPE public + identifier (single-quoted) state. */ + $this->token['public'] = ''; + $state = 'DOCTYPE public identifier (single-quoted)'; + } elseif ($char === '>') { + /* Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-end-of-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* Parse error. Set the DOCTYPE token's force-quirks + flag to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Parse error. Set the DOCTYPE token's force-quirks flag + to on. Switch to the bogus DOCTYPE state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-doctype' + ]); + $this->token['force-quirks'] = true; + $state = 'bogus DOCTYPE'; + } + break; + + case 'DOCTYPE public identifier (double-quoted)': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the after DOCTYPE public identifier state. */ + $state = 'after DOCTYPE public identifier'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-end-of-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Append the current input character to the current + DOCTYPE token's public identifier. Stay in the DOCTYPE + public identifier (double-quoted) state. */ + $this->token['public'] .= $char; + } + break; + + case 'DOCTYPE public identifier (single-quoted)': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "'") { + /* U+0027 APOSTROPHE (') + Switch to the after DOCTYPE public identifier state. */ + $state = 'after DOCTYPE public identifier'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-end-of-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Append the current input character to the current + DOCTYPE token's public identifier. Stay in the DOCTYPE + public identifier (double-quoted) state. */ + $this->token['public'] .= $char; + } + break; + + case 'after DOCTYPE public identifier': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after DOCTYPE public identifier state. */ + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Set the DOCTYPE token's system identifier to the + empty string (not missing), then switch to the DOCTYPE + system identifier (double-quoted) state. */ + $this->token['system'] = ''; + $state = 'DOCTYPE system identifier (double-quoted)'; + } elseif ($char === "'") { + /* U+0027 APOSTROPHE (') + Set the DOCTYPE token's system identifier to the + empty string (not missing), then switch to the DOCTYPE + system identifier (single-quoted) state. */ + $this->token['system'] = ''; + $state = 'DOCTYPE system identifier (single-quoted)'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current DOCTYPE token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* Parse error. Set the DOCTYPE token's force-quirks + flag to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Switch to the bogus DOCTYPE state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-doctype' + ]); + $this->token['force-quirks'] = true; + $state = 'bogus DOCTYPE'; + } + break; + + case 'before DOCTYPE system identifier': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the before DOCTYPE system identifier state. */ + } elseif ($char === '"') { + /* U+0022 QUOTATION MARK (") + Set the DOCTYPE token's system identifier to the empty + string (not missing), then switch to the DOCTYPE system + identifier (double-quoted) state. */ + $this->token['system'] = ''; + $state = 'DOCTYPE system identifier (double-quoted)'; + } elseif ($char === "'") { + /* U+0027 APOSTROPHE (') + Set the DOCTYPE token's system identifier to the empty + string (not missing), then switch to the DOCTYPE system + identifier (single-quoted) state. */ + $this->token['system'] = ''; + $state = 'DOCTYPE system identifier (single-quoted)'; + } elseif ($char === '>') { + /* Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* Parse error. Set the DOCTYPE token's force-quirks + flag to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Parse error. Set the DOCTYPE token's force-quirks flag + to on. Switch to the bogus DOCTYPE state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-doctype' + ]); + $this->token['force-quirks'] = true; + $state = 'bogus DOCTYPE'; + } + break; + + case 'DOCTYPE system identifier (double-quoted)': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '"') { + /* U+0022 QUOTATION MARK (") + Switch to the after DOCTYPE system identifier state. */ + $state = 'after DOCTYPE system identifier'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-end-of-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Append the current input character to the current + DOCTYPE token's system identifier. Stay in the DOCTYPE + system identifier (double-quoted) state. */ + $this->token['system'] .= $char; + } + break; + + case 'DOCTYPE system identifier (single-quoted)': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "'") { + /* U+0027 APOSTROPHE (') + Switch to the after DOCTYPE system identifier state. */ + $state = 'after DOCTYPE system identifier'; + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Switch to the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-end-of-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* EOF + Parse error. Set the DOCTYPE token's force-quirks flag + to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Append the current input character to the current + DOCTYPE token's system identifier. Stay in the DOCTYPE + system identifier (double-quoted) state. */ + $this->token['system'] .= $char; + } + break; + + case 'after DOCTYPE system identifier': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === "\t" || $char === "\n" || $char === "\x0c" || $char === ' ') { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + Stay in the after DOCTYPE system identifier state. */ + } elseif ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the current DOCTYPE token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + } elseif ($char === false) { + /* Parse error. Set the DOCTYPE token's force-quirks + flag to on. Emit that DOCTYPE token. Reconsume the EOF + character in the data state. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'eof-in-doctype' + ]); + $this->token['force-quirks'] = true; + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + } else { + /* Anything else + Parse error. Switch to the bogus DOCTYPE state. + (This does not set the DOCTYPE token's force-quirks + flag to on.) */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'unexpected-char-in-doctype' + ]); + $state = 'bogus DOCTYPE'; + } + break; + + case 'bogus DOCTYPE': + /* Consume the next input character: */ + $char = $this->stream->char(); + + if ($char === '>') { + /* U+003E GREATER-THAN SIGN (>) + Emit the DOCTYPE token. Switch to the data state. */ + $this->emitToken($this->token); + $state = 'data'; + + } elseif ($char === false) { + /* EOF + Emit the DOCTYPE token. Reconsume the EOF character in + the data state. */ + $this->emitToken($this->token); + $this->stream->unget(); + $state = 'data'; + + } else { + /* Anything else + Stay in the bogus DOCTYPE state. */ + } + break; + + // case 'cdataSection': + } + } + } + + /** + * Returns a serialized representation of the tree. + * + * @return DOMDocument|DOMNodeList + */ + public function save() { + return $this->tree->save(); + } + + /** + * @return HTML5_TreeBuilder The tree + */ + public function getTree() + { + return $this->tree; + } + + + /** + * Returns the input stream. + * + * @return HTML5_InputStream + */ + public function stream() { + return $this->stream; + } + + /** + * @param bool $allowed + * @param bool $inattr + * @return string + */ + private function consumeCharacterReference($allowed = false, $inattr = false) { + // This goes quite far against spec, and is far closer to the Python + // impl., mainly because we don't do the large unconsuming the spec + // requires. + + // All consumed characters. + $chars = $this->stream->char(); + + /* This section defines how to consume a character + reference. This definition is used when parsing character + references in text and in attributes. + + The behavior depends on the identity of the next character + (the one immediately after the U+0026 AMPERSAND character): */ + + if ( + $chars[0] === "\x09" || + $chars[0] === "\x0A" || + $chars[0] === "\x0C" || + $chars[0] === "\x20" || + $chars[0] === '<' || + $chars[0] === '&' || + $chars === false || + $chars[0] === $allowed + ) { + /* U+0009 CHARACTER TABULATION + U+000A LINE FEED (LF) + U+000C FORM FEED (FF) + U+0020 SPACE + U+003C LESS-THAN SIGN + U+0026 AMPERSAND + EOF + The additional allowed character, if there is one + Not a character reference. No characters are consumed, + and nothing is returned. (This is not an error, either.) */ + // We already consumed, so unconsume. + $this->stream->unget(); + return '&'; + } elseif ($chars[0] === '#') { + /* Consume the U+0023 NUMBER SIGN. */ + // Um, yeah, we already did that. + /* The behavior further depends on the character after + the U+0023 NUMBER SIGN: */ + $chars .= $this->stream->char(); + if (isset($chars[1]) && ($chars[1] === 'x' || $chars[1] === 'X')) { + /* U+0078 LATIN SMALL LETTER X + U+0058 LATIN CAPITAL LETTER X */ + /* Consume the X. */ + // Um, yeah, we already did that. + /* Follow the steps below, but using the range of + characters U+0030 DIGIT ZERO through to U+0039 DIGIT + NINE, U+0061 LATIN SMALL LETTER A through to U+0066 + LATIN SMALL LETTER F, and U+0041 LATIN CAPITAL LETTER + A, through to U+0046 LATIN CAPITAL LETTER F (in other + words, 0123456789, ABCDEF, abcdef). */ + $char_class = self::HEX; + /* When it comes to interpreting the + number, interpret it as a hexadecimal number. */ + $hex = true; + } else { + /* Anything else */ + // Unconsume because we shouldn't have consumed this. + $chars = $chars[0]; + $this->stream->unget(); + /* Follow the steps below, but using the range of + characters U+0030 DIGIT ZERO through to U+0039 DIGIT + NINE (i.e. just 0123456789). */ + $char_class = self::DIGIT; + /* When it comes to interpreting the number, + interpret it as a decimal number. */ + $hex = false; + } + + /* Consume as many characters as match the range of characters given above. */ + $consumed = $this->stream->charsWhile($char_class); + if ($consumed === '' || $consumed === false) { + /* If no characters match the range, then don't consume + any characters (and unconsume the U+0023 NUMBER SIGN + character and, if appropriate, the X character). This + is a parse error; nothing is returned. */ + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-numeric-entity' + ]); + return '&' . $chars; + } else { + /* Otherwise, if the next character is a U+003B SEMICOLON, + consume that too. If it isn't, there is a parse error. */ + if ($this->stream->char() !== ';') { + $this->stream->unget(); + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'numeric-entity-without-semicolon' + ]); + } + + /* If one or more characters match the range, then take + them all and interpret the string of characters as a number + (either hexadecimal or decimal as appropriate). */ + $codepoint = $hex ? hexdec($consumed) : (int) $consumed; + + /* If that number is one of the numbers in the first column + of the following table, then this is a parse error. Find the + row with that number in the first column, and return a + character token for the Unicode character given in the + second column of that row. */ + $new_codepoint = HTML5_Data::getRealCodepoint($codepoint); + if ($new_codepoint) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'illegal-windows-1252-entity' + ]); + return HTML5_Data::utf8chr($new_codepoint); + } else { + /* Otherwise, if the number is greater than 0x10FFFF, then + * this is a parse error. Return a U+FFFD REPLACEMENT + * CHARACTER. */ + if ($codepoint > 0x10FFFF) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'overlong-character-entity' // XXX probably not correct + ]); + return "\xEF\xBF\xBD"; + } + /* Otherwise, return a character token for the Unicode + * character whose code point is that number. If the + * number is in the range 0x0001 to 0x0008, 0x000E to + * 0x001F, 0x007F to 0x009F, 0xD800 to 0xDFFF, 0xFDD0 to + * 0xFDEF, or is one of 0x000B, 0xFFFE, 0xFFFF, 0x1FFFE, + * 0x1FFFF, 0x2FFFE, 0x2FFFF, 0x3FFFE, 0x3FFFF, 0x4FFFE, + * 0x4FFFF, 0x5FFFE, 0x5FFFF, 0x6FFFE, 0x6FFFF, 0x7FFFE, + * 0x7FFFF, 0x8FFFE, 0x8FFFF, 0x9FFFE, 0x9FFFF, 0xAFFFE, + * 0xAFFFF, 0xBFFFE, 0xBFFFF, 0xCFFFE, 0xCFFFF, 0xDFFFE, + * 0xDFFFF, 0xEFFFE, 0xEFFFF, 0xFFFFE, 0xFFFFF, 0x10FFFE, + * or 0x10FFFF, then this is a parse error. */ + // && has higher precedence than || + if ( + $codepoint >= 0x0000 && $codepoint <= 0x0008 || + $codepoint === 0x000B || + $codepoint >= 0x000E && $codepoint <= 0x001F || + $codepoint >= 0x007F && $codepoint <= 0x009F || + $codepoint >= 0xD800 && $codepoint <= 0xDFFF || + $codepoint >= 0xFDD0 && $codepoint <= 0xFDEF || + ($codepoint & 0xFFFE) === 0xFFFE || + $codepoint == 0x10FFFF || $codepoint == 0x10FFFE + ) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'illegal-codepoint-for-numeric-entity' + ]); + } + return HTML5_Data::utf8chr($codepoint); + } + } + } else { + /* Anything else */ + + /* Consume the maximum number of characters possible, + with the consumed characters matching one of the + identifiers in the first column of the named character + references table (in a case-sensitive manner). */ + // What we actually do here is consume as much as we can while it + // matches the start of one of the identifiers in the first column. + + $refs = HTML5_Data::getNamedCharacterReferences(); + + // Get the longest string which is the start of an identifier + // ($chars) as well as the longest identifier which matches ($id) + // and its codepoint ($codepoint). + $codepoint = false; + $char = $chars; + while ($char !== false && isset($refs[$char])) { + $refs = $refs[$char]; + if (isset($refs['codepoint'])) { + $id = $chars; + $codepoint = $refs['codepoint']; + } + $chars .= $char = $this->stream->char(); + } + + // Unconsume the one character we just took which caused the while + // statement to fail. This could be anything and could cause state + // changes (as if it matches the while loop it must be + // alphanumeric so we can just concat it to whatever we get later). + $this->stream->unget(); + if ($char !== false) { + $chars = substr($chars, 0, -1); + } + + /* If no match can be made, then this is a parse error. + No characters are consumed, and nothing is returned. */ + if (!$codepoint) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'expected-named-entity' + ]); + return '&' . $chars; + } + + /* If the last character matched is not a U+003B SEMICOLON + (;), there is a parse error. */ + $semicolon = true; + if (substr($id, -1) !== ';') { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'named-entity-without-semicolon' + ]); + $semicolon = false; + } + + /* If the character reference is being consumed as part of + an attribute, and the last character matched is not a + U+003B SEMICOLON (;), and the next character is in the + range U+0030 DIGIT ZERO to U+0039 DIGIT NINE, U+0041 + LATIN CAPITAL LETTER A to U+005A LATIN CAPITAL LETTER Z, + or U+0061 LATIN SMALL LETTER A to U+007A LATIN SMALL LETTER Z, + then, for historical reasons, all the characters that were + matched after the U+0026 AMPERSAND (&) must be unconsumed, + and nothing is returned. */ + if ($inattr && !$semicolon) { + // The next character is either the next character in $chars or in the stream. + if (strlen($chars) > strlen($id)) { + $next = substr($chars, strlen($id), 1); + } else { + $next = $this->stream->char(); + $this->stream->unget(); + } + if ( + '0' <= $next && $next <= '9' || + 'A' <= $next && $next <= 'Z' || + 'a' <= $next && $next <= 'z' + ) { + return '&' . $chars; + } + } + + /* Otherwise, return a character token for the character + corresponding to the character reference name (as given + by the second column of the named character references table). */ + return HTML5_Data::utf8chr($codepoint) . substr($chars, strlen($id)); + } + } + + /** + * @param bool $allowed + */ + private function characterReferenceInAttributeValue($allowed = false) { + /* Attempt to consume a character reference. */ + $entity = $this->consumeCharacterReference($allowed, true); + + /* If nothing is returned, append a U+0026 AMPERSAND + character to the current attribute's value. + + Otherwise, append the returned character token to the + current attribute's value. */ + $char = (!$entity) + ? '&' + : $entity; + + $last = count($this->token['attr']) - 1; + $this->token['attr'][$last]['value'] .= $char; + + /* Finally, switch back to the attribute value state that you + were in when were switched into this state. */ + } + + /** + * Emits a token, passing it on to the tree builder. + * + * @param $token + * @param bool $checkStream + * @param bool $dry + */ + protected function emitToken($token, $checkStream = true, $dry = false) { + if ($checkStream === true) { + // Emit errors from input stream. + while ($this->stream->errors) { + $this->emitToken(array_shift($this->stream->errors), false); + } + } + if ($token['type'] === self::ENDTAG && !empty($token['attr'])) { + for ($i = 0; $i < count($token['attr']); $i++) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'attributes-in-end-tag' + ]); + } + } + if ($token['type'] === self::ENDTAG && !empty($token['self-closing'])) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'self-closing-flag-on-end-tag', + ]); + } + if ($token['type'] === self::STARTTAG) { + // This could be changed to actually pass the tree-builder a hash + $hash = []; + foreach ($token['attr'] as $keypair) { + if (isset($hash[$keypair['name']])) { + $this->emitToken([ + 'type' => self::PARSEERROR, + 'data' => 'duplicate-attribute', + ]); + } else { + $hash[$keypair['name']] = $keypair['value']; + } + } + } + + if ($dry === false) { + // the current structure of attributes is not a terribly good one + $this->tree->emitToken($token); + } + + if ($dry === false && is_int($this->tree->content_model)) { + $this->content_model = $this->tree->content_model; + $this->tree->content_model = null; + + } elseif ($token['type'] === self::ENDTAG) { + $this->content_model = self::PCDATA; + } + } +} + diff --git a/vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php b/vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php new file mode 100644 index 0000000..993eabd --- /dev/null +++ b/vendor/dompdf/dompdf/lib/html5lib/TreeBuilder.php @@ -0,0 +1,3989 @@ + +Copyright 2009 Edward Z. Yang + +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. + +*/ + +// Tags for FIX ME!!!: (in order of priority) +// XXX - should be fixed NAO! +// XERROR - with regards to parse errors +// XSCRIPT - with regards to scripting mode +// XENCODING - with regards to encoding (for reparsing tests) +// XDOM - DOM specific code (tagName is explicitly not marked). +// this is not (yet) in helper functions. + +class HTML5_TreeBuilder { + public $stack = []; + public $content_model; + + private $mode; + private $original_mode; + private $secondary_mode; + private $dom; + // Whether or not normal insertion of nodes should actually foster + // parent (used in one case in spec) + private $foster_parent = false; + private $a_formatting = []; + + private $head_pointer = null; + private $form_pointer = null; + + private $flag_frameset_ok = true; + private $flag_force_quirks = false; + private $ignored = false; + private $quirks_mode = null; + // this gets to 2 when we want to ignore the next lf character, and + // is decrement at the beginning of each processed token (this way, + // code can check for (bool)$ignore_lf_token, but it phases out + // appropriately) + private $ignore_lf_token = 0; + private $fragment = false; + private $root; + + private $scoping = ['applet','button','caption','html','marquee','object','table','td','th', 'svg:foreignObject']; + private $formatting = ['a','b','big','code','em','font','i','nobr','s','small','strike','strong','tt','u']; + // dl and ds are speculative + private $special = ['address','area','article','aside','base','basefont','bgsound', + 'blockquote','body','br','center','col','colgroup','command','dc','dd','details','dir','div','dl','ds', + 'dt','embed','fieldset','figure','footer','form','frame','frameset','h1','h2','h3','h4','h5', + 'h6','head','header','hgroup','hr','iframe','img','input','isindex','li','link', + 'listing','menu','meta','nav','noembed','noframes','noscript','ol', + 'p','param','plaintext','pre','script','select','spacer','style', + 'tbody','textarea','tfoot','thead','title','tr','ul','wbr']; + + private $pendingTableCharacters; + private $pendingTableCharactersDirty; + + // Tree construction modes + const INITIAL = 0; + const BEFORE_HTML = 1; + const BEFORE_HEAD = 2; + const IN_HEAD = 3; + const IN_HEAD_NOSCRIPT = 4; + const AFTER_HEAD = 5; + const IN_BODY = 6; + const IN_CDATA_RCDATA = 7; + const IN_TABLE = 8; + const IN_TABLE_TEXT = 9; + const IN_CAPTION = 10; + const IN_COLUMN_GROUP = 11; + const IN_TABLE_BODY = 12; + const IN_ROW = 13; + const IN_CELL = 14; + const IN_SELECT = 15; + const IN_SELECT_IN_TABLE= 16; + const IN_FOREIGN_CONTENT= 17; + const AFTER_BODY = 18; + const IN_FRAMESET = 19; + const AFTER_FRAMESET = 20; + const AFTER_AFTER_BODY = 21; + const AFTER_AFTER_FRAMESET = 22; + + /** + * Converts a magic number to a readable name. Use for debugging. + */ + private function strConst($number) { + static $lookup; + if (!$lookup) { + $lookup = []; + $r = new ReflectionClass('HTML5_TreeBuilder'); + $consts = $r->getConstants(); + foreach ($consts as $const => $num) { + if (!is_int($num)) { + continue; + } + $lookup[$num] = $const; + } + } + return $lookup[$number]; + } + + // The different types of elements. + const SPECIAL = 100; + const SCOPING = 101; + const FORMATTING = 102; + const PHRASING = 103; + + // Quirks modes in $quirks_mode + const NO_QUIRKS = 200; + const QUIRKS_MODE = 201; + const LIMITED_QUIRKS_MODE = 202; + + // Marker to be placed in $a_formatting + const MARKER = 300; + + // Namespaces for foreign content + const NS_HTML = null; // to prevent DOM from requiring NS on everything + const NS_MATHML = 'http://www.w3.org/1998/Math/MathML'; + const NS_SVG = 'http://www.w3.org/2000/svg'; + const NS_XLINK = 'http://www.w3.org/1999/xlink'; + const NS_XML = 'http://www.w3.org/XML/1998/namespace'; + const NS_XMLNS = 'http://www.w3.org/2000/xmlns/'; + + // Different types of scopes to test for elements + const SCOPE = 0; + const SCOPE_LISTITEM = 1; + const SCOPE_TABLE = 2; + + /** + * HTML5_TreeBuilder constructor. + */ + public function __construct() { + $this->mode = self::INITIAL; + $this->dom = new DOMDocument; + + $this->dom->encoding = 'UTF-8'; + $this->dom->preserveWhiteSpace = true; + $this->dom->substituteEntities = true; + $this->dom->strictErrorChecking = false; + } + + public function getQuirksMode(){ + return $this->quirks_mode; + } + + /** + * Process tag tokens + * + * @param $token + * @param null $mode + */ + public function emitToken($token, $mode = null) { + // XXX: ignore parse errors... why are we emitting them, again? + if ($token['type'] === HTML5_Tokenizer::PARSEERROR) { + return; + } + if ($mode === null) { + $mode = $this->mode; + } + + /* + $backtrace = debug_backtrace(); + if ($backtrace[1]['class'] !== 'HTML5_TreeBuilder') echo "--\n"; + echo $this->strConst($mode); + if ($this->original_mode) echo " (originally ".$this->strConst($this->original_mode).")"; + echo "\n "; + token_dump($token); + $this->printStack(); + $this->printActiveFormattingElements(); + if ($this->foster_parent) echo " -> this is a foster parent mode\n"; + if ($this->flag_frameset_ok) echo " -> frameset ok\n"; + */ + + if ($this->ignore_lf_token) { + $this->ignore_lf_token--; + } + $this->ignored = false; + + switch ($mode) { + case self::INITIAL: + + /* A character token that is one of U+0009 CHARACTER TABULATION, + * U+000A LINE FEED (LF), U+000C FORM FEED (FF), or U+0020 SPACE */ + if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { + /* Ignore the token. */ + $this->ignored = true; + } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + if ( + $token['name'] !== 'html' || !empty($token['public']) || + !empty($token['system']) || $token !== 'about:legacy-compat' + ) { + /* If the DOCTYPE token's name is not a case-sensitive match + * for the string "html", or if the token's public identifier + * is not missing, or if the token's system identifier is + * neither missing nor a case-sensitive match for the string + * "about:legacy-compat", then there is a parse error (this + * is the DOCTYPE parse error). */ + // DOCTYPE parse error + } + /* Append a DocumentType node to the Document node, with the name + * attribute set to the name given in the DOCTYPE token, or the + * empty string if the name was missing; the publicId attribute + * set to the public identifier given in the DOCTYPE token, or + * the empty string if the public identifier was missing; the + * systemId attribute set to the system identifier given in the + * DOCTYPE token, or the empty string if the system identifier + * was missing; and the other attributes specific to + * DocumentType objects set to null and empty lists as + * appropriate. Associate the DocumentType node with the + * Document object so that it is returned as the value of the + * doctype attribute of the Document object. */ + if (!isset($token['public'])) { + $token['public'] = null; + } + if (!isset($token['system'])) { + $token['system'] = null; + } + // XDOM + // Yes this is hacky. I'm kind of annoyed that I can't appendChild + // a doctype to DOMDocument. Maybe I haven't chanted the right + // syllables. + $impl = new DOMImplementation(); + // This call can fail for particularly pathological cases (namely, + // the qualifiedName parameter ($token['name']) could be missing. + if ($token['name']) { + $doctype = $impl->createDocumentType($token['name'], $token['public'], $token['system']); + $this->dom->appendChild($doctype); + } else { + // It looks like libxml's not actually *able* to express this case. + // So... don't. + $this->dom->emptyDoctype = true; + } + $public = is_null($token['public']) ? false : strtolower($token['public']); + $system = is_null($token['system']) ? false : strtolower($token['system']); + $publicStartsWithForQuirks = [ + "+//silmaril//dtd html pro v0r11 19970101//", + "-//advasoft ltd//dtd html 3.0 aswedit + extensions//", + "-//as//dtd html 3.0 aswedit + extensions//", + "-//ietf//dtd html 2.0 level 1//", + "-//ietf//dtd html 2.0 level 2//", + "-//ietf//dtd html 2.0 strict level 1//", + "-//ietf//dtd html 2.0 strict level 2//", + "-//ietf//dtd html 2.0 strict//", + "-//ietf//dtd html 2.0//", + "-//ietf//dtd html 2.1e//", + "-//ietf//dtd html 3.0//", + "-//ietf//dtd html 3.2 final//", + "-//ietf//dtd html 3.2//", + "-//ietf//dtd html 3//", + "-//ietf//dtd html level 0//", + "-//ietf//dtd html level 1//", + "-//ietf//dtd html level 2//", + "-//ietf//dtd html level 3//", + "-//ietf//dtd html strict level 0//", + "-//ietf//dtd html strict level 1//", + "-//ietf//dtd html strict level 2//", + "-//ietf//dtd html strict level 3//", + "-//ietf//dtd html strict//", + "-//ietf//dtd html//", + "-//metrius//dtd metrius presentational//", + "-//microsoft//dtd internet explorer 2.0 html strict//", + "-//microsoft//dtd internet explorer 2.0 html//", + "-//microsoft//dtd internet explorer 2.0 tables//", + "-//microsoft//dtd internet explorer 3.0 html strict//", + "-//microsoft//dtd internet explorer 3.0 html//", + "-//microsoft//dtd internet explorer 3.0 tables//", + "-//netscape comm. corp.//dtd html//", + "-//netscape comm. corp.//dtd strict html//", + "-//o'reilly and associates//dtd html 2.0//", + "-//o'reilly and associates//dtd html extended 1.0//", + "-//o'reilly and associates//dtd html extended relaxed 1.0//", + "-//spyglass//dtd html 2.0 extended//", + "-//sq//dtd html 2.0 hotmetal + extensions//", + "-//sun microsystems corp.//dtd hotjava html//", + "-//sun microsystems corp.//dtd hotjava strict html//", + "-//w3c//dtd html 3 1995-03-24//", + "-//w3c//dtd html 3.2 draft//", + "-//w3c//dtd html 3.2 final//", + "-//w3c//dtd html 3.2//", + "-//w3c//dtd html 3.2s draft//", + "-//w3c//dtd html 4.0 frameset//", + "-//w3c//dtd html 4.0 transitional//", + "-//w3c//dtd html experimental 19960712//", + "-//w3c//dtd html experimental 970421//", + "-//w3c//dtd w3 html//", + "-//w3o//dtd w3 html 3.0//", + "-//webtechs//dtd mozilla html 2.0//", + "-//webtechs//dtd mozilla html//", + ]; + $publicSetToForQuirks = [ + "-//w3o//dtd w3 html strict 3.0//", + "-/w3c/dtd html 4.0 transitional/en", + "html", + ]; + $publicStartsWithAndSystemForQuirks = [ + "-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//", + ]; + $publicStartsWithForLimitedQuirks = [ + "-//w3c//dtd xhtml 1.0 frameset//", + "-//w3c//dtd xhtml 1.0 transitional//", + ]; + $publicStartsWithAndSystemForLimitedQuirks = [ + "-//w3c//dtd html 4.01 frameset//", + "-//w3c//dtd html 4.01 transitional//", + ]; + // first, do easy checks + if ( + !empty($token['force-quirks']) || + strtolower($token['name']) !== 'html' + ) { + $this->quirks_mode = self::QUIRKS_MODE; + } else { + do { + if ($system) { + foreach ($publicStartsWithAndSystemForQuirks as $x) { + if (strncmp($public, $x, strlen($x)) === 0) { + $this->quirks_mode = self::QUIRKS_MODE; + break; + } + } + if (!is_null($this->quirks_mode)) { + break; + } + foreach ($publicStartsWithAndSystemForLimitedQuirks as $x) { + if (strncmp($public, $x, strlen($x)) === 0) { + $this->quirks_mode = self::LIMITED_QUIRKS_MODE; + break; + } + } + if (!is_null($this->quirks_mode)) { + break; + } + } + foreach ($publicSetToForQuirks as $x) { + if ($public === $x) { + $this->quirks_mode = self::QUIRKS_MODE; + break; + } + } + if (!is_null($this->quirks_mode)) { + break; + } + foreach ($publicStartsWithForLimitedQuirks as $x) { + if (strncmp($public, $x, strlen($x)) === 0) { + $this->quirks_mode = self::LIMITED_QUIRKS_MODE; + } + } + if (!is_null($this->quirks_mode)) { + break; + } + if ($system === "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd") { + $this->quirks_mode = self::QUIRKS_MODE; + break; + } + foreach ($publicStartsWithForQuirks as $x) { + if (strncmp($public, $x, strlen($x)) === 0) { + $this->quirks_mode = self::QUIRKS_MODE; + break; + } + } + if (is_null($this->quirks_mode)) { + $this->quirks_mode = self::NO_QUIRKS; + } + } while (false); + } + $this->mode = self::BEFORE_HTML; + } else { + // parse error + /* Switch the insertion mode to "before html", then reprocess the + * current token. */ + $this->mode = self::BEFORE_HTML; + $this->quirks_mode = self::QUIRKS_MODE; + $this->emitToken($token); + } + break; + + case self::BEFORE_HTML: + /* A DOCTYPE token */ + if ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + // Parse error. Ignore the token. + $this->ignored = true; + + /* A comment token */ + } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) { + /* Append a Comment node to the Document object with the data + attribute set to the data given in the comment token. */ + // XDOM + $comment = $this->dom->createComment($token['data']); + $this->dom->appendChild($comment); + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + } elseif ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { + /* Ignore the token. */ + $this->ignored = true; + + /* A start tag whose tag name is "html" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] == 'html') { + /* Create an element for the token in the HTML namespace. Append it + * to the Document object. Put this element in the stack of open + * elements. */ + // XDOM + $html = $this->insertElement($token, false); + $this->dom->appendChild($html); + $this->stack[] = $html; + + $this->mode = self::BEFORE_HEAD; + + } else { + /* Create an html element. Append it to the Document object. Put + * this element in the stack of open elements. */ + // XDOM + $html = $this->dom->createElementNS(self::NS_HTML, 'html'); + $this->dom->appendChild($html); + $this->stack[] = $html; + + /* Switch the insertion mode to "before head", then reprocess the + * current token. */ + $this->mode = self::BEFORE_HEAD; + $this->emitToken($token); + } + break; + + case self::BEFORE_HEAD: + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { + /* Ignore the token. */ + $this->ignored = true; + + /* A comment token */ + } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A DOCTYPE token */ + } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + /* Parse error. Ignore the token */ + $this->ignored = true; + // parse error + + /* A start tag token with the tag name "html" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { + /* Process the token using the rules for the "in body" + * insertion mode. */ + $this->processWithRulesFor($token, self::IN_BODY); + + /* A start tag token with the tag name "head" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') { + /* Insert an HTML element for the token. */ + $element = $this->insertElement($token); + + /* Set the head element pointer to this new element node. */ + $this->head_pointer = $element; + + /* Change the insertion mode to "in head". */ + $this->mode = self::IN_HEAD; + + /* An end tag whose tag name is one of: "head", "body", "html", "br" */ + } elseif ( + $token['type'] === HTML5_Tokenizer::ENDTAG && ( + $token['name'] === 'head' || $token['name'] === 'body' || + $token['name'] === 'html' || $token['name'] === 'br' + )) { + /* Act as if a start tag token with the tag name "head" and no + * attributes had been seen, then reprocess the current token. */ + $this->emitToken([ + 'name' => 'head', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => [] + ]); + $this->emitToken($token); + + /* Any other end tag */ + } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG) { + /* Parse error. Ignore the token. */ + $this->ignored = true; + + } else { + /* Act as if a start tag token with the tag name "head" and no + * attributes had been seen, then reprocess the current token. + * Note: This will result in an empty head element being + * generated, with the current token being reprocessed in the + * "after head" insertion mode. */ + $this->emitToken([ + 'name' => 'head', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => [] + ]); + $this->emitToken($token); + } + break; + + case self::IN_HEAD: + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE. */ + if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { + /* Insert the character into the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + /* A DOCTYPE token */ + } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + /* Parse error. Ignore the token. */ + $this->ignored = true; + // parse error + + /* A start tag whose tag name is "html" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && + $token['name'] === 'html') { + $this->processWithRulesFor($token, self::IN_BODY); + + /* A start tag whose tag name is one of: "base", "command", "link" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && + ($token['name'] === 'base' || $token['name'] === 'command' || + $token['name'] === 'link')) { + /* Insert an HTML element for the token. Immediately pop the + * current node off the stack of open elements. */ + $this->insertElement($token); + array_pop($this->stack); + + // YYY: Acknowledge the token's self-closing flag, if it is set. + + /* A start tag whose tag name is "meta" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'meta') { + /* Insert an HTML element for the token. Immediately pop the + * current node off the stack of open elements. */ + $this->insertElement($token); + array_pop($this->stack); + + // XERROR: Acknowledge the token's self-closing flag, if it is set. + + // XENCODING: If the element has a charset attribute, and its value is a + // supported encoding, and the confidence is currently tentative, + // then change the encoding to the encoding given by the value of + // the charset attribute. + // + // Otherwise, if the element has a content attribute, and applying + // the algorithm for extracting an encoding from a Content-Type to + // its value returns a supported encoding encoding, and the + // confidence is currently tentative, then change the encoding to + // the encoding encoding. + + /* A start tag with the tag name "title" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'title') { + $this->insertRCDATAElement($token); + + /* A start tag whose tag name is "noscript", if the scripting flag is enabled, or + * A start tag whose tag name is one of: "noframes", "style" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && + ($token['name'] === 'noscript' || $token['name'] === 'noframes' || $token['name'] === 'style')) { + // XSCRIPT: Scripting flag not respected + $this->insertCDATAElement($token); + + // XSCRIPT: Scripting flag disable not implemented + + /* A start tag with the tag name "script" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'script') { + /* 1. Create an element for the token in the HTML namespace. */ + $node = $this->insertElement($token, false); + + /* 2. Mark the element as being "parser-inserted" */ + // Uhhh... XSCRIPT + + /* 3. If the parser was originally created for the HTML + * fragment parsing algorithm, then mark the script element as + * "already executed". (fragment case) */ + // ditto... XSCRIPT + + /* 4. Append the new element to the current node and push it onto + * the stack of open elements. */ + end($this->stack)->appendChild($node); + $this->stack[] = $node; + // I guess we could squash these together + + /* 6. Let the original insertion mode be the current insertion mode. */ + $this->original_mode = $this->mode; + /* 7. Switch the insertion mode to "in CDATA/RCDATA" */ + $this->mode = self::IN_CDATA_RCDATA; + /* 5. Switch the tokeniser's content model flag to the CDATA state. */ + $this->content_model = HTML5_Tokenizer::CDATA; + + /* An end tag with the tag name "head" */ + } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'head') { + /* Pop the current node (which will be the head element) off the stack of open elements. */ + array_pop($this->stack); + + /* Change the insertion mode to "after head". */ + $this->mode = self::AFTER_HEAD; + + // Slight logic inversion here to minimize duplication + /* A start tag with the tag name "head". */ + /* An end tag whose tag name is not one of: "body", "html", "br" */ + } elseif (($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] !== 'html' && + $token['name'] !== 'body' && $token['name'] !== 'br')) { + // Parse error. Ignore the token. + $this->ignored = true; + + /* Anything else */ + } else { + /* Act as if an end tag token with the tag name "head" had been + * seen, and reprocess the current token. */ + $this->emitToken([ + 'name' => 'head', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + + /* Then, reprocess the current token. */ + $this->emitToken($token); + } + break; + + case self::IN_HEAD_NOSCRIPT: + if ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + // parse error + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { + $this->processWithRulesFor($token, self::IN_BODY); + } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'noscript') { + /* Pop the current node (which will be a noscript element) from the + * stack of open elements; the new current node will be a head + * element. */ + array_pop($this->stack); + $this->mode = self::IN_HEAD; + } elseif ( + ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) || + ($token['type'] === HTML5_Tokenizer::COMMENT) || + ($token['type'] === HTML5_Tokenizer::STARTTAG && ( + $token['name'] === 'link' || $token['name'] === 'meta' || + $token['name'] === 'noframes' || $token['name'] === 'style'))) { + $this->processWithRulesFor($token, self::IN_HEAD); + // inverted logic + } elseif ( + ($token['type'] === HTML5_Tokenizer::STARTTAG && ( + $token['name'] === 'head' || $token['name'] === 'noscript')) || + ($token['type'] === HTML5_Tokenizer::ENDTAG && + $token['name'] !== 'br')) { + // parse error + } else { + // parse error + $this->emitToken([ + 'type' => HTML5_Tokenizer::ENDTAG, + 'name' => 'noscript', + ]); + $this->emitToken($token); + } + break; + + case self::AFTER_HEAD: + /* Handle the token as follows: */ + + /* A character token that is one of one of U+0009 CHARACTER TABULATION, + U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF), + or U+0020 SPACE */ + if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) { + /* Append the character to the current node. */ + $this->insertText($token['data']); + + /* A comment token */ + } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) { + /* Append a Comment node to the current node with the data attribute + set to the data given in the comment token. */ + $this->insertComment($token['data']); + + } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) { + // parse error + + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') { + $this->processWithRulesFor($token, self::IN_BODY); + + /* A start tag token with the tag name "body" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'body') { + $this->insertElement($token); + + /* Set the frameset-ok flag to "not ok". */ + $this->flag_frameset_ok = false; + + /* Change the insertion mode to "in body". */ + $this->mode = self::IN_BODY; + + /* A start tag token with the tag name "frameset" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'frameset') { + /* Insert a frameset element for the token. */ + $this->insertElement($token); + + /* Change the insertion mode to "in frameset". */ + $this->mode = self::IN_FRAMESET; + + /* A start tag token whose tag name is one of: "base", "link", "meta", + "script", "style", "title" */ + } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'], + ['base', 'link', 'meta', 'noframes', 'script', 'style', 'title'])) { + // parse error + /* Push the node pointed to by the head element pointer onto the + * stack of open elements. */ + $this->stack[] = $this->head_pointer; + $this->processWithRulesFor($token, self::IN_HEAD); + array_splice($this->stack, array_search($this->head_pointer, $this->stack, true), 1); + + // inversion of specification + } elseif ( + ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'head') || + ($token['type'] === HTML5_Tokenizer::ENDTAG && + $token['name'] !== 'body' && $token['name'] !== 'html' && + $token['name'] !== 'br')) { + // parse error + + /* Anything else */ + } else { + $this->emitToken([ + 'name' => 'body', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => [] + ]); + $this->flag_frameset_ok = true; + $this->emitToken($token); + } + break; + + case self::IN_BODY: + /* Handle the token as follows: */ + + switch($token['type']) { + /* A character token */ + case HTML5_Tokenizer::CHARACTER: + case HTML5_Tokenizer::SPACECHARACTER: + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Append the token's character to the current node. */ + $this->insertText($token['data']); + + /* If the token is not one of U+0009 CHARACTER TABULATION, + * U+000A LINE FEED (LF), U+000C FORM FEED (FF), or U+0020 + * SPACE, then set the frameset-ok flag to "not ok". */ + // i.e., if any of the characters is not whitespace + if (strlen($token['data']) !== strspn($token['data'], HTML5_Tokenizer::WHITESPACE)) { + $this->flag_frameset_ok = false; + } + break; + + /* A comment token */ + case HTML5_Tokenizer::COMMENT: + /* Append a Comment node to the current node with the data + attribute set to the data given in the comment token. */ + $this->insertComment($token['data']); + break; + + case HTML5_Tokenizer::DOCTYPE: + // parse error + break; + + case HTML5_Tokenizer::EOF: + // parse error + break; + + case HTML5_Tokenizer::STARTTAG: + switch($token['name']) { + case 'html': + // parse error + /* For each attribute on the token, check to see if the + * attribute is already present on the top element of the + * stack of open elements. If it is not, add the attribute + * and its corresponding value to that element. */ + foreach($token['attr'] as $attr) { + if (!$this->stack[0]->hasAttribute($attr['name'])) { + $this->stack[0]->setAttribute($attr['name'], $attr['value']); + } + } + break; + + case 'base': case 'command': case 'link': case 'meta': case 'noframes': + case 'script': case 'style': case 'title': + /* Process the token as if the insertion mode had been "in + head". */ + $this->processWithRulesFor($token, self::IN_HEAD); + break; + + /* A start tag token with the tag name "body" */ + case 'body': + /* Parse error. If the second element on the stack of open + elements is not a body element, or, if the stack of open + elements has only one node on it, then ignore the token. + (fragment case) */ + if (count($this->stack) === 1 || $this->stack[1]->tagName !== 'body') { + $this->ignored = true; + // Ignore + + /* Otherwise, for each attribute on the token, check to see + if the attribute is already present on the body element (the + second element) on the stack of open elements. If it is not, + add the attribute and its corresponding value to that + element. */ + } else { + foreach($token['attr'] as $attr) { + if (!$this->stack[1]->hasAttribute($attr['name'])) { + $this->stack[1]->setAttribute($attr['name'], $attr['value']); + } + } + } + break; + + case 'frameset': + // parse error + /* If the second element on the stack of open elements is + * not a body element, or, if the stack of open elements + * has only one node on it, then ignore the token. + * (fragment case) */ + if (count($this->stack) === 1 || $this->stack[1]->tagName !== 'body') { + $this->ignored = true; + // Ignore + } elseif (!$this->flag_frameset_ok) { + $this->ignored = true; + // Ignore + } else { + /* 1. Remove the second element on the stack of open + * elements from its parent node, if it has one. */ + if ($this->stack[1]->parentNode) { + $this->stack[1]->parentNode->removeChild($this->stack[1]); + } + + /* 2. Pop all the nodes from the bottom of the stack of + * open elements, from the current node up to the root + * html element. */ + array_splice($this->stack, 1); + + $this->insertElement($token); + $this->mode = self::IN_FRAMESET; + } + break; + + // in spec, there is a diversion here + + case 'address': case 'article': case 'aside': case 'blockquote': + case 'center': case 'datagrid': case 'details': case 'dir': + case 'div': case 'dl': case 'fieldset': case 'figure': case 'footer': + case 'header': case 'hgroup': case 'menu': case 'nav': + case 'ol': case 'p': case 'section': case 'ul': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + /* A start tag whose tag name is one of: "h1", "h2", "h3", "h4", + "h5", "h6" */ + case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* If the current node is an element whose tag name is one + * of "h1", "h2", "h3", "h4", "h5", or "h6", then this is a + * parse error; pop the current node off the stack of open + * elements. */ + $peek = array_pop($this->stack); + if (in_array($peek->tagName, ["h1", "h2", "h3", "h4", "h5", "h6"])) { + // parse error + } else { + $this->stack[] = $peek; + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + break; + + case 'pre': case 'listing': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + $this->insertElement($token); + /* If the next token is a U+000A LINE FEED (LF) character + * token, then ignore that token and move on to the next + * one. (Newlines at the start of pre blocks are ignored as + * an authoring convenience.) */ + $this->ignore_lf_token = 2; + $this->flag_frameset_ok = false; + break; + + /* A start tag whose tag name is "form" */ + case 'form': + /* If the form element pointer is not null, ignore the + token with a parse error. */ + if ($this->form_pointer !== null) { + $this->ignored = true; + // Ignore. + + /* Otherwise: */ + } else { + /* If the stack of open elements has a p element in + scope, then act as if an end tag with the tag name p + had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Insert an HTML element for the token, and set the + form element pointer to point to the element created. */ + $element = $this->insertElement($token); + $this->form_pointer = $element; + } + break; + + // condensed specification + case 'li': case 'dc': case 'dd': case 'ds': case 'dt': + /* 1. Set the frameset-ok flag to "not ok". */ + $this->flag_frameset_ok = false; + + $stack_length = count($this->stack) - 1; + for($n = $stack_length; 0 <= $n; $n--) { + /* 2. Initialise node to be the current node (the + bottommost node of the stack). */ + $stop = false; + $node = $this->stack[$n]; + $cat = $this->getElementCategory($node); + + // for case 'li': + /* 3. If node is an li element, then act as if an end + * tag with the tag name "li" had been seen, then jump + * to the last step. */ + // for case 'dc': case 'dd': case 'ds': case 'dt': + /* If node is a dc, dd, ds or dt element, then act as if an end + * tag with the same tag name as node had been seen, then + * jump to the last step. */ + if (($token['name'] === 'li' && $node->tagName === 'li') || + ($token['name'] !== 'li' && ($node->tagName == 'dc' || $node->tagName === 'dd' || $node->tagName == 'ds' || $node->tagName === 'dt'))) { // limited conditional + $this->emitToken([ + 'type' => HTML5_Tokenizer::ENDTAG, + 'name' => $node->tagName, + ]); + break; + } + + /* 4. If node is not in the formatting category, and is + not in the phrasing category, and is not an address, + div or p element, then stop this algorithm. */ + if ($cat !== self::FORMATTING && $cat !== self::PHRASING && + $node->tagName !== 'address' && $node->tagName !== 'div' && + $node->tagName !== 'p') { + break; + } + + /* 5. Otherwise, set node to the previous entry in the + * stack of open elements and return to step 2. */ + } + + /* 6. This is the last step. */ + + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Finally, insert an HTML element with the same tag + name as the token's. */ + $this->insertElement($token); + break; + + /* A start tag token whose tag name is "plaintext" */ + case 'plaintext': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been + seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + $this->content_model = HTML5_Tokenizer::PLAINTEXT; + break; + + // more diversions + + /* A start tag whose tag name is "a" */ + case 'a': + /* If the list of active formatting elements contains + an element whose tag name is "a" between the end of the + list and the last marker on the list (or the start of + the list if there is no marker on the list), then this + is a parse error; act as if an end tag with the tag name + "a" had been seen, then remove that element from the list + of active formatting elements and the stack of open + elements if the end tag didn't already remove it (it + might not have if the element is not in table scope). */ + $leng = count($this->a_formatting); + + for ($n = $leng - 1; $n >= 0; $n--) { + if ($this->a_formatting[$n] === self::MARKER) { + break; + + } elseif ($this->a_formatting[$n]->tagName === 'a') { + $a = $this->a_formatting[$n]; + $this->emitToken([ + 'name' => 'a', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + if (in_array($a, $this->a_formatting)) { + $a_i = array_search($a, $this->a_formatting, true); + if ($a_i !== false) { + array_splice($this->a_formatting, $a_i, 1); + } + } + if (in_array($a, $this->stack)) { + $a_i = array_search($a, $this->stack, true); + if ($a_i !== false) { + array_splice($this->stack, $a_i, 1); + } + } + break; + } + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + case 'b': case 'big': case 'code': case 'em': case 'font': case 'i': + case 's': case 'small': case 'strike': + case 'strong': case 'tt': case 'u': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + case 'nobr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* If the stack of open elements has a nobr element in + * scope, then this is a parse error; act as if an end tag + * with the tag name "nobr" had been seen, then once again + * reconstruct the active formatting elements, if any. */ + if ($this->elementInScope('nobr')) { + $this->emitToken([ + 'name' => 'nobr', + 'type' => HTML5_Tokenizer::ENDTAG, + ]); + $this->reconstructActiveFormattingElements(); + } + + /* Insert an HTML element for the token. */ + $el = $this->insertElement($token); + + /* Add that element to the list of active formatting + elements. */ + $this->a_formatting[] = $el; + break; + + // another diversion + + /* A start tag token whose tag name is "button" */ + case 'button': + /* If the stack of open elements has a button element in scope, + then this is a parse error; act as if an end tag with the tag + name "button" had been seen, then reprocess the token. (We don't + do that. Unnecessary.) (I hope you're right! -- ezyang) */ + if ($this->elementInScope('button')) { + $this->emitToken([ + 'name' => 'button', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + + $this->flag_frameset_ok = false; + break; + + case 'applet': case 'marquee': case 'object': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Insert a marker at the end of the list of active + formatting elements. */ + $this->a_formatting[] = self::MARKER; + + $this->flag_frameset_ok = false; + break; + + // spec diversion + + /* A start tag whose tag name is "table" */ + case 'table': + /* If the Document is not set to quirks mode, and the + * stack of open elements has a p element in scope, then + * act as if an end tag with the tag name "p" had been + * seen. */ + if ($this->quirks_mode !== self::QUIRKS_MODE && + $this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + $this->flag_frameset_ok = false; + + /* Change the insertion mode to "in table". */ + $this->mode = self::IN_TABLE; + break; + + /* A start tag whose tag name is one of: "area", "basefont", + "bgsound", "br", "embed", "img", "param", "spacer", "wbr" */ + case 'area': case 'basefont': case 'bgsound': case 'br': + case 'embed': case 'img': case 'input': case 'keygen': case 'spacer': + case 'wbr': + /* Reconstruct the active formatting elements, if any. */ + $this->reconstructActiveFormattingElements(); + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + // YYY: Acknowledge the token's self-closing flag, if it is set. + + $this->flag_frameset_ok = false; + break; + + case 'param': case 'source': + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + // YYY: Acknowledge the token's self-closing flag, if it is set. + break; + + /* A start tag whose tag name is "hr" */ + case 'hr': + /* If the stack of open elements has a p element in scope, + then act as if an end tag with the tag name p had been seen. */ + if ($this->elementInScope('p')) { + $this->emitToken([ + 'name' => 'p', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } + + /* Insert an HTML element for the token. */ + $this->insertElement($token); + + /* Immediately pop the current node off the stack of open elements. */ + array_pop($this->stack); + + // YYY: Acknowledge the token's self-closing flag, if it is set. + + $this->flag_frameset_ok = false; + break; + + /* A start tag whose tag name is "image" */ + case 'image': + /* Parse error. Change the token's tag name to "img" and + reprocess it. (Don't ask.) */ + $token['name'] = 'img'; + $this->emitToken($token); + break; + + /* A start tag whose tag name is "isindex" */ + case 'isindex': + /* Parse error. */ + + /* If the form element pointer is not null, + then ignore the token. */ + if ($this->form_pointer === null) { + /* Act as if a start tag token with the tag name "form" had + been seen. */ + /* If the token has an attribute called "action", set + * the action attribute on the resulting form + * element to the value of the "action" attribute of + * the token. */ + $attr = []; + $action = $this->getAttr($token, 'action'); + if ($action !== false) { + $attr[] = ['name' => 'action', 'value' => $action]; + } + $this->emitToken([ + 'name' => 'form', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => $attr + ]); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->emitToken([ + 'name' => 'hr', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => [] + ]); + + /* Act as if a start tag token with the tag name "label" + had been seen. */ + $this->emitToken([ + 'name' => 'label', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => [] + ]); + + /* Act as if a stream of character tokens had been seen. */ + $prompt = $this->getAttr($token, 'prompt'); + if ($prompt === false) { + $prompt = 'This is a searchable index. '. + 'Insert your search keywords here: '; + } + $this->emitToken([ + 'data' => $prompt, + 'type' => HTML5_Tokenizer::CHARACTER, + ]); + + /* Act as if a start tag token with the tag name "input" + had been seen, with all the attributes from the "isindex" + token, except with the "name" attribute set to the value + "isindex" (ignoring any explicit "name" attribute). */ + $attr = []; + foreach ($token['attr'] as $keypair) { + if ($keypair['name'] === 'name' || $keypair['name'] === 'action' || + $keypair['name'] === 'prompt') { + continue; + } + $attr[] = $keypair; + } + $attr[] = ['name' => 'name', 'value' => 'isindex']; + + $this->emitToken([ + 'name' => 'input', + 'type' => HTML5_Tokenizer::STARTTAG, + 'attr' => $attr + ]); + + /* Act as if an end tag token with the tag name "label" + had been seen. */ + $this->emitToken([ + 'name' => 'label', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + + /* Act as if a start tag token with the tag name "hr" had + been seen. */ + $this->emitToken([ + 'name' => 'hr', + 'type' => HTML5_Tokenizer::STARTTAG + ]); + + /* Act as if an end tag token with the tag name "form" had + been seen. */ + $this->emitToken([ + 'name' => 'form', + 'type' => HTML5_Tokenizer::ENDTAG + ]); + } else { + $this->ignored = true; + } + break; + + /* A start tag whose tag name is "textarea" */ + case 'textarea': + $this->insertElement($token); + + /* If the next token is a U+000A LINE FEED (LF) + * character token, then ignore that token and move on to + * the next one. (Newlines at the start of textarea + * elements are ignored as an authoring convenience.) + * need flag, see also
 */
+                            $this->ignore_lf_token = 2;
+
+                            $this->original_mode = $this->mode;
+                            $this->flag_frameset_ok = false;
+                            $this->mode = self::IN_CDATA_RCDATA;
+
+                            /* Switch the tokeniser's content model flag to the
+                            RCDATA state. */
+                            $this->content_model = HTML5_Tokenizer::RCDATA;
+                        break;
+
+                        /* A start tag token whose tag name is "xmp" */
+                        case 'xmp':
+                            /* If the stack of open elements has a p element in
+                            scope, then act as if an end tag with the tag name
+                            "p" has been seen. */
+                            if ($this->elementInScope('p')) {
+                                $this->emitToken([
+                                    'name' => 'p',
+                                    'type' => HTML5_Tokenizer::ENDTAG
+                                ]);
+                            }
+
+                            /* Reconstruct the active formatting elements, if any. */
+                            $this->reconstructActiveFormattingElements();
+
+                            $this->flag_frameset_ok = false;
+
+                            $this->insertCDATAElement($token);
+                        break;
+
+                        case 'iframe':
+                            $this->flag_frameset_ok = false;
+                            $this->insertCDATAElement($token);
+                        break;
+
+                        case 'noembed': case 'noscript':
+                            // XSCRIPT: should check scripting flag
+                            $this->insertCDATAElement($token);
+                        break;
+
+                        /* A start tag whose tag name is "select" */
+                        case 'select':
+                            /* Reconstruct the active formatting elements, if any. */
+                            $this->reconstructActiveFormattingElements();
+
+                            /* Insert an HTML element for the token. */
+                            $this->insertElement($token);
+
+                            $this->flag_frameset_ok = false;
+
+                            /* If the insertion mode is one of in table", "in caption",
+                             * "in column group", "in table body", "in row", or "in
+                             * cell", then switch the insertion mode to "in select in
+                             * table". Otherwise, switch the insertion mode  to "in
+                             * select". */
+                            if (
+                                $this->mode === self::IN_TABLE || $this->mode === self::IN_CAPTION ||
+                                $this->mode === self::IN_COLUMN_GROUP || $this->mode ==+self::IN_TABLE_BODY ||
+                                $this->mode === self::IN_ROW || $this->mode === self::IN_CELL
+                            ) {
+                                $this->mode = self::IN_SELECT_IN_TABLE;
+                            } else {
+                                $this->mode = self::IN_SELECT;
+                            }
+                        break;
+
+                        case 'option': case 'optgroup':
+                            if ($this->elementInScope('option')) {
+                                $this->emitToken([
+                                    'name' => 'option',
+                                    'type' => HTML5_Tokenizer::ENDTAG,
+                                ]);
+                            }
+                            $this->reconstructActiveFormattingElements();
+                            $this->insertElement($token);
+                        break;
+
+                        case 'rp': case 'rt':
+                            /* If the stack of open elements has a ruby element in scope, then generate
+                             * implied end tags. If the current node is not then a ruby element, this is
+                             * a parse error; pop all the nodes from the current node up to the node
+                             * immediately before the bottommost ruby element on the stack of open elements.
+                             */
+                            if ($this->elementInScope('ruby')) {
+                                $this->generateImpliedEndTags();
+                            }
+                            $peek = false;
+                            do {
+                                /*if ($peek) {
+                                    // parse error
+                                }*/
+                                $peek = array_pop($this->stack);
+                            } while ($peek->tagName !== 'ruby');
+                            $this->stack[] = $peek; // we popped one too many
+                            $this->insertElement($token);
+                        break;
+
+                        // spec diversion
+
+                        case 'math':
+                            $this->reconstructActiveFormattingElements();
+                            $token = $this->adjustMathMLAttributes($token);
+                            $token = $this->adjustForeignAttributes($token);
+                            $this->insertForeignElement($token, self::NS_MATHML);
+                            if (isset($token['self-closing'])) {
+                                // XERROR: acknowledge the token's self-closing flag
+                                array_pop($this->stack);
+                            }
+                            if ($this->mode !== self::IN_FOREIGN_CONTENT) {
+                                $this->secondary_mode = $this->mode;
+                                $this->mode = self::IN_FOREIGN_CONTENT;
+                            }
+                        break;
+
+                        case 'svg':
+                            $this->reconstructActiveFormattingElements();
+                            $token = $this->adjustSVGAttributes($token);
+                            $token = $this->adjustForeignAttributes($token);
+                            $this->insertForeignElement($token, self::NS_SVG);
+                            if (isset($token['self-closing'])) {
+                                // XERROR: acknowledge the token's self-closing flag
+                                array_pop($this->stack);
+                            }
+                            if ($this->mode !== self::IN_FOREIGN_CONTENT) {
+                                $this->secondary_mode = $this->mode;
+                                $this->mode = self::IN_FOREIGN_CONTENT;
+                            }
+                        break;
+
+                        case 'caption': case 'col': case 'colgroup': case 'frame': case 'head':
+                        case 'tbody': case 'td': case 'tfoot': case 'th': case 'thead': case 'tr':
+                            // parse error
+                        break;
+
+                        /* A start tag token not covered by the previous entries */
+                        default:
+                            /* Reconstruct the active formatting elements, if any. */
+                            $this->reconstructActiveFormattingElements();
+
+                            $this->insertElement($token);
+                            /* This element will be a phrasing  element. */
+                        break;
+                    }
+                    break;
+
+                    case HTML5_Tokenizer::ENDTAG:
+                    switch ($token['name']) {
+                        /* An end tag with the tag name "body" */
+                        case 'body':
+                            /* If the stack of open elements does not have a body
+                             * element in scope, this is a parse error; ignore the
+                             * token. */
+                            if (!$this->elementInScope('body')) {
+                                $this->ignored = true;
+
+                            /* Otherwise, if there is a node in the stack of open
+                             * elements that is not either a dc element, a dd element,
+                             * a ds element, a dt element, an li element, an optgroup
+                             * element, an option element, a p element, an rp element,
+                             * an rt element, a tbody element, a td element, a tfoot
+                             * element, a th element, a thead element, a tr element,
+                             * the body element, or the html element, then this is a
+                             * parse error.
+                             */
+                            } else {
+                                // XERROR: implement this check for parse error
+                            }
+
+                            /* Change the insertion mode to "after body". */
+                            $this->mode = self::AFTER_BODY;
+                        break;
+
+                        /* An end tag with the tag name "html" */
+                        case 'html':
+                            /* Act as if an end tag with tag name "body" had been seen,
+                            then, if that token wasn't ignored, reprocess the current
+                            token. */
+                            $this->emitToken([
+                                'name' => 'body',
+                                'type' => HTML5_Tokenizer::ENDTAG
+                            ]);
+
+                            if (!$this->ignored) {
+                                $this->emitToken($token);
+                            }
+                        break;
+
+                        case 'address': case 'article': case 'aside': case 'blockquote':
+                        case 'center': case 'datagrid': case 'details': case 'dir':
+                        case 'div': case 'dl': case 'fieldset': case 'footer':
+                        case 'header': case 'hgroup': case 'listing': case 'menu':
+                        case 'nav': case 'ol': case 'pre': case 'section': case 'ul':
+                            /* If the stack of open elements has an element in scope
+                            with the same tag name as that of the token, then generate
+                            implied end tags. */
+                            if ($this->elementInScope($token['name'])) {
+                                $this->generateImpliedEndTags();
+
+                                /* Now, if the current node is not an element with
+                                the same tag name as that of the token, then this
+                                is a parse error. */
+                                // XERROR: implement parse error logic
+
+                                /* If the stack of open elements has an element in
+                                scope with the same tag name as that of the token,
+                                then pop elements from this stack until an element
+                                with that tag name has been popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while ($node->tagName !== $token['name']);
+                            } else {
+                                // parse error
+                            }
+                        break;
+
+                        /* An end tag whose tag name is "form" */
+                        case 'form':
+                            /* Let node be the element that the form element pointer is set to. */
+                            $node = $this->form_pointer;
+                            /* Set the form element pointer  to null. */
+                            $this->form_pointer = null;
+                            /* If node is null or the stack of open elements does not
+                                * have node in scope, then this is a parse error; ignore the token. */
+                            if ($node === null || !in_array($node, $this->stack)) {
+                                // parse error
+                                $this->ignored = true;
+                            } else {
+                                /* 1. Generate implied end tags. */
+                                $this->generateImpliedEndTags();
+                                /* 2. If the current node is not node, then this is a parse error.  */
+                                if (end($this->stack) !== $node) {
+                                    // parse error
+                                }
+                                /* 3. Remove node from the stack of open elements. */
+                                array_splice($this->stack, array_search($node, $this->stack, true), 1);
+                            }
+
+                        break;
+
+                        /* An end tag whose tag name is "p" */
+                        case 'p':
+                            /* If the stack of open elements has a p element in scope,
+                            then generate implied end tags, except for p elements. */
+                            if ($this->elementInScope('p')) {
+                                /* Generate implied end tags, except for elements with
+                                 * the same tag name as the token. */
+                                $this->generateImpliedEndTags(['p']);
+
+                                /* If the current node is not a p element, then this is
+                                a parse error. */
+                                // XERROR: implement
+
+                                /* Pop elements from the stack of open elements  until
+                                 * an element with the same tag name as the token has
+                                 * been popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while ($node->tagName !== 'p');
+
+                            } else {
+                                // parse error
+                                $this->emitToken([
+                                    'name' => 'p',
+                                    'type' => HTML5_Tokenizer::STARTTAG,
+                                ]);
+                                $this->emitToken($token);
+                            }
+                        break;
+
+                        /* An end tag whose tag name is "li" */
+                        case 'li':
+                            /* If the stack of open elements does not have an element
+                             * in list item scope with the same tag name as that of the
+                             * token, then this is a parse error; ignore the token. */
+                            if ($this->elementInScope($token['name'], self::SCOPE_LISTITEM)) {
+                                /* Generate implied end tags, except for elements with the
+                                 * same tag name as the token. */
+                                $this->generateImpliedEndTags([$token['name']]);
+                                /* If the current node is not an element with the same tag
+                                 * name as that of the token, then this is a parse error. */
+                                // XERROR: parse error
+                                /* Pop elements from the stack of open elements  until an
+                                 * element with the same tag name as the token has been
+                                 * popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while ($node->tagName !== $token['name']);
+                            }
+                            /*else {
+                                // XERROR: parse error
+                            }*/
+                        break;
+
+                        /* An end tag whose tag name is "dc", "dd", "ds", "dt" */
+                        case 'dc': case 'dd': case 'ds': case 'dt':
+                            if ($this->elementInScope($token['name'])) {
+                                $this->generateImpliedEndTags([$token['name']]);
+
+                                /* If the current node is not an element with the same
+                                tag name as the token, then this is a parse error. */
+                                // XERROR: implement parse error
+
+                                /* Pop elements from the stack of open elements  until
+                                 * an element with the same tag name as the token has
+                                 * been popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while ($node->tagName !== $token['name']);
+                            }
+                            /*else {
+                                // XERROR: parse error
+                            }*/
+                        break;
+
+                        /* An end tag whose tag name is one of: "h1", "h2", "h3", "h4",
+                        "h5", "h6" */
+                        case 'h1': case 'h2': case 'h3': case 'h4': case 'h5': case 'h6':
+                            $elements = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
+
+                            /* If the stack of open elements has in scope an element whose
+                            tag name is one of "h1", "h2", "h3", "h4", "h5", or "h6", then
+                            generate implied end tags. */
+                            if ($this->elementInScope($elements)) {
+                                $this->generateImpliedEndTags();
+
+                                /* Now, if the current node is not an element with the same
+                                tag name as that of the token, then this is a parse error. */
+                                // XERROR: implement parse error
+
+                                /* If the stack of open elements has in scope an element
+                                whose tag name is one of "h1", "h2", "h3", "h4", "h5", or
+                                "h6", then pop elements from the stack until an element
+                                with one of those tag names has been popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while (!in_array($node->tagName, $elements));
+                            }
+                            /*else {
+                                // parse error
+                            }*/
+                        break;
+
+                        /* An end tag whose tag name is one of: "a", "b", "big", "em",
+                        "font", "i", "nobr", "s", "small", "strike", "strong", "tt", "u" */
+                        case 'a': case 'b': case 'big': case 'code': case 'em': case 'font':
+                        case 'i': case 'nobr': case 's': case 'small': case 'strike':
+                        case 'strong': case 'tt': case 'u':
+                            // XERROR: generally speaking this needs parse error logic
+                            /* 1. Let the formatting element be the last element in
+                            the list of active formatting elements that:
+                                * is between the end of the list and the last scope
+                                marker in the list, if any, or the start of the list
+                                otherwise, and
+                                * has the same tag name as the token.
+                            */
+                            while (true) {
+                                for ($a = count($this->a_formatting) - 1; $a >= 0; $a--) {
+                                    if ($this->a_formatting[$a] === self::MARKER) {
+                                        break;
+                                    } elseif ($this->a_formatting[$a]->tagName === $token['name']) {
+                                        $formatting_element = $this->a_formatting[$a];
+                                        $in_stack = in_array($formatting_element, $this->stack, true);
+                                        $fe_af_pos = $a;
+                                        break;
+                                    }
+                                }
+
+                                /* If there is no such node, or, if that node is
+                                also in the stack of open elements but the element
+                                is not in scope, then this is a parse error. Abort
+                                these steps. The token is ignored. */
+                                if (
+                                    !isset($formatting_element) || (
+                                        $in_stack &&
+                                        !$this->elementInScope($token['name'])
+                                    )
+                                ) {
+                                    $this->ignored = true;
+                                    break;
+
+                                /* Otherwise, if there is such a node, but that node
+                                is not in the stack of open elements, then this is a
+                                parse error; remove the element from the list, and
+                                abort these steps. */
+                                } elseif (isset($formatting_element) && !$in_stack) {
+                                    unset($this->a_formatting[$fe_af_pos]);
+                                    $this->a_formatting = array_merge($this->a_formatting);
+                                    break;
+                                }
+
+                                /* Otherwise, there is a formatting element and that
+                                 * element is in the stack and is in scope. If the
+                                 * element is not the current node, this is a parse
+                                 * error. In any case, proceed with the algorithm as
+                                 * written in the following steps. */
+                                // XERROR: implement me
+
+                                /* 2. Let the furthest block be the topmost node in the
+                                stack of open elements that is lower in the stack
+                                than the formatting element, and is not an element in
+                                the phrasing or formatting categories. There might
+                                not be one. */
+                                $fe_s_pos = array_search($formatting_element, $this->stack, true);
+                                $length = count($this->stack);
+
+                                for ($s = $fe_s_pos + 1; $s < $length; $s++) {
+                                    $category = $this->getElementCategory($this->stack[$s]);
+
+                                    if ($category !== self::PHRASING && $category !== self::FORMATTING) {
+                                        $furthest_block = $this->stack[$s];
+                                        break;
+                                    }
+                                }
+
+                                /* 3. If there is no furthest block, then the UA must
+                                skip the subsequent steps and instead just pop all
+                                the nodes from the bottom of the stack of open
+                                elements, from the current node up to the formatting
+                                element, and remove the formatting element from the
+                                list of active formatting elements. */
+                                if (!isset($furthest_block)) {
+                                    for ($n = $length - 1; $n >= $fe_s_pos; $n--) {
+                                        array_pop($this->stack);
+                                    }
+
+                                    unset($this->a_formatting[$fe_af_pos]);
+                                    $this->a_formatting = array_merge($this->a_formatting);
+                                    break;
+                                }
+
+                                /* 4. Let the common ancestor be the element
+                                immediately above the formatting element in the stack
+                                of open elements. */
+                                $common_ancestor = $this->stack[$fe_s_pos - 1];
+
+                                /* 5. Let a bookmark note the position of the
+                                formatting element in the list of active formatting
+                                elements relative to the elements on either side
+                                of it in the list. */
+                                $bookmark = $fe_af_pos;
+
+                                /* 6. Let node and last node  be the furthest block.
+                                Follow these steps: */
+                                $node = $furthest_block;
+                                $last_node = $furthest_block;
+
+                                while (true) {
+                                    for ($n = array_search($node, $this->stack, true) - 1; $n >= 0; $n--) {
+                                        /* 6.1 Let node be the element immediately
+                                        prior to node in the stack of open elements. */
+                                        $node = $this->stack[$n];
+
+                                        /* 6.2 If node is not in the list of active
+                                        formatting elements, then remove node from
+                                        the stack of open elements and then go back
+                                        to step 1. */
+                                        if (!in_array($node, $this->a_formatting, true)) {
+                                            array_splice($this->stack, $n, 1);
+                                        } else {
+                                            break;
+                                        }
+                                    }
+
+                                    /* 6.3 Otherwise, if node is the formatting
+                                    element, then go to the next step in the overall
+                                    algorithm. */
+                                    if ($node === $formatting_element) {
+                                        break;
+
+                                    /* 6.4 Otherwise, if last node is the furthest
+                                    block, then move the aforementioned bookmark to
+                                    be immediately after the node in the list of
+                                    active formatting elements. */
+                                    } elseif ($last_node === $furthest_block) {
+                                        $bookmark = array_search($node, $this->a_formatting, true) + 1;
+                                    }
+
+                                    /* 6.5 Create an element for the token for which
+                                     * the element node was created, replace the entry
+                                     * for node in the list of active formatting
+                                     * elements with an entry for the new element,
+                                     * replace the entry for node in the stack of open
+                                     * elements with an entry for the new element, and
+                                     * let node be the new element. */
+                                    // we don't know what the token is anymore
+                                    // XDOM
+                                    $clone = $node->cloneNode();
+                                    $a_pos = array_search($node, $this->a_formatting, true);
+                                    $s_pos = array_search($node, $this->stack, true);
+                                    $this->a_formatting[$a_pos] = $clone;
+                                    $this->stack[$s_pos] = $clone;
+                                    $node = $clone;
+
+                                    /* 6.6 Insert last node into node, first removing
+                                    it from its previous parent node if any. */
+                                    // XDOM
+                                    if ($last_node->parentNode !== null) {
+                                        $last_node->parentNode->removeChild($last_node);
+                                    }
+
+                                    // XDOM
+                                    $node->appendChild($last_node);
+
+                                    /* 6.7 Let last node be node. */
+                                    $last_node = $node;
+
+                                    /* 6.8 Return to step 1 of this inner set of steps. */
+                                }
+
+                                /* 7. If the common ancestor node is a table, tbody,
+                                 * tfoot, thead, or tr element, then, foster parent
+                                 * whatever last node ended up being in the previous
+                                 * step, first removing it from its previous parent
+                                 * node if any. */
+                                // XDOM
+                                if ($last_node->parentNode) { // common step
+                                    $last_node->parentNode->removeChild($last_node);
+                                }
+                                if (in_array($common_ancestor->tagName, ['table', 'tbody', 'tfoot', 'thead', 'tr'])) {
+                                    $this->fosterParent($last_node);
+                                /* Otherwise, append whatever last node  ended up being
+                                 * in the previous step to the common ancestor node,
+                                 * first removing it from its previous parent node if
+                                 * any. */
+                                } else {
+                                    // XDOM
+                                    $common_ancestor->appendChild($last_node);
+                                }
+
+                                /* 8. Create an element for the token for which the
+                                 * formatting element was created. */
+                                // XDOM
+                                $clone = $formatting_element->cloneNode();
+
+                                /* 9. Take all of the child nodes of the furthest
+                                block and append them to the element created in the
+                                last step. */
+                                // XDOM
+                                while ($furthest_block->hasChildNodes()) {
+                                    $child = $furthest_block->firstChild;
+                                    $furthest_block->removeChild($child);
+                                    $clone->appendChild($child);
+                                }
+
+                                /* 10. Append that clone to the furthest block. */
+                                // XDOM
+                                $furthest_block->appendChild($clone);
+
+                                /* 11. Remove the formatting element from the list
+                                of active formatting elements, and insert the new element
+                                into the list of active formatting elements at the
+                                position of the aforementioned bookmark. */
+                                $fe_af_pos = array_search($formatting_element, $this->a_formatting, true);
+                                array_splice($this->a_formatting, $fe_af_pos, 1);
+
+                                $af_part1 = array_slice($this->a_formatting, 0, $bookmark - 1);
+                                $af_part2 = array_slice($this->a_formatting, $bookmark);
+                                $this->a_formatting = array_merge($af_part1, [$clone], $af_part2);
+
+                                /* 12. Remove the formatting element from the stack
+                                of open elements, and insert the new element into the stack
+                                of open elements immediately below the position of the
+                                furthest block in that stack. */
+                                $fe_s_pos = array_search($formatting_element, $this->stack, true);
+                                array_splice($this->stack, $fe_s_pos, 1);
+
+                                $fb_s_pos = array_search($furthest_block, $this->stack, true);
+                                $s_part1 = array_slice($this->stack, 0, $fb_s_pos + 1);
+                                $s_part2 = array_slice($this->stack, $fb_s_pos + 1);
+                                $this->stack = array_merge($s_part1, [$clone], $s_part2);
+
+                                /* 13. Jump back to step 1 in this series of steps. */
+                                unset($formatting_element, $fe_af_pos, $fe_s_pos, $furthest_block);
+                            }
+                        break;
+
+                        case 'applet': case 'button': case 'marquee': case 'object':
+                            /* If the stack of open elements has an element in scope whose
+                            tag name matches the tag name of the token, then generate implied
+                            tags. */
+                            if ($this->elementInScope($token['name'])) {
+                                $this->generateImpliedEndTags();
+
+                                /* Now, if the current node is not an element with the same
+                                tag name as the token, then this is a parse error. */
+                                // XERROR: implement logic
+
+                                /* Pop elements from the stack of open elements  until
+                                 * an element with the same tag name as the token has
+                                 * been popped from the stack. */
+                                do {
+                                    $node = array_pop($this->stack);
+                                } while ($node->tagName !== $token['name']);
+
+                                /* Clear the list of active formatting elements up to the
+                                 * last marker. */
+                                $keys = array_keys($this->a_formatting, self::MARKER, true);
+                                $marker = end($keys);
+
+                                for ($n = count($this->a_formatting) - 1; $n > $marker; $n--) {
+                                    array_pop($this->a_formatting);
+                                }
+                            }
+                            /*else {
+                                // parse error
+                            }*/
+                        break;
+
+                        case 'br':
+                            // Parse error
+                            $this->emitToken([
+                                'name' => 'br',
+                                'type' => HTML5_Tokenizer::STARTTAG,
+                            ]);
+                        break;
+
+                        /* An end tag token not covered by the previous entries */
+                        default:
+                            for ($n = count($this->stack) - 1; $n >= 0; $n--) {
+                                /* Initialise node to be the current node (the bottommost
+                                node of the stack). */
+                                $node = $this->stack[$n];
+
+                                /* If node has the same tag name as the end tag token,
+                                then: */
+                                if ($token['name'] === $node->tagName) {
+                                    /* Generate implied end tags. */
+                                    $this->generateImpliedEndTags();
+
+                                    /* If the tag name of the end tag token does not
+                                    match the tag name of the current node, this is a
+                                    parse error. */
+                                    // XERROR: implement this
+
+                                    /* Pop all the nodes from the current node up to
+                                    node, including node, then stop these steps. */
+                                    // XSKETCHY
+                                    do {
+                                        $pop = array_pop($this->stack);
+                                    } while ($pop !== $node);
+                                    break;
+                                } else {
+                                    $category = $this->getElementCategory($node);
+
+                                    if ($category !== self::FORMATTING && $category !== self::PHRASING) {
+                                        /* Otherwise, if node is in neither the formatting
+                                        category nor the phrasing category, then this is a
+                                        parse error. Stop this algorithm. The end tag token
+                                        is ignored. */
+                                        $this->ignored = true;
+                                        break;
+                                        // parse error
+                                    }
+                                }
+                                /* Set node to the previous entry in the stack of open elements. Loop. */
+                            }
+                        break;
+                    }
+                    break;
+                }
+                break;
+
+            case self::IN_CDATA_RCDATA:
+                if (
+                    $token['type'] === HTML5_Tokenizer::CHARACTER ||
+                    $token['type'] === HTML5_Tokenizer::SPACECHARACTER
+                ) {
+                    $this->insertText($token['data']);
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    // parse error
+                    /* If the current node is a script  element, mark the script
+                     * element as "already executed". */
+                    // probably not necessary
+                    array_pop($this->stack);
+                    $this->mode = $this->original_mode;
+                    $this->emitToken($token);
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'script') {
+                    array_pop($this->stack);
+                    $this->mode = $this->original_mode;
+                    // we're ignoring all of the execution stuff
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG) {
+                    array_pop($this->stack);
+                    $this->mode = $this->original_mode;
+                }
+            break;
+
+            case self::IN_TABLE:
+                $clear = ['html', 'table'];
+
+                /* A character token */
+                if ($token['type'] === HTML5_Tokenizer::CHARACTER ||
+                    $token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    /* Let the pending table character tokens
+                     * be an empty list of tokens. */
+                    $this->pendingTableCharacters = "";
+                    $this->pendingTableCharactersDirty = false;
+                    /* Let the original insertion mode be the current
+                     * insertion mode. */
+                    $this->original_mode = $this->mode;
+                    /* Switch the insertion mode to
+                     * "in table text" and
+                     * reprocess the token. */
+                    $this->mode = self::IN_TABLE_TEXT;
+                    $this->emitToken($token);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the current node with the data
+                    attribute set to the data given in the comment token. */
+                    $this->insertComment($token['data']);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+
+                /* A start tag whose tag name is "caption" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'caption') {
+                    /* Clear the stack back to a table context. */
+                    $this->clearStackToTableContext($clear);
+
+                    /* Insert a marker at the end of the list of active
+                    formatting elements. */
+                    $this->a_formatting[] = self::MARKER;
+
+                    /* Insert an HTML element for the token, then switch the
+                    insertion mode to "in caption". */
+                    $this->insertElement($token);
+                    $this->mode = self::IN_CAPTION;
+
+                /* A start tag whose tag name is "colgroup" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'colgroup') {
+                    /* Clear the stack back to a table context. */
+                    $this->clearStackToTableContext($clear);
+
+                    /* Insert an HTML element for the token, then switch the
+                    insertion mode to "in column group". */
+                    $this->insertElement($token);
+                    $this->mode = self::IN_COLUMN_GROUP;
+
+                /* A start tag whose tag name is "col" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'col') {
+                    $this->emitToken([
+                        'name' => 'colgroup',
+                        'type' => HTML5_Tokenizer::STARTTAG,
+                        'attr' => []
+                    ]);
+
+                    $this->emitToken($token);
+
+                /* A start tag whose tag name is one of: "tbody", "tfoot", "thead" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'],
+                ['tbody', 'tfoot', 'thead'])) {
+                    /* Clear the stack back to a table context. */
+                    $this->clearStackToTableContext($clear);
+
+                    /* Insert an HTML element for the token, then switch the insertion
+                    mode to "in table body". */
+                    $this->insertElement($token);
+                    $this->mode = self::IN_TABLE_BODY;
+
+                /* A start tag whose tag name is one of: "td", "th", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                in_array($token['name'], ['td', 'th', 'tr'])) {
+                    /* Act as if a start tag token with the tag name "tbody" had been
+                    seen, then reprocess the current token. */
+                    $this->emitToken([
+                        'name' => 'tbody',
+                        'type' => HTML5_Tokenizer::STARTTAG,
+                        'attr' => []
+                    ]);
+
+                    $this->emitToken($token);
+
+                /* A start tag whose tag name is "table" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'table') {
+                    /* Parse error. Act as if an end tag token with the tag name "table"
+                    had been seen, then, if that token wasn't ignored, reprocess the
+                    current token. */
+                    $this->emitToken([
+                        'name' => 'table',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+
+                    if (!$this->ignored) {
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is "table" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'table') {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. (fragment case) */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->ignored = true;
+                    } else {
+                        do {
+                            $node = array_pop($this->stack);
+                        } while ($node->tagName !== 'table');
+
+                        /* Reset the insertion mode appropriately. */
+                        $this->resetInsertionMode();
+                    }
+
+                /* An end tag whose tag name is one of: "body", "caption", "col",
+                "colgroup", "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['body', 'caption', 'col', 'colgroup', 'html', 'tbody', 'td',
+                'tfoot', 'th', 'thead', 'tr'])) {
+                    // Parse error. Ignore the token.
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                ($token['name'] === 'style' || $token['name'] === 'script')) {
+                    $this->processWithRulesFor($token, self::IN_HEAD);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'input' &&
+                // assignment is intentional
+                /* If the token does not have an attribute with the name "type", or
+                 * if it does, but that attribute's value is not an ASCII
+                 * case-insensitive match for the string "hidden", then: act as
+                 * described in the "anything else" entry below. */
+                ($type = $this->getAttr($token, 'type')) && strtolower($type) === 'hidden') {
+                    // I.e., if its an input with the type attribute == 'hidden'
+                    /* Otherwise */
+                    // parse error
+                    $this->insertElement($token);
+                    array_pop($this->stack);
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    /* If the current node is not the root html element, then this is a parse error. */
+                    if (end($this->stack)->tagName !== 'html') {
+                        // Note: It can only be the current node in the fragment case.
+                        // parse error
+                    }
+                    /* Stop parsing. */
+                /* Anything else */
+                } else {
+                    /* Parse error. Process the token as if the insertion mode was "in
+                    body", with the following exception: */
+
+                    $old = $this->foster_parent;
+                    $this->foster_parent = true;
+                    $this->processWithRulesFor($token, self::IN_BODY);
+                    $this->foster_parent = $old;
+                }
+            break;
+
+            case self::IN_TABLE_TEXT:
+                /* A character token */
+                if ($token['type'] === HTML5_Tokenizer::CHARACTER) {
+                    /* Append the character token to the pending table
+                     * character tokens list. */
+                    $this->pendingTableCharacters .= $token['data'];
+                    $this->pendingTableCharactersDirty = true;
+                } elseif ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    $this->pendingTableCharacters .= $token['data'];
+                /* Anything else */
+                } else {
+                    if ($this->pendingTableCharacters !== '' && is_string($this->pendingTableCharacters)) {
+                        /* If any of the tokens in the pending table character tokens list
+                         * are character tokens that are not one of U+0009 CHARACTER
+                         * TABULATION, U+000A LINE FEED (LF), U+000C FORM FEED (FF), or
+                         * U+0020 SPACE, then reprocess those character tokens using the
+                         * rules given in the "anything else" entry in the in table"
+                         * insertion mode.*/
+                        if ($this->pendingTableCharactersDirty) {
+                            /* Parse error. Process the token using the rules for the
+                             * "in body" insertion mode, except that if the current
+                             * node is a table, tbody, tfoot, thead, or tr element,
+                             * then, whenever a node would be inserted into the current
+                             * node, it must instead be foster parented. */
+                            // XERROR
+                            $old = $this->foster_parent;
+                            $this->foster_parent = true;
+                            $text_token = [
+                                'type' => HTML5_Tokenizer::CHARACTER,
+                                'data' => $this->pendingTableCharacters,
+                            ];
+                            $this->processWithRulesFor($text_token, self::IN_BODY);
+                            $this->foster_parent = $old;
+
+                        /* Otherwise, insert the characters given by the pending table
+                         * character tokens list into the current node. */
+                        } else {
+                            $this->insertText($this->pendingTableCharacters);
+                        }
+                        $this->pendingTableCharacters = null;
+                        $this->pendingTableCharactersNull = null;
+                    }
+
+                    /* Switch the insertion mode to the original insertion mode and
+                     * reprocess the token.
+                     */
+                    $this->mode = $this->original_mode;
+                    $this->emitToken($token);
+                }
+            break;
+
+            case self::IN_CAPTION:
+                /* An end tag whose tag name is "caption" */
+                if ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'caption') {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. (fragment case) */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->ignored = true;
+                        // Ignore
+
+                    /* Otherwise: */
+                    } else {
+                        /* Generate implied end tags. */
+                        $this->generateImpliedEndTags();
+
+                        /* Now, if the current node is not a caption element, then this
+                        is a parse error. */
+                        // XERROR: implement
+
+                        /* Pop elements from this stack until a caption element has
+                        been popped from the stack. */
+                        do {
+                            $node = array_pop($this->stack);
+                        } while ($node->tagName !== 'caption');
+
+                        /* Clear the list of active formatting elements up to the last
+                        marker. */
+                        $this->clearTheActiveFormattingElementsUpToTheLastMarker();
+
+                        /* Switch the insertion mode to "in table". */
+                        $this->mode = self::IN_TABLE;
+                    }
+
+                /* A start tag whose tag name is one of: "caption", "col", "colgroup",
+                "tbody", "td", "tfoot", "th", "thead", "tr", or an end tag whose tag
+                name is "table" */
+                } elseif (($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'],
+                ['caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
+                'thead', 'tr'])) || ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'table')) {
+                    /* Parse error. Act as if an end tag with the tag name "caption"
+                    had been seen, then, if that token wasn't ignored, reprocess the
+                    current token. */
+                    $this->emitToken([
+                        'name' => 'caption',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+
+                    if (!$this->ignored) {
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is one of: "body", "col", "colgroup",
+                "html", "tbody", "td", "tfoot", "th", "thead", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['body', 'col', 'colgroup', 'html', 'tbody', 'tfoot', 'th',
+                'thead', 'tr'])) {
+                    // Parse error. Ignore the token.
+                    $this->ignored = true;
+                } else {
+                    /* Process the token as if the insertion mode was "in body". */
+                    $this->processWithRulesFor($token, self::IN_BODY);
+                }
+            break;
+
+            case self::IN_COLUMN_GROUP:
+                /* A character token that is one of one of U+0009 CHARACTER TABULATION,
+                U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
+                or U+0020 SPACE */
+                if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    /* Append the character to the current node. */
+                    $this->insertText($token['data']);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the current node with the data
+                    attribute set to the data given in the comment token. */
+                    $this->insertComment($token['data']);
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* A start tag whose tag name is "col" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'col') {
+                    /* Insert a col element for the token. Immediately pop the current
+                    node off the stack of open elements. */
+                    $this->insertElement($token);
+                    array_pop($this->stack);
+                    // XERROR: Acknowledge the token's self-closing flag, if it is set.
+
+                /* An end tag whose tag name is "colgroup" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'colgroup') {
+                    /* If the current node is the root html element, then this is a
+                    parse error, ignore the token. (fragment case) */
+                    if (end($this->stack)->tagName === 'html') {
+                        $this->ignored = true;
+
+                    /* Otherwise, pop the current node (which will be a colgroup
+                    element) from the stack of open elements. Switch the insertion
+                    mode to "in table". */
+                    } else {
+                        array_pop($this->stack);
+                        $this->mode = self::IN_TABLE;
+                    }
+
+                /* An end tag whose tag name is "col" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'col') {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+
+                /* An end-of-file token */
+                /* If the current node is the root html  element */
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF && end($this->stack)->tagName === 'html') {
+                    /* Stop parsing */
+
+                /* Anything else */
+                } else {
+                    /* Act as if an end tag with the tag name "colgroup" had been seen,
+                    and then, if that token wasn't ignored, reprocess the current token. */
+                    $this->emitToken([
+                        'name' => 'colgroup',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+
+                    if (!$this->ignored) {
+                        $this->emitToken($token);
+                    }
+                }
+            break;
+
+            case self::IN_TABLE_BODY:
+                $clear = ['tbody', 'tfoot', 'thead', 'html'];
+
+                /* A start tag whose tag name is "tr" */
+                if ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'tr') {
+                    /* Clear the stack back to a table body context. */
+                    $this->clearStackToTableContext($clear);
+
+                    /* Insert a tr element for the token, then switch the insertion
+                    mode to "in row". */
+                    $this->insertElement($token);
+                    $this->mode = self::IN_ROW;
+
+                /* A start tag whose tag name is one of: "th", "td" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                ($token['name'] === 'th' ||    $token['name'] === 'td')) {
+                    /* Parse error. Act as if a start tag with the tag name "tr" had
+                    been seen, then reprocess the current token. */
+                    $this->emitToken([
+                        'name' => 'tr',
+                        'type' => HTML5_Tokenizer::STARTTAG,
+                        'attr' => []
+                    ]);
+
+                    $this->emitToken($token);
+
+                /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                in_array($token['name'], ['tbody', 'tfoot', 'thead'])) {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        // Parse error
+                        $this->ignored = true;
+
+                    /* Otherwise: */
+                    } else {
+                        /* Clear the stack back to a table body context. */
+                        $this->clearStackToTableContext($clear);
+
+                        /* Pop the current node from the stack of open elements. Switch
+                        the insertion mode to "in table". */
+                        array_pop($this->stack);
+                        $this->mode = self::IN_TABLE;
+                    }
+
+                /* A start tag whose tag name is one of: "caption", "col", "colgroup",
+                "tbody", "tfoot", "thead", or an end tag whose tag name is "table" */
+                } elseif (($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'],
+                ['caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead'])) ||
+                ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'table')) {
+                    /* If the stack of open elements does not have a tbody, thead, or
+                    tfoot element in table scope, this is a parse error. Ignore the
+                    token. (fragment case) */
+                    if (!$this->elementInScope(['tbody', 'thead', 'tfoot'], self::SCOPE_TABLE)) {
+                        // parse error
+                        $this->ignored = true;
+
+                    /* Otherwise: */
+                    } else {
+                        /* Clear the stack back to a table body context. */
+                        $this->clearStackToTableContext($clear);
+
+                        /* Act as if an end tag with the same tag name as the current
+                        node ("tbody", "tfoot", or "thead") had been seen, then
+                        reprocess the current token. */
+                        $this->emitToken([
+                            'name' => end($this->stack)->tagName,
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is one of: "body", "caption", "col",
+                "colgroup", "html", "td", "th", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['body', 'caption', 'col', 'colgroup', 'html', 'td', 'th', 'tr'])) {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+
+                /* Anything else */
+                } else {
+                    /* Process the token as if the insertion mode was "in table". */
+                    $this->processWithRulesFor($token, self::IN_TABLE);
+                }
+            break;
+
+            case self::IN_ROW:
+                $clear = ['tr', 'html'];
+
+                /* A start tag whose tag name is one of: "th", "td" */
+                if ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                ($token['name'] === 'th' || $token['name'] === 'td')) {
+                    /* Clear the stack back to a table row context. */
+                    $this->clearStackToTableContext($clear);
+
+                    /* Insert an HTML element for the token, then switch the insertion
+                    mode to "in cell". */
+                    $this->insertElement($token);
+                    $this->mode = self::IN_CELL;
+
+                    /* Insert a marker at the end of the list of active formatting
+                    elements. */
+                    $this->a_formatting[] = self::MARKER;
+
+                /* An end tag whose tag name is "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'tr') {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. (fragment case) */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        // Ignore.
+                        $this->ignored = true;
+                    } else {
+                        /* Clear the stack back to a table row context. */
+                        $this->clearStackToTableContext($clear);
+
+                        /* Pop the current node (which will be a tr element) from the
+                        stack of open elements. Switch the insertion mode to "in table
+                        body". */
+                        array_pop($this->stack);
+                        $this->mode = self::IN_TABLE_BODY;
+                    }
+
+                /* A start tag whose tag name is one of: "caption", "col", "colgroup",
+                "tbody", "tfoot", "thead", "tr" or an end tag whose tag name is "table" */
+                } elseif (($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'],
+                ['caption', 'col', 'colgroup', 'tbody', 'tfoot', 'thead', 'tr'])) ||
+                ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'table')) {
+                    /* Act as if an end tag with the tag name "tr" had been seen, then,
+                    if that token wasn't ignored, reprocess the current token. */
+                    $this->emitToken([
+                        'name' => 'tr',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+                    if (!$this->ignored) {
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is one of: "tbody", "tfoot", "thead" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                in_array($token['name'], ['tbody', 'tfoot', 'thead'])) {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->ignored = true;
+
+                    /* Otherwise: */
+                    } else {
+                        /* Otherwise, act as if an end tag with the tag name "tr" had
+                        been seen, then reprocess the current token. */
+                        $this->emitToken([
+                            'name' => 'tr',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is one of: "body", "caption", "col",
+                "colgroup", "html", "td", "th" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['body', 'caption', 'col', 'colgroup', 'html', 'td', 'th'])) {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+
+                /* Anything else */
+                } else {
+                    /* Process the token as if the insertion mode was "in table". */
+                    $this->processWithRulesFor($token, self::IN_TABLE);
+                }
+            break;
+
+            case self::IN_CELL:
+                /* An end tag whose tag name is one of: "td", "th" */
+                if ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                ($token['name'] === 'td' || $token['name'] === 'th')) {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as that of the token, then this is a
+                    parse error and the token must be ignored. */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->ignored = true;
+
+                    /* Otherwise: */
+                    } else {
+                        /* Generate implied end tags, except for elements with the same
+                        tag name as the token. */
+                        $this->generateImpliedEndTags([$token['name']]);
+
+                        /* Now, if the current node is not an element with the same tag
+                        name as the token, then this is a parse error. */
+                        // XERROR: Implement parse error code
+
+                        /* Pop elements from this stack until an element with the same
+                        tag name as the token has been popped from the stack. */
+                        do {
+                            $node = array_pop($this->stack);
+                        } while ($node->tagName !== $token['name']);
+
+                        /* Clear the list of active formatting elements up to the last
+                        marker. */
+                        $this->clearTheActiveFormattingElementsUpToTheLastMarker();
+
+                        /* Switch the insertion mode to "in row". (The current node
+                        will be a tr element at this point.) */
+                        $this->mode = self::IN_ROW;
+                    }
+
+                /* A start tag whose tag name is one of: "caption", "col", "colgroup",
+                "tbody", "td", "tfoot", "th", "thead", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && in_array($token['name'],
+                ['caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th',
+                'thead', 'tr'])) {
+                    /* If the stack of open elements does not have a td or th element
+                    in table scope, then this is a parse error; ignore the token.
+                    (fragment case) */
+                    if (!$this->elementInScope(['td', 'th'], self::SCOPE_TABLE)) {
+                        // parse error
+                        $this->ignored = true;
+
+                    /* Otherwise, close the cell (see below) and reprocess the current
+                    token. */
+                    } else {
+                        $this->closeCell();
+                        $this->emitToken($token);
+                    }
+
+                /* An end tag whose tag name is one of: "body", "caption", "col",
+                "colgroup", "html" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['body', 'caption', 'col', 'colgroup', 'html'])) {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+
+                /* An end tag whose tag name is one of: "table", "tbody", "tfoot",
+                "thead", "tr" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && in_array($token['name'],
+                ['table', 'tbody', 'tfoot', 'thead', 'tr'])) {
+                    /* If the stack of open elements does not have a td or th element
+                    in table scope, then this is a parse error; ignore the token.
+                    (innerHTML case) */
+                    if (!$this->elementInScope(['td', 'th'], self::SCOPE_TABLE)) {
+                        // Parse error
+                        $this->ignored = true;
+
+                    /* Otherwise, close the cell (see below) and reprocess the current
+                    token. */
+                    } else {
+                        $this->closeCell();
+                        $this->emitToken($token);
+                    }
+
+                /* Anything else */
+                } else {
+                    /* Process the token as if the insertion mode was "in body". */
+                    $this->processWithRulesFor($token, self::IN_BODY);
+                }
+            break;
+
+            case self::IN_SELECT:
+                /* Handle the token as follows: */
+
+                /* A character token */
+                if (
+                    $token['type'] === HTML5_Tokenizer::CHARACTER ||
+                    $token['type'] === HTML5_Tokenizer::SPACECHARACTER
+                ) {
+                    /* Append the token's character to the current node. */
+                    $this->insertText($token['data']);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the current node with the data
+                    attribute set to the data given in the comment token. */
+                    $this->insertComment($token['data']);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* A start tag token whose tag name is "option" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'option') {
+                    /* If the current node is an option element, act as if an end tag
+                    with the tag name "option" had been seen. */
+                    if (end($this->stack)->tagName === 'option') {
+                        $this->emitToken([
+                            'name' => 'option',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+                    }
+
+                    /* Insert an HTML element for the token. */
+                    $this->insertElement($token);
+
+                /* A start tag token whose tag name is "optgroup" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'optgroup') {
+                    /* If the current node is an option element, act as if an end tag
+                    with the tag name "option" had been seen. */
+                    if (end($this->stack)->tagName === 'option') {
+                        $this->emitToken([
+                            'name' => 'option',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+                    }
+
+                    /* If the current node is an optgroup element, act as if an end tag
+                    with the tag name "optgroup" had been seen. */
+                    if (end($this->stack)->tagName === 'optgroup') {
+                        $this->emitToken([
+                            'name' => 'optgroup',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+                    }
+
+                    /* Insert an HTML element for the token. */
+                    $this->insertElement($token);
+
+                /* An end tag token whose tag name is "optgroup" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'optgroup') {
+                    /* First, if the current node is an option element, and the node
+                    immediately before it in the stack of open elements is an optgroup
+                    element, then act as if an end tag with the tag name "option" had
+                    been seen. */
+                    $elements_in_stack = count($this->stack);
+
+                    if ($this->stack[$elements_in_stack - 1]->tagName === 'option' &&
+                    $this->stack[$elements_in_stack - 2]->tagName === 'optgroup') {
+                        $this->emitToken([
+                            'name' => 'option',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+                    }
+
+                    /* If the current node is an optgroup element, then pop that node
+                    from the stack of open elements. Otherwise, this is a parse error,
+                    ignore the token. */
+                    if (end($this->stack)->tagName === 'optgroup') {
+                        array_pop($this->stack);
+                    } else {
+                        // parse error
+                        $this->ignored = true;
+                    }
+
+                /* An end tag token whose tag name is "option" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'option') {
+                    /* If the current node is an option element, then pop that node
+                    from the stack of open elements. Otherwise, this is a parse error,
+                    ignore the token. */
+                    if (end($this->stack)->tagName === 'option') {
+                        array_pop($this->stack);
+                    } else {
+                        // parse error
+                        $this->ignored = true;
+                    }
+
+                /* An end tag whose tag name is "select" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'select') {
+                    /* If the stack of open elements does not have an element in table
+                    scope with the same tag name as the token, this is a parse error.
+                    Ignore the token. (fragment case) */
+                    if (!$this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->ignored = true;
+                        // parse error
+
+                    /* Otherwise: */
+                    } else {
+                        /* Pop elements from the stack of open elements until a select
+                        element has been popped from the stack. */
+                        do {
+                            $node = array_pop($this->stack);
+                        } while ($node->tagName !== 'select');
+
+                        /* Reset the insertion mode appropriately. */
+                        $this->resetInsertionMode();
+                    }
+
+                /* A start tag whose tag name is "select" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'select') {
+                    /* Parse error. Act as if the token had been an end tag with the
+                    tag name "select" instead. */
+                    $this->emitToken([
+                        'name' => 'select',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                ($token['name'] === 'input' || $token['name'] === 'keygen' ||  $token['name'] === 'textarea')) {
+                    // parse error
+                    $this->emitToken([
+                        'name' => 'select',
+                        'type' => HTML5_Tokenizer::ENDTAG
+                    ]);
+                    $this->emitToken($token);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'script') {
+                    $this->processWithRulesFor($token, self::IN_HEAD);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    // XERROR: If the current node is not the root html element, then this is a parse error.
+                    /* Stop parsing */
+
+                /* Anything else */
+                } else {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+                }
+            break;
+
+            case self::IN_SELECT_IN_TABLE:
+
+                if ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                in_array($token['name'], ['caption', 'table', 'tbody',
+                'tfoot', 'thead', 'tr', 'td', 'th'])) {
+                    // parse error
+                    $this->emitToken([
+                        'name' => 'select',
+                        'type' => HTML5_Tokenizer::ENDTAG,
+                    ]);
+                    $this->emitToken($token);
+
+                /* An end tag whose tag name is one of: "caption", "table", "tbody",
+                "tfoot", "thead", "tr", "td", "th" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                in_array($token['name'], ['caption', 'table', 'tbody', 'tfoot', 'thead', 'tr', 'td', 'th']))  {
+                    /* Parse error. */
+                    // parse error
+
+                    /* If the stack of open elements has an element in table scope with
+                    the same tag name as that of the token, then act as if an end tag
+                    with the tag name "select" had been seen, and reprocess the token.
+                    Otherwise, ignore the token. */
+                    if ($this->elementInScope($token['name'], self::SCOPE_TABLE)) {
+                        $this->emitToken([
+                            'name' => 'select',
+                            'type' => HTML5_Tokenizer::ENDTAG
+                        ]);
+
+                        $this->emitToken($token);
+                    } else {
+                        $this->ignored = true;
+                    }
+                } else {
+                    $this->processWithRulesFor($token, self::IN_SELECT);
+                }
+            break;
+
+            case self::IN_FOREIGN_CONTENT:
+                if ($token['type'] === HTML5_Tokenizer::CHARACTER ||
+                $token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    $this->insertText($token['data']);
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    $this->insertComment($token['data']);
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // XERROR: parse error
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'script' && end($this->stack)->tagName === 'script' &&
+                // XDOM
+                end($this->stack)->namespaceURI === self::NS_SVG) {
+                    array_pop($this->stack);
+                    // a bunch of script running mumbo jumbo
+                } elseif (
+                    ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                        ((
+                            $token['name'] !== 'mglyph' &&
+                            $token['name'] !== 'malignmark' &&
+                            // XDOM
+                            end($this->stack)->namespaceURI === self::NS_MATHML &&
+                            in_array(end($this->stack)->tagName, ['mi', 'mo', 'mn', 'ms', 'mtext'])
+                        ) ||
+                        (
+                            $token['name'] === 'svg' &&
+                            // XDOM
+                            end($this->stack)->namespaceURI === self::NS_MATHML &&
+                            end($this->stack)->tagName === 'annotation-xml'
+                        ) ||
+                        (
+                            // XDOM
+                            end($this->stack)->namespaceURI === self::NS_SVG &&
+                            in_array(end($this->stack)->tagName, ['foreignObject', 'desc', 'title'])
+                        ) ||
+                        (
+                            // XSKETCHY && XDOM
+                            end($this->stack)->namespaceURI === self::NS_HTML
+                        ))
+                    ) || $token['type'] === HTML5_Tokenizer::ENDTAG
+                ) {
+                    $this->processWithRulesFor($token, $this->secondary_mode);
+                    /* If, after doing so, the insertion mode is still "in foreign
+                     * content", but there is no element in scope that has a namespace
+                     * other than the HTML namespace, switch the insertion mode to the
+                     * secondary insertion mode. */
+                    if ($this->mode === self::IN_FOREIGN_CONTENT) {
+                        $found = false;
+                        // this basically duplicates elementInScope()
+                        for ($i = count($this->stack) - 1; $i >= 0; $i--) {
+                            // XDOM
+                            $node = $this->stack[$i];
+                            if ($node->namespaceURI !== self::NS_HTML) {
+                                $found = true;
+                                break;
+                            } elseif (in_array($node->tagName, ['table', 'html',
+                            'applet', 'caption', 'td', 'th', 'button', 'marquee',
+                            'object']) || ($node->tagName === 'foreignObject' &&
+                            $node->namespaceURI === self::NS_SVG)) {
+                                break;
+                            }
+                        }
+                        if (!$found) {
+                            $this->mode = $this->secondary_mode;
+                        }
+                    }
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF || (
+                $token['type'] === HTML5_Tokenizer::STARTTAG &&
+                (in_array($token['name'], ['b', "big", "blockquote", "body", "br",
+                "center", "code", "dc", "dd", "div", "dl", "ds", "dt", "em", "embed", "h1", "h2",
+                "h3", "h4", "h5", "h6", "head", "hr", "i", "img", "li", "listing",
+                "menu", "meta", "nobr", "ol", "p", "pre", "ruby", "s",  "small",
+                "span", "strong", "strike",  "sub", "sup", "table", "tt", "u", "ul",
+                "var"]) || ($token['name'] === 'font' && ($this->getAttr($token, 'color') ||
+                $this->getAttr($token, 'face') || $this->getAttr($token, 'size')))))) {
+                    // XERROR: parse error
+                    do {
+                        $node = array_pop($this->stack);
+                        // XDOM
+                    } while ($node->namespaceURI !== self::NS_HTML);
+                    $this->stack[] = $node;
+                    $this->mode = $this->secondary_mode;
+                    $this->emitToken($token);
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG) {
+                    static $svg_lookup = [
+                        'altglyph' => 'altGlyph',
+                        'altglyphdef' => 'altGlyphDef',
+                        'altglyphitem' => 'altGlyphItem',
+                        'animatecolor' => 'animateColor',
+                        'animatemotion' => 'animateMotion',
+                        'animatetransform' => 'animateTransform',
+                        'clippath' => 'clipPath',
+                        'feblend' => 'feBlend',
+                        'fecolormatrix' => 'feColorMatrix',
+                        'fecomponenttransfer' => 'feComponentTransfer',
+                        'fecomposite' => 'feComposite',
+                        'feconvolvematrix' => 'feConvolveMatrix',
+                        'fediffuselighting' => 'feDiffuseLighting',
+                        'fedisplacementmap' => 'feDisplacementMap',
+                        'fedistantlight' => 'feDistantLight',
+                        'feflood' => 'feFlood',
+                        'fefunca' => 'feFuncA',
+                        'fefuncb' => 'feFuncB',
+                        'fefuncg' => 'feFuncG',
+                        'fefuncr' => 'feFuncR',
+                        'fegaussianblur' => 'feGaussianBlur',
+                        'feimage' => 'feImage',
+                        'femerge' => 'feMerge',
+                        'femergenode' => 'feMergeNode',
+                        'femorphology' => 'feMorphology',
+                        'feoffset' => 'feOffset',
+                        'fepointlight' => 'fePointLight',
+                        'fespecularlighting' => 'feSpecularLighting',
+                        'fespotlight' => 'feSpotLight',
+                        'fetile' => 'feTile',
+                        'feturbulence' => 'feTurbulence',
+                        'foreignobject' => 'foreignObject',
+                        'glyphref' => 'glyphRef',
+                        'lineargradient' => 'linearGradient',
+                        'radialgradient' => 'radialGradient',
+                        'textpath' => 'textPath',
+                    ];
+                    // XDOM
+                    $current = end($this->stack);
+                    if ($current->namespaceURI === self::NS_MATHML) {
+                        $token = $this->adjustMathMLAttributes($token);
+                    }
+                    if ($current->namespaceURI === self::NS_SVG &&
+                    isset($svg_lookup[$token['name']])) {
+                        $token['name'] = $svg_lookup[$token['name']];
+                    }
+                    if ($current->namespaceURI === self::NS_SVG) {
+                        $token = $this->adjustSVGAttributes($token);
+                    }
+                    $token = $this->adjustForeignAttributes($token);
+                    $this->insertForeignElement($token, $current->namespaceURI);
+                    if (isset($token['self-closing'])) {
+                        array_pop($this->stack);
+                        // XERROR: acknowledge self-closing flag
+                    }
+                }
+            break;
+
+            case self::AFTER_BODY:
+                /* Handle the token as follows: */
+
+                /* A character token that is one of one of U+0009 CHARACTER TABULATION,
+                U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
+                or U+0020 SPACE */
+                if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    /* Process the token as it would be processed if the insertion mode
+                    was "in body". */
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the first element in the stack of open
+                    elements (the html element), with the data attribute set to the
+                    data given in the comment token. */
+                    // XDOM
+                    $comment = $this->dom->createComment($token['data']);
+                    $this->stack[0]->appendChild($comment);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* An end tag with the tag name "html" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG && $token['name'] === 'html') {
+                    /*     If the parser was originally created as part of the HTML
+                     *     fragment parsing algorithm, this is a parse error; ignore
+                     *     the token. (fragment case) */
+                    $this->ignored = true;
+                    // XERROR: implement this
+
+                    $this->mode = self::AFTER_AFTER_BODY;
+
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    /* Stop parsing */
+
+                /* Anything else */
+                } else {
+                    /* Parse error. Set the insertion mode to "in body" and reprocess
+                    the token. */
+                    $this->mode = self::IN_BODY;
+                    $this->emitToken($token);
+                }
+            break;
+
+            case self::IN_FRAMESET:
+                /* Handle the token as follows: */
+
+                /* A character token that is one of one of U+0009 CHARACTER TABULATION,
+                U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
+                U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
+                if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    /* Append the character to the current node. */
+                    $this->insertText($token['data']);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the current node with the data
+                    attribute set to the data given in the comment token. */
+                    $this->insertComment($token['data']);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+
+                /* A start tag with the tag name "frameset" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'frameset') {
+                    $this->insertElement($token);
+
+                /* An end tag with the tag name "frameset" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'frameset') {
+                    /* If the current node is the root html element, then this is a
+                    parse error; ignore the token. (fragment case) */
+                    if (end($this->stack)->tagName === 'html') {
+                        $this->ignored = true;
+                        // Parse error
+
+                    } else {
+                        /* Otherwise, pop the current node from the stack of open
+                        elements. */
+                        array_pop($this->stack);
+
+                        /* If the parser was not originally created as part of the HTML
+                         * fragment parsing algorithm  (fragment case), and the current
+                         * node is no longer a frameset element, then switch the
+                         * insertion mode to "after frameset". */
+                        $this->mode = self::AFTER_FRAMESET;
+                    }
+
+                /* A start tag with the tag name "frame" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'frame') {
+                    /* Insert an HTML element for the token. */
+                    $this->insertElement($token);
+
+                    /* Immediately pop the current node off the stack of open elements. */
+                    array_pop($this->stack);
+
+                    // XERROR: Acknowledge the token's self-closing flag, if it is set.
+
+                /* A start tag with the tag name "noframes" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'noframes') {
+                    /* Process the token using the rules for the "in head" insertion mode. */
+                    $this->processwithRulesFor($token, self::IN_HEAD);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    // XERROR: If the current node is not the root html element, then this is a parse error.
+                    /* Stop parsing */
+                /* Anything else */
+                } else {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+                }
+            break;
+
+            case self::AFTER_FRAMESET:
+                /* Handle the token as follows: */
+
+                /* A character token that is one of one of U+0009 CHARACTER TABULATION,
+                U+000A LINE FEED (LF), U+000B LINE TABULATION, U+000C FORM FEED (FF),
+                U+000D CARRIAGE RETURN (CR), or U+0020 SPACE */
+                if ($token['type'] === HTML5_Tokenizer::SPACECHARACTER) {
+                    /* Append the character to the current node. */
+                    $this->insertText($token['data']);
+
+                /* A comment token */
+                } elseif ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the current node with the data
+                    attribute set to the data given in the comment token. */
+                    $this->insertComment($token['data']);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE) {
+                    // parse error
+
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html') {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* An end tag with the tag name "html" */
+                } elseif ($token['type'] === HTML5_Tokenizer::ENDTAG &&
+                $token['name'] === 'html') {
+                    $this->mode = self::AFTER_AFTER_FRAMESET;
+
+                /* A start tag with the tag name "noframes" */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG &&
+                $token['name'] === 'noframes') {
+                    $this->processWithRulesFor($token, self::IN_HEAD);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    /* Stop parsing */
+
+                /* Anything else */
+                } else {
+                    /* Parse error. Ignore the token. */
+                    $this->ignored = true;
+                }
+            break;
+
+            case self::AFTER_AFTER_BODY:
+                /* A comment token */
+                if ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the Document object with the data
+                    attribute set to the data given in the comment token. */
+                    // XDOM
+                    $comment = $this->dom->createComment($token['data']);
+                    $this->dom->appendChild($comment);
+
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE ||
+                $token['type'] === HTML5_Tokenizer::SPACECHARACTER ||
+                ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html')) {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* An end-of-file token */
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    /* OMG DONE!! */
+                } else {
+                    // parse error
+                    $this->mode = self::IN_BODY;
+                    $this->emitToken($token);
+                }
+            break;
+
+            case self::AFTER_AFTER_FRAMESET:
+                /* A comment token */
+                if ($token['type'] === HTML5_Tokenizer::COMMENT) {
+                    /* Append a Comment node to the Document object with the data
+                    attribute set to the data given in the comment token. */
+                    // XDOM
+                    $comment = $this->dom->createComment($token['data']);
+                    $this->dom->appendChild($comment);
+                } elseif ($token['type'] === HTML5_Tokenizer::DOCTYPE ||
+                $token['type'] === HTML5_Tokenizer::SPACECHARACTER ||
+                ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'html')) {
+                    $this->processWithRulesFor($token, self::IN_BODY);
+
+                /* An end-of-file token */
+                } elseif ($token['type'] === HTML5_Tokenizer::EOF) {
+                    /* OMG DONE!! */
+                } elseif ($token['type'] === HTML5_Tokenizer::STARTTAG && $token['name'] === 'nofrmaes') {
+                    $this->processWithRulesFor($token, self::IN_HEAD);
+                } else {
+                    // parse error
+                }
+            break;
+        }
+    }
+
+    private function insertElement($token, $append = true) {
+        $el = $this->dom->createElementNS(self::NS_HTML, $token['name']);
+
+        if (!empty($token['attr'])) {
+            foreach ($token['attr'] as $attr) {
+                if (!$el->hasAttribute($attr['name']) && preg_match("/^[a-zA-Z_:]/", $attr['name'])) {
+                    $el->setAttribute($attr['name'], $attr['value']);
+                }
+            }
+        }
+        if ($append) {
+            $this->appendToRealParent($el);
+            $this->stack[] = $el;
+        }
+
+        return $el;
+    }
+
+    /**
+     * @param $data
+     */
+    private function insertText($data) {
+        if ($data === '') {
+            return;
+        }
+        if ($this->ignore_lf_token) {
+            if ($data[0] === "\n") {
+                $data = substr($data, 1);
+                if ($data === false) {
+                    return;
+                }
+            }
+        }
+        $text = $this->dom->createTextNode($data);
+        $this->appendToRealParent($text);
+    }
+
+    /**
+     * @param $data
+     */
+    private function insertComment($data) {
+        $comment = $this->dom->createComment($data);
+        $this->appendToRealParent($comment);
+    }
+
+    /**
+     * @param $node
+     */
+    private function appendToRealParent($node) {
+        // this is only for the foster_parent case
+        /* If the current node is a table, tbody, tfoot, thead, or tr
+        element, then, whenever a node would be inserted into the current
+        node, it must instead be inserted into the foster parent element. */
+        if (
+            !$this->foster_parent ||
+            !in_array(
+                end($this->stack)->tagName,
+                ['table', 'tbody', 'tfoot', 'thead', 'tr']
+            )
+        ) {
+            end($this->stack)->appendChild($node);
+        } else {
+            $this->fosterParent($node);
+        }
+    }
+
+    /**
+     * @param $el
+     * @param int $scope
+     * @return bool|null
+     */
+    private function elementInScope($el, $scope = self::SCOPE) {
+        if (is_array($el)) {
+            foreach($el as $element) {
+                if ($this->elementInScope($element, $scope)) {
+                    return true;
+                }
+            }
+
+            return false;
+        }
+
+        $leng = count($this->stack);
+
+        for ($n = 0; $n < $leng; $n++) {
+            /* 1. Initialise node to be the current node (the bottommost node of
+            the stack). */
+            $node = $this->stack[$leng - 1 - $n];
+
+            if ($node->tagName === $el) {
+                /* 2. If node is the target node, terminate in a match state. */
+                return true;
+
+                // We've expanded the logic for these states a little differently;
+                // Hixie's refactoring into "specific scope" is more general, but
+                // this "gets the job done"
+
+            // these are the common states for all scopes
+            } elseif ($node->tagName === 'table' || $node->tagName === 'html') {
+                return false;
+
+            // these are valid for "in scope" and "in list item scope"
+            } elseif ($scope !== self::SCOPE_TABLE &&
+            (in_array($node->tagName, ['applet', 'caption', 'td',
+                'th', 'button', 'marquee', 'object']) ||
+                $node->tagName === 'foreignObject' && $node->namespaceURI === self::NS_SVG)) {
+                return false;
+
+
+            // these are valid for "in list item scope"
+            } elseif ($scope === self::SCOPE_LISTITEM && in_array($node->tagName, ['ol', 'ul'])) {
+                return false;
+            }
+
+            /* Otherwise, set node to the previous entry in the stack of open
+            elements and return to step 2. (This will never fail, since the loop
+            will always terminate in the previous step if the top of the stack
+            is reached.) */
+        }
+
+        // To fix warning. This never happens or should return true/false
+        return null;
+    }
+
+    /**
+     * @return bool
+     */
+    private function reconstructActiveFormattingElements() {
+        /* 1. If there are no entries in the list of active formatting elements,
+        then there is nothing to reconstruct; stop this algorithm. */
+        $formatting_elements = count($this->a_formatting);
+
+        if ($formatting_elements === 0) {
+            return false;
+        }
+
+        /* 3. Let entry be the last (most recently added) element in the list
+        of active formatting elements. */
+        $entry = end($this->a_formatting);
+
+        /* 2. If the last (most recently added) entry in the list of active
+        formatting elements is a marker, or if it is an element that is in the
+        stack of open elements, then there is nothing to reconstruct; stop this
+        algorithm. */
+        if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
+            return false;
+        }
+
+        for ($a = $formatting_elements - 1; $a >= 0; true) {
+            /* 4. If there are no entries before entry in the list of active
+            formatting elements, then jump to step 8. */
+            if ($a === 0) {
+                $step_seven = false;
+                break;
+            }
+
+            /* 5. Let entry be the entry one earlier than entry in the list of
+            active formatting elements. */
+            $a--;
+            $entry = $this->a_formatting[$a];
+
+            /* 6. If entry is neither a marker nor an element that is also in
+            thetack of open elements, go to step 4. */
+            if ($entry === self::MARKER || in_array($entry, $this->stack, true)) {
+                break;
+            }
+        }
+
+        while (true) {
+            /* 7. Let entry be the element one later than entry in the list of
+            active formatting elements. */
+            if (isset($step_seven) && $step_seven === true) {
+                $a++;
+                $entry = $this->a_formatting[$a];
+            }
+
+            /* 8. Perform a shallow clone of the element entry to obtain clone. */
+            $clone = $entry->cloneNode();
+
+            /* 9. Append clone to the current node and push it onto the stack
+            of open elements  so that it is the new current node. */
+            $this->appendToRealParent($clone);
+            $this->stack[] = $clone;
+
+            /* 10. Replace the entry for entry in the list with an entry for
+            clone. */
+            $this->a_formatting[$a] = $clone;
+
+            /* 11. If the entry for clone in the list of active formatting
+            elements is not the last entry in the list, return to step 7. */
+            if (end($this->a_formatting) !== $clone) {
+                $step_seven = true;
+            } else {
+                break;
+            }
+        }
+
+        // Return value not in use ATM. Would just make sense to also return true here.
+        return true;
+    }
+
+    /**
+     *
+     */
+    private function clearTheActiveFormattingElementsUpToTheLastMarker() {
+        /* When the steps below require the UA to clear the list of active
+        formatting elements up to the last marker, the UA must perform the
+        following steps: */
+
+        while (true) {
+            /* 1. Let entry be the last (most recently added) entry in the list
+            of active formatting elements. */
+            $entry = end($this->a_formatting);
+
+            /* 2. Remove entry from the list of active formatting elements. */
+            array_pop($this->a_formatting);
+
+            /* 3. If entry was a marker, then stop the algorithm at this point.
+            The list has been cleared up to the last marker. */
+            if ($entry === self::MARKER) {
+                break;
+            }
+        }
+    }
+
+    /**
+     * @param array $exclude
+     */
+    private function generateImpliedEndTags($exclude = []) {
+        /* When the steps below require the UA to generate implied end tags,
+         * then, while the current node is a dc element, a dd element, a ds
+         * element, a dt element, an li element, an option element, an optgroup
+         * element, a p element, an rp element, or an rt element, the UA must
+         * pop the current node off the stack of open elements. */
+        $node = end($this->stack);
+        $elements = array_diff(['dc', 'dd', 'ds', 'dt', 'li', 'p', 'td', 'th', 'tr'], $exclude);
+
+        while (in_array(end($this->stack)->tagName, $elements)) {
+            array_pop($this->stack);
+        }
+    }
+
+    /**
+     * @param $node
+     * @return int
+     */
+    private function getElementCategory($node) {
+        if (!is_object($node)) {
+            debug_print_backtrace();
+        }
+        $name = $node->tagName;
+        if (in_array($name, $this->special)) {
+            return self::SPECIAL;
+        } elseif (in_array($name, $this->scoping)) {
+            return self::SCOPING;
+        } elseif (in_array($name, $this->formatting)) {
+            return self::FORMATTING;
+        } else {
+            return self::PHRASING;
+        }
+    }
+
+    /**
+     * @param $elements
+     */
+    private function clearStackToTableContext($elements) {
+        /* When the steps above require the UA to clear the stack back to a
+        table context, it means that the UA must, while the current node is not
+        a table element or an html element, pop elements from the stack of open
+        elements. */
+        while (true) {
+            $name = end($this->stack)->tagName;
+
+            if (in_array($name, $elements)) {
+                break;
+            } else {
+                array_pop($this->stack);
+            }
+        }
+    }
+
+    /**
+     * @param null $context
+     */
+    private function resetInsertionMode($context = null) {
+        /* 1. Let last be false. */
+        $last = false;
+        $leng = count($this->stack);
+
+        for ($n = $leng - 1; $n >= 0; $n--) {
+            /* 2. Let node be the last node in the stack of open elements. */
+            $node = $this->stack[$n];
+
+            /* 3. If node is the first node in the stack of open elements, then
+             * set last to true and set node to the context  element. (fragment
+             * case) */
+            if ($this->stack[0]->isSameNode($node)) {
+                $last = true;
+                $node = $context;
+            }
+
+            /* 4. If node is a select element, then switch the insertion mode to
+            "in select" and abort these steps. (fragment case) */
+            if ($node->tagName === 'select') {
+                $this->mode = self::IN_SELECT;
+                break;
+
+            /* 5. If node is a td or th element, then switch the insertion mode
+            to "in cell" and abort these steps. */
+            } elseif ($node->tagName === 'td' || $node->nodeName === 'th') {
+                $this->mode = self::IN_CELL;
+                break;
+
+            /* 6. If node is a tr element, then switch the insertion mode to
+            "in    row" and abort these steps. */
+            } elseif ($node->tagName === 'tr') {
+                $this->mode = self::IN_ROW;
+                break;
+
+            /* 7. If node is a tbody, thead, or tfoot element, then switch the
+            insertion mode to "in table body" and abort these steps. */
+            } elseif (in_array($node->tagName, ['tbody', 'thead', 'tfoot'])) {
+                $this->mode = self::IN_TABLE_BODY;
+                break;
+
+            /* 8. If node is a caption element, then switch the insertion mode
+            to "in caption" and abort these steps. */
+            } elseif ($node->tagName === 'caption') {
+                $this->mode = self::IN_CAPTION;
+                break;
+
+            /* 9. If node is a colgroup element, then switch the insertion mode
+            to "in column group" and abort these steps. (innerHTML case) */
+            } elseif ($node->tagName === 'colgroup') {
+                $this->mode = self::IN_COLUMN_GROUP;
+                break;
+
+            /* 10. If node is a table element, then switch the insertion mode
+            to "in table" and abort these steps. */
+            } elseif ($node->tagName === 'table') {
+                $this->mode = self::IN_TABLE;
+                break;
+
+            /* 11. If node is an element from the MathML namespace or the SVG
+             * namespace, then switch the insertion mode to "in foreign
+             * content", let the secondary insertion mode be "in body", and
+             * abort these steps. */
+            } elseif ($node->namespaceURI === self::NS_SVG ||
+            $node->namespaceURI === self::NS_MATHML) {
+                $this->mode = self::IN_FOREIGN_CONTENT;
+                $this->secondary_mode = self::IN_BODY;
+                break;
+
+            /* 12. If node is a head element, then switch the insertion mode
+            to "in body" ("in body"! not "in head"!) and abort these steps.
+            (fragment case) */
+            } elseif ($node->tagName === 'head') {
+                $this->mode = self::IN_BODY;
+                break;
+
+            /* 13. If node is a body element, then switch the insertion mode to
+            "in body" and abort these steps. */
+            } elseif ($node->tagName === 'body') {
+                $this->mode = self::IN_BODY;
+                break;
+
+            /* 14. If node is a frameset element, then switch the insertion
+            mode to "in frameset" and abort these steps. (fragment case) */
+            } elseif ($node->tagName === 'frameset') {
+                $this->mode = self::IN_FRAMESET;
+                break;
+
+            /* 15. If node is an html element, then: if the head element
+            pointer is null, switch the insertion mode to "before head",
+            otherwise, switch the insertion mode to "after head". In either
+            case, abort these steps. (fragment case) */
+            } elseif ($node->tagName === 'html') {
+                $this->mode = ($this->head_pointer === null)
+                    ? self::BEFORE_HEAD
+                    : self::AFTER_HEAD;
+
+                break;
+
+            /* 16. If last is true, then set the insertion mode to "in body"
+            and    abort these steps. (fragment case) */
+            } elseif ($last) {
+                $this->mode = self::IN_BODY;
+                break;
+            }
+        }
+    }
+
+    /**
+     *
+     */
+    private function closeCell() {
+        /* If the stack of open elements has a td or th element in table scope,
+        then act as if an end tag token with that tag name had been seen. */
+        foreach (['td', 'th'] as $cell) {
+            if ($this->elementInScope($cell, self::SCOPE_TABLE)) {
+                $this->emitToken([
+                    'name' => $cell,
+                    'type' => HTML5_Tokenizer::ENDTAG
+                ]);
+
+                break;
+            }
+        }
+    }
+
+    /**
+     * @param $token
+     * @param $mode
+     */
+    private function processWithRulesFor($token, $mode) {
+        /* "using the rules for the m insertion mode", where m is one of these
+         * modes, the user agent must use the rules described under the m
+         * insertion mode's section, but must leave the insertion mode
+         * unchanged unless the rules in m themselves switch the insertion mode
+         * to a new value. */
+        $this->emitToken($token, $mode);
+    }
+
+    /**
+     * @param $token
+     */
+    private function insertCDATAElement($token) {
+        $this->insertElement($token);
+        $this->original_mode = $this->mode;
+        $this->mode = self::IN_CDATA_RCDATA;
+        $this->content_model = HTML5_Tokenizer::CDATA;
+    }
+
+    /**
+     * @param $token
+     */
+    private function insertRCDATAElement($token) {
+        $this->insertElement($token);
+        $this->original_mode = $this->mode;
+        $this->mode = self::IN_CDATA_RCDATA;
+        $this->content_model = HTML5_Tokenizer::RCDATA;
+    }
+
+    /**
+     * @param $token
+     * @param $key
+     * @return bool
+     */
+    private function getAttr($token, $key) {
+        if (!isset($token['attr'])) {
+            return false;
+        }
+        $ret = false;
+        foreach ($token['attr'] as $keypair) {
+            if ($keypair['name'] === $key) {
+                $ret = $keypair['value'];
+            }
+        }
+        return $ret;
+    }
+
+    /**
+     * @return mixed
+     */
+    private function getCurrentTable() {
+        /* The current table is the last table  element in the stack of open
+         * elements, if there is one. If there is no table element in the stack
+         * of open elements (fragment case), then the current table is the
+         * first element in the stack of open elements (the html element). */
+        for ($i = count($this->stack) - 1; $i >= 0; $i--) {
+            if ($this->stack[$i]->tagName === 'table') {
+                return $this->stack[$i];
+            }
+        }
+        return $this->stack[0];
+    }
+
+    /**
+     * @return mixed
+     */
+    private function getFosterParent() {
+        /* The foster parent element is the parent element of the last
+        table element in the stack of open elements, if there is a
+        table element and it has such a parent element. If there is no
+        table element in the stack of open elements (innerHTML case),
+        then the foster parent element is the first element in the
+        stack of open elements (the html  element). Otherwise, if there
+        is a table element in the stack of open elements, but the last
+        table element in the stack of open elements has no parent, or
+        its parent node is not an element, then the foster parent
+        element is the element before the last table element in the
+        stack of open elements. */
+        for ($n = count($this->stack) - 1; $n >= 0; $n--) {
+            if ($this->stack[$n]->tagName === 'table') {
+                $table = $this->stack[$n];
+                break;
+            }
+        }
+
+        if (isset($table) && $table->parentNode !== null) {
+            return $table->parentNode;
+
+        } elseif (!isset($table)) {
+            return $this->stack[0];
+
+        } elseif (isset($table) && ($table->parentNode === null ||
+        $table->parentNode->nodeType !== XML_ELEMENT_NODE)) {
+            return $this->stack[$n - 1];
+        }
+
+        return null;
+    }
+
+    /**
+     * @param $node
+     */
+    public function fosterParent($node) {
+        $foster_parent = $this->getFosterParent();
+        $table = $this->getCurrentTable(); // almost equivalent to last table element, except it can be html
+        /* When a node node is to be foster parented, the node node must be
+         * be inserted into the foster parent element. */
+        /* If the foster parent element is the parent element of the last table
+         * element in the stack of open elements, then node must be inserted
+         * immediately before the last table element in the stack of open
+         * elements in the foster parent element; otherwise, node must be
+         * appended to the foster parent element. */
+        if ($table->tagName === 'table' && $table->parentNode->isSameNode($foster_parent)) {
+            $foster_parent->insertBefore($node, $table);
+        } else {
+            $foster_parent->appendChild($node);
+        }
+    }
+
+    /**
+     * For debugging, prints the stack
+     */
+    private function printStack() {
+        $names = [];
+        foreach ($this->stack as $i => $element) {
+            $names[] = $element->tagName;
+        }
+        echo "  -> stack [" . implode(', ', $names) . "]\n";
+    }
+
+    /**
+     * For debugging, prints active formatting elements
+     */
+    private function printActiveFormattingElements() {
+        if (!$this->a_formatting) {
+            return;
+        }
+        $names = [];
+        foreach ($this->a_formatting as $node) {
+            if ($node === self::MARKER) {
+                $names[] = 'MARKER';
+            } else {
+                $names[] = $node->tagName;
+            }
+        }
+        echo "  -> active formatting [" . implode(', ', $names) . "]\n";
+    }
+
+    /**
+     * @return bool
+     */
+    public function currentTableIsTainted() {
+        return !empty($this->getCurrentTable()->tainted);
+    }
+
+    /**
+     * Sets up the tree constructor for building a fragment.
+     *
+     * @param null $context
+     */
+    public function setupContext($context = null) {
+        $this->fragment = true;
+        if ($context) {
+            $context = $this->dom->createElementNS(self::NS_HTML, $context);
+            /* 4.1. Set the HTML parser's tokenization  stage's content model
+             * flag according to the context element, as follows: */
+            switch ($context->tagName) {
+                case 'title': case 'textarea':
+                    $this->content_model = HTML5_Tokenizer::RCDATA;
+                    break;
+                case 'style': case 'script': case 'xmp': case 'iframe':
+                case 'noembed': case 'noframes':
+                    $this->content_model = HTML5_Tokenizer::CDATA;
+                    break;
+                case 'noscript':
+                    // XSCRIPT: assuming scripting is enabled
+                    $this->content_model = HTML5_Tokenizer::CDATA;
+                    break;
+                case 'plaintext':
+                    $this->content_model = HTML5_Tokenizer::PLAINTEXT;
+                    break;
+            }
+            /* 4.2. Let root be a new html element with no attributes. */
+            $root = $this->dom->createElementNS(self::NS_HTML, 'html');
+            $this->root = $root;
+            /* 4.3 Append the element root to the Document node created above. */
+            $this->dom->appendChild($root);
+            /* 4.4 Set up the parser's stack of open elements so that it
+             * contains just the single element root. */
+            $this->stack = [$root];
+            /* 4.5 Reset the parser's insertion mode appropriately. */
+            $this->resetInsertionMode($context);
+            /* 4.6 Set the parser's form element pointer  to the nearest node
+             * to the context element that is a form element (going straight up
+             * the ancestor chain, and including the element itself, if it is a
+             * form element), or, if there is no such form element, to null. */
+            $node = $context;
+            do {
+                if ($node->tagName === 'form') {
+                    $this->form_pointer = $node;
+                    break;
+                }
+            } while ($node = $node->parentNode);
+        }
+    }
+
+    /**
+     * @param $token
+     * @return mixed
+     */
+    public function adjustMathMLAttributes($token) {
+        foreach ($token['attr'] as &$kp) {
+            if ($kp['name'] === 'definitionurl') {
+                $kp['name'] = 'definitionURL';
+            }
+        }
+        return $token;
+    }
+
+    /**
+     * @param $token
+     * @return mixed
+     */
+    public function adjustSVGAttributes($token) {
+        static $lookup = [
+            'attributename' => 'attributeName',
+            'attributetype' => 'attributeType',
+            'basefrequency' => 'baseFrequency',
+            'baseprofile' => 'baseProfile',
+            'calcmode' => 'calcMode',
+            'clippathunits' => 'clipPathUnits',
+            'contentscripttype' => 'contentScriptType',
+            'contentstyletype' => 'contentStyleType',
+            'diffuseconstant' => 'diffuseConstant',
+            'edgemode' => 'edgeMode',
+            'externalresourcesrequired' => 'externalResourcesRequired',
+            'filterres' => 'filterRes',
+            'filterunits' => 'filterUnits',
+            'glyphref' => 'glyphRef',
+            'gradienttransform' => 'gradientTransform',
+            'gradientunits' => 'gradientUnits',
+            'kernelmatrix' => 'kernelMatrix',
+            'kernelunitlength' => 'kernelUnitLength',
+            'keypoints' => 'keyPoints',
+            'keysplines' => 'keySplines',
+            'keytimes' => 'keyTimes',
+            'lengthadjust' => 'lengthAdjust',
+            'limitingconeangle' => 'limitingConeAngle',
+            'markerheight' => 'markerHeight',
+            'markerunits' => 'markerUnits',
+            'markerwidth' => 'markerWidth',
+            'maskcontentunits' => 'maskContentUnits',
+            'maskunits' => 'maskUnits',
+            'numoctaves' => 'numOctaves',
+            'pathlength' => 'pathLength',
+            'patterncontentunits' => 'patternContentUnits',
+            'patterntransform' => 'patternTransform',
+            'patternunits' => 'patternUnits',
+            'pointsatx' => 'pointsAtX',
+            'pointsaty' => 'pointsAtY',
+            'pointsatz' => 'pointsAtZ',
+            'preservealpha' => 'preserveAlpha',
+            'preserveaspectratio' => 'preserveAspectRatio',
+            'primitiveunits' => 'primitiveUnits',
+            'refx' => 'refX',
+            'refy' => 'refY',
+            'repeatcount' => 'repeatCount',
+            'repeatdur' => 'repeatDur',
+            'requiredextensions' => 'requiredExtensions',
+            'requiredfeatures' => 'requiredFeatures',
+            'specularconstant' => 'specularConstant',
+            'specularexponent' => 'specularExponent',
+            'spreadmethod' => 'spreadMethod',
+            'startoffset' => 'startOffset',
+            'stddeviation' => 'stdDeviation',
+            'stitchtiles' => 'stitchTiles',
+            'surfacescale' => 'surfaceScale',
+            'systemlanguage' => 'systemLanguage',
+            'tablevalues' => 'tableValues',
+            'targetx' => 'targetX',
+            'targety' => 'targetY',
+            'textlength' => 'textLength',
+            'viewbox' => 'viewBox',
+            'viewtarget' => 'viewTarget',
+            'xchannelselector' => 'xChannelSelector',
+            'ychannelselector' => 'yChannelSelector',
+            'zoomandpan' => 'zoomAndPan',
+        ];
+        foreach ($token['attr'] as &$kp) {
+            if (isset($lookup[$kp['name']])) {
+                $kp['name'] = $lookup[$kp['name']];
+            }
+        }
+        return $token;
+    }
+
+    /**
+     * @param $token
+     * @return mixed
+     */
+    public function adjustForeignAttributes($token) {
+        static $lookup = [
+            'xlink:actuate' => ['xlink', 'actuate', self::NS_XLINK],
+            'xlink:arcrole' => ['xlink', 'arcrole', self::NS_XLINK],
+            'xlink:href' => ['xlink', 'href', self::NS_XLINK],
+            'xlink:role' => ['xlink', 'role', self::NS_XLINK],
+            'xlink:show' => ['xlink', 'show', self::NS_XLINK],
+            'xlink:title' => ['xlink', 'title', self::NS_XLINK],
+            'xlink:type' => ['xlink', 'type', self::NS_XLINK],
+            'xml:base' => ['xml', 'base', self::NS_XML],
+            'xml:lang' => ['xml', 'lang', self::NS_XML],
+            'xml:space' => ['xml', 'space', self::NS_XML],
+            'xmlns' => [null, 'xmlns', self::NS_XMLNS],
+            'xmlns:xlink' => ['xmlns', 'xlink', self::NS_XMLNS],
+        ];
+        foreach ($token['attr'] as &$kp) {
+            if (isset($lookup[$kp['name']])) {
+                $kp['name'] = $lookup[$kp['name']];
+            }
+        }
+        return $token;
+    }
+
+    /**
+     * @param $token
+     * @param $namespaceURI
+     */
+    public function insertForeignElement($token, $namespaceURI) {
+        $el = $this->dom->createElementNS($namespaceURI, $token['name']);
+
+        if (!empty($token['attr'])) {
+            foreach ($token['attr'] as $kp) {
+                $attr = $kp['name'];
+                if (is_array($attr)) {
+                    $ns = $attr[2];
+                    $attr = $attr[1];
+                } else {
+                    $ns = self::NS_HTML;
+                }
+                if (!$el->hasAttributeNS($ns, $attr)) {
+                    // XSKETCHY: work around godawful libxml bug
+                    if ($ns === self::NS_XLINK) {
+                        $el->setAttribute('xlink:'.$attr, $kp['value']);
+                    } elseif ($ns === self::NS_HTML) {
+                        // Another godawful libxml bug
+                        $el->setAttribute($attr, $kp['value']);
+                    } else {
+                        $el->setAttributeNS($ns, $attr, $kp['value']);
+                    }
+                }
+            }
+        }
+        $this->appendToRealParent($el);
+        $this->stack[] = $el;
+        // XERROR: see below
+        /* If the newly created element has an xmlns attribute in the XMLNS
+         * namespace  whose value is not exactly the same as the element's
+         * namespace, that is a parse error. Similarly, if the newly created
+         * element has an xmlns:xlink attribute in the XMLNS namespace whose
+         * value is not the XLink Namespace, that is a parse error. */
+    }
+
+    /**
+     * @return DOMDocument|DOMNodeList
+     */
+    public function save() {
+        $this->dom->normalize();
+        if (!$this->fragment) {
+            return $this->dom;
+        } else {
+            if ($this->root) {
+                return $this->root->childNodes;
+            } else {
+                return $this->dom->childNodes;
+            }
+        }
+    }
+}
+
diff --git a/vendor/dompdf/dompdf/lib/html5lib/named-character-references.ser b/vendor/dompdf/dompdf/lib/html5lib/named-character-references.ser
new file mode 100644
index 0000000..e3ae050
--- /dev/null
+++ b/vendor/dompdf/dompdf/lib/html5lib/named-character-references.ser
@@ -0,0 +1 @@
+a:52:{s:1:"A";a:16:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:198;}s:9:"codepoint";i:198;}}}}s:1:"M";a:1:{s:1:"P";a:2:{s:1:";";a:1:{s:9:"codepoint";i:38;}s:9:"codepoint";i:38;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:193;}s:9:"codepoint";i:193;}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:258;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:194;}s:9:"codepoint";i:194;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1040;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120068;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:192;}s:9:"codepoint";i:192;}}}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:913;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:256;}}}}}s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10835;}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:260;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120120;}}}}s:1:"p";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"F";a:1:{s:1:"u";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8289;}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:197;}s:9:"codepoint";i:197;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119964;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8788;}}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:195;}s:9:"codepoint";i:195;}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:196;}s:9:"codepoint";i:196;}}}}s:1:"B";a:8:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}}}}s:1:"r";a:2:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10983;}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8966;}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1041;}}}s:1:"e";a:3:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8757;}}}}}}s:1:"r";a:1:{s:1:"n";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:914;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120069;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120121;}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:728;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8782;}}}}}}}s:1:"C";a:14:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1063;}}}}s:1:"O";a:1:{s:1:"P";a:1:{s:1:"Y";a:2:{s:1:";";a:1:{s:9:"codepoint";i:169;}s:9:"codepoint";i:169;}}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:262;}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8914;}s:1:"i";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:"i";a:1:{s:1:"f";a:1:{s:1:"f";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8517;}}}}}}}}}}}}}}}}}}}s:1:"y";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"y";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8493;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:268;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:199;}s:9:"codepoint";i:199;}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:264;}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8752;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:266;}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:184;}}}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:183;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8493;}}}s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:935;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:"e";a:4:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8857;}}}}s:1:"M";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8854;}}}}}}s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8853;}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8855;}}}}}}}}}}}s:1:"l";a:1:{s:1:"o";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"w";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8754;}}}}}}}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8221;}}}}}}}}}}}}s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8217;}}}}}}}}}}}}}}}s:1:"o";a:4:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8759;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10868;}}}}}s:1:"n";a:3:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8801;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8751;}}}}s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}}}}}}}}}}}s:1:"p";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8450;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8720;}}}}}}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"C";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"w";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8755;}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10799;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119966;}}}}s:1:"u";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8915;}s:1:"C";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8781;}}}}}}}s:1:"D";a:11:{s:1:"D";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8517;}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"h";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10513;}}}}}}}}s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1026;}}}}s:1:"S";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1029;}}}}s:1:"Z";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1039;}}}}s:1:"a";a:3:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8225;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8609;}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10980;}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:270;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1044;}}}s:1:"e";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8711;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:916;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120071;}}}s:1:"i";a:2:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:180;}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:729;}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:733;}}}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:96;}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:732;}}}}}}}}}}}}}}s:1:"m";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8900;}}}}}}s:1:"f";a:1:{s:1:"f";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8518;}}}}}}}}}}}}}s:1:"o";a:4:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120123;}}}s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:168;}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8412;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8784;}}}}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:6:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8751;}}}}}}}}}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:168;}}s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}}}}}}}s:1:"L";a:2:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10980;}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8872;}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:6:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8595;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10515;}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8693;}}}}}}}}}}}}}s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:785;}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:3:{s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10576;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10590;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8637;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10582;}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10591;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8641;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10583;}}}}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8868;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8615;}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119967;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:272;}}}}}}}s:1:"E";a:16:{s:1:"N";a:1:{s:1:"G";a:1:{s:1:";";a:1:{s:9:"codepoint";i:330;}}}s:1:"T";a:1:{s:1:"H";a:2:{s:1:";";a:1:{s:9:"codepoint";i:208;}s:9:"codepoint";i:208;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:201;}s:9:"codepoint";i:201;}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:282;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:202;}s:9:"codepoint";i:202;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1069;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:278;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120072;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:200;}s:9:"codepoint";i:200;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8712;}}}}}}}s:1:"m";a:2:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:274;}}}}s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:2:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9723;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9643;}}}}}}}}}}}}}}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:280;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120124;}}}}s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:917;}}}}}}}s:1:"q";a:1:{s:1:"u";a:2:{s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10869;}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}}}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8496;}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10867;}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:919;}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:203;}s:9:"codepoint";i:203;}}}s:1:"x";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8707;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}}}}}}}}}}}}s:1:"F";a:5:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1060;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120073;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9724;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"S";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"S";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}}}}}}}}}}}}}}}}}}s:1:"o";a:3:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120125;}}}s:1:"r";a:1:{s:1:"A";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8704;}}}}}s:1:"u";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8497;}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8497;}}}}}s:1:"G";a:12:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1027;}}}}s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:62;}s:9:"codepoint";i:62;}s:1:"a";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:915;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:988;}}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:286;}}}}}}s:1:"c";a:3:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:290;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:284;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1043;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:288;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120074;}}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8921;}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120126;}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:6:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}}}}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8807;}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10914;}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8823;}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10878;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8819;}}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119970;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8811;}}}s:1:"H";a:8:{s:1:"A";a:1:{s:1:"R";a:1:{s:1:"D";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1066;}}}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:711;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:94;}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:292;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8460;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"b";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}}}}}}}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8461;}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"z";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9472;}}}}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:294;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"H";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8782;}}}}}}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8783;}}}}}}}}}}s:1:"I";a:14:{s:1:"E";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1045;}}}}s:1:"J";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:306;}}}}}s:1:"O";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1025;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:205;}s:9:"codepoint";i:205;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:206;}s:9:"codepoint";i:206;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1048;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:304;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:204;}s:9:"codepoint";i:204;}}}}}s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8465;}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:298;}}}s:1:"g";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"I";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8520;}}}}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}}s:1:"n";a:2:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8748;}s:1:"e";a:2:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8747;}}}}}s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}}}}}}}}}s:1:"v";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"C";a:1:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8291;}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8290;}}}}}}}}}}}}}}s:1:"o";a:3:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:302;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120128;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:921;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8464;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:296;}}}}}}s:1:"u";a:2:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1030;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:207;}s:9:"codepoint";i:207;}}}}s:1:"J";a:5:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:308;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1049;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120077;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120129;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119973;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1032;}}}}}}s:1:"u";a:1:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1028;}}}}}}s:1:"K";a:7:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1061;}}}}s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1036;}}}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:922;}}}}}s:1:"c";a:2:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:310;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1050;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120078;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120130;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119974;}}}}}s:1:"L";a:11:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1033;}}}}s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:60;}s:9:"codepoint";i:60;}s:1:"a";a:5:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:313;}}}}}s:1:"m";a:1:{s:1:"b";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:923;}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10218;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8606;}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:317;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:315;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1051;}}}s:1:"e";a:2:{s:1:"f";a:1:{s:1:"t";a:10:{s:1:"A";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10216;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8676;}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}}}}}}}}}}}}}s:1:"C";a:1:{s:1:"e";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8968;}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10214;}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10593;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8643;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10585;}}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8970;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8596;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10574;}}}}}}}}}}}}s:1:"T";a:2:{s:1:"e";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8867;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8612;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10586;}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8882;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10703;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:3:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10577;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10592;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8639;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10584;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8636;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10578;}}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"s";a:6:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8806;}}}}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8822;}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10913;}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10877;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8818;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120079;}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8920;}s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8666;}}}}}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:319;}}}}}}s:1:"o";a:3:{s:1:"n";a:1:{s:1:"g";a:4:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120131;}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8601;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8600;}}}}}}}}}}}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8624;}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:321;}}}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8810;}}}s:1:"M";a:8:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10501;}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1052;}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8287;}}}}}}}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120080;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120132;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:924;}}}s:1:"N";a:9:{s:1:"J";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1034;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:323;}}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:327;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:325;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1053;}}}s:1:"e";a:3:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"v";a:1:{s:1:"e";a:3:{s:1:"M";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:2:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"y";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8811;}}}}}}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8810;}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120081;}}}s:1:"o";a:4:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8288;}}}}}}s:1:"n";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"k";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:160;}}}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8469;}}}s:1:"t";a:11:{s:1:";";a:1:{s:9:"codepoint";i:10988;}s:1:"C";a:2:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8802;}}}}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"C";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8813;}}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}}}}}}}}}}}s:1:"E";a:3:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8713;}}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8800;}}}}}s:1:"x";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8708;}}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8815;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8817;}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8825;}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8821;}}}}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:2:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"T";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8814;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8816;}}}}}}s:1:"G";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8824;}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8820;}}}}}}}}}}s:1:"P";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8832;}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8928;}}}}}}}}}}}}}}}}}}}s:1:"R";a:2:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8716;}}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"T";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}}}}}}}}}}}}}}s:1:"S";a:2:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"S";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8930;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8931;}}}}}}}}}}}}}}}}}}}s:1:"u";a:3:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}}}}}}}}}s:1:"c";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8833;}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8929;}}}}}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}}}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8769;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8772;}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8775;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8777;}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119977;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:209;}s:9:"codepoint";i:209;}}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:925;}}}s:1:"O";a:14:{s:1:"E";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:338;}}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:211;}s:9:"codepoint";i:211;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:212;}s:9:"codepoint";i:212;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1054;}}}s:1:"d";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:336;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120082;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:210;}s:9:"codepoint";i:210;}}}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:332;}}}}s:1:"e";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:937;}}}}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:927;}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120134;}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"C";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8220;}}}}}}}}}}}}s:1:"Q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8216;}}}}}}}}}}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10836;}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119978;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:216;}s:9:"codepoint";i:216;}}}}}s:1:"t";a:1:{s:1:"i";a:2:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:213;}s:9:"codepoint";i:213;}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10807;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:214;}s:9:"codepoint";i:214;}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"B";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:175;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9182;}}s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9140;}}}}}}}}s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9180;}}}}}}}}}}}}}}}}s:1:"P";a:9:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8706;}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1055;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120083;}}}s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:934;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:928;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"M";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:177;}}}}}}}}}s:1:"o";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8460;}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8473;}}}}s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10939;}s:1:"e";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10927;}}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}}}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8243;}}}}s:1:"o";a:2:{s:1:"d";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8719;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8759;}s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119979;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:936;}}}}s:1:"Q";a:4:{s:1:"U";a:1:{s:1:"O";a:1:{s:1:"T";a:2:{s:1:";";a:1:{s:9:"codepoint";i:34;}s:9:"codepoint";i:34;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120084;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8474;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119980;}}}}}s:1:"R";a:12:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10512;}}}}}s:1:"E";a:1:{s:1:"G";a:2:{s:1:";";a:1:{s:9:"codepoint";i:174;}s:9:"codepoint";i:174;}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:340;}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10219;}}}s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8608;}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10518;}}}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:344;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:342;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1056;}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8476;}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:2:{s:1:"E";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8651;}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10607;}}}}}}}}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8476;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:929;}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:8:{s:1:"A";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10217;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8677;}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}}}}}}}}}}}}s:1:"C";a:1:{s:1:"e";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8969;}}}}}}}}s:1:"D";a:1:{s:1:"o";a:2:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"B";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10215;}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:2:{s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10589;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8642;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10581;}}}}}}}}}}}}}}s:1:"F";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8971;}}}}}}s:1:"T";a:2:{s:1:"e";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8866;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8614;}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10587;}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8883;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10704;}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:3:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10575;}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10588;}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8638;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10580;}}}}}}}}}}}}s:1:"V";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8640;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10579;}}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}}}}}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8477;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:"I";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10608;}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8667;}}}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8475;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8625;}}}s:1:"u";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"D";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10740;}}}}}}}}}}}}s:1:"S";a:13:{s:1:"H";a:2:{s:1:"C";a:1:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1065;}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1064;}}}}s:1:"O";a:1:{s:1:"F";a:1:{s:1:"T";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1068;}}}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:346;}}}}}}s:1:"c";a:5:{s:1:";";a:1:{s:9:"codepoint";i:10940;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:352;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:350;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:348;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1057;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120086;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:4:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}}}}}}}}s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8592;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8594;}}}}}}}}}}}s:1:"U";a:1:{s:1:"p";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}}}}}}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:931;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"C";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8728;}}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120138;}}}}s:1:"q";a:2:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8730;}}}s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9633;}s:1:"I";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8851;}}}}}}}}}}}}}s:1:"S";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}}}}}}}}}}}}}s:1:"U";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8852;}}}}}}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119982;}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8902;}}}}s:1:"u";a:4:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8912;}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8912;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8838;}}}}}}}}}}s:1:"c";a:2:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10928;}}}}}}s:1:"S";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}}}}}}}}s:1:"h";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8721;}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8913;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8839;}}}}}}}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8913;}}}}}}}s:1:"T";a:11:{s:1:"H";a:1:{s:1:"O";a:1:{s:1:"R";a:1:{s:1:"N";a:2:{s:1:";";a:1:{s:9:"codepoint";i:222;}s:9:"codepoint";i:222;}}}}s:1:"R";a:1:{s:1:"A";a:1:{s:1:"D";a:1:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8482;}}}}}s:1:"S";a:2:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1035;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1062;}}}}s:1:"a";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:932;}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:356;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:354;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1058;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120087;}}}s:1:"h";a:2:{s:1:"e";a:2:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:920;}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8201;}}}}}}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8764;}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8771;}}}}}}s:1:"F";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8773;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120139;}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8411;}}}}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119983;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:358;}}}}}}}s:1:"U";a:14:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:218;}s:9:"codepoint";i:218;}}}}s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8607;}s:1:"o";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10569;}}}}}}}}s:1:"b";a:1:{s:1:"r";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1038;}}}s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:364;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:219;}s:9:"codepoint";i:219;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1059;}}}s:1:"d";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:368;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120088;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:217;}s:9:"codepoint";i:217;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:362;}}}}}s:1:"n";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"B";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:818;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9183;}}s:1:"k";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9141;}}}}}}}}s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9181;}}}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8899;}s:1:"P";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8846;}}}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:370;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120140;}}}}s:1:"p";a:8:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8593;}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10514;}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8645;}}}}}}}}}}}}}}}s:1:"D";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8597;}}}}}}}}}}s:1:"E";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10606;}}}}}}}}}}}}s:1:"T";a:1:{s:1:"e";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8869;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8613;}}}}}}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"r";a:2:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8598;}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8599;}}}}}}}}}}}}}}s:1:"s";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:978;}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:933;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:366;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119984;}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:360;}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:220;}s:9:"codepoint";i:220;}}}}s:1:"V";a:9:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8875;}}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10987;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1042;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8873;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10982;}}}}}}s:1:"e";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}s:1:"r";a:3:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8214;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8214;}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}}}s:1:"L";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}}s:1:"S";a:1:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10072;}}}}}}}}}}s:1:"T";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8768;}}}}}}}}}}}s:1:"y";a:1:{s:1:"T";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8202;}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120089;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120141;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119985;}}}}s:1:"v";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8874;}}}}}}}s:1:"W";a:5:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:372;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120090;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120142;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119986;}}}}}s:1:"X";a:4:{s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120091;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:926;}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120143;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119987;}}}}}s:1:"Y";a:9:{s:1:"A";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1071;}}}}s:1:"I";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1031;}}}}s:1:"U";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1070;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:221;}s:9:"codepoint";i:221;}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:374;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1067;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120092;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120144;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119988;}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:376;}}}}}s:1:"Z";a:8:{s:1:"H";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1046;}}}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:377;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:381;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1047;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:379;}}}}s:1:"e";a:2:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"W";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"S";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8203;}}}}}}}}}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:918;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8488;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8484;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119989;}}}}}s:1:"a";a:16:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:225;}s:9:"codepoint";i:225;}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:259;}}}}}}s:1:"c";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8766;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8767;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:226;}s:9:"codepoint";i:226;}}}s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:180;}s:9:"codepoint";i:180;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1072;}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:230;}s:9:"codepoint";i:230;}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8289;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120094;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:224;}s:9:"codepoint";i:224;}}}}}s:1:"l";a:2:{s:1:"e";a:2:{s:1:"f";a:1:{s:1:"s";a:1:{s:1:"y";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8501;}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8501;}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:945;}}}}}s:1:"m";a:2:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:257;}}}s:1:"l";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10815;}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:38;}s:9:"codepoint";i:38;}}s:1:"n";a:2:{s:1:"d";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8743;}s:1:"a";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10837;}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10844;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10840;}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10842;}}}s:1:"g";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8736;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10660;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8736;}}}s:1:"m";a:1:{s:1:"s";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8737;}s:1:"a";a:8:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10664;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10665;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10666;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10667;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10668;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10669;}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10670;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10671;}}}}}}s:1:"r";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8735;}s:1:"v";a:1:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8894;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10653;}}}}}}s:1:"s";a:2:{s:1:"p";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8738;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8491;}}}s:1:"z";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9084;}}}}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:261;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120146;}}}}s:1:"p";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10864;}}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10863;}}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8778;}}s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8779;}}}s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:39;}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8778;}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:229;}s:9:"codepoint";i:229;}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119990;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:42;}}s:1:"y";a:1:{s:1:"m";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8776;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8781;}}}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:227;}s:9:"codepoint";i:227;}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:228;}s:9:"codepoint";i:228;}}}s:1:"w";a:2:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8755;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10769;}}}}}}s:1:"b";a:16:{s:1:"N";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10989;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:4:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8780;}}}}}s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1014;}}}}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8245;}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8765;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8909;}}}}}}}}s:1:"r";a:2:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8893;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8965;}s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8965;}}}}}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9141;}s:1:"t";a:1:{s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9142;}}}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8780;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1073;}}}s:1:"d";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8222;}}}}}s:1:"e";a:5:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"u";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8757;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8757;}}}}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10672;}}}}}}s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1014;}}}}s:1:"r";a:1:{s:1:"n";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8492;}}}}}s:1:"t";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:946;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8502;}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8812;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120095;}}}s:1:"i";a:1:{s:1:"g";a:7:{s:1:"c";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9711;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8899;}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10752;}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10753;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10754;}}}}}}}s:1:"s";a:2:{s:1:"q";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10758;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9733;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9661;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9651;}}}}}}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10756;}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}}}}s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10509;}}}}}}s:1:"l";a:3:{s:1:"a";a:2:{s:1:"c";a:1:{s:1:"k";a:3:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"z";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10731;}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9652;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9662;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9666;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9656;}}}}}}}}}}}}}}}}s:1:"n";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9251;}}}}s:1:"k";a:2:{i:1;a:2:{i:2;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9618;}}i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9617;}}}i:3;a:1:{i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:9619;}}}}s:1:"o";a:1:{s:1:"c";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9608;}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8976;}}}}s:1:"o";a:4:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120147;}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8869;}s:1:"t";a:1:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8869;}}}}}s:1:"w";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8904;}}}}}s:1:"x";a:12:{s:1:"D";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9559;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9556;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9558;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9555;}}}s:1:"H";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9552;}s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9574;}}s:1:"U";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9577;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9572;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9575;}}}s:1:"U";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9565;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9562;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9564;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9561;}}}s:1:"V";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9553;}s:1:"H";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9580;}}s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9571;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9568;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9579;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9570;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9567;}}}s:1:"b";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10697;}}}}s:1:"d";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9557;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9554;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9488;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9484;}}}s:1:"h";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9472;}s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9573;}}s:1:"U";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9576;}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9516;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9524;}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8863;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8862;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8864;}}}}}}s:1:"u";a:4:{s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9563;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9560;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9496;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9492;}}}s:1:"v";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9474;}s:1:"H";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9578;}}s:1:"L";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9569;}}s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9566;}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9532;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9508;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9500;}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8245;}}}}}}s:1:"r";a:2:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:728;}}}}s:1:"v";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:166;}s:9:"codepoint";i:166;}}}}}s:1:"s";a:4:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119991;}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8271;}}}}s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8765;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8909;}}}}s:1:"o";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:92;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10693;}}}}}s:1:"u";a:2:{s:1:"l";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8226;}s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8226;}}}}}s:1:"m";a:1:{s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8782;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10926;}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8783;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8783;}}}}}}}s:1:"c";a:15:{s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:263;}}}}}s:1:"p";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8745;}s:1:"a";a:1:{s:1:"n";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10820;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10825;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10827;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10823;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10816;}}}}}s:1:"r";a:2:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8257;}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:711;}}}}}s:1:"c";a:4:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10829;}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:269;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:231;}s:9:"codepoint";i:231;}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:265;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10828;}s:1:"s";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10832;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:267;}}}}s:1:"e";a:3:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:184;}s:9:"codepoint";i:184;}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10674;}}}}}}s:1:"n";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:162;}s:9:"codepoint";i:162;s:1:"e";a:1:{s:1:"r";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:183;}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120096;}}}s:1:"h";a:3:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1095;}}}s:1:"e";a:1:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10003;}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10003;}}}}}}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:967;}}}s:1:"i";a:1:{s:1:"r";a:7:{s:1:";";a:1:{s:9:"codepoint";i:9675;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10691;}}s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:710;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8791;}}}s:1:"l";a:1:{s:1:"e";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8634;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8635;}}}}}}}}}}}s:1:"d";a:5:{s:1:"R";a:1:{s:1:";";a:1:{s:9:"codepoint";i:174;}}s:1:"S";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9416;}}s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8859;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8858;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8861;}}}}}}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8791;}}s:1:"f";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10768;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10991;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10690;}}}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9827;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9827;}}}}}}}}s:1:"o";a:4:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:58;}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8788;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8788;}}}}}}s:1:"m";a:2:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:44;}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64;}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8705;}s:1:"f";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8728;}}}s:1:"l";a:1:{s:1:"e";a:2:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8705;}}}}}s:1:"x";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8450;}}}}}}}}s:1:"n";a:2:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8773;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10861;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}}s:1:"p";a:3:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120148;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8720;}}}}s:1:"y";a:3:{s:1:";";a:1:{s:9:"codepoint";i:169;}s:9:"codepoint";i:169;s:1:"s";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8471;}}}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8629;}}}}s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10007;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119992;}}}s:1:"u";a:2:{s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10959;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10961;}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10960;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10962;}}}}}s:1:"t";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8943;}}}}}s:1:"u";a:7:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10552;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10549;}}}}}}s:1:"e";a:2:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8926;}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8927;}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8630;}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10557;}}}}}}s:1:"p";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8746;}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10824;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10822;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10826;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8845;}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10821;}}}}s:1:"r";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8631;}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10556;}}}}}s:1:"l";a:1:{s:1:"y";a:3:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8926;}}}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8927;}}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8910;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8911;}}}}}}}}s:1:"r";a:1:{s:1:"e";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:164;}s:9:"codepoint";i:164;}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8630;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8631;}}}}}}}}}}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8910;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8911;}}}}}s:1:"w";a:2:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8754;}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8753;}}}}}s:1:"y";a:1:{s:1:"l";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9005;}}}}}}}s:1:"d";a:19:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8659;}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10597;}}}}s:1:"a";a:4:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8224;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8504;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8208;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8867;}}}}}s:1:"b";a:2:{s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10511;}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:733;}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:271;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1076;}}}s:1:"d";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8518;}s:1:"a";a:2:{s:1:"g";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8225;}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8650;}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10871;}}}}}}}s:1:"e";a:3:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:176;}s:9:"codepoint";i:176;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:948;}}}}s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10673;}}}}}}}s:1:"f";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10623;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120097;}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8643;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8642;}}}}}s:1:"i";a:5:{s:1:"a";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8900;}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8900;}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9830;}}}}}}}}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9830;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:168;}}s:1:"g";a:1:{s:1:"a";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:989;}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8946;}}}}s:1:"v";a:3:{s:1:";";a:1:{s:9:"codepoint";i:247;}s:1:"i";a:1:{s:1:"d";a:1:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:247;}s:9:"codepoint";i:247;s:1:"o";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8903;}}}}}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8903;}}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1106;}}}}s:1:"l";a:1:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8990;}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8973;}}}}}}s:1:"o";a:5:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:36;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120149;}}}s:1:"t";a:5:{s:1:";";a:1:{s:9:"codepoint";i:729;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8784;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8785;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8760;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8724;}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8865;}}}}}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8966;}}}}}}}}}}}}}s:1:"w";a:1:{s:1:"n";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8595;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8650;}}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8643;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8642;}}}}}}}}}}}}}}}}s:1:"r";a:2:{s:1:"b";a:1:{s:1:"k";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10512;}}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8991;}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8972;}}}}}}s:1:"s";a:3:{s:1:"c";a:2:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119993;}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1109;}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10742;}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:273;}}}}}}s:1:"t";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8945;}}}}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9663;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9662;}}}}}s:1:"u";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8693;}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10607;}}}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10662;}}}}}}}s:1:"z";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1119;}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10239;}}}}}}}}}s:1:"e";a:18:{s:1:"D";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10871;}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8785;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:233;}s:9:"codepoint";i:233;}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10862;}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:283;}}}}}s:1:"i";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8790;}s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:234;}s:9:"codepoint";i:234;}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8789;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1101;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:279;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}s:1:"f";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8786;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120098;}}}s:1:"g";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10906;}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:232;}s:9:"codepoint";i:232;}}}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10902;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10904;}}}}}}s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10905;}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9191;}}}}}}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8467;}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10901;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10903;}}}}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:275;}}}}s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8709;}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}}s:1:"s";a:1:{s:1:"p";a:2:{i:1;a:2:{i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8196;}}i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8197;}}}s:1:";";a:1:{s:9:"codepoint";i:8195;}}}}s:1:"n";a:2:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:331;}}s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8194;}}}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:281;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120150;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8917;}s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10723;}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10865;}}}}s:1:"s";a:1:{s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:1013;}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}}s:1:"q";a:4:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8790;}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8789;}}}}}}s:1:"s";a:2:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:2:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10902;}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10901;}}}}}}}}}}s:1:"u";a:3:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:61;}}}}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8799;}}}}s:1:"i";a:1:{s:1:"v";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8801;}s:1:"D";a:1:{s:1:"D";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10872;}}}}}}s:1:"v";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10725;}}}}}}}}s:1:"r";a:2:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8787;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10609;}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8495;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8784;}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8770;}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:951;}}s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:240;}s:9:"codepoint";i:240;}}s:1:"u";a:2:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:235;}s:9:"codepoint";i:235;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8364;}}}}s:1:"x";a:3:{s:1:"c";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:33;}}}s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8707;}}}}s:1:"p";a:2:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8496;}}}}}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8519;}}}}}}}}}}}}}s:1:"f";a:11:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8786;}}}}}}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1092;}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9792;}}}}}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64259;}}}}}s:1:"l";a:2:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64256;}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64260;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120099;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64257;}}}}}s:1:"l";a:3:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9837;}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:64258;}}}}s:1:"t";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9649;}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:402;}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120151;}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8704;}}}}s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8916;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10969;}}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10765;}}}}}}}}s:1:"r";a:2:{s:1:"a";a:2:{s:1:"c";a:6:{i:1;a:6:{i:2;a:2:{s:1:";";a:1:{s:9:"codepoint";i:189;}s:9:"codepoint";i:189;}i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8531;}}i:4;a:2:{s:1:";";a:1:{s:9:"codepoint";i:188;}s:9:"codepoint";i:188;}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8533;}}i:6;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8537;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8539;}}}i:2;a:2:{i:3;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8532;}}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8534;}}}i:3;a:3:{i:4;a:2:{s:1:";";a:1:{s:9:"codepoint";i:190;}s:9:"codepoint";i:190;}i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8535;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8540;}}}i:4;a:1:{i:5;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8536;}}}i:5;a:2:{i:6;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8538;}}i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8541;}}}i:7;a:1:{i:8;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8542;}}}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8260;}}}}s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8994;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119995;}}}}}s:1:"g";a:16:{s:1:"E";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8807;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10892;}}}s:1:"a";a:3:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:501;}}}}}s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:947;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:989;}}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10886;}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:287;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:285;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1075;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:289;}}}}s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}s:1:"q";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8805;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8807;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10878;}}}}}}}s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10878;}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10921;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10880;}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10882;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10884;}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10900;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120100;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8811;}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8921;}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8503;}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1107;}}}}s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8823;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10898;}}s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10917;}}s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10916;}}}s:1:"n";a:4:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8809;}}s:1:"a";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10890;}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10890;}}}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10888;}s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10888;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8809;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8935;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120152;}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:96;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8458;}}}s:1:"i";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8819;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10894;}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10896;}}}}}s:1:"t";a:7:{s:1:";";a:1:{s:9:"codepoint";i:62;}s:9:"codepoint";i:62;s:1:"c";a:2:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10919;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10874;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8919;}}}}s:1:"l";a:1:{s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10645;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10876;}}}}}}s:1:"r";a:5:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10886;}}}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10616;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8919;}}}}s:1:"e";a:1:{s:1:"q";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8923;}}}}}s:1:"q";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10892;}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8823;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8819;}}}}}}}s:1:"h";a:10:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}}}s:1:"a";a:4:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8202;}}}}}s:1:"l";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:189;}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8459;}}}}}s:1:"r";a:2:{s:1:"d";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1098;}}}}s:1:"r";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8596;}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10568;}}}}s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8621;}}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:293;}}}}}s:1:"e";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9829;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9829;}}}}}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8230;}}}}}s:1:"r";a:1:{s:1:"c";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8889;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120101;}}}s:1:"k";a:1:{s:1:"s";a:2:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10533;}}}}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10534;}}}}}}}}s:1:"o";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8703;}}}}s:1:"m";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8763;}}}}}s:1:"o";a:1:{s:1:"k";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8617;}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8618;}}}}}}}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120153;}}}s:1:"r";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8213;}}}}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119997;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:295;}}}}}}s:1:"y";a:2:{s:1:"b";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8259;}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8208;}}}}}}}s:1:"i";a:15:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:237;}s:9:"codepoint";i:237;}}}}}s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8291;}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:238;}s:9:"codepoint";i:238;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1080;}}}s:1:"e";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1077;}}}s:1:"x";a:1:{s:1:"c";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:161;}s:9:"codepoint";i:161;}}}}s:1:"f";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8660;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120102;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:236;}s:9:"codepoint";i:236;}}}}}s:1:"i";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8520;}s:1:"i";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10764;}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8749;}}}}s:1:"n";a:1:{s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10716;}}}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8489;}}}}}s:1:"j";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:307;}}}}}s:1:"m";a:3:{s:1:"a";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:299;}}}s:1:"g";a:3:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8464;}}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8465;}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:305;}}}}s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8887;}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:437;}}}}}s:1:"n";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8712;}s:1:"c";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8453;}}}}}s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8734;}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10717;}}}}}}}s:1:"o";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:305;}}}}}s:1:"t";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8747;}s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8890;}}}}s:1:"e";a:2:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8484;}}}}}s:1:"r";a:1:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8890;}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10775;}}}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10812;}}}}}}}s:1:"o";a:4:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1105;}}}s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:303;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120154;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:953;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10812;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:191;}s:9:"codepoint";i:191;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119998;}}}s:1:"i";a:1:{s:1:"n";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8712;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8953;}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8949;}}}}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8948;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8947;}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8712;}}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8290;}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:297;}}}}}}s:1:"u";a:2:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1110;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:239;}s:9:"codepoint";i:239;}}}}s:1:"j";a:6:{s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:309;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1081;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120103;}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:567;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120155;}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:119999;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1112;}}}}}}s:1:"u";a:1:{s:1:"k";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1108;}}}}}}s:1:"k";a:8:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:2:{s:1:";";a:1:{s:9:"codepoint";i:954;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1008;}}}}}}s:1:"c";a:2:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:311;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1082;}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120104;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:312;}}}}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1093;}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1116;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120156;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120000;}}}}}s:1:"l";a:22:{s:1:"A";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8666;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8656;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10523;}}}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10510;}}}}}s:1:"E";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8806;}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10891;}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10594;}}}}s:1:"a";a:9:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:314;}}}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10676;}}}}}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8466;}}}}}s:1:"m";a:1:{s:1:"b";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:955;}}}}}s:1:"n";a:1:{s:1:"g";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10216;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10641;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10216;}}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10885;}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:171;}s:9:"codepoint";i:171;}}}s:1:"r";a:1:{s:1:"r";a:8:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8676;}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10527;}}}}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10525;}}}s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8617;}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8619;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10553;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10611;}}}}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8610;}}}}}s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:10923;}s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10521;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10925;}}}}s:1:"b";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10508;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10098;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:123;}}s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:91;}}}}s:1:"k";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10635;}}s:1:"s";a:1:{s:1:"l";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10639;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10637;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:318;}}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:316;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8968;}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:123;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1083;}}}s:1:"d";a:4:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10550;}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8220;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8222;}}}}}s:1:"r";a:2:{s:1:"d";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10599;}}}}}s:1:"u";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10571;}}}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8626;}}}}s:1:"e";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8804;}s:1:"f";a:1:{s:1:"t";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8592;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8610;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8637;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8636;}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8647;}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8596;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8651;}}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8621;}}}}}}}}}}}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8907;}}}}}}}}}}}}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}s:1:"q";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8804;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8806;}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10877;}}}}}}}s:1:"s";a:5:{s:1:";";a:1:{s:9:"codepoint";i:10877;}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10920;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10879;}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10881;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10883;}}}}}}s:1:"g";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10899;}}}}s:1:"s";a:5:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10885;}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8918;}}}}s:1:"e";a:1:{s:1:"q";a:2:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8922;}}}}s:1:"q";a:1:{s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10891;}}}}}}}s:1:"g";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8822;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8818;}}}}}}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10620;}}}}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8970;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120105;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8822;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10897;}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8637;}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8636;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10602;}}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9604;}}}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1113;}}}}s:1:"l";a:5:{s:1:";";a:1:{s:9:"codepoint";i:8810;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8647;}}}}s:1:"c";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8990;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10603;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9722;}}}}}s:1:"m";a:2:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:320;}}}}}s:1:"o";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9136;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9136;}}}}}}}}}}s:1:"n";a:4:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8808;}}s:1:"a";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10889;}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10889;}}}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10887;}s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10887;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8808;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8934;}}}}}s:1:"o";a:8:{s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10220;}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8701;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10214;}}}}s:1:"n";a:1:{s:1:"g";a:3:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}}}}}}}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10236;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}}}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8619;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8620;}}}}}}}}}}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10629;}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120157;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10797;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10804;}}}}}}s:1:"w";a:2:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8727;}}}}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:95;}}}}}s:1:"z";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9674;}s:1:"e";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9674;}}}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10731;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:40;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10643;}}}}}}s:1:"r";a:5:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8646;}}}}s:1:"c";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8991;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8651;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10605;}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8206;}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8895;}}}}}s:1:"s";a:6:{s:1:"a";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8249;}}}}}s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120001;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8624;}}s:1:"i";a:1:{s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8818;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10893;}}s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10895;}}}}s:1:"q";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:91;}}s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8216;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8218;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:322;}}}}}}s:1:"t";a:9:{s:1:";";a:1:{s:9:"codepoint";i:60;}s:9:"codepoint";i:60;s:1:"c";a:2:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10918;}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10873;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8918;}}}}s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8907;}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8905;}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10614;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10875;}}}}}}s:1:"r";a:2:{s:1:"P";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10646;}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9667;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9666;}}}}}s:1:"u";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10570;}}}}}}s:1:"u";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10598;}}}}}}}}s:1:"m";a:14:{s:1:"D";a:1:{s:1:"D";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8762;}}}}}s:1:"a";a:4:{s:1:"c";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:175;}s:9:"codepoint";i:175;}}s:1:"l";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9794;}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10016;}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10016;}}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8614;}s:1:"s";a:1:{s:1:"t";a:1:{s:1:"o";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8614;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8615;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8612;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8613;}}}}}}}s:1:"r";a:1:{s:1:"k";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9646;}}}}}}s:1:"c";a:2:{s:1:"o";a:1:{s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10793;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1084;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8212;}}}}}s:1:"e";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8737;}}}}}}}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120106;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8487;}}}s:1:"i";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:181;}s:9:"codepoint";i:181;}}}s:1:"d";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8739;}s:1:"a";a:1:{s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:42;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10992;}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:183;}s:9:"codepoint";i:183;}}}}s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8722;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8863;}}s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8760;}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10794;}}}}}}}s:1:"l";a:2:{s:1:"c";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10971;}}}s:1:"d";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8230;}}}}s:1:"n";a:1:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}}}}}s:1:"o";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8871;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120158;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8723;}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120002;}}}s:1:"t";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8766;}}}}}}s:1:"u";a:3:{s:1:";";a:1:{s:9:"codepoint";i:956;}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8888;}}}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8888;}}}}}}s:1:"n";a:23:{s:1:"L";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8653;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8654;}}}}}}}}}}}}}}}s:1:"R";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8655;}}}}}}}}}}}s:1:"V";a:2:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8879;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8878;}}}}}}s:1:"a";a:4:{s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8711;}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:324;}}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8777;}s:1:"o";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:329;}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8777;}}}}}}s:1:"t";a:1:{s:1:"u";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9838;}s:1:"a";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9838;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8469;}}}}}}}}s:1:"b";a:1:{s:1:"s";a:1:{s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:160;}s:9:"codepoint";i:160;}}}s:1:"c";a:5:{s:1:"a";a:2:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10819;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:328;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:326;}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8775;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10818;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1085;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8211;}}}}}s:1:"e";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8800;}s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8663;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10532;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8599;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8599;}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8802;}}}}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10536;}}}}}s:1:"x";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8708;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8708;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120107;}}}s:1:"g";a:3:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8817;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8817;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8821;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8815;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8815;}}}}s:1:"h";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8654;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8622;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10994;}}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8715;}s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8956;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8954;}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8715;}}}s:1:"j";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1114;}}}}s:1:"l";a:6:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8653;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8602;}}}}s:1:"d";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8229;}}}s:1:"e";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8816;}s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8602;}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8622;}}}}}}}}}}}}}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8816;}}s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8814;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8820;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8814;}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"o";a:2:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120159;}}}s:1:"t";a:4:{s:1:";";a:1:{s:9:"codepoint";i:172;}s:9:"codepoint";i:172;s:1:"i";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8713;}s:1:"v";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8713;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8951;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8950;}}}}}s:1:"n";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8716;}s:1:"v";a:3:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8716;}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8958;}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8957;}}}}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8742;}s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10772;}}}}}}s:1:"r";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8832;}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8928;}}}}s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8832;}}}}}s:1:"r";a:4:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8655;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8603;}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8603;}}}}}}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}s:1:"s";a:7:{s:1:"c";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8833;}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8929;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120003;}}}s:1:"h";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:2:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}}}}}}}}}}s:1:"i";a:1:{s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8769;}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8772;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8772;}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8740;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8742;}}}}s:1:"q";a:1:{s:1:"s";a:1:{s:1:"u";a:2:{s:1:"b";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8930;}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8931;}}}}}}s:1:"u";a:3:{s:1:"b";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8836;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8840;}}}}}}}s:1:"c";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8833;}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8837;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8841;}}}}}}}}}s:1:"t";a:4:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8825;}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:241;}s:9:"codepoint";i:241;}}}}s:1:"l";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8824;}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8938;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8940;}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8939;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8941;}}}}}}}}}}}}}}}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:957;}s:1:"m";a:3:{s:1:";";a:1:{s:9:"codepoint";i:35;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8470;}}}}s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8199;}}}}}s:1:"v";a:6:{s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8877;}}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10500;}}}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8876;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"f";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10718;}}}}}}s:1:"l";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10498;}}}}}s:1:"r";a:1:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10499;}}}}}}s:1:"w";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8662;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10531;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8598;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8598;}}}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10535;}}}}}}}s:1:"o";a:18:{s:1:"S";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9416;}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:243;}s:9:"codepoint";i:243;}}}}s:1:"s";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8859;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8858;}s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:244;}s:9:"codepoint";i:244;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1086;}}}s:1:"d";a:5:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8861;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:337;}}}}}s:1:"i";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10808;}}}s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8857;}}}s:1:"s";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10684;}}}}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:339;}}}}}s:1:"f";a:2:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10687;}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120108;}}}s:1:"g";a:3:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:731;}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:242;}s:9:"codepoint";i:242;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10689;}}}s:1:"h";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10677;}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8486;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8750;}}}}s:1:"l";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8634;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10686;}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"s";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10683;}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8254;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10688;}}}s:1:"m";a:3:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:333;}}}}s:1:"e";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:969;}}}}s:1:"i";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:959;}}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10678;}}s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8854;}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120160;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10679;}}}s:1:"e";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10681;}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8853;}}}}}s:1:"r";a:7:{s:1:";";a:1:{s:9:"codepoint";i:8744;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8635;}}}}s:1:"d";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10845;}s:1:"e";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8500;}s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8500;}}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:170;}s:9:"codepoint";i:170;}s:1:"m";a:2:{s:1:";";a:1:{s:9:"codepoint";i:186;}s:9:"codepoint";i:186;}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8886;}}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10838;}}}s:1:"s";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10839;}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10843;}}}s:1:"s";a:3:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8500;}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:2:{s:1:";";a:1:{s:9:"codepoint";i:248;}s:9:"codepoint";i:248;}}}}s:1:"o";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8856;}}}}s:1:"t";a:1:{s:1:"i";a:2:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:245;}s:9:"codepoint";i:245;}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8855;}s:1:"a";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10806;}}}}}}}}s:1:"u";a:1:{s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:246;}s:9:"codepoint";i:246;}}}s:1:"v";a:1:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9021;}}}}}}s:1:"p";a:12:{s:1:"a";a:1:{s:1:"r";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8741;}s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:182;}s:9:"codepoint";i:182;s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}s:1:"s";a:2:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10995;}}}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:11005;}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8706;}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1087;}}}s:1:"e";a:1:{s:1:"r";a:5:{s:1:"c";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:37;}}}}s:1:"i";a:1:{s:1:"o";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:46;}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8240;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8869;}}s:1:"t";a:1:{s:1:"e";a:1:{s:1:"n";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8241;}}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120109;}}}s:1:"h";a:3:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:966;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:966;}}}s:1:"m";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8499;}}}}}s:1:"o";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9742;}}}}}s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:960;}s:1:"t";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8916;}}}}}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:982;}}}s:1:"l";a:2:{s:1:"a";a:1:{s:1:"n";a:2:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8463;}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8462;}}}}s:1:"k";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8463;}}}}}s:1:"u";a:1:{s:1:"s";a:9:{s:1:";";a:1:{s:9:"codepoint";i:43;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10787;}}}}}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8862;}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10786;}}}}s:1:"d";a:2:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8724;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10789;}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10866;}}s:1:"m";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:177;}s:9:"codepoint";i:177;}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10790;}}}}s:1:"t";a:1:{s:1:"w";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10791;}}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:177;}}s:1:"o";a:3:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10773;}}}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120161;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"d";a:2:{s:1:";";a:1:{s:9:"codepoint";i:163;}s:9:"codepoint";i:163;}}}}s:1:"r";a:10:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10931;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10935;}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10927;}s:1:"c";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8826;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10935;}}}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8828;}}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10927;}}}s:1:"n";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10937;}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10933;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8936;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8242;}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8473;}}}}}s:1:"n";a:3:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10933;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10937;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8936;}}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8719;}}s:1:"f";a:3:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9006;}}}}}s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8978;}}}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8979;}}}}}}s:1:"p";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8733;}s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8830;}}}}s:1:"u";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8880;}}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120005;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:968;}}}s:1:"u";a:1:{s:1:"n";a:1:{s:1:"c";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8200;}}}}}}}s:1:"q";a:6:{s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120110;}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10764;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120162;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8279;}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120006;}}}}s:1:"u";a:3:{s:1:"a";a:1:{s:1:"t";a:2:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"n";a:1:{s:1:"i";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8461;}}}}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10774;}}}}}}s:1:"e";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:63;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8799;}}}}}}s:1:"o";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:34;}s:9:"codepoint";i:34;}}}}s:1:"r";a:21:{s:1:"A";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8667;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8658;}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10524;}}}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10511;}}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10596;}}}}s:1:"a";a:7:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10714;}}s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:341;}}}}}s:1:"d";a:1:{s:1:"i";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8730;}}}}s:1:"e";a:1:{s:1:"m";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"y";a:1:{s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10675;}}}}}}}s:1:"n";a:1:{s:1:"g";a:4:{s:1:";";a:1:{s:9:"codepoint";i:10217;}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10642;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10661;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10217;}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:187;}s:9:"codepoint";i:187;}}}s:1:"r";a:1:{s:1:"r";a:11:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10613;}}}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8677;}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10528;}}}}s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10547;}}s:1:"f";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10526;}}}s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8618;}}}s:1:"l";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8620;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10565;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10612;}}}}s:1:"t";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8611;}}}s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8605;}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10522;}}}}s:1:"i";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8758;}s:1:"n";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8474;}}}}}}}}}s:1:"b";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10509;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10099;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:125;}}s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:93;}}}}s:1:"k";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10636;}}s:1:"s";a:1:{s:1:"l";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10638;}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10640;}}}}}}}s:1:"c";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:345;}}}}}s:1:"e";a:2:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:343;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8969;}}}}s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:125;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1088;}}}s:1:"d";a:4:{s:1:"c";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10551;}}}s:1:"l";a:1:{s:1:"d";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10601;}}}}}}s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8221;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8221;}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8627;}}}}s:1:"e";a:3:{s:1:"a";a:1:{s:1:"l";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8476;}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8475;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8476;}}}}}s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8477;}}}}s:1:"c";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9645;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:174;}s:9:"codepoint";i:174;}}s:1:"f";a:3:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10621;}}}}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8971;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120111;}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8641;}}s:1:"u";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8640;}s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10604;}}}}}s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:961;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1009;}}}}s:1:"i";a:3:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:6:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8594;}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8611;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8641;}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8640;}}}}}}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8649;}}}}}}}}}}}}s:1:"s";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8605;}}}}}}}}}}}s:1:"t";a:1:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8908;}}}}}}}}}}}}}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:730;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8787;}}}}}}}}}}}}s:1:"l";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8644;}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8652;}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8207;}}}s:1:"m";a:1:{s:1:"o";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9137;}s:1:"a";a:1:{s:1:"c";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9137;}}}}}}}}}}s:1:"n";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10990;}}}}}s:1:"o";a:4:{s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10221;}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8702;}}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10215;}}}}s:1:"p";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10630;}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120163;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10798;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10805;}}}}}}}s:1:"p";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:41;}s:1:"g";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10644;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10770;}}}}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8649;}}}}}s:1:"s";a:4:{s:1:"a";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8250;}}}}}s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120007;}}}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8625;}}s:1:"q";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:93;}}s:1:"u";a:1:{s:1:"o";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8217;}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8217;}}}}}}s:1:"t";a:3:{s:1:"h";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8908;}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8906;}}}}}s:1:"r";a:1:{s:1:"i";a:4:{s:1:";";a:1:{s:9:"codepoint";i:9657;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9656;}}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10702;}}}}}}}}s:1:"u";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10600;}}}}}}}s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8478;}}}s:1:"s";a:19:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:347;}}}}}}s:1:"b";a:1:{s:1:"q";a:1:{s:1:"u";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8218;}}}}}s:1:"c";a:10:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10932;}}s:1:"a";a:2:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10936;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:353;}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10928;}s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:351;}}}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:349;}}}}s:1:"n";a:3:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10934;}}s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10938;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8937;}}}}}s:1:"p";a:1:{s:1:"o";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10771;}}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1089;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8901;}s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8865;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10854;}}}}}s:1:"e";a:7:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8664;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10533;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8600;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8600;}}}}}}s:1:"c";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:167;}s:9:"codepoint";i:167;}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:59;}}}s:1:"s";a:1:{s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10537;}}}}}s:1:"t";a:1:{s:1:"m";a:2:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}s:1:"x";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10038;}}}}s:1:"f";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:120112;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8994;}}}}}}s:1:"h";a:4:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9839;}}}}s:1:"c";a:2:{s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1097;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1096;}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"t";a:2:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}}}s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}}}}}}}}}s:1:"y";a:2:{s:1:";";a:1:{s:9:"codepoint";i:173;}s:9:"codepoint";i:173;}}s:1:"i";a:2:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:963;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}}}}s:1:"m";a:8:{s:1:";";a:1:{s:9:"codepoint";i:8764;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10858;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8771;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8771;}}}s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10910;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10912;}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10909;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10911;}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8774;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10788;}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10610;}}}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8592;}}}}}s:1:"m";a:4:{s:1:"a";a:2:{s:1:"l";a:1:{s:1:"l";a:1:{s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}}}}}}}s:1:"s";a:1:{s:1:"h";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10803;}}}}}s:1:"e";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"s";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10724;}}}}}}}s:1:"i";a:2:{s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8739;}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8995;}}}}s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10922;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10924;}}}}s:1:"o";a:3:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1100;}}}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:47;}s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10692;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9023;}}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120164;}}}}s:1:"p";a:1:{s:1:"a";a:2:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:"s";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9824;}s:1:"u";a:1:{s:1:"i";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9824;}}}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8741;}}}}s:1:"q";a:3:{s:1:"c";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8851;}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8852;}}}}s:1:"s";a:1:{s:1:"u";a:2:{s:1:"b";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8847;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8849;}}}}}}}s:1:"p";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}s:1:"s";a:1:{s:1:"e";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8848;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8850;}}}}}}}}}s:1:"u";a:3:{s:1:";";a:1:{s:9:"codepoint";i:9633;}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9633;}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9642;}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8594;}}}}}s:1:"s";a:4:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120008;}}}s:1:"e";a:1:{s:1:"t";a:1:{s:1:"m";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8726;}}}}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8995;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8902;}}}}}}s:1:"t";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9734;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9733;}}}}s:1:"r";a:2:{s:1:"a";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1013;}}}}}}}}s:1:"p";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:981;}}}}}}}}}s:1:"n";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:175;}}}}}s:1:"u";a:5:{s:1:"b";a:9:{s:1:";";a:1:{s:9:"codepoint";i:8834;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10949;}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10941;}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8838;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10947;}}}}}s:1:"m";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10945;}}}}}s:1:"n";a:2:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10955;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8842;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10943;}}}}}s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10617;}}}}}s:1:"s";a:3:{s:1:"e";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8834;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8838;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10949;}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8842;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10955;}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10951;}}}s:1:"u";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10965;}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10963;}}}}}s:1:"c";a:1:{s:1:"c";a:6:{s:1:";";a:1:{s:9:"codepoint";i:8827;}s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10936;}}}}}}}s:1:"c";a:1:{s:1:"u";a:1:{s:1:"r";a:1:{s:1:"l";a:1:{s:1:"y";a:1:{s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8829;}}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10928;}}}s:1:"n";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10938;}}}}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10934;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8937;}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8831;}}}}}}s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8721;}}s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9834;}}}s:1:"p";a:13:{i:1;a:2:{s:1:";";a:1:{s:9:"codepoint";i:185;}s:9:"codepoint";i:185;}i:2;a:2:{s:1:";";a:1:{s:9:"codepoint";i:178;}s:9:"codepoint";i:178;}i:3;a:2:{s:1:";";a:1:{s:9:"codepoint";i:179;}s:9:"codepoint";i:179;}s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10950;}}s:1:"d";a:2:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10942;}}}s:1:"s";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10968;}}}}}s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8839;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10948;}}}}}s:1:"h";a:1:{s:1:"s";a:1:{s:1:"u";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10967;}}}}}s:1:"l";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10619;}}}}}s:1:"m";a:1:{s:1:"u";a:1:{s:1:"l";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10946;}}}}}s:1:"n";a:2:{s:1:"E";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10956;}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8843;}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10944;}}}}}s:1:"s";a:3:{s:1:"e";a:1:{s:1:"t";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8835;}s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8839;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10950;}}}}s:1:"n";a:1:{s:1:"e";a:1:{s:1:"q";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8843;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10956;}}}}}}}s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10952;}}}s:1:"u";a:2:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10964;}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10966;}}}}}}s:1:"w";a:3:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8665;}}}}s:1:"a";a:1:{s:1:"r";a:2:{s:1:"h";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10534;}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8601;}s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8601;}}}}}}s:1:"n";a:1:{s:1:"w";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10538;}}}}}}s:1:"z";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"g";a:2:{s:1:";";a:1:{s:9:"codepoint";i:223;}s:9:"codepoint";i:223;}}}}}s:1:"t";a:13:{s:1:"a";a:2:{s:1:"r";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8982;}}}}}s:1:"u";a:1:{s:1:";";a:1:{s:9:"codepoint";i:964;}}}s:1:"b";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9140;}}}}s:1:"c";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:357;}}}}}s:1:"e";a:1:{s:1:"d";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:355;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1090;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8411;}}}}s:1:"e";a:1:{s:1:"l";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8981;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120113;}}}s:1:"h";a:4:{s:1:"e";a:2:{s:1:"r";a:1:{s:1:"e";a:2:{i:4;a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}s:1:"f";a:1:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8756;}}}}}}}s:1:"t";a:1:{s:1:"a";a:3:{s:1:";";a:1:{s:9:"codepoint";i:952;}s:1:"s";a:1:{s:1:"y";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}}s:1:"i";a:2:{s:1:"c";a:1:{s:1:"k";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"x";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8764;}}}}}}s:1:"n";a:1:{s:1:"s";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8201;}}}}}s:1:"k";a:2:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8776;}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8764;}}}}}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:254;}s:9:"codepoint";i:254;}}}}s:1:"i";a:3:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:732;}}}}s:1:"m";a:1:{s:1:"e";a:1:{s:1:"s";a:4:{s:1:";";a:1:{s:9:"codepoint";i:215;}s:9:"codepoint";i:215;s:1:"b";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8864;}s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10801;}}}}s:1:"d";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10800;}}}}}s:1:"n";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8749;}}}}s:1:"o";a:3:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10536;}}}s:1:"p";a:4:{s:1:";";a:1:{s:9:"codepoint";i:8868;}s:1:"b";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9014;}}}}s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10993;}}}}s:1:"f";a:2:{s:1:";";a:1:{s:9:"codepoint";i:120165;}s:1:"o";a:1:{s:1:"r";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10970;}}}}}}s:1:"s";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10537;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8244;}}}}}}s:1:"r";a:3:{s:1:"a";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8482;}}}}s:1:"i";a:7:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:5:{s:1:";";a:1:{s:9:"codepoint";i:9653;}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9663;}}}}}s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9667;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8884;}}}}}}}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8796;}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9657;}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8885;}}}}}}}}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9708;}}}}s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8796;}}s:1:"m";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10810;}}}}}}s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10809;}}}}}s:1:"s";a:1:{s:1:"b";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10701;}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10811;}}}}}}s:1:"p";a:1:{s:1:"e";a:1:{s:1:"z";a:1:{s:1:"i";a:1:{s:1:"u";a:1:{s:1:"m";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9186;}}}}}}}}s:1:"s";a:3:{s:1:"c";a:2:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120009;}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1094;}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1115;}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:359;}}}}}}s:1:"w";a:2:{s:1:"i";a:1:{s:1:"x";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8812;}}}}s:1:"o";a:1:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"a";a:1:{s:1:"d";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8606;}}}}}}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8608;}}}}}}}}}}}}}}}}}}s:1:"u";a:18:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8657;}}}}s:1:"H";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10595;}}}}s:1:"a";a:2:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:250;}s:9:"codepoint";i:250;}}}}s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}s:1:"b";a:1:{s:1:"r";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1118;}}}s:1:"e";a:1:{s:1:"v";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:365;}}}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:2:{s:1:";";a:1:{s:9:"codepoint";i:251;}s:9:"codepoint";i:251;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1091;}}}s:1:"d";a:3:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8645;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:369;}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10606;}}}}}s:1:"f";a:2:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10622;}}}}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120114;}}}s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"v";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:249;}s:9:"codepoint";i:249;}}}}}s:1:"h";a:2:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:"l";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8639;}}s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8638;}}}}s:1:"b";a:1:{s:1:"l";a:1:{s:1:"k";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9600;}}}}}s:1:"l";a:2:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8988;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8988;}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8975;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9720;}}}}}s:1:"m";a:2:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:363;}}}}s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:168;}s:9:"codepoint";i:168;}}s:1:"o";a:2:{s:1:"g";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:371;}}}}s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120166;}}}}s:1:"p";a:6:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8593;}}}}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"n";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8597;}}}}}}}}}}s:1:"h";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:"o";a:1:{s:1:"o";a:1:{s:1:"n";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8639;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8638;}}}}}}}}}}}}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8846;}}}}s:1:"s";a:1:{s:1:"i";a:3:{s:1:";";a:1:{s:9:"codepoint";i:965;}s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:978;}}s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:965;}}}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"w";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8648;}}}}}}}}}}s:1:"r";a:3:{s:1:"c";a:2:{s:1:"o";a:1:{s:1:"r";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8989;}s:1:"e";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8989;}}}}}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8974;}}}}}s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:367;}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9721;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120010;}}}}s:1:"t";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8944;}}}}s:1:"i";a:1:{s:1:"l";a:1:{s:1:"d";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:361;}}}}}s:1:"r";a:1:{s:1:"i";a:2:{s:1:";";a:1:{s:9:"codepoint";i:9653;}s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9652;}}}}}s:1:"u";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8648;}}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:252;}s:9:"codepoint";i:252;}}}s:1:"w";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10663;}}}}}}}}s:1:"v";a:14:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8661;}}}}s:1:"B";a:1:{s:1:"a";a:1:{s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:10984;}s:1:"v";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10985;}}}}}s:1:"D";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8872;}}}}}s:1:"a";a:2:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10652;}}}}}s:1:"r";a:7:{s:1:"e";a:1:{s:1:"p";a:1:{s:1:"s";a:1:{s:1:"i";a:1:{s:1:"l";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:949;}}}}}}}}s:1:"k";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:"p";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1008;}}}}}}s:1:"n";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8709;}}}}}}}}s:1:"p";a:3:{s:1:"h";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:966;}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:982;}}s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:"t";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8597;}s:1:"h";a:1:{s:1:"o";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1009;}}}}s:1:"s";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"m";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:962;}}}}}}s:1:"t";a:2:{s:1:"h";a:1:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:977;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"a";a:1:{s:1:"n";a:1:{s:1:"g";a:1:{s:1:"l";a:1:{s:1:"e";a:2:{s:1:"l";a:1:{s:1:"e";a:1:{s:1:"f";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8882;}}}}}s:1:"r";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"h";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8883;}}}}}}}}}}}}}}}}s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1074;}}}s:1:"d";a:1:{s:1:"a";a:1:{s:1:"s";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8866;}}}}}s:1:"e";a:3:{s:1:"e";a:3:{s:1:";";a:1:{s:9:"codepoint";i:8744;}s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8891;}}}}s:1:"e";a:1:{s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8794;}}}}s:1:"l";a:1:{s:1:"l";a:1:{s:1:"i";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8942;}}}}}s:1:"r";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:124;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120115;}}}s:1:"l";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8882;}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120167;}}}}s:1:"p";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8733;}}}}}s:1:"r";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8883;}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120011;}}}}s:1:"z";a:1:{s:1:"i";a:1:{s:1:"g";a:1:{s:1:"z";a:1:{s:1:"a";a:1:{s:1:"g";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10650;}}}}}}}}s:1:"w";a:7:{s:1:"c";a:1:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:373;}}}}}s:1:"e";a:2:{s:1:"d";a:2:{s:1:"b";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10847;}}}}s:1:"g";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8743;}s:1:"q";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8793;}}}}}s:1:"i";a:1:{s:1:"e";a:1:{s:1:"r";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8472;}}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120116;}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120168;}}}}s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8472;}}s:1:"r";a:2:{s:1:";";a:1:{s:9:"codepoint";i:8768;}s:1:"e";a:1:{s:1:"a";a:1:{s:1:"t";a:1:{s:1:"h";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8768;}}}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120012;}}}}}s:1:"x";a:14:{s:1:"c";a:3:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8898;}}}s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9711;}}}}s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8899;}}}}s:1:"d";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9661;}}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120117;}}}s:1:"h";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10234;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10231;}}}}}s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:958;}}s:1:"l";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10232;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10229;}}}}}s:1:"m";a:1:{s:1:"a";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10236;}}}}s:1:"n";a:1:{s:1:"i";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8955;}}}}s:1:"o";a:3:{s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10752;}}}}s:1:"p";a:2:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120169;}}s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10753;}}}}}s:1:"t";a:1:{s:1:"i";a:1:{s:1:"m";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10754;}}}}}}s:1:"r";a:2:{s:1:"A";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10233;}}}}s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10230;}}}}}s:1:"s";a:2:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120013;}}}s:1:"q";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"p";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10758;}}}}}}s:1:"u";a:2:{s:1:"p";a:1:{s:1:"l";a:1:{s:1:"u";a:1:{s:1:"s";a:1:{s:1:";";a:1:{s:9:"codepoint";i:10756;}}}}}s:1:"t";a:1:{s:1:"r";a:1:{s:1:"i";a:1:{s:1:";";a:1:{s:9:"codepoint";i:9651;}}}}}s:1:"v";a:1:{s:1:"e";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8897;}}}}s:1:"w";a:1:{s:1:"e";a:1:{s:1:"d";a:1:{s:1:"g";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8896;}}}}}}}s:1:"y";a:8:{s:1:"a";a:1:{s:1:"c";a:2:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:2:{s:1:";";a:1:{s:9:"codepoint";i:253;}s:9:"codepoint";i:253;}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1103;}}}}s:1:"c";a:2:{s:1:"i";a:1:{s:1:"r";a:1:{s:1:"c";a:1:{s:1:";";a:1:{s:9:"codepoint";i:375;}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1099;}}}s:1:"e";a:1:{s:1:"n";a:2:{s:1:";";a:1:{s:9:"codepoint";i:165;}s:9:"codepoint";i:165;}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120118;}}}s:1:"i";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1111;}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120170;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120014;}}}}s:1:"u";a:2:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1102;}}}s:1:"m";a:1:{s:1:"l";a:2:{s:1:";";a:1:{s:9:"codepoint";i:255;}s:9:"codepoint";i:255;}}}}s:1:"z";a:10:{s:1:"a";a:1:{s:1:"c";a:1:{s:1:"u";a:1:{s:1:"t";a:1:{s:1:"e";a:1:{s:1:";";a:1:{s:9:"codepoint";i:378;}}}}}}s:1:"c";a:2:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"o";a:1:{s:1:"n";a:1:{s:1:";";a:1:{s:9:"codepoint";i:382;}}}}}s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1079;}}}s:1:"d";a:1:{s:1:"o";a:1:{s:1:"t";a:1:{s:1:";";a:1:{s:9:"codepoint";i:380;}}}}s:1:"e";a:2:{s:1:"e";a:1:{s:1:"t";a:1:{s:1:"r";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8488;}}}}}s:1:"t";a:1:{s:1:"a";a:1:{s:1:";";a:1:{s:9:"codepoint";i:950;}}}}s:1:"f";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120119;}}}s:1:"h";a:1:{s:1:"c";a:1:{s:1:"y";a:1:{s:1:";";a:1:{s:9:"codepoint";i:1078;}}}}s:1:"i";a:1:{s:1:"g";a:1:{s:1:"r";a:1:{s:1:"a";a:1:{s:1:"r";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8669;}}}}}}}s:1:"o";a:1:{s:1:"p";a:1:{s:1:"f";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120171;}}}}s:1:"s";a:1:{s:1:"c";a:1:{s:1:"r";a:1:{s:1:";";a:1:{s:9:"codepoint";i:120015;}}}}s:1:"w";a:2:{s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8205;}}s:1:"n";a:1:{s:1:"j";a:1:{s:1:";";a:1:{s:9:"codepoint";i:8204;}}}}}}
\ No newline at end of file
diff --git a/vendor/dompdf/dompdf/lib/res/broken_image.png b/vendor/dompdf/dompdf/lib/res/broken_image.png
new file mode 100644
index 0000000000000000000000000000000000000000..771a1a378e407aae9dd395994dddb76ce8ab5738
GIT binary patch
literal 618
zcmV-w0+s!VP)@4daft*x!*=H~hN`30Qbr~m)}32;bR
za{vGf5&!@T5&_cPe*6Fc0338hSaefwW^{L9a%BKPWN%_+AVz6&Wp{6KYjYq&Q#1y$
z)1UwV02XvbSad^jWnpw_Z*Cw|X>DZyFf=bQGA}VP6XzqJ0004*Nkl)=yb*v7}-u|xv-e-LuUk!kh4lJ_);5w=To%I0CpbKmOtcnX9zybJO2JD9$0Joxx
z&AkJf#}aUzBVgT>1p-iV;jDWAZkYtS-~*7S(|-~G_z@B&i5!p;!FB|ML=YeVvWi60
z31ERFngBEx={y3EbP~rDz*v#XTm+&7_D}|b3wnVV-~(Zmh($07*qoM6N<$
Ef+<`F!~g&Q

literal 0
HcmV?d00001

diff --git a/vendor/dompdf/dompdf/lib/res/broken_image.svg b/vendor/dompdf/dompdf/lib/res/broken_image.svg
new file mode 100644
index 0000000..83ba7e7
--- /dev/null
+++ b/vendor/dompdf/dompdf/lib/res/broken_image.svg
@@ -0,0 +1,8 @@
+
+
+ 
+  
+  
+  
+ 
+
\ No newline at end of file
diff --git a/vendor/dompdf/dompdf/lib/res/html.css b/vendor/dompdf/dompdf/lib/res/html.css
new file mode 100644
index 0000000..2243ec3
--- /dev/null
+++ b/vendor/dompdf/dompdf/lib/res/html.css
@@ -0,0 +1,527 @@
+/**
+ * dompdf default stylesheet.
+ *
+ * @package dompdf
+ * @link    http://dompdf.github.com/
+ * @author  Benj Carson 
+ * @author  Blake Ross 
+ * @author  Fabien Ménager 
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ *
+ * Portions from Mozilla
+ * @link https://dxr.mozilla.org/mozilla-central/source/layout/style/res/html.css
+ * @license http://mozilla.org/MPL/2.0/ Mozilla Public License, v. 2.0 
+ *
+ * Portions from W3C
+ * @link https://drafts.csswg.org/css-ui-3/#default-style-sheet
+ *
+ */
+
+@page {
+  margin: 1.2cm;
+}
+
+html {
+  display: -dompdf-page !important;
+  counter-reset: page;
+}
+
+/* blocks */
+
+article,
+aside,
+details,
+div,
+dt,
+figcaption,
+footer,
+form,
+header,
+hgroup,
+main,
+nav,
+noscript,
+section,
+summary {
+  display: block;
+}
+
+body {
+  page-break-before: avoid;
+  display: block !important;
+  counter-increment: page;
+}
+
+p, dl, multicol {
+  display: block;
+  margin: 1em 0;
+}
+
+dd {
+  display: block;
+  margin-left: 40px;
+}
+
+blockquote, figure {
+  display: block;
+  margin: 1em 40px;
+}
+
+address {
+  display: block;
+  font-style: italic;
+}
+
+center {
+  display: block;
+  text-align: center;
+}
+
+blockquote[type=cite] {
+  display: block;
+  margin: 1em 0;
+  padding-left: 1em;
+  border-left: solid;
+  border-color: blue;
+  border-width: thin;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  display: block;
+  font-weight: bold;
+}
+
+h1 {
+  font-size: 2em;
+  margin: .67em 0;
+}
+
+h2 {
+  font-size: 1.5em;
+  margin: .83em 0;
+}
+
+h3 {
+  font-size: 1.17em;
+  margin: 1em 0;
+}
+
+h4 {
+  margin: 1.33em 0;
+}
+
+h5 {
+  font-size: 0.83em;
+  margin: 1.67em 0;
+}
+
+h6 {
+  font-size: 0.67em;
+  margin: 2.33em 0;
+}
+
+listing {
+  display: block;
+  font-family: fixed;
+  font-size: medium;
+  white-space: pre;
+  margin: 1em 0;
+}
+
+plaintext, pre, xmp {
+  display: block;
+  font-family: fixed;
+  white-space: pre;
+  margin: 1em 0;
+}
+
+/* tables */
+
+table {
+  display: table;
+  border-spacing: 2px;
+  border-collapse: separate;
+  margin-top: 0;
+  margin-bottom: 0;
+  text-indent: 0;
+  text-align: left; /* quirk */
+}
+
+table[border] {
+  border-style: outset;
+  border-color: gray;
+}
+
+/* This won't work (???) */
+/*
+table[border] td,
+table[border] th {
+  border: 1pt solid grey;
+}*/
+
+/* make sure backgrounds are inherited in tables  -- see bug 4510 */
+td, th, tr {
+  background-color: inherit;
+  background-image: inherit;
+  background-image-resolution: inherit;
+  background-position: inherit;
+  background-repeat: inherit;
+  background-size: inherit;
+}
+
+/* caption inherits from table not table-outer */
+caption {
+  display: table-caption;
+  text-align: center;
+}
+
+tr {
+  display: table-row;
+  vertical-align: inherit;
+}
+
+col {
+  display: table-column;
+}
+
+colgroup {
+  display: table-column-group;
+}
+
+tbody {
+  display: table-row-group;
+  vertical-align: middle;
+}
+
+thead {
+  display: table-header-group;
+  vertical-align: middle;
+}
+
+tfoot {
+  display: table-footer-group;
+  vertical-align: middle;
+}
+
+/* To simulate tbody auto-insertion */
+table > tr {
+  vertical-align: middle;
+}
+
+td {
+  display: table-cell;
+  vertical-align: inherit;
+  text-align: inherit;
+  padding: 1px;
+}
+
+th {
+  display: table-cell;
+  vertical-align: inherit;
+  text-align: center;
+  font-weight: bold;
+  padding: 1px;
+}
+
+/* inlines */
+q {
+  quotes: '"' '"' "'" "'"; /* FIXME only the first level is used */
+}
+
+q:before {
+  content: open-quote;
+}
+
+q:after {
+  content: close-quote;
+}
+
+:link {
+  color: #00c;
+  text-decoration: underline;
+}
+
+b, strong {
+  font-weight: bolder;
+}
+
+i, cite, em, var, dfn {
+  font-style: italic;
+}
+
+tt, code, kbd, samp {
+  font-family: fixed;
+}
+
+u, ins {
+  text-decoration: underline;
+}
+
+s, strike, del {
+  text-decoration: line-through;
+}
+
+big {
+  font-size: larger;
+}
+
+small {
+  font-size: smaller;
+}
+
+sub {
+  vertical-align: sub;
+  font-size: smaller;
+  line-height: normal;
+}
+
+sup {
+  vertical-align: super;
+  font-size: smaller;
+  line-height: normal;
+}
+
+nobr {
+  white-space: nowrap;
+}
+
+mark {
+  background: yellow;
+  color: black;
+}
+
+/* titles */
+
+abbr[title], acronym[title] {
+  text-decoration: dotted underline;
+}
+
+/* lists */
+
+ul, menu, dir {
+  display: block;
+  list-style-type: disc;
+  margin: 1em 0;
+  padding-left: 40px;
+}
+
+ol {
+  display: block;
+  list-style-type: decimal;
+  margin: 1em 0;
+  padding-left: 40px;
+}
+
+li {
+  display: list-item;
+}
+
+/*li:before {
+  display: -dompdf-list-bullet !important;
+  content: counter(-dompdf-default-counter) ". ";
+  padding-right: 0.5em;
+}*/
+
+/* nested lists have no top/bottom margins */
+:matches(ul, ol, dir, menu, dl) ul,
+:matches(ul, ol, dir, menu, dl) ol,
+:matches(ul, ol, dir, menu, dl) dir,
+:matches(ul, ol, dir, menu, dl) menu,
+:matches(ul, ol, dir, menu, dl) dl {
+  margin-top: 0;
+  margin-bottom: 0;
+}
+
+/* 2 deep unordered lists use a circle */
+:matches(ul, ol, dir, menu) ul,
+:matches(ul, ol, dir, menu) ul,
+:matches(ul, ol, dir, menu) ul,
+:matches(ul, ol, dir, menu) ul {
+  list-style-type: circle;
+}
+
+/* 3 deep (or more) unordered lists use a square */
+:matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) ul,
+:matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) menu,
+:matches(ul, ol, dir, menu) :matches(ul, ol, dir, menu) dir {
+  list-style-type: square;
+}
+
+/* forms */
+/* From https://drafts.csswg.org/css-ui-3/#default-style-sheet */
+form {
+  display: block;
+}
+
+input, button, select {
+  display: inline-block;
+  font-family: sans-serif;
+}
+
+input[type=text],
+input[type=password],
+select {
+  width: 12em;
+}
+
+input[type=text],
+input[type=password],
+input[type=button],
+input[type=submit],
+input[type=reset],
+input[type=file],
+button,
+textarea,
+select {
+  background: #FFF;
+  border: 1px solid #999;
+  padding: 2px;
+  margin: 2px;
+}
+
+input[type=button],
+input[type=submit],
+input[type=reset],
+input[type=file],
+button {
+  background: #CCC;
+  text-align: center;
+}
+
+input[type=file] {
+  width: 8em;
+}
+
+input[type=text]:before,
+input[type=button]:before,
+input[type=submit]:before,
+input[type=reset]:before {
+  content: attr(value);
+}
+
+input[type=file]:before {
+  content: "Choose a file";
+}
+
+input[type=password][value]:before {
+  font-family: "DejaVu Sans" !important;
+  content: "\2022\2022\2022\2022\2022\2022\2022\2022";
+  line-height: 1em;
+}
+
+input[type=checkbox],
+input[type=radio],
+select:after {
+  font-family: "DejaVu Sans" !important;
+  font-size: 18px;
+  line-height: 1;
+}
+
+input[type=checkbox]:before {
+  content: "\2610";
+}
+
+input[type=checkbox][checked]:before {
+  content: "\2611";
+}
+
+input[type=radio]:before {
+  content: "\25CB";
+}
+
+input[type=radio][checked]:before {
+  content: "\25C9";
+}
+
+textarea {
+  display: block;
+  height: 3em;
+  overflow: hidden;
+  font-family: monospace;
+  white-space: pre-wrap;
+  word-wrap: break-word;
+}
+
+select {
+  position: relative!important;
+  overflow: hidden!important;
+}
+
+select:after {
+  position: absolute;
+  right: 0;
+  top: 0;
+  height: 5em;
+  width: 1.4em;
+  text-align: center;
+  background: #CCC;
+  content: "\25BE";
+}
+
+select option {
+  display: none;
+}
+
+select option[selected] {
+  display: inline;
+}
+
+fieldset {
+  display: block;
+  margin: 0.6em 2px 2px;
+  padding: 0.75em;
+  border: 1pt groove #666;
+  position: relative;
+}
+
+fieldset > legend {
+  position: absolute;
+  top: -0.6em;
+  left: 0.75em;
+  padding: 0 0.3em;
+  background: white;
+}
+
+legend {
+  display: inline-block;
+}
+
+/* leafs */
+
+hr {
+  display: block;
+  height: 0;
+  border: 1px inset;
+  margin: 0.5em auto 0.5em auto;
+}
+
+hr[size="1"] {
+  border-style: solid none none none;
+}
+
+iframe {
+  border: 2px inset;
+}
+
+noframes {
+  display: block;
+}
+
+br {
+  display: -dompdf-br;
+}
+
+img, img_generated {
+  display: -dompdf-image !important;
+}
+
+dompdf_generated {
+  display: inline;
+}
+
+/* hidden elements */
+area, base, basefont, head, meta, script, style, title,
+noembed, param {
+  display: none;
+  -dompdf-keep: yes;
+}
diff --git a/vendor/dompdf/dompdf/phpcs.xml b/vendor/dompdf/dompdf/phpcs.xml
new file mode 100644
index 0000000..fbda3fd
--- /dev/null
+++ b/vendor/dompdf/dompdf/phpcs.xml
@@ -0,0 +1,142 @@
+
+
+
+ Coding standard ruleset based on the PSR-2 coding standard.
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+ 
+  0
+ 
+
diff --git a/vendor/dompdf/dompdf/src/Adapter/CPDF.php b/vendor/dompdf/dompdf/src/Adapter/CPDF.php
new file mode 100644
index 0000000..9d8f156
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/Adapter/CPDF.php
@@ -0,0 +1,1225 @@
+
+ * @author  Orion Richardson 
+ * @author  Helmut Tischer 
+ * @author  Fabien Ménager 
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+
+// FIXME: Need to sanity check inputs to this class
+namespace Dompdf\Adapter;
+
+use Dompdf\Canvas;
+use Dompdf\Dompdf;
+use Dompdf\Helpers;
+use Dompdf\Exception;
+use Dompdf\Image\Cache;
+use Dompdf\PhpEvaluator;
+use FontLib\Exception\FontNotFoundException;
+
+/**
+ * PDF rendering interface
+ *
+ * Dompdf\Adapter\CPDF provides a simple stateless interface to the stateful one
+ * provided by the Cpdf class.
+ *
+ * Unless otherwise mentioned, all dimensions are in points (1/72 in).  The
+ * coordinate origin is in the top left corner, and y values increase
+ * downwards.
+ *
+ * See {@link http://www.ros.co.nz/pdf/} for more complete documentation
+ * on the underlying {@link Cpdf} class.
+ *
+ * @package dompdf
+ */
+class CPDF implements Canvas
+{
+
+    /**
+     * Dimensions of paper sizes in points
+     *
+     * @var array;
+     */
+    static $PAPER_SIZES = [
+        "4a0" => [0, 0, 4767.87, 6740.79],
+        "2a0" => [0, 0, 3370.39, 4767.87],
+        "a0" => [0, 0, 2383.94, 3370.39],
+        "a1" => [0, 0, 1683.78, 2383.94],
+        "a2" => [0, 0, 1190.55, 1683.78],
+        "a3" => [0, 0, 841.89, 1190.55],
+        "a4" => [0, 0, 595.28, 841.89],
+        "a5" => [0, 0, 419.53, 595.28],
+        "a6" => [0, 0, 297.64, 419.53],
+        "a7" => [0, 0, 209.76, 297.64],
+        "a8" => [0, 0, 147.40, 209.76],
+        "a9" => [0, 0, 104.88, 147.40],
+        "a10" => [0, 0, 73.70, 104.88],
+        "b0" => [0, 0, 2834.65, 4008.19],
+        "b1" => [0, 0, 2004.09, 2834.65],
+        "b2" => [0, 0, 1417.32, 2004.09],
+        "b3" => [0, 0, 1000.63, 1417.32],
+        "b4" => [0, 0, 708.66, 1000.63],
+        "b5" => [0, 0, 498.90, 708.66],
+        "b6" => [0, 0, 354.33, 498.90],
+        "b7" => [0, 0, 249.45, 354.33],
+        "b8" => [0, 0, 175.75, 249.45],
+        "b9" => [0, 0, 124.72, 175.75],
+        "b10" => [0, 0, 87.87, 124.72],
+        "c0" => [0, 0, 2599.37, 3676.54],
+        "c1" => [0, 0, 1836.85, 2599.37],
+        "c2" => [0, 0, 1298.27, 1836.85],
+        "c3" => [0, 0, 918.43, 1298.27],
+        "c4" => [0, 0, 649.13, 918.43],
+        "c5" => [0, 0, 459.21, 649.13],
+        "c6" => [0, 0, 323.15, 459.21],
+        "c7" => [0, 0, 229.61, 323.15],
+        "c8" => [0, 0, 161.57, 229.61],
+        "c9" => [0, 0, 113.39, 161.57],
+        "c10" => [0, 0, 79.37, 113.39],
+        "ra0" => [0, 0, 2437.80, 3458.27],
+        "ra1" => [0, 0, 1729.13, 2437.80],
+        "ra2" => [0, 0, 1218.90, 1729.13],
+        "ra3" => [0, 0, 864.57, 1218.90],
+        "ra4" => [0, 0, 609.45, 864.57],
+        "sra0" => [0, 0, 2551.18, 3628.35],
+        "sra1" => [0, 0, 1814.17, 2551.18],
+        "sra2" => [0, 0, 1275.59, 1814.17],
+        "sra3" => [0, 0, 907.09, 1275.59],
+        "sra4" => [0, 0, 637.80, 907.09],
+        "letter" => [0, 0, 612.00, 792.00],
+        "half-letter" => [0, 0, 396.00, 612.00],
+        "legal" => [0, 0, 612.00, 1008.00],
+        "ledger" => [0, 0, 1224.00, 792.00],
+        "tabloid" => [0, 0, 792.00, 1224.00],
+        "executive" => [0, 0, 521.86, 756.00],
+        "folio" => [0, 0, 612.00, 936.00],
+        "commercial #10 envelope" => [0, 0, 684, 297],
+        "catalog #10 1/2 envelope" => [0, 0, 648, 864],
+        "8.5x11" => [0, 0, 612.00, 792.00],
+        "8.5x14" => [0, 0, 612.00, 1008.0],
+        "11x17" => [0, 0, 792.00, 1224.00],
+    ];
+
+    /**
+     * The Dompdf object
+     *
+     * @var Dompdf
+     */
+    protected $_dompdf;
+
+    /**
+     * Instance of Cpdf class
+     *
+     * @var Cpdf
+     */
+    protected $_pdf;
+
+    /**
+     * PDF width, in points
+     *
+     * @var float
+     */
+    protected $_width;
+
+    /**
+     * PDF height, in points
+     *
+     * @var float;
+     */
+    protected $_height;
+
+    /**
+     * Current page number
+     *
+     * @var int
+     */
+    protected $_page_number;
+
+    /**
+     * Total number of pages
+     *
+     * @var int
+     */
+    protected $_page_count;
+
+    /**
+     * Text to display on every page
+     *
+     * @var array
+     */
+    protected $_page_text;
+
+    /**
+     * Array of pages for accessing after rendering is initially complete
+     *
+     * @var array
+     */
+    protected $_pages;
+
+    /**
+     * Array of temporary cached images to be deleted when processing is complete
+     *
+     * @var array
+     */
+    protected $_image_cache;
+
+    /**
+     * Currently-applied opacity level (0 - 1)
+     *
+     * @var float
+     */
+    protected $_current_opacity = 1;
+
+    /**
+     * Class constructor
+     *
+     * @param mixed $paper The size of paper to use in this PDF ({@link CPDF::$PAPER_SIZES})
+     * @param string $orientation The orientation of the document (either 'landscape' or 'portrait')
+     * @param Dompdf $dompdf The Dompdf instance
+     */
+    public function __construct($paper = "letter", $orientation = "portrait", Dompdf $dompdf)
+    {
+        if (is_array($paper)) {
+            $size = $paper;
+        } else if (isset(self::$PAPER_SIZES[mb_strtolower($paper)])) {
+            $size = self::$PAPER_SIZES[mb_strtolower($paper)];
+        } else {
+            $size = self::$PAPER_SIZES["letter"];
+        }
+
+        if (mb_strtolower($orientation) === "landscape") {
+            [$size[2], $size[3]] = [$size[3], $size[2]];
+        }
+
+        $this->_dompdf = $dompdf;
+
+        $this->_pdf = new \Dompdf\Cpdf(
+            $size,
+            true,
+            $dompdf->getOptions()->getFontCache(),
+            $dompdf->getOptions()->getTempDir()
+        );
+
+        $this->_pdf->addInfo("Producer", sprintf("%s + CPDF", $dompdf->version));
+        $time = substr_replace(date('YmdHisO'), '\'', -2, 0) . '\'';
+        $this->_pdf->addInfo("CreationDate", "D:$time");
+        $this->_pdf->addInfo("ModDate", "D:$time");
+
+        $this->_width = $size[2] - $size[0];
+        $this->_height = $size[3] - $size[1];
+
+        $this->_page_number = $this->_page_count = 1;
+        $this->_page_text = [];
+
+        $this->_pages = [$this->_pdf->getFirstPageId()];
+
+        $this->_image_cache = [];
+    }
+
+    /**
+     * @return Dompdf
+     */
+    public function get_dompdf()
+    {
+        return $this->_dompdf;
+    }
+
+    /**
+     * Class destructor
+     *
+     * Deletes all temporary image files
+     */
+    public function __destruct()
+    {
+        foreach ($this->_image_cache as $img) {
+            // The file might be already deleted by 3rd party tmp cleaner,
+            // the file might not have been created at all
+            // (if image outputting commands failed)
+            // or because the destructor was called twice accidentally.
+            if (!file_exists($img)) {
+                continue;
+            }
+
+            if ($this->_dompdf->getOptions()->getDebugPng()) {
+                print '[__destruct unlink ' . $img . ']';
+            }
+            if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) {
+                unlink($img);
+            }
+        }
+    }
+
+    /**
+     * Returns the Cpdf instance
+     *
+     * @return \Dompdf\Cpdf
+     */
+    public function get_cpdf()
+    {
+        return $this->_pdf;
+    }
+
+    /**
+     * Add meta information to the PDF
+     *
+     * @param string $label label of the value (Creator, Producer, etc.)
+     * @param string $value the text to set
+     */
+    public function add_info($label, $value)
+    {
+        $this->_pdf->addInfo($label, $value);
+    }
+
+    /**
+     * Opens a new 'object'
+     *
+     * While an object is open, all drawing actions are recorded in the object,
+     * as opposed to being drawn on the current page.  Objects can be added
+     * later to a specific page or to several pages.
+     *
+     * The return value is an integer ID for the new object.
+     *
+     * @see CPDF::close_object()
+     * @see CPDF::add_object()
+     *
+     * @return int
+     */
+    public function open_object()
+    {
+        $ret = $this->_pdf->openObject();
+        $this->_pdf->saveState();
+        return $ret;
+    }
+
+    /**
+     * Reopens an existing 'object'
+     *
+     * @see CPDF::open_object()
+     * @param int $object the ID of a previously opened object
+     */
+    public function reopen_object($object)
+    {
+        $this->_pdf->reopenObject($object);
+        $this->_pdf->saveState();
+    }
+
+    /**
+     * Closes the current 'object'
+     *
+     * @see CPDF::open_object()
+     */
+    public function close_object()
+    {
+        $this->_pdf->restoreState();
+        $this->_pdf->closeObject();
+    }
+
+    /**
+     * Adds a specified 'object' to the document
+     *
+     * $object int specifying an object created with {@link
+     * CPDF::open_object()}.  $where can be one of:
+     * - 'add' add to current page only
+     * - 'all' add to every page from the current one onwards
+     * - 'odd' add to all odd numbered pages from now on
+     * - 'even' add to all even numbered pages from now on
+     * - 'next' add the object to the next page only
+     * - 'nextodd' add to all odd numbered pages from the next one
+     * - 'nexteven' add to all even numbered pages from the next one
+     *
+     * @see Cpdf::addObject()
+     *
+     * @param int $object
+     * @param string $where
+     */
+    public function add_object($object, $where = 'all')
+    {
+        $this->_pdf->addObject($object, $where);
+    }
+
+    /**
+     * Stops the specified 'object' from appearing in the document.
+     *
+     * The object will stop being displayed on the page following the current
+     * one.
+     *
+     * @param int $object
+     */
+    public function stop_object($object)
+    {
+        $this->_pdf->stopObject($object);
+    }
+
+    /**
+     * @access private
+     */
+    public function serialize_object($id)
+    {
+        // Serialize the pdf object's current state for retrieval later
+        return $this->_pdf->serializeObject($id);
+    }
+
+    /**
+     * @access private
+     */
+    public function reopen_serialized_object($obj)
+    {
+        return $this->_pdf->restoreSerializedObject($obj);
+    }
+
+    //........................................................................
+
+    /**
+     * Returns the PDF's width in points
+     * @return float
+     */
+    public function get_width()
+    {
+        return $this->_width;
+    }
+
+    /**
+     * Returns the PDF's height in points
+     * @return float
+     */
+    public function get_height()
+    {
+        return $this->_height;
+    }
+
+    /**
+     * Returns the current page number
+     * @return int
+     */
+    public function get_page_number()
+    {
+        return $this->_page_number;
+    }
+
+    /**
+     * Returns the total number of pages in the document
+     * @return int
+     */
+    public function get_page_count()
+    {
+        return $this->_page_count;
+    }
+
+    /**
+     * Sets the current page number
+     *
+     * @param int $num
+     */
+    public function set_page_number($num)
+    {
+        $this->_page_number = $num;
+    }
+
+    /**
+     * Sets the page count
+     *
+     * @param int $count
+     */
+    public function set_page_count($count)
+    {
+        $this->_page_count = $count;
+    }
+
+    /**
+     * Sets the stroke color
+     *
+     * See {@link Style::set_color()} for the format of the color array.
+     * @param array $color
+     */
+    protected function _set_stroke_color($color)
+    {
+        $this->_pdf->setStrokeColor($color);
+        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
+        if ($this->_current_opacity != 1) {
+            $alpha *= $this->_current_opacity;
+        }
+        $this->_set_line_transparency("Normal", $alpha);
+    }
+
+    /**
+     * Sets the fill colour
+     *
+     * See {@link Style::set_color()} for the format of the colour array.
+     * @param array $color
+     */
+    protected function _set_fill_color($color)
+    {
+        $this->_pdf->setColor($color);
+        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
+        if ($this->_current_opacity) {
+            $alpha *= $this->_current_opacity;
+        }
+        $this->_set_fill_transparency("Normal", $alpha);
+    }
+
+    /**
+     * Sets line transparency
+     * @see Cpdf::setLineTransparency()
+     *
+     * Valid blend modes are (case-sensitive):
+     *
+     * Normal, Multiply, Screen, Overlay, Darken, Lighten,
+     * ColorDodge, ColorBurn, HardLight, SoftLight, Difference,
+     * Exclusion
+     *
+     * @param string $mode the blending mode to use
+     * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
+     */
+    protected function _set_line_transparency($mode, $opacity)
+    {
+        $this->_pdf->setLineTransparency($mode, $opacity);
+    }
+
+    /**
+     * Sets fill transparency
+     * @see Cpdf::setFillTransparency()
+     *
+     * Valid blend modes are (case-sensitive):
+     *
+     * Normal, Multiply, Screen, Overlay, Darken, Lighten,
+     * ColorDogde, ColorBurn, HardLight, SoftLight, Difference,
+     * Exclusion
+     *
+     * @param string $mode the blending mode to use
+     * @param float $opacity 0.0 fully transparent, 1.0 fully opaque
+     */
+    protected function _set_fill_transparency($mode, $opacity)
+    {
+        $this->_pdf->setFillTransparency($mode, $opacity);
+    }
+
+    /**
+     * Sets the line style
+     *
+     * @see Cpdf::setLineStyle()
+     *
+     * @param float $width
+     * @param string $cap
+     * @param string $join
+     * @param array $dash
+     */
+    protected function _set_line_style($width, $cap, $join, $dash)
+    {
+        $this->_pdf->setLineStyle($width, $cap, $join, $dash);
+    }
+
+    /**
+     * Sets the opacity
+     *
+     * @param $opacity
+     * @param $mode
+     */
+    public function set_opacity($opacity, $mode = "Normal")
+    {
+        $this->_set_line_transparency($mode, $opacity);
+        $this->_set_fill_transparency($mode, $opacity);
+        $this->_current_opacity = $opacity;
+    }
+
+    public function set_default_view($view, $options = [])
+    {
+        array_unshift($options, $view);
+        call_user_func_array([$this->_pdf, "openHere"], $options);
+    }
+
+    /**
+     * Remaps y coords from 4th to 1st quadrant
+     *
+     * @param float $y
+     * @return float
+     */
+    protected function y($y)
+    {
+        return $this->_height - $y;
+    }
+
+    /**
+     * Canvas implementation
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function line($x1, $y1, $x2, $y2, $color, $width, $style = [])
+    {
+        $this->_set_stroke_color($color);
+        $this->_set_line_style($width, "butt", "", $style);
+
+        $this->_pdf->line($x1, $this->y($y1),
+            $x2, $this->y($y2));
+        $this->_set_line_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * Draw line at the specified coordinates on every page.
+     *
+     * See {@link Style::munge_color()} for the format of the colour array.
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style optional
+     */
+    public function page_line($x1, $y1, $x2, $y2, $color, $width, $style = [])
+    {
+        $_t = 'line';
+        $this->_page_text[] = compact('_t', 'x1', 'y1', 'x2', 'y2', 'color', 'width', 'style');
+    }
+
+    /**
+     * @param float $x
+     * @param float $y
+     * @param float $r1
+     * @param float $r2
+     * @param float $astart
+     * @param float $aend
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = [])
+    {
+        $this->_set_stroke_color($color);
+        $this->_set_line_style($width, "butt", "", $style);
+
+        $this->_pdf->ellipse($x, $this->y($y), $r1, $r2, 0, 8, $astart, $aend, false, false, true, false);
+        $this->_set_line_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * Convert a GIF or BMP image to a PNG image
+     *
+     * @param string $image_url
+     * @param integer $type
+     *
+     * @throws Exception
+     * @return string The url of the newly converted image
+     */
+    protected function _convert_gif_bmp_to_png($image_url, $type)
+    {
+        $func_name = "imagecreatefrom$type";
+
+        if (!function_exists($func_name)) {
+            if (!method_exists(Helpers::class, $func_name)) {
+                throw new Exception("Function $func_name() not found.  Cannot convert $type image: $image_url.  Please install the image PHP extension.");
+            }
+            $func_name = "\\Dompdf\\Helpers::" . $func_name;
+        }
+
+        set_error_handler([Helpers::class, 'record_warnings']);
+
+        try {
+            $im = call_user_func($func_name, $image_url);
+
+            if ($im) {
+                imageinterlace($im, false);
+
+                $tmp_dir = $this->_dompdf->getOptions()->getTempDir();
+                $tmp_name = @tempnam($tmp_dir, "{$type}dompdf_img_");
+                @unlink($tmp_name);
+                $filename = "$tmp_name.png";
+                $this->_image_cache[] = $filename;
+
+                imagepng($im, $filename);
+                imagedestroy($im);
+            } else {
+                $filename = Cache::$broken_image;
+            }
+        } finally {
+            restore_error_handler();
+        }
+
+        return $filename;
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function rectangle($x1, $y1, $w, $h, $color, $width, $style = [])
+    {
+        $this->_set_stroke_color($color);
+        $this->_set_line_style($width, "butt", "", $style);
+        $this->_pdf->rectangle($x1, $this->y($y1) - $h, $w, $h);
+        $this->_set_line_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     */
+    public function filled_rectangle($x1, $y1, $w, $h, $color)
+    {
+        $this->_set_fill_color($color);
+        $this->_pdf->filledRectangle($x1, $this->y($y1) - $h, $w, $h);
+        $this->_set_fill_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     */
+    public function clipping_rectangle($x1, $y1, $w, $h)
+    {
+        $this->_pdf->clippingRectangle($x1, $this->y($y1) - $h, $w, $h);
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param float $rTL
+     * @param float $rTR
+     * @param float $rBR
+     * @param float $rBL
+     */
+    public function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL)
+    {
+        $this->_pdf->clippingRectangleRounded($x1, $this->y($y1) - $h, $w, $h, $rTL, $rTR, $rBR, $rBL);
+    }
+
+    /**
+     *
+     */
+    public function clipping_end()
+    {
+        $this->_pdf->clippingEnd();
+    }
+
+    /**
+     *
+     */
+    public function save()
+    {
+        $this->_pdf->saveState();
+    }
+
+    /**
+     *
+     */
+    public function restore()
+    {
+        $this->_pdf->restoreState();
+    }
+
+    /**
+     * @param $angle
+     * @param $x
+     * @param $y
+     */
+    public function rotate($angle, $x, $y)
+    {
+        $this->_pdf->rotate($angle, $x, $y);
+    }
+
+    /**
+     * @param $angle_x
+     * @param $angle_y
+     * @param $x
+     * @param $y
+     */
+    public function skew($angle_x, $angle_y, $x, $y)
+    {
+        $this->_pdf->skew($angle_x, $angle_y, $x, $y);
+    }
+
+    /**
+     * @param $s_x
+     * @param $s_y
+     * @param $x
+     * @param $y
+     */
+    public function scale($s_x, $s_y, $x, $y)
+    {
+        $this->_pdf->scale($s_x, $s_y, $x, $y);
+    }
+
+    /**
+     * @param $t_x
+     * @param $t_y
+     */
+    public function translate($t_x, $t_y)
+    {
+        $this->_pdf->translate($t_x, $t_y);
+    }
+
+    /**
+     * @param $a
+     * @param $b
+     * @param $c
+     * @param $d
+     * @param $e
+     * @param $f
+     */
+    public function transform($a, $b, $c, $d, $e, $f)
+    {
+        $this->_pdf->transform([$a, $b, $c, $d, $e, $f]);
+    }
+
+    /**
+     * @param array $points
+     * @param array $color
+     * @param null $width
+     * @param array $style
+     * @param bool $fill
+     */
+    public function polygon($points, $color, $width = null, $style = [], $fill = false)
+    {
+        $this->_set_fill_color($color);
+        $this->_set_stroke_color($color);
+
+        // Adjust y values
+        for ($i = 1; $i < count($points); $i += 2) {
+            $points[$i] = $this->y($points[$i]);
+        }
+
+        $this->_pdf->polygon($points, count($points) / 2, $fill);
+
+        $this->_set_fill_transparency("Normal", $this->_current_opacity);
+        $this->_set_line_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * @param float $x
+     * @param float $y
+     * @param float $r1
+     * @param array $color
+     * @param null $width
+     * @param null $style
+     * @param bool $fill
+     */
+    public function circle($x, $y, $r1, $color, $width = null, $style = null, $fill = false)
+    {
+        $this->_set_fill_color($color);
+        $this->_set_stroke_color($color);
+
+        if (!$fill && isset($width)) {
+            $this->_set_line_style($width, "round", "round", $style);
+        }
+
+        $this->_pdf->ellipse($x, $this->y($y), $r1, 0, 0, 8, 0, 360, 1, $fill);
+
+        $this->_set_fill_transparency("Normal", $this->_current_opacity);
+        $this->_set_line_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * @param string $img
+     * @param float $x
+     * @param float $y
+     * @param int $w
+     * @param int $h
+     * @param string $resolution
+     */
+    public function image($img, $x, $y, $w, $h, $resolution = "normal")
+    {
+        [$width, $height, $type] = Helpers::dompdf_getimagesize($img, $this->get_dompdf()->getHttpContext());
+
+        $debug_png = $this->_dompdf->getOptions()->getDebugPng();
+
+        if ($debug_png) {
+            print "[image:$img|$width|$height|$type]";
+        }
+
+        switch ($type) {
+            case "jpeg":
+                if ($debug_png) {
+                    print '!!!jpg!!!';
+                }
+                $this->_pdf->addJpegFromFile($img, $x, $this->y($y) - $h, $w, $h);
+                break;
+
+            case "gif":
+            /** @noinspection PhpMissingBreakStatementInspection */
+            case "bmp":
+                if ($debug_png) print '!!!bmp or gif!!!';
+                // @todo use cache for BMP and GIF
+                $img = $this->_convert_gif_bmp_to_png($img, $type);
+
+            case "png":
+                if ($debug_png) print '!!!png!!!';
+
+                $this->_pdf->addPngFromFile($img, $x, $this->y($y) - $h, $w, $h);
+                break;
+
+            case "svg":
+                if ($debug_png) print '!!!SVG!!!';
+
+                $this->_pdf->addSvgFromFile($img, $x, $this->y($y) - $h, $w, $h);
+                break;
+
+            default:
+                if ($debug_png) print '!!!unknown!!!';
+        }
+    }
+
+    public function select($x, $y, $w, $h, $font, $size, $color = [0, 0, 0], $opts = [])
+    {
+        $pdf = $this->_pdf;
+
+        $font .= ".afm";
+        $pdf->selectFont($font);
+
+        if (!isset($pdf->acroFormId)) {
+            $pdf->addForm();
+        }
+
+        $ft = \Dompdf\Cpdf::ACROFORM_FIELD_CHOICE;
+        $ff = \Dompdf\Cpdf::ACROFORM_FIELD_CHOICE_COMBO;
+
+        $id = $pdf->addFormField($ft, rand(), $x, $this->y($y) - $h, $x + $w, $this->y($y), $ff, $size, $color);
+        $pdf->setFormFieldOpt($id, $opts);
+    }
+
+    public function textarea($x, $y, $w, $h, $font, $size, $color = [0, 0, 0])
+    {
+        $pdf = $this->_pdf;
+
+        $font .= ".afm";
+        $pdf->selectFont($font);
+
+        if (!isset($pdf->acroFormId)) {
+            $pdf->addForm();
+        }
+
+        $ft = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT;
+        $ff = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT_MULTILINE;
+
+        $pdf->addFormField($ft, rand(), $x, $this->y($y) - $h, $x + $w, $this->y($y), $ff, $size, $color);
+    }
+
+    public function input($x, $y, $w, $h, $type, $font, $size, $color = [0, 0, 0])
+    {
+        $pdf = $this->_pdf;
+
+        $font .= ".afm";
+        $pdf->selectFont($font);
+
+        if (!isset($pdf->acroFormId)) {
+            $pdf->addForm();
+        }
+
+        $ft = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT;
+        $ff = 0;
+
+        switch($type) {
+            case 'text':
+                $ft = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT;
+                break;
+            case 'password':
+                $ft = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT;
+                $ff = \Dompdf\Cpdf::ACROFORM_FIELD_TEXT_PASSWORD;
+                break;
+            case 'submit':
+                $ft = \Dompdf\Cpdf::ACROFORM_FIELD_BUTTON;
+                break;
+        }
+
+        $pdf->addFormField($ft, rand(), $x, $this->y($y) - $h, $x + $w, $this->y($y), $ff, $size, $color);
+    }
+
+    /**
+     * @param float $x
+     * @param float $y
+     * @param string $text
+     * @param string $font
+     * @param float $size
+     * @param array $color
+     * @param float $word_space
+     * @param float $char_space
+     * @param float $angle
+     */
+    public function text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
+    {
+        $pdf = $this->_pdf;
+
+        $this->_set_fill_color($color);
+
+        $is_font_subsetting = $this->_dompdf->getOptions()->getIsFontSubsettingEnabled();
+        $pdf->selectFont($font . '.afm', '', true, $is_font_subsetting);
+
+        $pdf->addText($x, $this->y($y) - $pdf->getFontHeight($size), $size, $text, $angle, $word_space, $char_space);
+
+        $this->_set_fill_transparency("Normal", $this->_current_opacity);
+    }
+
+    /**
+     * @param string $code
+     */
+    public function javascript($code)
+    {
+        $this->_pdf->addJavascript($code);
+    }
+
+    //........................................................................
+
+    /**
+     * Add a named destination (similar to ... in html)
+     *
+     * @param string $anchorname The name of the named destination
+     */
+    public function add_named_dest($anchorname)
+    {
+        $this->_pdf->addDestination($anchorname, "Fit");
+    }
+
+    /**
+     * Add a link to the pdf
+     *
+     * @param string $url The url to link to
+     * @param float $x The x position of the link
+     * @param float $y The y position of the link
+     * @param float $width The width of the link
+     * @param float $height The height of the link
+     */
+    public function add_link($url, $x, $y, $width, $height)
+    {
+        $y = $this->y($y) - $height;
+
+        if (strpos($url, '#') === 0) {
+            // Local link
+            $name = substr($url, 1);
+            if ($name) {
+                $this->_pdf->addInternalLink($name, $x, $y, $x + $width, $y + $height);
+            }
+        } else {
+            $this->_pdf->addLink(rawurldecode($url), $x, $y, $x + $width, $y + $height);
+        }
+    }
+
+    /**
+     * @param string $text
+     * @param string $font
+     * @param float $size
+     * @param int $word_spacing
+     * @param int $char_spacing
+     * @return float|int
+     */
+    public function get_text_width($text, $font, $size, $word_spacing = 0, $char_spacing = 0)
+    {
+        $this->_pdf->selectFont($font, '', true, $this->_dompdf->getOptions()->getIsFontSubsettingEnabled());
+        return $this->_pdf->getTextWidth($size, $text, $word_spacing, $char_spacing);
+    }
+
+    /**
+     * @param $font
+     * @param $string
+     */
+    public function register_string_subset($font, $string)
+    {
+        $this->_pdf->registerText($font, $string);
+    }
+
+    /**
+     * @param string $font
+     * @param float $size
+     * @return float|int
+     * @throws FontNotFoundException
+     */
+    public function get_font_height($font, $size)
+    {
+        $options = $this->_dompdf->getOptions();
+        $this->_pdf->selectFont($font, '', true, $options->getIsFontSubsettingEnabled());
+
+        return $this->_pdf->getFontHeight($size) * $options->getFontHeightRatio();
+    }
+
+    /*function get_font_x_height($font, $size) {
+      $this->_pdf->selectFont($font);
+      $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+      return $this->_pdf->getFontXHeight($size) * $ratio;
+    }*/
+
+    /**
+     * @param string $font
+     * @param float $size
+     * @return float
+     */
+    public function get_font_baseline($font, $size)
+    {
+        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+        return $this->get_font_height($font, $size) / $ratio;
+    }
+
+    /**
+     * Writes text at the specified x and y coordinates on every page
+     *
+     * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
+     * with their current values.
+     *
+     * See {@link Style::munge_color()} for the format of the colour array.
+     *
+     * @param float $x
+     * @param float $y
+     * @param string $text the text to write
+     * @param string $font the font file to use
+     * @param float $size the font size, in points
+     * @param array $color
+     * @param float $word_space word spacing adjustment
+     * @param float $char_space char spacing adjustment
+     * @param float $angle angle to write the text at, measured CW starting from the x-axis
+     */
+    public function page_text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
+    {
+        $_t = "text";
+        $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle");
+    }
+
+    /**
+     * Processes a script on every page
+     *
+     * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available.
+     *
+     * This function can be used to add page numbers to all pages
+     * after the first one, for example.
+     *
+     * @param string $code the script code
+     * @param string $type the language type for script
+     */
+    public function page_script($code, $type = "text/php")
+    {
+        $_t = "script";
+        $this->_page_text[] = compact("_t", "code", "type");
+    }
+
+    /**
+     * @return int
+     */
+    public function new_page()
+    {
+        $this->_page_number++;
+        $this->_page_count++;
+
+        $ret = $this->_pdf->newPage();
+        $this->_pages[] = $ret;
+        return $ret;
+    }
+
+    /**
+     * Add text to each page after rendering is complete
+     */
+    protected function _add_page_text()
+    {
+        if (!count($this->_page_text)) {
+            return;
+        }
+
+        $page_number = 1;
+        $eval = null;
+
+        foreach ($this->_pages as $pid) {
+            $this->reopen_object($pid);
+
+            foreach ($this->_page_text as $pt) {
+                extract($pt);
+
+                switch ($_t) {
+                    case "text":
+                        $text = str_replace(["{PAGE_NUM}", "{PAGE_COUNT}"],
+                            [$page_number, $this->_page_count], $text);
+                        $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
+                        break;
+
+                    case "script":
+                        if (!$eval) {
+                            $eval = new PhpEvaluator($this);
+                        }
+                        $eval->evaluate($code, ['PAGE_NUM' => $page_number, 'PAGE_COUNT' => $this->_page_count]);
+                        break;
+
+                    case 'line':
+                        $this->line( $x1, $y1, $x2, $y2, $color, $width, $style );
+                        break;
+                }
+            }
+
+            $this->close_object();
+            $page_number++;
+        }
+    }
+
+    /**
+     * Streams the PDF to the client.
+     *
+     * @param string $filename The filename to present to the client.
+     * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1).
+     */
+    public function stream($filename = "document.pdf", $options = [])
+    {
+        if (headers_sent()) {
+            die("Unable to stream pdf: headers already sent");
+        }
+
+        if (!isset($options["compress"])) $options["compress"] = true;
+        if (!isset($options["Attachment"])) $options["Attachment"] = true;
+
+        $this->_add_page_text();
+
+        $debug = !$options['compress'];
+        $tmp = ltrim($this->_pdf->output($debug));
+
+        header("Cache-Control: private");
+        header("Content-Type: application/pdf");
+        header("Content-Length: " . mb_strlen($tmp, "8bit"));
+
+        $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf";
+        $attachment = $options["Attachment"] ? "attachment" : "inline";
+        header(Helpers::buildContentDispositionHeader($attachment, $filename));
+
+        echo $tmp;
+        flush();
+    }
+
+    /**
+     * Returns the PDF as a string.
+     *
+     * @param array $options Associative array: 'compress' => 1 or 0 (default 1).
+     * @return string
+     */
+    public function output($options = [])
+    {
+        if (!isset($options["compress"])) $options["compress"] = true;
+
+        $this->_add_page_text();
+
+        $debug = !$options['compress'];
+
+        return $this->_pdf->output($debug);
+    }
+
+    /**
+     * Returns logging messages generated by the Cpdf class
+     *
+     * @return string
+     */
+    public function get_messages()
+    {
+        return $this->_pdf->messages;
+    }
+}
diff --git a/vendor/dompdf/dompdf/src/Adapter/GD.php b/vendor/dompdf/dompdf/src/Adapter/GD.php
new file mode 100644
index 0000000..229776b
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/Adapter/GD.php
@@ -0,0 +1,1113 @@
+
+ * @author  Fabien Ménager 
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+namespace Dompdf\Adapter;
+
+use Dompdf\Canvas;
+use Dompdf\Dompdf;
+use Dompdf\Image\Cache;
+use Dompdf\Helpers;
+
+/**
+ * Image rendering interface
+ *
+ * Renders to an image format supported by GD (jpeg, gif, png, xpm).
+ * Not super-useful day-to-day but handy nonetheless
+ *
+ * @package dompdf
+ */
+class GD implements Canvas
+{
+    /**
+     * @var Dompdf
+     */
+    protected $_dompdf;
+
+    /**
+     * Resource handle for the image
+     *
+     * @var resource
+     */
+    protected $_img;
+
+    /**
+     * Resource handle for the image
+     *
+     * @var resource[]
+     */
+    protected $_imgs;
+
+    /**
+     * Apparent canvas width in pixels
+     *
+     * @var int
+     */
+    protected $_width;
+
+    /**
+     * Apparent canvas height in pixels
+     *
+     * @var int
+     */
+    protected $_height;
+
+    /**
+     * Actual image width in pixels
+     *
+     * @var int
+     */
+    protected $_actual_width;
+
+    /**
+     * Actual image height in pixels
+     *
+     * @var int
+     */
+    protected $_actual_height;
+
+    /**
+     * Current page number
+     *
+     * @var int
+     */
+    protected $_page_number;
+
+    /**
+     * Total number of pages
+     *
+     * @var int
+     */
+    protected $_page_count;
+
+    /**
+     * Image antialias factor
+     *
+     * @var float
+     */
+    protected $_aa_factor;
+
+    /**
+     * Allocated colors
+     *
+     * @var array
+     */
+    protected $_colors;
+
+    /**
+     * Background color
+     *
+     * @var int
+     */
+    protected $_bg_color;
+
+    /**
+     * Background color array
+     *
+     * @var int
+     */
+    protected $_bg_color_array;
+
+    /**
+     * Actual DPI
+     *
+     * @var int
+     */
+    protected $dpi;
+
+    /**
+     * Amount to scale font sizes
+     *
+     * Font sizes are 72 DPI, GD internally uses 96. Scale them proportionally.
+     * 72 / 96 = 0.75.
+     *
+     * @var float
+     */
+    const FONT_SCALE = 0.75;
+
+    /**
+     * Class constructor
+     *
+     * @param mixed $size The size of image to create: array(x1,y1,x2,y2) or "letter", "legal", etc.
+     * @param string $orientation The orientation of the document (either 'landscape' or 'portrait')
+     * @param Dompdf $dompdf
+     * @param float $aa_factor Anti-aliasing factor, 1 for no AA
+     * @param array $bg_color Image background color: array(r,g,b,a), 0 <= r,g,b,a <= 1
+     */
+    public function __construct($size = 'letter', $orientation = "portrait", Dompdf $dompdf, $aa_factor = 1.0, $bg_color = [1, 1, 1, 0])
+    {
+
+        if (!is_array($size)) {
+            $size = strtolower($size);
+
+            if (isset(CPDF::$PAPER_SIZES[$size])) {
+                $size = CPDF::$PAPER_SIZES[$size];
+            } else {
+                $size = CPDF::$PAPER_SIZES["letter"];
+            }
+        }
+
+        if (strtolower($orientation) === "landscape") {
+            list($size[2], $size[3]) = [$size[3], $size[2]];
+        }
+
+        $this->_dompdf = $dompdf;
+
+        $this->dpi = $this->get_dompdf()->getOptions()->getDpi();
+
+        if ($aa_factor < 1) {
+            $aa_factor = 1;
+        }
+
+        $this->_aa_factor = $aa_factor;
+
+        $size[2] *= $aa_factor;
+        $size[3] *= $aa_factor;
+
+        $this->_width = $size[2] - $size[0];
+        $this->_height = $size[3] - $size[1];
+
+        $this->_actual_width = $this->_upscale($this->_width);
+        $this->_actual_height = $this->_upscale($this->_height);
+
+        $this->_page_number = $this->_page_count = 1;
+        $this->_page_text = [];
+
+        if (is_null($bg_color) || !is_array($bg_color)) {
+            // Pure white bg
+            $bg_color = [1, 1, 1, 0];
+        }
+
+        $this->_bg_color_array = $bg_color;
+
+        $this->new_page();
+    }
+
+    /**
+     * @return Dompdf
+     */
+    public function get_dompdf()
+    {
+        return $this->_dompdf;
+    }
+
+    /**
+     * Return the GF image resource
+     *
+     * @return resource
+     */
+    public function get_image()
+    {
+        return $this->_img;
+    }
+
+    /**
+     * Return the image's width in pixels
+     *
+     * @return float
+     */
+    public function get_width()
+    {
+        return $this->_width / $this->_aa_factor;
+    }
+
+    /**
+     * Return the image's height in pixels
+     *
+     * @return float
+     */
+    public function get_height()
+    {
+        return $this->_height / $this->_aa_factor;
+    }
+
+    /**
+     * Returns the current page number
+     * @return int
+     */
+    public function get_page_number()
+    {
+        return $this->_page_number;
+    }
+
+    /**
+     * Returns the total number of pages in the document
+     * @return int
+     */
+    public function get_page_count()
+    {
+        return $this->_page_count;
+    }
+
+    /**
+     * Sets the current page number
+     *
+     * @param int $num
+     */
+    public function set_page_number($num)
+    {
+        $this->_page_number = $num;
+    }
+
+    /**
+     * Sets the page count
+     *
+     * @param int $count
+     */
+    public function set_page_count($count)
+    {
+        $this->_page_count = $count;
+    }
+
+    /**
+     * Sets the opacity
+     *
+     * @param $opacity
+     * @param $mode
+     */
+    public function set_opacity($opacity, $mode = "Normal")
+    {
+        // FIXME
+    }
+
+    /**
+     * Allocate a new color.  Allocate with GD as needed and store
+     * previously allocated colors in $this->_colors.
+     *
+     * @param array $color The new current color
+     * @return int           The allocated color
+     */
+    protected function _allocate_color($color)
+    {
+        $a = isset($color["alpha"]) ? $color["alpha"] : 1;
+
+        if (isset($color["c"])) {
+            $color = Helpers::cmyk_to_rgb($color);
+        }
+
+        list($r, $g, $b) = $color;
+
+        $r *= 255;
+        $g *= 255;
+        $b *= 255;
+        $a = 127 - ($a * 127);
+
+        // Clip values
+        $r = $r > 255 ? 255 : $r;
+        $g = $g > 255 ? 255 : $g;
+        $b = $b > 255 ? 255 : $b;
+        $a = $a > 127 ? 127 : $a;
+
+        $r = $r < 0 ? 0 : $r;
+        $g = $g < 0 ? 0 : $g;
+        $b = $b < 0 ? 0 : $b;
+        $a = $a < 0 ? 0 : $a;
+
+        $key = sprintf("#%02X%02X%02X%02X", $r, $g, $b, $a);
+
+        if (isset($this->_colors[$key])) {
+            return $this->_colors[$key];
+        }
+
+        if ($a != 0) {
+            $this->_colors[$key] = imagecolorallocatealpha($this->get_image(), $r, $g, $b, $a);
+        } else {
+            $this->_colors[$key] = imagecolorallocate($this->get_image(), $r, $g, $b);
+        }
+
+        return $this->_colors[$key];
+    }
+
+    /**
+     * Scales value up to the current canvas DPI from 72 DPI
+     *
+     * @param float $length
+     * @return float
+     */
+    protected function _upscale($length)
+    {
+        return ($length * $this->dpi) / 72 * $this->_aa_factor;
+    }
+
+    /**
+     * Scales value down from the current canvas DPI to 72 DPI
+     *
+     * @param float $length
+     * @return float
+     */
+    protected function _downscale($length)
+    {
+        return ($length / $this->dpi * 72) / $this->_aa_factor;
+    }
+
+    /**
+     * Draws a line from x1,y1 to x2,y2
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the format of the
+     * $style parameter (aka dash).
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function line($x1, $y1, $x2, $y2, $color, $width, $style = null)
+    {
+
+        // Scale by the AA factor and DPI
+        $x1 = $this->_upscale($x1);
+        $y1 = $this->_upscale($y1);
+        $x2 = $this->_upscale($x2);
+        $y2 = $this->_upscale($y2);
+        $width = $this->_upscale($width);
+
+        $c = $this->_allocate_color($color);
+
+        // Convert the style array if required
+        if (is_array($style) && count($style) > 0) {
+            $gd_style = [];
+
+            if (count($style) == 1) {
+                for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
+                    $gd_style[] = $c;
+                }
+
+                for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
+                    $gd_style[] = $this->_bg_color;
+                }
+            } else {
+                $i = 0;
+                foreach ($style as $length) {
+                    if ($i % 2 == 0) {
+                        // 'On' pattern
+                        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
+                            $gd_style[] = $c;
+                        }
+
+                    } else {
+                        // Off pattern
+                        for ($i = 0; $i < $style[0] * $this->_aa_factor; $i++) {
+                            $gd_style[] = $this->_bg_color;
+                        }
+                    }
+                    $i++;
+                }
+            }
+
+            if (!empty($gd_style)) {
+                imagesetstyle($this->get_image(), $gd_style);
+                $c = IMG_COLOR_STYLED;
+            }
+        }
+
+        imagesetthickness($this->get_image(), $width);
+
+        imageline($this->get_image(), $x1, $y1, $x2, $y2, $c);
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $r1
+     * @param float $r2
+     * @param float $astart
+     * @param float $aend
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function arc($x1, $y1, $r1, $r2, $astart, $aend, $color, $width, $style = [])
+    {
+        // @todo
+    }
+
+    /**
+     * Draws a rectangle at x1,y1 with width w and height h
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function rectangle($x1, $y1, $w, $h, $color, $width, $style = null)
+    {
+
+        // Scale by the AA factor and DPI
+        $x1 = $this->_upscale($x1);
+        $y1 = $this->_upscale($y1);
+        $w = $this->_upscale($w);
+        $h = $this->_upscale($h);
+        $width = $this->_upscale($width);
+
+        $c = $this->_allocate_color($color);
+
+        // Convert the style array if required
+        if (is_array($style) && count($style) > 0) {
+            $gd_style = [];
+
+            foreach ($style as $length) {
+                for ($i = 0; $i < $length; $i++) {
+                    $gd_style[] = $c;
+                }
+            }
+
+            if (!empty($gd_style)) {
+                imagesetstyle($this->get_image(), $gd_style);
+                $c = IMG_COLOR_STYLED;
+            }
+        }
+
+        imagesetthickness($this->get_image(), $width);
+
+        imagerectangle($this->get_image(), $x1, $y1, $x1 + $w, $y1 + $h, $c);
+    }
+
+    /**
+     * Draws a filled rectangle at x1,y1 with width w and height h
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     */
+    public function filled_rectangle($x1, $y1, $w, $h, $color)
+    {
+        // Scale by the AA factor and DPI
+        $x1 = $this->_upscale($x1);
+        $y1 = $this->_upscale($y1);
+        $w = $this->_upscale($w);
+        $h = $this->_upscale($h);
+
+        $c = $this->_allocate_color($color);
+
+        imagefilledrectangle($this->get_image(), $x1, $y1, $x1 + $w, $y1 + $h, $c);
+    }
+
+    /**
+     * Starts a clipping rectangle at x1,y1 with width w and height h
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     */
+    public function clipping_rectangle($x1, $y1, $w, $h)
+    {
+        // @todo
+    }
+
+    public function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL)
+    {
+        // @todo
+    }
+
+    /**
+     * Ends the last clipping shape
+     */
+    public function clipping_end()
+    {
+        // @todo
+    }
+
+    /**
+     *
+     */
+    public function save()
+    {
+        $this->get_dompdf()->getOptions()->setDpi(72);
+    }
+
+    /**
+     *
+     */
+    public function restore()
+    {
+        $this->get_dompdf()->getOptions()->setDpi($this->dpi);
+    }
+
+    /**
+     * @param $angle
+     * @param $x
+     * @param $y
+     */
+    public function rotate($angle, $x, $y)
+    {
+        // @todo
+    }
+
+    /**
+     * @param $angle_x
+     * @param $angle_y
+     * @param $x
+     * @param $y
+     */
+    public function skew($angle_x, $angle_y, $x, $y)
+    {
+        // @todo
+    }
+
+    /**
+     * @param $s_x
+     * @param $s_y
+     * @param $x
+     * @param $y
+     */
+    public function scale($s_x, $s_y, $x, $y)
+    {
+        // @todo
+    }
+
+    /**
+     * @param $t_x
+     * @param $t_y
+     */
+    public function translate($t_x, $t_y)
+    {
+        // @todo
+    }
+
+    /**
+     * @param $a
+     * @param $b
+     * @param $c
+     * @param $d
+     * @param $e
+     * @param $f
+     */
+    public function transform($a, $b, $c, $d, $e, $f)
+    {
+        // @todo
+    }
+
+    /**
+     * Draws a polygon
+     *
+     * The polygon is formed by joining all the points stored in the $points
+     * array.  $points has the following structure:
+     * 
+     * array(0 => x1,
+     *       1 => y1,
+     *       2 => x2,
+     *       3 => y2,
+     *       ...
+     *       );
+     * 
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param array $points
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     * @param bool $fill Fills the polygon if true
+     */
+    public function polygon($points, $color, $width = null, $style = null, $fill = false)
+    {
+
+        // Scale each point by the AA factor and DPI
+        foreach (array_keys($points) as $i) {
+            $points[$i] = $this->_upscale($points[$i]);
+        }
+
+        $c = $this->_allocate_color($color);
+
+        // Convert the style array if required
+        if (is_array($style) && count($style) > 0 && !$fill) {
+            $gd_style = [];
+
+            foreach ($style as $length) {
+                for ($i = 0; $i < $length; $i++) {
+                    $gd_style[] = $c;
+                }
+            }
+
+            if (!empty($gd_style)) {
+                imagesetstyle($this->get_image(), $gd_style);
+                $c = IMG_COLOR_STYLED;
+            }
+        }
+
+        imagesetthickness($this->get_image(), $width);
+
+        if ($fill) {
+            imagefilledpolygon($this->get_image(), $points, count($points) / 2, $c);
+        } else {
+            imagepolygon($this->get_image(), $points, count($points) / 2, $c);
+        }
+    }
+
+    /**
+     * Draws a circle at $x,$y with radius $r
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param float $x
+     * @param float $y
+     * @param float $r
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     * @param bool $fill Fills the circle if true
+     */
+    public function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false)
+    {
+        // Scale by the AA factor and DPI
+        $x = $this->_upscale($x);
+        $y = $this->_upscale($y);
+        $r = $this->_upscale($r);
+
+        $c = $this->_allocate_color($color);
+
+        // Convert the style array if required
+        if (is_array($style) && count($style) > 0 && !$fill) {
+            $gd_style = [];
+
+            foreach ($style as $length) {
+                for ($i = 0; $i < $length; $i++) {
+                    $gd_style[] = $c;
+                }
+            }
+
+            if (!empty($gd_style)) {
+                imagesetstyle($this->get_image(), $gd_style);
+                $c = IMG_COLOR_STYLED;
+            }
+        }
+
+        imagesetthickness($this->get_image(), $width);
+
+        if ($fill) {
+            imagefilledellipse($this->get_image(), $x, $y, $r, $r, $c);
+        } else {
+            imageellipse($this->get_image(), $x, $y, $r, $r, $c);
+        }
+    }
+
+    /**
+     * Add an image to the pdf.
+     * The image is placed at the specified x and y coordinates with the
+     * given width and height.
+     *
+     * @param string $img_url the path to the image
+     * @param float $x x position
+     * @param float $y y position
+     * @param int $w width (in pixels)
+     * @param int $h height (in pixels)
+     * @param string $resolution
+     * @return void
+     *
+     * @throws \Exception
+     * @internal param string $img_type the type (e.g. extension) of the image
+     */
+    public function image($img_url, $x, $y, $w, $h, $resolution = "normal")
+    {
+        $img_type = Cache::detect_type($img_url, $this->get_dompdf()->getHttpContext());
+
+        if (!$img_type) {
+            return;
+        }
+
+        $func_name = "imagecreatefrom$img_type";
+        if (!function_exists($func_name)) {
+            if (!method_exists("Dompdf\Helpers", $func_name)) {
+                throw new \Exception("Function $func_name() not found.  Cannot convert $img_type image: $img_url.  Please install the image PHP extension.");
+            }
+            $func_name = "\\Dompdf\\Helpers::" . $func_name;
+        }
+        $src = @call_user_func($func_name, $img_url);
+
+        if (!$src) {
+            return; // Probably should add to $_dompdf_errors or whatever here
+        }
+
+        // Scale by the AA factor and DPI
+        $x = $this->_upscale($x);
+        $y = $this->_upscale($y);
+
+        $w = $this->_upscale($w);
+        $h = $this->_upscale($h);
+
+        $img_w = imagesx($src);
+        $img_h = imagesy($src);
+
+        imagecopyresampled($this->get_image(), $src, $x, $y, 0, 0, $w, $h, $img_w, $img_h);
+    }
+
+    /**
+     * Writes text at the specified x and y coordinates
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float $x
+     * @param float $y
+     * @param string $text the text to write
+     * @param string $font the font file to use
+     * @param float $size the font size, in points
+     * @param array $color
+     * @param float $word_spacing word spacing adjustment
+     * @param float $char_spacing
+     * @param float $angle Text angle
+     *
+     * @return void
+     */
+    public function text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_spacing = 0.0, $char_spacing = 0.0, $angle = 0.0)
+    {
+        // Scale by the AA factor and DPI
+        $x = $this->_upscale($x);
+        $y = $this->_upscale($y);
+        $size = $this->_upscale($size) * self::FONT_SCALE;
+
+        $h = $this->get_font_height_actual($font, $size);
+        $c = $this->_allocate_color($color);
+
+        // imagettftext() converts numeric entities to their respective
+        // character. Preserve any originally double encoded entities to be
+        // represented as is.
+        // eg: &#160; will render   rather than its character.
+        $text = preg_replace('/&(#(?:x[a-fA-F0-9]+|[0-9]+);)/', '&\1', $text);
+
+        $text = mb_encode_numericentity($text, [0x0080, 0xff, 0, 0xff], 'UTF-8');
+
+        $font = $this->get_ttf_file($font);
+
+        // FIXME: word spacing
+        imagettftext($this->get_image(), $size, $angle, $x, $y + $h, $c, $font, $text);
+    }
+
+    public function javascript($code)
+    {
+        // Not implemented
+    }
+
+    /**
+     * Add a named destination (similar to ... in html)
+     *
+     * @param string $anchorname The name of the named destination
+     */
+    public function add_named_dest($anchorname)
+    {
+        // Not implemented
+    }
+
+    /**
+     * Add a link to the pdf
+     *
+     * @param string $url The url to link to
+     * @param float $x The x position of the link
+     * @param float $y The y position of the link
+     * @param float $width The width of the link
+     * @param float $height The height of the link
+     */
+    public function add_link($url, $x, $y, $width, $height)
+    {
+        // Not implemented
+    }
+
+    /**
+     * Add meta information to the PDF
+     *
+     * @param string $label label of the value (Creator, Producer, etc.)
+     * @param string $value the text to set
+     */
+    public function add_info($label, $value)
+    {
+        // N/A
+    }
+
+    /**
+     * @param string $view
+     * @param array $options
+     */
+    public function set_default_view($view, $options = [])
+    {
+        // N/A
+    }
+
+    /**
+     * Calculates text size, in points
+     *
+     * @param string $text the text to be sized
+     * @param string $font the desired font
+     * @param float $size the desired font size
+     * @param float $word_spacing word spacing, if any
+     * @param float $char_spacing char spacing, if any
+     *
+     * @return float
+     */
+    public function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0)
+    {
+        $font = $this->get_ttf_file($font);
+        $size = $this->_upscale($size) * self::FONT_SCALE;
+
+        // imagettfbbox() converts numeric entities to their respective
+        // character. Preserve any originally double encoded entities to be
+        // represented as is.
+        // eg: &#160; will render   rather than its character.
+        $text = preg_replace('/&(#(?:x[a-fA-F0-9]+|[0-9]+);)/', '&\1', $text);
+
+        $text = mb_encode_numericentity($text, [0x0080, 0xffff, 0, 0xffff], 'UTF-8');
+
+        // FIXME: word spacing
+        list($x1, , $x2) = imagettfbbox($size, 0, $font, $text);
+
+        // Add additional 1pt to prevent text overflow issues
+        return $this->_downscale($x2 - $x1) + 1;
+    }
+
+    /**
+     * @param $font
+     * @return string
+     */
+    public function get_ttf_file($font)
+    {
+        if ( stripos($font, ".ttf") === false ) {
+            $font .= ".ttf";
+        }
+
+        if (!file_exists($font)) {
+            $font_metrics = $this->_dompdf->getFontMetrics();
+            $font = $font_metrics->getFont($this->_dompdf->getOptions()->getDefaultFont()) . ".ttf";
+            if (!file_exists($font)) {
+                if (strpos($font, "mono")) {
+                    $font = $font_metrics->getFont("DejaVu Mono") . ".ttf";
+                } elseif (strpos($font, "sans") !== false) {
+                    $font = $font_metrics->getFont("DejaVu Sans") . ".ttf";
+                } elseif (strpos($font, "serif")) {
+                    $font = $font_metrics->getFont("DejaVu Serif") . ".ttf";
+                } else {
+                    $font = $font_metrics->getFont("DejaVu Sans") . ".ttf";
+                }
+            }
+        }
+
+        return $font;
+    }
+
+    /**
+     * Calculates font height, in points
+     *
+     * @param string $font
+     * @param float $size
+     * @return float
+     */
+    public function get_font_height($font, $size)
+    {
+        $size = $this->_upscale($size) * self::FONT_SCALE;
+
+        $height = $this->get_font_height_actual($font, $size);
+
+        return $this->_downscale($height);
+    }
+
+    protected function get_font_height_actual($font, $size)
+    {
+        $font = $this->get_ttf_file($font);
+        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+
+        // FIXME: word spacing
+        list(, $y2, , , , $y1) = imagettfbbox($size, 0, $font, "MXjpqytfhl"); // Test string with ascenders, descenders and caps
+        return ($y2 - $y1) * $ratio;
+    }
+
+    /**
+     * @param string $font
+     * @param float $size
+     * @return float
+     */
+    public function get_font_baseline($font, $size)
+    {
+        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+        return $this->get_font_height($font, $size) / $ratio;
+    }
+
+    /**
+     * Starts a new page
+     *
+     * Subsequent drawing operations will appear on the new page.
+     */
+    public function new_page()
+    {
+        $this->_page_number++;
+        $this->_page_count++;
+
+        $this->_img = imagecreatetruecolor($this->_actual_width, $this->_actual_height);
+
+        $this->_bg_color = $this->_allocate_color($this->_bg_color_array);
+        imagealphablending($this->_img, true);
+        imagesavealpha($this->_img, true);
+        imagefill($this->_img, 0, 0, $this->_bg_color);
+
+        $this->_imgs[] = $this->_img;
+    }
+
+    public function open_object()
+    {
+        // N/A
+    }
+
+    public function close_object()
+    {
+        // N/A
+    }
+
+    public function add_object()
+    {
+        // N/A
+    }
+
+    /**
+     * Writes text at the specified x and y coordinates on every page
+     *
+     * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
+     * with their current values.
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float  $x
+     * @param float  $y
+     * @param string $text       the text to write
+     * @param string $font       the font file to use
+     * @param float  $size       the font size, in points
+     * @param array  $color
+     * @param float  $word_space word spacing adjustment
+     * @param float  $char_space char spacing adjustment
+     * @param float  $angle      angle to write the text at, measured CW starting from the x-axis
+     */
+    public function page_text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
+    {
+        // N/A
+    }
+
+    public function page_line()
+    {
+        // N/A
+    }
+
+    /**
+     * Streams the image to the client.
+     *
+     * @param string $filename The filename to present to the client.
+     * @param array $options Associative array: 'type' => jpeg|jpg|png; 'quality' => 0 - 100 (JPEG only);
+     *     'page' => Number of the page to output (defaults to the first); 'Attachment': 1 or 0 (default 1).
+     */
+    public function stream($filename, $options = [])
+    {
+        if (headers_sent()) {
+            die("Unable to stream image: headers already sent");
+        }
+
+        if (!isset($options["type"])) $options["type"] = "png";
+        if (!isset($options["Attachment"])) $options["Attachment"] = true;
+        $type = strtolower($options["type"]);
+
+        switch ($type) {
+            case "jpg":
+            case "jpeg":
+                $contentType = "image/jpeg";
+                $extension = ".jpg";
+                break;
+            case "png":
+            default:
+                $contentType = "image/png";
+                $extension = ".png";
+                break;
+        }
+
+        header("Cache-Control: private");
+        header("Content-Type: $contentType");
+
+        $filename = str_replace(["\n", "'"], "", basename($filename, ".$type")) . $extension;
+        $attachment = $options["Attachment"] ? "attachment" : "inline";
+        header(Helpers::buildContentDispositionHeader($attachment, $filename));
+
+        $this->_output($options);
+        flush();
+    }
+
+    /**
+     * Returns the image as a string.
+     *
+     * @param array $options Associative array: 'type' => jpeg|jpg|png; 'quality' => 0 - 100 (JPEG only);
+     *     'page' => Number of the page to output (defaults to the first).
+     * @return string
+     */
+    public function output($options = [])
+    {
+        ob_start();
+
+        $this->_output($options);
+
+        return ob_get_clean();
+    }
+
+    /**
+     * Outputs the image stream directly.
+     *
+     * @param array $options Associative array: 'type' => jpeg|jpg|png; 'quality' => 0 - 100 (JPEG only);
+     *     'page' => Number of the page to output (defaults to the first).
+     */
+    protected function _output($options = [])
+    {
+        if (!isset($options["type"])) $options["type"] = "png";
+        if (!isset($options["page"])) $options["page"] = 1;
+        $type = strtolower($options["type"]);
+
+        if (isset($this->_imgs[$options["page"] - 1])) {
+            $img = $this->_imgs[$options["page"] - 1];
+        } else {
+            $img = $this->_imgs[0];
+        }
+
+        // Perform any antialiasing
+        if ($this->_aa_factor != 1) {
+            $dst_w = $this->_actual_width / $this->_aa_factor;
+            $dst_h = $this->_actual_height / $this->_aa_factor;
+            $dst = imagecreatetruecolor($dst_w, $dst_h);
+            imagecopyresampled($dst, $img, 0, 0, 0, 0,
+                $dst_w, $dst_h,
+                $this->_actual_width, $this->_actual_height);
+        } else {
+            $dst = $img;
+        }
+
+        switch ($type) {
+            case "jpg":
+            case "jpeg":
+                if (!isset($options["quality"])) {
+                    $options["quality"] = 75;
+                }
+
+                imagejpeg($dst, null, $options["quality"]);
+                break;
+            case "png":
+            default:
+                imagepng($dst);
+                break;
+        }
+
+        if ($this->_aa_factor != 1) {
+            imagedestroy($dst);
+        }
+    }
+}
diff --git a/vendor/dompdf/dompdf/src/Adapter/PDFLib.php b/vendor/dompdf/dompdf/src/Adapter/PDFLib.php
new file mode 100644
index 0000000..8f13be7
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/Adapter/PDFLib.php
@@ -0,0 +1,1664 @@
+
+ * @author  Helmut Tischer 
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+
+namespace Dompdf\Adapter;
+
+use Dompdf\Canvas;
+use Dompdf\Dompdf;
+use Dompdf\Helpers;
+use Dompdf\Exception;
+use Dompdf\Image\Cache;
+use Dompdf\PhpEvaluator;
+
+/**
+ * PDF rendering interface
+ *
+ * Dompdf\Adapter\PDFLib provides a simple, stateless interface to the one
+ * provided by PDFLib.
+ *
+ * Unless otherwise mentioned, all dimensions are in points (1/72 in).
+ * The coordinate origin is in the top left corner and y values
+ * increase downwards.
+ *
+ * See {@link http://www.pdflib.com/} for more complete documentation
+ * on the underlying PDFlib functions.
+ *
+ * @package dompdf
+ */
+class PDFLib implements Canvas
+{
+
+    /**
+     * Dimensions of paper sizes in points
+     *
+     * @var array;
+     */
+    public static $PAPER_SIZES = []; // Set to Dompdf\Adapter\CPDF::$PAPER_SIZES below.
+
+    /**
+     * Whether to create PDFs in memory or on disk
+     *
+     * @var bool
+     */
+    static $IN_MEMORY = true;
+
+    /**
+     * Saves the major version of PDFLib for compatibility requests
+     *
+     * @var null|int
+     */
+    protected static $MAJOR_VERSION = null;
+
+
+    /**
+     * Transforms the list of native fonts into PDFLib compatible names (casesensitive)
+     *
+     * @var array
+     */
+    public static $nativeFontsTpPDFLib = [
+        "courier"               => "Courier",
+        "courier-bold"          => "Courier-Bold",
+        "courier-oblique"       => "Courier-Oblique",
+        "courier-boldoblique"   => "Courier-BoldOblique",
+        "helvetica"             => "Helvetica",
+        "helvetica-bold"        => "Helvetica-Bold",
+        "helvetica-oblique"     => "Helvetica-Oblique",
+        "helvetica-boldoblique" => "Helvetica-BoldOblique",
+        "times"                 => "Times-Roman",
+        "times-roman"           => "Times-Roman",
+        "times-bold"            => "Times-Bold",
+        "times-italic"          => "Times-Italic",
+        "times-bolditalic"      => "Times-BoldItalic",
+        "symbol"                => "Symbol",
+        "zapfdinbats"           => "ZapfDingbats",
+        "zapfdingbats"          => "ZapfDingbats",
+    ];
+
+    /**
+     * @var \Dompdf\Dompdf
+     */
+    protected $_dompdf;
+
+    /**
+     * Instance of PDFLib class
+     *
+     * @var \PDFLib
+     */
+    protected $_pdf;
+
+    /**
+     * Name of temporary file used for PDFs created on disk
+     *
+     * @var string
+     */
+    protected $_file;
+
+    /**
+     * PDF width, in points
+     *
+     * @var float
+     */
+    protected $_width;
+
+    /**
+     * PDF height, in points
+     *
+     * @var float
+     */
+    protected $_height;
+
+    /**
+     * Last fill color used
+     *
+     * @var array
+     */
+    protected $_last_fill_color;
+
+    /**
+     * Last stroke color used
+     *
+     * @var array
+     */
+    protected $_last_stroke_color;
+
+    /**
+     * The current opacity level
+     *
+     * @var array
+     */
+    protected $_current_opacity;
+
+    /**
+     * Cache of image handles
+     *
+     * @var array
+     */
+    protected $_imgs;
+
+    /**
+     * Cache of font handles
+     *
+     * @var array
+     */
+    protected $_fonts;
+
+    /**
+     * Cache of fontFile checks
+     *
+     * @var array
+     */
+    protected $_fontsFiles;
+
+    /**
+     * List of objects (templates) to add to multiple pages
+     *
+     * @var array
+     */
+    protected $_objs;
+
+    /**
+     * List of gstate objects created for this PDF (for reuse)
+     *
+     * @var array
+     */
+    protected $_gstates = [];
+
+    /**
+     * Current page number
+     *
+     * @var int
+     */
+    protected $_page_number;
+
+    /**
+     * Total number of pages
+     *
+     * @var int
+     */
+    protected $_page_count;
+
+    /**
+     * Text to display on every page
+     *
+     * @var array
+     */
+    protected $_page_text;
+
+    /**
+     * Array of pages for accesing after rendering is initially complete
+     *
+     * @var array
+     */
+    protected $_pages;
+
+    /**
+     * Class constructor
+     *
+     * @param string|array $paper The size of paper to use either a string (see {@link Dompdf\Adapter\CPDF::$PAPER_SIZES}) or
+     *                            an array(xmin,ymin,xmax,ymax)
+     * @param string $orientation The orientation of the document (either 'landscape' or 'portrait')
+     * @param Dompdf $dompdf
+     */
+    public function __construct($paper = "letter", $orientation = "portrait", Dompdf $dompdf)
+    {
+        if (is_array($paper)) {
+            $size = $paper;
+        } elseif (isset(self::$PAPER_SIZES[mb_strtolower($paper)])) {
+            $size = self::$PAPER_SIZES[mb_strtolower($paper)];
+        } else {
+            $size = self::$PAPER_SIZES["letter"];
+        }
+
+        if (mb_strtolower($orientation) === "landscape") {
+            list($size[2], $size[3]) = [$size[3], $size[2]];
+        }
+
+        $this->_width = $size[2] - $size[0];
+        $this->_height = $size[3] - $size[1];
+
+        $this->_dompdf = $dompdf;
+
+        $this->_pdf = new \PDFLib();
+
+        $license = $dompdf->getOptions()->getPdflibLicense();
+        if (strlen($license) > 0) {
+            $this->setPDFLibParameter("license", $license);
+        }
+
+        $this->setPDFLibParameter("textformat", "utf8");
+        if ($this->getPDFLibMajorVersion() >= 7) {
+            $this->setPDFLibParameter("errorpolicy", "return");
+            //            $this->_pdf->set_option('logging={filename=' . \APP_PATH . '/logs/pdflib.log classes={api=1 warning=2}}');
+            //            $this->_pdf->set_option('errorpolicy=exception');
+        } else {
+            $this->setPDFLibParameter("fontwarning", "false");
+        }
+
+        $searchPath = $this->_dompdf->getOptions()->getFontDir();
+        if (empty($searchPath) === false) {
+            $this->_pdf->set_option('searchpath={' . $searchPath . '}');
+        }
+
+        // fetch PDFLib version information for the producer field
+        $this->_pdf->set_info("Producer Addendum", sprintf("%s + PDFLib %s", $dompdf->version, $this->getPDFLibMajorVersion()));
+
+        // Silence pedantic warnings about missing TZ settings
+        $tz = @date_default_timezone_get();
+        date_default_timezone_set("UTC");
+        $this->_pdf->set_info("Date", date("Y-m-d"));
+        date_default_timezone_set($tz);
+
+        if (self::$IN_MEMORY) {
+            $this->_pdf->begin_document("", "");
+        } else {
+            $tmp_dir = $this->_dompdf->getOptions()->getTempDir();
+            $tmp_name = @tempnam($tmp_dir, "libdompdf_pdf_");
+            @unlink($tmp_name);
+            $this->_file = "$tmp_name.pdf";
+            $this->_pdf->begin_document($this->_file, "");
+        }
+
+        $this->_pdf->begin_page_ext($this->_width, $this->_height, "");
+
+        $this->_page_number = $this->_page_count = 1;
+        $this->_page_text = [];
+
+        $this->_imgs = [];
+        $this->_fonts = [];
+        $this->_objs = [];
+    }
+
+    /**
+     * @return Dompdf
+     */
+    function get_dompdf()
+    {
+        return $this->_dompdf;
+    }
+
+    /**
+     * Close the pdf
+     */
+    protected function _close()
+    {
+        $this->_place_objects();
+
+        // Close all pages
+        $this->_pdf->suspend_page("");
+        for ($p = 1; $p <= $this->_page_count; $p++) {
+            $this->_pdf->resume_page("pagenumber=$p");
+            $this->_pdf->end_page_ext("");
+        }
+
+        $this->_pdf->end_document("");
+    }
+
+
+    /**
+     * Returns the PDFLib instance
+     *
+     * @return PDFLib
+     */
+    public function get_pdflib()
+    {
+        return $this->_pdf;
+    }
+
+    /**
+     * Add meta information to the PDF
+     *
+     * @param string $label label of the value (Creator, Producter, etc.)
+     * @param string $value the text to set
+     */
+    public function add_info($label, $value)
+    {
+        $this->_pdf->set_info($label, $value);
+    }
+
+    /**
+     * Opens a new 'object' (template in PDFLib-speak)
+     *
+     * While an object is open, all drawing actions are recorded to the
+     * object instead of being drawn on the current page.  Objects can
+     * be added later to a specific page or to several pages.
+     *
+     * The return value is an integer ID for the new object.
+     *
+     * @see PDFLib::close_object()
+     * @see PDFLib::add_object()
+     *
+     * @return int
+     */
+    public function open_object()
+    {
+        $this->_pdf->suspend_page("");
+        if ($this->getPDFLibMajorVersion() >= 7) {
+            $ret = $this->_pdf->begin_template_ext($this->_width, $this->_height, null);
+        } else {
+            $ret = $this->_pdf->begin_template($this->_width, $this->_height);
+        }
+        $this->_pdf->save();
+        $this->_objs[$ret] = ["start_page" => $this->_page_number];
+
+        return $ret;
+    }
+
+    /**
+     * Reopen an existing object (NOT IMPLEMENTED)
+     * PDFLib does not seem to support reopening templates.
+     *
+     * @param int $object the ID of a previously opened object
+     *
+     * @throws Exception
+     * @return void
+     */
+    public function reopen_object($object)
+    {
+        throw new Exception("PDFLib does not support reopening objects.");
+    }
+
+    /**
+     * Close the current template
+     *
+     * @see PDFLib::open_object()
+     */
+    public function close_object()
+    {
+        $this->_pdf->restore();
+        if ($this->getPDFLibMajorVersion() >= 7) {
+            $this->_pdf->end_template_ext($this->_width, $this->_height);
+        } else {
+            $this->_pdf->end_template();
+        }
+        $this->_pdf->resume_page("pagenumber=" . $this->_page_number);
+    }
+
+    /**
+     * Adds the specified object to the document
+     *
+     * $where can be one of:
+     * - 'add' add to current page only
+     * - 'all' add to every page from the current one onwards
+     * - 'odd' add to all odd numbered pages from now on
+     * - 'even' add to all even numbered pages from now on
+     * - 'next' add the object to the next page only
+     * - 'nextodd' add to all odd numbered pages from the next one
+     * - 'nexteven' add to all even numbered pages from the next one
+     *
+     * @param int    $object the object handle returned by open_object()
+     * @param string $where
+     */
+    public function add_object($object, $where = 'all')
+    {
+
+        if (mb_strpos($where, "next") !== false) {
+            $this->_objs[$object]["start_page"]++;
+            $where = str_replace("next", "", $where);
+            if ($where == "") {
+                $where = "add";
+            }
+        }
+
+        $this->_objs[$object]["where"] = $where;
+    }
+
+    /**
+     * Stops the specified template from appearing in the document.
+     *
+     * The object will stop being displayed on the page following the
+     * current one.
+     *
+     * @param int $object
+     */
+    public function stop_object($object)
+    {
+
+        if (!isset($this->_objs[$object])) {
+            return;
+        }
+
+        $start = $this->_objs[$object]["start_page"];
+        $where = $this->_objs[$object]["where"];
+
+        // Place the object on this page if required
+        if ($this->_page_number >= $start &&
+            (($this->_page_number % 2 == 0 && $where === "even") ||
+                ($this->_page_number % 2 == 1 && $where === "odd") ||
+                ($where === "all"))
+        ) {
+            $this->_pdf->fit_image($object, 0, 0, "");
+        }
+
+        $this->_objs[$object] = null;
+        unset($this->_objs[$object]);
+    }
+
+    /**
+     * Add all active objects to the current page
+     */
+    protected function _place_objects()
+    {
+
+        foreach ($this->_objs as $obj => $props) {
+            $start = $props["start_page"];
+            $where = $props["where"];
+
+            // Place the object on this page if required
+            if ($this->_page_number >= $start &&
+                (($this->_page_number % 2 == 0 && $where === "even") ||
+                    ($this->_page_number % 2 == 1 && $where === "odd") ||
+                    ($where === "all"))
+            ) {
+                $this->_pdf->fit_image($obj, 0, 0, "");
+            }
+        }
+    }
+
+    /**
+     * @return float|mixed
+     */
+    public function get_width()
+    {
+        return $this->_width;
+    }
+
+    /**
+     * @return float|mixed
+     */
+    public function get_height()
+    {
+        return $this->_height;
+    }
+
+    /**
+     * @return int
+     */
+    public function get_page_number()
+    {
+        return $this->_page_number;
+    }
+
+    /**
+     * @return int
+     */
+    public function get_page_count()
+    {
+        return $this->_page_count;
+    }
+
+    /**
+     * @param $num
+     */
+    public function set_page_number($num)
+    {
+        $this->_page_number = (int)$num;
+    }
+
+    /**
+     * @param int $count
+     */
+    public function set_page_count($count)
+    {
+        $this->_page_count = (int)$count;
+    }
+
+    /**
+     * Sets the line style
+     *
+     * @param float  $width
+     * @param        $cap
+     * @param string $join
+     * @param array  $dash
+     *
+     * @return void
+     */
+    protected function _set_line_style($width, $cap, $join, $dash)
+    {
+        if (!is_array($dash)) {
+            $dash = array();
+        }
+
+        if (count($dash) == 1) {
+            $dash[] = $dash[0];
+        }
+
+        if ($this->getPDFLibMajorVersion() >= 9) {
+            if (count($dash) > 1) {
+                $this->_pdf->set_graphics_option("dasharray={" . implode(" ", $dash) . "}");
+            } else {
+                $this->_pdf->set_graphics_option("dasharray=none");
+            }
+        } else {
+            if (count($dash) > 1) {
+                $this->_pdf->setdashpattern("dasharray={" . implode(" ", $dash) . "}");
+            } else {
+                $this->_pdf->setdash(0, 0);
+            }
+        }
+
+        switch ($join) {
+            case "miter":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linejoin=0');
+                } else {
+                    $this->_pdf->setlinejoin(0);
+                }
+                break;
+
+            case "round":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linejoin=1');
+                } else {
+                    $this->_pdf->setlinejoin(1);
+                }
+                break;
+
+            case "bevel":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linejoin=2');
+                } else {
+                    $this->_pdf->setlinejoin(2);
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        switch ($cap) {
+            case "butt":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linecap=0');
+                } else {
+                    $this->_pdf->setlinecap(0);
+                }
+                break;
+
+            case "round":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linecap=1');
+                } else {
+                    $this->_pdf->setlinecap(1);
+                }
+                break;
+
+            case "square":
+                if ($this->getPDFLibMajorVersion() >= 9) {
+                    $this->_pdf->set_graphics_option('linecap=2');
+                } else {
+                    $this->_pdf->setlinecap(2);
+                }
+                break;
+
+            default:
+                break;
+        }
+
+        $this->_pdf->setlinewidth($width);
+    }
+
+    /**
+     * Sets the line color
+     *
+     * @param array $color array(r,g,b)
+     */
+    protected function _set_stroke_color($color)
+    {
+        // TODO: we should check the current PDF stroke color
+        // instead of the cached value
+        if ($this->_last_stroke_color == $color) {
+            // FIXME: do nothing, this optimization is broken by the
+            // stroke being set as a side effect of other operations
+            //return;
+        }
+
+        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
+        if (isset($this->_current_opacity)) {
+            $alpha *= $this->_current_opacity;
+        }
+
+        $this->_last_stroke_color = $color;
+
+        if (isset($color[3])) {
+            $type = "cmyk";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], $color[2], $color[3]];
+        } elseif (isset($color[2])) {
+            $type = "rgb";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], $color[2], null];
+        } else {
+            $type = "gray";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], null, null];
+        }
+
+        $this->_set_stroke_opacity($alpha, "Normal");
+        $this->_pdf->setcolor("stroke", $type, $c1, $c2, $c3, $c4);
+    }
+
+    /**
+     * Sets the fill color
+     *
+     * @param array $color array(r,g,b)
+     */
+    protected function _set_fill_color($color)
+    {
+        // TODO: we should check the current PDF fill color
+        // instead of the cached value
+        if ($this->_last_fill_color == $color) {
+            // FIXME: do nothing, this optimization is broken by the
+            // fill being set as a side effect of other operations
+            //return;
+        }
+
+        $alpha = isset($color["alpha"]) ? $color["alpha"] : 1;
+        if (isset($this->_current_opacity)) {
+            $alpha *= $this->_current_opacity;
+        }
+
+        $this->_last_fill_color = $color;
+
+        if (isset($color[3])) {
+            $type = "cmyk";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], $color[2], $color[3]];
+        } elseif (isset($color[2])) {
+            $type = "rgb";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], $color[2], null];
+        } else {
+            $type = "gray";
+            list($c1, $c2, $c3, $c4) = [$color[0], $color[1], null, null];
+        }
+
+        $this->_set_fill_opacity($alpha, "Normal");
+        $this->_pdf->setcolor("fill", $type, $c1, $c2, $c3, $c4);
+    }
+
+    /**
+     * Sets the fill opacity
+     *
+     * @param $opacity
+     * @param $mode
+     */
+    public function _set_fill_opacity($opacity, $mode = "Normal")
+    {
+        if ($mode === "Normal" && is_null($opacity) === false) {
+            $this->_set_gstate("opacityfill=$opacity");
+        }
+    }
+
+    /**
+     * Sets the stroke opacity
+     *
+     * @param $opacity
+     * @param $mode
+     */
+    public function _set_stroke_opacity($opacity, $mode = "Normal")
+    {
+        if ($mode === "Normal" && is_null($opacity) === false) {
+            $this->_set_gstate("opacitystroke=$opacity");
+        }
+    }
+
+    /**
+     * Sets the opacity
+     *
+     * @param $opacity
+     * @param $mode
+     */
+    public function set_opacity($opacity, $mode = "Normal")
+    {
+        if ($mode === "Normal" && is_null($opacity) === false) {
+            $this->_set_gstate("opacityfill=$opacity opacitystroke=$opacity");
+            $this->_current_opacity = $opacity;
+        }
+    }
+
+    /**
+     * Sets the gstate
+     *
+     * @param $gstate_options
+     * @return int
+     */
+    public function _set_gstate($gstate_options)
+    {
+        if (($gstate = array_search($gstate_options, $this->_gstates)) === false) {
+            $gstate = $this->_pdf->create_gstate($gstate_options);
+            $this->_gstates[$gstate] = $gstate_options;
+        }
+
+        return $this->_pdf->set_gstate($gstate);
+    }
+
+    public function set_default_view($view, $options = [])
+    {
+        // TODO
+        // http://www.pdflib.com/fileadmin/pdflib/pdf/manuals/PDFlib-8.0.2-API-reference.pdf
+        /**
+         * fitheight Fit the page height to the window, with the x coordinate left at the left edge of the window.
+         * fitrect Fit the rectangle specified by left, bottom, right, and top to the window.
+         * fitvisible Fit the visible contents of the page (the ArtBox) to the window.
+         * fitvisibleheight Fit the visible contents of the page to the window with the x coordinate left at the left edge of the window.
+         * fitvisiblewidth Fit the visible contents of the page to the window with the y coordinate top at the top edge of the window.
+         * fitwidth Fit the page width to the window, with the y coordinate top at the top edge of the window.
+         * fitwindow Fit the complete page to the window.
+         * fixed
+         */
+        //$this->setPDFLibParameter("openaction", $view);
+    }
+
+    /**
+     * Loads a specific font and stores the corresponding descriptor.
+     *
+     * @param string $font
+     * @param string $encoding
+     * @param string $options
+     *
+     * @return int the font descriptor for the font
+     */
+    protected function _load_font($font, $encoding = null, $options = "")
+    {
+        // Fix for PDFLibs case-sensitive font names
+        $baseFont = basename($font);
+        $isNativeFont = false;
+        if (isset(self::$nativeFontsTpPDFLib[$baseFont])) {
+            $font = self::$nativeFontsTpPDFLib[$baseFont];
+            $isNativeFont = true;
+        }
+
+        // Check if the font is a native PDF font
+        // Embed non-native fonts
+        $test = strtolower($baseFont);
+        if (in_array($test, DOMPDF::$nativeFonts)) {
+            $font = basename($font);
+        } else {
+            // Embed non-native fonts
+            $options .= " embedding=true";
+        }
+
+        $options .= " autosubsetting=" . ($this->_dompdf->getOptions()->getIsFontSubsettingEnabled() === false ? "false" : "true");
+
+        if (is_null($encoding)) {
+            // Unicode encoding is only available for the commerical
+            // version of PDFlib and not PDFlib-Lite
+            if (strlen($this->_dompdf->getOptions()->getPdflibLicense()) > 0) {
+                $encoding = "unicode";
+            } else {
+                $encoding = "auto";
+            }
+        }
+
+        $key = "$font:$encoding:$options";
+        if (isset($this->_fonts[$key])) {
+            return $this->_fonts[$key];
+        }
+
+        // Native fonts are build in, just load it
+        if ($isNativeFont) {
+            $this->_fonts[$key] = $this->_pdf->load_font($font, $encoding, $options);
+
+            return $this->_fonts[$key];
+        }
+
+        $fontOutline = $this->getPDFLibParameter("FontOutline", 1);
+        if ($fontOutline === "" || $fontOutline <= 0) {
+            $families = $this->_dompdf->getFontMetrics()->getFontFamilies();
+            foreach ($families as $files) {
+                foreach ($files as $file) {
+                    $face = basename($file);
+                    $afm = null;
+
+                    if (isset($this->_fontsFiles[$face])) {
+                        continue;
+                    }
+
+                    // Prefer ttfs to afms
+                    if (file_exists("$file.ttf")) {
+                        $outline = "$file.ttf";
+                    } elseif (file_exists("$file.TTF")) {
+                        $outline = "$file.TTF";
+                    } elseif (file_exists("$file.pfb")) {
+                        $outline = "$file.pfb";
+                        if (file_exists("$file.afm")) {
+                            $afm = "$file.afm";
+                        }
+                    } elseif (file_exists("$file.PFB")) {
+                        $outline = "$file.PFB";
+                        if (file_exists("$file.AFM")) {
+                            $afm = "$file.AFM";
+                        }
+                    } else {
+                        continue;
+                    }
+
+                    $this->_fontsFiles[$face] = true;
+
+                    if ($this->getPDFLibMajorVersion() >= 9) {
+                        $this->setPDFLibParameter("FontOutline", '{' . "$face=$outline" . '}');
+                    } else {
+                        $this->setPDFLibParameter("FontOutline", "\{$face\}=\{$outline\}");
+                    }
+
+                    if (is_null($afm)) {
+                        continue;
+                    }
+                    if ($this->getPDFLibMajorVersion() >= 9) {
+                        $this->setPDFLibParameter("FontAFM", '{' . "$face=$afm" . '}');
+                    } else {
+                        $this->setPDFLibParameter("FontAFM", "\{$face\}=\{$afm\}");
+                    }
+                }
+            }
+        }
+
+        $this->_fonts[$key] = $this->_pdf->load_font($font, $encoding, $options);
+
+        return $this->_fonts[$key];
+    }
+
+    /**
+     * Remaps y coords from 4th to 1st quadrant
+     *
+     * @param float $y
+     * @return float
+     */
+    protected function y($y)
+    {
+        return $this->_height - $y;
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function line($x1, $y1, $x2, $y2, $color, $width, $style = null)
+    {
+        $this->_set_line_style($width, "butt", "", $style);
+        $this->_set_stroke_color($color);
+
+        $y1 = $this->y($y1);
+        $y2 = $this->y($y2);
+
+        $this->_pdf->moveto($x1, $y1);
+        $this->_pdf->lineto($x2, $y2);
+        $this->_pdf->stroke();
+
+        $this->_set_stroke_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * Draw line at the specified coordinates on every page.
+     *
+     * See {@link Style::munge_color()} for the format of the colour array.
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style optional
+     */
+    public function page_line($x1, $y1, $x2, $y2, $color, $width, $style = [])
+    {
+        $_t = 'line';
+        $this->_page_text[] = compact('_t', 'x1', 'y1', 'x2', 'y2', 'color', 'width', 'style');
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $r1
+     * @param float $r2
+     * @param float $astart
+     * @param float $aend
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    public function arc($x1, $y1, $r1, $r2, $astart, $aend, $color, $width, $style = [])
+    {
+        $this->_set_line_style($width, "butt", "", $style);
+        $this->_set_stroke_color($color);
+
+        $y1 = $this->y($y1);
+
+        $this->_pdf->arc($x1, $y1, $r1, $astart, $aend);
+        $this->_pdf->stroke();
+
+        $this->_set_stroke_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     * @param float $width
+     * @param null  $style
+     */
+    public function rectangle($x1, $y1, $w, $h, $color, $width, $style = null)
+    {
+        $this->_set_stroke_color($color);
+        $this->_set_line_style($width, "butt", "", $style);
+
+        $y1 = $this->y($y1) - $h;
+
+        $this->_pdf->rect($x1, $y1, $w, $h);
+        $this->_pdf->stroke();
+
+        $this->_set_stroke_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     */
+    public function filled_rectangle($x1, $y1, $w, $h, $color)
+    {
+        $this->_set_fill_color($color);
+
+        $y1 = $this->y($y1) - $h;
+
+        $this->_pdf->rect(floatval($x1), floatval($y1), floatval($w), floatval($h));
+        $this->_pdf->fill();
+
+        $this->_set_fill_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     */
+    public function clipping_rectangle($x1, $y1, $w, $h)
+    {
+        $this->_pdf->save();
+
+        $y1 = $this->y($y1) - $h;
+
+        $this->_pdf->rect(floatval($x1), floatval($y1), floatval($w), floatval($h));
+        $this->_pdf->clip();
+    }
+
+    /**
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param float $rTL
+     * @param float $rTR
+     * @param float $rBR
+     * @param float $rBL
+     */
+    public function clipping_roundrectangle($x1, $y1, $w, $h, $rTL, $rTR, $rBR, $rBL)
+    {
+        if ($this->getPDFLibMajorVersion() < 9) {
+            //TODO: add PDFLib7 support
+            $this->clipping_rectangle($x1, $y1, $w, $h);
+            return;
+        }
+
+        $this->_pdf->save();
+
+        // we use 0,0 for the base coordinates for the path points
+        // since we're drawing the path at the $x1,$y1 coordinates
+
+        $path = 0;
+        //start: left edge, top end
+        $path = $this->_pdf->add_path_point($path, 0, 0 - $rTL + $h, "move", "");
+        // line: left edge, bottom end
+        $path = $this->_pdf->add_path_point($path, 0, 0 + $rBL, "line", "");
+        // curve: bottom-left corner
+        $path = $this->_pdf->add_path_point($path, 0 + $rBL, 0, "elliptical", "radius=$rBL clockwise=false");
+        // line: bottom edge, left end
+        $path = $this->_pdf->add_path_point($path, 0 - $rBR + $w, 0, "line", "");
+        // curve: bottom-right corner
+        $path = $this->_pdf->add_path_point($path, 0 + $w, 0 + $rBR, "elliptical", "radius=$rBR clockwise=false");
+        // line: right edge, top end
+        $path = $this->_pdf->add_path_point($path, 0 + $w, 0 - $rTR + $h, "line", "");
+        // curve: top-right corner
+        $path = $this->_pdf->add_path_point($path, 0 - $rTR + $w, 0 +$h, "elliptical", "radius=$rTR clockwise=false");
+        // line: top edge, left end
+        $path = $this->_pdf->add_path_point($path, 0 + $rTL, 0 + $h, "line", "");
+        // curve: top-left corner
+        $path = $this->_pdf->add_path_point($path, 0, 0 - $rTL + $h, "elliptical", "radius=$rTL clockwise=false");
+        $this->_pdf->draw_path($path, $x1, $this->_height-$y1-$h, "clip=true");
+    }
+
+    /**
+     *
+     */
+    public function clipping_end()
+    {
+        $this->_pdf->restore();
+    }
+
+    /**
+     *
+     */
+    public function save()
+    {
+        $this->_pdf->save();
+    }
+
+    function restore()
+    {
+        $this->_pdf->restore();
+    }
+
+    /**
+     * @param $angle
+     * @param $x
+     * @param $y
+     */
+    public function rotate($angle, $x, $y)
+    {
+        $pdf = $this->_pdf;
+        $pdf->translate($x, $this->_height - $y);
+        $pdf->rotate(-$angle);
+        $pdf->translate(-$x, -$this->_height + $y);
+    }
+
+    /**
+     * @param $angle_x
+     * @param $angle_y
+     * @param $x
+     * @param $y
+     */
+    public function skew($angle_x, $angle_y, $x, $y)
+    {
+        $pdf = $this->_pdf;
+        $pdf->translate($x, $this->_height - $y);
+        $pdf->skew($angle_y, $angle_x); // Needs to be inverted
+        $pdf->translate(-$x, -$this->_height + $y);
+    }
+
+    /**
+     * @param $s_x
+     * @param $s_y
+     * @param $x
+     * @param $y
+     */
+    public function scale($s_x, $s_y, $x, $y)
+    {
+        $pdf = $this->_pdf;
+        $pdf->translate($x, $this->_height - $y);
+        $pdf->scale($s_x, $s_y);
+        $pdf->translate(-$x, -$this->_height + $y);
+    }
+
+    /**
+     * @param $t_x
+     * @param $t_y
+     */
+    public function translate($t_x, $t_y)
+    {
+        $this->_pdf->translate($t_x, -$t_y);
+    }
+
+    /**
+     * @param $a
+     * @param $b
+     * @param $c
+     * @param $d
+     * @param $e
+     * @param $f
+     */
+    public function transform($a, $b, $c, $d, $e, $f)
+    {
+        $this->_pdf->concat($a, $b, $c, $d, $e, $f);
+    }
+
+    /**
+     * @param array $points
+     * @param array $color
+     * @param null  $width
+     * @param null  $style
+     * @param bool  $fill
+     */
+    public function polygon($points, $color, $width = null, $style = null, $fill = false)
+    {
+        $this->_set_fill_color($color);
+        $this->_set_stroke_color($color);
+
+        if (!$fill && isset($width)) {
+            $this->_set_line_style($width, "square", "miter", $style);
+        }
+
+        $y = $this->y(array_pop($points));
+        $x = array_pop($points);
+        $this->_pdf->moveto($x, $y);
+
+        while (count($points) > 1) {
+            $y = $this->y(array_pop($points));
+            $x = array_pop($points);
+            $this->_pdf->lineto($x, $y);
+        }
+
+        if ($fill) {
+            $this->_pdf->fill();
+        } else {
+            $this->_pdf->closepath_stroke();
+        }
+
+        $this->_set_fill_opacity($this->_current_opacity, "Normal");
+        $this->_set_stroke_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param float $x
+     * @param float $y
+     * @param float $r
+     * @param array $color
+     * @param null  $width
+     * @param null  $style
+     * @param bool  $fill
+     */
+    public function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false)
+    {
+        $this->_set_fill_color($color);
+        $this->_set_stroke_color($color);
+
+        if (!$fill && isset($width)) {
+            $this->_set_line_style($width, "round", "round", $style);
+        }
+
+        $y = $this->y($y);
+
+        $this->_pdf->circle($x, $y, $r);
+
+        if ($fill) {
+            $this->_pdf->fill();
+        } else {
+            $this->_pdf->stroke();
+        }
+
+        $this->_set_fill_opacity($this->_current_opacity, "Normal");
+        $this->_set_stroke_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param string $img_url
+     * @param float  $x
+     * @param float  $y
+     * @param int    $w
+     * @param int    $h
+     * @param string $resolution
+     */
+    public function image($img_url, $x, $y, $w, $h, $resolution = "normal")
+    {
+        $w = (int)$w;
+        $h = (int)$h;
+
+        $img_type = Cache::detect_type($img_url, $this->get_dompdf()->getHttpContext());
+
+        if (!isset($this->_imgs[$img_url])) {
+            if (strtolower($img_type) === "svg") {
+                //FIXME: PDFLib loads SVG but returns error message "Function must not be called in 'page' scope"
+                $image_load_response = $this->_pdf->load_graphics($img_type, $img_url, "");
+            } else {
+                $image_load_response = $this->_pdf->load_image($img_type, $img_url, "");
+            }
+            if ($image_load_response === 0) {
+                //TODO: should do something with the error message
+                $error = $this->_pdf->get_errmsg();
+                return;
+            }
+            $this->_imgs[$img_url] = $image_load_response;
+        }
+
+        $img = $this->_imgs[$img_url];
+
+        $y = $this->y($y) - $h;
+        if (strtolower($img_type) === "svg") {
+            $this->_pdf->fit_graphics($img, $x, $y, 'boxsize={' . "$w $h" . '} fitmethod=entire');
+        } else {
+            $this->_pdf->fit_image($img, $x, $y, 'boxsize={' . "$w $h" . '} fitmethod=entire');
+        }
+    }
+
+    /**
+     * @param float  $x
+     * @param float  $y
+     * @param string $text
+     * @param string $font
+     * @param float  $size
+     * @param array  $color
+     * @param int    $word_spacing
+     * @param int    $char_spacing
+     * @param int    $angle
+     */
+    public function text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_spacing = 0, $char_spacing = 0, $angle = 0)
+    {
+        $fh = $this->_load_font($font);
+
+        $this->_pdf->setfont($fh, $size);
+        $this->_set_fill_color($color);
+
+        $y = $this->y($y) - $this->get_font_height($font, $size);
+
+        $word_spacing = (float)$word_spacing;
+        $char_spacing = (float)$char_spacing;
+        $angle = -(float)$angle;
+
+        $this->_pdf->fit_textline($text, $x, $y, "rotate=$angle wordspacing=$word_spacing charspacing=$char_spacing ");
+
+        $this->_set_fill_opacity($this->_current_opacity, "Normal");
+    }
+
+    /**
+     * @param string $code
+     */
+    public function javascript($code)
+    {
+        if (strlen($this->_dompdf->getOptions()->getPdflibLicense()) > 0) {
+            $this->_pdf->create_action("JavaScript", $code);
+        }
+    }
+
+    /**
+     * Add a named destination (similar to ... in html)
+     *
+     * @param string $anchorname The name of the named destination
+     */
+    public function add_named_dest($anchorname)
+    {
+        $this->_pdf->add_nameddest($anchorname, "");
+    }
+
+    /**
+     * Add a link to the pdf
+     *
+     * @param string $url    The url to link to
+     * @param float  $x      The x position of the link
+     * @param float  $y      The y position of the link
+     * @param float  $width  The width of the link
+     * @param float  $height The height of the link
+     */
+    public function add_link($url, $x, $y, $width, $height)
+    {
+        $y = $this->y($y) - $height;
+        if (strpos($url, '#') === 0) {
+            // Local link
+            $name = substr($url, 1);
+            if ($name) {
+                $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link',
+                    "contents={$url} destname=" . substr($url, 1) . " linewidth=0");
+            }
+        } else {
+            list($proto, $host, $path, $file) = Helpers::explode_url($url);
+
+            if ($proto == "" || $proto === "file://") {
+                return; // Local links are not allowed
+            }
+            $url = Helpers::build_url($proto, $host, $path, $file);
+            $url = '{' . rawurldecode($url) . '}';
+
+            $action = $this->_pdf->create_action("URI", "url=" . $url);
+            $this->_pdf->create_annotation($x, $y, $x + $width, $y + $height, 'Link', "contents={$url} action={activate=$action} linewidth=0");
+        }
+    }
+
+    /**
+     * @param string $text
+     * @param string $font
+     * @param float  $size
+     * @param int    $word_spacing
+     * @param int    $letter_spacing
+     * @return mixed
+     */
+    public function get_text_width($text, $font, $size, $word_spacing = 0, $letter_spacing = 0)
+    {
+        $fh = $this->_load_font($font);
+
+        // Determine the additional width due to extra spacing
+        $num_spaces = mb_substr_count($text, " ");
+        $delta = $word_spacing * $num_spaces;
+
+        if ($letter_spacing) {
+            $num_chars = mb_strlen($text);
+            $delta += ($num_chars - $num_spaces) * $letter_spacing;
+        }
+
+        return $this->_pdf->stringwidth($text, $fh, $size) + $delta;
+    }
+
+    /**
+     * @param string $font
+     * @param float  $size
+     * @return float
+     */
+    public function get_font_height($font, $size)
+    {
+        $fh = $this->_load_font($font);
+
+        $this->_pdf->setfont($fh, $size);
+
+        $asc = $this->_pdf->info_font($fh, "ascender", "fontsize=$size");
+        $desc = $this->_pdf->info_font($fh, "descender", "fontsize=$size");
+
+        // $desc is usually < 0,
+        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+
+        return (abs($asc) + abs($desc)) * $ratio;
+    }
+
+    /**
+     * @param string $font
+     * @param float  $size
+     * @return float
+     */
+    public function get_font_baseline($font, $size)
+    {
+        $ratio = $this->_dompdf->getOptions()->getFontHeightRatio();
+
+        return $this->get_font_height($font, $size) / $ratio * 1.1;
+    }
+
+    /**
+     * Writes text at the specified x and y coordinates on every page
+     *
+     * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
+     * with their current values.
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float  $x
+     * @param float  $y
+     * @param string $text       the text to write
+     * @param string $font       the font file to use
+     * @param float  $size       the font size, in points
+     * @param array  $color
+     * @param float  $word_space word spacing adjustment
+     * @param float  $char_space char spacing adjustment
+     * @param float  $angle      angle to write the text at, measured CW starting from the x-axis
+     */
+    public function page_text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0)
+    {
+        $_t = "text";
+        $this->_page_text[] = compact("_t", "x", "y", "text", "font", "size", "color", "word_space", "char_space", "angle");
+    }
+
+    //........................................................................
+
+    /**
+     * Processes a script on every page
+     *
+     * The variables $pdf, $PAGE_NUM, and $PAGE_COUNT are available.
+     *
+     * This function can be used to add page numbers to all pages
+     * after the first one, for example.
+     *
+     * @param string $code the script code
+     * @param string $type the language type for script
+     */
+    public function page_script($code, $type = "text/php")
+    {
+        $_t = "script";
+        $this->_page_text[] = compact("_t", "code", "type");
+    }
+
+    /**
+     *
+     */
+    public function new_page()
+    {
+        // Add objects to the current page
+        $this->_place_objects();
+
+        $this->_pdf->suspend_page("");
+        $this->_pdf->begin_page_ext($this->_width, $this->_height, "");
+        $this->_page_number = ++$this->_page_count;
+    }
+
+    /**
+     * Add text to each page after rendering is complete
+     */
+    protected function _add_page_text()
+    {
+        if (count($this->_page_text) === 0) {
+            return;
+        }
+
+        $eval = null;
+        $this->_pdf->suspend_page("");
+
+        for ($p = 1; $p <= $this->_page_count; $p++) {
+            $this->_pdf->resume_page("pagenumber=$p");
+
+            foreach ($this->_page_text as $pt) {
+                extract($pt);
+
+                switch ($_t) {
+                    case "text":
+                        $text = str_replace(["{PAGE_NUM}", "{PAGE_COUNT}"],
+                            [$p, $this->_page_count], $text);
+                        $this->text($x, $y, $text, $font, $size, $color, $word_space, $char_space, $angle);
+                        break;
+
+                    case "script":
+                        if (!$eval) {
+                            $eval = new PHPEvaluator($this);
+                        }
+                        $eval->evaluate($code, ['PAGE_NUM' => $p, 'PAGE_COUNT' => $this->_page_count]);
+                        break;
+
+                    case 'line':
+                        $this->line( $x1, $y1, $x2, $y2, $color, $width, $style );
+                        break;
+
+                }
+            }
+
+            $this->_pdf->suspend_page("");
+        }
+
+        $this->_pdf->resume_page("pagenumber=" . $this->_page_number);
+    }
+
+    /**
+     * Streams the PDF to the client.
+     *
+     * @param string $filename The filename to present to the client.
+     * @param array  $options  Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1).
+     * @throws Exception
+     */
+    public function stream($filename = "document.pdf", $options = [])
+    {
+        if (headers_sent()) {
+            die("Unable to stream pdf: headers already sent");
+        }
+
+        if (!isset($options["compress"])) {
+            $options["compress"] = true;
+        }
+        if (!isset($options["Attachment"])) {
+            $options["Attachment"] = true;
+        }
+
+        $this->_add_page_text();
+
+        if ($options["compress"]) {
+            $this->setPDFLibValue("compress", 6);
+        } else {
+            $this->setPDFLibValue("compress", 0);
+        }
+
+        $this->_close();
+
+        $data = "";
+
+        if (self::$IN_MEMORY) {
+            $data = $this->_pdf->get_buffer();
+            $size = mb_strlen($data, "8bit");
+        } else {
+            $size = filesize($this->_file);
+        }
+
+        header("Cache-Control: private");
+        header("Content-Type: application/pdf");
+        header("Content-Length: " . $size);
+
+        $filename = str_replace(["\n", "'"], "", basename($filename, ".pdf")) . ".pdf";
+        $attachment = $options["Attachment"] ? "attachment" : "inline";
+        header(Helpers::buildContentDispositionHeader($attachment, $filename));
+
+        if (self::$IN_MEMORY) {
+            echo $data;
+        } else {
+            // Chunked readfile()
+            $chunk = (1 << 21); // 2 MB
+            $fh = fopen($this->_file, "rb");
+            if (!$fh) {
+                throw new Exception("Unable to load temporary PDF file: " . $this->_file);
+            }
+
+            while (!feof($fh)) {
+                echo fread($fh, $chunk);
+            }
+            fclose($fh);
+
+            //debugpng
+            if ($this->_dompdf->getOptions()->getDebugPng()) {
+                print '[pdflib stream unlink ' . $this->_file . ']';
+            }
+            if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) {
+                unlink($this->_file);
+            }
+            $this->_file = null;
+            unset($this->_file);
+        }
+
+        flush();
+    }
+
+    /**
+     * Returns the PDF as a string.
+     *
+     * @param array $options Associative array: 'compress' => 1 or 0 (default 1).
+     * @return string
+     */
+    public function output($options = [])
+    {
+        if (!isset($options["compress"])) {
+            $options["compress"] = true;
+        }
+
+        $this->_add_page_text();
+
+        if ($options["compress"]) {
+            $this->setPDFLibValue("compress", 6);
+        } else {
+            $this->setPDFLibValue("compress", 0);
+        }
+
+        $this->_close();
+
+        if (self::$IN_MEMORY) {
+            $data = $this->_pdf->get_buffer();
+        } else {
+            $data = file_get_contents($this->_file);
+
+            //debugpng
+            if ($this->_dompdf->getOptions()->getDebugPng()) {
+                print '[pdflib output unlink ' . $this->_file . ']';
+            }
+            if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) {
+                unlink($this->_file);
+            }
+            $this->_file = null;
+            unset($this->_file);
+        }
+
+        return $data;
+    }
+
+    /**
+     * @param string $keyword
+     * @param string $optlist
+     * @return mixed
+     */
+    protected function getPDFLibParameter($keyword, $optlist = "")
+    {
+        if ($this->getPDFLibMajorVersion() >= 9) {
+            return $this->_pdf->get_option($keyword, "");
+        }
+
+        return $this->_pdf->get_parameter($keyword, $optlist);
+    }
+
+    /**
+     * @param string $keyword
+     * @param string $value
+     * @return mixed
+     */
+    protected function setPDFLibParameter($keyword, $value)
+    {
+        if ($this->getPDFLibMajorVersion() >= 9) {
+            return $this->_pdf->set_option($keyword . "=" . $value);
+        }
+
+        return $this->_pdf->set_parameter($keyword, $value);
+    }
+
+    /**
+     * @param string $keyword
+     * @param string $optlist
+     * @return mixed
+     */
+    protected function getPDFLibValue($keyword, $optlist = "")
+    {
+        if ($this->getPDFLibMajorVersion() >= 9) {
+            return $this->getPDFLibParameter($keyword, $optlist);
+        }
+
+        return $this->_pdf->get_value($keyword);
+    }
+
+    /**
+     * @param string $keyword
+     * @param string $value
+     * @return mixed
+     */
+    protected function setPDFLibValue($keyword, $value)
+    {
+        if ($this->getPDFLibMajorVersion() >= 9) {
+            return $this->setPDFLibParameter($keyword, $value);
+        }
+
+        return $this->_pdf->set_value($keyword, $value);
+    }
+
+    /**
+     * @return int
+     */
+    protected function getPDFLibMajorVersion()
+    {
+        if (is_null(self::$MAJOR_VERSION)) {
+            if (method_exists($this->_pdf, "get_option")) {
+                self::$MAJOR_VERSION = abs(intval($this->_pdf->get_option("major", "")));
+            } else {
+                self::$MAJOR_VERSION = abs(intval($this->_pdf->get_value("major", "")));
+            }
+        }
+
+        return self::$MAJOR_VERSION;
+    }
+}
+
+// Workaround for idiotic limitation on statics...
+PDFLib::$PAPER_SIZES = CPDF::$PAPER_SIZES;
diff --git a/vendor/dompdf/dompdf/src/Autoloader.php b/vendor/dompdf/dompdf/src/Autoloader.php
new file mode 100644
index 0000000..c6ade50
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/Autoloader.php
@@ -0,0 +1,42 @@
+
+ * @author  Fabien Ménager 
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+
+namespace Dompdf;
+
+/**
+ * Main rendering interface
+ *
+ * Currently {@link Dompdf\Adapter\CPDF}, {@link Dompdf\Adapter\PDFLib}, and {@link Dompdf\Adapter\GD}
+ * implement this interface.
+ *
+ * Implementations should measure x and y increasing to the left and down,
+ * respectively, with the origin in the top left corner.  Implementations
+ * are free to use a unit other than points for length, but I can't
+ * guarantee that the results will look any good.
+ *
+ * @package dompdf
+ */
+interface Canvas
+{
+    function __construct($paper = "letter", $orientation = "portrait", Dompdf $dompdf);
+
+    /**
+     * @return Dompdf
+     */
+    function get_dompdf();
+
+    /**
+     * Returns the current page number
+     *
+     * @return int
+     */
+    function get_page_number();
+
+    /**
+     * Returns the total number of pages
+     *
+     * @return int
+     */
+    function get_page_count();
+
+    /**
+     * Sets the total number of pages
+     *
+     * @param int $count
+     */
+    function set_page_count($count);
+
+    /**
+     * Draws a line from x1,y1 to x2,y2
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the format of the
+     * $style parameter (aka dash).
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $x2
+     * @param float $y2
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    function line($x1, $y1, $x2, $y2, $color, $width, $style = null);
+
+    /**
+     * Draws a rectangle at x1,y1 with width w and height h
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     */
+    function rectangle($x1, $y1, $w, $h, $color, $width, $style = null);
+
+    /**
+     * Draws a filled rectangle at x1,y1 with width w and height h
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param array $color
+     */
+    function filled_rectangle($x1, $y1, $w, $h, $color);
+
+    /**
+     * Starts a clipping rectangle at x1,y1 with width w and height h
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     */
+    function clipping_rectangle($x1, $y1, $w, $h);
+
+    /**
+     * Starts a rounded clipping rectangle at x1,y1 with width w and height h
+     *
+     * @param float $x1
+     * @param float $y1
+     * @param float $w
+     * @param float $h
+     * @param float $tl
+     * @param float $tr
+     * @param float $br
+     * @param float $bl
+     *
+     * @return
+     */
+    function clipping_roundrectangle($x1, $y1, $w, $h, $tl, $tr, $br, $bl);
+
+    /**
+     * Ends the last clipping shape
+     */
+    function clipping_end();
+
+    /**
+     * Writes text at the specified x and y coordinates on every page
+     *
+     * The strings '{PAGE_NUM}' and '{PAGE_COUNT}' are automatically replaced
+     * with their current values.
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float  $x
+     * @param float  $y
+     * @param string $text       the text to write
+     * @param string $font       the font file to use
+     * @param float  $size       the font size, in points
+     * @param array  $color
+     * @param float  $word_space word spacing adjustment
+     * @param float  $char_space char spacing adjustment
+     * @param float  $angle      angle to write the text at, measured CW starting from the x-axis
+     */
+    public function page_text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0);
+
+    /**
+     * Save current state
+     */
+    function save();
+
+    /**
+     * Restore last state
+     */
+    function restore();
+
+    /**
+     * Rotate
+     *
+     * @param float $angle angle in degrees for counter-clockwise rotation
+     * @param float $x     Origin abscissa
+     * @param float $y     Origin ordinate
+     */
+    function rotate($angle, $x, $y);
+
+    /**
+     * Skew
+     *
+     * @param float $angle_x
+     * @param float $angle_y
+     * @param float $x Origin abscissa
+     * @param float $y Origin ordinate
+     */
+    function skew($angle_x, $angle_y, $x, $y);
+
+    /**
+     * Scale
+     *
+     * @param float $s_x scaling factor for width as percent
+     * @param float $s_y scaling factor for height as percent
+     * @param float $x   Origin abscissa
+     * @param float $y   Origin ordinate
+     */
+    function scale($s_x, $s_y, $x, $y);
+
+    /**
+     * Translate
+     *
+     * @param float $t_x movement to the right
+     * @param float $t_y movement to the bottom
+     */
+    function translate($t_x, $t_y);
+
+    /**
+     * Transform
+     *
+     * @param $a
+     * @param $b
+     * @param $c
+     * @param $d
+     * @param $e
+     * @param $f
+     * @return
+     */
+    function transform($a, $b, $c, $d, $e, $f);
+
+    /**
+     * Draws a polygon
+     *
+     * The polygon is formed by joining all the points stored in the $points
+     * array.  $points has the following structure:
+     * 
+     * array(0 => x1,
+     *       1 => y1,
+     *       2 => x2,
+     *       3 => y2,
+     *       ...
+     *       );
+     * 
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param array $points
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     * @param bool $fill Fills the polygon if true
+     */
+    function polygon($points, $color, $width = null, $style = null, $fill = false);
+
+    /**
+     * Draws a circle at $x,$y with radius $r
+     *
+     * See {@link Style::munge_color()} for the format of the color array.
+     * See {@link Cpdf::setLineStyle()} for a description of the $style
+     * parameter (aka dash)
+     *
+     * @param float $x
+     * @param float $y
+     * @param float $r
+     * @param array $color
+     * @param float $width
+     * @param array $style
+     * @param bool $fill Fills the circle if true
+     */
+    function circle($x, $y, $r, $color, $width = null, $style = null, $fill = false);
+
+    /**
+     * Add an image to the pdf.
+     *
+     * The image is placed at the specified x and y coordinates with the
+     * given width and height.
+     *
+     * @param string $img_url the path to the image
+     * @param float $x x position
+     * @param float $y y position
+     * @param int $w width (in pixels)
+     * @param int $h height (in pixels)
+     * @param string $resolution The resolution of the image
+     */
+    function image($img_url, $x, $y, $w, $h, $resolution = "normal");
+
+    /**
+     * Add an arc to the PDF
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float $x X coordinate of the arc
+     * @param float $y Y coordinate of the arc
+     * @param float $r1 Radius 1
+     * @param float $r2 Radius 2
+     * @param float $astart Start angle in degrees
+     * @param float $aend End angle in degrees
+     * @param array $color Color
+     * @param float $width
+     * @param array $style
+     */
+    function arc($x, $y, $r1, $r2, $astart, $aend, $color, $width, $style = []);
+
+    /**
+     * Writes text at the specified x and y coordinates
+     * See {@link Style::munge_color()} for the format of the color array.
+     *
+     * @param float $x
+     * @param float $y
+     * @param string $text the text to write
+     * @param string $font the font file to use
+     * @param float $size the font size, in points
+     * @param array $color
+     * @param float $word_space word spacing adjustment
+     * @param float $char_space char spacing adjustment
+     * @param float $angle angle
+     */
+    function text($x, $y, $text, $font, $size, $color = [0, 0, 0], $word_space = 0.0, $char_space = 0.0, $angle = 0.0);
+
+    /**
+     * Add a named destination (similar to ... in html)
+     *
+     * @param string $anchorname The name of the named destination
+     */
+    function add_named_dest($anchorname);
+
+    /**
+     * Add a link to the pdf
+     *
+     * @param string $url The url to link to
+     * @param float $x The x position of the link
+     * @param float $y The y position of the link
+     * @param float $width The width of the link
+     * @param float $height The height of the link
+     */
+    function add_link($url, $x, $y, $width, $height);
+
+    /**
+     * Add meta information to the pdf
+     *
+     * @param string $name Label of the value (Creator, Producer, etc.)
+     * @param string $value The text to set
+     */
+    function add_info($name, $value);
+
+    /**
+     * Calculates text size, in points
+     *
+     * @param string $text the text to be sized
+     * @param string $font the desired font
+     * @param float $size the desired font size
+     * @param float $word_spacing word spacing, if any
+     * @param float $char_spacing
+     *
+     * @return float
+     */
+    function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0);
+
+    /**
+     * Calculates font height, in points
+     *
+     * @param string $font
+     * @param float $size
+     *
+     * @return float
+     */
+    function get_font_height($font, $size);
+
+    /**
+     * Calculates font baseline, in points
+     *
+     * @param string $font
+     * @param float $size
+     *
+     * @return float
+     */
+    function get_font_baseline($font, $size);
+
+    /**
+     * Returns the PDF's width in points
+     *
+     * @return float
+     */
+    function get_width();
+
+
+    /**
+     * Return the image's height in pixels
+     *
+     * @return float
+     */
+    function get_height();
+
+    /**
+     * Returns the font x-height, in points
+     *
+     * @param string $font
+     * @param float $size
+     *
+     * @return float
+     */
+    //function get_font_x_height($font, $size);
+
+    /**
+     * Sets the opacity
+     *
+     * @param float $opacity
+     * @param string $mode
+     */
+    function set_opacity($opacity, $mode = "Normal");
+
+    /**
+     * Sets the default view
+     *
+     * @param string $view
+     * 'XYZ'  left, top, zoom
+     * 'Fit'
+     * 'FitH' top
+     * 'FitV' left
+     * 'FitR' left,bottom,right
+     * 'FitB'
+     * 'FitBH' top
+     * 'FitBV' left
+     * @param array $options
+     *
+     * @return void
+     */
+    function set_default_view($view, $options = []);
+
+    /**
+     * @param string $script
+     *
+     * @return void
+     */
+    function javascript($script);
+
+    /**
+     * Starts a new page
+     *
+     * Subsequent drawing operations will appear on the new page.
+     */
+    function new_page();
+
+    /**
+     * Streams the PDF directly to the browser.
+     *
+     * @param string $filename The filename to present to the browser.
+     * @param array $options Associative array: 'compress' => 1 or 0 (default 1); 'Attachment' => 1 or 0 (default 1).
+     */
+    function stream($filename, $options = []);
+
+    /**
+     * Returns the PDF as a string.
+     *
+     * @param array $options Associative array: 'compress' => 1 or 0 (default 1).
+     * @return string
+     */
+    function output($options = []);
+}
diff --git a/vendor/dompdf/dompdf/src/CanvasFactory.php b/vendor/dompdf/dompdf/src/CanvasFactory.php
new file mode 100644
index 0000000..b2bf127
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/CanvasFactory.php
@@ -0,0 +1,59 @@
+
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+namespace Dompdf;
+
+/**
+ * Create canvas instances
+ *
+ * The canvas factory creates canvas instances based on the
+ * availability of rendering backends and config options.
+ *
+ * @package dompdf
+ */
+class CanvasFactory
+{
+    /**
+     * Constructor is private: this is a static class
+     */
+    private function __construct()
+    {
+    }
+
+    /**
+     * @param Dompdf $dompdf
+     * @param string|array $paper
+     * @param string $orientation
+     * @param string $class
+     *
+     * @return Canvas
+     */
+    static function get_instance(Dompdf $dompdf, $paper = null, $orientation = null, $class = null)
+    {
+        $backend = strtolower($dompdf->getOptions()->getPdfBackend());
+
+        if (isset($class) && class_exists($class, false)) {
+            $class .= "_Adapter";
+        } else {
+            if (($backend === "auto" || $backend === "pdflib") &&
+                class_exists("PDFLib", false)
+            ) {
+                $class = "Dompdf\\Adapter\\PDFLib";
+            }
+
+            else {
+                if ($backend === "gd" && extension_loaded('gd')) {
+                    $class = "Dompdf\\Adapter\\GD";
+                } else {
+                    $class = "Dompdf\\Adapter\\CPDF";
+                }
+            }
+        }
+
+        return new $class($paper, $orientation, $dompdf);
+    }
+}
diff --git a/vendor/dompdf/dompdf/src/Cellmap.php b/vendor/dompdf/dompdf/src/Cellmap.php
new file mode 100644
index 0000000..6fe9973
--- /dev/null
+++ b/vendor/dompdf/dompdf/src/Cellmap.php
@@ -0,0 +1,913 @@
+
+ * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
+ */
+namespace Dompdf;
+
+use Dompdf\FrameDecorator\Table as TableFrameDecorator;
+use Dompdf\FrameDecorator\TableCell as TableCellFrameDecorator;
+
+/**
+ * Maps table cells to the table grid.
+ *
+ * This class resolves borders in tables with collapsed borders and helps
+ * place row & column spanned table cells.
+ *
+ * @package dompdf
+ */
+class Cellmap
+{
+    /**
+     * Border style weight lookup for collapsed border resolution.
+     *
+     * @var array
+     */
+    protected static $_BORDER_STYLE_SCORE = [
+        "inset"  => 1,
+        "groove" => 2,
+        "outset" => 3,
+        "ridge"  => 4,
+        "dotted" => 5,
+        "dashed" => 6,
+        "solid"  => 7,
+        "double" => 8,
+        "hidden" => 9,
+        "none"   => 0,
+    ];
+
+    /**
+     * The table object this cellmap is attached to.
+     *
+     * @var TableFrameDecorator
+     */
+    protected $_table;
+
+    /**
+     * The total number of rows in the table
+     *
+     * @var int
+     */
+    protected $_num_rows;
+
+    /**
+     * The total number of columns in the table
+     *
+     * @var int
+     */
+    protected $_num_cols;
+
+    /**
+     * 2D array mapping  to frames
+     *
+     * @var Frame[][]
+     */
+    protected $_cells;
+
+    /**
+     * 1D array of column dimensions
+     *
+     * @var array
+     */
+    protected $_columns;
+
+    /**
+     * 1D array of row dimensions
+     *
+     * @var array
+     */
+    protected $_rows;
+
+    /**
+     * 2D array of border specs
+     *
+     * @var array
+     */
+    protected $_borders;
+
+    /**
+     * 1D Array mapping frames to (multiple)  pairs, keyed on frame_id.
+     *
+     * @var Frame[]
+     */
+    protected $_frames;
+
+    /**
+     * Current column when adding cells, 0-based
+     *
+     * @var int
+     */
+    private $__col;
+
+    /**
+     * Current row when adding cells, 0-based
+     *
+     * @var int
+     */
+    private $__row;
+
+    /**
+     * Tells whether the columns' width can be modified
+     *
+     * @var bool
+     */
+    private $_columns_locked = false;
+
+    /**
+     * Tells whether the table has table-layout:fixed
+     *
+     * @var bool
+     */
+    private $_fixed_layout = false;
+
+    /**
+     * @param TableFrameDecorator $table
+     */
+    public function __construct(TableFrameDecorator $table)
+    {
+        $this->_table = $table;
+        $this->reset();
+    }
+
+    /**
+     *
+     */
+    public function reset()
+    {
+        $this->_num_rows = 0;
+        $this->_num_cols = 0;
+
+        $this->_cells = [];
+        $this->_frames = [];
+
+        if (!$this->_columns_locked) {
+            $this->_columns = [];
+        }
+
+        $this->_rows = [];
+
+        $this->_borders = [];
+
+        $this->__col = $this->__row = 0;
+    }
+
+    /**
+     *
+     */
+    public function lock_columns()
+    {
+        $this->_columns_locked = true;
+    }
+
+    /**
+     * @return bool
+     */
+    public function is_columns_locked()
+    {
+        return $this->_columns_locked;
+    }
+
+    /**
+     * @param $fixed
+     */
+    public function set_layout_fixed($fixed)
+    {
+        $this->_fixed_layout = $fixed;
+    }
+
+    /**
+     * @return bool
+     */
+    public function is_layout_fixed()
+    {
+        return $this->_fixed_layout;
+    }
+
+    /**
+     * @return int
+     */
+    public function get_num_rows()
+    {
+        return $this->_num_rows;
+    }
+
+    /**
+     * @return int
+     */
+    public function get_num_cols()
+    {
+        return $this->_num_cols;
+    }
+
+    /**
+     * @return array
+     */
+    public function &get_columns()
+    {
+        return $this->_columns;
+    }
+
+    /**
+     * @param $columns
+     */
+    public function set_columns($columns)
+    {
+        $this->_columns = $columns;
+    }
+
+    /**
+     * @param int $i
+     *
+     * @return mixed
+     */
+    public function &get_column($i)
+    {
+        if (!isset($this->_columns[$i])) {
+            $this->_columns[$i] = [
+                "x"          => 0,
+                "min-width"  => 0,
+                "max-width"  => 0,
+                "used-width" => null,
+                "absolute"   => 0,
+                "percent"    => 0,
+                "auto"       => true,
+            ];
+        }
+
+        return $this->_columns[$i];
+    }
+
+    /**
+     * @return array
+     */
+    public function &get_rows()
+    {
+        return $this->_rows;
+    }
+
+    /**
+     * @param int $j
+     *
+     * @return mixed
+     */
+    public function &get_row($j)
+    {
+        if (!isset($this->_rows[$j])) {
+            $this->_rows[$j] = [
+                "y"            => 0,
+                "first-column" => 0,
+                "height"       => null,
+            ];
+        }
+
+        return $this->_rows[$j];
+    }
+
+    /**
+     * @param int $i
+     * @param int $j
+     * @param mixed $h_v
+     * @param null|mixed $prop
+     *
+     * @return mixed
+     */
+    public function get_border($i, $j, $h_v, $prop = null)
+    {
+        if (!isset($this->_borders[$i][$j][$h_v])) {
+            $this->_borders[$i][$j][$h_v] = [
+                "width" => 0,
+                "style" => "solid",
+                "color" => "black",
+            ];
+        }
+
+        if (isset($prop)) {
+            return $this->_borders[$i][$j][$h_v][$prop];
+        }
+
+        return $this->_borders[$i][$j][$h_v];
+    }
+
+    /**
+     * @param int $i
+     * @param int $j
+     *
+     * @return array
+     */
+    public function get_border_properties($i, $j)
+    {
+        return [
+            "top"    => $this->get_border($i, $j, "horizontal"),
+            "right"  => $this->get_border($i, $j + 1, "vertical"),
+            "bottom" => $this->get_border($i + 1, $j, "horizontal"),
+            "left"   => $this->get_border($i, $j, "vertical"),
+        ];
+    }
+
+    /**
+     * @param Frame $frame
+     *
+     * @return null|Frame
+     */
+    public function get_spanned_cells(Frame $frame)
+    {
+        $key = $frame->get_id();
+
+        if (isset($this->_frames[$key])) {
+            return $this->_frames[$key];
+        }
+
+        return null;
+    }
+
+    /**
+     * @param Frame $frame
+     *
+     * @return bool
+     */
+    public function frame_exists_in_cellmap(Frame $frame)
+    {
+        $key = $frame->get_id();
+
+        return isset($this->_frames[$key]);
+    }
+
+    /**
+     * @param Frame $frame
+     *
+     * @return array
+     * @throws Exception
+     */
+    public function get_frame_position(Frame $frame)
+    {
+        global $_dompdf_warnings;
+
+        $key = $frame->get_id();
+
+        if (!isset($this->_frames[$key])) {
+            throw new Exception("Frame not found in cellmap");
+        }
+
+        $col = $this->_frames[$key]["columns"][0];
+        $row = $this->_frames[$key]["rows"][0];
+
+        if (!isset($this->_columns[$col])) {
+            $_dompdf_warnings[] = "Frame not found in columns array.  Check your table layout for missing or extra TDs.";
+            $x = 0;
+        } else {
+            $x = $this->_columns[$col]["x"];
+        }
+
+        if (!isset($this->_rows[$row])) {
+            $_dompdf_warnings[] = "Frame not found in row array.  Check your table layout for missing or extra TDs.";
+            $y = 0;
+        } else {
+            $y = $this->_rows[$row]["y"];
+        }
+
+        return [$x, $y, "x" => $x, "y" => $y];
+    }
+
+    /**
+     * @param Frame $frame
+     *
+     * @return int
+     * @throws Exception
+     */
+    public function get_frame_width(Frame $frame)
+    {
+        $key = $frame->get_id();
+
+        if (!isset($this->_frames[$key])) {
+            throw new Exception("Frame not found in cellmap");
+        }
+
+        $cols = $this->_frames[$key]["columns"];
+        $w = 0;
+        foreach ($cols as $i) {
+            $w += $this->_columns[$i]["used-width"];
+        }
+
+        return $w;
+    }
+
+    /**
+     * @param Frame $frame
+     *
+     * @return int
+     * @throws Exception
+     * @throws Exception
+     */
+    public function get_frame_height(Frame $frame)
+    {
+        $key = $frame->get_id();
+
+        if (!isset($this->_frames[$key])) {
+            throw new Exception("Frame not found in cellmap");
+        }
+
+        $rows = $this->_frames[$key]["rows"];
+        $h = 0;
+        foreach ($rows as $i) {
+            if (!isset($this->_rows[$i])) {
+                throw new Exception("The row #$i could not be found, please file an issue in the tracker with the HTML code");
+            }
+
+            $h += $this->_rows[$i]["height"];
+        }
+
+        return $h;
+    }
+
+    /**
+     * @param int $j
+     * @param mixed $width
+     */
+    public function set_column_width($j, $width)
+    {
+        if ($this->_columns_locked) {
+            return;
+        }
+
+        $col =& $this->get_column($j);
+        $col["used-width"] = $width;
+        $next_col =& $this->get_column($j + 1);
+        $next_col["x"] = $next_col["x"] + $width;
+    }
+
+    /**
+     * @param int $i
+     * @param mixed $height
+     */
+    public function set_row_height($i, $height)
+    {
+        $row =& $this->get_row($i);
+
+        if ($row["height"] !== null && $height <= $row["height"]) {
+            return;
+        }
+
+        $row["height"] = $height;
+        $next_row =& $this->get_row($i + 1);
+        $next_row["y"] = $row["y"] + $height;
+    }
+
+    /**
+     * @param int $i
+     * @param int $j
+     * @param mixed $h_v
+     * @param mixed $border_spec
+     *
+     * @return mixed
+     */
+    protected function _resolve_border($i, $j, $h_v, $border_spec)
+    {
+        $n_width = $border_spec["width"];
+        $n_style = $border_spec["style"];
+
+        if (!isset($this->_borders[$i][$j][$h_v])) {
+            $this->_borders[$i][$j][$h_v] = $border_spec;
+
+            return $this->_borders[$i][$j][$h_v]["width"];
+        }
+
+        $border = & $this->_borders[$i][$j][$h_v];
+
+        $o_width = $border["width"];
+        $o_style = $border["style"];
+
+        if (($n_style === "hidden" ||
+                $n_width > $o_width ||
+                $o_style === "none")
+
+            or
+
+            ($o_width == $n_width &&
+                in_array($n_style, self::$_BORDER_STYLE_SCORE) &&
+                self::$_BORDER_STYLE_SCORE[$n_style] > self::$_BORDER_STYLE_SCORE[$o_style])
+        ) {
+            $border = $border_spec;
+        }
+
+        return $border["width"];
+    }
+
+    /**
+     * @param Frame $frame
+     */
+    public function add_frame(Frame $frame)
+    {
+        $style = $frame->get_style();
+        $display = $style->display;
+
+        $collapse = $this->_table->get_style()->border_collapse == "collapse";
+
+        // Recursively add the frames within tables, table-row-groups and table-rows
+        if ($display === "table-row" ||
+            $display === "table" ||
+            $display === "inline-table" ||
+            in_array($display, TableFrameDecorator::$ROW_GROUPS)
+        ) {
+            $start_row = $this->__row;
+            foreach ($frame->get_children() as $child) {
+                // Ignore all Text frames and :before/:after pseudo-selector elements.
+                if (!($child instanceof FrameDecorator\Text) && $child->get_node()->nodeName !== 'dompdf_generated') {
+                    $this->add_frame($child);
+                }
+            }
+
+            if ($display === "table-row") {
+                $this->add_row();
+            }
+
+            $num_rows = $this->__row - $start_row - 1;
+            $key = $frame->get_id();
+
+            // Row groups always span across the entire table
+            $this->_frames[$key]["columns"] = range(0, max(0, $this->_num_cols - 1));
+            $this->_frames[$key]["rows"] = range($start_row, max(0, $this->__row - 1));
+            $this->_frames[$key]["frame"] = $frame;
+
+            if ($display !== "table-row" && $collapse) {
+                $bp = $style->get_border_properties();
+
+                // Resolve the borders
+                for ($i = 0; $i < $num_rows + 1; $i++) {
+                    $this->_resolve_border($start_row + $i, 0, "vertical", $bp["left"]);
+                    $this->_resolve_border($start_row + $i, $this->_num_cols, "vertical", $bp["right"]);
+                }
+
+                for ($j = 0; $j < $this->_num_cols; $j++) {
+                    $this->_resolve_border($start_row, $j, "horizontal", $bp["top"]);
+                    $this->_resolve_border($this->__row, $j, "horizontal", $bp["bottom"]);
+                }
+            }
+            return;
+        }
+
+        $node = $frame->get_node();
+
+        // Determine where this cell is going
+        $colspan = $node->getAttribute("colspan");
+        $rowspan = $node->getAttribute("rowspan");
+
+        if (!$colspan) {
+            $colspan = 1;
+            $node->setAttribute("colspan", 1);
+        }
+
+        if (!$rowspan) {
+            $rowspan = 1;
+            $node->setAttribute("rowspan", 1);
+        }
+        $key = $frame->get_id();
+
+        $bp = $style->get_border_properties();
+
+
+        // Add the frame to the cellmap
+        $max_left = $max_right = 0;
+
+        // Find the next available column (fix by Ciro Mondueri)
+        $ac = $this->__col;
+        while (isset($this->_cells[$this->__row][$ac])) {
+            $ac++;
+        }
+
+        $this->__col = $ac;
+
+        // Rows:
+        for ($i = 0; $i < $rowspan; $i++) {
+            $row = $this->__row + $i;
+
+            $this->_frames[$key]["rows"][] = $row;
+
+            for ($j = 0; $j < $colspan; $j++) {
+                $this->_cells[$row][$this->__col + $j] = $frame;
+            }
+
+            if ($collapse) {
+                // Resolve vertical borders
+                $max_left = max($max_left, $this->_resolve_border($row, $this->__col, "vertical", $bp["left"]));
+                $max_right = max($max_right, $this->_resolve_border($row, $this->__col + $colspan, "vertical", $bp["right"]));
+            }
+        }
+
+        $max_top = $max_bottom = 0;
+
+        // Columns:
+        for ($j = 0; $j < $colspan; $j++) {
+            $col = $this->__col + $j;
+            $this->_frames[$key]["columns"][] = $col;
+
+            if ($collapse) {
+                // Resolve horizontal borders
+                $max_top = max($max_top, $this->_resolve_border($this->__row, $col, "horizontal", $bp["top"]));
+                $max_bottom = max($max_bottom, $this->_resolve_border($this->__row + $rowspan, $col, "horizontal", $bp["bottom"]));
+            }
+        }
+
+        $this->_frames[$key]["frame"] = $frame;
+
+        // Handle seperated border model
+        if (!$collapse) {
+            list($h, $v) = $this->_table->get_style()->border_spacing;
+
+            // Border spacing is effectively a margin between cells
+            $v = $style->length_in_pt($v);
+            if (is_numeric($v)) {
+                $v = $v / 2;
+            }
+            $h = $style->length_in_pt($h);
+            if (is_numeric($h)) {
+                $h = $h / 2;
+            }
+            $style->margin = "$v $h";
+
+            // The additional 1/2 width gets added to the table proper
+        } else {
+            // Drop the frame's actual border
+            $style->border_left_width = $max_left / 2;
+            $style->border_right_width = $max_right / 2;
+            $style->border_top_width = $max_top / 2;
+            $style->border_bottom_width = $max_bottom / 2;
+            $style->margin = "none";
+        }
+
+        if (!$this->_columns_locked) {
+            // Resolve the frame's width
+            if ($this->_fixed_layout) {
+                list($frame_min, $frame_max) = [0, 10e-10];
+            } else {
+                list($frame_min, $frame_max) = $frame->get_min_max_width();
+            }
+
+            $width = $style->width;
+
+            $val = null;
+            if (Helpers::is_percent($width)) {
+                $var = "percent";
+                $val = (float)rtrim($width, "% ") / $colspan;
+            } else if ($width !== "auto") {
+                $var = "absolute";
+                $val = $style->length_in_pt($frame_min) / $colspan;
+            }
+
+            $min = 0;
+            $max = 0;
+            for ($cs = 0; $cs < $colspan; $cs++) {
+
+                // Resolve the frame's width(s) with other cells
+                $col =& $this->get_column($this->__col + $cs);
+
+                // Note: $var is either 'percent' or 'absolute'.  We compare the
+                // requested percentage or absolute values with the existing widths
+                // and adjust accordingly.
+                if (isset($var) && $val > $col[$var]) {
+                    $col[$var] = $val;
+                    $col["auto"] = false;
+                }
+
+                $min += $col["min-width"];
+                $max += $col["max-width"];
+            }
+
+            if ($frame_min > $min) {
+                // The frame needs more space.  Expand each sub-column
+                // FIXME try to avoid putting this dummy value when table-layout:fixed
+                $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_min - $min) / $colspan);
+                for ($c = 0; $c < $colspan; $c++) {
+                    $col =& $this->get_column($this->__col + $c);
+                    $col["min-width"] += $inc;
+                }
+            }
+
+            if ($frame_max > $max) {
+                // FIXME try to avoid putting this dummy value when table-layout:fixed
+                $inc = ($this->is_layout_fixed() ? 10e-10 : ($frame_max - $max) / $colspan);
+                for ($c = 0; $c < $colspan; $c++) {
+                    $col =& $this->get_column($this->__col + $c);
+                    $col["max-width"] += $inc;
+                }
+            }
+        }
+
+        $this->__col += $colspan;
+        if ($this->__col > $this->_num_cols) {
+            $this->_num_cols = $this->__col;
+        }
+    }
+
+    /**
+     *
+     */
+    public function add_row()
+    {
+        $this->__row++;
+        $this->_num_rows++;
+
+        // Find the next available column
+        $i = 0;
+        while (isset($this->_cells[$this->__row][$i])) {
+            $i++;
+        }
+
+        $this->__col = $i;
+    }
+
+    /**
+     * Remove a row from the cellmap.
+     *
+     * @param Frame
+     */
+    public function remove_row(Frame $row)
+    {
+        $key = $row->get_id();
+        if (!isset($this->_frames[$key])) {
+            return; // Presumably this row has alredy been removed
+        }
+
+        $this->__row = $this->_num_rows--;
+
+        $rows = $this->_frames[$key]["rows"];
+        $columns = $this->_frames[$key]["columns"];
+
+        // Remove all frames from this row
+        foreach ($rows as $r) {
+            foreach ($columns as $c) {
+                if (isset($this->_cells[$r][$c])) {
+                    $id = $this->_cells[$r][$c]->get_id();
+
+                    $this->_cells[$r][$c] = null;
+                    unset($this->_cells[$r][$c]);
+
+                    // has multiple rows?
+                    if (isset($this->_frames[$id]) && count($this->_frames[$id]["rows"]) > 1) {
+                        // remove just the desired row, but leave the frame
+                        if (($row_key = array_search($r, $this->_frames[$id]["rows"])) !== false) {
+                            unset($this->_frames[$id]["rows"][$row_key]);
+                        }
+                        continue;
+                    }
+
+                    $this->_frames[$id] = null;
+                    unset($this->_frames[$id]);
+                }
+            }
+
+            $this->_rows[$r] = null;
+            unset($this->_rows[$r]);
+        }
+
+        $this->_frames[$key] = null;
+        unset($this->_frames[$key]);
+    }
+
+    /**
+     * Remove a row group from the cellmap.
+     *
+     * @param Frame $group The group to remove
+     */
+    public function remove_row_group(Frame $group)
+    {
+        $key = $group->get_id();
+        if (!isset($this->_frames[$key])) {
+            return; // Presumably this row has alredy been removed
+        }
+
+        $iter = $group->get_first_child();
+        while ($iter) {
+            $this->remove_row($iter);
+            $iter = $iter->get_next_sibling();
+        }
+
+        $this->_frames[$key] = null;
+        unset($this->_frames[$key]);
+    }
+
+    /**
+     * Update a row group after rows have been removed
+     *
+     * @param Frame $group    The group to update
+     * @param Frame $last_row The last row in the row group
+     */
+    public function update_row_group(Frame $group, Frame $last_row)
+    {
+        $g_key = $group->get_id();
+        $r_key = $last_row->get_id();
+
+        $r_rows = $this->_frames[$g_key]["rows"];
+        $this->_frames[$g_key]["rows"] = range($this->_frames[$g_key]["rows"][0], end($r_rows));
+    }
+
+    /**
+     *
+     */
+    public function assign_x_positions()
+    {
+        // Pre-condition: widths must be resolved and assigned to columns and
+        // column[0]["x"] must be set.
+
+        if ($this->_columns_locked) {
+            return;
+        }
+
+        $x = $this->_columns[0]["x"];
+        foreach (array_keys($this->_columns) as $j) {
+            $this->_columns[$j]["x"] = $x;
+            $x += $this->_columns[$j]["used-width"];
+        }
+    }
+
+    /**
+     *
+     */
+    public function assign_frame_heights()
+    {
+        // Pre-condition: widths and heights of each column & row must be
+        // calcluated
+        foreach ($this->_frames as $arr) {
+            $frame = $arr["frame"];
+
+            $h = 0;
+            foreach ($arr["rows"] as $row) {
+                if (!isset($this->_rows[$row])) {
+                    // The row has been removed because of a page split, so skip it.
+                    continue;
+                }
+
+                $h += $this->_rows[$row]["height"];
+            }
+
+            if ($frame instanceof TableCellFrameDecorator) {
+                $frame->set_cell_height($h);
+            } else {
+                $frame->get_style()->height = $h;
+            }
+        }
+    }
+
+    /**
+     * Re-adjust frame height if the table height is larger than its content
+     */
+    public function set_frame_heights($table_height, $content_height)
+    {
+        // Distribute the increased height proportionally amongst each row
+        foreach ($this->_frames as $arr) {
+            $frame = $arr["frame"];
+
+            $h = 0;
+            foreach ($arr["rows"] as $row) {
+                if (!isset($this->_rows[$row])) {
+                    continue;
+                }
+
+                $h += $this->_rows[$row]["height"];
+            }
+
+            if ($content_height > 0) {
+                $new_height = ($h / $content_height) * $table_height;
+            } else {
+                $new_height = 0;
+            }
+
+            if ($frame instanceof TableCellFrameDecorator) {
+                $frame->set_cell_height($new_height);
+            } else {
+                $frame->get_style()->height = $new_height;
+            }
+        }
+    }
+
+    /**
+     * Used for debugging:
+     *
+     * @return string
+     */
+    public function __toString()
+    {
+        $str = "";
+        $str .= "Columns:
"; + $str .= Helpers::pre_r($this->_columns, true); + $str .= "Rows:
"; + $str .= Helpers::pre_r($this->_rows, true); + + $str .= "Frames:
"; + $arr = []; + foreach ($this->_frames as $key => $val) { + $arr[$key] = ["columns" => $val["columns"], "rows" => $val["rows"]]; + } + + $str .= Helpers::pre_r($arr, true); + + if (php_sapi_name() == "cli") { + $str = strip_tags(str_replace(["
", "", ""], + ["\n", chr(27) . "[01;33m", chr(27) . "[0m"], + $str)); + } + + return $str; + } +} diff --git a/vendor/dompdf/dompdf/src/Css/AttributeTranslator.php b/vendor/dompdf/dompdf/src/Css/AttributeTranslator.php new file mode 100644 index 0000000..eeae5e6 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Css/AttributeTranslator.php @@ -0,0 +1,638 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Css; + +use Dompdf\Frame; + +/** + * Translates HTML 4.0 attributes into CSS rules + * + * @package dompdf + */ +class AttributeTranslator +{ + static $_style_attr = "_html_style_attribute"; + + // Munged data originally from + // http://www.w3.org/TR/REC-html40/index/attributes.html + // http://www.cs.tut.fi/~jkorpela/html2css.html + private static $__ATTRIBUTE_LOOKUP = [ + //'caption' => array ( 'align' => '', ), + 'img' => [ + 'align' => [ + 'bottom' => 'vertical-align: baseline;', + 'middle' => 'vertical-align: middle;', + 'top' => 'vertical-align: top;', + 'left' => 'float: left;', + 'right' => 'float: right;' + ], + 'border' => 'border: %0.2Fpx solid;', + 'height' => 'height: %spx;', + 'hspace' => 'padding-left: %1$0.2Fpx; padding-right: %1$0.2Fpx;', + 'vspace' => 'padding-top: %1$0.2Fpx; padding-bottom: %1$0.2Fpx;', + 'width' => 'width: %spx;', + ], + 'table' => [ + 'align' => [ + 'left' => 'margin-left: 0; margin-right: auto;', + 'center' => 'margin-left: auto; margin-right: auto;', + 'right' => 'margin-left: auto; margin-right: 0;' + ], + 'bgcolor' => 'background-color: %s;', + 'border' => '!set_table_border', + 'cellpadding' => '!set_table_cellpadding', //'border-spacing: %0.2F; border-collapse: separate;', + 'cellspacing' => '!set_table_cellspacing', + 'frame' => [ + 'void' => 'border-style: none;', + 'above' => 'border-top-style: solid;', + 'below' => 'border-bottom-style: solid;', + 'hsides' => 'border-left-style: solid; border-right-style: solid;', + 'vsides' => 'border-top-style: solid; border-bottom-style: solid;', + 'lhs' => 'border-left-style: solid;', + 'rhs' => 'border-right-style: solid;', + 'box' => 'border-style: solid;', + 'border' => 'border-style: solid;' + ], + 'rules' => '!set_table_rules', + 'width' => 'width: %s;', + ], + 'hr' => [ + 'align' => '!set_hr_align', // Need to grab width to set 'left' & 'right' correctly + 'noshade' => 'border-style: solid;', + 'size' => '!set_hr_size', //'border-width: %0.2F px;', + 'width' => 'width: %s;', + ], + 'div' => [ + 'align' => 'text-align: %s;', + ], + 'h1' => [ + 'align' => 'text-align: %s;', + ], + 'h2' => [ + 'align' => 'text-align: %s;', + ], + 'h3' => [ + 'align' => 'text-align: %s;', + ], + 'h4' => [ + 'align' => 'text-align: %s;', + ], + 'h5' => [ + 'align' => 'text-align: %s;', + ], + 'h6' => [ + 'align' => 'text-align: %s;', + ], + //TODO: translate more form element attributes + 'input' => [ + 'size' => '!set_input_width' + ], + 'p' => [ + 'align' => 'text-align: %s;', + ], +// 'col' => array( +// 'align' => '', +// 'valign' => '', +// ), +// 'colgroup' => array( +// 'align' => '', +// 'valign' => '', +// ), + 'tbody' => [ + 'align' => '!set_table_row_align', + 'valign' => '!set_table_row_valign', + ], + 'td' => [ + 'align' => 'text-align: %s;', + 'bgcolor' => '!set_background_color', + 'height' => 'height: %s;', + 'nowrap' => 'white-space: nowrap;', + 'valign' => 'vertical-align: %s;', + 'width' => 'width: %s;', + ], + 'tfoot' => [ + 'align' => '!set_table_row_align', + 'valign' => '!set_table_row_valign', + ], + 'th' => [ + 'align' => 'text-align: %s;', + 'bgcolor' => '!set_background_color', + 'height' => 'height: %s;', + 'nowrap' => 'white-space: nowrap;', + 'valign' => 'vertical-align: %s;', + 'width' => 'width: %s;', + ], + 'thead' => [ + 'align' => '!set_table_row_align', + 'valign' => '!set_table_row_valign', + ], + 'tr' => [ + 'align' => '!set_table_row_align', + 'bgcolor' => '!set_table_row_bgcolor', + 'valign' => '!set_table_row_valign', + ], + 'body' => [ + 'background' => 'background-image: url(%s);', + 'bgcolor' => '!set_background_color', + 'link' => '!set_body_link', + 'text' => '!set_color', + ], + 'br' => [ + 'clear' => 'clear: %s;', + ], + 'basefont' => [ + 'color' => '!set_color', + 'face' => 'font-family: %s;', + 'size' => '!set_basefont_size', + ], + 'font' => [ + 'color' => '!set_color', + 'face' => 'font-family: %s;', + 'size' => '!set_font_size', + ], + 'dir' => [ + 'compact' => 'margin: 0.5em 0;', + ], + 'dl' => [ + 'compact' => 'margin: 0.5em 0;', + ], + 'menu' => [ + 'compact' => 'margin: 0.5em 0;', + ], + 'ol' => [ + 'compact' => 'margin: 0.5em 0;', + 'start' => 'counter-reset: -dompdf-default-counter %d;', + 'type' => 'list-style-type: %s;', + ], + 'ul' => [ + 'compact' => 'margin: 0.5em 0;', + 'type' => 'list-style-type: %s;', + ], + 'li' => [ + 'type' => 'list-style-type: %s;', + 'value' => 'counter-reset: -dompdf-default-counter %d;', + ], + 'pre' => [ + 'width' => 'width: %s;', + ], + ]; + + protected static $_last_basefont_size = 3; + protected static $_font_size_lookup = [ + // For basefont support + -3 => "4pt", + -2 => "5pt", + -1 => "6pt", + 0 => "7pt", + + 1 => "8pt", + 2 => "10pt", + 3 => "12pt", + 4 => "14pt", + 5 => "18pt", + 6 => "24pt", + 7 => "34pt", + + // For basefont support + 8 => "48pt", + 9 => "44pt", + 10 => "52pt", + 11 => "60pt", + ]; + + /** + * @param Frame $frame + */ + static function translate_attributes(Frame $frame) + { + $node = $frame->get_node(); + $tag = $node->nodeName; + + if (!isset(self::$__ATTRIBUTE_LOOKUP[$tag])) { + return; + } + + $valid_attrs = self::$__ATTRIBUTE_LOOKUP[$tag]; + $attrs = $node->attributes; + $style = rtrim($node->getAttribute(self::$_style_attr), "; "); + if ($style != "") { + $style .= ";"; + } + + foreach ($attrs as $attr => $attr_node) { + if (!isset($valid_attrs[$attr])) { + continue; + } + + $value = $attr_node->value; + + $target = $valid_attrs[$attr]; + + // Look up $value in $target, if $target is an array: + if (is_array($target)) { + if (isset($target[$value])) { + $style .= " " . self::_resolve_target($node, $target[$value], $value); + } + } else { + // otherwise use target directly + $style .= " " . self::_resolve_target($node, $target, $value); + } + } + + if (!is_null($style)) { + $style = ltrim($style); + $node->setAttribute(self::$_style_attr, $style); + } + } + + /** + * @param \DOMNode $node + * @param string $target + * @param string $value + * + * @return string + */ + protected static function _resolve_target(\DOMNode $node, $target, $value) + { + if ($target[0] === "!") { + // Function call + $func = "_" . mb_substr($target, 1); + + return self::$func($node, $value); + } + + return $value ? sprintf($target, $value) : ""; + } + + /** + * @param \DOMElement $node + * @param string $new_style + */ + static function append_style(\DOMElement $node, $new_style) + { + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + $style .= $new_style; + $style = ltrim($style, ";"); + $node->setAttribute(self::$_style_attr, $style); + } + + /** + * @param \DOMNode $node + * + * @return \DOMNodeList|\DOMElement[] + */ + protected static function get_cell_list(\DOMNode $node) + { + $xpath = new \DOMXpath($node->ownerDocument); + + switch ($node->nodeName) { + default: + case "table": + $query = "tr/td | thead/tr/td | tbody/tr/td | tfoot/tr/td | tr/th | thead/tr/th | tbody/tr/th | tfoot/tr/th"; + break; + + case "tbody": + case "tfoot": + case "thead": + $query = "tr/td | tr/th"; + break; + + case "tr": + $query = "td | th"; + break; + } + + return $xpath->query($query, $node); + } + + /** + * @param string $value + * + * @return string + */ + protected static function _get_valid_color($value) + { + if (preg_match('/^#?([0-9A-F]{6})$/i', $value, $matches)) { + $value = "#$matches[1]"; + } + + return $value; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_color(\DOMElement $node, $value) + { + $value = self::_get_valid_color($value); + + return "color: $value;"; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_background_color(\DOMElement $node, $value) + { + $value = self::_get_valid_color($value); + + return "background-color: $value;"; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_table_cellpadding(\DOMElement $node, $value) + { + $cell_list = self::get_cell_list($node); + + foreach ($cell_list as $cell) { + self::append_style($cell, "; padding: {$value}px;"); + } + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_table_border(\DOMElement $node, $value) + { + $cell_list = self::get_cell_list($node); + + foreach ($cell_list as $cell) { + $style = rtrim($cell->getAttribute(self::$_style_attr)); + $style .= "; border-width: " . ($value > 0 ? 1 : 0) . "pt; border-style: inset;"; + $style = ltrim($style, ";"); + $cell->setAttribute(self::$_style_attr, $style); + } + + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + $style .= "; border-width: $value" . "px; "; + + return ltrim($style, "; "); + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_table_cellspacing(\DOMElement $node, $value) + { + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + + if ($value == 0) { + $style .= "; border-collapse: collapse;"; + } else { + $style .= "; border-spacing: {$value}px; border-collapse: separate;"; + } + + return ltrim($style, ";"); + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null|string + */ + protected static function _set_table_rules(\DOMElement $node, $value) + { + $new_style = "; border-collapse: collapse;"; + + switch ($value) { + case "none": + $new_style .= "border-style: none;"; + break; + + case "groups": + // FIXME: unsupported + return null; + + case "rows": + $new_style .= "border-style: solid none solid none; border-width: 1px; "; + break; + + case "cols": + $new_style .= "border-style: none solid none solid; border-width: 1px; "; + break; + + case "all": + $new_style .= "border-style: solid; border-width: 1px; "; + break; + + default: + // Invalid value + return null; + } + + $cell_list = self::get_cell_list($node); + + foreach ($cell_list as $cell) { + $style = $cell->getAttribute(self::$_style_attr); + $style .= $new_style; + $cell->setAttribute(self::$_style_attr, $style); + } + + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + $style .= "; border-collapse: collapse; "; + + return ltrim($style, "; "); + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_hr_size(\DOMElement $node, $value) + { + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + $style .= "; border-width: " . max(0, $value - 2) . "; "; + + return ltrim($style, "; "); + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null|string + */ + protected static function _set_hr_align(\DOMElement $node, $value) + { + $style = rtrim($node->getAttribute(self::$_style_attr), ";"); + $width = $node->getAttribute("width"); + + if ($width == "") { + $width = "100%"; + } + + $remainder = 100 - (double)rtrim($width, "% "); + + switch ($value) { + case "left": + $style .= "; margin-right: $remainder %;"; + break; + + case "right": + $style .= "; margin-left: $remainder %;"; + break; + + case "center": + $style .= "; margin-left: auto; margin-right: auto;"; + break; + + default: + return null; + } + + return ltrim($style, "; "); + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null|string + */ + protected static function _set_input_width(\DOMElement $node, $value) + { + if (empty($value)) { return null; } + + if ($node->hasAttribute("type") && in_array(strtolower($node->getAttribute("type")), ["text","password"])) { + return sprintf("width: %Fem", (((int)$value * .65)+2)); + } else { + return sprintf("width: %upx;", (int)$value); + } + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_table_row_align(\DOMElement $node, $value) + { + $cell_list = self::get_cell_list($node); + + foreach ($cell_list as $cell) { + self::append_style($cell, "; text-align: $value;"); + } + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_table_row_valign(\DOMElement $node, $value) + { + $cell_list = self::get_cell_list($node); + + foreach ($cell_list as $cell) { + self::append_style($cell, "; vertical-align: $value;"); + } + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_table_row_bgcolor(\DOMElement $node, $value) + { + $cell_list = self::get_cell_list($node); + $value = self::_get_valid_color($value); + + foreach ($cell_list as $cell) { + self::append_style($cell, "; background-color: $value;"); + } + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_body_link(\DOMElement $node, $value) + { + $a_list = $node->getElementsByTagName("a"); + $value = self::_get_valid_color($value); + + foreach ($a_list as $a) { + self::append_style($a, "; color: $value;"); + } + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return null + */ + protected static function _set_basefont_size(\DOMElement $node, $value) + { + // FIXME: ? we don't actually set the font size of anything here, just + // the base size for later modification by tags. + self::$_last_basefont_size = $value; + + return null; + } + + /** + * @param \DOMElement $node + * @param string $value + * + * @return string + */ + protected static function _set_font_size(\DOMElement $node, $value) + { + $style = $node->getAttribute(self::$_style_attr); + + if ($value[0] === "-" || $value[0] === "+") { + $value = self::$_last_basefont_size + (int)$value; + } + + if (isset(self::$_font_size_lookup[$value])) { + $style .= "; font-size: " . self::$_font_size_lookup[$value] . ";"; + } else { + $style .= "; font-size: $value;"; + } + + return ltrim($style, "; "); + } +} diff --git a/vendor/dompdf/dompdf/src/Css/Color.php b/vendor/dompdf/dompdf/src/Css/Color.php new file mode 100644 index 0000000..4591037 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Css/Color.php @@ -0,0 +1,319 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Css; + +use Dompdf\Helpers; + +class Color +{ + static $cssColorNames = [ + "aliceblue" => "F0F8FF", + "antiquewhite" => "FAEBD7", + "aqua" => "00FFFF", + "aquamarine" => "7FFFD4", + "azure" => "F0FFFF", + "beige" => "F5F5DC", + "bisque" => "FFE4C4", + "black" => "000000", + "blanchedalmond" => "FFEBCD", + "blue" => "0000FF", + "blueviolet" => "8A2BE2", + "brown" => "A52A2A", + "burlywood" => "DEB887", + "cadetblue" => "5F9EA0", + "chartreuse" => "7FFF00", + "chocolate" => "D2691E", + "coral" => "FF7F50", + "cornflowerblue" => "6495ED", + "cornsilk" => "FFF8DC", + "crimson" => "DC143C", + "cyan" => "00FFFF", + "darkblue" => "00008B", + "darkcyan" => "008B8B", + "darkgoldenrod" => "B8860B", + "darkgray" => "A9A9A9", + "darkgreen" => "006400", + "darkgrey" => "A9A9A9", + "darkkhaki" => "BDB76B", + "darkmagenta" => "8B008B", + "darkolivegreen" => "556B2F", + "darkorange" => "FF8C00", + "darkorchid" => "9932CC", + "darkred" => "8B0000", + "darksalmon" => "E9967A", + "darkseagreen" => "8FBC8F", + "darkslateblue" => "483D8B", + "darkslategray" => "2F4F4F", + "darkslategrey" => "2F4F4F", + "darkturquoise" => "00CED1", + "darkviolet" => "9400D3", + "deeppink" => "FF1493", + "deepskyblue" => "00BFFF", + "dimgray" => "696969", + "dimgrey" => "696969", + "dodgerblue" => "1E90FF", + "firebrick" => "B22222", + "floralwhite" => "FFFAF0", + "forestgreen" => "228B22", + "fuchsia" => "FF00FF", + "gainsboro" => "DCDCDC", + "ghostwhite" => "F8F8FF", + "gold" => "FFD700", + "goldenrod" => "DAA520", + "gray" => "808080", + "green" => "008000", + "greenyellow" => "ADFF2F", + "grey" => "808080", + "honeydew" => "F0FFF0", + "hotpink" => "FF69B4", + "indianred" => "CD5C5C", + "indigo" => "4B0082", + "ivory" => "FFFFF0", + "khaki" => "F0E68C", + "lavender" => "E6E6FA", + "lavenderblush" => "FFF0F5", + "lawngreen" => "7CFC00", + "lemonchiffon" => "FFFACD", + "lightblue" => "ADD8E6", + "lightcoral" => "F08080", + "lightcyan" => "E0FFFF", + "lightgoldenrodyellow" => "FAFAD2", + "lightgray" => "D3D3D3", + "lightgreen" => "90EE90", + "lightgrey" => "D3D3D3", + "lightpink" => "FFB6C1", + "lightsalmon" => "FFA07A", + "lightseagreen" => "20B2AA", + "lightskyblue" => "87CEFA", + "lightslategray" => "778899", + "lightslategrey" => "778899", + "lightsteelblue" => "B0C4DE", + "lightyellow" => "FFFFE0", + "lime" => "00FF00", + "limegreen" => "32CD32", + "linen" => "FAF0E6", + "magenta" => "FF00FF", + "maroon" => "800000", + "mediumaquamarine" => "66CDAA", + "mediumblue" => "0000CD", + "mediumorchid" => "BA55D3", + "mediumpurple" => "9370DB", + "mediumseagreen" => "3CB371", + "mediumslateblue" => "7B68EE", + "mediumspringgreen" => "00FA9A", + "mediumturquoise" => "48D1CC", + "mediumvioletred" => "C71585", + "midnightblue" => "191970", + "mintcream" => "F5FFFA", + "mistyrose" => "FFE4E1", + "moccasin" => "FFE4B5", + "navajowhite" => "FFDEAD", + "navy" => "000080", + "oldlace" => "FDF5E6", + "olive" => "808000", + "olivedrab" => "6B8E23", + "orange" => "FFA500", + "orangered" => "FF4500", + "orchid" => "DA70D6", + "palegoldenrod" => "EEE8AA", + "palegreen" => "98FB98", + "paleturquoise" => "AFEEEE", + "palevioletred" => "DB7093", + "papayawhip" => "FFEFD5", + "peachpuff" => "FFDAB9", + "peru" => "CD853F", + "pink" => "FFC0CB", + "plum" => "DDA0DD", + "powderblue" => "B0E0E6", + "purple" => "800080", + "red" => "FF0000", + "rosybrown" => "BC8F8F", + "royalblue" => "4169E1", + "saddlebrown" => "8B4513", + "salmon" => "FA8072", + "sandybrown" => "F4A460", + "seagreen" => "2E8B57", + "seashell" => "FFF5EE", + "sienna" => "A0522D", + "silver" => "C0C0C0", + "skyblue" => "87CEEB", + "slateblue" => "6A5ACD", + "slategray" => "708090", + "slategrey" => "708090", + "snow" => "FFFAFA", + "springgreen" => "00FF7F", + "steelblue" => "4682B4", + "tan" => "D2B48C", + "teal" => "008080", + "thistle" => "D8BFD8", + "tomato" => "FF6347", + "turquoise" => "40E0D0", + "violet" => "EE82EE", + "wheat" => "F5DEB3", + "white" => "FFFFFF", + "whitesmoke" => "F5F5F5", + "yellow" => "FFFF00", + "yellowgreen" => "9ACD32", + ]; + + /** + * @param $color + * @return array|mixed|null|string + */ + static function parse($color) + { + if ($color === null) { + return null; + } + + if (is_array($color)) { + // Assume the array has the right format... + // FIXME: should/could verify this. + return $color; + } + + static $cache = []; + + $color = strtolower($color); + + if (isset($cache[$color])) { + return $cache[$color]; + } + + if (in_array($color, ["transparent", "inherit"])) { + return $cache[$color] = $color; + } + + if (isset(self::$cssColorNames[$color])) { + return $cache[$color] = self::getArray(self::$cssColorNames[$color]); + } + + $length = mb_strlen($color); + + // #rgb format + if ($length == 4 && $color[0] === "#") { + return $cache[$color] = self::getArray($color[1] . $color[1] . $color[2] . $color[2] . $color[3] . $color[3]); + } // #rgba format + else if ($length == 5 && $color[0] === "#") { + $alpha = round(hexdec($color[4] . $color[4])/255, 2); + return $cache[$color] = self::getArray($color[1] . $color[1] . $color[2] . $color[2] . $color[3] . $color[3], $alpha); + } // #rrggbb format + else if ($length == 7 && $color[0] === "#") { + return $cache[$color] = self::getArray(mb_substr($color, 1, 6)); + } // #rrggbbaa format + else if ($length == 9 && $color[0] === "#") { + $alpha = round(hexdec(mb_substr($color, 7, 2))/255, 2); + return $cache[$color] = self::getArray(mb_substr($color, 1, 6), $alpha); + } // rgb( r,g,b ) / rgba( r,g,b,α ) format + else if (mb_strpos($color, "rgb") !== false) { + $i = mb_strpos($color, "("); + $j = mb_strpos($color, ")"); + + // Bad color value + if ($i === false || $j === false) { + return null; + } + + $triplet = explode(",", mb_substr($color, $i + 1, $j - $i - 1)); + + // alpha transparency + // FIXME: not currently using transparency + $alpha = 1.0; + if (count($triplet) == 4) { + $alpha = (trim(array_pop($triplet))); + if (Helpers::is_percent($alpha)) { + $alpha = round((float)$alpha / 100, 2); + } + $alpha = (float)$alpha; + // bad value, set to fully opaque + if ($alpha > 1.0 || $alpha < 0.0) { + $alpha = 1.0; + } + } + + if (count($triplet) != 3) { + return null; + } + + foreach (array_keys($triplet) as $c) { + $triplet[$c] = trim($triplet[$c]); + + if (Helpers::is_percent($triplet[$c])) { + $triplet[$c] = round((float)$triplet[$c] * 2.55); + } + } + + return $cache[$color] = self::getArray(vsprintf("%02X%02X%02X", $triplet), $alpha); + + } + + // cmyk( c,m,y,k ) format + // http://www.w3.org/TR/css3-gcpm/#cmyk-colors + else if (mb_strpos($color, "cmyk") !== false) { + $i = mb_strpos($color, "("); + $j = mb_strpos($color, ")"); + + // Bad color value + if ($i === false || $j === false) { + return null; + } + + $values = explode(",", mb_substr($color, $i + 1, $j - $i - 1)); + + if (count($values) != 4) { + return null; + } + + $values = array_map(function($c) { + return min(1.0, max(0.0, floatval(trim($c)))); + }, $values); + + return $cache[$color] = self::getArray($values); + } + + return self::getArray($color); + } + + /** + * @param $color + * @param float $alpha + * @return array + */ + static function getArray($color, $alpha = 1.0) + { + $c = [null, null, null, null, "alpha" => $alpha, "hex" => null]; + + if (is_array($color)) { + $c = $color; + $c["c"] = $c[0]; + $c["m"] = $c[1]; + $c["y"] = $c[2]; + $c["k"] = $c[3]; + $c["alpha"] = $alpha; + $c["hex"] = "cmyk($c[0],$c[1],$c[2],$c[3])"; + } else { + if (ctype_xdigit($color) === false || mb_strlen($color) !== 6) { + // invalid color value ... expected 6-character hex + return $c; + } + $c[0] = hexdec(mb_substr($color, 0, 2)) / 0xff; + $c[1] = hexdec(mb_substr($color, 2, 2)) / 0xff; + $c[2] = hexdec(mb_substr($color, 4, 2)) / 0xff; + $c["r"] = $c[0]; + $c["g"] = $c[1]; + $c["b"] = $c[2]; + $c["alpha"] = $alpha; + $c["hex"] = sprintf("#%s%02X", $color, round($alpha * 255)); + } + + return $c; + } +} diff --git a/vendor/dompdf/dompdf/src/Css/Style.php b/vendor/dompdf/dompdf/src/Css/Style.php new file mode 100644 index 0000000..e2fc6c1 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Css/Style.php @@ -0,0 +1,3372 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Css; + +use Dompdf\Adapter\CPDF; +use Dompdf\Exception; +use Dompdf\FontMetrics; +use Dompdf\Frame; +use Dompdf\Helpers; + +/** + * Represents CSS properties. + * + * The Style class is responsible for handling and storing CSS properties. + * It includes methods to resolve colors and lengths, as well as getters & + * setters for many CSS properites. + * + * Actual CSS parsing is performed in the {@link Stylesheet} class. + * + * @package dompdf + */ +class Style +{ + + const CSS_IDENTIFIER = "-?[_a-zA-Z]+[_a-zA-Z0-9-]*"; + const CSS_INTEGER = "-?\d+"; + + /** + * Default font size, in points. + * + * @var float + */ + static $default_font_size = 12; + + /** + * Default line height, as a fraction of the font size. + * + * @var float + */ + static $default_line_height = 1.2; + + /** + * Default "absolute" font sizes relative to the default font-size + * http://www.w3.org/TR/css3-fonts/#font-size-the-font-size-property + * @var array + */ + static $font_size_keywords = [ + "xx-small" => 0.6, // 3/5 + "x-small" => 0.75, // 3/4 + "small" => 0.889, // 8/9 + "medium" => 1, // 1 + "large" => 1.2, // 6/5 + "x-large" => 1.5, // 3/2 + "xx-large" => 2.0, // 2/1 + ]; + + /** + * List of valid text-align keywords. Should also really be a constant. + * + * @var array + */ + static $text_align_keywords = ["left", "right", "center", "justify"]; + + /** + * List of valid vertical-align keywords. Should also really be a constant. + * + * @var array + */ + static $vertical_align_keywords = ["baseline", "bottom", "middle", "sub", + "super", "text-bottom", "text-top", "top"]; + + /** + * List of all inline types. Should really be a constant. + * + * @var array + */ + static $INLINE_TYPES = ["inline"]; + + /** + * List of all block types. Should really be a constant. + * + * @var array + */ + static $BLOCK_TYPES = ["block", "inline-block", "table-cell", "list-item"]; + + /** + * List of all positionned types. Should really be a constant. + * + * @var array + */ + static $POSITIONNED_TYPES = ["relative", "absolute", "fixed"]; + + /** + * List of all table types. Should really be a constant. + * + * @var array; + */ + static $TABLE_TYPES = ["table", "inline-table"]; + + /** + * List of valid border styles. Should also really be a constant. + * + * @var array + */ + static $BORDER_STYLES = ["none", "hidden", "dotted", "dashed", "solid", + "double", "groove", "ridge", "inset", "outset"]; + + /** + * List of CSS shorthand properties + * + * @var array + */ + protected static $_props_shorthand = ["background", "border", + "border_bottom", "border_color", "border_left", "border_radius", + "border_right", "border_style", "border_top", "border_width", + "flex", "font", "list_style", "margin", "padding"]; + + /** + * Default style values. + * + * @link http://www.w3.org/TR/CSS21/propidx.html + * + * @var array + */ + protected static $_defaults = null; + + /** + * List of inherited properties + * + * @link http://www.w3.org/TR/CSS21/propidx.html + * + * @var array + */ + protected static $_inherited = null; + + /** + * Caches method_exists result + * + * @var array + */ + protected static $_methods_cache = []; + + /** + * The stylesheet this style belongs to + * + * @see Stylesheet + * @var Stylesheet + */ + protected $_stylesheet; // stylesheet this style is attached to + + /** + * Media queries attached to the style + * + * @var int + */ + protected $_media_queries; + + /** + * Main array of all CSS properties & values + * + * @var array + */ + protected $_props = []; + + /* var instead of protected would allow access outside of class */ + protected $_important_props = []; + + /** + * The computed values of the CSS property + * + * @var array + */ + protected $_props_computed = []; + + protected static $_dependency_map = [ + "border_top_style" => [ + "border_top_width" + ], + "border_bottom_style" => [ + "border_bottom_width" + ], + "border_left_style" => [ + "border_left_width" + ], + "border_right_style" => [ + "border_right_width" + ], + "direction" => [ + "text_align" + ], + "font_size" => [ + "background_position", + "background_size", + "border_top_width", + "border_right_width", + "border_bottom_width", + "border_left_width", + "line_height", + "margin_top", + "margin_right", + "margin_bottom", + "margin_left", + "outline_width", + "padding_top", + "padding_right", + "padding_bottom", + "padding_left" + ] + ]; + + /** + * The used values of the CSS property + * + * @var array + */ + protected $_prop_cache = []; + + /** + * Font size of parent element in document tree. Used for relative font + * size resolution. + * + * @var float + */ + protected $_parent_font_size; + + /** + * @var Frame + */ + protected $_frame; + + /** + * The origin of the style + * + * @var int + */ + protected $_origin = Stylesheet::ORIG_AUTHOR; + + // private members + /** + * The computed bottom spacing + */ + private $_computed_bottom_spacing = null; + + /** + * The computed border radius + */ + private $_computed_border_radius = null; + + /** + * @var bool + */ + public $_has_border_radius = false; + + /** + * @var FontMetrics + */ + private $fontMetrics; + + /** + * Class constructor + * + * @param Stylesheet $stylesheet the stylesheet this Style is associated with. + * @param int $origin + */ + public function __construct(Stylesheet $stylesheet, $origin = Stylesheet::ORIG_AUTHOR) + { + $this->setFontMetrics($stylesheet->getFontMetrics()); + + $this->_props = []; + $this->_important_props = []; + $this->_stylesheet = $stylesheet; + $this->_media_queries = []; + $this->_origin = $origin; + $this->_parent_font_size = null; + + if (!isset(self::$_defaults)) { + + // Shorthand + $d =& self::$_defaults; + + // All CSS 2.1 properties, and their default values + $d["azimuth"] = "center"; + $d["background_attachment"] = "scroll"; + $d["background_color"] = "transparent"; + $d["background_image"] = "none"; + $d["background_image_resolution"] = "normal"; + $d["background_position"] = "0% 0%"; + $d["background_repeat"] = "repeat"; + $d["background"] = ""; + $d["border_collapse"] = "separate"; + $d["border_color"] = ""; + $d["border_spacing"] = "0"; + $d["border_style"] = ""; + $d["border_top"] = ""; + $d["border_right"] = ""; + $d["border_bottom"] = ""; + $d["border_left"] = ""; + $d["border_top_color"] = ""; + $d["border_right_color"] = ""; + $d["border_bottom_color"] = ""; + $d["border_left_color"] = ""; + $d["border_top_style"] = "none"; + $d["border_right_style"] = "none"; + $d["border_bottom_style"] = "none"; + $d["border_left_style"] = "none"; + $d["border_top_width"] = "medium"; + $d["border_right_width"] = "medium"; + $d["border_bottom_width"] = "medium"; + $d["border_left_width"] = "medium"; + $d["border_width"] = "medium"; + $d["border_bottom_left_radius"] = ""; + $d["border_bottom_right_radius"] = ""; + $d["border_top_left_radius"] = ""; + $d["border_top_right_radius"] = ""; + $d["border_radius"] = ""; + $d["border"] = ""; + $d["bottom"] = "auto"; + $d["caption_side"] = "top"; + $d["clear"] = "none"; + $d["clip"] = "auto"; + $d["color"] = "#000000"; + $d["content"] = "normal"; + $d["counter_increment"] = "none"; + $d["counter_reset"] = "none"; + $d["cue_after"] = "none"; + $d["cue_before"] = "none"; + $d["cue"] = ""; + $d["cursor"] = "auto"; + $d["direction"] = "ltr"; + $d["display"] = "inline"; + $d["elevation"] = "level"; + $d["empty_cells"] = "show"; + $d["float"] = "none"; + $d["font_family"] = $stylesheet->get_dompdf()->getOptions()->getDefaultFont(); + $d["font_size"] = "medium"; + $d["font_style"] = "normal"; + $d["font_variant"] = "normal"; + $d["font_weight"] = "normal"; + $d["font"] = ""; + $d["height"] = "auto"; + $d["image_resolution"] = "normal"; + $d["left"] = "auto"; + $d["letter_spacing"] = "normal"; + $d["line_height"] = "normal"; + $d["list_style_image"] = "none"; + $d["list_style_position"] = "outside"; + $d["list_style_type"] = "disc"; + $d["list_style"] = ""; + $d["margin_right"] = "0"; + $d["margin_left"] = "0"; + $d["margin_top"] = "0"; + $d["margin_bottom"] = "0"; + $d["margin"] = ""; + $d["max_height"] = "none"; + $d["max_width"] = "none"; + $d["min_height"] = "0"; + $d["min_width"] = "0"; + $d["orphans"] = "2"; + $d["outline_color"] = ""; // "invert" special color is not supported + $d["outline_style"] = "none"; + $d["outline_width"] = "medium"; + $d["outline"] = ""; + $d["overflow"] = "visible"; + $d["padding_top"] = "0"; + $d["padding_right"] = "0"; + $d["padding_bottom"] = "0"; + $d["padding_left"] = "0"; + $d["padding"] = ""; + $d["page_break_after"] = "auto"; + $d["page_break_before"] = "auto"; + $d["page_break_inside"] = "auto"; + $d["pause_after"] = "0"; + $d["pause_before"] = "0"; + $d["pause"] = ""; + $d["pitch_range"] = "50"; + $d["pitch"] = "medium"; + $d["play_during"] = "auto"; + $d["position"] = "static"; + $d["quotes"] = ""; + $d["richness"] = "50"; + $d["right"] = "auto"; + $d["size"] = "auto"; // @page + $d["speak_header"] = "once"; + $d["speak_numeral"] = "continuous"; + $d["speak_punctuation"] = "none"; + $d["speak"] = "normal"; + $d["speech_rate"] = "medium"; + $d["stress"] = "50"; + $d["table_layout"] = "auto"; + $d["text_align"] = ""; + $d["text_decoration"] = "none"; + $d["text_indent"] = "0"; + $d["text_transform"] = "none"; + $d["top"] = "auto"; + $d["unicode_bidi"] = "normal"; + $d["vertical_align"] = "baseline"; + $d["visibility"] = "visible"; + $d["voice_family"] = ""; + $d["volume"] = "medium"; + $d["white_space"] = "normal"; + $d["word_wrap"] = "normal"; + $d["widows"] = "2"; + $d["width"] = "auto"; + $d["word_spacing"] = "normal"; + $d["z_index"] = "auto"; + + // CSS3 + $d["opacity"] = "1.0"; + $d["background_size"] = "auto auto"; + $d["transform"] = "none"; + $d["transform_origin"] = "50% 50%"; + + // for @font-face + $d["src"] = ""; + $d["unicode_range"] = ""; + + // vendor-previxed properties + $d["_dompdf_background_image_resolution"] = &$d["background_image_resolution"]; + $d["_dompdf_image_resolution"] = &$d["image_resolution"]; + $d["_dompdf_keep"] = ""; + $d["_webkit_transform"] = &$d["transform"]; + $d["_webkit_transform_origin"] = &$d["transform_origin"]; + + // Properties that inherit by default + self::$_inherited = [ + "azimuth", + "background_image_resolution", + "border_collapse", + "border_spacing", + "caption_side", + "color", + "cursor", + "direction", + "elevation", + "empty_cells", + "font_family", + "font_size", + "font_style", + "font_variant", + "font_weight", + "font", + "image_resolution", + "letter_spacing", + "line_height", + "list_style_image", + "list_style_position", + "list_style_type", + "list_style", + "orphans", + "page_break_inside", + "pitch_range", + "pitch", + "quotes", + "richness", + "speak_header", + "speak_numeral", + "speak_punctuation", + "speak", + "speech_rate", + "stress", + "text_align", + "text_indent", + "text_transform", + "visibility", + "voice_family", + "volume", + "white_space", + "word_wrap", + "widows", + "word_spacing", + ]; + } + } + + /** + * "Destructor": forcibly free all references held by this object + */ + function dispose() + { + } + + /** + * @param $media_queries + */ + function set_media_queries($media_queries) + { + $this->_media_queries = $media_queries; + } + + /** + * @return array|int + */ + function get_media_queries() + { + return $this->_media_queries; + } + + /** + * @param Frame $frame + */ + function set_frame(Frame $frame) + { + $this->_frame = $frame; + } + + /** + * @return Frame + */ + function get_frame() + { + return $this->_frame; + } + + /** + * @param $origin + */ + function set_origin($origin) + { + $this->_origin = $origin; + } + + /** + * @return int + */ + function get_origin() + { + return $this->_origin; + } + + /** + * returns the {@link Stylesheet} this Style is associated with. + * + * @return Stylesheet + */ + function get_stylesheet() + { + return $this->_stylesheet; + } + + /** + * Converts any CSS length value into an absolute length in points. + * + * length_in_pt() takes a single length (e.g. '1em') or an array of + * lengths and returns an absolute length. If an array is passed, then + * the return value is the sum of all elements. If any of the lengths + * provided are "auto" or "none" then that value is returned. + * + * If a reference size is not provided, the default font size is used + * ({@link Style::$default_font_size}). + * + * @param float|string|array $length the numeric length (or string measurement) or array of lengths to resolve + * @param float $ref_size an absolute reference size to resolve percentage lengths + * @return float|string + */ + function length_in_pt($length, $ref_size = null) + { + static $cache = []; + + if (!isset($ref_size)) { + $ref_size = $this->__get("font_size"); + } + + if (!is_array($length)) { + $key = $length . "/$ref_size"; + //Early check on cache, before converting $length to array + if (isset($cache[$key])) { + return $cache[$key]; + } + $length = [$length]; + } else { + $key = implode("@", $length) . "/$ref_size"; + if (isset($cache[$key])) { + return $cache[$key]; + } + } + + $ret = 0; + foreach ($length as $l) { + + if ($l === "auto") { + return "auto"; + } + + if ($l === "none") { + return "none"; + } + + // Assume numeric values are already in points + if (is_numeric($l)) { + $ret += $l; + continue; + } + + if ($l === "normal") { + $ret += (float)$ref_size; + continue; + } + + // Border lengths + if ($l === "thin") { + $ret += 0.5; + continue; + } + + if ($l === "medium") { + $ret += 1.5; + continue; + } + + if ($l === "thick") { + $ret += 2.5; + continue; + } + + if (($i = mb_stripos($l, "px")) !== false) { + $dpi = $this->_stylesheet->get_dompdf()->getOptions()->getDpi(); + $ret += ((float)mb_substr($l, 0, $i) * 72) / $dpi; + continue; + } + + if (($i = mb_stripos($l, "pt")) !== false) { + $ret += (float)mb_substr($l, 0, $i); + continue; + } + + if (($i = mb_stripos($l, "%")) !== false) { + $ret += (float)mb_substr($l, 0, $i) / 100 * (float)$ref_size; + continue; + } + + if (($i = mb_stripos($l, "rem")) !== false) { + if ($this->_stylesheet->get_dompdf()->getTree()->get_root()->get_style() === null) { + // Interpreting it as "em", see https://github.com/dompdf/dompdf/issues/1406 + $ret += (float)mb_substr($l, 0, $i) * $this->__get("font_size"); + } else { + $ret += (float)mb_substr($l, 0, $i) * $this->_stylesheet->get_dompdf()->getTree()->get_root()->get_style()->font_size; + } + continue; + } + + if (($i = mb_stripos($l, "em")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * $this->__get("font_size"); + continue; + } + + if (($i = mb_stripos($l, "cm")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * 72 / 2.54; + continue; + } + + if (($i = mb_stripos($l, "mm")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * 72 / 25.4; + continue; + } + + // FIXME: em:ex ratio? + if (($i = mb_stripos($l, "ex")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * $this->__get("font_size") / 2; + continue; + } + + if (($i = mb_stripos($l, "in")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * 72; + continue; + } + + if (($i = mb_stripos($l, "pc")) !== false) { + $ret += (float)mb_substr($l, 0, $i) * 12; + continue; + } + + // Bogus value + $ret += (float)$ref_size; + } + + return $cache[$key] = $ret; + } + + + /** + * Set inherited properties in this style using values in $parent + * + * @param Style $parent + * + * @return Style + */ + function inherit(Style $parent) + { + // Set parent font size, changes affect font size of the element + if ($this->_parent_font_size !== $parent->font_size) { + $this->_parent_font_size = $parent->font_size; + if (isset($this->_props["font_size"])) { + $this->__set("font_size", $this->_props["font_size"]); + } + } + + foreach (self::$_inherited as $prop) { + // don't inherit shorthand properties, the specific properties will inherit + if (in_array($prop, self::$_props_shorthand) === true) { + continue; + } + + //inherit the !important property also. + //if local property is also !important, don't inherit. + + if (isset($parent->_props_computed[$prop]) && + ( + !isset($this->_props[$prop]) + || (isset($parent->_important_props[$prop]) && !isset($this->_important_props[$prop])) + ) + ) { + if (isset($parent->_important_props[$prop])) { + $this->_important_props[$prop] = true; + } + if (isset($parent->_props_computed[$prop])) { + $this->__set($prop, $parent->_props_computed[$prop]); + } else { + // parent prop not set, use the default + $this->__set($prop, self::$_defaults[$prop]); + } + } + } + + foreach ($this->_props as $prop => $value) { + // don't inherit shorthand properties, the specific properties will inherit + if (in_array($prop, self::$_props_shorthand) === true) { + continue; + } + if ($value === "inherit") { + if (isset($parent->_important_props[$prop])) { + $this->_important_props[$prop] = true; + } + //do not assign direct, but + //implicite assignment through __set, redirect to specialized, get value with __get + //This is for computing defaults if the parent setting is also missing. + //Therefore do not directly assign the value without __set + //set _important_props before that to be able to propagate. + //see __set and __get, on all assignments clear cache! + //$this->_prop_cache[$prop] = null; + //$this->_props[$prop] = $parent->_props[$prop]; + //props_set for more obvious explicite assignment not implemented, because + //too many implicite uses. + // $this->props_set($prop, $parent->$prop); + if (isset($parent->_props_computed[$prop])) { + $this->__set($prop, $parent->_props_computed[$prop]); + } else { + // parent prop not set, use the default + $this->__set($prop, self::$_defaults[$prop]); + } + // set the specified prop back to "inherit" + $this->_props[$prop] = "inherit"; + } + } + + return $this; + } + + /** + * Override properties in this style with those in $style + * + * @param Style $style + */ + function merge(Style $style) + { + //treat the !important attribute + //if old rule has !important attribute, override with new rule only if + //the new rule is also !important + foreach ($style->_props as $prop => $val) { + $can_merge = false; + if (isset($style->_important_props[$prop])) { + $this->_important_props[$prop] = true; + $can_merge = true; + } else if (isset($val) && !isset($this->_important_props[$prop])) { + $can_merge = true; + } + + if ($can_merge) { + // Clear out "inherit" shorthand properties if a more specific property value has been set + $shorthands = array_filter(self::$_props_shorthand, function ($el) use ($prop) { + return (strpos($prop, $el . "_") !== false); + }); + foreach ($shorthands as $shorthand) { + if (array_key_exists($shorthand, $this->_props) && $this->_props[$shorthand] === "inherit") { + unset($this->_props[$shorthand]); + unset($this->_props_computed[$shorthand]); + unset($this->_prop_cache[$shorthand]); + } + } + $this->__set($prop, $val); + } + } + } + + /** + * Returns an array(r, g, b, "r"=> r, "g"=>g, "b"=>b, "hex"=>"#rrggbb") + * based on the provided CSS color value. + * + * @param string $color + * @return array + */ + function munge_color($color) + { + return Color::parse($color); + } + + /* direct access to _important_props array from outside would work only when declared as + * 'var $_important_props;' instead of 'protected $_important_props;' + * Don't call _set/__get on missing attribute. Therefore need a special access. + * Assume that __set will be also called when this is called, so do not check validity again. + * Only created, if !important exists -> always set true. + */ + function important_set($prop) + { + $prop = str_replace("-", "_", $prop); + $this->_important_props[$prop] = true; + } + + /** + * @param $prop + * @return bool + */ + function important_get($prop) + { + return isset($this->_important_props[$prop]); + } + + /** + * PHP5 overloaded setter + * + * This function along with {@link Style::__get()} permit a user of the + * Style class to access any (CSS) property using the following syntax: + * + * Style->margin_top = "1em"; + * echo (Style->margin_top); + * + * + * __set() automatically calls the provided set function, if one exists, + * otherwise it sets the property directly. Typically, __set() is not + * called directly from outside of this class. + * + * On each modification clear cache to return accurate setting. + * Also affects direct settings not using __set + * For easier finding all assignments, attempted to allowing only explicite assignment: + * Very many uses, e.g. AbstractFrameReflower.php -> for now leave as it is + * function __set($prop, $val) { + * throw new Exception("Implicit replacement of assignment by __set. Not good."); + * } + * function props_set($prop, $val) { ... } + * + * @param string $prop the property to set + * @param mixed $val the value of the property + * + */ + function __set($prop, $val) + { + $prop = str_replace("-", "_", $prop); + + if (!isset(self::$_defaults[$prop])) { + global $_dompdf_warnings; + $_dompdf_warnings[] = "'$prop' is not a recognized CSS property."; + return; + } + + if ($prop !== "content" && is_string($val) && strlen($val) > 5 && mb_strpos($val, "url") === false) { + $val = mb_strtolower(trim(str_replace(["\n", "\t"], [" "], $val))); + $val = preg_replace("/([0-9]+) (pt|px|pc|em|ex|in|cm|mm|%)/S", "\\1\\2", $val); + } + + $this->_props[$prop] = $val; + $this->_props_computed[$prop] = null; + $this->_prop_cache[$prop] = null; + + $method = "set_$prop"; + + if (!isset(self::$_methods_cache[$method])) { + self::$_methods_cache[$method] = method_exists($this, $method); + } + + if (self::$_methods_cache[$method]) { + $this->$method($val); + } + if (isset($this->_props_computed[$prop]) === false && isset($val) && $val !== '' && $val !== 'inherit') { + $this->_props_computed[$prop] = $val; + } + + if (isset($this->_props_computed[$prop])) { + //FIXME: need to catch for circular dependencies because oops + if (array_key_exists($prop, self::$_dependency_map)) { + foreach (self::$_dependency_map[$prop] as $dependent) { + if (isset($this->_props[$dependent]) === true) { + $this->__set($dependent, $this->_props[$dependent]); + } + } + } + } + } + + /** + * PHP5 overloaded getter + * Along with {@link Style::__set()} __get() provides access to all CSS + * properties directly. Typically __get() is not called directly outside + * of this class. + * On each modification clear cache to return accurate setting. + * Also affects direct settings not using __set + * + * @param string $prop + * + * @return mixed + * @throws Exception + */ + function __get($prop) + { + //FIXME: need to get shorthand from component properties + if (!isset(self::$_defaults[$prop])) { + throw new Exception("'$prop' is not a recognized CSS property."); + } + + if (isset($this->_prop_cache[$prop])) { + return $this->_prop_cache[$prop]; + } + + $method = "get_$prop"; + + $retval = null; + + // Preview the value based on the default if the property is not cached + // and the computed value has not yet been set. + $reset_value = false; + $specified_value = null; + $computed_value = null; + if (!isset($this->_prop_cache[$prop]) && !isset($this->_props_computed[$prop])) { + $reset_value = true; + if (isset($this->_props[$prop])) { + $specified_value = $this->_props[$prop]; + } + if (isset($this->_props_computed[$prop])) { + $computed_value = $this->_props_computed[$prop]; + } + if (empty($this->_props[$prop]) || $this->_props[$prop] === "inherit") { + $this->__set($prop, self::$_defaults[$prop]); + } + if (empty($this->_props_computed[$prop])) { + // computed value should be set if the property is set, we'll recalculate it + $this->__set($prop, $this->_props[$prop]); + } + } + + if (!isset(self::$_methods_cache[$method])) { + self::$_methods_cache[$method] = method_exists($this, $method); + } + + if (self::$_methods_cache[$method]) { + $retval = $this->_prop_cache[$prop] = $this->$method(); + } + + if (!isset($retval)) { + $retval = $this->_prop_cache[$prop] = $this->_props_computed[$prop]; + } + + // When previewing the value reset the specified and computed properties + // so that we don't interfere with inheritance. + if ($reset_value) { + $this->_props[$prop] = $specified_value; + $this->_props_computed[$prop] = $computed_value; + } + + return $retval; + } + + /** + * Sets the property value without calculating the computed value + * + * @param $prop + * @param $val + */ + function set_prop($prop, $val) + { + $prop = str_replace("-", "_", $prop); + + if (!isset(self::$_defaults[$prop])) { + global $_dompdf_warnings; + $_dompdf_warnings[] = "'$prop' is not a recognized CSS property."; + return; + } + + if ($prop !== "content" && is_string($val) && strlen($val) > 5 && mb_strpos($val, "url") === false) { + $val = mb_strtolower(trim(str_replace(["\n", "\t"], [" "], $val))); + $val = preg_replace("/([0-9]+) (pt|px|pc|em|ex|in|cm|mm|%)/S", "\\1\\2", $val); + } + + $this->_props[$prop] = $val; + $this->_props_computed[$prop] = null; + $this->_prop_cache[$prop] = null; + + //FIXME: this doesn't work for shorthand properties + } + + /** + * Similar to __get() without storing the result. Useful for accessing + * properties while loading stylesheets. + * + * @param $prop + * @return string + * @throws Exception + */ + function get_prop($prop) + { + if (!isset(self::$_defaults[$prop])) { + throw new Exception("'$prop' is not a recognized CSS property."); + } + + $method = "get_$prop"; + + // Fall back on defaults if property is not set + if (!isset($this->_props_computed[$prop])) { + return self::$_defaults[$prop]; + } + + if (method_exists($this, $method)) { + return $this->$method(); + } + + return $this->_props[$prop]; + } + + /** + * Calculates the computed value of the CSS properties that have been set (the specified properties) + */ + function compute_props() + { + foreach ($this->_props as $prop => $val) { + if (in_array($prop, self::$_props_shorthand) === false) { + $this->__set($prop, $val); + } + } + } + + /** + * @return float|null|string + */ + function computed_bottom_spacing() + { + if ($this->_computed_bottom_spacing !== null) { + return $this->_computed_bottom_spacing; + } + return $this->_computed_bottom_spacing = $this->length_in_pt( + [ + $this->margin_bottom, + $this->padding_bottom, + $this->border_bottom_width + ] + ); + } + + /** + * @return string + */ + function get_font_family_raw() + { + return trim($this->_props["font_family"], " \t\n\r\x0B\"'"); + } + + /** + * Getter for the 'font-family' CSS property. + * Uses the {@link FontMetrics} class to resolve the font family into an + * actual font file. + * + * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-family + * @throws Exception + * + * @return string + */ + function get_font_family() + { + //TODO: we should be using the calculated prop rather than perform the entire family parsing operation again + + $DEBUGCSS = $this->_stylesheet->get_dompdf()->getOptions()->getDebugCss(); + + // Select the appropriate font. First determine the subtype, then check + // the specified font-families for a candidate. + + // Resolve font-weight + $weight = $this->__get("font_weight"); + if ($weight === 'bold') { + $weight = 700; + } elseif (preg_match('/^[0-9]+$/', $weight, $match)) { + $weight = (int)$match[0]; + } else { + $weight = 400; + } + + // Resolve font-style + $font_style = $this->__get("font_style"); + $subtype = $this->getFontMetrics()->getType($weight . ' ' . $font_style); + + $families = preg_split("/\s*,\s*/", $this->_props_computed["font_family"]); + + $font = null; + foreach ($families as $family) { + //remove leading and trailing string delimiters, e.g. on font names with spaces; + //remove leading and trailing whitespace + $family = trim($family, " \t\n\r\x0B\"'"); + if ($DEBUGCSS) { + print '(' . $family . ')'; + } + $font = $this->getFontMetrics()->getFont($family, $subtype); + + if ($font) { + if ($DEBUGCSS) { + print "
[get_font_family:";
+                    print '(' . $this->_props_computed["font_family"] . '.' . $font_style . '.' . $weight . '.' . $subtype . ')';
+                    print '(' . $font . ")get_font_family]\n
"; + } + return $font; + } + } + + $family = null; + if ($DEBUGCSS) { + print '(default)'; + } + $font = $this->getFontMetrics()->getFont($family, $subtype); + + if ($font) { + if ($DEBUGCSS) { + print '(' . $font . ")get_font_family]\n
"; + } + return $font; + } + + throw new Exception("Unable to find a suitable font replacement for: '" . $this->_props_computed["font_family"] . "'"); + } + + /** + * @link http://www.w3.org/TR/CSS21/text.html#propdef-word-spacing + * @return float + */ + function get_word_spacing() + { + $word_spacing = $this->_props_computed["word_spacing"]; + + if ($word_spacing === "normal") { + return 0; + } + + if (strpos($word_spacing, "%") !== false) { + return $word_spacing; + } + + return (float)$this->length_in_pt($word_spacing, $this->__get("font_size")); + } + + /** + * @link http://www.w3.org/TR/CSS21/text.html#propdef-letter-spacing + * @return float + */ + function get_letter_spacing() + { + $letter_spacing = $this->_props_computed["letter_spacing"]; + + if ($letter_spacing === "normal") { + return 0; + } + + return (float)$this->length_in_pt($letter_spacing, $this->__get("font_size")); + } + + /** + * @link http://www.w3.org/TR/CSS21/visudet.html#propdef-line-height + * @return float + */ + function get_line_height() + { + $line_height = $this->_props_computed["line_height"]; + + if ($line_height === "normal") { + return self::$default_line_height * $this->__get("font_size"); + } + + if (is_numeric($line_height)) { + return $line_height * $this->__get("font_size"); + } + + return (float)$this->length_in_pt($line_height, $this->__get("font_size")); + } + + /** + * Returns the color as an array + * + * The array has the following format: + * array(r,g,b, "r" => r, "g" => g, "b" => b, "hex" => "#rrggbb") + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color + * @return array + */ + function get_color() + { + return $this->munge_color($this->_props_computed["color"]); + } + + /** + * Returns the background color as an array + * + * The returned array has the same format as {@link Style::get_color()} + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color + * @return array + */ + function get_background_color() + { + return $this->munge_color($this->_props_computed["background_color"]); + } + + /** + * Returns the background image URI, or "none" + * + * @link https://www.w3.org/TR/CSS21/colors.html#propdef-background-image + * @return string + */ + function get_background_image() + { + return $this->_image($this->_props_computed["background_image"]); + } + + /** + * Returns the background position as an array + * + * The returned array has the following format: + * array(x,y, "x" => x, "y" => y) + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position + * @return array + */ + function get_background_position() + { + if (strpos($this->_props_computed["background_position"], " ") === false) { + $this->__set("background_position", $this->_props["background_position"]); + } + $tmp = explode(" ", $this->_props_computed["background_position"]); + + return [ + 0 => $tmp[0], "x" => $tmp[0], + 1 => $tmp[1], "y" => $tmp[1], + ]; + } + + + /** + * Returns the background size as an array + * + * The return value has one of the following formats: + * "cover" + * "contain" + * array(width,height) + * + * @link https://www.w3.org/TR/css3-background/#background-size + * @return string|array + */ + function get_background_size() + { + switch ($this->_props_computed["background_size"]) { + case "cover": + return "cover"; + case "contain": + return "contain"; + default: + break; + } + + if (strpos($this->_props_computed["background_size"], " ") === false) { + $this->__set("background_size", $this->_props["background_size"]); + } + $result = explode(" ", $this->_props_computed["background_size"]); + return [$result[0], $result[1]]; + } + + /**#@+ + * Returns the border color as an array + * + * See {@link Style::get_color()} + * + * @link http://www.w3.org/TR/CSS21/box.html#border-color-properties + * @return array + */ + function get_border_top_color() + { + return $this->munge_color($this->_props_computed["border_top_color"]); + } + + /** + * @return array + */ + function get_border_right_color() + { + return $this->munge_color($this->_props_computed["border_right_color"]); + } + + /** + * @return array + */ + function get_border_bottom_color() + { + return $this->munge_color($this->_props_computed["border_bottom_color"]); + } + + /** + * @return array + */ + function get_border_left_color() + { + return $this->munge_color($this->_props_computed["border_left_color"]); + } + + /**#@-*/ + + /** + * Return an array of all border properties. + * + * The returned array has the following structure: + * + * array("top" => array("width" => [border-width], + * "style" => [border-style], + * "color" => [border-color (array)]), + * "bottom" ... ) + * + * + * @return array + */ + function get_border_properties() + { + return [ + "top" => [ + "width" => $this->__get("border_top_width"), + "style" => $this->__get("border_top_style"), + "color" => $this->__get("border_top_color"), + ], + "bottom" => [ + "width" => $this->__get("border_bottom_width"), + "style" => $this->__get("border_bottom_style"), + "color" => $this->__get("border_bottom_color"), + ], + "right" => [ + "width" => $this->__get("border_right_width"), + "style" => $this->__get("border_right_style"), + "color" => $this->__get("border_right_color"), + ], + "left" => [ + "width" => $this->__get("border_left_width"), + "style" => $this->__get("border_left_style"), + "color" => $this->__get("border_left_color"), + ], + ]; + } + + /** + * Return a single border property + * + * @param string $side + * + * @return mixed + */ + protected function _get_border($side) + { + $color = $this->__get("border_" . $side . "_color"); + + return $this->__get("border_" . $side . "_width") . " " . + $this->__get("border_" . $side . "_style") . " " . $color["hex"]; + } + + /**#@+ + * Return full border properties as a string + * + * Border properties are returned just as specified in CSS: + *
[width] [style] [color]
+ * e.g. "1px solid blue" + * + * @link http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties + * @return string + */ + function get_border_top() + { + return $this->_get_border("top"); + } + + /** + * @return mixed + */ + function get_border_right() + { + return $this->_get_border("right"); + } + + /** + * @return mixed + */ + function get_border_bottom() + { + return $this->_get_border("bottom"); + } + + /** + * @return mixed + */ + function get_border_left() + { + return $this->_get_border("left"); + } + + private function _get_width($prop) + { + //TODO: should be handled in setter + if (strpos($this->_props_computed[$prop], "%") !== false) { + // calculate against width of containing block, needs to be done outside the style class + return $this->_props_computed[$prop]; + } + return $this->length_in_pt($this->_props_computed[$prop], $this->__get("font_size")); + } + + function get_margin_top() + { + return $this->_get_width("margin_top"); + } + + function get_margin_right() + { + return $this->_get_width("margin_right"); + } + + function get_margin_bottom() + { + return $this->_get_width("margin_bottom"); + } + + function get_margin_left() + { + return $this->_get_width("margin_left"); + } + + function get_padding_top() + { + return $this->_get_width("padding_top"); + } + + function get_padding_right() + { + return $this->_get_width("padding_right"); + } + + function get_padding_bottom() + { + return $this->_get_width("padding_bottom"); + } + + function get_padding_left() + { + return $this->_get_width("padding_left"); + } + + /** + * @param $w + * @param $h + * @return array|null + */ + function get_computed_border_radius($w, $h) + { + if (!empty($this->_computed_border_radius)) { + return $this->_computed_border_radius; + } + + $w = (float)$w; + $h = (float)$h; + $rTL = (float)$this->__get("border_top_left_radius"); + $rTR = (float)$this->__get("border_top_right_radius"); + $rBL = (float)$this->__get("border_bottom_left_radius"); + $rBR = (float)$this->__get("border_bottom_right_radius"); + + if ($rTL + $rTR + $rBL + $rBR == 0) { + return $this->_computed_border_radius = [ + 0, 0, 0, 0, + "top-left" => 0, + "top-right" => 0, + "bottom-right" => 0, + "bottom-left" => 0, + ]; + } + + $t = (float)$this->__get("border_top_width"); + $r = (float)$this->__get("border_right_width"); + $b = (float)$this->__get("border_bottom_width"); + $l = (float)$this->__get("border_left_width"); + + $rTL = min($rTL, $h - $rBL - $t / 2 - $b / 2, $w - $rTR - $l / 2 - $r / 2); + $rTR = min($rTR, $h - $rBR - $t / 2 - $b / 2, $w - $rTL - $l / 2 - $r / 2); + $rBL = min($rBL, $h - $rTL - $t / 2 - $b / 2, $w - $rBR - $l / 2 - $r / 2); + $rBR = min($rBR, $h - $rTR - $t / 2 - $b / 2, $w - $rBL - $l / 2 - $r / 2); + + return $this->_computed_border_radius = [ + $rTL, $rTR, $rBR, $rBL, + "top-left" => $rTL, + "top-right" => $rTR, + "bottom-right" => $rBR, + "bottom-left" => $rBL, + ]; + } + + /** + * Returns the outline color as an array + * + * See {@link Style::get_color()} + * + * @link http://www.w3.org/TR/CSS21/box.html#border-color-properties + * @return array + */ + function get_outline_color() + { + return $this->munge_color($this->_props_computed["outline_color"]); + } + + /**#@+ + * Returns the outline width, as it is currently stored + * @return float|string + */ + function get_outline_width() + { + $style = $this->__get("outline_style"); + return $style !== "none" && $style !== "hidden" ? $this->length_in_pt($this->_props_computed["outline_width"]) : 0; + } + + /**#@+ + * Return full outline properties as a string + * + * Outline properties are returned just as specified in CSS: + *
[width] [style] [color]
+ * e.g. "1px solid blue" + * + * @link http://www.w3.org/TR/CSS21/box.html#border-shorthand-properties + * @return string + */ + function get_outline() + { + $color = $this->__get("outline_color"); + return + $this->__get("outline_width") . " " . + $this->__get("outline_style") . " " . + $color["hex"]; + } + /**#@-*/ + + /** + * Returns border spacing as an array + * + * The array has the format (h_space,v_space) + * + * @link http://www.w3.org/TR/CSS21/tables.html#propdef-border-spacing + * @return array + */ + function get_border_spacing() + { + $arr = explode(" ", $this->_props_computed["border_spacing"]); + if (count($arr) == 1) { + $arr[1] = $arr[0]; + } + return $arr; + } + + /** + * Returns the list style image URI, or "none" + * + * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image + * @return string + */ + function get_list_style_image() + { + return $this->_image($this->_props_computed["list_style_image"]); + } + + /** + * @param $val + */ + function get_counter_increment() + { + $val = trim($this->_props_computed["counter_increment"]); + $value = null; + + if (in_array($val, ["none", "inherit"])) { + $value = $val; + } else { + if (preg_match_all("/(" . self::CSS_IDENTIFIER . ")(?:\s+(" . self::CSS_INTEGER . "))?/", $val, $matches, PREG_SET_ORDER)) { + $value = []; + foreach ($matches as $match) { + $value[$match[1]] = isset($match[2]) ? $match[2] : 1; + } + } + } + return $value; + } + + + /*==============================*/ + + /* + !important attribute + For basic functionality of the !important attribute with overloading + of several styles of an element, changes in inherit(), merge() and _parse_properties() + are sufficient [helpers var $_important_props, __construct(), important_set(), important_get()] + + Only for combined attributes extra treatment needed. See below. + + div { border: 1px red; } + div { border: solid; } // Not combined! Only one occurrence of same style per context + // + div { border: 1px red; } + div a { border: solid; } // Adding to border style ok by inheritance + // + div { border-style: solid; } // Adding to border style ok because of different styles + div { border: 1px red; } + // + div { border-style: solid; !important} // border: overrides, even though not !important + div { border: 1px dashed red; } + // + div { border: 1px red; !important } + div a { border-style: solid; } // Need to override because not set + + Special treatment: + At individual property like border-top-width need to check whether overriding value is also !important. + Also store the !important condition for later overrides. + Since not known who is initiating the override, need to get passed !important as parameter. + !important Parameter taken as in the original style in the css file. + When property border !important given, do not mark subsets like border_style as important. Only + individual properties. + + Note: + Setting individual property directly from css with e.g. set_border_top_style() is not needed, because + missing set functions handled by a generic handler __set(), including the !important. + Setting individual property of as sub-property is handled below. + + Implementation see at _set_style_side_type() + Callers _set_style_sides_type(), _set_style_type, _set_style_type_important() + + Related functionality for background, padding, margin, font, list_style + */ + + /** + * Generalized set function for individual attribute of combined style. + * With check for !important + * Applicable for background, border, padding, margin, font, list_style + * + * Note: $type has a leading underscore (or is empty), the others not. + * + * @param $style + * @param $side + * @param $type + * @param $val + * @param $important + */ + protected function _set_style_side_type($style, $side, $type, $val, $important) + { + $prop = $style; + if (!empty($side)) { + $prop .= "_" . $side; + }; + if (!empty($type)) { + $prop .= "_" . $type; + }; + $this->_props[$prop] = $val; + $this->_prop_cache[$prop] = null; + + if ($val === "inherit") { + $this->_props_computed[$prop] = null; + return; + } + + if (!isset($this->_important_props[$prop]) || $important) { + $val_computed = (float)$this->length_in_pt($val); + if ($side === "bottom") { + $this->_computed_bottom_spacing = null; //reset computed cache, border style can disable/enable border calculations + } + if ($important) { + $this->_important_props[$prop] = true; + } + + if ($val_computed < 0 && ($style === "border" || $style === "padding" || $style === "outline")) { + $this->_props[$prop] = null; // passed-in value is invalid + } else if ( + (($style === "border" || $style === "outline") && $type === "width" && strpos($val, "%") !== false) + || + (($style === "margin" || $style === "padding") && (strpos($val, "%") !== false || $val === "auto")) + ) { + $this->_props_computed[$prop] = $val; + } elseif (($style === "border" || $style === "outline") && $type === "width" && strpos($val, "%") === false) { + $line_style_prop = $style; + if (!empty($side)) { + $line_style_prop .= "_" . $side; + }; + $line_style_prop .= "_style"; + $line_style = $this->__get($line_style_prop); + $this->_props_computed[$prop] = ($line_style !== "none" && $line_style !== "hidden" ? $val_computed : 0); + } elseif (($style === "margin" || $style === "padding")) { + $this->_props_computed[$prop] = ($val !== "none" && $val !== "hidden" ? $val_computed : 0); + } elseif ($type === "color") { + $this->set_prop_color($prop, $val); + } elseif (!empty($val)) { + $this->_props_computed[$prop] = $val; + } + } + } + + /** + * @param $style + * @param $top + * @param $right + * @param $bottom + * @param $left + * @param $type + * @param $important + */ + protected function _set_style_sides_type($style, $top, $right, $bottom, $left, $type, $important) + { + $this->_set_style_side_type($style, 'top', $type, $top, $important); + $this->_set_style_side_type($style, 'right', $type, $right, $important); + $this->_set_style_side_type($style, 'bottom', $type, $bottom, $important); + $this->_set_style_side_type($style, 'left', $type, $left, $important); + } + + /** + * @param $style + * @param $type + * @param $val + * @param $important + */ + protected function _set_style_type($style, $type, $val, $important) + { + $val = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces + $arr = explode(" ", $val); + + switch (count($arr)) { + case 1: + $this->_set_style_sides_type($style, $arr[0], $arr[0], $arr[0], $arr[0], $type, $important); + break; + case 2: + $this->_set_style_sides_type($style, $arr[0], $arr[1], $arr[0], $arr[1], $type, $important); + break; + case 3: + $this->_set_style_sides_type($style, $arr[0], $arr[1], $arr[2], $arr[1], $type, $important); + break; + case 4: + $this->_set_style_sides_type($style, $arr[0], $arr[1], $arr[2], $arr[3], $type, $important); + break; + } + } + + /** + * @param $style + * @param $type + * @param $val + */ + protected function _set_style_type_important($style, $type, $val) + { + $this->_set_style_type($style, $type, $val, isset($this->_important_props[$style . $type])); + } + + /** + * Anyway only called if _important matches and is assigned + * E.g. _set_style_side_type($style,$side,'',str_replace("none", "0px", $val),isset($this->_important_props[$style.'_'.$side])); + * + * @param $style + * @param $side + * @param $val + */ + protected function _set_style_side_width_important($style, $side, $val) + { + $this->_set_style_side_type($style, $side, "", $val, isset($this->_important_props[$style . $side])); + } + + /** + * @param $style + * @param $val + * @param $important + */ + protected function _set_style($style, $val, $important) + { + if (!isset($this->_important_props[$style]) || $important) { + if ($important) { + $this->_important_props[$style] = true; + } + $this->__set($style, $val); + } + } + + /** + * @param $val + * @return string + */ + protected function _image($val) + { + $DEBUGCSS = $this->_stylesheet->get_dompdf()->getOptions()->getDebugCss(); + $parsed_url = "none"; + + if (empty($val) || $val === "none") { + $path = "none"; + } else if (mb_strpos($val, "url") === false) { + $path = "none"; //Don't resolve no image -> otherwise would prefix path and no longer recognize as none + } else { + $val = preg_replace("/url\(\s*['\"]?([^'\")]+)['\"]?\s*\)/", "\\1", trim($val)); + + // Resolve the url now in the context of the current stylesheet + $parsed_url = Helpers::explode_url($val); + $path = Helpers::build_url($this->_stylesheet->get_protocol(), + $this->_stylesheet->get_host(), + $this->_stylesheet->get_base_path(), + $val); + if ($parsed_url["protocol"] == "" && $this->_stylesheet->get_protocol() == "") { + $path = realpath($path); + // If realpath returns FALSE then specifically state that there is no background image + if (!$path) { + $path = 'none'; + } + } + } + if ($DEBUGCSS) { + print "
[_image\n";
+            print_r($parsed_url);
+            print $this->_stylesheet->get_protocol() . "\n" . $this->_stylesheet->get_base_path() . "\n" . $path . "\n";
+            print "_image]
";; + } + return $path; + } + + /*======================*/ + + protected function set_prop_color($prop, $color) + { + $munged_color = $this->munge_color($color); + + if (is_null($munged_color)) { + return; + } + + $this->_props[$prop] = $color; + $this->_props_computed[$prop] = null; + $this->_prop_cache[$prop] = null; + + $this->_props_computed[$prop] = (is_array($munged_color) ? $munged_color["hex"] : $munged_color); + } + + /** + * Sets color + * + * The color parameter can be any valid CSS color value + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-color + * @param string $color + */ + function set_color($color) + { + $this->set_prop_color("color", $color); + } + + /** + * Sets the background color + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-color + * @param string $color + */ + function set_background_color($color) + { + $this->set_prop_color("background_color", $color); + } + + /** + * Set the background image url + * @link https://www.w3.org/TR/CSS21/colors.html#propdef-background-image + * + * @param string $val + */ + function set_background_image($val) + { + $this->_props["background_image"] = $val; + $this->_props_computed["background_image"] = "url(" . $this->_image($val) . ")"; + $this->_prop_cache["background_image"] = null; + } + + /** + * Sets the background repeat + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-repeat + * @param string $val + */ + function set_background_repeat($val) + { + $this->_props["background_repeat"] = $val; + $this->_props_computed["background_repeat"] = null; + $this->_prop_cache["background_repeat"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["background_repeat"] = $val; + } + + /** + * Sets the background attachment + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-attachment + * @param string $val + */ + function set_background_attachment($val) + { + $this->_props["background_attachment"] = $val; + $this->_props_computed["background_attachment"] = null; + $this->_prop_cache["background_attachment"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["background_attachment"] = $val; + } + + /** + * Sets the background position + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background-position + * @param string $val + */ + function set_background_position($val) + { + $this->_props["background_position"] = $val; + + $tmp = explode(" ", $val); + + switch ($tmp[0]) { + case "left": + $x = "0%"; + break; + + case "right": + $x = "100%"; + break; + + case "top": + $y = "0%"; + break; + + case "bottom": + $y = "100%"; + break; + + case "center": + $x = "50%"; + $y = "50%"; + break; + + default: + $x = $tmp[0]; + break; + } + + if (isset($tmp[1])) { + switch ($tmp[1]) { + case "left": + $x = "0%"; + break; + + case "right": + $x = "100%"; + break; + + case "top": + $y = "0%"; + break; + + case "bottom": + $y = "100%"; + break; + + case "center": + if ($tmp[0] === "left" || $tmp[0] === "right" || $tmp[0] === "center") { + $y = "50%"; + } else { + $x = "50%"; + } + break; + + default: + $y = $tmp[1]; + break; + } + } else { + $y = "50%"; + } + + if (!isset($x)) { + $x = "0%"; + } + + if (!isset($y)) { + $y = "0%"; + } + + $this->_props_computed["background_position"] = "$x $y"; + $this->_prop_cache["background_position"] = null; + } + + /** + * Sets the background size + * + * @link https://www.w3.org/TR/css3-background/#background-size + * @param string $val + */ + function set_background_size($val) + { + $this->_props["background_size"] = $val; + $this->_prop_cache["background_size"] = null; + + $result = explode(" ", $val); + $width = $result[0]; + + switch ($width) { + case "cover": + case "contain": + case "inherit": + $this->_props_computed["background_size"] = $width; + return; + } + + if ($width !== "auto" && strpos($width, "%") === false) { + $width = (float)$this->length_in_pt($width); + } + + $height = $result[1] ?? "auto"; + if ($height !== "auto" && strpos($height, "%") === false) { + $height = (float)$this->length_in_pt($height); + } + + $this->_props_computed["background_size"] = "$width $height"; + } + + /** + * Sets the background - combined options + * + * @link http://www.w3.org/TR/CSS21/colors.html#propdef-background + * @param string $val + */ + function set_background($val) + { + $val = trim($val); + $important = isset($this->_important_props["background"]); + + if ($val === "none") { + $this->_set_style("background_image", "none", $important); + $this->_set_style("background_color", "transparent", $important); + } else { + $pos = []; + $tmp = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces + $tmp = preg_split("/\s+/", $tmp); + + foreach ($tmp as $attr) { + if (mb_substr($attr, 0, 3) === "url" || $attr === "none") { + $this->_set_style("background_image", $attr, $important); + } elseif ($attr === "fixed" || $attr === "scroll") { + $this->_set_style("background_attachment", $attr, $important); + } elseif ($attr === "repeat" || $attr === "repeat-x" || $attr === "repeat-y" || $attr === "no-repeat") { + $this->_set_style("background_repeat", $attr, $important); + } elseif (($col = $this->munge_color($attr)) != null) { + $this->_set_style("background_color", is_array($col) ? $col["hex"] : $col, $important); + } else { + $pos[] = $attr; + } + } + + if (count($pos)) { + $this->_set_style("background_position", implode(" ", $pos), $important); + } + } + + //see __set and __get, on all assignments clear cache, not needed on direct set through __set + $this->_props["background"] = $val; + $this->_props_computed["background"] = null; + $this->_prop_cache["background"] = null; + } + + /** + * Sets the font size + * + * $size can be any acceptable CSS size + * + * @link http://www.w3.org/TR/CSS21/fonts.html#propdef-font-size + * @param string|float $size + */ + function set_font_size($size) + { + $this->_props["font_size"] = $size; + $this->_props_computed["font_size"] = null; + $this->_prop_cache["font_size"] = null; + + if ($size === "inherit") { + return; + } + if (!isset($this->_parent_font_size)) { + $this->_parent_font_size = self::$default_font_size; + } + + switch ((string)$size) { + case "xx-small": + case "x-small": + case "small": + case "medium": + case "large": + case "x-large": + case "xx-large": + $fs = self::$default_font_size * self::$font_size_keywords[$size]; + break; + + case "smaller": + $fs = 8 / 9 * $this->_parent_font_size; + break; + + case "larger": + $fs = 6 / 5 * $this->_parent_font_size; + break; + + default: + $fs = $size; + break; + } + + // length_in_pt uses the font size if units are em or ex (and, potentially, rem) so we'll calculate in the method + if (($i = mb_strpos($fs, "rem")) !== false) { + if ($this->_stylesheet->get_dompdf()->getTree()->get_root()->get_style() === null) { + // Interpreting it as "em", see https://github.com/dompdf/dompdf/issues/1406 + $fs = (float)mb_substr($fs, 0, $i) * $this->_parent_font_size; + } else { + $fs = (float)mb_substr($fs, 0, $i) * $this->_stylesheet->get_dompdf()->getTree()->get_root()->get_style()->font_size; + } + } elseif (($i = mb_strpos($fs, "em")) !== false) { + $fs = (float)mb_substr($fs, 0, $i) * $this->_parent_font_size; + } elseif (($i = mb_strpos($fs, "ex")) !== false) { + $fs = (float)mb_substr($fs, 0, $i) * $this->_parent_font_size / 2; + } else { + //FIXME: prefer just calling length_in_pt, when we provide a ref size to length_in_pt should em and ex use that instead of the current font size? + $fs = (float)$this->length_in_pt($fs, $this->_parent_font_size); + } + + $this->_props_computed["font_size"] = $fs; + } + + /** + * Sets the font weight + * + * @param string|int $weight + */ + function set_font_weight($weight) + { + $this->_props["font_weight"] = $weight; + $this->_props_computed["font_weight"] = null; + $this->_prop_cache["font_weight"] = null; + + $computed_weight = $weight; + + if ($weight === "bolder") { + //TODO: One font weight heavier than the parent element (among the available weights of the font). + $computed_weight = "bold"; + } elseif ($weight === "lighter") { + //TODO: One font weight lighter than the parent element (among the available weights of the font). + $computed_weight = "normal"; + } + + $this->_props_computed["font_weight"] = $computed_weight; + } + + /** + * Sets the font style + * + * combined attributes + * set individual attributes also, respecting !important mark + * exactly this order, separate by space. Multiple fonts separated by comma: + * font-style, font-variant, font-weight, font-size, line-height, font-family + * + * Other than with border and list, existing partial attributes should + * reset when starting here, even when not mentioned. + * If individual attribute is !important and explicit or implicit replacement is not, + * keep individual attribute + * + * require whitespace as delimiters for single value attributes + * On delimiter "/" treat first as font height, second as line height + * treat all remaining at the end of line as font + * font-style, font-variant, font-weight, font-size, line-height, font-family + * + * missing font-size and font-family might be not allowed, but accept it here and + * use default (medium size, empty font name) + * + * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style + * @param $val + */ + function set_font($val) + { + //see __set and __get, on all assignments clear cache, not needed on direct set through __set + $this->_prop_cache["font"] = null; + $this->_props["font"] = $val; + $this->_props_computed["font"] = null; + + $important = isset($this->_important_props["font"]); + + if (strtolower($val) === "inherit") { + $this->_set_style("font_family", "inherit", $important); + $this->_set_style("font_size", "inherit", $important); + $this->_set_style("font_style", "inherit", $important); + $this->_set_style("font_variant", "inherit", $important); + $this->_set_style("font_weight", "inherit", $important); + $this->_set_style("line_height", "inherit", $important); + return; + } + + if (preg_match("/^(italic|oblique|normal)\s*(.*)$/i", $val, $match)) { + $this->_set_style("font_style", $match[1], $important); + $val = $match[2]; + } + + if (preg_match("/^(small-caps|normal)\s*(.*)$/i", $val, $match)) { + $this->_set_style("font_variant", $match[1], $important); + $val = $match[2]; + } + + //matching numeric value followed by unit -> this is indeed a subsequent font size. Skip! + if (preg_match("/^(bold|bolder|lighter|100|200|300|400|500|600|700|800|900|normal)\s*(.*)$/i", $val, $match) && + !preg_match("/^(?:pt|px|pc|em|ex|in|cm|mm|%)/", $match[2]) + ) { + $this->_set_style("font_weight", $match[1], $important); + $val = $match[2]; + } + + if (preg_match("/^(xx-small|x-small|small|medium|large|x-large|xx-large|smaller|larger|\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))(?:\/|\s*)(.*)$/i", $val, $match)) { + $this->_set_style("font_size", $match[1], $important); + $val = $match[2]; + if (preg_match("/^(?:\/|\s*)(\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%)?)\s*(.*)$/i", $val, $match)) { + $this->_set_style("line_height", $match[1], $important); + $val = $match[2]; + } + } + + if (strlen($val) != 0) { + $this->_set_style("font_family", $val, $important); + } + } + + /** + * Sets the text alignment + * + * If no alignment is set on the element and the direction is rtl then + * the property is set to "right", otherwise it is set to "left". + * + * @link https://www.w3.org/TR/CSS21/text.html#propdef-text-align + */ + public function set_text_align($val) + { + $alignment = ""; + if (in_array($val, self::$text_align_keywords)) { + $alignment = $val; + } + if ($alignment === "") { + $alignment = "left"; + if ($this->__get("direction") === "rtl") { + $alignment = "right"; + } + + } + $this->_props_computed["text_align"] = $alignment; + } + + /** + * Sets word spacing property + * + * @link http://www.w3.org/TR/CSS21/text.html#propdef-word-spacing + * @param $val + */ + function set_word_spacing($val) + { + $this->_props["word_spacing"] = $val; + $this->_props_computed["word_spacing"] = null; + $this->_prop_cache["word_spacing"] = null; + + if ($val === 'inherit') { + return; + } + + if ($val === "normal" || strpos($val, "%") !== false) { + $this->_props_computed["word_spacing"] = $val; + } else { + $this->_props_computed["word_spacing"] = ((float)$this->length_in_pt($val, $this->__get("font_size"))) . "pt"; + } + } + + /** + * Sets letter spacing property + * + * @link http://www.w3.org/TR/CSS21/text.html#propdef-letter-spacing + * @param $val + */ + function set_letter_spacing($val) + { + $this->_props["letter_spacing"] = $val; + $this->_props_computed["letter_spacing"] = null; + $this->_prop_cache["letter_spacing"] = null; + + if ($val === 'inherit') { + return; + } + + if ($val === "normal") { + $this->_props_computed["letter_spacing"] = $val; + } else { + $this->_props_computed["letter_spacing"] = ((float)$this->length_in_pt($val, $this->__get("font_size"))) . "pt"; + } + } + + /** + * Sets line height property + * + * @link http://www.w3.org/TR/CSS21/visudet.html#propdef-line-height + * @param $val + */ + function set_line_height($val) + { + $this->_props["line_height"] = $val; + $this->_props_computed["line_height"] = null; + $this->_prop_cache["line_height"] = null; + + if ($val === 'inherit') { + return; + } + + if ($val === "normal" || is_numeric($val)) { + $this->_props_computed["line_height"] = $val; + } else { + $this->_props_computed["line_height"] = ((float)$this->length_in_pt($val, $this->__get("font_size"))) . "pt"; + } + } + + /** + * Sets page break properties + * + * @link http://www.w3.org/TR/CSS21/page.html#page-breaks + * @param string $break + */ + function set_page_break_before($break) + { + $this->_props["page_break_before"] = $break; + $this->_props_computed["page_break_before"] = null; + $this->_prop_cache["page_break_before"] = null; + + if ($break === 'inherit') { + return; + } + + if ($break === "left" || $break === "right") { + $break = "always"; + } + + $this->_props_computed["page_break_before"] = $break; + } + + /** + * @param $break + */ + function set_page_break_after($break) + { + $this->_props["page_break_after"] = $break; + $this->_props_computed["page_break_after"] = null; + $this->_prop_cache["page_break_after"] = null; + + if ($break === 'inherit') { + return; + } + + if ($break === "left" || $break === "right") { + $break = "always"; + } + + $this->_props_computed["page_break_after"] = $break; + } + + /** + * Sets the margin size + * + * @link http://www.w3.org/TR/CSS21/box.html#margin-properties + * @param $val + */ + function set_margin_top($val) + { + $this->_set_style_side_width_important('margin', 'top', $val); + } + + /** + * @param $val + */ + function set_margin_right($val) + { + $this->_set_style_side_width_important('margin', 'right', $val); + } + + /** + * @param $val + */ + function set_margin_bottom($val) + { + $this->_set_style_side_width_important('margin', 'bottom', $val); + } + + /** + * @param $val + */ + function set_margin_left($val) + { + $this->_set_style_side_width_important('margin', 'left', $val); + } + + /** + * @param $val + */ + function set_margin($val) + { + $this->_set_style_type_important('margin', '', $val); + } + + /** + * Sets the padding size + * + * @link http://www.w3.org/TR/CSS21/box.html#padding-properties + * @param $val + */ + function set_padding_top($val) + { + $this->_set_style_side_width_important('padding', 'top', $val); + } + + /** + * @param $val + */ + function set_padding_right($val) + { + $this->_set_style_side_width_important('padding', 'right', $val); + } + + /** + * @param $val + */ + function set_padding_bottom($val) + { + $this->_set_style_side_width_important('padding', 'bottom', $val); + } + + /** + * @param $val + */ + function set_padding_left($val) + { + $this->_set_style_side_width_important('padding', 'left', $val); + } + + /** + * @param $val + */ + function set_padding($val) + { + $this->_set_style_type_important('padding', '', $val); + } + /**#@-*/ + + /** + * Sets a single border + * + * @param string $side + * @param string $border_spec ([width] [style] [color]) + * @param boolean $important + */ + protected function _set_border($side, $border_spec, $important) + { + $border_spec = preg_replace("/\s*\,\s*/", ",", $border_spec); + //$border_spec = str_replace(",", " ", $border_spec); // Why did we have this ?? rbg(10, 102, 10) > rgb(10 102 10) + $arr = explode(" ", $border_spec); + + // FIXME: handle partial values + //For consistency of individual and combined properties, and with ie8 and firefox3 + //reset all attributes, even if only partially given + //$this->_set_style_side_type('border', $side, 'style', self::$_defaults['border_' . $side . '_style'], $important); + //$this->_set_style_side_type('border', $side, 'width', self::$_defaults['border_' . $side . '_width'], $important); + //$this->_set_style_side_type('border', $side, 'color', self::$_defaults['border_' . $side . '_color'], $important); + + foreach ($arr as $value) { + $value = trim($value); + if (in_array($value, self::$BORDER_STYLES)) { + $this->_set_style_side_type('border', $side, 'style', $value, $important); + } elseif (preg_match("/[.0-9]+(?:px|pt|pc|em|ex|%|in|mm|cm)|(?:thin|medium|thick)/", $value)) { + $this->_set_style_side_type('border', $side, 'width', $value, $important); + } elseif ($value === "inherit") { + $this->_set_style_side_type('border', $side, 'style', $value, $important); + $this->_set_style_side_type('border', $side, 'width', $value, $important); + $this->_set_style_side_type('border', $side, 'color', $value, $important); + } else { + // must be color + $this->_set_style_side_type('border', $side, 'color', $this->munge_color($value), $important); + } + } + } + + /** + * Sets the border styles + * + * @link http://www.w3.org/TR/CSS21/box.html#border-properties + * @param string $val + */ + function set_border_top($val) + { + $this->_set_border("top", $val, isset($this->_important_props['border_top'])); + } + + function set_border_top_color($val) + { + $color = $val; + if ($val === "") { + $color = $this->__get("color"); + } + $this->_set_style_side_type('border', 'top', 'color', $color, isset($this->_important_props['border_top_color'])); + } + + function set_border_top_style($val) + { + $this->_set_style_side_type('border', 'top', 'style', $val, isset($this->_important_props['border_top_style'])); + } + + function set_border_top_width($val) + { + $this->_set_style_side_type('border', 'top', 'width', $val, isset($this->_important_props['border_top_width'])); + } + + /** + * @param $val + */ + function set_border_right($val) + { + $this->_set_border("right", $val, isset($this->_important_props['border_right'])); + } + + function set_border_right_color($val) + { + $color = $val; + if ($val === "") { + $color = $this->__get("color"); + } + $this->_set_style_side_type('border', 'right', 'color', $color, isset($this->_important_props['border_right_color'])); + } + + function set_border_right_style($val) + { + $this->_set_style_side_type('border', 'right', 'style', $val, isset($this->_important_props['border_right_style'])); + } + + function set_border_right_width($val) + { + $this->_set_style_side_type('border', 'right', 'width', $val, isset($this->_important_props['border_right_width'])); + } + + /** + * @param $val + */ + function set_border_bottom($val) + { + $this->_set_border("bottom", $val, isset($this->_important_props['border_bottom'])); + } + + function set_border_bottom_color($val) + { + $color = $val; + if ($val === "") { + $color = $this->__get("color"); + } + $this->_set_style_side_type('border', 'bottom', 'color', $color, isset($this->_important_props['border_bottom_color'])); + } + + function set_border_bottom_style($val) + { + $this->_set_style_side_type('border', 'bottom', 'style', $val, isset($this->_important_props['border_bottom_style'])); + } + + function set_border_bottom_width($val) + { + $this->_set_style_side_type('border', 'bottom', 'width', $val, isset($this->_important_props['border_bottom_width'])); + } + + /** + * @param $val + */ + function set_border_left($val) + { + $this->_set_border("left", $val, isset($this->_important_props['border_left'])); + } + + function set_border_left_color($val) + { + $color = $val; + if ($val === "") { + $color = $this->__get("color"); + } + $this->_set_style_side_type('border', 'left', 'color', $color, isset($this->_important_props['border_left_color'])); + } + + function set_border_left_style($val) + { + $this->_set_style_side_type('border', 'left', 'style', $val, isset($this->_important_props['border_left_style'])); + } + + function set_border_left_width($val) + { + $this->_set_style_side_type('border', 'left', 'width', $val, isset($this->_important_props['border_left_width'])); + } + + /** + * @param $val + */ + function set_border($val) + { + $important = isset($this->_important_props["border"]); + + $this->_set_border("top", $val, $important); + $this->_set_border("right", $val, $important); + $this->_set_border("bottom", $val, $important); + $this->_set_border("left", $val, $important); + } + + /** + * @param $val + */ + function set_border_width($val) + { + $this->_set_style_type_important('border', 'width', $val); + } + + /** + * @param $val + */ + function set_border_color($val) + { + $this->_set_style_type_important('border', 'color', $val); + } + + /** + * @param $val + */ + function set_border_style($val) + { + $this->_set_style_type_important('border', 'style', $val); + } + + /** + * Sets the border radius size + * + * http://www.w3.org/TR/css3-background/#corners + * + * @param $val + */ + function set_border_top_left_radius($val) + { + $this->_set_border_radius_corner($val, "top_left"); + } + + /** + * @param $val + */ + function set_border_top_right_radius($val) + { + $this->_set_border_radius_corner($val, "top_right"); + } + + /** + * @param $val + */ + function set_border_bottom_left_radius($val) + { + $this->_set_border_radius_corner($val, "bottom_left"); + } + + /** + * @param $val + */ + function set_border_bottom_right_radius($val) + { + $this->_set_border_radius_corner($val, "bottom_right"); + } + + /** + * @param $val + */ + function set_border_radius($val) + { + $val = preg_replace("/\s*\,\s*/", ",", $val); // when border-radius has spaces + $arr = explode(" ", $val); + + switch (count($arr)) { + case 1: + $this->_set_border_radii($arr[0], $arr[0], $arr[0], $arr[0]); + break; + case 2: + $this->_set_border_radii($arr[0], $arr[1], $arr[0], $arr[1]); + break; + case 3: + $this->_set_border_radii($arr[0], $arr[1], $arr[2], $arr[1]); + break; + case 4: + $this->_set_border_radii($arr[0], $arr[1], $arr[2], $arr[3]); + break; + } + } + + /** + * @param $val1 + * @param $val2 + * @param $val3 + * @param $val4 + */ + protected function _set_border_radii($val1, $val2, $val3, $val4) + { + $this->_set_border_radius_corner($val1, "top_left"); + $this->_set_border_radius_corner($val2, "top_right"); + $this->_set_border_radius_corner($val3, "bottom_right"); + $this->_set_border_radius_corner($val4, "bottom_left"); + } + + /** + * @param $val + * @param $corner + */ + protected function _set_border_radius_corner($val, $corner) + { + $this->_has_border_radius = true; + + $this->_props["border_" . $corner . "_radius"] = $val; + $this->_props_computed["border_" . $corner . "_radius"] = null; + $this->_prop_cache["border_" . $corner . "_radius"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["border_" . $corner . "_radius"] = $val; + } + + /** + * @return float|int|string + */ + function get_border_top_left_radius() + { + return $this->_get_border_radius_corner("top_left"); + } + + /** + * @return float|int|string + */ + function get_border_top_right_radius() + { + return $this->_get_border_radius_corner("top_right"); + } + + /** + * @return float|int|string + */ + function get_border_bottom_left_radius() + { + return $this->_get_border_radius_corner("bottom_left"); + } + + /** + * @return float|int|string + */ + function get_border_bottom_right_radius() + { + return $this->_get_border_radius_corner("bottom_right"); + } + + /** + * @param $corner + * @return float|int|string + */ + protected function _get_border_radius_corner($corner) + { + if (!isset($this->_props_computed["border_" . $corner . "_radius"]) || empty($this->_props_computed["border_" . $corner . "_radius"])) { + return 0; + } + + return $this->length_in_pt($this->_props_computed["border_" . $corner . "_radius"]); + } + + /** + * Sets the outline styles + * + * @link http://www.w3.org/TR/CSS21/ui.html#dynamic-outlines + * @param string $val + */ + function set_outline($val) + { + $important = isset($this->_important_props["outline"]); + + $props = [ + "outline_style", + "outline_width", + "outline_color", + ]; + + foreach ($props as $prop) { + $_val = self::$_defaults[$prop]; + + if (!isset($this->_important_props[$prop]) || $important) { + //see __set and __get, on all assignments clear cache! + $this->_prop_cache[$prop] = null; + if ($important) { + $this->_important_props[$prop] = true; + } + $this->_props[$prop] = $_val; + } + } + + $val = preg_replace("/\s*\,\s*/", ",", $val); // when rgb() has spaces + $arr = explode(" ", $val); + foreach ($arr as $value) { + $value = trim($value); + + if (in_array($value, self::$BORDER_STYLES)) { + $this->__set("outline_style", $value); + } else if (preg_match("/[.0-9]+(?:px|pt|pc|em|ex|%|in|mm|cm)|(?:thin|medium|thick)/", $value)) { + $this->__set("outline_width", $value); + } else { + // must be color + $this->__set("outline_color", $value); + } + } + + //see __set and __get, on all assignments clear cache, not needed on direct set through __set + $this->_props["outline"] = $val; + $this->_props_computed["outline"] = null; + $this->_prop_cache["outline"] = null; + } + + /** + * @param $val + */ + function set_outline_width($val) + { + $this->_set_style_side_type("outline", null, "width", $val, isset($this->_important_props["outline_width"])); + } + + /** + * @param $val + */ + function set_outline_color($val) + { + $color = $val; + if ($val === "") { + $color = $this->__get("color"); + } + $this->_set_style_side_type("outline", null, "color", $color, isset($this->_important_props["outline_color"])); + } + + /** + * @param $val + */ + function set_outline_style($val) + { + $this->_set_style_side_type("outline", null, "style", $val, isset($this->_important_props["outline_style"])); + } + + /** + * Sets the border spacing + * + * @link http://www.w3.org/TR/CSS21/box.html#border-properties + * @param float $val + */ + function set_border_spacing($val) + { + $arr = explode(" ", $val); + + if (count($arr) == 1) { + $arr[1] = $arr[0]; + } + + $this->_props["border_spacing"] = $val; + $this->_props_computed["border_spacing"] = null; + $this->_prop_cache["border_spacing"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["border_spacing"] = "$arr[0] $arr[1]"; + } + + /** + * Sets the list style image + * + * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style-image + * @param $val + */ + function set_list_style_image($val) + { + $this->_props["list_style_image"] = $val; + $this->_props_computed["list_style_image"] = "url(" . $this->_image($val) . ")"; + $this->_prop_cache["list_style_image"] = null; + } + + /** + * Sets the list style + * + * @link http://www.w3.org/TR/CSS21/generate.html#propdef-list-style + * @param $val + */ + function set_list_style($val) + { + $important = isset($this->_important_props["list_style"]); + $arr = explode(" ", str_replace(",", " ", $val)); + + static $types = [ + "disc", "circle", "square", + "decimal-leading-zero", "decimal", "1", + "lower-roman", "upper-roman", "a", "A", + "lower-greek", + "lower-latin", "upper-latin", + "lower-alpha", "upper-alpha", + "armenian", "georgian", "hebrew", + "cjk-ideographic", "hiragana", "katakana", + "hiragana-iroha", "katakana-iroha", "none" + ]; + + static $positions = ["inside", "outside"]; + + foreach ($arr as $value) { + /* http://www.w3.org/TR/CSS21/generate.html#list-style + * A value of 'none' for the 'list-style' property sets both 'list-style-type' and 'list-style-image' to 'none' + */ + if ($value === "none") { + $this->_set_style("list_style_type", $value, $important); + $this->_set_style("list_style_image", $value, $important); + continue; + } + + //On setting or merging or inheriting list_style_image as well as list_style_type, + //and url exists, then url has precedence, otherwise fall back to list_style_type + //Firefox is wrong here (list_style_image gets overwritten on explicit list_style_type) + //Internet Explorer 7/8 and dompdf is right. + + if (mb_substr($value, 0, 3) === "url") { + $this->_set_style("list_style_image", $value, $important); + continue; + } + + if (in_array($value, $types)) { + $this->_set_style("list_style_type", $value, $important); + } else if (in_array($value, $positions)) { + $this->_set_style("list_style_position", $value, $important); + } + } + + $this->_props["list_style"] = $val; + $this->_props_computed["list_style"] = null; + $this->_prop_cache["list_style"] = null; + } + + /** + * @param $val + */ + function set_size($val) + { + $this->_props["size"] = $val; + $this->_props_computed["size"] = null; + $this->_prop_cache["size"] = null; + + $length_re = "/(\d+\s*(?:pt|px|pc|em|ex|in|cm|mm|%))/"; + + $val = mb_strtolower($val); + + if ($val === "auto") { + $this->_props["size"] = $val; + return; + } + + $parts = preg_split("/\s+/", $val); + + $computed = []; + if (preg_match($length_re, $parts[0])) { + $computed[] = $this->length_in_pt($parts[0]); + + if (isset($parts[1]) && preg_match($length_re, $parts[1])) { + $computed[] = $this->length_in_pt($parts[1]); + } else { + $computed[] = $computed[0]; + } + + if (isset($parts[2]) && $parts[2] === "landscape") { + $computed = array_reverse($computed); + } + } elseif (isset(CPDF::$PAPER_SIZES[$parts[0]])) { + $computed = array_slice(CPDF::$PAPER_SIZES[$parts[0]], 2, 2); + + if (isset($parts[1]) && $parts[1] === "landscape") { + $computed = array_reverse($computed); + } + } else { + return; + } + + $this->_props_computed["size"] = $computed; + } + + /** + * Gets the CSS3 transform property + * + * @link http://www.w3.org/TR/css3-2d-transforms/#transform-property + * @return array|null + */ + function get_transform() + { + //TODO: should be handled in setter (lengths set to absolute) + + $number = "\s*([^,\s]+)\s*"; + $tr_value = "\s*([^,\s]+)\s*"; + $angle = "\s*([^,\s]+(?:deg|rad)?)\s*"; + + if (!preg_match_all("/[a-z]+\([^\)]+\)/i", $this->_props_computed["transform"], $parts, PREG_SET_ORDER)) { + return null; + } + + $functions = [ + //"matrix" => "\($number,$number,$number,$number,$number,$number\)", + + "translate" => "\($tr_value(?:,$tr_value)?\)", + "translateX" => "\($tr_value\)", + "translateY" => "\($tr_value\)", + + "scale" => "\($number(?:,$number)?\)", + "scaleX" => "\($number\)", + "scaleY" => "\($number\)", + + "rotate" => "\($angle\)", + + "skew" => "\($angle(?:,$angle)?\)", + "skewX" => "\($angle\)", + "skewY" => "\($angle\)", + ]; + + $transforms = []; + + foreach ($parts as $part) { + $t = $part[0]; + + foreach ($functions as $name => $pattern) { + if (preg_match("/$name\s*$pattern/i", $t, $matches)) { + $values = array_slice($matches, 1); + + switch ($name) { + // units + case "rotate": + case "skew": + case "skewX": + case "skewY": + + foreach ($values as $i => $value) { + if (strpos($value, "rad")) { + $values[$i] = rad2deg(floatval($value)); + } else { + $values[$i] = floatval($value); + } + } + + switch ($name) { + case "skew": + if (!isset($values[1])) { + $values[1] = 0; + } + break; + case "skewX": + $name = "skew"; + $values = [$values[0], 0]; + break; + case "skewY": + $name = "skew"; + $values = [0, $values[0]]; + break; + } + break; + + // units + case "translate": + $values[0] = $this->length_in_pt($values[0], (float)$this->length_in_pt($this->width)); + + if (isset($values[1])) { + $values[1] = $this->length_in_pt($values[1], (float)$this->length_in_pt($this->height)); + } else { + $values[1] = 0; + } + break; + + case "translateX": + $name = "translate"; + $values = [$this->length_in_pt($values[0], (float)$this->length_in_pt($this->width)), 0]; + break; + + case "translateY": + $name = "translate"; + $values = [0, $this->length_in_pt($values[0], (float)$this->length_in_pt($this->height))]; + break; + + // units + case "scale": + if (!isset($values[1])) { + $values[1] = $values[0]; + } + break; + + case "scaleX": + $name = "scale"; + $values = [$values[0], 1.0]; + break; + + case "scaleY": + $name = "scale"; + $values = [1.0, $values[0]]; + break; + } + + $transforms[] = [ + $name, + $values, + ]; + } + } + } + + return $transforms; + } + + /** + * @param $val + */ + function set_transform($val) + { + //see __set and __get, on all assignments clear cache, not needed on direct set through __set + $this->_props["transform"] = $val; + $this->_props_computed["transform"] = null; + $this->_prop_cache["transform"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["transform"] = $val; + } + + /** + * @param $val + */ + function set__webkit_transform($val) + { + $this->__set("transform", $val); + } + + /** + * @param $val + */ + function set__webkit_transform_origin($val) + { + $this->__set("transform_origin", $val); + } + + /** + * Sets the CSS3 transform-origin property + * + * @link http://www.w3.org/TR/css3-2d-transforms/#transform-origin + * @param string $val + */ + function set_transform_origin($val) + { + $this->_props["transform_origin"] = $val; + $this->_props_computed["transform_origin"] = null; + $this->_prop_cache["transform_origin"] = null; + + if ($val === 'inherit') { + return; + } + + $this->_props_computed["transform_origin"] = $val; + } + + /** + * Gets the CSS3 transform-origin property + * + * @link http://www.w3.org/TR/css3-2d-transforms/#transform-origin + * @return mixed[] + */ + function get_transform_origin() + { + //TODO: should be handled in setter + + $values = preg_split("/\s+/", $this->_props_computed['transform_origin']); + + $values = array_map(function ($value) { + if (in_array($value, ["top", "left"])) { + return 0; + } else if (in_array($value, ["bottom", "right"])) { + return "100%"; + } else { + return $value; + } + }, $values); + + if (!isset($values[1])) { + $values[1] = $values[0]; + } + + return $values; + } + + /** + * @param $val + * @return null + */ + protected function parse_image_resolution($val) + { + // If exif data could be get: + // $re = '/^\s*(\d+|normal|auto)(?:\s*,\s*(\d+|normal))?\s*$/'; + + $re = '/^\s*(\d+|normal|auto)\s*$/'; + + if (!preg_match($re, $val, $matches)) { + return null; + } + + return $matches[1]; + } + + /** + * auto | normal | dpi + * + * @param $val + */ + function set_background_image_resolution($val) + { + $this->_props["background_image_resolution"] = $val; + $this->_props_computed["background_image_resolution"] = null; + $this->_prop_cache["background_image_resolution"] = null; + + $parsed = $this->parse_image_resolution($val); + + $this->_props_computed["background_image_resolution"] = $parsed; + } + + /** + * auto | normal | dpi + * + * @param $val + */ + function set_image_resolution($val) + { + $this->_props["image_resolution"] = $val; + $this->_props_computed["image_resolution"] = null; + $this->_prop_cache["image_resolution"] = null; + + $parsed = $this->parse_image_resolution($val); + + $this->_props_computed["image_resolution"] = $parsed; + } + + /** + * @param $val + */ + function set__dompdf_background_image_resolution($val) + { + $this->__set("background_image_resolution", $val); + } + + /** + * @param $val + */ + function set__dompdf_image_resolution($val) + { + $this->__set("image_resolution", $val); + } + + /** + * @param $val + */ + function set_z_index($val) + { + $this->_props["z_index"] = $val; + $this->_props_computed["z_index"] = null; + $this->_prop_cache["z_index"] = null; + + if (round($val) != $val && $val !== "auto") { + return; + } + + $this->_props_computed["z_index"] = $val; + } + + /** + * @param FontMetrics $fontMetrics + * @return $this + */ + public function setFontMetrics(FontMetrics $fontMetrics) + { + $this->fontMetrics = $fontMetrics; + return $this; + } + + /** + * @return FontMetrics + */ + public function getFontMetrics() + { + return $this->fontMetrics; + } + + /** + * Generate a string representation of the Style + * + * This dumps the entire property array into a string via print_r. Useful + * for debugging. + * + * @return string + */ + /*DEBUGCSS print: see below additional debugging util*/ + function __toString() + { + return print_r(array_merge(["parent_font_size" => $this->_parent_font_size], + $this->_props), true); + } + + /*DEBUGCSS*/ + function debug_print() + { + print " parent_font_size:" . $this->_parent_font_size . ";\n"; + print " Props [\n"; + print " specified [\n"; + foreach ($this->_props as $prop => $val) { + print ' ' . $prop . ': ' . preg_replace("/\r\n/", ' ', print_r($val, true)); + if (isset($this->_important_props[$prop])) { + print ' !important'; + } + print ";\n"; + } + print " ]\n"; + print " computed [\n"; + foreach ($this->_props_computed as $prop => $val) { + print ' ' . $prop . ': ' . preg_replace("/\r\n/", ' ', print_r($val, true)); + print ";\n"; + } + print " ]\n"; + print " cached [\n"; + foreach ($this->_prop_cache as $prop => $val) { + print ' ' . $prop . ': ' . preg_replace("/\r\n/", ' ', print_r($val, true)); + print ";\n"; + } + print " ]\n"; + print " ]\n"; + } +} diff --git a/vendor/dompdf/dompdf/src/Css/Stylesheet.php b/vendor/dompdf/dompdf/src/Css/Stylesheet.php new file mode 100644 index 0000000..f175d97 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Css/Stylesheet.php @@ -0,0 +1,1754 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Css; + +use DOMElement; +use DOMXPath; +use Dompdf\Dompdf; +use Dompdf\Helpers; +use Dompdf\Exception; +use Dompdf\FontMetrics; +use Dompdf\Frame\FrameTree; + +/** + * The master stylesheet class + * + * The Stylesheet class is responsible for parsing stylesheets and style + * tags/attributes. It also acts as a registry of the individual Style + * objects generated by the current set of loaded CSS files and style + * elements. + * + * @see Style + * @package dompdf + */ +class Stylesheet +{ + /** + * The location of the default built-in CSS file. + */ + const DEFAULT_STYLESHEET = "/lib/res/html.css"; + + /** + * User agent stylesheet origin + * + * @var int + */ + const ORIG_UA = 1; + + /** + * User normal stylesheet origin + * + * @var int + */ + const ORIG_USER = 2; + + /** + * Author normal stylesheet origin + * + * @var int + */ + const ORIG_AUTHOR = 3; + + /* + * The highest possible specificity is 0x01000000 (and that is only for author + * stylesheets, as it is for inline styles). Origin precedence can be achieved by + * adding multiples of 0x10000000 to the actual specificity. Important + * declarations are handled in Style; though technically they should be handled + * here so that user important declarations can be made to take precedence over + * user important declarations, this doesn't matter in practice as Dompdf does + * not support user stylesheets, and user agent stylesheets can not include + * important declarations. + */ + private static $_stylesheet_origins = [ + self::ORIG_UA => 0x00000000, // user agent declarations + self::ORIG_USER => 0x10000000, // user normal declarations + self::ORIG_AUTHOR => 0x30000000, // author normal declarations + ]; + + /* + * Non-CSS presentational hints (i.e. HTML 4 attributes) are handled as if added + * to the beginning of an author stylesheet, i.e. anything in author stylesheets + * should override them. + */ + const SPEC_NON_CSS = 0x20000000; + + /** + * Current dompdf instance + * + * @var Dompdf + */ + private $_dompdf; + + /** + * Array of currently defined styles + * + * @var Style[] + */ + private $_styles; + + /** + * Base protocol of the document being parsed + * Used to handle relative urls. + * + * @var string + */ + private $_protocol; + + /** + * Base hostname of the document being parsed + * Used to handle relative urls. + * + * @var string + */ + private $_base_host; + + /** + * Base path of the document being parsed + * Used to handle relative urls. + * + * @var string + */ + private $_base_path; + + /** + * The styles defined by @page rules + * + * @var array + $child = $child->nextSibling; + } + } else { + $css = $tag->nodeValue; + } + + // Set the base path of the Stylesheet to that of the file being processed + $this->css->set_protocol($this->protocol); + $this->css->set_host($this->baseHost); + $this->css->set_base_path($this->basePath); + + $this->css->load_css($css, Stylesheet::ORIG_AUTHOR); + break; + } + + // Set the base path of the Stylesheet to that of the file being processed + $this->css->set_protocol($this->protocol); + $this->css->set_host($this->baseHost); + $this->css->set_base_path($this->basePath); + } + } + + /** + * @param string $cacheId + * @deprecated + */ + public function enable_caching($cacheId) + { + $this->enableCaching($cacheId); + } + + /** + * Enable experimental caching capability + * + * @param string $cacheId + */ + public function enableCaching($cacheId) + { + $this->cacheId = $cacheId; + } + + /** + * @param string $value + * @return bool + * @deprecated + */ + public function parse_default_view($value) + { + return $this->parseDefaultView($value); + } + + /** + * @param string $value + * @return bool + */ + public function parseDefaultView($value) + { + $valid = ["XYZ", "Fit", "FitH", "FitV", "FitR", "FitB", "FitBH", "FitBV"]; + + $options = preg_split("/\s*,\s*/", trim($value)); + $defaultView = array_shift($options); + + if (!in_array($defaultView, $valid)) { + return false; + } + + $this->setDefaultView($defaultView, $options); + return true; + } + + /** + * Renders the HTML to PDF + */ + public function render() + { + $this->saveLocale(); + $options = $this->options; + + $logOutputFile = $options->getLogOutputFile(); + if ($logOutputFile) { + if (!file_exists($logOutputFile) && is_writable(dirname($logOutputFile))) { + touch($logOutputFile); + } + + $this->startTime = microtime(true); + if (is_writable($logOutputFile)) { + ob_start(); + } + } + + $this->processHtml(); + + $this->css->apply_styles($this->tree); + + // @page style rules : size, margins + $pageStyles = $this->css->get_page_styles(); + $basePageStyle = $pageStyles["base"]; + unset($pageStyles["base"]); + + foreach ($pageStyles as $pageStyle) { + $pageStyle->inherit($basePageStyle); + } + + $defaultOptionPaperSize = $this->getPaperSize($options->getDefaultPaperSize()); + // If there is a CSS defined paper size compare to the paper size used to create the canvas to determine a + // recreation need + if (is_array($basePageStyle->size)) { + $basePageStyleSize = $basePageStyle->size; + $this->setPaper([0, 0, $basePageStyleSize[0], $basePageStyleSize[1]]); + } + + $paperSize = $this->getPaperSize(); + if ( + $defaultOptionPaperSize[2] !== $paperSize[2] || + $defaultOptionPaperSize[3] !== $paperSize[3] || + $options->getDefaultPaperOrientation() !== $this->paperOrientation + ) { + $this->setCanvas(CanvasFactory::get_instance($this, $this->paperSize, $this->paperOrientation)); + $this->fontMetrics->setCanvas($this->getCanvas()); + } + + $canvas = $this->getCanvas(); + + $root = null; + + foreach ($this->tree->get_frames() as $frame) { + // Set up the root frame + if (is_null($root)) { + $root = Factory::decorate_root($this->tree->get_root(), $this); + continue; + } + + // Create the appropriate decorators, reflowers & positioners. + Factory::decorate_frame($frame, $this, $root); + } + + // Add meta information + $title = $this->dom->getElementsByTagName("title"); + if ($title->length) { + $canvas->add_info("Title", trim($title->item(0)->nodeValue)); + } + + $metas = $this->dom->getElementsByTagName("meta"); + $labels = [ + "author" => "Author", + "keywords" => "Keywords", + "description" => "Subject", + ]; + /** @var \DOMElement $meta */ + foreach ($metas as $meta) { + $name = mb_strtolower($meta->getAttribute("name")); + $value = trim($meta->getAttribute("content")); + + if (isset($labels[$name])) { + $canvas->add_info($labels[$name], $value); + continue; + } + + if ($name === "dompdf.view" && $this->parseDefaultView($value)) { + $canvas->set_default_view($this->defaultView, $this->defaultViewOptions); + } + } + + $root->set_containing_block(0, 0, $canvas->get_width(), $canvas->get_height()); + $root->set_renderer(new Renderer($this)); + + // This is where the magic happens: + $root->reflow(); + + // Clean up cached images + Cache::clear(); + + global $_dompdf_warnings, $_dompdf_show_warnings; + if ($_dompdf_show_warnings && isset($_dompdf_warnings)) { + echo 'Dompdf Warnings
';
+            foreach ($_dompdf_warnings as $msg) {
+                echo $msg . "\n";
+            }
+
+            if ($canvas instanceof CPDF) {
+                echo $canvas->get_cpdf()->messages;
+            }
+            echo '
'; + flush(); + } + + if ($logOutputFile && is_writable($logOutputFile)) { + $this->write_log(); + ob_end_clean(); + } + + $this->restoreLocale(); + } + + /** + * Add meta information to the PDF after rendering + */ + public function add_info($label, $value) + { + $canvas = $this->getCanvas(); + if (!is_null($canvas)) { + $canvas->add_info($label, $value); + } + } + + /** + * Writes the output buffer in the log file + * + * @return void + */ + private function write_log() + { + $log_output_file = $this->getOptions()->getLogOutputFile(); + if (!$log_output_file || !is_writable($log_output_file)) { + return; + } + + $frames = Frame::$ID_COUNTER; + $memory = memory_get_peak_usage(true) / 1024; + $time = (microtime(true) - $this->startTime) * 1000; + + $out = sprintf( + "%6d" . + "%10.2f KB" . + "%10.2f ms" . + " " . + ($this->quirksmode ? " ON" : "OFF") . + "
", $frames, $memory, $time); + + $out .= ob_get_contents(); + ob_clean(); + + file_put_contents($log_output_file, $out); + } + + /** + * Streams the PDF to the client. + * + * The file will open a download dialog by default. The options + * parameter controls the output. Accepted options (array keys) are: + * + * 'compress' = > 1 (=default) or 0: + * Apply content stream compression + * + * 'Attachment' => 1 (=default) or 0: + * Set the 'Content-Disposition:' HTTP header to 'attachment' + * (thereby causing the browser to open a download dialog) + * + * @param string $filename the name of the streamed file + * @param array $options header options (see above) + */ + public function stream($filename = "document.pdf", $options = []) + { + $this->saveLocale(); + + $canvas = $this->getCanvas(); + if (!is_null($canvas)) { + $canvas->stream($filename, $options); + } + + $this->restoreLocale(); + } + + /** + * Returns the PDF as a string. + * + * The options parameter controls the output. Accepted options are: + * + * 'compress' = > 1 or 0 - apply content stream compression, this is + * on (1) by default + * + * @param array $options options (see above) + * + * @return string|null + */ + public function output($options = []) + { + $this->saveLocale(); + + $canvas = $this->getCanvas(); + if (is_null($canvas)) { + return null; + } + + $output = $canvas->output($options); + + $this->restoreLocale(); + + return $output; + } + + /** + * @return string + * @deprecated + */ + public function output_html() + { + return $this->outputHtml(); + } + + /** + * Returns the underlying HTML document as a string + * + * @return string + */ + public function outputHtml() + { + return $this->dom->saveHTML(); + } + + /** + * Get the dompdf option value + * + * @param string $key + * @return mixed + * @deprecated + */ + public function get_option($key) + { + return $this->options->get($key); + } + + /** + * @param string $key + * @param mixed $value + * @return $this + * @deprecated + */ + public function set_option($key, $value) + { + $this->options->set($key, $value); + return $this; + } + + /** + * @param array $options + * @return $this + * @deprecated + */ + public function set_options(array $options) + { + $this->options->set($options); + return $this; + } + + /** + * @param string $size + * @param string $orientation + * @deprecated + */ + public function set_paper($size, $orientation = "portrait") + { + $this->setPaper($size, $orientation); + } + + /** + * Sets the paper size & orientation + * + * @param string|array $size 'letter', 'legal', 'A4', etc. {@link Dompdf\Adapter\CPDF::$PAPER_SIZES} + * @param string $orientation 'portrait' or 'landscape' + * @return $this + */ + public function setPaper($size, $orientation = "portrait") + { + $this->paperSize = $size; + $this->paperOrientation = $orientation; + return $this; + } + + /** + * Gets the paper size + * + * @param null|string|array $paperSize + * @return int[] A four-element integer array + */ + public function getPaperSize($paperSize = null) + { + $size = $paperSize !== null ? $paperSize : $this->paperSize; + if (is_array($size)) { + return $size; + } else if (isset(Adapter\CPDF::$PAPER_SIZES[mb_strtolower($size)])) { + return Adapter\CPDF::$PAPER_SIZES[mb_strtolower($size)]; + } else { + return Adapter\CPDF::$PAPER_SIZES["letter"]; + } + } + + /** + * Gets the paper orientation + * + * @return string Either "portrait" or "landscape" + */ + public function getPaperOrientation() + { + return $this->paperOrientation; + } + + /** + * @param FrameTree $tree + * @return $this + */ + public function setTree(FrameTree $tree) + { + $this->tree = $tree; + return $this; + } + + /** + * @return FrameTree + * @deprecated + */ + public function get_tree() + { + return $this->getTree(); + } + + /** + * Returns the underlying {@link FrameTree} object + * + * @return FrameTree + */ + public function getTree() + { + return $this->tree; + } + + /** + * @param string $protocol + * @return $this + * @deprecated + */ + public function set_protocol($protocol) + { + return $this->setProtocol($protocol); + } + + /** + * Sets the protocol to use + * FIXME validate these + * + * @param string $protocol + * @return $this + */ + public function setProtocol($protocol) + { + $this->protocol = $protocol; + return $this; + } + + /** + * @return string + * @deprecated + */ + public function get_protocol() + { + return $this->getProtocol(); + } + + /** + * Returns the protocol in use + * + * @return string + */ + public function getProtocol() + { + return $this->protocol; + } + + /** + * @param string $host + * @deprecated + */ + public function set_host($host) + { + $this->setBaseHost($host); + } + + /** + * Sets the base hostname + * + * @param string $baseHost + * @return $this + */ + public function setBaseHost($baseHost) + { + $this->baseHost = $baseHost; + return $this; + } + + /** + * @return string + * @deprecated + */ + public function get_host() + { + return $this->getBaseHost(); + } + + /** + * Returns the base hostname + * + * @return string + */ + public function getBaseHost() + { + return $this->baseHost; + } + + /** + * Sets the base path + * + * @param string $path + * @deprecated + */ + public function set_base_path($path) + { + $this->setBasePath($path); + } + + /** + * Sets the base path + * + * @param string $basePath + * @return $this + */ + public function setBasePath($basePath) + { + $this->basePath = $basePath; + return $this; + } + + /** + * @return string + * @deprecated + */ + public function get_base_path() + { + return $this->getBasePath(); + } + + /** + * Returns the base path + * + * @return string + */ + public function getBasePath() + { + return $this->basePath; + } + + /** + * @param string $default_view The default document view + * @param array $options The view's options + * @return $this + * @deprecated + */ + public function set_default_view($default_view, $options) + { + return $this->setDefaultView($default_view, $options); + } + + /** + * Sets the default view + * + * @param string $defaultView The default document view + * @param array $options The view's options + * @return $this + */ + public function setDefaultView($defaultView, $options) + { + $this->defaultView = $defaultView; + $this->defaultViewOptions = $options; + return $this; + } + + /** + * @param resource $http_context + * @return $this + * @deprecated + */ + public function set_http_context($http_context) + { + return $this->setHttpContext($http_context); + } + + /** + * Sets the HTTP context + * + * @param resource $httpContext + * @return $this + */ + public function setHttpContext($httpContext) + { + $this->httpContext = $httpContext; + return $this; + } + + /** + * @return resource + * @deprecated + */ + public function get_http_context() + { + return $this->getHttpContext(); + } + + /** + * Returns the HTTP context + * + * @return resource + */ + public function getHttpContext() + { + return $this->httpContext; + } + + /** + * @param Canvas $canvas + * @return $this + */ + public function setCanvas(Canvas $canvas) + { + $this->canvas = $canvas; + return $this; + } + + /** + * @return Canvas + * @deprecated + */ + public function get_canvas() + { + return $this->getCanvas(); + } + + /** + * Return the underlying Canvas instance (e.g. Dompdf\Adapter\CPDF, Dompdf\Adapter\GD) + * + * @return Canvas + */ + public function getCanvas() + { + return $this->canvas; + } + + /** + * @param Stylesheet $css + * @return $this + */ + public function setCss(Stylesheet $css) + { + $this->css = $css; + return $this; + } + + /** + * @return Stylesheet + * @deprecated + */ + public function get_css() + { + return $this->getCss(); + } + + /** + * Returns the stylesheet + * + * @return Stylesheet + */ + public function getCss() + { + return $this->css; + } + + /** + * @param DOMDocument $dom + * @return $this + */ + public function setDom(DOMDocument $dom) + { + $this->dom = $dom; + return $this; + } + + /** + * @return DOMDocument + * @deprecated + */ + public function get_dom() + { + return $this->getDom(); + } + + /** + * @return DOMDocument + */ + public function getDom() + { + return $this->dom; + } + + /** + * @param Options $options + * @return $this + */ + public function setOptions(Options $options) + { + $this->options = $options; + $fontMetrics = $this->getFontMetrics(); + if (isset($fontMetrics)) { + $fontMetrics->setOptions($options); + } + return $this; + } + + /** + * @return Options + */ + public function getOptions() + { + return $this->options; + } + + /** + * @return array + * @deprecated + */ + public function get_callbacks() + { + return $this->getCallbacks(); + } + + /** + * Returns the callbacks array + * + * @return array + */ + public function getCallbacks() + { + return $this->callbacks; + } + + /** + * @param array $callbacks the set of callbacks to set + * @deprecated + */ + public function set_callbacks($callbacks) + { + $this->setCallbacks($callbacks); + } + + /** + * Sets callbacks for events like rendering of pages and elements. + * The callbacks array contains arrays with 'event' set to 'begin_page', + * 'end_page', 'begin_frame', or 'end_frame' and 'f' set to a function or + * object plus method to be called. + * + * The function 'f' must take an array as argument, which contains info + * about the event. + * + * @param array $callbacks the set of callbacks to set + */ + public function setCallbacks($callbacks) + { + if (is_array($callbacks)) { + $this->callbacks = []; + foreach ($callbacks as $c) { + if (is_array($c) && isset($c['event']) && isset($c['f'])) { + $event = $c['event']; + $f = $c['f']; + if (is_callable($f) && is_string($event)) { + $this->callbacks[$event][] = $f; + } + } + } + } + } + + /** + * @return boolean + * @deprecated + */ + public function get_quirksmode() + { + return $this->getQuirksmode(); + } + + /** + * Get the quirks mode + * + * @return boolean true if quirks mode is active + */ + public function getQuirksmode() + { + return $this->quirksmode; + } + + /** + * @param FontMetrics $fontMetrics + * @return $this + */ + public function setFontMetrics(FontMetrics $fontMetrics) + { + $this->fontMetrics = $fontMetrics; + return $this; + } + + /** + * @return FontMetrics + */ + public function getFontMetrics() + { + return $this->fontMetrics; + } + + /** + * PHP5 overloaded getter + * Along with {@link Dompdf::__set()} __get() provides access to all + * properties directly. Typically __get() is not called directly outside + * of this class. + * + * @param string $prop + * + * @throws Exception + * @return mixed + */ + function __get($prop) + { + switch ($prop) + { + case 'version' : + return $this->version; + default: + throw new Exception( 'Invalid property: ' . $prop ); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Exception.php b/vendor/dompdf/dompdf/src/Exception.php new file mode 100644 index 0000000..c9fb0df --- /dev/null +++ b/vendor/dompdf/dompdf/src/Exception.php @@ -0,0 +1,29 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf; + +/** + * Standard exception thrown by DOMPDF classes + * + * @package dompdf + */ +class Exception extends \Exception +{ + + /** + * Class constructor + * + * @param string $message Error message + * @param int $code Error code + */ + public function __construct($message = null, $code = 0) + { + parent::__construct($message, $code); + } +} diff --git a/vendor/dompdf/dompdf/src/Exception/ImageException.php b/vendor/dompdf/dompdf/src/Exception/ImageException.php new file mode 100644 index 0000000..62b44b1 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Exception/ImageException.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Exception; + +use Dompdf\Exception; + +/** + * Image exception thrown by DOMPDF + * + * @package dompdf + */ +class ImageException extends Exception +{ + + /** + * Class constructor + * + * @param string $message Error message + * @param int $code Error code + */ + function __construct($message = null, $code = 0) + { + parent::__construct($message, $code); + } + +} diff --git a/vendor/dompdf/dompdf/src/FontMetrics.php b/vendor/dompdf/dompdf/src/FontMetrics.php new file mode 100644 index 0000000..9af41ba --- /dev/null +++ b/vendor/dompdf/dompdf/src/FontMetrics.php @@ -0,0 +1,578 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf; + +use FontLib\Font; + +/** + * The font metrics class + * + * This class provides information about fonts and text. It can resolve + * font names into actual installed font files, as well as determine the + * size of text in a particular font and size. + * + * @static + * @package dompdf + */ +class FontMetrics +{ + /** + * Name of the font cache file + * + * This file must be writable by the webserver process only to update it + * with save_font_families() after adding the .afm file references of a new font family + * with FontMetrics::saveFontFamilies(). + * This is typically done only from command line with load_font.php on converting + * ttf fonts to ufm with php-font-lib. + */ + const CACHE_FILE = "dompdf_font_family_cache.php"; + + /** + * @var Canvas + * @deprecated + */ + protected $pdf; + + /** + * Underlying {@link Canvas} object to perform text size calculations + * + * @var Canvas + */ + protected $canvas; + + /** + * Array of font family names to font files + * + * Usually cached by the {@link load_font.php} script + * + * @var array + */ + protected $fontLookup = []; + + /** + * @var Options + */ + private $options; + + /** + * Class initialization + */ + public function __construct(Canvas $canvas, Options $options) + { + $this->setCanvas($canvas); + $this->setOptions($options); + $this->loadFontFamilies(); + } + + /** + * @deprecated + */ + public function save_font_families() + { + $this->saveFontFamilies(); + } + + /** + * Saves the stored font family cache + * + * The name and location of the cache file are determined by {@link + * FontMetrics::CACHE_FILE}. This file should be writable by the + * webserver process. + * + * @see FontMetrics::loadFontFamilies() + */ + public function saveFontFamilies() + { + // replace the path to the DOMPDF font directories with the corresponding constants (allows for more portability) + $cacheData = sprintf("fontLookup as $family => $variants) { + $cacheData .= sprintf(" '%s' => array(%s", addslashes($family), PHP_EOL); + foreach ($variants as $variant => $path) { + $path = sprintf("'%s'", $path); + $path = str_replace('\'' . $this->getOptions()->getFontDir() , '$fontDir . \'' , $path); + $path = str_replace('\'' . $this->getOptions()->getRootDir() , '$rootDir . \'' , $path); + $cacheData .= sprintf(" '%s' => %s,%s", $variant, $path, PHP_EOL); + } + $cacheData .= sprintf(" ),%s", PHP_EOL); + } + $cacheData .= ") ?>"; + file_put_contents($this->getCacheFile(), $cacheData); + } + + /** + * @deprecated + */ + public function load_font_families() + { + $this->loadFontFamilies(); + } + + /** + * Loads the stored font family cache + * + * @see FontMetrics::saveFontFamilies() + */ + public function loadFontFamilies() + { + $fontDir = $this->getOptions()->getFontDir(); + $rootDir = $this->getOptions()->getRootDir(); + + // FIXME: temporarily define constants for cache files <= v0.6.2 + if (!defined("DOMPDF_DIR")) { define("DOMPDF_DIR", $rootDir); } + if (!defined("DOMPDF_FONT_DIR")) { define("DOMPDF_FONT_DIR", $fontDir); } + + $file = $rootDir . "/lib/fonts/dompdf_font_family_cache.dist.php"; + $distFonts = require $file; + + if (!is_readable($this->getCacheFile())) { + $this->fontLookup = $distFonts; + return; + } + + $cacheData = require $this->getCacheFile(); + + $this->fontLookup = []; + if (is_array($this->fontLookup)) { + foreach ($cacheData as $key => $value) { + $this->fontLookup[stripslashes($key)] = $value; + } + } + + // Merge provided fonts + $this->fontLookup += $distFonts; + } + + /** + * @param array $style + * @param string $remote_file + * @param resource $context + * @return bool + * @deprecated + */ + public function register_font($style, $remote_file, $context = null) + { + return $this->registerFont($style, $remote_file); + } + + /** + * @param array $style + * @param string $remoteFile + * @param resource $context + * @return bool + */ + public function registerFont($style, $remoteFile, $context = null) + { + $fontname = mb_strtolower($style["family"]); + $families = $this->getFontFamilies(); + + $entry = []; + if (isset($families[$fontname])) { + $entry = $families[$fontname]; + } + + $styleString = $this->getType("{$style['weight']} {$style['style']}"); + + $fontDir = $this->getOptions()->getFontDir(); + $remoteHash = md5($remoteFile); + + $prefix = $fontname . "_" . $styleString; + $prefix = preg_replace("/[^\\pL\d]+/u", "-", $prefix); + $prefix = trim($prefix, "-"); + if (function_exists('iconv')) { + $prefix = iconv('utf-8', 'us-ascii//TRANSLIT', $prefix); + } + $prefix = preg_replace("/[^-\w]+/", "", $prefix); + + $localFile = $fontDir . "/" . $prefix . "_" . $remoteHash; + + if (isset($entry[$styleString]) && $localFile == $entry[$styleString]) { + return true; + } + + $cacheEntry = $localFile; + $localFile .= ".".strtolower(pathinfo(parse_url($remoteFile, PHP_URL_PATH), PATHINFO_EXTENSION)); + + $entry[$styleString] = $cacheEntry; + + // Download the remote file + [$protocol, $baseHost, $basePath] = Helpers::explode_url($remoteFile); + if (!$this->options->isRemoteEnabled() && ($protocol != "" && $protocol !== "file://")) { + Helpers::record_warnings(E_USER_WARNING, "Remote font resource $remoteFile referenced, but remote file download is disabled.", __FILE__, __LINE__); + return false; + } + if ($protocol == "" || $protocol === "file://") { + $realfile = realpath($remoteFile); + + $rootDir = realpath($this->options->getRootDir()); + if (strpos($realfile, $rootDir) !== 0) { + $chroot = realpath($this->options->getChroot()); + if (!$chroot || strpos($realfile, $chroot) !== 0) { + Helpers::record_warnings(E_USER_WARNING, "Permission denied on $remoteFile. The file could not be found under the directory specified by Options::chroot.", __FILE__, __LINE__); + return false; + } + } + + if (!$realfile) { + Helpers::record_warnings(E_USER_WARNING, "File '$realfile' not found.", __FILE__, __LINE__); + return false; + } + + $remoteFile = $realfile; + } + list($remoteFileContent, $http_response_header) = @Helpers::getFileContent($remoteFile, $context); + if (empty($remoteFileContent)) { + return false; + } + + $localTempFile = @tempnam($this->options->get("tempDir"), "dompdf-font-"); + file_put_contents($localTempFile, $remoteFileContent); + + $font = Font::load($localTempFile); + + if (!$font) { + unlink($localTempFile); + return false; + } + + $font->parse(); + $font->saveAdobeFontMetrics("$cacheEntry.ufm"); + $font->close(); + + unlink($localTempFile); + + if ( !file_exists("$cacheEntry.ufm") ) { + return false; + } + + // Save the changes + file_put_contents($localFile, $remoteFileContent); + + if ( !file_exists($localFile) ) { + unlink("$cacheEntry.ufm"); + return false; + } + + $this->setFontFamily($fontname, $entry); + $this->saveFontFamilies(); + + return true; + } + + /** + * @param $text + * @param $font + * @param $size + * @param float $word_spacing + * @param float $char_spacing + * @return float + * @deprecated + */ + public function get_text_width($text, $font, $size, $word_spacing = 0.0, $char_spacing = 0.0) + { + //return self::$_pdf->get_text_width($text, $font, $size, $word_spacing, $char_spacing); + return $this->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); + } + + /** + * Calculates text size, in points + * + * @param string $text the text to be sized + * @param string $font the desired font + * @param float $size the desired font size + * @param float $wordSpacing + * @param float $charSpacing + * + * @internal param float $spacing word spacing, if any + * @return float + */ + public function getTextWidth($text, $font, $size, $wordSpacing = 0.0, $charSpacing = 0.0) + { + // @todo Make sure this cache is efficient before enabling it + static $cache = []; + + if ($text === "") { + return 0; + } + + // Don't cache long strings + $useCache = !isset($text[50]); // Faster than strlen + + $key = "$font/$size/$wordSpacing/$charSpacing"; + + if ($useCache && isset($cache[$key][$text])) { + return $cache[$key]["$text"]; + } + + $width = $this->getCanvas()->get_text_width($text, $font, $size, $wordSpacing, $charSpacing); + + if ($useCache) { + $cache[$key][$text] = $width; + } + + return $width; + } + + /** + * @param $font + * @param $size + * @return float + * @deprecated + */ + public function get_font_height($font, $size) + { + return $this->getFontHeight($font, $size); + } + + /** + * Calculates font height + * + * @param string $font + * @param float $size + * + * @return float + */ + public function getFontHeight($font, $size) + { + return $this->getCanvas()->get_font_height($font, $size); + } + + /** + * @param $family_raw + * @param string $subtype_raw + * @return string + * @deprecated + */ + public function get_font($family_raw, $subtype_raw = "normal") + { + return $this->getFont($family_raw, $subtype_raw); + } + + /** + * Resolves a font family & subtype into an actual font file + * Subtype can be one of 'normal', 'bold', 'italic' or 'bold_italic'. If + * the particular font family has no suitable font file, the default font + * ({@link Options::defaultFont}) is used. The font file returned + * is the absolute pathname to the font file on the system. + * + * @param string $familyRaw + * @param string $subtypeRaw + * + * @return string + */ + public function getFont($familyRaw, $subtypeRaw = "normal") + { + static $cache = []; + + if (isset($cache[$familyRaw][$subtypeRaw])) { + return $cache[$familyRaw][$subtypeRaw]; + } + + /* Allow calling for various fonts in search path. Therefore not immediately + * return replacement on non match. + * Only when called with NULL try replacement. + * When this is also missing there is really trouble. + * If only the subtype fails, nevertheless return failure. + * Only on checking the fallback font, check various subtypes on same font. + */ + + $subtype = strtolower($subtypeRaw); + + if ($familyRaw) { + $family = str_replace(["'", '"'], "", strtolower($familyRaw)); + + if (isset($this->fontLookup[$family][$subtype])) { + return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype]; + } + + return null; + } + + $family = "serif"; + + if (isset($this->fontLookup[$family][$subtype])) { + return $cache[$familyRaw][$subtypeRaw] = $this->fontLookup[$family][$subtype]; + } + + if (!isset($this->fontLookup[$family])) { + return null; + } + + $family = $this->fontLookup[$family]; + + foreach ($family as $sub => $font) { + if (strpos($subtype, $sub) !== false) { + return $cache[$familyRaw][$subtypeRaw] = $font; + } + } + + if ($subtype !== "normal") { + foreach ($family as $sub => $font) { + if ($sub !== "normal") { + return $cache[$familyRaw][$subtypeRaw] = $font; + } + } + } + + $subtype = "normal"; + + if (isset($family[$subtype])) { + return $cache[$familyRaw][$subtypeRaw] = $family[$subtype]; + } + + return null; + } + + /** + * @param $family + * @return null|string + * @deprecated + */ + public function get_family($family) + { + return $this->getFamily($family); + } + + /** + * @param string $family + * @return null|string + */ + public function getFamily($family) + { + $family = str_replace(["'", '"'], "", mb_strtolower($family)); + + if (isset($this->fontLookup[$family])) { + return $this->fontLookup[$family]; + } + + return null; + } + + /** + * @param $type + * @return string + * @deprecated + */ + public function get_type($type) + { + return $this->getType($type); + } + + /** + * @param string $type + * @return string + */ + public function getType($type) + { + if (preg_match('/bold/i', $type)) { + $weight = 700; + } elseif (preg_match('/([1-9]00)/', $type, $match)) { + $weight = (int)$match[0]; + } else { + $weight = 400; + } + $weight = $weight === 400 ? 'normal' : $weight; + $weight = $weight === 700 ? 'bold' : $weight; + + $style = preg_match('/italic|oblique/i', $type) ? 'italic' : null; + + if ($weight === 'normal' && $style !== null) { + return $style; + } + + return $style === null + ? $weight + : $weight.'_'.$style; + } + + /** + * @return array + * @deprecated + */ + public function get_font_families() + { + return $this->getFontFamilies(); + } + + /** + * Returns the current font lookup table + * + * @return array + */ + public function getFontFamilies() + { + return $this->fontLookup; + } + + /** + * @param string $fontname + * @param mixed $entry + * @deprecated + */ + public function set_font_family($fontname, $entry) + { + $this->setFontFamily($fontname, $entry); + } + + /** + * @param string $fontname + * @param mixed $entry + */ + public function setFontFamily($fontname, $entry) + { + $this->fontLookup[mb_strtolower($fontname)] = $entry; + } + + /** + * @return string + */ + public function getCacheFile() + { + return $this->getOptions()->getFontDir() . '/' . self::CACHE_FILE; + } + + /** + * @param Options $options + * @return $this + */ + public function setOptions(Options $options) + { + $this->options = $options; + return $this; + } + + /** + * @return Options + */ + public function getOptions() + { + return $this->options; + } + + /** + * @param Canvas $canvas + * @return $this + */ + public function setCanvas(Canvas $canvas) + { + $this->canvas = $canvas; + // Still write deprecated pdf for now. It might be used by a parent class. + $this->pdf = $canvas; + return $this; + } + + /** + * @return Canvas + */ + public function getCanvas() + { + return $this->canvas; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Frame.php b/vendor/dompdf/dompdf/src/Frame.php new file mode 100644 index 0000000..ac38fa2 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame.php @@ -0,0 +1,1261 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +/** + * The main Frame class + * + * This class represents a single HTML element. This class stores + * positioning information as well as containing block location and + * dimensions. Style information for the element is stored in a {@link + * Style} object. Tree structure is maintained via the parent & children + * links. + * + * @package dompdf + */ +class Frame +{ + const WS_TEXT = 1; + const WS_SPACE = 2; + + /** + * The DOMElement or DOMText object this frame represents + * + * @var \DOMElement|\DOMText + */ + protected $_node; + + /** + * Unique identifier for this frame. Used to reference this frame + * via the node. + * + * @var string + */ + protected $_id; + + /** + * Unique id counter + */ + public static $ID_COUNTER = 0; /*protected*/ + + /** + * This frame's calculated style + * + * @var Style + */ + protected $_style; + + /** + * This frame's original style. Needed for cases where frames are + * split across pages. + * + * @var Style + */ + protected $_original_style; + + /** + * This frame's parent in the document tree. + * + * @var Frame + */ + protected $_parent; + + /** + * This frame's children + * + * @var Frame[] + */ + protected $_frame_list; + + /** + * This frame's first child. All children are handled as a + * doubly-linked list. + * + * @var Frame + */ + protected $_first_child; + + /** + * This frame's last child. + * + * @var Frame + */ + protected $_last_child; + + /** + * This frame's previous sibling in the document tree. + * + * @var Frame + */ + protected $_prev_sibling; + + /** + * This frame's next sibling in the document tree. + * + * @var Frame + */ + protected $_next_sibling; + + /** + * This frame's containing block (used in layout): array(x, y, w, h) + * + * @var float[] + */ + protected $_containing_block; + + /** + * Position on the page of the top-left corner of the margin box of + * this frame: array(x,y) + * + * @var float[] + */ + protected $_position; + + /** + * Absolute opacity of this frame + * + * @var float + */ + protected $_opacity; + + /** + * This frame's decorator + * + * @var \Dompdf\FrameDecorator\AbstractFrameDecorator + */ + protected $_decorator; + + /** + * This frame's containing line box + * + * @var LineBox + */ + protected $_containing_line; + + /** + * @var array + */ + protected $_is_cache = []; + + /** + * Tells whether the frame was already pushed to the next page + * + * @var bool + */ + public $_already_pushed = false; + + /** + * @var bool + */ + public $_float_next_line = false; + + /** + * Tells whether the frame was split + * + * @var bool + */ + public $_splitted; + + /** + * @var int + */ + public static $_ws_state = self::WS_SPACE; + + /** + * Class constructor + * + * @param \DOMNode $node the DOMNode this frame represents + */ + public function __construct(\DOMNode $node) + { + $this->_node = $node; + + $this->_parent = null; + $this->_first_child = null; + $this->_last_child = null; + $this->_prev_sibling = $this->_next_sibling = null; + + $this->_style = null; + $this->_original_style = null; + + $this->_containing_block = [ + "x" => null, + "y" => null, + "w" => null, + "h" => null, + ]; + + $this->_containing_block[0] =& $this->_containing_block["x"]; + $this->_containing_block[1] =& $this->_containing_block["y"]; + $this->_containing_block[2] =& $this->_containing_block["w"]; + $this->_containing_block[3] =& $this->_containing_block["h"]; + + $this->_position = [ + "x" => null, + "y" => null, + ]; + + $this->_position[0] =& $this->_position["x"]; + $this->_position[1] =& $this->_position["y"]; + + $this->_opacity = 1.0; + $this->_decorator = null; + + $this->set_id(self::$ID_COUNTER++); + } + + /** + * WIP : preprocessing to remove all the unused whitespace + */ + protected function ws_trim() + { + if ($this->ws_keep()) { + return; + } + + if (self::$_ws_state === self::WS_SPACE) { + $node = $this->_node; + + if ($node->nodeName === "#text" && !empty($node->nodeValue)) { + $node->nodeValue = preg_replace("/[ \t\r\n\f]+/u", " ", trim($node->nodeValue)); + self::$_ws_state = self::WS_TEXT; + } + } + } + + /** + * @return bool + */ + protected function ws_keep() + { + $whitespace = $this->get_style()->white_space; + + return in_array($whitespace, ["pre", "pre-wrap", "pre-line"]); + } + + /** + * @return bool + */ + protected function ws_is_text() + { + $node = $this->get_node(); + + if ($node->nodeName === "img") { + return true; + } + + if (!$this->is_in_flow()) { + return false; + } + + if ($this->is_text_node()) { + return trim($node->nodeValue) !== ""; + } + + return true; + } + + /** + * "Destructor": forcibly free all references held by this frame + * + * @param bool $recursive if true, call dispose on all children + */ + public function dispose($recursive = false) + { + if ($recursive) { + while ($child = $this->_first_child) { + $child->dispose(true); + } + } + + // Remove this frame from the tree + if ($this->_prev_sibling) { + $this->_prev_sibling->_next_sibling = $this->_next_sibling; + } + + if ($this->_next_sibling) { + $this->_next_sibling->_prev_sibling = $this->_prev_sibling; + } + + if ($this->_parent && $this->_parent->_first_child === $this) { + $this->_parent->_first_child = $this->_next_sibling; + } + + if ($this->_parent && $this->_parent->_last_child === $this) { + $this->_parent->_last_child = $this->_prev_sibling; + } + + if ($this->_parent) { + $this->_parent->get_node()->removeChild($this->_node); + } + + $this->_style->dispose(); + $this->_style = null; + unset($this->_style); + + $this->_original_style->dispose(); + $this->_original_style = null; + unset($this->_original_style); + } + + /** + * Re-initialize the frame + */ + public function reset() + { + $this->_position["x"] = null; + $this->_position["y"] = null; + + $this->_containing_block["x"] = null; + $this->_containing_block["y"] = null; + $this->_containing_block["w"] = null; + $this->_containing_block["h"] = null; + + $this->_style = null; + unset($this->_style); + $this->_style = clone $this->_original_style; + + // If this represents a generated node then child nodes represent generated content. + // Remove the children since the content will be generated next time this frame is reflowed. + if ($this->_node->nodeName === "dompdf_generated" && $this->_style->content != "normal") { + foreach ($this->get_children() as $child) { + $this->remove_child($child); + } + } + } + + /** + * @return \DOMElement|\DOMText + */ + public function get_node() + { + return $this->_node; + } + + /** + * @return string + */ + public function get_id() + { + return $this->_id; + } + + /** + * @return Style + */ + public function get_style() + { + return $this->_style; + } + + /** + * @return Style + */ + public function get_original_style() + { + return $this->_original_style; + } + + /** + * @return Frame + */ + public function get_parent() + { + return $this->_parent; + } + + /** + * @return \Dompdf\FrameDecorator\AbstractFrameDecorator + */ + public function get_decorator() + { + return $this->_decorator; + } + + /** + * @return Frame + */ + public function get_first_child() + { + return $this->_first_child; + } + + /** + * @return Frame + */ + public function get_last_child() + { + return $this->_last_child; + } + + /** + * @return Frame + */ + public function get_prev_sibling() + { + return $this->_prev_sibling; + } + + /** + * @return Frame + */ + public function get_next_sibling() + { + return $this->_next_sibling; + } + + /** + * @return FrameList|Frame[] + */ + public function get_children() + { + if (isset($this->_frame_list)) { + return $this->_frame_list; + } + + $this->_frame_list = new FrameList($this); + + return $this->_frame_list; + } + + // Layout property accessors + + /** + * Containing block dimensions + * + * @param $i string The key of the wanted containing block's dimension (x, y, w, h) + * + * @return float[]|float + */ + public function get_containing_block($i = null) + { + if (isset($i)) { + return $this->_containing_block[$i]; + } + + return $this->_containing_block; + } + + /** + * Block position + * + * @param $i string The key of the wanted position value (x, y) + * + * @return array|float + */ + public function get_position($i = null) + { + if (isset($i)) { + return $this->_position[$i]; + } + + return $this->_position; + } + + //........................................................................ + + /** + * Return the height of the margin box of the frame, in pt. Meaningless + * unless the height has been calculated properly. + * + * @return float + */ + public function get_margin_height() + { + $style = $this->_style; + + return ( + (float)$style->length_in_pt( + [ + $style->height, + (float)$style->length_in_pt( + [ + $style->border_top_width, + $style->border_bottom_width, + $style->margin_top, + $style->margin_bottom, + $style->padding_top, + $style->padding_bottom + ], $this->_containing_block["w"] + ) + ], + $this->_containing_block["h"] + ) + ); + } + + /** + * Return the width of the margin box of the frame, in pt. Meaningless + * unless the width has been calculated properly. + * + * @return float + */ + public function get_margin_width() + { + $style = $this->_style; + + return (float)$style->length_in_pt([ + $style->width, + $style->margin_left, + $style->margin_right, + $style->border_left_width, + $style->border_right_width, + $style->padding_left, + $style->padding_right + ], $this->_containing_block["w"]); + } + + /** + * @return float + */ + public function get_break_margins() + { + $style = $this->_style; + + return ( + (float)$style->length_in_pt( + [ + //$style->height, + (float)$style->length_in_pt( + [ + $style->border_top_width, + $style->border_bottom_width, + $style->margin_top, + $style->margin_bottom, + $style->padding_top, + $style->padding_bottom + ], $this->_containing_block["w"] + ) + ], + $this->_containing_block["h"] + ) + ); + } + + /** + * Return the content box (x,y,w,h) of the frame + * + * @return array + */ + public function get_content_box() + { + $style = $this->_style; + $cb = $this->_containing_block; + + $x = $this->_position["x"] + + (float)$style->length_in_pt( + [ + $style->margin_left, + $style->border_left_width, + $style->padding_left + ], + $cb["w"] + ); + + $y = $this->_position["y"] + + (float)$style->length_in_pt( + [ + $style->margin_top, + $style->border_top_width, + $style->padding_top + ], + $cb["w"]); + + $w = $style->length_in_pt($style->width, $cb["w"]); + + $h = $style->length_in_pt($style->height, $cb["h"]); + + return [0 => $x, "x" => $x, + 1 => $y, "y" => $y, + 2 => $w, "w" => $w, + 3 => $h, "h" => $h]; + } + + /** + * Return the padding box (x,y,w,h) of the frame + * + * @return array + */ + public function get_padding_box() + { + $style = $this->_style; + $cb = $this->_containing_block; + + $x = $this->_position["x"] + + (float)$style->length_in_pt( + [ + $style->margin_left, + $style->border_left_width + ], + $cb["w"]); + + $y = $this->_position["y"] + + (float)$style->length_in_pt( + [ + $style->margin_top, + $style->border_top_width + ], + $cb["h"] + ); + + $w = $style->length_in_pt( + [ + $style->padding_left, + $style->width, + $style->padding_right + ], + $cb["w"] + ); + + $h = $style->length_in_pt( + [ + $style->padding_top, + $style->padding_bottom, + $style->length_in_pt($style->height, $cb["h"]) + ], + $cb["w"] + ); + + return [0 => $x, "x" => $x, + 1 => $y, "y" => $y, + 2 => $w, "w" => $w, + 3 => $h, "h" => $h]; + } + + /** + * Return the border box of the frame + * + * @return array + */ + public function get_border_box() + { + $style = $this->_style; + $cb = $this->_containing_block; + + $x = $this->_position["x"] + (float)$style->length_in_pt($style->margin_left, $cb["w"]); + + $y = $this->_position["y"] + (float)$style->length_in_pt($style->margin_top, $cb["w"]); + + $w = $style->length_in_pt( + [ + $style->border_left_width, + $style->padding_left, + $style->width, + $style->padding_right, + $style->border_right_width + ], + $cb["w"]); + + $h = $style->length_in_pt( + [ + $style->border_top_width, + $style->padding_top, + $style->padding_bottom, + $style->border_bottom_width, + $style->length_in_pt($style->height, $cb["h"]) + ], + $cb["w"]); + + return [0 => $x, "x" => $x, + 1 => $y, "y" => $y, + 2 => $w, "w" => $w, + 3 => $h, "h" => $h]; + } + + /** + * @param null $opacity + * + * @return float + */ + public function get_opacity($opacity = null) + { + if ($opacity !== null) { + $this->set_opacity($opacity); + } + + return $this->_opacity; + } + + /** + * @return LineBox + */ + public function &get_containing_line() + { + return $this->_containing_line; + } + + //........................................................................ + + // Set methods + /** + * @param $id + */ + public function set_id($id) + { + $this->_id = $id; + + // We can only set attributes of DOMElement objects (nodeType == 1). + // Since these are the only objects that we can assign CSS rules to, + // this shortcoming is okay. + if ($this->_node->nodeType == XML_ELEMENT_NODE) { + $this->_node->setAttribute("frame_id", $id); + } + } + + /** + * @param Style $style + */ + public function set_style(Style $style) + { + if (is_null($this->_style)) { + $this->_original_style = clone $style; + } + + //$style->set_frame($this); + $this->_style = $style; + } + + /** + * @param \Dompdf\FrameDecorator\AbstractFrameDecorator $decorator + */ + public function set_decorator(FrameDecorator\AbstractFrameDecorator $decorator) + { + $this->_decorator = $decorator; + } + + /** + * @param null $x + * @param null $y + * @param null $w + * @param null $h + */ + public function set_containing_block($x = null, $y = null, $w = null, $h = null) + { + if (is_array($x)) { + foreach ($x as $key => $val) { + $$key = $val; + } + } + + if (is_numeric($x)) { + $this->_containing_block["x"] = $x; + } + + if (is_numeric($y)) { + $this->_containing_block["y"] = $y; + } + + if (is_numeric($w)) { + $this->_containing_block["w"] = $w; + } + + if (is_numeric($h)) { + $this->_containing_block["h"] = $h; + } + } + + /** + * @param null $x + * @param null $y + */ + public function set_position($x = null, $y = null) + { + if (is_array($x)) { + list($x, $y) = [$x["x"], $x["y"]]; + } + + if (is_numeric($x)) { + $this->_position["x"] = $x; + } + + if (is_numeric($y)) { + $this->_position["y"] = $y; + } + } + + /** + * @param $opacity + */ + public function set_opacity($opacity) + { + $parent = $this->get_parent(); + $base_opacity = (($parent && $parent->_opacity !== null) ? $parent->_opacity : 1.0); + $this->_opacity = $base_opacity * $opacity; + } + + /** + * @param LineBox $line + */ + public function set_containing_line(LineBox $line) + { + $this->_containing_line = $line; + } + + /** + * Indicates if the margin height is auto sized + * + * @return bool + */ + public function is_auto_height() + { + $style = $this->_style; + + return in_array( + "auto", + [ + $style->height, + $style->margin_top, + $style->margin_bottom, + $style->border_top_width, + $style->border_bottom_width, + $style->padding_top, + $style->padding_bottom, + $this->_containing_block["h"] + ], + true + ); + } + + /** + * Indicates if the margin width is auto sized + * + * @return bool + */ + public function is_auto_width() + { + $style = $this->_style; + + return in_array( + "auto", + [ + $style->width, + $style->margin_left, + $style->margin_right, + $style->border_left_width, + $style->border_right_width, + $style->padding_left, + $style->padding_right, + $this->_containing_block["w"] + ], + true + ); + } + + /** + * Tells if the frame is a text node + * + * @return bool + */ + public function is_text_node() + { + if (isset($this->_is_cache["text_node"])) { + return $this->_is_cache["text_node"]; + } + + return $this->_is_cache["text_node"] = ($this->get_node()->nodeName === "#text"); + } + + /** + * @return bool + */ + public function is_positionned() + { + if (isset($this->_is_cache["positionned"])) { + return $this->_is_cache["positionned"]; + } + + $position = $this->get_style()->position; + + return $this->_is_cache["positionned"] = in_array($position, Style::$POSITIONNED_TYPES); + } + + /** + * @return bool + */ + public function is_absolute() + { + if (isset($this->_is_cache["absolute"])) { + return $this->_is_cache["absolute"]; + } + + $position = $this->get_style()->position; + + return $this->_is_cache["absolute"] = ($position === "absolute" || $position === "fixed"); + } + + /** + * @return bool + */ + public function is_block() + { + if (isset($this->_is_cache["block"])) { + return $this->_is_cache["block"]; + } + + return $this->_is_cache["block"] = in_array($this->get_style()->display, Style::$BLOCK_TYPES); + } + + /** + * @return bool + */ + public function is_inline_block() + { + if (isset($this->_is_cache["inline_block"])) { + return $this->_is_cache["inline_block"]; + } + + return $this->_is_cache["inline_block"] = ($this->get_style()->display === 'inline-block'); + } + + /** + * @return bool + */ + public function is_in_flow() + { + if (isset($this->_is_cache["in_flow"])) { + return $this->_is_cache["in_flow"]; + } + return $this->_is_cache["in_flow"] = !($this->get_style()->float !== "none" || $this->is_absolute()); + } + + /** + * @return bool + */ + public function is_pre() + { + if (isset($this->_is_cache["pre"])) { + return $this->_is_cache["pre"]; + } + + $white_space = $this->get_style()->white_space; + + return $this->_is_cache["pre"] = in_array($white_space, ["pre", "pre-wrap"]); + } + + /** + * @return bool + */ + public function is_table() + { + if (isset($this->_is_cache["table"])) { + return $this->_is_cache["table"]; + } + + $display = $this->get_style()->display; + + return $this->_is_cache["table"] = in_array($display, Style::$TABLE_TYPES); + } + + + /** + * Inserts a new child at the beginning of the Frame + * + * @param $child Frame The new Frame to insert + * @param $update_node boolean Whether or not to update the DOM + */ + public function prepend_child(Frame $child, $update_node = true) + { + if ($update_node) { + $this->_node->insertBefore($child->_node, $this->_first_child ? $this->_first_child->_node : null); + } + + // Remove the child from its parent + if ($child->_parent) { + $child->_parent->remove_child($child, false); + } + + $child->_parent = $this; + $child->_prev_sibling = null; + + // Handle the first child + if (!$this->_first_child) { + $this->_first_child = $child; + $this->_last_child = $child; + $child->_next_sibling = null; + } else { + $this->_first_child->_prev_sibling = $child; + $child->_next_sibling = $this->_first_child; + $this->_first_child = $child; + } + } + + /** + * Inserts a new child at the end of the Frame + * + * @param $child Frame The new Frame to insert + * @param $update_node boolean Whether or not to update the DOM + */ + public function append_child(Frame $child, $update_node = true) + { + if ($update_node) { + $this->_node->appendChild($child->_node); + } + + // Remove the child from its parent + if ($child->_parent) { + $child->_parent->remove_child($child, false); + } + + $child->_parent = $this; + $decorator = $child->get_decorator(); + // force an update to the cached parent + if ($decorator !== null) { + $decorator->get_parent(false); + } + $child->_next_sibling = null; + + // Handle the first child + if (!$this->_last_child) { + $this->_first_child = $child; + $this->_last_child = $child; + $child->_prev_sibling = null; + } else { + $this->_last_child->_next_sibling = $child; + $child->_prev_sibling = $this->_last_child; + $this->_last_child = $child; + } + } + + /** + * Inserts a new child immediately before the specified frame + * + * @param $new_child Frame The new Frame to insert + * @param $ref Frame The Frame after the new Frame + * @param $update_node boolean Whether or not to update the DOM + * + * @throws Exception + */ + public function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) + { + if ($ref === $this->_first_child) { + $this->prepend_child($new_child, $update_node); + + return; + } + + if (is_null($ref)) { + $this->append_child($new_child, $update_node); + + return; + } + + if ($ref->_parent !== $this) { + throw new Exception("Reference child is not a child of this node."); + } + + // Update the node + if ($update_node) { + $this->_node->insertBefore($new_child->_node, $ref->_node); + } + + // Remove the child from its parent + if ($new_child->_parent) { + $new_child->_parent->remove_child($new_child, false); + } + + $new_child->_parent = $this; + $new_child->_next_sibling = $ref; + $new_child->_prev_sibling = $ref->_prev_sibling; + + if ($ref->_prev_sibling) { + $ref->_prev_sibling->_next_sibling = $new_child; + } + + $ref->_prev_sibling = $new_child; + } + + /** + * Inserts a new child immediately after the specified frame + * + * @param $new_child Frame The new Frame to insert + * @param $ref Frame The Frame before the new Frame + * @param $update_node boolean Whether or not to update the DOM + * + * @throws Exception + */ + public function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) + { + if ($ref === $this->_last_child) { + $this->append_child($new_child, $update_node); + + return; + } + + if (is_null($ref)) { + $this->prepend_child($new_child, $update_node); + + return; + } + + if ($ref->_parent !== $this) { + throw new Exception("Reference child is not a child of this node."); + } + + // Update the node + if ($update_node) { + if ($ref->_next_sibling) { + $next_node = $ref->_next_sibling->_node; + $this->_node->insertBefore($new_child->_node, $next_node); + } else { + $new_child->_node = $this->_node->appendChild($new_child->_node); + } + } + + // Remove the child from its parent + if ($new_child->_parent) { + $new_child->_parent->remove_child($new_child, false); + } + + $new_child->_parent = $this; + $new_child->_prev_sibling = $ref; + $new_child->_next_sibling = $ref->_next_sibling; + + if ($ref->_next_sibling) { + $ref->_next_sibling->_prev_sibling = $new_child; + } + + $ref->_next_sibling = $new_child; + } + + /** + * Remove a child frame + * + * @param Frame $child + * @param boolean $update_node Whether or not to remove the DOM node + * + * @throws Exception + * @return Frame The removed child frame + */ + public function remove_child(Frame $child, $update_node = true) + { + if ($child->_parent !== $this) { + throw new Exception("Child not found in this frame"); + } + + if ($update_node) { + $this->_node->removeChild($child->_node); + } + + if ($child === $this->_first_child) { + $this->_first_child = $child->_next_sibling; + } + + if ($child === $this->_last_child) { + $this->_last_child = $child->_prev_sibling; + } + + if ($child->_prev_sibling) { + $child->_prev_sibling->_next_sibling = $child->_next_sibling; + } + + if ($child->_next_sibling) { + $child->_next_sibling->_prev_sibling = $child->_prev_sibling; + } + + $child->_next_sibling = null; + $child->_prev_sibling = null; + $child->_parent = null; + + return $child; + } + + //........................................................................ + + // Debugging function: + /** + * @return string + */ + public function __toString() + { + // Skip empty text frames +// if ( $this->is_text_node() && +// preg_replace("/\s/", "", $this->_node->data) === "" ) +// return ""; + + + $str = "" . $this->_node->nodeName . ":
"; + //$str .= spl_object_hash($this->_node) . "
"; + $str .= "Id: " . $this->get_id() . "
"; + $str .= "Class: " . get_class($this) . "
"; + + if ($this->is_text_node()) { + $tmp = htmlspecialchars($this->_node->nodeValue); + $str .= "
'" . mb_substr($tmp, 0, 70) .
+                (mb_strlen($tmp) > 70 ? "..." : "") . "'
"; + } elseif ($css_class = $this->_node->getAttribute("class")) { + $str .= "CSS class: '$css_class'
"; + } + + if ($this->_parent) { + $str .= "\nParent:" . $this->_parent->_node->nodeName . + " (" . spl_object_hash($this->_parent->_node) . ") " . + "
"; + } + + if ($this->_prev_sibling) { + $str .= "Prev: " . $this->_prev_sibling->_node->nodeName . + " (" . spl_object_hash($this->_prev_sibling->_node) . ") " . + "
"; + } + + if ($this->_next_sibling) { + $str .= "Next: " . $this->_next_sibling->_node->nodeName . + " (" . spl_object_hash($this->_next_sibling->_node) . ") " . + "
"; + } + + $d = $this->get_decorator(); + while ($d && $d != $d->get_decorator()) { + $str .= "Decorator: " . get_class($d) . "
"; + $d = $d->get_decorator(); + } + + $str .= "Position: " . Helpers::pre_r($this->_position, true); + $str .= "\nContaining block: " . Helpers::pre_r($this->_containing_block, true); + $str .= "\nMargin width: " . Helpers::pre_r($this->get_margin_width(), true); + $str .= "\nMargin height: " . Helpers::pre_r($this->get_margin_height(), true); + + $str .= "\nStyle:
" . $this->_style->__toString() . "
"; + + if ($this->_decorator instanceof FrameDecorator\Block) { + $str .= "Lines:
";
+            foreach ($this->_decorator->get_line_boxes() as $line) {
+                foreach ($line->get_frames() as $frame) {
+                    if ($frame instanceof FrameDecorator\Text) {
+                        $str .= "\ntext: ";
+                        $str .= "'" . htmlspecialchars($frame->get_text()) . "'";
+                    } else {
+                        $str .= "\nBlock: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")";
+                    }
+                }
+
+                $str .=
+                    "\ny => " . $line->y . "\n" .
+                    "w => " . $line->w . "\n" .
+                    "h => " . $line->h . "\n" .
+                    "left => " . $line->left . "\n" .
+                    "right => " . $line->right . "\n";
+            }
+            $str .= "
"; + } + + $str .= "\n"; + if (php_sapi_name() === "cli") { + $str = strip_tags(str_replace(["
", "", ""], + ["\n", "", ""], + $str)); + } + + return $str; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Frame/Factory.php b/vendor/dompdf/dompdf/src/Frame/Factory.php new file mode 100644 index 0000000..e14f75b --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/Factory.php @@ -0,0 +1,287 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Frame; + +use Dompdf\Css\Style; +use Dompdf\Dompdf; +use Dompdf\Exception; +use Dompdf\Frame; +use Dompdf\FrameDecorator\AbstractFrameDecorator; +use DOMXPath; +use Dompdf\FrameDecorator\Page as PageFrameDecorator; +use Dompdf\FrameReflower\Page as PageFrameReflower; +use Dompdf\Positioner\AbstractPositioner; + +/** + * Contains frame decorating logic + * + * This class is responsible for assigning the correct {@link AbstractFrameDecorator}, + * {@link AbstractPositioner}, and {@link AbstractFrameReflower} objects to {@link Frame} + * objects. This is determined primarily by the Frame's display type, but + * also by the Frame's node's type (e.g. DomElement vs. #text) + * + * @access private + * @package dompdf + */ +class Factory +{ + + /** + * Array of positioners for specific frame types + * + * @var AbstractPositioner[] + */ + protected static $_positioners; + + /** + * Decorate the root Frame + * + * @param $root Frame The frame to decorate + * @param $dompdf Dompdf The dompdf instance + * + * @return PageFrameDecorator + */ + static function decorate_root(Frame $root, Dompdf $dompdf) + { + $frame = new PageFrameDecorator($root, $dompdf); + $frame->set_reflower(new PageFrameReflower($frame)); + $root->set_decorator($frame); + + return $frame; + } + + /** + * Decorate a Frame + * + * @param Frame $frame The frame to decorate + * @param Dompdf $dompdf The dompdf instance + * @param Frame $root The frame to decorate + * + * @throws Exception + * @return AbstractFrameDecorator + * FIXME: this is admittedly a little smelly... + */ + static function decorate_frame(Frame $frame, Dompdf $dompdf, Frame $root = null) + { + if (is_null($dompdf)) { + throw new Exception("The DOMPDF argument is required"); + } + + $style = $frame->get_style(); + + // Floating (and more generally out-of-flow) elements are blocks + // http://coding.smashingmagazine.com/2007/05/01/css-float-theory-things-you-should-know/ + if (!$frame->is_in_flow() && in_array($style->display, Style::$INLINE_TYPES)) { + $style->display = "block"; + } + + $display = $style->display; + + switch ($display) { + + case "flex": //FIXME: display type not yet supported + case "table-caption": //FIXME: display type not yet supported + case "block": + $positioner = "Block"; + $decorator = "Block"; + $reflower = "Block"; + break; + + case "inline-flex": //FIXME: display type not yet supported + case "inline-block": + $positioner = "Inline"; + $decorator = "Block"; + $reflower = "Block"; + break; + + case "inline": + $positioner = "Inline"; + if ($frame->is_text_node()) { + $decorator = "Text"; + $reflower = "Text"; + } else { + if ($style->float !== "none") { + $decorator = "Block"; + $reflower = "Block"; + } else { + $decorator = "Inline"; + $reflower = "Inline"; + } + } + break; + + case "table": + $positioner = "Block"; + $decorator = "Table"; + $reflower = "Table"; + break; + + case "inline-table": + $positioner = "Inline"; + $decorator = "Table"; + $reflower = "Table"; + break; + + case "table-row-group": + case "table-header-group": + case "table-footer-group": + $positioner = "NullPositioner"; + $decorator = "TableRowGroup"; + $reflower = "TableRowGroup"; + break; + + case "table-row": + $positioner = "NullPositioner"; + $decorator = "TableRow"; + $reflower = "TableRow"; + break; + + case "table-cell": + $positioner = "TableCell"; + $decorator = "TableCell"; + $reflower = "TableCell"; + break; + + case "list-item": + $positioner = "Block"; + $decorator = "Block"; + $reflower = "Block"; + break; + + case "-dompdf-list-bullet": + if ($style->list_style_position === "inside") { + $positioner = "Inline"; + } else { + $positioner = "ListBullet"; + } + + if ($style->list_style_image !== "none") { + $decorator = "ListBulletImage"; + } else { + $decorator = "ListBullet"; + } + + $reflower = "ListBullet"; + break; + + case "-dompdf-image": + $positioner = "Inline"; + $decorator = "Image"; + $reflower = "Image"; + break; + + case "-dompdf-br": + $positioner = "Inline"; + $decorator = "Inline"; + $reflower = "Inline"; + break; + + default: + // FIXME: should throw some sort of warning or something? + case "none": + if ($style->_dompdf_keep !== "yes") { + // Remove the node and the frame + $frame->get_parent()->remove_child($frame); + return; + } + + $positioner = "NullPositioner"; + $decorator = "NullFrameDecorator"; + $reflower = "NullFrameReflower"; + break; + } + + // Handle CSS position + $position = $style->position; + + if ($position === "absolute") { + $positioner = "Absolute"; + } else { + if ($position === "fixed") { + $positioner = "Fixed"; + } + } + + $node = $frame->get_node(); + + // Handle nodeName + if ($node->nodeName === "img") { + $style->display = "-dompdf-image"; + $decorator = "Image"; + $reflower = "Image"; + } + + $decorator = "Dompdf\\FrameDecorator\\$decorator"; + $reflower = "Dompdf\\FrameReflower\\$reflower"; + + /** @var AbstractFrameDecorator $deco */ + $deco = new $decorator($frame, $dompdf); + + $deco->set_positioner(self::getPositionerInstance($positioner)); + $deco->set_reflower(new $reflower($deco, $dompdf->getFontMetrics())); + + if ($root) { + $deco->set_root($root); + } + + if ($display === "list-item") { + // Insert a list-bullet frame + $xml = $dompdf->getDom(); + $bullet_node = $xml->createElement("bullet"); // arbitrary choice + $b_f = new Frame($bullet_node); + + $node = $frame->get_node(); + $parent_node = $node->parentNode; + + if ($parent_node) { + if (!$parent_node->hasAttribute("dompdf-children-count")) { + $xpath = new DOMXPath($xml); + $count = $xpath->query("li", $parent_node)->length; + $parent_node->setAttribute("dompdf-children-count", $count); + } + + if (is_numeric($node->getAttribute("value"))) { + $index = intval($node->getAttribute("value")); + } else { + if (!$parent_node->hasAttribute("dompdf-counter")) { + $index = ($parent_node->hasAttribute("start") ? $parent_node->getAttribute("start") : 1); + } else { + $index = (int)$parent_node->getAttribute("dompdf-counter") + 1; + } + } + + $parent_node->setAttribute("dompdf-counter", $index); + $bullet_node->setAttribute("dompdf-counter", $index); + } + + $new_style = $dompdf->getCss()->create_style(); + $new_style->display = "-dompdf-list-bullet"; + $new_style->inherit($style); + $b_f->set_style($new_style); + + $deco->prepend_child(Factory::decorate_frame($b_f, $dompdf, $root)); + } + + return $deco; + } + + /** + * Creates Positioners + * + * @param string $type type of positioner to use + * @return AbstractPositioner + */ + protected static function getPositionerInstance($type) + { + if (!isset(self::$_positioners[$type])) { + $class = '\\Dompdf\\Positioner\\'.$type; + self::$_positioners[$type] = new $class(); + } + return self::$_positioners[$type]; + } +} diff --git a/vendor/dompdf/dompdf/src/Frame/FrameList.php b/vendor/dompdf/dompdf/src/Frame/FrameList.php new file mode 100644 index 0000000..37d9990 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/FrameList.php @@ -0,0 +1,35 @@ +_frame = $frame; + } + + /** + * @return FrameListIterator + */ + function getIterator() + { + return new FrameListIterator($this->_frame); + } +} diff --git a/vendor/dompdf/dompdf/src/Frame/FrameListIterator.php b/vendor/dompdf/dompdf/src/Frame/FrameListIterator.php new file mode 100644 index 0000000..ada9dde --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/FrameListIterator.php @@ -0,0 +1,91 @@ +_parent = $frame; + $this->_cur = $frame->get_first_child(); + $this->_num = 0; + } + + /** + * + */ + public function rewind() + { + $this->_cur = $this->_parent->get_first_child(); + $this->_num = 0; + } + + /** + * @return bool + */ + public function valid() + { + return isset($this->_cur); // && ($this->_cur->get_prev_sibling() === $this->_prev); + } + + /** + * @return int + */ + public function key() + { + return $this->_num; + } + + /** + * @return Frame + */ + public function current() + { + return $this->_cur; + } + + /** + * @return Frame + */ + public function next() + { + $ret = $this->_cur; + if (!$ret) { + return null; + } + + $this->_cur = $this->_cur->get_next_sibling(); + $this->_num++; + return $ret; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Frame/FrameTree.php b/vendor/dompdf/dompdf/src/Frame/FrameTree.php new file mode 100644 index 0000000..944d12b --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/FrameTree.php @@ -0,0 +1,315 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +/** + * Represents an entire document as a tree of frames + * + * The FrameTree consists of {@link Frame} objects each tied to specific + * DOMNode objects in a specific DomDocument. The FrameTree has the same + * structure as the DomDocument, but adds additional capabilities for + * styling and layout. + * + * @package dompdf + */ +class FrameTree +{ + /** + * Tags to ignore while parsing the tree + * + * @var array + */ + protected static $HIDDEN_TAGS = [ + "area", + "base", + "basefont", + "head", + "style", + "meta", + "title", + "colgroup", + "noembed", + "param", + "#comment" + ]; + + /** + * The main DomDocument + * + * @see http://ca2.php.net/manual/en/ref.dom.php + * @var DOMDocument + */ + protected $_dom; + + /** + * The root node of the FrameTree. + * + * @var Frame + */ + protected $_root; + + /** + * Subtrees of absolutely positioned elements + * + * @var array of Frames + */ + protected $_absolute_frames; + + /** + * A mapping of {@link Frame} objects to DOMNode objects + * + * @var array + */ + protected $_registry; + + /** + * Class constructor + * + * @param DOMDocument $dom the main DomDocument object representing the current html document + */ + public function __construct(DomDocument $dom) + { + $this->_dom = $dom; + $this->_root = null; + $this->_registry = []; + } + + /** + * Returns the DOMDocument object representing the current html document + * + * @return DOMDocument + */ + public function get_dom() + { + return $this->_dom; + } + + /** + * Returns the root frame of the tree + * + * @return Frame + */ + public function get_root() + { + return $this->_root; + } + + /** + * Returns a specific frame given its id + * + * @param string $id + * + * @return Frame|null + */ + public function get_frame($id) + { + return isset($this->_registry[$id]) ? $this->_registry[$id] : null; + } + + /** + * Returns a post-order iterator for all frames in the tree + * + * @return FrameTreeList|Frame[] + */ + public function get_frames() + { + return new FrameTreeList($this->_root); + } + + /** + * Builds the tree + */ + public function build_tree() + { + $html = $this->_dom->getElementsByTagName("html")->item(0); + if (is_null($html)) { + $html = $this->_dom->firstChild; + } + + if (is_null($html)) { + throw new Exception("Requested HTML document contains no data."); + } + + $this->fix_tables(); + + $this->_root = $this->_build_tree_r($html); + } + + /** + * Adds missing TBODYs around TR + */ + protected function fix_tables() + { + $xp = new DOMXPath($this->_dom); + + // Move table caption before the table + // FIXME find a better way to deal with it... + $captions = $xp->query('//table/caption'); + foreach ($captions as $caption) { + $table = $caption->parentNode; + $table->parentNode->insertBefore($caption, $table); + } + + $firstRows = $xp->query('//table/tr[1]'); + /** @var DOMElement $tableChild */ + foreach ($firstRows as $tableChild) { + $tbody = $this->_dom->createElement('tbody'); + $tableNode = $tableChild->parentNode; + do { + if ($tableChild->nodeName === 'tr') { + $tmpNode = $tableChild; + $tableChild = $tableChild->nextSibling; + $tableNode->removeChild($tmpNode); + $tbody->appendChild($tmpNode); + } else { + if ($tbody->hasChildNodes() === true) { + $tableNode->insertBefore($tbody, $tableChild); + $tbody = $this->_dom->createElement('tbody'); + } + $tableChild = $tableChild->nextSibling; + } + } while ($tableChild); + if ($tbody->hasChildNodes() === true) { + $tableNode->appendChild($tbody); + } + } + } + + // FIXME: temporary hack, preferably we will improve rendering of sequential #text nodes + /** + * Remove a child from a node + * + * Remove a child from a node. If the removed node results in two + * adjacent #text nodes then combine them. + * + * @param DOMNode $node the current DOMNode being considered + * @param array $children an array of nodes that are the children of $node + * @param int $index index from the $children array of the node to remove + */ + protected function _remove_node(DOMNode $node, array &$children, $index) + { + $child = $children[$index]; + $previousChild = $child->previousSibling; + $nextChild = $child->nextSibling; + $node->removeChild($child); + if (isset($previousChild, $nextChild)) { + if ($previousChild->nodeName === "#text" && $nextChild->nodeName === "#text") { + $previousChild->nodeValue .= $nextChild->nodeValue; + $this->_remove_node($node, $children, $index+1); + } + } + array_splice($children, $index, 1); + } + + /** + * Recursively adds {@link Frame} objects to the tree + * + * Recursively build a tree of Frame objects based on a dom tree. + * No layout information is calculated at this time, although the + * tree may be adjusted (i.e. nodes and frames for generated content + * and images may be created). + * + * @param DOMNode $node the current DOMNode being considered + * + * @return Frame + */ + protected function _build_tree_r(DOMNode $node) + { + $frame = new Frame($node); + $id = $frame->get_id(); + $this->_registry[$id] = $frame; + + if (!$node->hasChildNodes()) { + return $frame; + } + + // Store the children in an array so that the tree can be modified + $children = []; + $length = $node->childNodes->length; + for ($i = 0; $i < $length; $i++) { + $children[] = $node->childNodes->item($i); + } + $index = 0; + // INFO: We don't advance $index if a node is removed to avoid skipping nodes + while ($index < count($children)) { + $child = $children[$index]; + $nodeName = strtolower($child->nodeName); + + // Skip non-displaying nodes + if (in_array($nodeName, self::$HIDDEN_TAGS)) { + if ($nodeName !== "head" && $nodeName !== "style") { + $this->_remove_node($node, $children, $index); + } else { + $index++; + } + continue; + } + // Skip empty text nodes + if ($nodeName === "#text" && $child->nodeValue === "") { + $this->_remove_node($node, $children, $index); + continue; + } + // Skip empty image nodes + if ($nodeName === "img" && $child->getAttribute("src") === "") { + $this->_remove_node($node, $children, $index); + continue; + } + + if (is_object($child)) { + $frame->append_child($this->_build_tree_r($child), false); + } + $index++; + } + + return $frame; + } + + /** + * @param DOMElement $node + * @param DOMElement $new_node + * @param string $pos + * + * @return mixed + */ + public function insert_node(DOMElement $node, DOMElement $new_node, $pos) + { + if ($pos === "after" || !$node->firstChild) { + $node->appendChild($new_node); + } else { + $node->insertBefore($new_node, $node->firstChild); + } + + $this->_build_tree_r($new_node); + + $frame_id = $new_node->getAttribute("frame_id"); + $frame = $this->get_frame($frame_id); + + $parent_id = $node->getAttribute("frame_id"); + $parent = $this->get_frame($parent_id); + + if ($parent) { + if ($pos === "before") { + $parent->prepend_child($frame, false); + } else { + $parent->append_child($frame, false); + } + } + + return $frame_id; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Frame/FrameTreeIterator.php b/vendor/dompdf/dompdf/src/Frame/FrameTreeIterator.php new file mode 100644 index 0000000..d1d82c2 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/FrameTreeIterator.php @@ -0,0 +1,96 @@ +_stack[] = $this->_root = $root; + $this->_num = 0; + } + + /** + * + */ + public function rewind() + { + $this->_stack = [$this->_root]; + $this->_num = 0; + } + + /** + * @return bool + */ + public function valid() + { + return count($this->_stack) > 0; + } + + /** + * @return int + */ + public function key() + { + return $this->_num; + } + + /** + * @return Frame + */ + public function current() + { + return end($this->_stack); + } + + /** + * @return Frame + */ + public function next() + { + $b = end($this->_stack); + + // Pop last element + unset($this->_stack[key($this->_stack)]); + $this->_num++; + + // Push all children onto the stack in reverse order + if ($c = $b->get_last_child()) { + $this->_stack[] = $c; + while ($c = $c->get_prev_sibling()) { + $this->_stack[] = $c; + } + } + + return $b; + } +} + diff --git a/vendor/dompdf/dompdf/src/Frame/FrameTreeList.php b/vendor/dompdf/dompdf/src/Frame/FrameTreeList.php new file mode 100644 index 0000000..f8b996c --- /dev/null +++ b/vendor/dompdf/dompdf/src/Frame/FrameTreeList.php @@ -0,0 +1,35 @@ +_root = $root; + } + + /** + * @return FrameTreeIterator + */ + public function getIterator() + { + return new FrameTreeIterator($this->_root); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php b/vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php new file mode 100644 index 0000000..eb86341 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/AbstractFrameDecorator.php @@ -0,0 +1,915 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +/** + * Base AbstractFrameDecorator class + * + * @package dompdf + */ +abstract class AbstractFrameDecorator extends Frame +{ + const DEFAULT_COUNTER = "-dompdf-default-counter"; + + public $_counters = []; // array([id] => counter_value) (for generated content) + + /** + * The root node of the DOM tree + * + * @var Frame + */ + protected $_root; + + /** + * The decorated frame + * + * @var Frame + */ + protected $_frame; + + /** + * AbstractPositioner object used to position this frame (Strategy pattern) + * + * @var AbstractPositioner + */ + protected $_positioner; + + /** + * Reflower object used to calculate frame dimensions (Strategy pattern) + * + * @var \Dompdf\FrameReflower\AbstractFrameReflower + */ + protected $_reflower; + + /** + * Reference to the current dompdf instance + * + * @var Dompdf + */ + protected $_dompdf; + + /** + * First block parent + * + * @var Block + */ + private $_block_parent; + + /** + * First positionned parent (position: relative | absolute | fixed) + * + * @var AbstractFrameDecorator + */ + private $_positionned_parent; + + /** + * Cache for the get_parent while loop results + * + * @var Frame + */ + private $_cached_parent; + + /** + * Class constructor + * + * @param Frame $frame The decoration target + * @param Dompdf $dompdf The Dompdf object + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + $this->_frame = $frame; + $this->_root = null; + $this->_dompdf = $dompdf; + $frame->set_decorator($this); + } + + /** + * "Destructor": foribly free all references held by this object + * + * @param bool $recursive if true, call dispose on all children + */ + function dispose($recursive = false) + { + if ($recursive) { + while ($child = $this->get_first_child()) { + $child->dispose(true); + } + } + + $this->_root = null; + unset($this->_root); + + $this->_frame->dispose(true); + $this->_frame = null; + unset($this->_frame); + + $this->_positioner = null; + unset($this->_positioner); + + $this->_reflower = null; + unset($this->_reflower); + } + + /** + * Return a copy of this frame with $node as its node + * + * @param DOMNode $node + * + * @return Frame + */ + function copy(DOMNode $node) + { + $frame = new Frame($node); + $frame->set_style(clone $this->_frame->get_original_style()); + + return Factory::decorate_frame($frame, $this->_dompdf, $this->_root); + } + + /** + * Create a deep copy: copy this node and all children + * + * @return Frame + */ + function deep_copy() + { + $node = $this->_frame->get_node(); + + if ($node instanceof DOMElement && $node->hasAttribute("id")) { + $node->setAttribute("data-dompdf-original-id", $node->getAttribute("id")); + $node->removeAttribute("id"); + } + + $frame = new Frame($node->cloneNode()); + $frame->set_style(clone $this->_frame->get_original_style()); + + $deco = Factory::decorate_frame($frame, $this->_dompdf, $this->_root); + + foreach ($this->get_children() as $child) { + $deco->append_child($child->deep_copy()); + } + + return $deco; + } + + /** + * Delegate calls to decorated frame object + */ + function reset() + { + $this->_frame->reset(); + + $this->_counters = []; + + $this->_cached_parent = null; //clear get_parent() cache + + // Reset all children + foreach ($this->get_children() as $child) { + $child->reset(); + } + } + + // Getters ----------- + + /** + * @return string + */ + function get_id() + { + return $this->_frame->get_id(); + } + + /** + * @return Frame + */ + function get_frame() + { + return $this->_frame; + } + + /** + * @return DOMElement|DOMText + */ + function get_node() + { + return $this->_frame->get_node(); + } + + /** + * @return Style + */ + function get_style() + { + return $this->_frame->get_style(); + } + + /** + * @return Style + */ + function get_original_style() + { + return $this->_frame->get_original_style(); + } + + /** + * @param integer $i + * + * @return array|float + */ + function get_containing_block($i = null) + { + return $this->_frame->get_containing_block($i); + } + + /** + * @param integer $i + * + * @return array|float + */ + function get_position($i = null) + { + return $this->_frame->get_position($i); + } + + /** + * @return Dompdf + */ + function get_dompdf() + { + return $this->_dompdf; + } + + /** + * @return float + */ + function get_margin_height() + { + return $this->_frame->get_margin_height(); + } + + /** + * @return float + */ + function get_margin_width() + { + return $this->_frame->get_margin_width(); + } + + /** + * @return array + */ + function get_content_box() + { + return $this->_frame->get_content_box(); + } + + /** + * @return array + */ + function get_padding_box() + { + return $this->_frame->get_padding_box(); + } + + /** + * @return array + */ + function get_border_box() + { + return $this->_frame->get_border_box(); + } + + /** + * @param integer $id + */ + function set_id($id) + { + $this->_frame->set_id($id); + } + + /** + * @param Style $style + */ + function set_style(Style $style) + { + $this->_frame->set_style($style); + } + + /** + * @param float $x + * @param float $y + * @param float $w + * @param float $h + */ + function set_containing_block($x = null, $y = null, $w = null, $h = null) + { + $this->_frame->set_containing_block($x, $y, $w, $h); + } + + /** + * @param float $x + * @param float $y + */ + function set_position($x = null, $y = null) + { + $this->_frame->set_position($x, $y); + } + + /** + * @return bool + */ + function is_auto_height() + { + return $this->_frame->is_auto_height(); + } + + /** + * @return bool + */ + function is_auto_width() + { + return $this->_frame->is_auto_width(); + } + + /** + * @return string + */ + function __toString() + { + return $this->_frame->__toString(); + } + + /** + * @param Frame $child + * @param bool $update_node + */ + function prepend_child(Frame $child, $update_node = true) + { + while ($child instanceof AbstractFrameDecorator) { + $child = $child->_frame; + } + + $this->_frame->prepend_child($child, $update_node); + } + + /** + * @param Frame $child + * @param bool $update_node + */ + function append_child(Frame $child, $update_node = true) + { + while ($child instanceof AbstractFrameDecorator) { + $child = $child->_frame; + } + + $this->_frame->append_child($child, $update_node); + } + + /** + * @param Frame $new_child + * @param Frame $ref + * @param bool $update_node + */ + function insert_child_before(Frame $new_child, Frame $ref, $update_node = true) + { + while ($new_child instanceof AbstractFrameDecorator) { + $new_child = $new_child->_frame; + } + + if ($ref instanceof AbstractFrameDecorator) { + $ref = $ref->_frame; + } + + $this->_frame->insert_child_before($new_child, $ref, $update_node); + } + + /** + * @param Frame $new_child + * @param Frame $ref + * @param bool $update_node + */ + function insert_child_after(Frame $new_child, Frame $ref, $update_node = true) + { + $insert_frame = $new_child; + while ($insert_frame instanceof AbstractFrameDecorator) { + $insert_frame = $insert_frame->_frame; + } + + $reference_frame = $ref; + while ($reference_frame instanceof AbstractFrameDecorator) { + $reference_frame = $reference_frame->_frame; + } + + $this->_frame->insert_child_after($insert_frame, $reference_frame, $update_node); + } + + /** + * @param Frame $child + * @param bool $update_node + * + * @return Frame + */ + function remove_child(Frame $child, $update_node = true) + { + while ($child instanceof AbstractFrameDecorator) { + $child = $child->_frame; + } + + return $this->_frame->remove_child($child, $update_node); + } + + /** + * @param bool $use_cache + * @return AbstractFrameDecorator + */ + function get_parent($use_cache = true) + { + if ($use_cache && $this->_cached_parent) { + return $this->_cached_parent; + } + $p = $this->_frame->get_parent(); + if ($p && $deco = $p->get_decorator()) { + while ($tmp = $deco->get_decorator()) { + $deco = $tmp; + } + + return $this->_cached_parent = $deco; + } else { + return $this->_cached_parent = $p; + } + } + + /** + * @return AbstractFrameDecorator + */ + function get_first_child() + { + $c = $this->_frame->get_first_child(); + if ($c && $deco = $c->get_decorator()) { + while ($tmp = $deco->get_decorator()) { + $deco = $tmp; + } + + return $deco; + } else { + if ($c) { + return $c; + } + } + + return null; + } + + /** + * @return AbstractFrameDecorator + */ + function get_last_child() + { + $c = $this->_frame->get_last_child(); + if ($c && $deco = $c->get_decorator()) { + while ($tmp = $deco->get_decorator()) { + $deco = $tmp; + } + + return $deco; + } else { + if ($c) { + return $c; + } + } + + return null; + } + + /** + * @return AbstractFrameDecorator + */ + function get_prev_sibling() + { + $s = $this->_frame->get_prev_sibling(); + if ($s && $deco = $s->get_decorator()) { + while ($tmp = $deco->get_decorator()) { + $deco = $tmp; + } + + return $deco; + } else { + if ($s) { + return $s; + } + } + + return null; + } + + /** + * @return AbstractFrameDecorator + */ + function get_next_sibling() + { + $s = $this->_frame->get_next_sibling(); + if ($s && $deco = $s->get_decorator()) { + while ($tmp = $deco->get_decorator()) { + $deco = $tmp; + } + + return $deco; + } else { + if ($s) { + return $s; + } + } + + return null; + } + + /** + * @return FrameTreeList + */ + function get_subtree() + { + return new FrameTreeList($this); + } + + function set_positioner(AbstractPositioner $posn) + { + $this->_positioner = $posn; + if ($this->_frame instanceof AbstractFrameDecorator) { + $this->_frame->set_positioner($posn); + } + } + + function set_reflower(AbstractFrameReflower $reflower) + { + $this->_reflower = $reflower; + if ($this->_frame instanceof AbstractFrameDecorator) { + $this->_frame->set_reflower($reflower); + } + } + + /** + * @return \Dompdf\FrameReflower\AbstractFrameReflower + */ + function get_reflower() + { + return $this->_reflower; + } + + /** + * @param Frame $root + */ + function set_root(Frame $root) + { + $this->_root = $root; + + if ($this->_frame instanceof AbstractFrameDecorator) { + $this->_frame->set_root($root); + } + } + + /** + * @return Page + */ + function get_root() + { + return $this->_root; + } + + /** + * @return Block + */ + function find_block_parent() + { + // Find our nearest block level parent + $p = $this->get_parent(); + + while ($p) { + if ($p->is_block()) { + break; + } + + $p = $p->get_parent(); + } + + return $this->_block_parent = $p; + } + + /** + * @return AbstractFrameDecorator + */ + function find_positionned_parent() + { + // Find our nearest relative positionned parent + $p = $this->get_parent(); + while ($p) { + if ($p->is_positionned()) { + break; + } + + $p = $p->get_parent(); + } + + if (!$p) { + $p = $this->_root->get_first_child(); // + } + + return $this->_positionned_parent = $p; + } + + /** + * split this frame at $child. + * The current frame is cloned and $child and all children following + * $child are added to the clone. The clone is then passed to the + * current frame's parent->split() method. + * + * @param Frame $child + * @param boolean $force_pagebreak + * + * @throws Exception + * @return void + */ + function split(Frame $child = null, $force_pagebreak = false) + { + // decrement any counters that were incremented on the current node, unless that node is the body + $style = $this->_frame->get_style(); + if ( + $this->_frame->get_node()->nodeName !== "body" && + $style->counter_increment && + ($decrement = $style->counter_increment) !== "none" + ) { + $this->decrement_counters($decrement); + } + + if (is_null($child)) { + // check for counter increment on :before content (always a child of the selected element @link AbstractFrameReflower::_set_content) + // this can push the current node to the next page before counter rules have bubbled up (but only if + // it's been rendered, thus the position check) + if (!$this->is_text_node() && $this->get_node()->hasAttribute("dompdf_before_frame_id")) { + foreach ($this->_frame->get_children() as $child) { + if ( + $this->get_node()->getAttribute("dompdf_before_frame_id") == $child->get_id() && + $child->get_position('x') !== null + ) { + $style = $child->get_style(); + if ($style->counter_increment && ($decrement = $style->counter_increment) !== "none") { + $this->decrement_counters($decrement); + } + } + } + } + $this->get_parent()->split($this, $force_pagebreak); + + return; + } + + if ($child->get_parent() !== $this) { + throw new Exception("Unable to split: frame is not a child of this one."); + } + + $node = $this->_frame->get_node(); + + if ($node instanceof DOMElement && $node->hasAttribute("id")) { + $node->setAttribute("data-dompdf-original-id", $node->getAttribute("id")); + $node->removeAttribute("id"); + } + + $split = $this->copy($node->cloneNode()); + $split->reset(); + $split->get_original_style()->text_indent = 0; + $split->_splitted = true; + $split->_already_pushed = true; + + // The body's properties must be kept + if ($node->nodeName !== "body") { + // Style reset on the first and second parts + $style = $this->_frame->get_style(); + $style->margin_bottom = 0; + $style->padding_bottom = 0; + $style->border_bottom = 0; + + // second + $orig_style = $split->get_original_style(); + $orig_style->text_indent = 0; + $orig_style->margin_top = 0; + $orig_style->padding_top = 0; + $orig_style->border_top = 0; + $orig_style->page_break_before = "auto"; + } + + // recalculate the float offsets after paging + $this->get_parent()->insert_child_after($split, $this); + if ($this instanceof Block) { + foreach ($this->get_line_boxes() as $index => $line_box) { + $line_box->get_float_offsets(); + } + } + + // Add $frame and all following siblings to the new split node + $iter = $child; + while ($iter) { + $frame = $iter; + $iter = $iter->get_next_sibling(); + $frame->reset(); + $frame->_parent = $split; + $split->append_child($frame); + + // recalculate the float offsets + if ($frame instanceof Block) { + foreach ($frame->get_line_boxes() as $index => $line_box) { + $line_box->get_float_offsets(); + } + } + } + + $this->get_parent()->split($split, $force_pagebreak); + + // If this node resets a counter save the current value to use when rendering on the next page + if ($style->counter_reset && ($reset = $style->counter_reset) !== "none") { + $vars = preg_split('/\s+/', trim($reset), 2); + $split->_counters['__' . $vars[0]] = $this->lookup_counter_frame($vars[0])->_counters[$vars[0]]; + } + } + + /** + * @param string $id + * @param int $value + */ + function reset_counter($id = self::DEFAULT_COUNTER, $value = 0) + { + $this->get_parent()->_counters[$id] = intval($value); + } + + /** + * @param $counters + */ + function decrement_counters($counters) + { + foreach ($counters as $id => $increment) { + $this->increment_counter($id, intval($increment) * -1); + } + } + + /** + * @param $counters + */ + function increment_counters($counters) + { + foreach ($counters as $id => $increment) { + $this->increment_counter($id, intval($increment)); + } + } + + /** + * @param string $id + * @param int $increment + */ + function increment_counter($id = self::DEFAULT_COUNTER, $increment = 1) + { + $counter_frame = $this->lookup_counter_frame($id); + + if ($counter_frame) { + if (!isset($counter_frame->_counters[$id])) { + $counter_frame->_counters[$id] = 0; + } + + $counter_frame->_counters[$id] += $increment; + } + } + + /** + * @param string $id + * @return AbstractFrameDecorator|null + */ + function lookup_counter_frame($id = self::DEFAULT_COUNTER) + { + $f = $this->get_parent(); + + while ($f) { + if (isset($f->_counters[$id])) { + return $f; + } + $fp = $f->get_parent(); + + if (!$fp) { + return $f; + } + + $f = $fp; + } + + return null; + } + + /** + * @param string $id + * @param string $type + * @return bool|string + * + * TODO: What version is the best : this one or the one in ListBullet ? + */ + function counter_value($id = self::DEFAULT_COUNTER, $type = "decimal") + { + $type = mb_strtolower($type); + + if (!isset($this->_counters[$id])) { + $this->_counters[$id] = 0; + } + + $value = $this->_counters[$id]; + + switch ($type) { + default: + case "decimal": + return $value; + + case "decimal-leading-zero": + return str_pad($value, 2, "0", STR_PAD_LEFT); + + case "lower-roman": + return Helpers::dec2roman($value); + + case "upper-roman": + return mb_strtoupper(Helpers::dec2roman($value)); + + case "lower-latin": + case "lower-alpha": + return chr(($value % 26) + ord('a') - 1); + + case "upper-latin": + case "upper-alpha": + return chr(($value % 26) + ord('A') - 1); + + case "lower-greek": + return Helpers::unichr($value + 944); + + case "upper-greek": + return Helpers::unichr($value + 912); + } + } + + /** + * + */ + final function position() + { + $this->_positioner->position($this); + } + + /** + * @param $offset_x + * @param $offset_y + * @param bool $ignore_self + */ + final function move($offset_x, $offset_y, $ignore_self = false) + { + $this->_positioner->move($this, $offset_x, $offset_y, $ignore_self); + } + + /** + * @param Block|null $block + */ + final function reflow(Block $block = null) + { + // Uncomment this to see the frames before they're laid out, instead of + // during rendering. + //echo $this->_frame; flush(); + $this->_reflower->reflow($block); + } + + /** + * @return array + */ + final function get_min_max_width() + { + return $this->_reflower->get_min_max_width(); + } + + /** + * Determine current frame width based on contents + * + * @return float + */ + final function calculate_auto_width() + { + return $this->_reflower->calculate_auto_width(); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Block.php b/vendor/dompdf/dompdf/src/FrameDecorator/Block.php new file mode 100644 index 0000000..6c3e5df --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Block.php @@ -0,0 +1,284 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\LineBox; + +/** + * Decorates frames for block layout + * + * @access private + * @package dompdf + */ +class Block extends AbstractFrameDecorator +{ + /** + * Current line index + * + * @var int + */ + protected $_cl; + + /** + * The block's line boxes + * + * @var LineBox[] + */ + protected $_line_boxes; + + /** + * Block constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + + $this->_line_boxes = [new LineBox($this)]; + $this->_cl = 0; + } + + /** + * + */ + function reset() + { + parent::reset(); + + $this->_line_boxes = [new LineBox($this)]; + $this->_cl = 0; + } + + /** + * @return LineBox + */ + function get_current_line_box() + { + return $this->_line_boxes[$this->_cl]; + } + + /** + * @return integer + */ + function get_current_line_number() + { + return $this->_cl; + } + + /** + * @return LineBox[] + */ + function get_line_boxes() + { + return $this->_line_boxes; + } + + /** + * @param integer $line_number + * @return integer + */ + function set_current_line_number($line_number) + { + $line_boxes_count = count($this->_line_boxes); + $cl = max(min($line_number, $line_boxes_count), 0); + return ($this->_cl = $cl); + } + + /** + * @param integer $i + */ + function clear_line($i) + { + if (isset($this->_line_boxes[$i])) { + unset($this->_line_boxes[$i]); + } + } + + /** + * @param Frame $frame + */ + function add_frame_to_line(Frame $frame) + { + if (!$frame->is_in_flow()) { + return; + } + + $style = $frame->get_style(); + + $frame->set_containing_line($this->_line_boxes[$this->_cl]); + + /* + // Adds a new line after a block, only if certain conditions are met + if ((($frame instanceof Inline && $frame->get_node()->nodeName !== "br") || + $frame instanceof Text && trim($frame->get_text())) && + ($frame->get_prev_sibling() && $frame->get_prev_sibling()->get_style()->display === "block" && + $this->_line_boxes[$this->_cl]->w > 0 )) { + + $this->maximize_line_height( $style->length_in_pt($style->line_height), $frame ); + $this->add_line(); + + // Add each child of the inline frame to the line individually + foreach ($frame->get_children() as $child) + $this->add_frame_to_line( $child ); + } + else*/ + + // Handle inline frames (which are effectively wrappers) + if ($frame instanceof Inline) { + // Handle line breaks + if ($frame->get_node()->nodeName === "br") { + $this->maximize_line_height($style->line_height, $frame); + $this->add_line(true); + } + + return; + } + + // Trim leading text if this is an empty line. Kinda a hack to put it here, + // but what can you do... + if ($this->get_current_line_box()->w == 0 && + $frame->is_text_node() && + !$frame->is_pre() + ) { + $frame->set_text(ltrim($frame->get_text())); + $frame->recalculate_width(); + } + + $w = $frame->get_margin_width(); + + // FIXME: Why? Doesn't quite seem to be the correct thing to do, + // but does appear to be necessary. Hack to handle wrapped white space? + if ($w == 0 && $frame->get_node()->nodeName !== "hr" && !$frame->is_pre()) { + return; + } + + // Debugging code: + /* + Helpers::pre_r("\n

Adding frame to line:

"); + + // Helpers::pre_r("Me: " . $this->get_node()->nodeName . " (" . spl_object_hash($this->get_node()) . ")"); + // Helpers::pre_r("Node: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")"); + if ( $frame->is_text_node() ) + Helpers::pre_r('"'.$frame->get_node()->nodeValue.'"'); + + Helpers::pre_r("Line width: " . $this->_line_boxes[$this->_cl]->w); + Helpers::pre_r("Frame: " . get_class($frame)); + Helpers::pre_r("Frame width: " . $w); + Helpers::pre_r("Frame height: " . $frame->get_margin_height()); + Helpers::pre_r("Containing block width: " . $this->get_containing_block("w")); + */ + // End debugging + + $line = $this->_line_boxes[$this->_cl]; + if ($line->left + $line->w + $line->right + $w > $this->get_containing_block("w")) { + $this->add_line(); + } + + $frame->position(); + + $current_line = $this->_line_boxes[$this->_cl]; + $current_line->add_frame($frame); + + if ($frame->is_text_node()) { + // split the text into words (used to determine spacing between words on justified lines) + // The regex splits on everything that's a separator (^\S double negative), excluding nbsp (\xa0) + // This currently excludes the "narrow nbsp" character + $words = preg_split('/[^\S\xA0]+/u', trim($frame->get_text())); + $current_line->wc += count($words); + } + + $this->increase_line_width($w); + + $this->maximize_line_height($frame->get_margin_height(), $frame); + } + + /** + * @param Frame $frame + */ + function remove_frames_from_line(Frame $frame) + { + // Search backwards through the lines for $frame + $i = $this->_cl; + $j = null; + + while ($i >= 0) { + if (($j = in_array($frame, $this->_line_boxes[$i]->get_frames(), true)) !== false) { + break; + } + + $i--; + } + + if ($j === false) { + return; + } + + // Remove $frame and all frames that follow + while ($j < count($this->_line_boxes[$i]->get_frames())) { + $frames = $this->_line_boxes[$i]->get_frames(); + $f = $frames[$j]; + $frames[$j] = null; + unset($frames[$j]); + $j++; + $this->_line_boxes[$i]->w -= $f->get_margin_width(); + } + + // Recalculate the height of the line + $h = 0; + foreach ($this->_line_boxes[$i]->get_frames() as $f) { + $h = max($h, $f->get_margin_height()); + } + + $this->_line_boxes[$i]->h = $h; + + // Remove all lines that follow + while ($this->_cl > $i) { + $this->_line_boxes[$this->_cl] = null; + unset($this->_line_boxes[$this->_cl]); + $this->_cl--; + } + } + + /** + * @param float $w + */ + function increase_line_width($w) + { + $this->_line_boxes[$this->_cl]->w += $w; + } + + /** + * @param $val + * @param Frame $frame + */ + function maximize_line_height($val, Frame $frame) + { + if ($val > $this->_line_boxes[$this->_cl]->h) { + $this->_line_boxes[$this->_cl]->tallest_frame = $frame; + $this->_line_boxes[$this->_cl]->h = $val; + } + } + + /** + * @param bool $br + */ + function add_line($br = false) + { + $this->_line_boxes[$this->_cl]->br = $br; + $y = $this->_line_boxes[$this->_cl]->y + $this->_line_boxes[$this->_cl]->h; + + $new_line = new LineBox($this, $y); + + $this->_line_boxes[++$this->_cl] = $new_line; + } + + //........................................................................ +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Image.php b/vendor/dompdf/dompdf/src/FrameDecorator/Image.php new file mode 100644 index 0000000..0dc62e9 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Image.php @@ -0,0 +1,91 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\Image\Cache; + +/** + * Decorates frames for image layout and rendering + * + * @package dompdf + */ +class Image extends AbstractFrameDecorator +{ + + /** + * The path to the image file (note that remote images are + * downloaded locally to Options:tempDir). + * + * @var string + */ + protected $_image_url; + + /** + * The image's file error message + * + * @var string + */ + protected $_image_msg; + + /** + * Class constructor + * + * @param Frame $frame the frame to decorate + * @param DOMPDF $dompdf the document's dompdf object (required to resolve relative & remote urls) + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + $url = $frame->get_node()->getAttribute("src"); + + $debug_png = $dompdf->getOptions()->getDebugPng(); + if ($debug_png) { + print '[__construct ' . $url . ']'; + } + + list($this->_image_url, /*$type*/, $this->_image_msg) = Cache::resolve_url( + $url, + $dompdf->getProtocol(), + $dompdf->getBaseHost(), + $dompdf->getBasePath(), + $dompdf + ); + + if (Cache::is_broken($this->_image_url) && + $alt = $frame->get_node()->getAttribute("alt") + ) { + $style = $frame->get_style(); + $style->width = (4 / 3) * $dompdf->getFontMetrics()->getTextWidth($alt, $style->font_family, $style->font_size, $style->word_spacing); + $style->height = $dompdf->getFontMetrics()->getFontHeight($style->font_family, $style->font_size); + } + } + + /** + * Return the image's url + * + * @return string The url of this image + */ + function get_image_url() + { + return $this->_image_url; + } + + /** + * Return the image's error message + * + * @return string The image's error message + */ + function get_image_msg() + { + return $this->_image_msg; + } + +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Inline.php b/vendor/dompdf/dompdf/src/FrameDecorator/Inline.php new file mode 100644 index 0000000..5b39381 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Inline.php @@ -0,0 +1,106 @@ + + * @author Helmut Tischer + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use DOMElement; +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\Exception; + +/** + * Decorates frames for inline layout + * + * @access private + * @package dompdf + */ +class Inline extends AbstractFrameDecorator +{ + + /** + * Inline constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + } + + /** + * @param Frame|null $frame + * @param bool $force_pagebreak + * @throws Exception + */ + function split(Frame $frame = null, $force_pagebreak = false) + { + if (is_null($frame)) { + $this->get_parent()->split($this, $force_pagebreak); + return; + } + + if ($frame->get_parent() !== $this) { + throw new Exception("Unable to split: frame is not a child of this one."); + } + + $node = $this->_frame->get_node(); + + if ($node instanceof DOMElement && $node->hasAttribute("id")) { + $node->setAttribute("data-dompdf-original-id", $node->getAttribute("id")); + $node->removeAttribute("id"); + } + + $split = $this->copy($node->cloneNode()); + // if this is a generated node don't propagate the content style + if ($split->get_node()->nodeName == "dompdf_generated") { + $split->get_style()->content = "normal"; + } + $this->get_parent()->insert_child_after($split, $this); + + // Unset the current node's right style properties + $style = $this->_frame->get_style(); + $style->margin_right = 0; + $style->padding_right = 0; + $style->border_right_width = 0; + + // Unset the split node's left style properties since we don't want them + // to propagate + $style = $split->get_style(); + $style->margin_left = 0; + $style->padding_left = 0; + $style->border_left_width = 0; + + //On continuation of inline element on next line, + //don't repeat non-vertically repeatble background images + //See e.g. in testcase image_variants, long desriptions + if (($url = $style->background_image) && $url !== "none" + && ($repeat = $style->background_repeat) && $repeat !== "repeat" && $repeat !== "repeat-y" + ) { + $style->background_image = "none"; + } + + // Add $frame and all following siblings to the new split node + $iter = $frame; + while ($iter) { + $frame = $iter; + $iter = $iter->get_next_sibling(); + $frame->reset(); + $split->append_child($frame); + } + + $page_breaks = ["always", "left", "right"]; + $frame_style = $frame->get_style(); + if ($force_pagebreak || + in_array($frame_style->page_break_before, $page_breaks) || + in_array($frame_style->page_break_after, $page_breaks) + ) { + $this->get_parent()->split($split, true); + } + } + +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/ListBullet.php b/vendor/dompdf/dompdf/src/FrameDecorator/ListBullet.php new file mode 100644 index 0000000..0479fc1 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/ListBullet.php @@ -0,0 +1,87 @@ + + * @author Helmut Tischer + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; + +/** + * Decorates frames for list bullet rendering + * + * @package dompdf + */ +class ListBullet extends AbstractFrameDecorator +{ + + const BULLET_PADDING = 1; // Distance from bullet to text in pt + // As fraction of font size (including descent). See also DECO_THICKNESS. + const BULLET_THICKNESS = 0.04; // Thickness of bullet outline. Screen: 0.08, print: better less, e.g. 0.04 + const BULLET_DESCENT = 0.3; //descent of font below baseline. Todo: Guessed for now. + const BULLET_SIZE = 0.35; // bullet diameter. For now 0.5 of font_size without descent. + + static $BULLET_TYPES = ["disc", "circle", "square"]; + + /** + * ListBullet constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + } + + /** + * @return float|int + */ + function get_margin_width() + { + $style = $this->_frame->get_style(); + + if ($style->list_style_type === "none") { + return 0; + } + + return $style->font_size * self::BULLET_SIZE + 2 * self::BULLET_PADDING; + } + + /** + * hits only on "inset" lists items, to increase height of box + * + * @return float|int + */ + function get_margin_height() + { + $style = $this->_frame->get_style(); + + if ($style->list_style_type === "none") { + return 0; + } + + return $style->font_size * self::BULLET_SIZE + 2 * self::BULLET_PADDING; + } + + /** + * @return float|int + */ + function get_width() + { + return $this->get_margin_width(); + } + + /** + * @return float|int + */ + function get_height() + { + return $this->get_margin_height(); + } + + //........................................................................ +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/ListBulletImage.php b/vendor/dompdf/dompdf/src/FrameDecorator/ListBulletImage.php new file mode 100644 index 0000000..65f1857 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/ListBulletImage.php @@ -0,0 +1,171 @@ + + * @author Helmut Tischer + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\Helpers; +use Dompdf\Image\Cache; + +/** + * Decorates frames for list bullets with custom images + * + * @package dompdf + */ +class ListBulletImage extends AbstractFrameDecorator +{ + + /** + * The underlying image frame + * + * @var Image + */ + protected $_img; + + /** + * The image's width in pixels + * + * @var int + */ + protected $_width; + + /** + * The image's height in pixels + * + * @var int + */ + protected $_height; + + /** + * Class constructor + * + * @param Frame $frame the bullet frame to decorate + * @param Dompdf $dompdf the document's dompdf object + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + $style = $frame->get_style(); + $url = $style->list_style_image; + $frame->get_node()->setAttribute("src", $url); + $this->_img = new Image($frame, $dompdf); + parent::__construct($this->_img, $dompdf); + + if (Cache::is_broken($this->_img->get_image_url())) { + $width = 0; + $height = 0; + } else { + list($width, $height) = Helpers::dompdf_getimagesize($this->_img->get_image_url(), $dompdf->getHttpContext()); + } + + // Resample the bullet image to be consistent with 'auto' sized images + // See also Image::get_min_max_width + // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary. + $dpi = $this->_dompdf->getOptions()->getDpi(); + $this->_width = ((float)rtrim($width, "px") * 72) / $dpi; + $this->_height = ((float)rtrim($height, "px") * 72) / $dpi; + + //If an image is taller as the containing block/box, the box should be extended. + //Neighbour elements are overwriting the overlapping image areas. + //Todo: Where can the box size be extended? + //Code below has no effect. + //See block_frame_reflower _calculate_restricted_height + //See generated_frame_reflower, Dompdf:render() "list-item", "-dompdf-list-bullet"S. + //Leave for now + //if ($style->min_height < $this->_height ) { + // $style->min_height = $this->_height; + //} + //$style->height = "auto"; + } + + /** + * Return the bullet's width + * + * @return int + */ + function get_width() + { + //ignore image width, use same width as on predefined bullet ListBullet + //for proper alignment of bullet image and text. Allow image to not fitting on left border. + //This controls the distance between bullet image and text + //return $this->_width; + return $this->_frame->get_style()->font_size * ListBullet::BULLET_SIZE + + 2 * ListBullet::BULLET_PADDING; + } + + /** + * Return the bullet's height + * + * @return int + */ + function get_height() + { + //based on image height + if ($this->_height == 0) { + $style = $this->_frame->get_style(); + + if ($style->list_style_type === "none") { + return 0; + } + + return $style->font_size * ListBullet::BULLET_SIZE + 2 * ListBullet::BULLET_PADDING; + } else { + return $this->_height; + } + } + + /** + * Override get_margin_width + * + * @return int + */ + function get_margin_width() + { + //ignore image width, use same width as on predefined bullet ListBullet + //for proper alignment of bullet image and text. Allow image to not fitting on left border. + //This controls the extra indentation of text to make room for the bullet image. + //Here use actual image size, not predefined bullet size + //return $this->_frame->get_style()->font_size*ListBullet::BULLET_SIZE + + // 2 * ListBullet::BULLET_PADDING; + + // Small hack to prevent indenting of list text + // Image might not exist, then position like on list_bullet_frame_decorator fallback to none. + if ($this->_frame->get_style()->list_style_position === "outside" || $this->_width == 0) { + return 0; + } + //This aligns the "inside" image position with the text. + //The text starts to the right of the image. + //Between the image and the text there is an added margin of image width. + //Where this comes from is unknown. + //The corresponding ListBullet sets a smaller margin. bullet size? + return $this->_width + 2 * ListBullet::BULLET_PADDING; + } + + /** + * Override get_margin_height() + * + * @return int + */ + function get_margin_height() + { + //Hits only on "inset" lists items, to increase height of box + //based on image height + return $this->_height + 2 * ListBullet::BULLET_PADDING; + } + + /** + * Return image url + * + * @return string + */ + function get_image_url() + { + return $this->_img->get_image_url(); + } + +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/NullFrameDecorator.php b/vendor/dompdf/dompdf/src/FrameDecorator/NullFrameDecorator.php new file mode 100644 index 0000000..e3457cf --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/NullFrameDecorator.php @@ -0,0 +1,34 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; + +/** + * Dummy decorator + * + * @package dompdf + */ +class NullFrameDecorator extends AbstractFrameDecorator +{ + /** + * NullFrameDecorator constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + $style = $this->_frame->get_style(); + $style->width = 0; + $style->height = 0; + $style->margin = 0; + $style->padding = 0; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Page.php b/vendor/dompdf/dompdf/src/FrameDecorator/Page.php new file mode 100644 index 0000000..6278776 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Page.php @@ -0,0 +1,682 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Css\Style; +use Dompdf\Dompdf; +use Dompdf\Helpers; +use Dompdf\Frame; +use Dompdf\Renderer; + +/** + * Decorates frames for page layout + * + * @access private + * @package dompdf + */ +class Page extends AbstractFrameDecorator +{ + + /** + * y value of bottom page margin + * + * @var float + */ + protected $_bottom_page_margin; + + /** + * Flag indicating page is full. + * + * @var bool + */ + protected $_page_full; + + /** + * Number of tables currently being reflowed + * + * @var int + */ + protected $_in_table; + + /** + * The pdf renderer + * + * @var Renderer + */ + protected $_renderer; + + /** + * This page's floating frames + * + * @var array + */ + protected $_floating_frames = []; + + //........................................................................ + + /** + * Class constructor + * + * @param Frame $frame the frame to decorate + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + $this->_page_full = false; + $this->_in_table = 0; + $this->_bottom_page_margin = null; + } + + /** + * Set the renderer used for this pdf + * + * @param Renderer $renderer the renderer to use + */ + function set_renderer($renderer) + { + $this->_renderer = $renderer; + } + + /** + * Return the renderer used for this pdf + * + * @return Renderer + */ + function get_renderer() + { + return $this->_renderer; + } + + /** + * Set the frame's containing block. Overridden to set $this->_bottom_page_margin. + * + * @param float $x + * @param float $y + * @param float $w + * @param float $h + */ + function set_containing_block($x = null, $y = null, $w = null, $h = null) + { + parent::set_containing_block($x, $y, $w, $h); + //$w = $this->get_containing_block("w"); + if (isset($h)) { + $this->_bottom_page_margin = $h; + } // - $this->_frame->get_style()->length_in_pt($this->_frame->get_style()->margin_bottom, $w); + } + + /** + * Returns true if the page is full and is no longer accepting frames. + * + * @return bool + */ + function is_full() + { + return $this->_page_full; + } + + /** + * Start a new page by resetting the full flag. + */ + function next_page() + { + $this->_floating_frames = []; + $this->_renderer->new_page(); + $this->_page_full = false; + } + + /** + * Indicate to the page that a table is currently being reflowed. + */ + function table_reflow_start() + { + $this->_in_table++; + } + + /** + * Indicate to the page that table reflow is finished. + */ + function table_reflow_end() + { + $this->_in_table--; + } + + /** + * Return whether we are currently in a nested table or not + * + * @return bool + */ + function in_nested_table() + { + return $this->_in_table > 1; + } + + /** + * Check if a forced page break is required before $frame. This uses the + * frame's page_break_before property as well as the preceeding frame's + * page_break_after property. + * + * @link http://www.w3.org/TR/CSS21/page.html#forced + * + * @param Frame $frame the frame to check + * + * @return bool true if a page break occured + */ + function check_forced_page_break(Frame $frame) + { + // Skip check if page is already split + if ($this->_page_full) { + return null; + } + + $block_types = ["block", "list-item", "table", "inline"]; + $page_breaks = ["always", "left", "right"]; + + $style = $frame->get_style(); + + if (!in_array($style->display, $block_types)) { + return false; + } + + // Find the previous block-level sibling + $prev = $frame->get_prev_sibling(); + + while ($prev && !in_array($prev->get_style()->display, $block_types)) { + $prev = $prev->get_prev_sibling(); + } + + if (in_array($style->page_break_before, $page_breaks)) { + // Prevent cascading splits + $frame->split(null, true); + // We have to grab the style again here because split() resets + // $frame->style to the frame's original style. + $frame->get_style()->page_break_before = "auto"; + $this->_page_full = true; + $frame->_already_pushed = true; + + return true; + } + + if ($prev && in_array($prev->get_style()->page_break_after, $page_breaks)) { + // Prevent cascading splits + $frame->split(null, true); + $prev->get_style()->page_break_after = "auto"; + $this->_page_full = true; + $frame->_already_pushed = true; + + return true; + } + + if ($prev && $prev->get_last_child() && $frame->get_node()->nodeName != "body") { + $prev_last_child = $prev->get_last_child(); + if (in_array($prev_last_child->get_style()->page_break_after, $page_breaks)) { + $frame->split(null, true); + $prev_last_child->get_style()->page_break_after = "auto"; + $this->_page_full = true; + $frame->_already_pushed = true; + + return true; + } + } + + return false; + } + + /** + * Determine if a page break is allowed before $frame + * http://www.w3.org/TR/CSS21/page.html#allowed-page-breaks + * + * In the normal flow, page breaks can occur at the following places: + * + * 1. In the vertical margin between block boxes. When a page + * break occurs here, the used values of the relevant + * 'margin-top' and 'margin-bottom' properties are set to '0'. + * 2. Between line boxes inside a block box. + * 3. Between the content edge of a block container box and the + * outer edges of its child content (margin edges of block-level + * children or line box edges for inline-level children) if there + * is a (non-zero) gap between them. + * + * These breaks are subject to the following rules: + * + * * Rule A: Breaking at (1) is allowed only if the + * 'page-break-after' and 'page-break-before' properties of + * all the elements generating boxes that meet at this margin + * allow it, which is when at least one of them has the value + * 'always', 'left', or 'right', or when all of them are + * 'auto'. + * + * * Rule B: However, if all of them are 'auto' and the + * nearest common ancestor of all the elements has a + * 'page-break-inside' value of 'avoid', then breaking here is + * not allowed. + * + * * Rule C: Breaking at (2) is allowed only if the number of + * line boxes between the break and the start of the enclosing + * block box is the value of 'orphans' or more, and the number + * of line boxes between the break and the end of the box is + * the value of 'widows' or more. + * + * * Rule D: In addition, breaking at (2) is allowed only if + * the 'page-break-inside' property is 'auto'. + * + * If the above doesn't provide enough break points to keep + * content from overflowing the page boxes, then rules B and D are + * dropped in order to find additional breakpoints. + * + * If that still does not lead to sufficient break points, rules A + * and C are dropped as well, to find still more break points. + * + * We will also allow breaks between table rows. However, when + * splitting a table, the table headers should carry over to the + * next page (but they don't yet). + * + * @param Frame $frame the frame to check + * + * @return bool true if a break is allowed, false otherwise + */ + protected function _page_break_allowed(Frame $frame) + { + $block_types = ["block", "list-item", "table", "-dompdf-image"]; + Helpers::dompdf_debug("page-break", "_page_break_allowed(" . $frame->get_node()->nodeName . ")"); + $display = $frame->get_style()->display; + + // Block Frames (1): + if (in_array($display, $block_types)) { + + // Avoid breaks within table-cells + if ($this->_in_table > ($display === "table" ? 1 : 0)) { + Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table); + + return false; + } + + // Rules A & B + + if ($frame->get_style()->page_break_before === "avoid") { + Helpers::dompdf_debug("page-break", "before: avoid"); + + return false; + } + + // Find the preceeding block-level sibling + $prev = $frame->get_prev_sibling(); + while ($prev && !in_array($prev->get_style()->display, $block_types)) { + $prev = $prev->get_prev_sibling(); + } + + // Does the previous element allow a page break after? + if ($prev && $prev->get_style()->page_break_after === "avoid") { + Helpers::dompdf_debug("page-break", "after: avoid"); + + return false; + } + + // If both $prev & $frame have the same parent, check the parent's + // page_break_inside property. + $parent = $frame->get_parent(); + if ($prev && $parent && $parent->get_style()->page_break_inside === "avoid") { + Helpers::dompdf_debug("page-break", "parent inside: avoid"); + + return false; + } + + // To prevent cascading page breaks when a top-level element has + // page-break-inside: avoid, ensure that at least one frame is + // on the page before splitting. + if ($parent->get_node()->nodeName === "body" && !$prev) { + // We are the body's first child + Helpers::dompdf_debug("page-break", "Body's first child."); + + return false; + } + + // If the frame is the first block-level frame, only allow a page + // break if there is a (non-zero) gap between the frame and its + // parent + if (!$prev && $parent) { + Helpers::dompdf_debug("page-break", "First block level frame, checking gap"); + + return $frame->get_style()->length_in_pt($frame->get_style()->margin_top) != 0 + || $parent->get_style()->length_in_pt($parent->get_style()->padding_top) != 0; + } + + Helpers::dompdf_debug("page-break", "block: break allowed"); + + return true; + + } // Inline frames (2): + else { + if (in_array($display, Style::$INLINE_TYPES)) { + + // Avoid breaks within table-cells + if ($this->_in_table) { + Helpers::dompdf_debug("page-break", "In table: " . $this->_in_table); + + return false; + } + + // Rule C + $block_parent = $frame->find_block_parent(); + if (count($block_parent->get_line_boxes()) < $frame->get_style()->orphans) { + Helpers::dompdf_debug("page-break", "orphans"); + + return false; + } + + // FIXME: Checking widows is tricky without having laid out the + // remaining line boxes. Just ignore it for now... + + // Rule D + $p = $block_parent; + while ($p) { + if ($p->get_style()->page_break_inside === "avoid") { + Helpers::dompdf_debug("page-break", "parent->inside: avoid"); + + return false; + } + $p = $p->find_block_parent(); + } + + // To prevent cascading page breaks when a top-level element has + // page-break-inside: avoid, ensure that at least one frame with + // some content is on the page before splitting. + $prev = $frame->get_prev_sibling(); + while ($prev && ($prev->is_text_node() && trim($prev->get_node()->nodeValue) == "")) { + $prev = $prev->get_prev_sibling(); + } + + if ($block_parent->get_node()->nodeName === "body" && !$prev) { + // We are the body's first child + Helpers::dompdf_debug("page-break", "Body's first child."); + + return false; + } + + // Skip breaks on empty text nodes + if ($frame->is_text_node() && $frame->get_node()->nodeValue == "") { + return false; + } + + Helpers::dompdf_debug("page-break", "inline: break allowed"); + + return true; + + // Table-rows + } else { + if ($display === "table-row") { + // Simply check if the parent table's page_break_inside property is + // not 'avoid' + $table = Table::find_parent_table($frame); + + $p = $table; + while ($p) { + if ($p->get_style()->page_break_inside === "avoid") { + Helpers::dompdf_debug("page-break", "parent->inside: avoid"); + + return false; + } + $p = $p->find_block_parent(); + } + + // Avoid breaking before the first row of a table + if ($table && $table->get_first_child() === $frame || $table->get_first_child()->get_first_child() === $frame) { + Helpers::dompdf_debug("page-break", "table: first-row"); + + return false; + } + + // If this is a nested table, prevent the page from breaking + if ($this->_in_table > 1) { + Helpers::dompdf_debug("page-break", "table: nested table"); + + return false; + } + + Helpers::dompdf_debug("page-break", "table-row/row-groups: break allowed"); + + return true; + } else { + if (in_array($display, Table::$ROW_GROUPS)) { + + // Disallow breaks at row-groups: only split at row boundaries + return false; + + } else { + Helpers::dompdf_debug("page-break", "? " . $frame->get_style()->display . ""); + + return false; + } + } + } + } + } + + /** + * Check if $frame will fit on the page. If the frame does not fit, + * the frame tree is modified so that a page break occurs in the + * correct location. + * + * @param Frame $frame the frame to check + * + * @return bool + */ + function check_page_break(Frame $frame) + { + if ($this->_page_full || $frame->_already_pushed) { + return false; + } + + $p = $frame; + do { + $display = $p->get_style()->display; + if ($display == "table-row") { + if ($p->_already_pushed) { return false; } + } + } while ($p = $p->get_parent()); + + // If the frame is absolute or fixed it shouldn't break + $p = $frame; + do { + if ($p->is_absolute()) { + return false; + } + } while ($p = $p->get_parent()); + + $margin_height = $frame->get_margin_height(); + + // Determine the frame's maximum y value + $max_y = (float)$frame->get_position("y") + $margin_height; + + // If a split is to occur here, then the bottom margins & paddings of all + // parents of $frame must fit on the page as well: + $p = $frame->get_parent(); + while ($p) { + $max_y += (float) $p->get_style()->computed_bottom_spacing(); + $p = $p->get_parent(); + } + + // Check if $frame flows off the page + if ($max_y <= $this->_bottom_page_margin) { + // no: do nothing + return false; + } + + Helpers::dompdf_debug("page-break", "check_page_break"); + Helpers::dompdf_debug("page-break", "in_table: " . $this->_in_table); + + // yes: determine page break location + $iter = $frame; + $flg = false; + $pushed_flg = false; + + $in_table = $this->_in_table; + + Helpers::dompdf_debug("page-break", "Starting search"); + while ($iter) { + // echo "\nbacktrack: " .$iter->get_node()->nodeName ." ".spl_object_hash($iter->get_node()). ""; + if ($iter === $this) { + Helpers::dompdf_debug("page-break", "reached root."); + // We've reached the root in our search. Just split at $frame. + break; + } + + if ($iter->_already_pushed) { + $pushed_flg = true; + } elseif ($this->_page_break_allowed($iter)) { + Helpers::dompdf_debug("page-break", "break allowed, splitting."); + $iter->split(null, true); + $this->_page_full = true; + $this->_in_table = $in_table; + $iter->_already_pushed = true; + $frame->_already_pushed = true; + + return true; + } + + if (!$flg && $next = $iter->get_last_child()) { + Helpers::dompdf_debug("page-break", "following last child."); + + if ($next->is_table()) { + $this->_in_table++; + } + + $iter = $next; + $pushed_flg = false; + continue; + } + + if ($pushed_flg) { + // The frame was already pushed, avoid breaking on a previous page + break; + } + + if ($next = $iter->get_prev_sibling()) { + Helpers::dompdf_debug("page-break", "following prev sibling."); + + if ($next->is_table() && !$iter->is_table()) { + $this->_in_table++; + } else if (!$next->is_table() && $iter->is_table()) { + $this->_in_table--; + } + + $iter = $next; + $flg = false; + continue; + } + + if ($next = $iter->get_parent()) { + Helpers::dompdf_debug("page-break", "following parent."); + + if ($iter->is_table()) { + $this->_in_table--; + } + + $iter = $next; + $flg = true; + continue; + } + + break; + } + + $this->_in_table = $in_table; + + // No valid page break found. Just break at $frame. + Helpers::dompdf_debug("page-break", "no valid break found, just splitting."); + + // If we are in a table, backtrack to the nearest top-level table row + if ($this->_in_table) { + $iter = $frame; + while ($iter && $iter->get_style()->display !== "table-row" && $iter->get_style()->display !== 'table-row-group' && $iter->_already_pushed === false) { + $iter = $iter->get_parent(); + } + + if ($iter) { + $iter->split(null, true); + $iter->_already_pushed = true; + } else { + return false; + } + } else { + $frame->split(null, true); + } + + $this->_page_full = true; + $frame->_already_pushed = true; + + return true; + } + + //........................................................................ + + /** + * @param Frame|null $frame + * @param bool $force_pagebreak + */ + function split(Frame $frame = null, $force_pagebreak = false) + { + // Do nothing + } + + /** + * Add a floating frame + * + * @param Frame $frame + * + * @return void + */ + function add_floating_frame(Frame $frame) + { + array_unshift($this->_floating_frames, $frame); + } + + /** + * @return Frame[] + */ + function get_floating_frames() + { + return $this->_floating_frames; + } + + /** + * @param $key + */ + public function remove_floating_frame($key) + { + unset($this->_floating_frames[$key]); + } + + /** + * @param Frame $child + * @return int|mixed + */ + public function get_lowest_float_offset(Frame $child) + { + $style = $child->get_style(); + $side = $style->clear; + $float = $style->float; + + $y = 0; + + if ($float === "none") { + foreach ($this->_floating_frames as $key => $frame) { + if ($side === "both" || $frame->get_style()->float === $side) { + $y = max($y, $frame->get_position("y") + $frame->get_margin_height()); + } + $this->remove_floating_frame($key); + } + } + + if ($y > 0) { + $y++; // add 1px buffer from float + } + + return $y; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Table.php b/vendor/dompdf/dompdf/src/FrameDecorator/Table.php new file mode 100644 index 0000000..5e28939 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Table.php @@ -0,0 +1,398 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Cellmap; +use DOMNode; +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\Frame\Factory; + +/** + * Decorates Frames for table layout + * + * @package dompdf + */ +class Table extends AbstractFrameDecorator +{ + public static $VALID_CHILDREN = [ + "table-row-group", + "table-row", + "table-header-group", + "table-footer-group", + "table-column", + "table-column-group", + "table-caption", + "table-cell" + ]; + + public static $ROW_GROUPS = [ + 'table-row-group', + 'table-header-group', + 'table-footer-group' + ]; + + /** + * The Cellmap object for this table. The cellmap maps table cells + * to rows and columns, and aids in calculating column widths. + * + * @var \Dompdf\Cellmap + */ + protected $_cellmap; + + /** + * The minimum width of the table, in pt + * + * @var float + */ + protected $_min_width; + + /** + * The maximum width of the table, in pt + * + * @var float + */ + protected $_max_width; + + /** + * Table header rows. Each table header is duplicated when a table + * spans pages. + * + * @var array + */ + protected $_headers; + + /** + * Table footer rows. Each table footer is duplicated when a table + * spans pages. + * + * @var array + */ + protected $_footers; + + /** + * Class constructor + * + * @param Frame $frame the frame to decorate + * @param Dompdf $dompdf + */ + public function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + $this->_cellmap = new Cellmap($this); + + if ($frame->get_style()->table_layout === "fixed") { + $this->_cellmap->set_layout_fixed(true); + } + + $this->_min_width = null; + $this->_max_width = null; + $this->_headers = []; + $this->_footers = []; + } + + public function reset() + { + parent::reset(); + $this->_cellmap->reset(); + $this->_min_width = null; + $this->_max_width = null; + $this->_headers = []; + $this->_footers = []; + $this->_reflower->reset(); + } + + //........................................................................ + + /** + * split the table at $row. $row and all subsequent rows will be + * added to the clone. This method is overidden in order to remove + * frames from the cellmap properly. + * + * @param Frame $child + * @param bool $force_pagebreak + * + * @return void + */ + public function split(Frame $child = null, $force_pagebreak = false) + { + if (is_null($child)) { + parent::split(); + + return; + } + + // If $child is a header or if it is the first non-header row, do + // not duplicate headers, simply move the table to the next page. + if (count($this->_headers) && !in_array($child, $this->_headers, true) && + !in_array($child->get_prev_sibling(), $this->_headers, true) + ) { + $first_header = null; + + // Insert copies of the table headers before $child + foreach ($this->_headers as $header) { + + $new_header = $header->deep_copy(); + + if (is_null($first_header)) { + $first_header = $new_header; + } + + $this->insert_child_before($new_header, $child); + } + + parent::split($first_header); + + } elseif (in_array($child->get_style()->display, self::$ROW_GROUPS)) { + + // Individual rows should have already been handled + parent::split($child); + + } else { + + $iter = $child; + + while ($iter) { + $this->_cellmap->remove_row($iter); + $iter = $iter->get_next_sibling(); + } + + parent::split($child); + } + } + + /** + * Return a copy of this frame with $node as its node + * + * @param DOMNode $node + * + * @return Frame + */ + public function copy(DOMNode $node) + { + $deco = parent::copy($node); + + // In order to keep columns' widths through pages + $deco->_cellmap->set_columns($this->_cellmap->get_columns()); + $deco->_cellmap->lock_columns(); + + return $deco; + } + + /** + * Static function to locate the parent table of a frame + * + * @param Frame $frame + * + * @return Table the table that is an ancestor of $frame + */ + public static function find_parent_table(Frame $frame) + { + while ($frame = $frame->get_parent()) { + if ($frame->is_table()) { + break; + } + } + + return $frame; + } + + /** + * Return this table's Cellmap + * + * @return \Dompdf\Cellmap + */ + public function get_cellmap() + { + return $this->_cellmap; + } + + /** + * Return the minimum width of this table + * + * @return float + */ + public function get_min_width() + { + return $this->_min_width; + } + + /** + * Return the maximum width of this table + * + * @return float + */ + public function get_max_width() + { + return $this->_max_width; + } + + /** + * Set the minimum width of the table + * + * @param float $width the new minimum width + */ + public function set_min_width($width) + { + $this->_min_width = $width; + } + + /** + * Set the maximum width of the table + * + * @param float $width the new maximum width + */ + public function set_max_width($width) + { + $this->_max_width = $width; + } + + /** + * Restructure tree so that the table has the correct structure. + * Invalid children (i.e. all non-table-rows) are moved below the + * table. + * + * @fixme #1363 Method has some bugs. $table_row has not been initialized and lookup most likely could return an + * array of Style instead a Style Object + */ + public function normalise() + { + // Store frames generated by invalid tags and move them outside the table + $erroneous_frames = []; + $anon_row = false; + $iter = $this->get_first_child(); + while ($iter) { + $child = $iter; + $iter = $iter->get_next_sibling(); + + $display = $child->get_style()->display; + + if ($anon_row) { + + if ($display === "table-row") { + // Add the previous anonymous row + $this->insert_child_before($table_row, $child); + + $table_row->normalise(); + $child->normalise(); + $this->_cellmap->add_row(); + $anon_row = false; + continue; + } + + // add the child to the anonymous row + $table_row->append_child($child); + continue; + + } else { + + if ($display === "table-row") { + $child->normalise(); + continue; + } + + if ($display === "table-cell") { + $css = $this->get_style()->get_stylesheet(); + + // Create an anonymous table row group + $tbody = $this->get_node()->ownerDocument->createElement("tbody"); + + $frame = new Frame($tbody); + + $style = $css->create_style(); + $style->inherit($this->get_style()); + + // Lookup styles for tbody tags. If the user wants styles to work + // better, they should make the tbody explicit... I'm not going to + // try to guess what they intended. + if ($tbody_style = $css->lookup("tbody")) { + $style->merge($tbody_style); + } + $style->display = 'table-row-group'; + + // Okay, I have absolutely no idea why I need this clone here, but + // if it's omitted, php (as of 2004-07-28) segfaults. + $frame->set_style($style); + $table_row_group = Factory::decorate_frame($frame, $this->_dompdf, $this->_root); + + // Create an anonymous table row + $tr = $this->get_node()->ownerDocument->createElement("tr"); + + $frame = new Frame($tr); + + $style = $css->create_style(); + $style->inherit($this->get_style()); + + // Lookup styles for tr tags. If the user wants styles to work + // better, they should make the tr explicit... I'm not going to + // try to guess what they intended. + if ($tr_style = $css->lookup("tr")) { + $style->merge($tr_style); + } + $style->display = 'table-row'; + + // Okay, I have absolutely no idea why I need this clone here, but + // if it's omitted, php (as of 2004-07-28) segfaults. + $frame->set_style(clone $style); + $table_row = Factory::decorate_frame($frame, $this->_dompdf, $this->_root); + + // Add the cell to the row + $table_row->append_child($child, true); + + // Add the tr to the tbody + $table_row_group->append_child($table_row, true); + + $anon_row = true; + continue; + } + + if (!in_array($display, self::$VALID_CHILDREN)) { + $erroneous_frames[] = $child; + continue; + } + + // Normalise other table parts (i.e. row groups) + foreach ($child->get_children() as $grandchild) { + if ($grandchild->get_style()->display === "table-row") { + $grandchild->normalise(); + } + } + + // Add headers and footers + if ($display === "table-header-group") { + $this->_headers[] = $child; + } elseif ($display === "table-footer-group") { + $this->_footers[] = $child; + } + } + } + + if ($anon_row && $table_row_group instanceof AbstractFrameDecorator) { + // Add the row to the table + $this->_frame->append_child($table_row_group->_frame); + $table_row->normalise(); + } + + foreach ($erroneous_frames as $frame) { + $this->move_after($frame); + } + } + + //........................................................................ + + /** + * Moves the specified frame and it's corresponding node outside of + * the table. + * + * @param Frame $frame the frame to move + */ + public function move_after(Frame $frame) + { + $this->get_parent()->insert_child_after($frame, $this); + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/TableCell.php b/vendor/dompdf/dompdf/src/FrameDecorator/TableCell.php new file mode 100644 index 0000000..996e16f --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/TableCell.php @@ -0,0 +1,144 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; + +/** + * Decorates table cells for layout + * + * @package dompdf + */ +class TableCell extends BlockFrameDecorator +{ + + protected $_resolved_borders; + protected $_content_height; + + //........................................................................ + + /** + * TableCell constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + $this->_resolved_borders = []; + $this->_content_height = 0; + } + + //........................................................................ + + function reset() + { + parent::reset(); + $this->_resolved_borders = []; + $this->_content_height = 0; + $this->_frame->reset(); + } + + /** + * @return int + */ + function get_content_height() + { + return $this->_content_height; + } + + /** + * @param $height + */ + function set_content_height($height) + { + $this->_content_height = $height; + } + + /** + * @param $height + */ + function set_cell_height($height) + { + $style = $this->get_style(); + $v_space = (float)$style->length_in_pt( + [ + $style->margin_top, + $style->padding_top, + $style->border_top_width, + $style->border_bottom_width, + $style->padding_bottom, + $style->margin_bottom + ], + (float)$style->length_in_pt($style->height) + ); + + $new_height = $height - $v_space; + $style->height = $new_height; + + if ($new_height > $this->_content_height) { + $y_offset = 0; + + // Adjust our vertical alignment + switch ($style->vertical_align) { + default: + case "baseline": + // FIXME: this isn't right + + case "top": + // Don't need to do anything + return; + + case "middle": + $y_offset = ($new_height - $this->_content_height) / 2; + break; + + case "bottom": + $y_offset = $new_height - $this->_content_height; + break; + } + + if ($y_offset) { + // Move our children + foreach ($this->get_line_boxes() as $line) { + foreach ($line->get_frames() as $frame) { + $frame->move(0, $y_offset); + } + } + } + } + } + + /** + * @param $side + * @param $border_spec + */ + function set_resolved_border($side, $border_spec) + { + $this->_resolved_borders[$side] = $border_spec; + } + + /** + * @param $side + * @return mixed + */ + function get_resolved_border($side) + { + return $this->_resolved_borders[$side]; + } + + /** + * @return array + */ + function get_resolved_borders() + { + return $this->_resolved_borders; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/TableRow.php b/vendor/dompdf/dompdf/src/FrameDecorator/TableRow.php new file mode 100644 index 0000000..2fbfeb4 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/TableRow.php @@ -0,0 +1,68 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\FrameDecorator\Table as TableFrameDecorator; + +/** + * Decorates Frames for table row layout + * + * @package dompdf + */ +class TableRow extends AbstractFrameDecorator +{ + /** + * TableRow constructor. + * @param Frame $frame + * @param Dompdf $dompdf + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + } + + //........................................................................ + + /** + * Remove all non table-cell frames from this row and move them after + * the table. + */ + function normalise() + { + // Find our table parent + $p = TableFrameDecorator::find_parent_table($this); + + $erroneous_frames = []; + foreach ($this->get_children() as $child) { + $display = $child->get_style()->display; + + if ($display !== "table-cell") { + $erroneous_frames[] = $child; + } + } + + // dump the extra nodes after the table. + foreach ($erroneous_frames as $frame) { + $p->move_after($frame); + } + } + + function split(Frame $child = null, $force_pagebreak = false) + { + $this->_already_pushed = true; + + if (is_null($child)) { + parent::split(); + return; + } + + parent::split($child, $force_pagebreak); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/TableRowGroup.php b/vendor/dompdf/dompdf/src/FrameDecorator/TableRowGroup.php new file mode 100644 index 0000000..aabbd4e --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/TableRowGroup.php @@ -0,0 +1,70 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; + +/** + * Table row group decorator + * + * Overrides split() method for tbody, thead & tfoot elements + * + * @package dompdf + */ +class TableRowGroup extends AbstractFrameDecorator +{ + + /** + * Class constructor + * + * @param Frame $frame Frame to decorate + * @param Dompdf $dompdf Current dompdf instance + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + parent::__construct($frame, $dompdf); + } + + /** + * Override split() to remove all child rows and this element from the cellmap + * + * @param Frame $child + * @param bool $force_pagebreak + * + * @return void + */ + function split(Frame $child = null, $force_pagebreak = false) + { + if (is_null($child)) { + parent::split(); + return; + } + + // Remove child & all subsequent rows from the cellmap + $cellmap = $this->get_parent()->get_cellmap(); + $iter = $child; + + while ($iter) { + $cellmap->remove_row($iter); + $iter = $iter->get_next_sibling(); + } + + // If we are splitting at the first child remove the + // table-row-group from the cellmap as well + if ($child === $this->get_first_child()) { + $cellmap->remove_row_group($this); + parent::split(); + return; + } + + $cellmap->update_row_group($this, $child->get_prev_sibling()); + parent::split($child); + } +} + diff --git a/vendor/dompdf/dompdf/src/FrameDecorator/Text.php b/vendor/dompdf/dompdf/src/FrameDecorator/Text.php new file mode 100644 index 0000000..92eafc2 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameDecorator/Text.php @@ -0,0 +1,203 @@ + + * @author Brian Sweeney + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameDecorator; + +use Dompdf\Dompdf; +use Dompdf\Frame; +use Dompdf\Exception; + +/** + * Decorates Frame objects for text layout + * + * @access private + * @package dompdf + */ +class Text extends AbstractFrameDecorator +{ + + // protected members + protected $_text_spacing; + + /** + * Text constructor. + * @param Frame $frame + * @param Dompdf $dompdf + * @throws Exception + */ + function __construct(Frame $frame, Dompdf $dompdf) + { + if (!$frame->is_text_node()) { + throw new Exception("Text_Decorator can only be applied to #text nodes."); + } + + parent::__construct($frame, $dompdf); + $this->_text_spacing = null; + } + + function reset() + { + parent::reset(); + $this->_text_spacing = null; + } + + // Accessor methods + + /** + * @return null + */ + function get_text_spacing() + { + return $this->_text_spacing; + } + + /** + * @return string + */ + function get_text() + { + // FIXME: this should be in a child class (and is incorrect) +// if ( $this->_frame->get_style()->content !== "normal" ) { +// $this->_frame->get_node()->data = $this->_frame->get_style()->content; +// $this->_frame->get_style()->content = "normal"; +// } + +// Helpers::pre_r("---"); +// $style = $this->_frame->get_style(); +// var_dump($text = $this->_frame->get_node()->data); +// var_dump($asc = utf8_decode($text)); +// for ($i = 0; $i < strlen($asc); $i++) +// Helpers::pre_r("$i: " . $asc[$i] . " - " . ord($asc[$i])); +// Helpers::pre_r("width: " . $this->_dompdf->getFontMetrics()->getTextWidth($text, $style->font_family, $style->font_size)); + + return $this->_frame->get_node()->data; + } + + //........................................................................ + + /** + * Vertical margins & padding do not apply to text frames + * + * http://www.w3.org/TR/CSS21/visudet.html#inline-non-replaced: + * + * The vertical padding, border and margin of an inline, non-replaced box + * start at the top and bottom of the content area, not the + * 'line-height'. But only the 'line-height' is used to calculate the + * height of the line box. + * + * @return float|int + */ + function get_margin_height() + { + // This function is called in add_frame_to_line() and is used to + // determine the line height, so we actually want to return the + // 'line-height' property, not the actual margin box + $style = $this->get_style(); + $font = $style->font_family; + $size = $style->font_size; + + /* + Helpers::pre_r('-----'); + Helpers::pre_r($style->line_height); + Helpers::pre_r($style->font_size); + Helpers::pre_r($this->_dompdf->getFontMetrics()->getFontHeight($font, $size)); + Helpers::pre_r(($style->line_height / $size) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size)); + */ + + return ($style->line_height / ($size > 0 ? $size : 1)) * $this->_dompdf->getFontMetrics()->getFontHeight($font, $size); + } + + /** + * @return array + */ + function get_padding_box() + { + $style = $this->_frame->get_style(); + $pb = $this->_frame->get_padding_box(); + $pb[3] = $pb["h"] = $style->length_in_pt($style->height); + return $pb; + } + + /** + * @param $spacing + */ + function set_text_spacing($spacing) + { + $style = $this->_frame->get_style(); + + $this->_text_spacing = $spacing; + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + + // Re-adjust our width to account for the change in spacing + $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($this->get_text(), $style->font_family, $style->font_size, $spacing, $char_spacing); + } + + /** + * Recalculate the text width + * + * @return float + */ + function recalculate_width() + { + $style = $this->get_style(); + $text = $this->get_text(); + $size = $style->font_size; + $font = $style->font_family; + $word_spacing = (float)$style->length_in_pt($style->word_spacing); + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + + return $style->width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); + } + + // Text manipulation methods + + /** + * split the text in this frame at the offset specified. The remaining + * text is added a sibling frame following this one and is returned. + * + * @param $offset + * @return Frame|null + */ + function split_text($offset) + { + if ($offset == 0) { + return null; + } + + $split = $this->_frame->get_node()->splitText($offset); + + $deco = $this->copy($split); + + $p = $this->get_parent(); + $p->insert_child_after($deco, $this, false); + + if ($p instanceof Inline) { + $p->split($deco); + } + + return $deco; + } + + /** + * @param $offset + * @param $count + */ + function delete_text($offset, $count) + { + $this->_frame->get_node()->deleteData($offset, $count); + } + + /** + * @param $text + */ + function set_text($text) + { + $this->_frame->get_node()->data = $text; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/AbstractFrameReflower.php b/vendor/dompdf/dompdf/src/FrameReflower/AbstractFrameReflower.php new file mode 100644 index 0000000..46d0114 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/AbstractFrameReflower.php @@ -0,0 +1,529 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\Adapter\CPDF; +use Dompdf\Css\Style; +use Dompdf\Dompdf; +use Dompdf\Helpers; +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block; +use Dompdf\Frame\Factory; + +/** + * Base reflower class + * + * Reflower objects are responsible for determining the width and height of + * individual frames. They also create line and page breaks as necessary. + * + * @package dompdf + */ +abstract class AbstractFrameReflower +{ + + /** + * Frame for this reflower + * + * @var Frame + */ + protected $_frame; + + /** + * Cached min/max size + * + * @var array + */ + protected $_min_max_cache; + + /** + * AbstractFrameReflower constructor. + * @param Frame $frame + */ + function __construct(Frame $frame) + { + $this->_frame = $frame; + $this->_min_max_cache = null; + } + + function dispose() + { + } + + /** + * @return Dompdf + */ + function get_dompdf() + { + return $this->_frame->get_dompdf(); + } + + /** + * Collapse frames margins + * http://www.w3.org/TR/CSS2/box.html#collapsing-margins + */ + protected function _collapse_margins() + { + $frame = $this->_frame; + $cb = $frame->get_containing_block(); + $style = $frame->get_style(); + + // Margins of float/absolutely positioned/inline-block elements do not collapse. + if (!$frame->is_in_flow() || $frame->is_inline_block() || $frame->get_root() == $frame || $frame->get_parent() == $frame->get_root()) { + return; + } + + $t = $style->length_in_pt($style->margin_top, $cb["h"]); + $b = $style->length_in_pt($style->margin_bottom, $cb["h"]); + + // Handle 'auto' values + if ($t === "auto") { + $style->margin_top = "0pt"; + $t = 0; + } + + if ($b === "auto") { + $style->margin_bottom = "0pt"; + $b = 0; + } + + // Collapse vertical margins: + $n = $frame->get_next_sibling(); + if ( $n && !$n->is_block() & !$n->is_table() ) { + while ($n = $n->get_next_sibling()) { + if ($n->is_block() || $n->is_table()) { + break; + } + + if (!$n->get_first_child()) { + $n = null; + break; + } + } + } + + if ($n) { + $n_style = $n->get_style(); + $n_t = (float)$n_style->length_in_pt($n_style->margin_top, $cb["h"]); + + $b = $this->_get_collapsed_margin_length($b, $n_t); + $style->margin_bottom = $b . "pt"; + $n_style->margin_top = "0pt"; + } + + // Collapse our first child's margin, if there is no border or padding + if ($style->border_top_width == 0 && $style->length_in_pt($style->padding_top) == 0) { + $f = $this->_frame->get_first_child(); + if ( $f && !$f->is_block() && !$f->is_table() ) { + while ( $f = $f->get_next_sibling() ) { + if ( $f->is_block() || $f->is_table() ) { + break; + } + + if ( !$f->get_first_child() ) { + $f = null; + break; + } + } + } + + // Margin are collapsed only between block-level boxes + if ($f) { + $f_style = $f->get_style(); + $f_t = (float)$f_style->length_in_pt($f_style->margin_top, $cb["h"]); + + $t = $this->_get_collapsed_margin_length($t, $f_t); + $style->margin_top = $t."pt"; + $f_style->margin_top = "0pt"; + } + } + + // Collapse our last child's margin, if there is no border or padding + if ($style->border_bottom_width == 0 && $style->length_in_pt($style->padding_bottom) == 0) { + $l = $this->_frame->get_last_child(); + if ( $l && !$l->is_block() && !$l->is_table() ) { + while ( $l = $l->get_prev_sibling() ) { + if ( $l->is_block() || $l->is_table() ) { + break; + } + + if ( !$l->get_last_child() ) { + $l = null; + break; + } + } + } + + // Margin are collapsed only between block-level boxes + if ($l) { + $l_style = $l->get_style(); + $l_b = (float)$l_style->length_in_pt($l_style->margin_bottom, $cb["h"]); + + $b = $this->_get_collapsed_margin_length($b, $l_b); + $style->margin_bottom = $b."pt"; + $l_style->margin_bottom = "0pt"; + } + } + } + + /** + * Get the combined (collapsed) length of two adjoining margins. + * + * See http://www.w3.org/TR/CSS2/box.html#collapsing-margins. + * + * @param number $length1 + * @param number $length2 + * @return number + */ + private function _get_collapsed_margin_length($length1, $length2) + { + if ($length1 < 0 && $length2 < 0) { + return min($length1, $length2); // min(x, y) = - max(abs(x), abs(y)), if x < 0 && y < 0 + } + + if ($length1 < 0 || $length2 < 0) { + return $length1 + $length2; // x + y = x - abs(y), if y < 0 + } + + return max($length1, $length2); + } + + /** + * @param Block|null $block + * @return mixed + */ + abstract function reflow(Block $block = null); + + /** + * Required for table layout: Returns an array(0 => min, 1 => max, "min" + * => min, "max" => max) of the minimum and maximum widths of this frame. + * This provides a basic implementation. Child classes should override + * this if necessary. + * + * @return array|null + */ + function get_min_max_width() + { + if (!is_null($this->_min_max_cache)) { + return $this->_min_max_cache; + } + + $style = $this->_frame->get_style(); + + // Account for margins & padding + $dims = [$style->padding_left, + $style->padding_right, + $style->border_left_width, + $style->border_right_width, + $style->margin_left, + $style->margin_right]; + + $cb_w = $this->_frame->get_containing_block("w"); + $delta = (float)$style->length_in_pt($dims, $cb_w); + + // Handle degenerate case + if (!$this->_frame->get_first_child()) { + return $this->_min_max_cache = [ + $delta, $delta, + "min" => $delta, + "max" => $delta, + ]; + } + + $low = []; + $high = []; + + for ($iter = $this->_frame->get_children()->getIterator(); $iter->valid(); $iter->next()) { + $inline_min = 0; + $inline_max = 0; + + // Add all adjacent inline widths together to calculate max width + while ($iter->valid() && in_array($iter->current()->get_style()->display, Style::$INLINE_TYPES)) { + $child = $iter->current(); + + $minmax = $child->get_min_max_width(); + + if (in_array($iter->current()->get_style()->white_space, ["pre", "nowrap"])) { + $inline_min += $minmax["min"]; + } else { + $low[] = $minmax["min"]; + } + + $inline_max += $minmax["max"]; + $iter->next(); + } + + if ($inline_max > 0) { + $high[] = $inline_max; + } + if ($inline_min > 0) { + $low[] = $inline_min; + } + + if ($iter->valid()) { + list($low[], $high[]) = $iter->current()->get_min_max_width(); + continue; + } + } + $min = count($low) ? max($low) : 0; + $max = count($high) ? max($high) : 0; + + // Use specified width if it is greater than the minimum defined by the + // content. If the width is a percentage ignore it for now. + $width = $style->width; + if ($width !== "auto" && !Helpers::is_percent($width)) { + $width = (float)$style->length_in_pt($width, $cb_w); + if ($min < $width) { + $min = $width; + } + if ($max < $width) { + $max = $width; + } + } + + $min += $delta; + $max += $delta; + return $this->_min_max_cache = [$min, $max, "min" => $min, "max" => $max]; + } + + /** + * Parses a CSS string containing quotes and escaped hex characters + * + * @param $string string The CSS string to parse + * @param $single_trim + * @return string + */ + protected function _parse_string($string, $single_trim = false) + { + if ($single_trim) { + $string = preg_replace('/^[\"\']/', "", $string); + $string = preg_replace('/[\"\']$/', "", $string); + } else { + $string = trim($string, "'\""); + } + + $string = str_replace(["\\\n", '\\"', "\\'"], + ["", '"', "'"], $string); + + // Convert escaped hex characters into ascii characters (e.g. \A => newline) + $string = preg_replace_callback("/\\\\([0-9a-fA-F]{0,6})/", + function ($matches) { return \Dompdf\Helpers::unichr(hexdec($matches[1])); }, + $string); + return $string; + } + + /** + * Parses a CSS "quotes" property + * + * @return array|null An array of pairs of quotes + */ + protected function _parse_quotes() + { + // Matches quote types + $re = '/(\'[^\']*\')|(\"[^\"]*\")/'; + + $quotes = $this->_frame->get_style()->quotes; + + // split on spaces, except within quotes + if (!preg_match_all($re, "$quotes", $matches, PREG_SET_ORDER)) { + return null; + } + + $quotes_array = []; + foreach ($matches as $_quote) { + $quotes_array[] = $this->_parse_string($_quote[0], true); + } + + if (empty($quotes_array)) { + $quotes_array = ['"', '"']; + } + + return array_chunk($quotes_array, 2); + } + + /** + * Parses the CSS "content" property + * + * @return string|null The resulting string + */ + protected function _parse_content() + { + // Matches generated content + $re = "/\n" . + "\s(counters?\\([^)]*\\))|\n" . + "\A(counters?\\([^)]*\\))|\n" . + "\s([\"']) ( (?:[^\"']|\\\\[\"'])+ )(?_frame->get_style()->content; + + $quotes = $this->_parse_quotes(); + + // split on spaces, except within quotes + if (!preg_match_all($re, $content, $matches, PREG_SET_ORDER)) { + return null; + } + + $text = ""; + + foreach ($matches as $match) { + if (isset($match[2]) && $match[2] !== "") { + $match[1] = $match[2]; + } + + if (isset($match[6]) && $match[6] !== "") { + $match[4] = $match[6]; + } + + if (isset($match[8]) && $match[8] !== "") { + $match[7] = $match[8]; + } + + if (isset($match[1]) && $match[1] !== "") { + // counters?(...) + $match[1] = mb_strtolower(trim($match[1])); + + // Handle counter() references: + // http://www.w3.org/TR/CSS21/generate.html#content + + $i = mb_strpos($match[1], ")"); + if ($i === false) { + continue; + } + + preg_match('/(counters?)(^\()*?\(\s*([^\s,]+)\s*(,\s*["\']?([^"\'\)]*)["\']?\s*(,\s*([^\s)]+)\s*)?)?\)/i', $match[1], $args); + $counter_id = $args[3]; + if (strtolower($args[1]) == 'counter') { + // counter(name [,style]) + if (isset($args[5])) { + $type = trim($args[5]); + } else { + $type = null; + } + $p = $this->_frame->lookup_counter_frame($counter_id); + + $text .= $p->counter_value($counter_id, $type); + + } else if (strtolower($args[1]) == 'counters') { + // counters(name, string [,style]) + if (isset($args[5])) { + $string = $this->_parse_string($args[5]); + } else { + $string = ""; + } + + if (isset($args[7])) { + $type = trim($args[7]); + } else { + $type = null; + } + + $p = $this->_frame->lookup_counter_frame($counter_id); + $tmp = []; + while ($p) { + // We only want to use the counter values when they actually increment the counter + if (array_key_exists($counter_id, $p->_counters)) { + array_unshift($tmp, $p->counter_value($counter_id, $type)); + } + $p = $p->lookup_counter_frame($counter_id); + } + $text .= implode($string, $tmp); + } else { + // countertops? + continue; + } + + } else if (isset($match[4]) && $match[4] !== "") { + // String match + $text .= $this->_parse_string($match[4]); + } else if (isset($match[7]) && $match[7] !== "") { + // Directive match + + if ($match[7] === "open-quote") { + // FIXME: do something here + $text .= $quotes[0][0]; + } else if ($match[7] === "close-quote") { + // FIXME: do something else here + $text .= $quotes[0][1]; + } else if ($match[7] === "no-open-quote") { + // FIXME: + } else if ($match[7] === "no-close-quote") { + // FIXME: + } else if (mb_strpos($match[7], "attr(") === 0) { + $i = mb_strpos($match[7], ")"); + if ($i === false) { + continue; + } + + $attr = mb_substr($match[7], 5, $i - 5); + if ($attr == "") { + continue; + } + + $text .= $this->_frame->get_parent()->get_node()->getAttribute($attr); + } else { + continue; + } + } + } + + return $text; + } + + /** + * Sets the generated content of a generated frame + */ + protected function _set_content() + { + $frame = $this->_frame; + $style = $frame->get_style(); + + // if the element was pushed to a new page use the saved counter value, otherwise use the CSS reset value + if ($style->counter_reset && ($reset = $style->counter_reset) !== "none") { + $vars = preg_split('/\s+/', trim($reset), 2); + $frame->reset_counter($vars[0], (isset($frame->_counters['__' . $vars[0]]) ? $frame->_counters['__' . $vars[0]] : (isset($vars[1]) ? $vars[1] : 0))); + } + + if ($style->counter_increment && ($increment = $style->counter_increment) !== "none") { + $frame->increment_counters($increment); + } + + if ($style->content && $frame->get_node()->nodeName === "dompdf_generated") { + $content = $this->_parse_content(); + // add generated content to the font subset + // FIXME: This is currently too late because the font subset has already been generated. + // See notes in issue #750. + if ($frame->get_dompdf()->getOptions()->getIsFontSubsettingEnabled() && $frame->get_dompdf()->get_canvas() instanceof CPDF) { + $frame->get_dompdf()->get_canvas()->register_string_subset($style->font_family, $content); + } + + $node = $frame->get_node()->ownerDocument->createTextNode($content); + + $new_style = $style->get_stylesheet()->create_style(); + $new_style->inherit($style); + + $new_frame = new Frame($node); + $new_frame->set_style($new_style); + + Factory::decorate_frame($new_frame, $frame->get_dompdf(), $frame->get_root()); + $frame->append_child($new_frame); + } + } + + /** + * Determine current frame width based on contents + * + * @return float + */ + public function calculate_auto_width() + { + return $this->_frame->get_margin_width(); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Block.php b/vendor/dompdf/dompdf/src/FrameReflower/Block.php new file mode 100644 index 0000000..8dc628a --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Block.php @@ -0,0 +1,948 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\TableCell as TableCellFrameDecorator; +use Dompdf\FrameDecorator\Text as TextFrameDecorator; +use Dompdf\Exception; +use Dompdf\Css\Style; + +/** + * Reflows block frames + * + * @package dompdf + */ +class Block extends AbstractFrameReflower +{ + // Minimum line width to justify, as fraction of available width + const MIN_JUSTIFY_WIDTH = 0.80; + + /** + * @var BlockFrameDecorator + */ + protected $_frame; + + function __construct(BlockFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * Calculate the ideal used value for the width property as per: + * http://www.w3.org/TR/CSS21/visudet.html#Computing_widths_and_margins + * + * @param float $width + * + * @return array + */ + protected function _calculate_width($width) + { + $frame = $this->_frame; + $style = $frame->get_style(); + $w = $frame->get_containing_block("w"); + + if ($style->position === "fixed") { + $w = $frame->get_parent()->get_containing_block("w"); + } + + $rm = $style->length_in_pt($style->margin_right, $w); + $lm = $style->length_in_pt($style->margin_left, $w); + + $left = $style->length_in_pt($style->left, $w); + $right = $style->length_in_pt($style->right, $w); + + // Handle 'auto' values + $dims = [$style->border_left_width, + $style->border_right_width, + $style->padding_left, + $style->padding_right, + $width !== "auto" ? $width : 0, + $rm !== "auto" ? $rm : 0, + $lm !== "auto" ? $lm : 0]; + + // absolutely positioned boxes take the 'left' and 'right' properties into account + if ($frame->is_absolute()) { + $absolute = true; + $dims[] = $left !== "auto" ? $left : 0; + $dims[] = $right !== "auto" ? $right : 0; + } else { + $absolute = false; + } + + $sum = (float)$style->length_in_pt($dims, $w); + + // Compare to the containing block + $diff = $w - $sum; + + if ($diff > 0) { + if ($absolute) { + // resolve auto properties: see + // http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-width + + if ($width === "auto" && $left === "auto" && $right === "auto") { + if ($lm === "auto") { + $lm = 0; + } + if ($rm === "auto") { + $rm = 0; + } + + // Technically, the width should be "shrink-to-fit" i.e. based on the + // preferred width of the content... a little too costly here as a + // special case. Just get the width to take up the slack: + $left = 0; + $right = 0; + $width = $diff; + } else if ($width === "auto") { + if ($lm === "auto") { + $lm = 0; + } + if ($rm === "auto") { + $rm = 0; + } + if ($left === "auto") { + $left = 0; + } + if ($right === "auto") { + $right = 0; + } + + $width = $diff; + } else if ($left === "auto") { + if ($lm === "auto") { + $lm = 0; + } + if ($rm === "auto") { + $rm = 0; + } + if ($right === "auto") { + $right = 0; + } + + $left = $diff; + } else if ($right === "auto") { + if ($lm === "auto") { + $lm = 0; + } + if ($rm === "auto") { + $rm = 0; + } + + $right = $diff; + } + + } else { + // Find auto properties and get them to take up the slack + if ($width === "auto") { + $width = $diff; + } else if ($lm === "auto" && $rm === "auto") { + $lm = $rm = round($diff / 2); + } else if ($lm === "auto") { + $lm = $diff; + } else if ($rm === "auto") { + $rm = $diff; + } + } + } else if ($diff < 0) { + // We are over constrained--set margin-right to the difference + $rm = $diff; + } + + return [ + "width" => $width, + "margin_left" => $lm, + "margin_right" => $rm, + "left" => $left, + "right" => $right, + ]; + } + + /** + * Call the above function, but resolve max/min widths + * + * @throws Exception + * @return array + */ + protected function _calculate_restricted_width() + { + $frame = $this->_frame; + $style = $frame->get_style(); + $cb = $frame->get_containing_block(); + + if ($style->position === "fixed") { + $cb = $frame->get_root()->get_containing_block(); + } + + //if ( $style->position === "absolute" ) + // $cb = $frame->find_positionned_parent()->get_containing_block(); + + if (!isset($cb["w"])) { + throw new Exception("Box property calculation requires containing block width"); + } + + // Treat width 100% as auto + if ($style->width === "100%") { + $width = "auto"; + } else { + $width = $style->length_in_pt($style->width, $cb["w"]); + } + + $calculate_width = $this->_calculate_width($width); + $margin_left = $calculate_width['margin_left']; + $margin_right = $calculate_width['margin_right']; + $width = $calculate_width['width']; + $left = $calculate_width['left']; + $right = $calculate_width['right']; + + // Handle min/max width + $min_width = $style->length_in_pt($style->min_width, $cb["w"]); + $max_width = $style->length_in_pt($style->max_width, $cb["w"]); + + if ($max_width !== "none" && $min_width > $max_width) { + list($max_width, $min_width) = [$min_width, $max_width]; + } + + if ($max_width !== "none" && $width > $max_width) { + extract($this->_calculate_width($max_width)); + } + + if ($width < $min_width) { + $calculate_width = $this->_calculate_width($min_width); + $margin_left = $calculate_width['margin_left']; + $margin_right = $calculate_width['margin_right']; + $width = $calculate_width['width']; + $left = $calculate_width['left']; + $right = $calculate_width['right']; + } + + return [$width, $margin_left, $margin_right, $left, $right]; + } + + /** + * Determine the unrestricted height of content within the block + * not by adding each line's height, but by getting the last line's position. + * This because lines could have been pushed lower by a clearing element. + * + * @return float + */ + protected function _calculate_content_height() + { + $height = 0; + $lines = $this->_frame->get_line_boxes(); + if (count($lines) > 0) { + $last_line = end($lines); + $content_box = $this->_frame->get_content_box(); + $height = $last_line->y + $last_line->h - $content_box["y"]; + } + return $height; + } + + /** + * Determine the frame's restricted height + * + * @return array + */ + protected function _calculate_restricted_height() + { + $frame = $this->_frame; + $style = $frame->get_style(); + $content_height = $this->_calculate_content_height(); + $cb = $frame->get_containing_block(); + + $height = $style->length_in_pt($style->height, $cb["h"]); + + $top = $style->length_in_pt($style->top, $cb["h"]); + $bottom = $style->length_in_pt($style->bottom, $cb["h"]); + + $margin_top = $style->length_in_pt($style->margin_top, $cb["h"]); + $margin_bottom = $style->length_in_pt($style->margin_bottom, $cb["h"]); + + if ($frame->is_absolute()) { + + // see http://www.w3.org/TR/CSS21/visudet.html#abs-non-replaced-height + + $dims = [$top !== "auto" ? $top : 0, + $style->margin_top !== "auto" ? $style->margin_top : 0, + $style->padding_top, + $style->border_top_width, + $height !== "auto" ? $height : 0, + $style->border_bottom_width, + $style->padding_bottom, + $style->margin_bottom !== "auto" ? $style->margin_bottom : 0, + $bottom !== "auto" ? $bottom : 0]; + + $sum = (float)$style->length_in_pt($dims, $cb["h"]); + + $diff = $cb["h"] - $sum; + + if ($diff > 0) { + if ($height === "auto" && $top === "auto" && $bottom === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $height = $diff; + } else if ($height === "auto" && $top === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $height = $content_height; + $top = $diff - $content_height; + } else if ($height === "auto" && $bottom === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $height = $content_height; + $bottom = $diff - $content_height; + } else if ($top === "auto" && $bottom === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $bottom = $diff; + } else if ($top === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $top = $diff; + } else if ($height === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $height = $diff; + } else if ($bottom === "auto") { + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + + $bottom = $diff; + } else { + if ($style->overflow === "visible") { + // set all autos to zero + if ($margin_top === "auto") { + $margin_top = 0; + } + if ($margin_bottom === "auto") { + $margin_bottom = 0; + } + if ($top === "auto") { + $top = 0; + } + if ($bottom === "auto") { + $bottom = 0; + } + if ($height === "auto") { + $height = $content_height; + } + } + + // FIXME: overflow hidden + } + } + + } else { + // Expand the height if overflow is visible + if ($height === "auto" && $content_height > $height /* && $style->overflow === "visible" */) { + $height = $content_height; + } + + // FIXME: this should probably be moved to a seperate function as per + // _calculate_restricted_width + + // Only handle min/max height if the height is independent of the frame's content + if (!($style->overflow === "visible" || ($style->overflow === "hidden" && $height === "auto"))) { + $min_height = $style->min_height; + $max_height = $style->max_height; + + if (isset($cb["h"])) { + $min_height = $style->length_in_pt($min_height, $cb["h"]); + $max_height = $style->length_in_pt($max_height, $cb["h"]); + } else if (isset($cb["w"])) { + if (mb_strpos($min_height, "%") !== false) { + $min_height = 0; + } else { + $min_height = $style->length_in_pt($min_height, $cb["w"]); + } + + if (mb_strpos($max_height, "%") !== false) { + $max_height = "none"; + } else { + $max_height = $style->length_in_pt($max_height, $cb["w"]); + } + } + + if ($max_height !== "none" && $min_height > $max_height) { + // Swap 'em + list($max_height, $min_height) = [$min_height, $max_height]; + } + + if ($max_height !== "none" && $height > $max_height) { + $height = $max_height; + } + + if ($height < $min_height) { + $height = $min_height; + } + } + } + + return [$height, $margin_top, $margin_bottom, $top, $bottom]; + } + + /** + * Adjust the justification of each of our lines. + * http://www.w3.org/TR/CSS21/text.html#propdef-text-align + */ + protected function _text_align() + { + $style = $this->_frame->get_style(); + $w = $this->_frame->get_containing_block("w"); + $width = (float)$style->length_in_pt($style->width, $w); + + switch ($style->text_align) { + default: + case "left": + foreach ($this->_frame->get_line_boxes() as $line) { + if (!$line->left) { + continue; + } + + foreach ($line->get_frames() as $frame) { + if ($frame instanceof BlockFrameDecorator) { + continue; + } + $frame->set_position($frame->get_position("x") + $line->left); + } + } + return; + + case "right": + foreach ($this->_frame->get_line_boxes() as $line) { + // Move each child over by $dx + $dx = $width - $line->w - $line->right; + + foreach ($line->get_frames() as $frame) { + // Block frames are not aligned by text-align + if ($frame instanceof BlockFrameDecorator) { + continue; + } + + $frame->set_position($frame->get_position("x") + $dx); + } + } + break; + + case "justify": + // We justify all lines except the last one + $lines = $this->_frame->get_line_boxes(); // needs to be a variable (strict standards) + $last_line = array_pop($lines); + + foreach ($lines as $i => $line) { + if ($line->br) { + unset($lines[$i]); + } + } + + // One space character's width. Will be used to get a more accurate spacing + $space_width = $this->get_dompdf()->getFontMetrics()->getTextWidth(" ", $style->font_family, $style->font_size); + + foreach ($lines as $line) { + if ($line->left) { + foreach ($line->get_frames() as $frame) { + if (!$frame instanceof TextFrameDecorator) { + continue; + } + + $frame->set_position($frame->get_position("x") + $line->left); + } + } + + // Set the spacing for each child + if ($line->wc > 1) { + $spacing = ($width - ($line->left + $line->w + $line->right)) / ($line->wc - 1); + } else { + $spacing = 0; + } + + $dx = 0; + foreach ($line->get_frames() as $frame) { + if (!$frame instanceof TextFrameDecorator) { + continue; + } + + $text = $frame->get_text(); + $spaces = mb_substr_count($text, " "); + + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + $_spacing = $spacing + $char_spacing; + + $frame->set_position($frame->get_position("x") + $dx); + $frame->set_text_spacing($_spacing); + + $dx += $spaces * $_spacing; + } + + // The line (should) now occupy the entire width + $line->w = $width; + } + + // Adjust the last line if necessary + if ($last_line->left) { + foreach ($last_line->get_frames() as $frame) { + if ($frame instanceof BlockFrameDecorator) { + continue; + } + $frame->set_position($frame->get_position("x") + $last_line->left); + } + } + break; + + case "center": + case "centre": + foreach ($this->_frame->get_line_boxes() as $line) { + // Centre each line by moving each frame in the line by: + $dx = ($width + $line->left - $line->w - $line->right) / 2; + + foreach ($line->get_frames() as $frame) { + // Block frames are not aligned by text-align + if ($frame instanceof BlockFrameDecorator) { + continue; + } + + $frame->set_position($frame->get_position("x") + $dx); + } + } + break; + } + } + + /** + * Align inline children vertically. + * Aligns each child vertically after each line is reflowed + */ + function vertical_align() + { + $canvas = null; + + foreach ($this->_frame->get_line_boxes() as $line) { + + $height = $line->h; + + foreach ($line->get_frames() as $frame) { + $style = $frame->get_style(); + $isInlineBlock = ( + '-dompdf-image' === $style->display + || 'inline-block' === $style->display + || 'inline-table' === $style->display + ); + if (!$isInlineBlock && $style->display !== "inline") { + continue; + } + + if (!isset($canvas)) { + $canvas = $frame->get_root()->get_dompdf()->get_canvas(); + } + + $baseline = $canvas->get_font_baseline($style->font_family, $style->font_size); + $y_offset = 0; + + //FIXME: The 0.8 ratio applied to the height is arbitrary (used to accommodate descenders?) + if($isInlineBlock) { + $lineFrames = $line->get_frames(); + if (count($lineFrames) == 1) { + continue; + } + $frameBox = $frame->get_frame()->get_border_box(); + $imageHeightDiff = $height * 0.8 - (float)$frameBox['h']; + + $align = $frame->get_style()->vertical_align; + if (in_array($align, Style::$vertical_align_keywords) === true) { + switch ($align) { + case "middle": + $y_offset = $imageHeightDiff / 2; + break; + + case "sub": + $y_offset = 0.3 * $height + $imageHeightDiff; + break; + + case "super": + $y_offset = -0.2 * $height + $imageHeightDiff; + break; + + case "text-top": // FIXME: this should be the height of the frame minus the height of the text + $y_offset = $height - $style->line_height; + break; + + case "top": + break; + + case "text-bottom": // FIXME: align bottom of image with the descender? + case "bottom": + $y_offset = 0.3 * $height + $imageHeightDiff; + break; + + case "baseline": + default: + $y_offset = $imageHeightDiff; + break; + } + } else { + $y_offset = $baseline - (float)$style->length_in_pt($align, $style->font_size) - (float)$frameBox['h']; + } + } else { + $parent = $frame->get_parent(); + if ($parent instanceof TableCellFrameDecorator) { + $align = "baseline"; + } else { + $align = $parent->get_style()->vertical_align; + } + if (in_array($align, Style::$vertical_align_keywords) === true) { + switch ($align) { + case "middle": + $y_offset = ($height * 0.8 - $baseline) / 2; + break; + + case "sub": + $y_offset = $height * 0.8 - $baseline * 0.5; + break; + + case "super": + $y_offset = $height * 0.8 - $baseline * 1.4; + break; + + case "text-top": + case "top": // Not strictly accurate, but good enough for now + break; + + case "text-bottom": + case "bottom": + $y_offset = $height * 0.8 - $baseline; + break; + + case "baseline": + default: + $y_offset = $height * 0.8 - $baseline; + break; + } + } else { + $y_offset = $height * 0.8 - $baseline - (float)$style->length_in_pt($align, $style->font_size); + } + } + + if ($y_offset !== 0) { + $frame->move(0, $y_offset); + } + } + } + } + + /** + * @param Frame $child + */ + function process_clear(Frame $child) + { + $child_style = $child->get_style(); + $root = $this->_frame->get_root(); + + // Handle "clear" + if ($child_style->clear !== "none") { + //TODO: this is a WIP for handling clear/float frames that are in between inline frames + if ($child->get_prev_sibling() !== null) { + $this->_frame->add_line(); + } + if ($child_style->float !== "none" && $child->get_next_sibling()) { + $this->_frame->set_current_line_number($this->_frame->get_current_line_number() - 1); + } + + $lowest_y = $root->get_lowest_float_offset($child); + + // If a float is still applying, we handle it + if ($lowest_y) { + if ($child->is_in_flow()) { + $line_box = $this->_frame->get_current_line_box(); + $line_box->y = $lowest_y + $child->get_margin_height(); + $line_box->left = 0; + $line_box->right = 0; + } + + $child->move(0, $lowest_y - $child->get_position("y")); + } + } + } + + /** + * @param Frame $child + * @param float $cb_x + * @param float $cb_w + */ + function process_float(Frame $child, $cb_x, $cb_w) + { + $child_style = $child->get_style(); + $root = $this->_frame->get_root(); + + // Handle "float" + if ($child_style->float !== "none") { + $root->add_floating_frame($child); + + // Remove next frame's beginning whitespace + $next = $child->get_next_sibling(); + if ($next && $next instanceof TextFrameDecorator) { + $next->set_text(ltrim($next->get_text())); + } + + $line_box = $this->_frame->get_current_line_box(); + list($old_x, $old_y) = $child->get_position(); + + $float_x = $cb_x; + $float_y = $old_y; + $float_w = $child->get_margin_width(); + + if ($child_style->clear === "none") { + switch ($child_style->float) { + case "left": + $float_x += $line_box->left; + break; + case "right": + $float_x += ($cb_w - $line_box->right - $float_w); + break; + } + } else { + if ($child_style->float === "right") { + $float_x += ($cb_w - $float_w); + } + } + + if ($cb_w < $float_x + $float_w - $old_x) { + // TODO handle when floating elements don't fit + } + + $line_box->get_float_offsets(); + + if ($child->_float_next_line) { + $float_y += $line_box->h; + } + + $child->set_position($float_x, $float_y); + $child->move($float_x - $old_x, $float_y - $old_y, true); + } + } + + /** + * @param BlockFrameDecorator $block + * @return mixed|void + */ + function reflow(BlockFrameDecorator $block = null) + { + + // Check if a page break is forced + $page = $this->_frame->get_root(); + $page->check_forced_page_break($this->_frame); + + // Bail if the page is full + if ($page->is_full()) { + return; + } + + // Generated content + $this->_set_content(); + + // Collapse margins if required + $this->_collapse_margins(); + + $style = $this->_frame->get_style(); + $cb = $this->_frame->get_containing_block(); + + if ($style->position === "fixed") { + $cb = $this->_frame->get_root()->get_containing_block(); + } + + // Determine the constraints imposed by this frame: calculate the width + // of the content area: + list($w, $left_margin, $right_margin, $left, $right) = $this->_calculate_restricted_width(); + + // Store the calculated properties + $style->width = $w; + $style->margin_left = $left_margin; + $style->margin_right = $right_margin; + $style->left = $left; + $style->right = $right; + + // Update the position + $this->_frame->position(); + list($x, $y) = $this->_frame->get_position(); + + // Adjust the first line based on the text-indent property + $indent = (float)$style->length_in_pt($style->text_indent, $cb["w"]); + $this->_frame->increase_line_width($indent); + + // Determine the content edge + $top = (float)$style->length_in_pt([$style->margin_top, + $style->padding_top, + $style->border_top_width], $cb["h"]); + + $bottom = (float)$style->length_in_pt([$style->border_bottom_width, + $style->margin_bottom, + $style->padding_bottom], $cb["h"]); + + $cb_x = $x + (float)$left_margin + (float)$style->length_in_pt([$style->border_left_width, + $style->padding_left], $cb["w"]); + + $cb_y = $y + $top; + + $cb_h = ($cb["h"] + $cb["y"]) - $bottom - $cb_y; + + // Set the y position of the first line in this block + $line_box = $this->_frame->get_current_line_box(); + $line_box->y = $cb_y; + $line_box->get_float_offsets(); + + // Set the containing blocks and reflow each child + foreach ($this->_frame->get_children() as $child) { + + // Bail out if the page is full + if ($page->is_full()) { + break; + } + + $child->set_containing_block($cb_x, $cb_y, $w, $cb_h); + + $this->process_clear($child); + + $child->reflow($this->_frame); + + // Don't add the child to the line if a page break has occurred + if ($page->check_page_break($child)) { + break; + } + + $this->process_float($child, $cb_x, $w); + } + + // Determine our height + list($height, $margin_top, $margin_bottom, $top, $bottom) = $this->_calculate_restricted_height(); + $style->height = $height; + $style->margin_top = $margin_top; + $style->margin_bottom = $margin_bottom; + $style->top = $top; + $style->bottom = $bottom; + + $orig_style = $this->_frame->get_original_style(); + + $needs_reposition = ($style->position === "absolute" && ($style->right !== "auto" || $style->bottom !== "auto")); + + // Absolute positioning measurement + if ($needs_reposition) { + if ($orig_style->width === "auto" && ($orig_style->left === "auto" || $orig_style->right === "auto")) { + $width = 0; + foreach ($this->_frame->get_line_boxes() as $line) { + $width = max($line->w, $width); + } + $style->width = $width; + } + + $style->left = $orig_style->left; + $style->right = $orig_style->right; + } + + // Calculate inline-block / float auto-widths + if (($style->display === "inline-block" || $style->float !== 'none') && $orig_style->width === 'auto') { + $width = 0; + + foreach ($this->_frame->get_line_boxes() as $line) { + $line->recalculate_width(); + + $width = max($line->w, $width); + } + + if ($width === 0) { + foreach ($this->_frame->get_children() as $child) { + $width += $child->calculate_auto_width(); + } + } + + $style->width = $width; + } + + $this->_text_align(); + $this->vertical_align(); + + // Absolute positioning + if ($needs_reposition) { + list($x, $y) = $this->_frame->get_position(); + $this->_frame->position(); + list($new_x, $new_y) = $this->_frame->get_position(); + $this->_frame->move($new_x - $x, $new_y - $y, true); + } + + if ($block && $this->_frame->is_in_flow()) { + $block->add_frame_to_line($this->_frame); + + // May be inline-block + if ($style->display === "block") { + $block->add_line(); + } + } + } + + /** + * Determine current frame width based on contents + * + * @return float + */ + public function calculate_auto_width() + { + $width = 0; + + foreach ($this->_frame->get_line_boxes() as $line) { + $line_width = 0; + + foreach ($line->get_frames() as $frame) { + if ($frame->get_original_style()->width == 'auto') { + $line_width += $frame->calculate_auto_width(); + } else { + $line_width += $frame->get_margin_width(); + } + } + + $width = max($line_width, $width); + } + + $this->_frame->get_style()->width = $width; + + return $this->_frame->get_margin_width(); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Image.php b/vendor/dompdf/dompdf/src/FrameReflower/Image.php new file mode 100644 index 0000000..6619397 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Image.php @@ -0,0 +1,202 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\Frame; +use Dompdf\Helpers; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Image as ImageFrameDecorator; + +/** + * Image reflower class + * + * @package dompdf + */ +class Image extends AbstractFrameReflower +{ + + /** + * Image constructor. + * @param ImageFrameDecorator $frame + */ + function __construct(ImageFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $this->_frame->position(); + + //FLOAT + //$frame = $this->_frame; + //$page = $frame->get_root(); + + //if ($frame->get_style()->float !== "none" ) { + // $page->add_floating_frame($this); + //} + + // Set the frame's width + $this->get_min_max_width(); + + if ($block) { + $block->add_frame_to_line($this->_frame); + } + } + + /** + * @return array + */ + function get_min_max_width() + { + $frame = $this->_frame; + + if ($this->get_dompdf()->getOptions()->getDebugPng()) { + // Determine the image's size. Time consuming. Only when really needed? + list($img_width, $img_height) = Helpers::dompdf_getimagesize($frame->get_image_url(), $this->get_dompdf()->getHttpContext()); + print "get_min_max_width() " . + $frame->get_style()->width . ' ' . + $frame->get_style()->height . ';' . + $frame->get_parent()->get_style()->width . " " . + $frame->get_parent()->get_style()->height . ";" . + $frame->get_parent()->get_parent()->get_style()->width . ' ' . + $frame->get_parent()->get_parent()->get_style()->height . ';' . + $img_width . ' ' . + $img_height . '|'; + } + + $style = $frame->get_style(); + + $width_forced = true; + $height_forced = true; + + //own style auto or invalid value: use natural size in px + //own style value: ignore suffix text including unit, use given number as px + //own style %: walk up parent chain until found available space in pt; fill available space + // + //special ignored unit: e.g. 10ex: e treated as exponent; x ignored; 10e completely invalid ->like auto + + $width = $this->get_size($frame, 'width'); + $height = $this->get_size($frame, 'height'); + + if ($width === 'auto' || $height === 'auto') { + // Determine the image's size. Time consuming. Only when really needed! + list($img_width, $img_height) = Helpers::dompdf_getimagesize($frame->get_image_url(), $this->get_dompdf()->getHttpContext()); + + // don't treat 0 as error. Can be downscaled or can be catched elsewhere if image not readable. + // Resample according to px per inch + // See also ListBulletImage::__construct + if ($width === 'auto' && $height === 'auto') { + $dpi = $frame->get_dompdf()->getOptions()->getDpi(); + $width = (float)($img_width * 72) / $dpi; + $height = (float)($img_height * 72) / $dpi; + $width_forced = false; + $height_forced = false; + } elseif ($height === 'auto') { + $height_forced = false; + $height = ($width / $img_width) * $img_height; //keep aspect ratio + } else { + $width_forced = false; + $width = ($height / $img_height) * $img_width; //keep aspect ratio + } + } + + // Handle min/max width/height + if ($style->min_width !== "none" || + $style->max_width !== "none" || + $style->min_height !== "none" || + $style->max_height !== "none" + ) { + + list( /*$x*/, /*$y*/, $w, $h) = $frame->get_containing_block(); + + $min_width = $style->length_in_pt($style->min_width, $w); + $max_width = $style->length_in_pt($style->max_width, $w); + $min_height = $style->length_in_pt($style->min_height, $h); + $max_height = $style->length_in_pt($style->max_height, $h); + + if ($max_width !== "none" && $width > $max_width) { + if (!$height_forced) { + $height *= $max_width / $width; + } + + $width = $max_width; + } + + if ($min_width !== "none" && $width < $min_width) { + if (!$height_forced) { + $height *= $min_width / $width; + } + + $width = $min_width; + } + + if ($max_height !== "none" && $height > $max_height) { + if (!$width_forced) { + $width *= $max_height / $height; + } + + $height = $max_height; + } + + if ($min_height !== "none" && $height < $min_height) { + if (!$width_forced) { + $width *= $min_height / $height; + } + + $height = $min_height; + } + } + + if ($this->get_dompdf()->getOptions()->getDebugPng()) { + print $width . ' ' . $height . ';'; + } + + $style->width = $width . "pt"; + $style->height = $height . "pt"; + + $style->min_width = "none"; + $style->max_width = "none"; + $style->min_height = "none"; + $style->max_height = "none"; + + return [$width, $width, "min" => $width, "max" => $width]; + } + + private function get_size(Frame $f, string $type) + { + $ref_stack = []; + $result_size = 0.0; + do { + $f_style = $f->get_style(); + $current_size = $f_style->$type; + if (Helpers::is_percent($current_size)) { + $ref_stack[] = str_replace('%px', '%', $current_size); + } else { + // auto is a valid first result. In case of previous percentage values we need a real size + if ($current_size !== 'auto' || count($ref_stack) === 0) { + $result_size = $f_style->length_in_pt($current_size); + break; + } + } + } while (($f = $f->get_parent())); + + // if we built a percentage stack walk up to find the real size + if (count($ref_stack) > 0) { + while (($ref = array_pop($ref_stack))) { + $result_size = $f_style->length_in_pt($ref, $result_size); + } + } + + return $result_size; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Inline.php b/vendor/dompdf/dompdf/src/FrameReflower/Inline.php new file mode 100644 index 0000000..68662a5 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Inline.php @@ -0,0 +1,103 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Text as TextFrameDecorator; + +/** + * Reflows inline frames + * + * @package dompdf + */ +class Inline extends AbstractFrameReflower +{ + + /** + * Inline constructor. + * @param Frame $frame + */ + function __construct(Frame $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $frame = $this->_frame; + + // Check if a page break is forced + $page = $frame->get_root(); + $page->check_forced_page_break($frame); + + if ($page->is_full()) { + return; + } + + $style = $frame->get_style(); + + // Generated content + $this->_set_content(); + + $frame->position(); + + $cb = $frame->get_containing_block(); + + // Add our margin, padding & border to the first and last children + if (($f = $frame->get_first_child()) && $f instanceof TextFrameDecorator) { + $f_style = $f->get_style(); + $f_style->margin_left = $style->margin_left; + $f_style->padding_left = $style->padding_left; + $f_style->border_left = $style->border_left; + } + + if (($l = $frame->get_last_child()) && $l instanceof TextFrameDecorator) { + $l_style = $l->get_style(); + $l_style->margin_right = $style->margin_right; + $l_style->padding_right = $style->padding_right; + $l_style->border_right = $style->border_right; + } + + if ($block) { + $block->add_frame_to_line($this->_frame); + } + + // Set the containing blocks and reflow each child. The containing + // block is not changed by line boxes. + foreach ($frame->get_children() as $child) { + $child->set_containing_block($cb); + $child->reflow($block); + } + } + + /** + * Determine current frame width based on contents + * + * @return float + */ + public function calculate_auto_width() + { + $width = 0; + + foreach ($this->_frame->get_children() as $child) { + if ($child->get_original_style()->width == 'auto') { + $width += $child->calculate_auto_width(); + } else { + $width += $child->get_margin_width(); + } + } + + $this->_frame->get_style()->width = $width; + + return $this->_frame->get_margin_width(); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/ListBullet.php b/vendor/dompdf/dompdf/src/FrameReflower/ListBullet.php new file mode 100644 index 0000000..48613cc --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/ListBullet.php @@ -0,0 +1,45 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Reflows list bullets + * + * @package dompdf + */ +class ListBullet extends AbstractFrameReflower +{ + + /** + * ListBullet constructor. + * @param AbstractFrameDecorator $frame + */ + function __construct(AbstractFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $style = $this->_frame->get_style(); + + $style->width = $this->_frame->get_width(); + $this->_frame->position(); + + if ($style->list_style_position === "inside") { + $p = $this->_frame->find_block_parent(); + $p->add_frame_to_line($this->_frame); + } + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/NullFrameReflower.php b/vendor/dompdf/dompdf/src/FrameReflower/NullFrameReflower.php new file mode 100644 index 0000000..8bdb0f1 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/NullFrameReflower.php @@ -0,0 +1,39 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\FrameReflower; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; + +/** + * Dummy reflower + * + * @package dompdf + */ +class NullFrameReflower extends AbstractFrameReflower +{ + + /** + * NullFrameReflower constructor. + * @param Frame $frame + */ + function __construct(Frame $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + return; + } + +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Page.php b/vendor/dompdf/dompdf/src/FrameReflower/Page.php new file mode 100644 index 0000000..3399b97 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Page.php @@ -0,0 +1,205 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Page as PageFrameDecorator; + +/** + * Reflows pages + * + * @package dompdf + */ +class Page extends AbstractFrameReflower +{ + + /** + * Cache of the callbacks array + * + * @var array + */ + private $_callbacks; + + /** + * Cache of the canvas + * + * @var \Dompdf\Canvas + */ + private $_canvas; + + /** + * Page constructor. + * @param PageFrameDecorator $frame + */ + function __construct(PageFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * @param Frame $frame + * @param $page_number + */ + function apply_page_style(Frame $frame, $page_number) + { + $style = $frame->get_style(); + $page_styles = $style->get_stylesheet()->get_page_styles(); + + // http://www.w3.org/TR/CSS21/page.html#page-selectors + if (count($page_styles) > 1) { + $odd = $page_number % 2 == 1; + $first = $page_number == 1; + + $style = clone $page_styles["base"]; + + // FIXME RTL + if ($odd && isset($page_styles[":right"])) { + $style->merge($page_styles[":right"]); + } + + if ($odd && isset($page_styles[":odd"])) { + $style->merge($page_styles[":odd"]); + } + + // FIXME RTL + if (!$odd && isset($page_styles[":left"])) { + $style->merge($page_styles[":left"]); + } + + if (!$odd && isset($page_styles[":even"])) { + $style->merge($page_styles[":even"]); + } + + if ($first && isset($page_styles[":first"])) { + $style->merge($page_styles[":first"]); + } + + $frame->set_style($style); + } + } + + /** + * Paged layout: + * http://www.w3.org/TR/CSS21/page.html + * + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $fixed_children = []; + $prev_child = null; + $child = $this->_frame->get_first_child(); + $current_page = 0; + + while ($child) { + $this->apply_page_style($this->_frame, $current_page + 1); + + $style = $this->_frame->get_style(); + + // Pages are only concerned with margins + $cb = $this->_frame->get_containing_block(); + $left = (float)$style->length_in_pt($style->margin_left, $cb["w"]); + $right = (float)$style->length_in_pt($style->margin_right, $cb["w"]); + $top = (float)$style->length_in_pt($style->margin_top, $cb["h"]); + $bottom = (float)$style->length_in_pt($style->margin_bottom, $cb["h"]); + + $content_x = $cb["x"] + $left; + $content_y = $cb["y"] + $top; + $content_width = $cb["w"] - $left - $right; + $content_height = $cb["h"] - $top - $bottom; + + // Only if it's the first page, we save the nodes with a fixed position + if ($current_page == 0) { + $children = $child->get_children(); + foreach ($children as $onechild) { + if ($onechild->get_style()->position === "fixed") { + $fixed_children[] = $onechild->deep_copy(); + } + } + $fixed_children = array_reverse($fixed_children); + } + + $child->set_containing_block($content_x, $content_y, $content_width, $content_height); + + // Check for begin reflow callback + $this->_check_callbacks("begin_page_reflow", $child); + + //Insert a copy of each node which have a fixed position + if ($current_page >= 1) { + foreach ($fixed_children as $fixed_child) { + $child->insert_child_before($fixed_child->deep_copy(), $child->get_first_child()); + } + } + + $child->reflow(); + $next_child = $child->get_next_sibling(); + + // Check for begin render callback + $this->_check_callbacks("begin_page_render", $child); + + // Render the page + $this->_frame->get_renderer()->render($child); + + // Check for end render callback + $this->_check_callbacks("end_page_render", $child); + + if ($next_child) { + $this->_frame->next_page(); + } + + // Wait to dispose of all frames on the previous page + // so callback will have access to them + if ($prev_child) { + $prev_child->dispose(true); + } + $prev_child = $child; + $child = $next_child; + $current_page++; + } + + // Dispose of previous page if it still exists + if ($prev_child) { + $prev_child->dispose(true); + } + } + + /** + * Check for callbacks that need to be performed when a given event + * gets triggered on a page + * + * @param string $event the type of event + * @param Frame $frame the frame that event is triggered on + */ + protected function _check_callbacks($event, $frame) + { + if (!isset($this->_callbacks)) { + $dompdf = $this->_frame->get_dompdf(); + $this->_callbacks = $dompdf->get_callbacks(); + $this->_canvas = $dompdf->get_canvas(); + } + + if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) { + $info = [ + 0 => $this->_canvas, "canvas" => $this->_canvas, + 1 => $frame, "frame" => $frame, + ]; + $fs = $this->_callbacks[$event]; + foreach ($fs as $f) { + if (is_callable($f)) { + if (is_array($f)) { + $f[0]->{$f[1]}($info); + } else { + $f($info); + } + } + } + } + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Table.php b/vendor/dompdf/dompdf/src/FrameReflower/Table.php new file mode 100644 index 0000000..ebf430e --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Table.php @@ -0,0 +1,589 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Table as TableFrameDecorator; + +/** + * Reflows tables + * + * @access private + * @package dompdf + */ +class Table extends AbstractFrameReflower +{ + /** + * Frame for this reflower + * + * @var TableFrameDecorator + */ + protected $_frame; + + /** + * Cache of results between call to get_min_max_width and assign_widths + * + * @var array + */ + protected $_state; + + /** + * Table constructor. + * @param TableFrameDecorator $frame + */ + function __construct(TableFrameDecorator $frame) + { + $this->_state = null; + parent::__construct($frame); + } + + /** + * State is held here so it needs to be reset along with the decorator + */ + function reset() + { + $this->_state = null; + $this->_min_max_cache = null; + } + + protected function _assign_widths() + { + $style = $this->_frame->get_style(); + + // Find the min/max width of the table and sort the columns into + // absolute/percent/auto arrays + $min_width = $this->_state["min_width"]; + $max_width = $this->_state["max_width"]; + $percent_used = $this->_state["percent_used"]; + $absolute_used = $this->_state["absolute_used"]; + $auto_min = $this->_state["auto_min"]; + + $absolute =& $this->_state["absolute"]; + $percent =& $this->_state["percent"]; + $auto =& $this->_state["auto"]; + + // Determine the actual width of the table + $cb = $this->_frame->get_containing_block(); + $columns =& $this->_frame->get_cellmap()->get_columns(); + + $width = $style->width; + + // Calculate padding & border fudge factor + $left = $style->margin_left; + $right = $style->margin_right; + + $centered = ($left === "auto" && $right === "auto"); + + $left = (float)($left === "auto" ? 0 : $style->length_in_pt($left, $cb["w"])); + $right = (float)($right === "auto" ? 0 : $style->length_in_pt($right, $cb["w"])); + + $delta = $left + $right; + + if (!$centered) { + $delta += (float)$style->length_in_pt([ + $style->padding_left, + $style->border_left_width, + $style->border_right_width, + $style->padding_right], + $cb["w"]); + } + + $min_table_width = (float)$style->length_in_pt($style->min_width, $cb["w"] - $delta); + + // min & max widths already include borders & padding + $min_width -= $delta; + $max_width -= $delta; + + if ($width !== "auto") { + $preferred_width = (float)$style->length_in_pt($width, $cb["w"]) - $delta; + + if ($preferred_width < $min_table_width) { + $preferred_width = $min_table_width; + } + + if ($preferred_width > $min_width) { + $width = $preferred_width; + } else { + $width = $min_width; + } + + } else { + if ($max_width + $delta < $cb["w"]) { + $width = $max_width; + } else if ($cb["w"] - $delta > $min_width) { + $width = $cb["w"] - $delta; + } else { + $width = $min_width; + } + + if ($width < $min_table_width) { + $width = $min_table_width; + } + + } + + // Store our resolved width + $style->width = $width; + + $cellmap = $this->_frame->get_cellmap(); + + if ($cellmap->is_columns_locked()) { + return; + } + + // If the whole table fits on the page, then assign each column it's max width + if ($width == $max_width) { + foreach (array_keys($columns) as $i) { + $cellmap->set_column_width($i, $columns[$i]["max-width"]); + } + + return; + } + + // Determine leftover and assign it evenly to all columns + if ($width > $min_width) { + // We have four cases to deal with: + // + // 1. All columns are auto--no widths have been specified. In this + // case we distribute extra space across all columns weighted by max-width. + // + // 2. Only absolute widths have been specified. In this case we + // distribute any extra space equally among 'width: auto' columns, or all + // columns if no auto columns have been specified. + // + // 3. Only percentage widths have been specified. In this case we + // normalize the percentage values and distribute any remaining % to + // width: auto columns. We then proceed to assign widths as fractions + // of the table width. + // + // 4. Both absolute and percentage widths have been specified. + + $increment = 0; + + // Case 1: + if ($absolute_used == 0 && $percent_used == 0) { + $increment = $width - $min_width; + + foreach (array_keys($columns) as $i) { + $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment * ($columns[$i]["max-width"] / $max_width)); + } + return; + } + + // Case 2 + if ($absolute_used > 0 && $percent_used == 0) { + if (count($auto) > 0) { + $increment = ($width - $auto_min - $absolute_used) / count($auto); + } + + // Use the absolutely specified width or the increment + foreach (array_keys($columns) as $i) { + if ($columns[$i]["absolute"] > 0 && count($auto)) { + $cellmap->set_column_width($i, $columns[$i]["min-width"]); + } else if (count($auto)) { + $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment); + } else { + // All absolute columns + $increment = ($width - $absolute_used) * $columns[$i]["absolute"] / $absolute_used; + + $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment); + } + + } + return; + } + + // Case 3: + if ($absolute_used == 0 && $percent_used > 0) { + $scale = null; + $remaining = null; + + // Scale percent values if the total percentage is > 100, or if all + // values are specified as percentages. + if ($percent_used > 100 || count($auto) == 0) { + $scale = 100 / $percent_used; + } else { + $scale = 1; + } + + // Account for the minimum space used by the unassigned auto columns + $used_width = $auto_min; + + foreach ($percent as $i) { + $columns[$i]["percent"] *= $scale; + + $slack = $width - $used_width; + + $w = min($columns[$i]["percent"] * $width / 100, $slack); + + if ($w < $columns[$i]["min-width"]) { + $w = $columns[$i]["min-width"]; + } + + $cellmap->set_column_width($i, $w); + $used_width += $w; + + } + + // This works because $used_width includes the min-width of each + // unassigned column + if (count($auto) > 0) { + $increment = ($width - $used_width) / count($auto); + + foreach ($auto as $i) { + $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment); + } + + } + return; + } + + // Case 4: + + // First-come, first served + if ($absolute_used > 0 && $percent_used > 0) { + $used_width = $auto_min; + + foreach ($absolute as $i) { + $cellmap->set_column_width($i, $columns[$i]["min-width"]); + $used_width += $columns[$i]["min-width"]; + } + + // Scale percent values if the total percentage is > 100 or there + // are no auto values to take up slack + if ($percent_used > 100 || count($auto) == 0) { + $scale = 100 / $percent_used; + } else { + $scale = 1; + } + + $remaining_width = $width - $used_width; + + foreach ($percent as $i) { + $slack = $remaining_width - $used_width; + + $columns[$i]["percent"] *= $scale; + $w = min($columns[$i]["percent"] * $remaining_width / 100, $slack); + + if ($w < $columns[$i]["min-width"]) { + $w = $columns[$i]["min-width"]; + } + + $columns[$i]["used-width"] = $w; + $used_width += $w; + } + + if (count($auto) > 0) { + $increment = ($width - $used_width) / count($auto); + + foreach ($auto as $i) { + $cellmap->set_column_width($i, $columns[$i]["min-width"] + $increment); + } + } + + return; + } + } else { // we are over constrained + // Each column gets its minimum width + foreach (array_keys($columns) as $i) { + $cellmap->set_column_width($i, $columns[$i]["min-width"]); + } + } + } + + /** + * Determine the frame's height based on min/max height + * + * @return float|int|mixed|string + */ + protected function _calculate_height() + { + $style = $this->_frame->get_style(); + $height = $style->height; + + $cellmap = $this->_frame->get_cellmap(); + $cellmap->assign_frame_heights(); + $rows = $cellmap->get_rows(); + + // Determine our content height + $content_height = 0; + foreach ($rows as $r) { + $content_height += $r["height"]; + } + + $cb = $this->_frame->get_containing_block(); + + if (!($style->overflow === "visible" || + ($style->overflow === "hidden" && $height === "auto")) + ) { + // Only handle min/max height if the height is independent of the frame's content + + $min_height = $style->min_height; + $max_height = $style->max_height; + + if (isset($cb["h"])) { + $min_height = $style->length_in_pt($min_height, $cb["h"]); + $max_height = $style->length_in_pt($max_height, $cb["h"]); + + } else if (isset($cb["w"])) { + if (mb_strpos($min_height, "%") !== false) { + $min_height = 0; + } else { + $min_height = $style->length_in_pt($min_height, $cb["w"]); + } + if (mb_strpos($max_height, "%") !== false) { + $max_height = "none"; + } else { + $max_height = $style->length_in_pt($max_height, $cb["w"]); + } + } + + if ($max_height !== "none" && $min_height > $max_height) { + // Swap 'em + list($max_height, $min_height) = [$min_height, $max_height]; + } + + if ($max_height !== "none" && $height > $max_height) { + $height = $max_height; + } + + if ($height < $min_height) { + $height = $min_height; + } + } else { + // Use the content height or the height value, whichever is greater + if ($height !== "auto") { + $height = $style->length_in_pt($height, $cb["h"]); + + if ($height <= $content_height) { + $height = $content_height; + } else { + $cellmap->set_frame_heights($height, $content_height); + } + } else { + $height = $content_height; + } + } + + return $height; + } + + /** + * @param BlockFrameDecorator $block + */ + function reflow(BlockFrameDecorator $block = null) + { + /** @var TableFrameDecorator */ + $frame = $this->_frame; + + // Check if a page break is forced + $page = $frame->get_root(); + $page->check_forced_page_break($frame); + + // Bail if the page is full + if ($page->is_full()) { + return; + } + + // Let the page know that we're reflowing a table so that splits + // are suppressed (simply setting page-break-inside: avoid won't + // work because we may have an arbitrary number of block elements + // inside tds.) + $page->table_reflow_start(); + + // Collapse vertical margins, if required + $this->_collapse_margins(); + + $frame->position(); + + // Table layout algorithm: + // http://www.w3.org/TR/CSS21/tables.html#auto-table-layout + + if (is_null($this->_state)) { + $this->get_min_max_width(); + } + + $cb = $frame->get_containing_block(); + $style = $frame->get_style(); + + // This is slightly inexact, but should be okay. Add half the + // border-spacing to the table as padding. The other half is added to + // the cells themselves. + if ($style->border_collapse === "separate") { + list($h, $v) = $style->border_spacing; + + $v = (float)$style->length_in_pt($v) / 2; + $h = (float)$style->length_in_pt($h) / 2; + + $style->padding_left = (float)$style->length_in_pt($style->padding_left, $cb["w"]) + $h; + $style->padding_right = (float)$style->length_in_pt($style->padding_right, $cb["w"]) + $h; + $style->padding_top = (float)$style->length_in_pt($style->padding_top, $cb["h"]) + $v; + $style->padding_bottom = (float)$style->length_in_pt($style->padding_bottom, $cb["h"]) + $v; + } + + $this->_assign_widths(); + + // Adjust left & right margins, if they are auto + $width = $style->width; + $left = $style->margin_left; + $right = $style->margin_right; + + $diff = (float)$cb["w"] - (float)$width; + + if ($left === "auto" && $right === "auto") { + if ($diff < 0) { + $left = 0; + $right = $diff; + } else { + $left = $right = $diff / 2; + } + + $style->margin_left = sprintf("%Fpt", $left); + $style->margin_right = sprintf("%Fpt", $right);; + } else { + if ($left === "auto") { + $left = (float)$style->length_in_pt($cb["w"], $cb["w"]) - (float)$style->length_in_pt($right, $cb["w"]) - (float)$style->length_in_pt($width, $cb["w"]); + } + if ($right === "auto") { + $left = (float)$style->length_in_pt($left, $cb["w"]); + } + } + + list($x, $y) = $frame->get_position(); + + // Determine the content edge + $content_x = $x + (float)$left + (float)$style->length_in_pt([$style->padding_left, + $style->border_left_width], $cb["w"]); + $content_y = $y + (float)$style->length_in_pt([$style->margin_top, + $style->border_top_width, + $style->padding_top], $cb["h"]); + + if (isset($cb["h"])) { + $h = $cb["h"]; + } else { + $h = null; + } + + $cellmap = $frame->get_cellmap(); + $col =& $cellmap->get_column(0); + $col["x"] = $content_x; + + $row =& $cellmap->get_row(0); + $row["y"] = $content_y; + + $cellmap->assign_x_positions(); + + // Set the containing block of each child & reflow + foreach ($frame->get_children() as $child) { + // Bail if the page is full + if (!$page->in_nested_table() && $page->is_full()) { + break; + } + + $child->set_containing_block($content_x, $content_y, $width, $h); + $child->reflow(); + + if (!$page->in_nested_table()) { + // Check if a split has occured + $page->check_page_break($child); + } + + } + + // Assign heights to our cells: + $style->height = $this->_calculate_height(); + + if ($style->border_collapse === "collapse") { + // Unset our borders because our cells are now using them + $style->border_style = "none"; + } + + $page->table_reflow_end(); + + // Debugging: + //echo ($this->_frame->get_cellmap()); + + if ($block && $style->float === "none" && $frame->is_in_flow()) { + $block->add_frame_to_line($frame); + $block->add_line(); + } + } + + /** + * @return array|null + */ + function get_min_max_width() + { + if (!is_null($this->_min_max_cache)) { + return $this->_min_max_cache; + } + + $style = $this->_frame->get_style(); + + $this->_frame->normalise(); + + // Add the cells to the cellmap (this will calcluate column widths as + // frames are added) + $this->_frame->get_cellmap()->add_frame($this->_frame); + + // Find the min/max width of the table and sort the columns into + // absolute/percent/auto arrays + $this->_state = []; + $this->_state["min_width"] = 0; + $this->_state["max_width"] = 0; + + $this->_state["percent_used"] = 0; + $this->_state["absolute_used"] = 0; + $this->_state["auto_min"] = 0; + + $this->_state["absolute"] = []; + $this->_state["percent"] = []; + $this->_state["auto"] = []; + + $columns =& $this->_frame->get_cellmap()->get_columns(); + foreach (array_keys($columns) as $i) { + $this->_state["min_width"] += $columns[$i]["min-width"]; + $this->_state["max_width"] += $columns[$i]["max-width"]; + + if ($columns[$i]["absolute"] > 0) { + $this->_state["absolute"][] = $i; + $this->_state["absolute_used"] += $columns[$i]["absolute"]; + } else if ($columns[$i]["percent"] > 0) { + $this->_state["percent"][] = $i; + $this->_state["percent_used"] += $columns[$i]["percent"]; + } else { + $this->_state["auto"][] = $i; + $this->_state["auto_min"] += $columns[$i]["min-width"]; + } + } + + // Account for margins & padding + $dims = [$style->border_left_width, + $style->border_right_width, + $style->padding_left, + $style->padding_right, + $style->margin_left, + $style->margin_right]; + + if ($style->border_collapse !== "collapse") { + list($dims[]) = $style->border_spacing; + } + + $delta = (float)$style->length_in_pt($dims, $this->_frame->get_containing_block("w")); + + $this->_state["min_width"] += $delta; + $this->_state["max_width"] += $delta; + + return $this->_min_max_cache = [ + $this->_state["min_width"], + $this->_state["max_width"], + "min" => $this->_state["min_width"], + "max" => $this->_state["max_width"], + ]; + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/TableCell.php b/vendor/dompdf/dompdf/src/FrameReflower/TableCell.php new file mode 100644 index 0000000..b3c93df --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/TableCell.php @@ -0,0 +1,121 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Table as TableFrameDecorator; + +/** + * Reflows table cells + * + * @package dompdf + */ +class TableCell extends Block +{ + /** + * TableCell constructor. + * @param BlockFrameDecorator $frame + */ + function __construct(BlockFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $style = $this->_frame->get_style(); + + $table = TableFrameDecorator::find_parent_table($this->_frame); + $cellmap = $table->get_cellmap(); + + list($x, $y) = $cellmap->get_frame_position($this->_frame); + $this->_frame->set_position($x, $y); + + $cells = $cellmap->get_spanned_cells($this->_frame); + + $w = 0; + foreach ($cells["columns"] as $i) { + $col = $cellmap->get_column($i); + $w += $col["used-width"]; + } + + //FIXME? + $h = $this->_frame->get_containing_block("h"); + + $left_space = (float)$style->length_in_pt([$style->margin_left, + $style->padding_left, + $style->border_left_width], + $w); + + $right_space = (float)$style->length_in_pt([$style->padding_right, + $style->margin_right, + $style->border_right_width], + $w); + + $top_space = (float)$style->length_in_pt([$style->margin_top, + $style->padding_top, + $style->border_top_width], + $h); + $bottom_space = (float)$style->length_in_pt([$style->margin_bottom, + $style->padding_bottom, + $style->border_bottom_width], + $h); + + $style->width = $cb_w = $w - $left_space - $right_space; + + $content_x = $x + $left_space; + $content_y = $line_y = $y + $top_space; + + // Adjust the first line based on the text-indent property + $indent = (float)$style->length_in_pt($style->text_indent, $w); + $this->_frame->increase_line_width($indent); + + $page = $this->_frame->get_root(); + + // Set the y position of the first line in the cell + $line_box = $this->_frame->get_current_line_box(); + $line_box->y = $line_y; + + // Set the containing blocks and reflow each child + foreach ($this->_frame->get_children() as $child) { + if ($page->is_full()) { + break; + } + + $child->set_containing_block($content_x, $content_y, $cb_w, $h); + $this->process_clear($child); + $child->reflow($this->_frame); + $this->process_float($child, $x + $left_space, $w - $right_space - $left_space); + } + + // Determine our height + $style_height = (float)$style->length_in_pt($style->height, $h); + + $this->_frame->set_content_height($this->_calculate_content_height()); + + $height = max($style_height, (float)$this->_frame->get_content_height()); + + // Let the cellmap know our height + $cell_height = $height / count($cells["rows"]); + + if ($style_height <= $height) { + $cell_height += $top_space + $bottom_space; + } + + foreach ($cells["rows"] as $i) { + $cellmap->set_row_height($i, $cell_height); + } + + $style->height = $height; + $this->_text_align(); + $this->vertical_align(); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/TableRow.php b/vendor/dompdf/dompdf/src/FrameReflower/TableRow.php new file mode 100644 index 0000000..5b94473 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/TableRow.php @@ -0,0 +1,74 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Table as TableFrameDecorator; +use Dompdf\FrameDecorator\TableRow as TableRowFrameDecorator; +use Dompdf\Exception; + +/** + * Reflows table rows + * + * @package dompdf + */ +class TableRow extends AbstractFrameReflower +{ + /** + * TableRow constructor. + * @param TableRowFrameDecorator $frame + */ + function __construct(TableRowFrameDecorator $frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $page = $this->_frame->get_root(); + + if ($page->is_full()) { + return; + } + + $this->_frame->position(); + $style = $this->_frame->get_style(); + $cb = $this->_frame->get_containing_block(); + + foreach ($this->_frame->get_children() as $child) { + if ($page->is_full()) { + return; + } + + $child->set_containing_block($cb); + $child->reflow(); + } + + if ($page->is_full()) { + return; + } + + $table = TableFrameDecorator::find_parent_table($this->_frame); + $cellmap = $table->get_cellmap(); + $style->width = $cellmap->get_frame_width($this->_frame); + $style->height = $cellmap->get_frame_height($this->_frame); + + $this->_frame->set_position($cellmap->get_frame_position($this->_frame)); + } + + /** + * @throws Exception + */ + function get_min_max_width() + { + throw new Exception("Min/max width is undefined for table rows"); + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php b/vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php new file mode 100644 index 0000000..13a1987 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/TableRowGroup.php @@ -0,0 +1,72 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Table as TableFrameDecorator; + +/** + * Reflows table row groups (e.g. tbody tags) + * + * @package dompdf + */ +class TableRowGroup extends AbstractFrameReflower +{ + + /** + * TableRowGroup constructor. + * @param \Dompdf\Frame $frame + */ + function __construct($frame) + { + parent::__construct($frame); + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $page = $this->_frame->get_root(); + + $style = $this->_frame->get_style(); + + // Our width is equal to the width of our parent table + $table = TableFrameDecorator::find_parent_table($this->_frame); + + $cb = $this->_frame->get_containing_block(); + + foreach ($this->_frame->get_children() as $child) { + // Bail if the page is full + if ($page->is_full()) { + return; + } + + $child->set_containing_block($cb["x"], $cb["y"], $cb["w"], $cb["h"]); + $child->reflow(); + + // Check if a split has occured + $page->check_page_break($child); + } + + if ($page->is_full()) { + return; + } + + $cellmap = $table->get_cellmap(); + $style->width = $cellmap->get_frame_width($this->_frame); + $style->height = $cellmap->get_frame_height($this->_frame); + + $this->_frame->set_position($cellmap->get_frame_position($this->_frame)); + + if ($table->get_style()->border_collapse === "collapse") { + // Unset our borders because our cells are now using them + $style->border_style = "none"; + } + } +} diff --git a/vendor/dompdf/dompdf/src/FrameReflower/Text.php b/vendor/dompdf/dompdf/src/FrameReflower/Text.php new file mode 100644 index 0000000..ea92343 --- /dev/null +++ b/vendor/dompdf/dompdf/src/FrameReflower/Text.php @@ -0,0 +1,512 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\FrameReflower; + +use Dompdf\FrameDecorator\Block as BlockFrameDecorator; +use Dompdf\FrameDecorator\Text as TextFrameDecorator; +use Dompdf\FontMetrics; +use Dompdf\Helpers; + +/** + * Reflows text frames. + * + * @package dompdf + */ +class Text extends AbstractFrameReflower +{ + + /** + * @var BlockFrameDecorator + */ + protected $_block_parent; // Nearest block-level ancestor + + /** + * @var TextFrameDecorator + */ + protected $_frame; + + // The regex splits on everything that's a separator (^\S double negative), excluding nbsp (\xa0) + // This currently excludes the "narrow nbsp" character + public static $_whitespace_pattern = '/([^\S\xA0]+)/u'; + // The regex splits on everything that's a separator (^\S double negative), excluding nbsp (\xa0), plus dashes + // This currently excludes the "narrow nbsp" character + public static $_wordbreak_pattern = '/([^\S\xA0]+|-+)/u'; + + /** + * @var FontMetrics + */ + private $fontMetrics; + + /** + * @param TextFrameDecorator $frame + * @param FontMetrics $fontMetrics + */ + public function __construct(TextFrameDecorator $frame, FontMetrics $fontMetrics) + { + parent::__construct($frame); + $this->setFontMetrics($fontMetrics); + } + + /** + * @param $text + * @return mixed + */ + protected function _collapse_white_space($text) + { + return preg_replace(self::$_whitespace_pattern, " ", $text); + } + + /** + * @param $text + * @return bool|int + */ + protected function _line_break($text) + { + $style = $this->_frame->get_style(); + $size = $style->font_size; + $font = $style->font_family; + $current_line = $this->_block_parent->get_current_line_box(); + + // Determine the available width + $line_width = $this->_frame->get_containing_block("w"); + $current_line_width = $current_line->left + $current_line->w + $current_line->right; + + $available_width = $line_width - $current_line_width; + + // Account for word-spacing + $word_spacing = (float)$style->length_in_pt($style->word_spacing); + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + + // Determine the frame width including margin, padding & border + $text_width = $this->getFontMetrics()->getTextWidth($text, $font, $size, $word_spacing, $char_spacing); + $mbp_width = + (float)$style->length_in_pt([$style->margin_left, + $style->border_left_width, + $style->padding_left, + $style->padding_right, + $style->border_right_width, + $style->margin_right], $line_width); + + $frame_width = $text_width + $mbp_width; + +// Debugging: +// Helpers::pre_r("Text: '" . htmlspecialchars($text). "'"); +// Helpers::pre_r("width: " .$frame_width); +// Helpers::pre_r("textwidth + delta: $text_width + $mbp_width"); +// Helpers::pre_r("font-size: $size"); +// Helpers::pre_r("cb[w]: " .$line_width); +// Helpers::pre_r("available width: " . $available_width); +// Helpers::pre_r("current line width: " . $current_line_width); + +// Helpers::pre_r($words); + + if ($frame_width <= $available_width) { + return false; + } + + // split the text into words + $words = preg_split(self::$_wordbreak_pattern, $text, -1, PREG_SPLIT_DELIM_CAPTURE); + $wc = count($words); + + // Determine the split point + $width = 0; + $str = ""; + reset($words); + + // @todo support , + for ($i = 0; $i < $wc; $i += 2) { + $word = $words[$i] . (isset($words[$i + 1]) ? $words[$i + 1] : ""); + $word_width = $this->getFontMetrics()->getTextWidth($word, $font, $size, $word_spacing, $char_spacing); + if ($width + $word_width + $mbp_width > $available_width) { + break; + } + + $width += $word_width; + $str .= $word; + } + + $break_word = ($style->word_wrap === "break-word"); + + // The first word has overflowed. Force it onto the line + if ($current_line_width == 0 && $width == 0) { + $s = ""; + $last_width = 0; + + if ($break_word) { + for ($j = 0; $j < strlen($word); $j++) { + $s .= $word[$j]; + $_width = $this->getFontMetrics()->getTextWidth($s, $font, $size, $word_spacing, $char_spacing); + if ($_width > $available_width) { + break; + } + + $last_width = $_width; + } + } + + if ($break_word && $last_width > 0) { + //$width += $last_width; + $str .= substr($s, 0, -1); + } else { + //$width += $word_width; + $str .= $word; + } + } + + $offset = mb_strlen($str); + + // More debugging: + // var_dump($str); + // print_r("Width: ". $width); + // print_r("Offset: " . $offset); + + return $offset; + } + + //........................................................................ + + /** + * @param $text + * @return bool|int + */ + protected function _newline_break($text) + { + if (($i = mb_strpos($text, "\n")) === false) { + return false; + } + + return $i + 1; + } + + protected function _layout_line(): bool + { + $frame = $this->_frame; + $style = $frame->get_style(); + $text = $frame->get_text(); + $size = $style->font_size; + $font = $style->font_family; + + // Determine the text height + $style->height = $this->getFontMetrics()->getFontHeight($font, $size); + + $split = false; + $add_line = false; + + // Handle text transform: + // http://www.w3.org/TR/CSS21/text.html#propdef-text-transform + switch (strtolower($style->text_transform)) { + default: + break; + case "capitalize": + $text = Helpers::mb_ucwords($text); + break; + case "uppercase": + $text = mb_convert_case($text, MB_CASE_UPPER); + break; + case "lowercase": + $text = mb_convert_case($text, MB_CASE_LOWER); + break; + } + + // Handle white-space property: + // http://www.w3.org/TR/CSS21/text.html#propdef-white-space + switch ($style->white_space) { + default: + case "normal": + $frame->set_text($text = $this->_collapse_white_space($text)); + if ($text === "") { + break; + } + + $split = $this->_line_break($text); + break; + + case "pre": + $split = $this->_newline_break($text); + $add_line = $split !== false; + break; + + case "nowrap": + $frame->set_text($text = $this->_collapse_white_space($text)); + break; + /** @noinspection PhpMissingBreakStatementInspection */ + case "pre-line": + // Collapse white-space except for \n + $frame->set_text($text = preg_replace("/[ \t]+/u", " ", $text)); + + if ($text === "") { + break; + } + case "pre-wrap": + $split = $this->_newline_break($text); + + if (($tmp = $this->_line_break($text)) !== false) { + if ($split === false || $tmp < $split) { + $split = $tmp; + } else { + $add_line = true; + } + } else if ($split !== false) { + $add_line = true; + } + + break; + } + + // Handle degenerate case + if ($text === "") { + $split = 0; + } + + if ($split !== false) { + // Handle edge cases + if ($split == 0 && !$frame->is_pre() && empty(trim($text))) { + $frame->set_text(""); + } else if ($split === 0) { + // Remove any trailing white space from the previous sibling + if (($sibling = $frame->get_prev_sibling()) !== null) { + if ($sibling instanceof \Dompdf\FrameDecorator\Text && !$sibling->is_pre()) { + $st = $sibling->get_text(); + if (preg_match(self::$_whitespace_pattern, mb_substr($st, -1))) { + $sibling->set_text(mb_substr($st, 0, -1)); + $sibling->recalculate_width(); + $this->_block_parent->get_current_line_box()->recalculate_width(); + } + } + } + + // Trim newlines from the beginning of the line + //$this->_frame->set_text(ltrim($text, "\n\r")); + + $this->_block_parent->maximize_line_height($style->height, $frame); + $this->_block_parent->add_line(); + $frame->position(); + + // Layout the new line + $add_line = $this->_layout_line(); + } else if ($split < mb_strlen($frame->get_text())) { + // split the line if required + $frame->split_text($split); + + // Do we need to trim spaces on wrapped lines? This might be desired, however, we + // can't trim the lines here or the layout will be affected if trimming the line + // leaves enough space to fit the next word in the text stream (because pdf layout + // is performed elsewhere). + /*if (!$this->_frame->get_prev_sibling() && !$this->_frame->get_next_sibling()) { + $t = $this->_frame->get_text(); + $this->_frame->set_text( trim($t) ); + }*/ + } + + // Remove any trailing white space + if (!$frame->is_pre() && $add_line) { + $t = $frame->get_text(); + if (preg_match(self::$_whitespace_pattern, mb_substr($t, -1))) { + $frame->set_text(mb_substr($t, 0, -1)); + } + } + } else { + // Remove empty space from start and end of line, but only where there isn't an inline sibling + // and the parent node isn't an inline element with siblings + // FIXME: Include non-breaking spaces? + $t = $frame->get_text(); + $parent = $frame->get_parent(); + $is_inline_frame = ($parent instanceof \Dompdf\FrameDecorator\Inline); + + if ((!$is_inline_frame && !$frame->get_next_sibling()) /* || + ( $is_inline_frame && !$parent->get_next_sibling())*/ + ) { // fails BOLD UNDERLINED becomes BOLDUNDERLINED + $t = rtrim($t); + } + + if ((!$is_inline_frame && !$frame->get_prev_sibling()) /* || + ( $is_inline_frame && !$parent->get_prev_sibling())*/ + ) { // AB C fails (the whitespace is removed) + $t = ltrim($t); + } + + $frame->set_text($t); + } + + // Set our new width + $frame->recalculate_width(); + + return $add_line; + } + + /** + * @param BlockFrameDecorator|null $block + */ + function reflow(BlockFrameDecorator $block = null) + { + $frame = $this->_frame; + $page = $frame->get_root(); + $page->check_forced_page_break($this->_frame); + + if ($page->is_full()) { + return; + } + + $this->_block_parent = /*isset($block) ? $block : */ + $frame->find_block_parent(); + + // Left trim the text if this is the first text on the line and we're + // collapsing white space +// if ( $this->_block_parent->get_current_line()->w == 0 && +// ($frame->get_style()->white_space !== "pre" || +// $frame->get_style()->white_space !== "pre-wrap") ) { +// $frame->set_text( ltrim( $frame->get_text() ) ); +// } + + $frame->position(); + + $add_line = $this->_layout_line(); + + if ($block) { + $block->add_frame_to_line($frame); + + if ($add_line === true) { + $block->add_line(); + } + } + } + + //........................................................................ + + // Returns an array(0 => min, 1 => max, "min" => min, "max" => max) of the + // minimum and maximum widths of this frame + function get_min_max_width() + { + /*if ( !is_null($this->_min_max_cache) ) + return $this->_min_max_cache;*/ + $frame = $this->_frame; + $style = $frame->get_style(); + $this->_block_parent = $frame->find_block_parent(); + $line_width = $frame->get_containing_block("w"); + + $str = $text = $frame->get_text(); + $size = $style->font_size; + $font = $style->font_family; + + $word_spacing = (float)$style->length_in_pt($style->word_spacing); + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + + // determine minimum text width based on the whitespace setting + switch ($style->white_space) { + default: + /** @noinspection PhpMissingBreakStatementInspection */ + case "normal": + $str = preg_replace(self::$_whitespace_pattern, " ", $str); + case "pre-wrap": + case "pre-line": + + // Find the longest word (i.e. minimum length) + + // split the text into words + $words = array_flip(preg_split(self::$_wordbreak_pattern, $str, -1, PREG_SPLIT_DELIM_CAPTURE)); + $root = $this; + array_walk($words, function(&$chunked_text_width, $chunked_text) use ($font, $size, $word_spacing, $char_spacing, $root) { + $chunked_text_width = $root->getFontMetrics()->getTextWidth($chunked_text, $font, $size, $word_spacing, $char_spacing); + }); + + arsort($words); + $min = reset($words); + break; + + case "pre": + $lines = array_flip(preg_split("/\R/u", $str)); + $root = $this; + array_walk($lines, function(&$chunked_text_width, $chunked_text) use ($font, $size, $word_spacing, $char_spacing, $root) { + $chunked_text_width = $root->getFontMetrics()->getTextWidth($chunked_text, $font, $size, $word_spacing, $char_spacing); + }); + + arsort($lines); + $min = reset($lines); + break; + + case "nowrap": + $min = $this->getFontMetrics()->getTextWidth($this->_collapse_white_space($str), $font, $size, $word_spacing, $char_spacing); + break; + } + + // clean up the frame text based on the whitespace setting and use to determine maximum text width + switch ($style->white_space) { + default: + case "normal": + case "nowrap": + $str = preg_replace(self::$_whitespace_pattern, " ", $text); + break; + + case "pre-line": + $str = preg_replace("/[ \t]+/u", " ", $text); + break; + + case "pre-wrap": + // Find the longest word (i.e. minimum length) + $lines = array_flip(preg_split("/\R/u", $text)); + $root = $this; + array_walk($lines, function(&$chunked_text_width, $chunked_text) use ($font, $size, $word_spacing, $char_spacing, $root) { + $chunked_text_width = $root->getFontMetrics()->getTextWidth($chunked_text, $font, $size, $word_spacing, $char_spacing); + }); + arsort($lines); + reset($lines); + $str = key($lines); + break; + } + $max = $this->getFontMetrics()->getTextWidth($str, $font, $size, $word_spacing, $char_spacing); + + $delta = (float)$style->length_in_pt([$style->margin_left, + $style->border_left_width, + $style->padding_left, + $style->padding_right, + $style->border_right_width, + $style->margin_right], $line_width); + $min += $delta; + $min_word = $min; + $max += $delta; + + if ($style->word_wrap === 'break-word') { + // If it is allowed to break words, the min width is the widest character. + // But for performance reasons, we only check the first character. + $char = mb_substr($str, 0, 1); + $min_char = $this->getFontMetrics()->getTextWidth($char, $font, $size, $word_spacing, $char_spacing); + $min = $delta + $min_char; + } + + return $this->_min_max_cache = [$min, $max, $min_word, "min" => $min, "max" => $max, 'min_word' => $min_word]; + } + + /** + * @param FontMetrics $fontMetrics + * @return $this + */ + public function setFontMetrics(FontMetrics $fontMetrics) + { + $this->fontMetrics = $fontMetrics; + return $this; + } + + /** + * @return FontMetrics + */ + public function getFontMetrics() + { + return $this->fontMetrics; + } + + /** + * Determine current frame width based on contents + * + * @return float + */ + public function calculate_auto_width() + { + return $this->_frame->recalculate_width(); + } +} diff --git a/vendor/dompdf/dompdf/src/Helpers.php b/vendor/dompdf/dompdf/src/Helpers.php new file mode 100644 index 0000000..f28508c --- /dev/null +++ b/vendor/dompdf/dompdf/src/Helpers.php @@ -0,0 +1,937 @@ + tags if the current sapi is not 'cli'. + * Returns the output string instead of displaying it if $return is true. + * + * @param mixed $mixed variable or expression to display + * @param bool $return + * + * @return string|null + */ + public static function pre_r($mixed, $return = false) + { + if ($return) { + return "
" . print_r($mixed, true) . "
"; + } + + if (php_sapi_name() !== "cli") { + echo "
";
+        }
+
+        print_r($mixed);
+
+        if (php_sapi_name() !== "cli") {
+            echo "
"; + } else { + echo "\n"; + } + + flush(); + + return null; + } + + /** + * builds a full url given a protocol, hostname, base path and url + * + * @param string $protocol + * @param string $host + * @param string $base_path + * @param string $url + * @return string + * + * Initially the trailing slash of $base_path was optional, and conditionally appended. + * However on dynamically created sites, where the page is given as url parameter, + * the base path might not end with an url. + * Therefore do not append a slash, and **require** the $base_url to ending in a slash + * when needed. + * Vice versa, on using the local file system path of a file, make sure that the slash + * is appended (o.k. also for Windows) + */ + public static function build_url($protocol, $host, $base_path, $url) + { + $protocol = mb_strtolower($protocol); + if (strlen($url) == 0) { + //return $protocol . $host . rtrim($base_path, "/\\") . "/"; + return $protocol . $host . $base_path; + } + + // Is the url already fully qualified, a Data URI, or a reference to a named anchor? + // File-protocol URLs may require additional processing (e.g. for URLs with a relative path) + if ((mb_strpos($url, "://") !== false && substr($url, 0, 7) !== "file://") || mb_substr($url, 0, 1) === "#" || mb_strpos($url, "data:") === 0 || mb_strpos($url, "mailto:") === 0 || mb_strpos($url, "tel:") === 0) { + return $url; + } + + if (strpos($url, "file://") === 0) { + $url = substr($url, 7); + $protocol = ""; + } + + $ret = ""; + if ($protocol != "file://") { + $ret = $protocol; + } + + if (!in_array(mb_strtolower($protocol), ["http://", "https://", "ftp://", "ftps://"])) { + //On Windows local file, an abs path can begin also with a '\' or a drive letter and colon + //drive: followed by a relative path would be a drive specific default folder. + //not known in php app code, treat as abs path + //($url[1] !== ':' || ($url[2]!=='\\' && $url[2]!=='/')) + if ($url[0] !== '/' && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN' || (mb_strlen($url) > 1 && $url[0] !== '\\' && $url[1] !== ':'))) { + // For rel path and local access we ignore the host, and run the path through realpath() + $ret .= realpath($base_path) . '/'; + } + $ret .= $url; + $ret = preg_replace('/\?(.*)$/', "", $ret); + return $ret; + } + + // Protocol relative urls (e.g. "//example.org/style.css") + if (strpos($url, '//') === 0) { + $ret .= substr($url, 2); + //remote urls with backslash in html/css are not really correct, but lets be genereous + } elseif ($url[0] === '/' || $url[0] === '\\') { + // Absolute path + $ret .= $host . $url; + } else { + // Relative path + //$base_path = $base_path !== "" ? rtrim($base_path, "/\\") . "/" : ""; + $ret .= $host . $base_path . $url; + } + + // URL should now be complete, final cleanup + $parsed_url = parse_url($ret); + + // reproduced from https://www.php.net/manual/en/function.parse-url.php#106731 + $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : ''; + $host = isset($parsed_url['host']) ? $parsed_url['host'] : ''; + $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''; + $user = isset($parsed_url['user']) ? $parsed_url['user'] : ''; + $pass = isset($parsed_url['pass']) ? ':' . $parsed_url['pass'] : ''; + $pass = ($user || $pass) ? "$pass@" : ''; + $path = isset($parsed_url['path']) ? $parsed_url['path'] : ''; + $query = isset($parsed_url['query']) ? '?' . $parsed_url['query'] : ''; + $fragment = isset($parsed_url['fragment']) ? '#' . $parsed_url['fragment'] : ''; + + // partially reproduced from https://stackoverflow.com/a/1243431/264628 + /* replace '//' or '/./' or '/foo/../' with '/' */ + $re = array('#(/\.?/)#', '#/(?!\.\.)[^/]+/\.\./#'); + for($n=1; $n>0; $path=preg_replace($re, '/', $path, -1, $n)) {} + + $ret = "$scheme$user$pass$host$port$path$query$fragment"; + + return $ret; + } + + /** + * Builds a HTTP Content-Disposition header string using `$dispositionType` + * and `$filename`. + * + * If the filename contains any characters not in the ISO-8859-1 character + * set, a fallback filename will be included for clients not supporting the + * `filename*` parameter. + * + * @param string $dispositionType + * @param string $filename + * @return string + */ + public static function buildContentDispositionHeader($dispositionType, $filename) + { + $encoding = mb_detect_encoding($filename); + $fallbackfilename = mb_convert_encoding($filename, "ISO-8859-1", $encoding); + $fallbackfilename = str_replace("\"", "", $fallbackfilename); + $encodedfilename = rawurlencode($filename); + + $contentDisposition = "Content-Disposition: $dispositionType; filename=\"$fallbackfilename\""; + if ($fallbackfilename !== $filename) { + $contentDisposition .= "; filename*=UTF-8''$encodedfilename"; + } + + return $contentDisposition; + } + + /** + * Converts decimal numbers to roman numerals + * + * @param int $num + * + * @throws Exception + * @return string + */ + public static function dec2roman($num) + { + + static $ones = ["", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"]; + static $tens = ["", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"]; + static $hund = ["", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"]; + static $thou = ["", "m", "mm", "mmm"]; + + if (!is_numeric($num)) { + throw new Exception("dec2roman() requires a numeric argument."); + } + + if ($num > 4000 || $num < 0) { + return "(out of range)"; + } + + $num = strrev((string)$num); + + $ret = ""; + switch (mb_strlen($num)) { + /** @noinspection PhpMissingBreakStatementInspection */ + case 4: + $ret .= $thou[$num[3]]; + /** @noinspection PhpMissingBreakStatementInspection */ + case 3: + $ret .= $hund[$num[2]]; + /** @noinspection PhpMissingBreakStatementInspection */ + case 2: + $ret .= $tens[$num[1]]; + /** @noinspection PhpMissingBreakStatementInspection */ + case 1: + $ret .= $ones[$num[0]]; + default: + break; + } + + return $ret; + } + + /** + * Determines whether $value is a percentage or not + * + * @param float $value + * + * @return bool + */ + public static function is_percent($value) + { + return false !== mb_strpos($value, "%"); + } + + /** + * Parses a data URI scheme + * http://en.wikipedia.org/wiki/Data_URI_scheme + * + * @param string $data_uri The data URI to parse + * + * @return array|bool The result with charset, mime type and decoded data + */ + public static function parse_data_uri($data_uri) + { + if (!preg_match('/^data:(?P[a-z0-9\/+-.]+)(;charset=(?P[a-z0-9-])+)?(?P;base64)?\,(?P.*)?/is', $data_uri, $match)) { + return false; + } + + $match['data'] = rawurldecode($match['data']); + $result = [ + 'charset' => $match['charset'] ? $match['charset'] : 'US-ASCII', + 'mime' => $match['mime'] ? $match['mime'] : 'text/plain', + 'data' => $match['base64'] ? base64_decode($match['data']) : $match['data'], + ]; + + return $result; + } + + /** + * Encodes a Uniform Resource Identifier (URI) by replacing non-alphanumeric + * characters with a percent (%) sign followed by two hex digits, excepting + * characters in the URI reserved character set. + * + * Assumes that the URI is a complete URI, so does not encode reserved + * characters that have special meaning in the URI. + * + * Simulates the encodeURI function available in JavaScript + * https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/encodeURI + * + * Source: http://stackoverflow.com/q/4929584/264628 + * + * @param string $uri The URI to encode + * @return string The original URL with special characters encoded + */ + public static function encodeURI($uri) { + $unescaped = [ + '%2D'=>'-','%5F'=>'_','%2E'=>'.','%21'=>'!', '%7E'=>'~', + '%2A'=>'*', '%27'=>"'", '%28'=>'(', '%29'=>')' + ]; + $reserved = [ + '%3B'=>';','%2C'=>',','%2F'=>'/','%3F'=>'?','%3A'=>':', + '%40'=>'@','%26'=>'&','%3D'=>'=','%2B'=>'+','%24'=>'$' + ]; + $score = [ + '%23'=>'#' + ]; + return strtr(rawurlencode(rawurldecode($uri)), array_merge($reserved, $unescaped, $score)); + } + + /** + * Decoder for RLE8 compression in windows bitmaps + * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp + * + * @param string $str Data to decode + * @param integer $width Image width + * + * @return string + */ + public static function rle8_decode($str, $width) + { + $lineWidth = $width + (3 - ($width - 1) % 4); + $out = ''; + $cnt = strlen($str); + + for ($i = 0; $i < $cnt; $i++) { + $o = ord($str[$i]); + switch ($o) { + case 0: # ESCAPE + $i++; + switch (ord($str[$i])) { + case 0: # NEW LINE + $padCnt = $lineWidth - strlen($out) % $lineWidth; + if ($padCnt < $lineWidth) { + $out .= str_repeat(chr(0), $padCnt); # pad line + } + break; + case 1: # END OF FILE + $padCnt = $lineWidth - strlen($out) % $lineWidth; + if ($padCnt < $lineWidth) { + $out .= str_repeat(chr(0), $padCnt); # pad line + } + break 3; + case 2: # DELTA + $i += 2; + break; + default: # ABSOLUTE MODE + $num = ord($str[$i]); + for ($j = 0; $j < $num; $j++) { + $out .= $str[++$i]; + } + if ($num % 2) { + $i++; + } + } + break; + default: + $out .= str_repeat($str[++$i], $o); + } + } + return $out; + } + + /** + * Decoder for RLE4 compression in windows bitmaps + * see http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_6x0u.asp + * + * @param string $str Data to decode + * @param integer $width Image width + * + * @return string + */ + public static function rle4_decode($str, $width) + { + $w = floor($width / 2) + ($width % 2); + $lineWidth = $w + (3 - (($width - 1) / 2) % 4); + $pixels = []; + $cnt = strlen($str); + $c = 0; + + for ($i = 0; $i < $cnt; $i++) { + $o = ord($str[$i]); + switch ($o) { + case 0: # ESCAPE + $i++; + switch (ord($str[$i])) { + case 0: # NEW LINE + while (count($pixels) % $lineWidth != 0) { + $pixels[] = 0; + } + break; + case 1: # END OF FILE + while (count($pixels) % $lineWidth != 0) { + $pixels[] = 0; + } + break 3; + case 2: # DELTA + $i += 2; + break; + default: # ABSOLUTE MODE + $num = ord($str[$i]); + for ($j = 0; $j < $num; $j++) { + if ($j % 2 == 0) { + $c = ord($str[++$i]); + $pixels[] = ($c & 240) >> 4; + } else { + $pixels[] = $c & 15; + } + } + + if ($num % 2 == 0) { + $i++; + } + } + break; + default: + $c = ord($str[++$i]); + for ($j = 0; $j < $o; $j++) { + $pixels[] = ($j % 2 == 0 ? ($c & 240) >> 4 : $c & 15); + } + } + } + + $out = ''; + if (count($pixels) % 2) { + $pixels[] = 0; + } + + $cnt = count($pixels) / 2; + + for ($i = 0; $i < $cnt; $i++) { + $out .= chr(16 * $pixels[2 * $i] + $pixels[2 * $i + 1]); + } + + return $out; + } + + /** + * parse a full url or pathname and return an array(protocol, host, path, + * file + query + fragment) + * + * @param string $url + * @return array + */ + public static function explode_url($url) + { + $protocol = ""; + $host = ""; + $path = ""; + $file = ""; + + $arr = parse_url($url); + if ( isset($arr["scheme"]) ) { + $arr["scheme"] = mb_strtolower($arr["scheme"]); + } + + // Exclude windows drive letters... + if (isset($arr["scheme"]) && $arr["scheme"] !== "file" && strlen($arr["scheme"]) > 1) { + $protocol = $arr["scheme"] . "://"; + + if (isset($arr["user"])) { + $host .= $arr["user"]; + + if (isset($arr["pass"])) { + $host .= ":" . $arr["pass"]; + } + + $host .= "@"; + } + + if (isset($arr["host"])) { + $host .= $arr["host"]; + } + + if (isset($arr["port"])) { + $host .= ":" . $arr["port"]; + } + + if (isset($arr["path"]) && $arr["path"] !== "") { + // Do we have a trailing slash? + if ($arr["path"][mb_strlen($arr["path"]) - 1] === "/") { + $path = $arr["path"]; + $file = ""; + } else { + $path = rtrim(dirname($arr["path"]), '/\\') . "/"; + $file = basename($arr["path"]); + } + } + + if (isset($arr["query"])) { + $file .= "?" . $arr["query"]; + } + + if (isset($arr["fragment"])) { + $file .= "#" . $arr["fragment"]; + } + + } else { + + $i = mb_stripos($url, "file://"); + if ($i !== false) { + $url = mb_substr($url, $i + 7); + } + + $protocol = ""; // "file://"; ? why doesn't this work... It's because of + // network filenames like //COMPU/SHARENAME + + $host = ""; // localhost, really + $file = basename($url); + + $path = dirname($url); + + // Check that the path exists + if ($path !== false) { + $path .= '/'; + + } else { + // generate a url to access the file if no real path found. + $protocol = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https://' : 'http://'; + + $host = isset($_SERVER["HTTP_HOST"]) ? $_SERVER["HTTP_HOST"] : php_uname("n"); + + if (substr($arr["path"], 0, 1) === '/') { + $path = dirname($arr["path"]); + } else { + $path = '/' . rtrim(dirname($_SERVER["SCRIPT_NAME"]), '/') . '/' . $arr["path"]; + } + } + } + + $ret = [$protocol, $host, $path, $file, + "protocol" => $protocol, + "host" => $host, + "path" => $path, + "file" => $file]; + return $ret; + } + + /** + * Print debug messages + * + * @param string $type The type of debug messages to print + * @param string $msg The message to show + */ + public static function dompdf_debug($type, $msg) + { + global $_DOMPDF_DEBUG_TYPES, $_dompdf_show_warnings, $_dompdf_debug; + if (isset($_DOMPDF_DEBUG_TYPES[$type]) && ($_dompdf_show_warnings || $_dompdf_debug)) { + $arr = debug_backtrace(); + + echo basename($arr[0]["file"]) . " (" . $arr[0]["line"] . "): " . $arr[1]["function"] . ": "; + Helpers::pre_r($msg); + } + } + + /** + * Stores warnings in an array for display later + * This function allows warnings generated by the DomDocument parser + * and CSS loader ({@link Stylesheet}) to be captured and displayed + * later. Without this function, errors are displayed immediately and + * PDF streaming is impossible. + * @see http://www.php.net/manual/en/function.set-error_handler.php + * + * @param int $errno + * @param string $errstr + * @param string $errfile + * @param string $errline + * + * @throws Exception + */ + public static function record_warnings($errno, $errstr, $errfile, $errline) + { + // Not a warning or notice + if (!($errno & (E_WARNING | E_NOTICE | E_USER_NOTICE | E_USER_WARNING | E_STRICT | E_DEPRECATED | E_USER_DEPRECATED))) { + throw new Exception($errstr . " $errno"); + } + + global $_dompdf_warnings; + global $_dompdf_show_warnings; + + if ($_dompdf_show_warnings) { + echo $errstr . "\n"; + } + + $_dompdf_warnings[] = $errstr; + } + + /** + * @param $c + * @return bool|string + */ + public static function unichr($c) + { + if ($c <= 0x7F) { + return chr($c); + } else if ($c <= 0x7FF) { + return chr(0xC0 | $c >> 6) . chr(0x80 | $c & 0x3F); + } else if ($c <= 0xFFFF) { + return chr(0xE0 | $c >> 12) . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } else if ($c <= 0x10FFFF) { + return chr(0xF0 | $c >> 18) . chr(0x80 | $c >> 12 & 0x3F) + . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } + return false; + } + + /** + * Converts a CMYK color to RGB + * + * @param float|float[] $c + * @param float $m + * @param float $y + * @param float $k + * + * @return float[] + */ + public static function cmyk_to_rgb($c, $m = null, $y = null, $k = null) + { + if (is_array($c)) { + [$c, $m, $y, $k] = $c; + } + + $c *= 255; + $m *= 255; + $y *= 255; + $k *= 255; + + $r = (1 - round(2.55 * ($c + $k))); + $g = (1 - round(2.55 * ($m + $k))); + $b = (1 - round(2.55 * ($y + $k))); + + if ($r < 0) { + $r = 0; + } + if ($g < 0) { + $g = 0; + } + if ($b < 0) { + $b = 0; + } + + return [ + $r, $g, $b, + "r" => $r, "g" => $g, "b" => $b + ]; + } + + /** + * getimagesize doesn't give a good size for 32bit BMP image v5 + * + * @param string $filename + * @param resource $context + * @return array The same format as getimagesize($filename) + */ + public static function dompdf_getimagesize($filename, $context = null) + { + static $cache = []; + + if (isset($cache[$filename])) { + return $cache[$filename]; + } + + [$width, $height, $type] = getimagesize($filename); + + // Custom types + $types = [ + IMAGETYPE_JPEG => "jpeg", + IMAGETYPE_GIF => "gif", + IMAGETYPE_BMP => "bmp", + IMAGETYPE_PNG => "png", + ]; + + $type = isset($types[$type]) ? $types[$type] : null; + + if ($width == null || $height == null) { + [$data, $headers] = Helpers::getFileContent($filename, $context); + + if (!empty($data)) { + if (substr($data, 0, 2) === "BM") { + $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data); + $width = (int)$meta['width']; + $height = (int)$meta['height']; + $type = "bmp"; + } else { + if (strpos($data, "loadFile($filename); + + [$width, $height] = $doc->getDimensions(); + $type = "svg"; + } + } + } + } + + return $cache[$filename] = [$width, $height, $type]; + } + + /** + * Credit goes to mgutt + * http://www.programmierer-forum.de/function-imagecreatefrombmp-welche-variante-laeuft-t143137.htm + * Modified by Fabien Menager to support RGB555 BMP format + */ + public static function imagecreatefrombmp($filename, $context = null) + { + if (!function_exists("imagecreatetruecolor")) { + trigger_error("The PHP GD extension is required, but is not installed.", E_ERROR); + return false; + } + + // version 1.00 + if (!($fh = fopen($filename, 'rb'))) { + trigger_error('imagecreatefrombmp: Can not open ' . $filename, E_USER_WARNING); + return false; + } + + $bytes_read = 0; + + // read file header + $meta = unpack('vtype/Vfilesize/Vreserved/Voffset', fread($fh, 14)); + + // check for bitmap + if ($meta['type'] != 19778) { + trigger_error('imagecreatefrombmp: ' . $filename . ' is not a bitmap!', E_USER_WARNING); + return false; + } + + // read image header + $meta += unpack('Vheadersize/Vwidth/Vheight/vplanes/vbits/Vcompression/Vimagesize/Vxres/Vyres/Vcolors/Vimportant', fread($fh, 40)); + $bytes_read += 40; + + // read additional bitfield header + if ($meta['compression'] == 3) { + $meta += unpack('VrMask/VgMask/VbMask', fread($fh, 12)); + $bytes_read += 12; + } + + // set bytes and padding + $meta['bytes'] = $meta['bits'] / 8; + $meta['decal'] = 4 - (4 * (($meta['width'] * $meta['bytes'] / 4) - floor($meta['width'] * $meta['bytes'] / 4))); + if ($meta['decal'] == 4) { + $meta['decal'] = 0; + } + + // obtain imagesize + if ($meta['imagesize'] < 1) { + $meta['imagesize'] = $meta['filesize'] - $meta['offset']; + // in rare cases filesize is equal to offset so we need to read physical size + if ($meta['imagesize'] < 1) { + $meta['imagesize'] = @filesize($filename) - $meta['offset']; + if ($meta['imagesize'] < 1) { + trigger_error('imagecreatefrombmp: Can not obtain filesize of ' . $filename . '!', E_USER_WARNING); + return false; + } + } + } + + // calculate colors + $meta['colors'] = !$meta['colors'] ? pow(2, $meta['bits']) : $meta['colors']; + + // read color palette + $palette = []; + if ($meta['bits'] < 16) { + $palette = unpack('l' . $meta['colors'], fread($fh, $meta['colors'] * 4)); + // in rare cases the color value is signed + if ($palette[1] < 0) { + foreach ($palette as $i => $color) { + $palette[$i] = $color + 16777216; + } + } + } + + // ignore extra bitmap headers + if ($meta['headersize'] > $bytes_read) { + fread($fh, $meta['headersize'] - $bytes_read); + } + + // create gd image + $im = imagecreatetruecolor($meta['width'], $meta['height']); + $data = fread($fh, $meta['imagesize']); + + // uncompress data + switch ($meta['compression']) { + case 1: + $data = Helpers::rle8_decode($data, $meta['width']); + break; + case 2: + $data = Helpers::rle4_decode($data, $meta['width']); + break; + } + + $p = 0; + $vide = chr(0); + $y = $meta['height'] - 1; + $error = 'imagecreatefrombmp: ' . $filename . ' has not enough data!'; + + // loop through the image data beginning with the lower left corner + while ($y >= 0) { + $x = 0; + while ($x < $meta['width']) { + switch ($meta['bits']) { + case 32: + case 24: + if (!($part = substr($data, $p, 3 /*$meta['bytes']*/))) { + trigger_error($error, E_USER_WARNING); + return $im; + } + $color = unpack('V', $part . $vide); + break; + case 16: + if (!($part = substr($data, $p, 2 /*$meta['bytes']*/))) { + trigger_error($error, E_USER_WARNING); + return $im; + } + $color = unpack('v', $part); + + if (empty($meta['rMask']) || $meta['rMask'] != 0xf800) { + $color[1] = (($color[1] & 0x7c00) >> 7) * 65536 + (($color[1] & 0x03e0) >> 2) * 256 + (($color[1] & 0x001f) << 3); // 555 + } else { + $color[1] = (($color[1] & 0xf800) >> 8) * 65536 + (($color[1] & 0x07e0) >> 3) * 256 + (($color[1] & 0x001f) << 3); // 565 + } + break; + case 8: + $color = unpack('n', $vide . substr($data, $p, 1)); + $color[1] = $palette[$color[1] + 1]; + break; + case 4: + $color = unpack('n', $vide . substr($data, floor($p), 1)); + $color[1] = ($p * 2) % 2 == 0 ? $color[1] >> 4 : $color[1] & 0x0F; + $color[1] = $palette[$color[1] + 1]; + break; + case 1: + $color = unpack('n', $vide . substr($data, floor($p), 1)); + switch (($p * 8) % 8) { + case 0: + $color[1] = $color[1] >> 7; + break; + case 1: + $color[1] = ($color[1] & 0x40) >> 6; + break; + case 2: + $color[1] = ($color[1] & 0x20) >> 5; + break; + case 3: + $color[1] = ($color[1] & 0x10) >> 4; + break; + case 4: + $color[1] = ($color[1] & 0x8) >> 3; + break; + case 5: + $color[1] = ($color[1] & 0x4) >> 2; + break; + case 6: + $color[1] = ($color[1] & 0x2) >> 1; + break; + case 7: + $color[1] = ($color[1] & 0x1); + break; + } + $color[1] = $palette[$color[1] + 1]; + break; + default: + trigger_error('imagecreatefrombmp: ' . $filename . ' has ' . $meta['bits'] . ' bits and this is not supported!', E_USER_WARNING); + return false; + } + imagesetpixel($im, $x, $y, $color[1]); + $x++; + $p += $meta['bytes']; + } + $y--; + $p += $meta['decal']; + } + fclose($fh); + return $im; + } + + /** + * Gets the content of the file at the specified path using one of + * the following methods, in preferential order: + * - file_get_contents: if allow_url_fopen is true or the file is local + * - curl: if allow_url_fopen is false and curl is available + * + * @param string $uri + * @param resource $context (ignored if curl is used) + * @param int $offset + * @param int $maxlen (ignored if curl is used) + * @return string[] + */ + public static function getFileContent($uri, $context = null, $offset = 0, $maxlen = null) + { + $content = null; + $headers = null; + [$proto, $host, $path, $file] = Helpers::explode_url($uri); + $is_local_path = ($proto == '' || $proto === 'file://'); + + set_error_handler([self::class, 'record_warnings']); + + try { + if ($is_local_path || ini_get('allow_url_fopen')) { + if ($is_local_path === false) { + $uri = Helpers::encodeURI($uri); + } + if (isset($maxlen)) { + $result = file_get_contents($uri, null, $context, $offset, $maxlen); + } else { + $result = file_get_contents($uri, null, $context, $offset); + } + if ($result !== false) { + $content = $result; + } + if (isset($http_response_header)) { + $headers = $http_response_header; + } + + } elseif (function_exists('curl_exec')) { + $curl = curl_init($uri); + + //TODO: use $context to define additional curl options + curl_setopt($curl, CURLOPT_TIMEOUT, 10); + curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); + curl_setopt($curl, CURLOPT_HEADER, true); + if ($offset > 0) { + curl_setopt($curl, CURLOPT_RESUME_FROM, $offset); + } + + $data = curl_exec($curl); + + if ($data !== false && !curl_errno($curl)) { + switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) { + case 200: + $raw_headers = substr($data, 0, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); + $headers = preg_split("/[\n\r]+/", trim($raw_headers)); + $content = substr($data, curl_getinfo($curl, CURLINFO_HEADER_SIZE)); + break; + } + } + curl_close($curl); + } + } finally { + restore_error_handler(); + } + + return [$content, $headers]; + } + + public static function mb_ucwords($str) { + $max_len = mb_strlen($str); + if ($max_len === 1) { + return mb_strtoupper($str); + } + + $str = mb_strtoupper(mb_substr($str, 0, 1)) . mb_substr($str, 1); + + foreach ([' ', '.', ',', '!', '?', '-', '+'] as $s) { + $pos = 0; + while (($pos = mb_strpos($str, $s, $pos)) !== false) { + $pos++; + // Nothing to do if the separator is the last char of the string + if ($pos !== false && $pos < $max_len) { + // If the char we want to upper is the last char there is nothing to append behind + if ($pos + 1 < $max_len) { + $str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1)) . mb_substr($str, $pos + 1); + } else { + $str = mb_substr($str, 0, $pos) . mb_strtoupper(mb_substr($str, $pos, 1)); + } + } + } + } + + return $str; + } +} diff --git a/vendor/dompdf/dompdf/src/Image/Cache.php b/vendor/dompdf/dompdf/src/Image/Cache.php new file mode 100644 index 0000000..9f9130f --- /dev/null +++ b/vendor/dompdf/dompdf/src/Image/Cache.php @@ -0,0 +1,208 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Image; + +use Dompdf\Dompdf; +use Dompdf\Helpers; +use Dompdf\Exception\ImageException; + +/** + * Static class that resolves image urls and downloads and caches + * remote images if required. + * + * @package dompdf + */ +class Cache +{ + /** + * Array of downloaded images. Cached so that identical images are + * not needlessly downloaded. + * + * @var array + */ + protected static $_cache = []; + + /** + * The url to the "broken image" used when images can't be loaded + * + * @var string + */ + public static $broken_image = "data:image/svg+xml;charset=utf8,%3C?xml version='1.0'?%3E%3Csvg width='64' height='64' xmlns='http://www.w3.org/2000/svg'%3E%3Cg%3E%3Crect stroke='%23666666' id='svg_1' height='60.499994' width='60.166667' y='1.666669' x='1.999998' stroke-width='1.5' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_3' y2='59.333253' x2='59.749916' y1='4.333415' x1='4.250079' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3Cline stroke-linecap='null' stroke-linejoin='null' id='svg_4' y2='59.999665' x2='4.062838' y1='3.750342' x1='60.062164' stroke-width='1.5' stroke='%23999999' fill='none'/%3E%3C/g%3E%3C/svg%3E"; + + public static $error_message = "Image not found or type unknown"; + + /** + * Current dompdf instance + * + * @var Dompdf + */ + protected static $_dompdf; + + /** + * Resolve and fetch an image for use. + * + * @param string $url The url of the image + * @param string $protocol Default protocol if none specified in $url + * @param string $host Default host if none specified in $url + * @param string $base_path Default path if none specified in $url + * @param Dompdf $dompdf The Dompdf instance + * + * @throws ImageException + * @return array An array with two elements: The local path to the image and the image extension + */ + static function resolve_url($url, $protocol, $host, $base_path, Dompdf $dompdf) + { + self::$_dompdf = $dompdf; + + $protocol = mb_strtolower($protocol); + $parsed_url = Helpers::explode_url($url); + $message = null; + + $remote = ($protocol && $protocol !== "file://") || ($parsed_url['protocol'] != ""); + + $data_uri = strpos($parsed_url['protocol'], "data:") === 0; + $full_url = null; + $enable_remote = $dompdf->getOptions()->getIsRemoteEnabled(); + + try { + + // Remote not allowed and is not DataURI + if (!$enable_remote && $remote && !$data_uri) { + throw new ImageException("Remote file access is disabled.", E_WARNING); + } + + // remote allowed or DataURI + if (($enable_remote && $remote) || $data_uri) { + // Download remote files to a temporary directory + $full_url = Helpers::build_url($protocol, $host, $base_path, $url); + + // From cache + if (isset(self::$_cache[$full_url])) { + $resolved_url = self::$_cache[$full_url]; + } // From remote + else { + $tmp_dir = $dompdf->getOptions()->getTempDir(); + if (($resolved_url = @tempnam($tmp_dir, "ca_dompdf_img_")) === false) { + throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); + } + $image = ""; + + if ($data_uri) { + if ($parsed_data_uri = Helpers::parse_data_uri($url)) { + $image = $parsed_data_uri['data']; + } + } else { + list($image, $http_response_header) = Helpers::getFileContent($full_url, $dompdf->getHttpContext()); + } + + // Image not found or invalid + if (empty($image)) { + $msg = ($data_uri ? "Data-URI could not be parsed" : "Image not found"); + throw new ImageException($msg, E_WARNING); + } // Image found, put in cache and process + else { + //e.g. fetch.php?media=url.jpg&cache=1 + //- Image file name might be one of the dynamic parts of the url, don't strip off! + //- a remote url does not need to have a file extension at all + //- local cached file does not have a matching file extension + //Therefore get image type from the content + if (@file_put_contents($resolved_url, $image) === false) { + throw new ImageException("Unable to create temporary image in " . $tmp_dir, E_WARNING); + } + } + } + } // Not remote, local image + else { + $resolved_url = Helpers::build_url($protocol, $host, $base_path, $url); + + if ($protocol == "" || $protocol === "file://") { + $realfile = realpath($resolved_url); + + $rootDir = realpath($dompdf->getOptions()->getRootDir()); + if (strpos($realfile, $rootDir) !== 0) { + $chroot = realpath($dompdf->getOptions()->getChroot()); + if (!$chroot || strpos($realfile, $chroot) !== 0) { + throw new ImageException("Permission denied on $resolved_url. The file could not be found under the directory specified by Options::chroot.", E_WARNING); + } + } + + if (!$realfile) { + throw new ImageException("File '$realfile' not found.", E_WARNING); + } + + $resolved_url = $realfile; + } + } + + // Check if the local file is readable + if (!is_readable($resolved_url) || !filesize($resolved_url)) { + throw new ImageException("Image not readable or empty", E_WARNING); + } // Check is the file is an image + else { + list($width, $height, $type) = Helpers::dompdf_getimagesize($resolved_url, $dompdf->getHttpContext()); + + // Known image type + if ($width && $height && in_array($type, ["gif", "png", "jpeg", "bmp", "svg"])) { + //Don't put replacement image into cache - otherwise it will be deleted on cache cleanup. + //Only execute on successful caching of remote image. + if ($enable_remote && $remote || $data_uri) { + self::$_cache[$full_url] = $resolved_url; + } + } // Unknown image type + else { + throw new ImageException("Image type unknown", E_WARNING); + } + } + } catch (ImageException $e) { + $resolved_url = self::$broken_image; + $type = "png"; + $message = self::$error_message; + Helpers::record_warnings($e->getCode(), $e->getMessage() . " \n $url", $e->getFile(), $e->getLine()); + } + + return [$resolved_url, $type, $message]; + } + + /** + * Unlink all cached images (i.e. temporary images either downloaded + * or converted) + */ + static function clear() + { + if (empty(self::$_cache) || self::$_dompdf->getOptions()->getDebugKeepTemp()) { + return; + } + + foreach (self::$_cache as $file) { + if (self::$_dompdf->getOptions()->getDebugPng()) { + print "[clear unlink $file]"; + } + unlink($file); + } + + self::$_cache = []; + } + + static function detect_type($file, $context = null) + { + list(, , $type) = Helpers::dompdf_getimagesize($file, $context); + + return $type; + } + + static function is_broken($url) + { + return $url === self::$broken_image; + } +} + +if (file_exists(realpath(__DIR__ . "/../../lib/res/broken_image.svg"))) { + Cache::$broken_image = realpath(__DIR__ . "/../../lib/res/broken_image.svg"); +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/JavascriptEmbedder.php b/vendor/dompdf/dompdf/src/JavascriptEmbedder.php new file mode 100644 index 0000000..7a8fce5 --- /dev/null +++ b/vendor/dompdf/dompdf/src/JavascriptEmbedder.php @@ -0,0 +1,52 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf; + +/** + * Embeds Javascript into the PDF document + * + * @package dompdf + */ +class JavascriptEmbedder +{ + + /** + * @var Dompdf + */ + protected $_dompdf; + + /** + * JavascriptEmbedder constructor. + * + * @param Dompdf $dompdf + */ + public function __construct(Dompdf $dompdf) + { + $this->_dompdf = $dompdf; + } + + /** + * @param $script + */ + public function insert($script) + { + $this->_dompdf->getCanvas()->javascript($script); + } + + /** + * @param Frame $frame + */ + public function render(Frame $frame) + { + if (!$this->_dompdf->getOptions()->getIsJavascriptEnabled()) { + return; + } + + $this->insert($frame->get_node()->nodeValue); + } +} diff --git a/vendor/dompdf/dompdf/src/LineBox.php b/vendor/dompdf/dompdf/src/LineBox.php new file mode 100644 index 0000000..68e1f70 --- /dev/null +++ b/vendor/dompdf/dompdf/src/LineBox.php @@ -0,0 +1,303 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf; + +use Dompdf\FrameDecorator\Block; +use Dompdf\FrameDecorator\Page; + +/** + * The line box class + * + * This class represents a line box + * http://www.w3.org/TR/CSS2/visuren.html#line-box + * + * @package dompdf + */ +class LineBox +{ + + /** + * @var Block + */ + protected $_block_frame; + + /** + * @var Frame[] + */ + protected $_frames = []; + + /** + * @var integer + */ + public $wc = 0; + + /** + * @var float + */ + public $y = null; + + /** + * @var float + */ + public $w = 0.0; + + /** + * @var float + */ + public $h = 0.0; + + /** + * @var float + */ + public $left = 0.0; + + /** + * @var float + */ + public $right = 0.0; + + /** + * @var Frame + */ + public $tallest_frame = null; + + /** + * @var bool[] + */ + public $floating_blocks = []; + + /** + * @var bool + */ + public $br = false; + + /** + * Class constructor + * + * @param Block $frame the Block containing this line + * @param int $y + */ + public function __construct(Block $frame, $y = 0) + { + $this->_block_frame = $frame; + $this->_frames = []; + $this->y = $y; + + $this->get_float_offsets(); + } + + /** + * Returns the floating elements inside the first floating parent + * + * @param Page $root + * + * @return Frame[] + */ + public function get_floats_inside(Page $root) + { + $floating_frames = $root->get_floating_frames(); + + if (count($floating_frames) == 0) { + return $floating_frames; + } + + // Find nearest floating element + $p = $this->_block_frame; + while ($p->get_style()->float === "none") { + $parent = $p->get_parent(); + + if (!$parent) { + break; + } + + $p = $parent; + } + + if ($p == $root) { + return $floating_frames; + } + + $parent = $p; + + $childs = []; + + foreach ($floating_frames as $_floating) { + $p = $_floating->get_parent(); + + while (($p = $p->get_parent()) && $p !== $parent); + + if ($p) { + $childs[] = $p; + } + } + + return $childs; + } + + /** + * + */ + public function get_float_offsets() + { + static $anti_infinite_loop = 10000; // FIXME smelly hack + + $reflower = $this->_block_frame->get_reflower(); + + if (!$reflower) { + return; + } + + $cb_w = null; + + $block = $this->_block_frame; + $root = $block->get_root(); + + if (!$root) { + return; + } + + $style = $this->_block_frame->get_style(); + $floating_frames = $this->get_floats_inside($root); + $inside_left_floating_width = 0; + $inside_right_floating_width = 0; + $outside_left_floating_width = 0; + $outside_right_floating_width = 0; + + foreach ($floating_frames as $child_key => $floating_frame) { + $floating_frame_parent = $floating_frame->get_parent(); + $id = $floating_frame->get_id(); + + if (isset($this->floating_blocks[$id])) { + continue; + } + + $float = $floating_frame->get_style()->float; + $floating_width = $floating_frame->get_margin_width(); + + if (!$cb_w) { + $cb_w = $floating_frame->get_containing_block("w"); + } + + $line_w = $this->get_width(); + + if (!$floating_frame->_float_next_line && ($cb_w <= $line_w + $floating_width) && ($cb_w > $line_w)) { + $floating_frame->_float_next_line = true; + continue; + } + + // If the child is still shifted by the floating element + if ($anti_infinite_loop-- > 0 && + $floating_frame->get_position("y") + $floating_frame->get_margin_height() >= $this->y && + $block->get_position("x") + $block->get_margin_width() >= $floating_frame->get_position("x") + ) { + if ($float === "left") { + if ($floating_frame_parent === $this->_block_frame) { + $inside_left_floating_width += $floating_width; + } else { + $outside_left_floating_width += $floating_width; + } + } elseif ($float === "right") { + if ($floating_frame_parent === $this->_block_frame) { + $inside_right_floating_width += $floating_width; + } else { + $outside_right_floating_width += $floating_width; + } + } + + $this->floating_blocks[$id] = true; + } // else, the floating element won't shift anymore + else { + $root->remove_floating_frame($child_key); + } + } + + $this->left += $inside_left_floating_width; + if ($outside_left_floating_width > 0 && $outside_left_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_left))) { + $this->left += $outside_left_floating_width - (float)$style->length_in_pt($style->margin_left) - (float)$style->length_in_pt($style->padding_left); + } + $this->right += $inside_right_floating_width; + if ($outside_right_floating_width > 0 && $outside_right_floating_width > ((float)$style->length_in_pt($style->margin_left) + (float)$style->length_in_pt($style->padding_right))) { + $this->right += $outside_right_floating_width - (float)$style->length_in_pt($style->margin_right) - (float)$style->length_in_pt($style->padding_right); + } + } + + /** + * @return float + */ + public function get_width() + { + return $this->left + $this->w + $this->right; + } + + /** + * @return Block + */ + public function get_block_frame() + { + return $this->_block_frame; + } + + /** + * @return Frame[] + */ + function &get_frames() + { + return $this->_frames; + } + + /** + * @param Frame $frame + */ + public function add_frame(Frame $frame) + { + $this->_frames[] = $frame; + } + + /** + * Recalculate LineBox width based on the contained frames total width. + * + * @return float + */ + public function recalculate_width() + { + $width = 0; + + foreach ($this->get_frames() as $frame) { + $width += $frame->calculate_auto_width(); + } + + return $this->w = $width; + } + + /** + * @return string + */ + public function __toString() + { + $props = ["wc", "y", "w", "h", "left", "right", "br"]; + $s = ""; + foreach ($props as $prop) { + $s .= "$prop: " . $this->$prop . "\n"; + } + $s .= count($this->_frames) . " frames\n"; + + return $s; + } + /*function __get($prop) { + if (!isset($this->{"_$prop"})) return; + return $this->{"_$prop"}; + }*/ +} + +/* +class LineBoxList implements Iterator { + private $_p = 0; + private $_lines = array(); + +} +*/ diff --git a/vendor/dompdf/dompdf/src/Options.php b/vendor/dompdf/dompdf/src/Options.php new file mode 100644 index 0000000..b46c396 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Options.php @@ -0,0 +1,1005 @@ + ... tags. + * + * ==== IMPORTANT ==== + * Enabling this for documents you do not trust (e.g. arbitrary remote html + * pages) is a security risk. Embedded scripts are run with the same level of + * system access available to dompdf. Set this option to false (recommended) + * if you wish to process untrusted documents. + * + * This setting may increase the risk of system exploit. Do not change + * this settings without understanding the consequences. Additional + * documentation is available on the dompdf wiki at: + * https://github.com/dompdf/dompdf/wiki + * + * @var bool + */ + private $isPhpEnabled = false; + + /** + * Enable remote file access + * + * If this setting is set to true, DOMPDF will access remote sites for + * images and CSS files as required. + * + * ==== IMPORTANT ==== + * This can be a security risk, in particular in combination with isPhpEnabled and + * allowing remote html code to be passed to $dompdf = new DOMPDF(); $dompdf->load_html(...); + * This allows anonymous users to download legally doubtful internet content which on + * tracing back appears to being downloaded by your server, or allows malicious php code + * in remote html pages to be executed by your server with your account privileges. + * + * This setting may increase the risk of system exploit. Do not change + * this settings without understanding the consequences. Additional + * documentation is available on the dompdf wiki at: + * https://github.com/dompdf/dompdf/wiki + * + * @var bool + */ + private $isRemoteEnabled = false; + + /** + * Enable inline Javascript + * + * If this setting is set to true then DOMPDF will automatically insert + * JavaScript code contained within tags. + * + * @var bool + */ + private $isJavascriptEnabled = true; + + /** + * Use the more-than-experimental HTML5 Lib parser + * + * @var bool + */ + private $isHtml5ParserEnabled = false; + + /** + * Whether to enable font subsetting or not. + * + * @var bool + */ + private $isFontSubsettingEnabled = true; + + /** + * @var bool + */ + private $debugPng = false; + + /** + * @var bool + */ + private $debugKeepTemp = false; + + /** + * @var bool + */ + private $debugCss = false; + + /** + * @var bool + */ + private $debugLayout = false; + + /** + * @var bool + */ + private $debugLayoutLines = true; + + /** + * @var bool + */ + private $debugLayoutBlocks = true; + + /** + * @var bool + */ + private $debugLayoutInline = true; + + /** + * @var bool + */ + private $debugLayoutPaddingBox = true; + + /** + * The PDF rendering backend to use + * + * Valid settings are 'PDFLib', 'CPDF', 'GD', and 'auto'. 'auto' will + * look for PDFLib and use it if found, or if not it will fall back on + * CPDF. 'GD' renders PDFs to graphic files. {@link Dompdf\CanvasFactory} + * ultimately determines which rendering class to instantiate + * based on this setting. + * + * @var string + */ + private $pdfBackend = "CPDF"; + + /** + * PDFlib license key + * + * If you are using a licensed, commercial version of PDFlib, specify + * your license key here. If you are using PDFlib-Lite or are evaluating + * the commercial version of PDFlib, comment out this setting. + * + * @link http://www.pdflib.com + * + * If pdflib present in web server and auto or selected explicitly above, + * a real license code must exist! + * + * @var string + */ + private $pdflibLicense = ""; + + /** + * @var string + * @deprecated + */ + private $adminUsername = "user"; + + /** + * @var string + * @deprecated + */ + private $adminPassword = "password"; + + /** + * @param array $attributes + */ + public function __construct(array $attributes = null) + { + $this->setChroot(realpath(__DIR__ . "/../")); + $this->setRootDir($this->getChroot()); + $this->setTempDir(sys_get_temp_dir()); + $this->setFontDir($this->chroot . "/lib/fonts"); + $this->setFontCache($this->getFontDir()); + $this->setLogOutputFile($this->getTempDir() . "/log.htm"); + + if (null !== $attributes) { + $this->set($attributes); + } + } + + /** + * @param array|string $attributes + * @param null|mixed $value + * @return $this + */ + public function set($attributes, $value = null) + { + if (!is_array($attributes)) { + $attributes = [$attributes => $value]; + } + foreach ($attributes as $key => $value) { + if ($key === 'tempDir' || $key === 'temp_dir') { + $this->setTempDir($value); + } elseif ($key === 'fontDir' || $key === 'font_dir') { + $this->setFontDir($value); + } elseif ($key === 'fontCache' || $key === 'font_cache') { + $this->setFontCache($value); + } elseif ($key === 'chroot') { + $this->setChroot($value); + } elseif ($key === 'logOutputFile' || $key === 'log_output_file') { + $this->setLogOutputFile($value); + } elseif ($key === 'defaultMediaType' || $key === 'default_media_type') { + $this->setDefaultMediaType($value); + } elseif ($key === 'defaultPaperSize' || $key === 'default_paper_size') { + $this->setDefaultPaperSize($value); + } elseif ($key === 'defaultPaperOrientation' || $key === 'default_paper_orientation') { + $this->setDefaultPaperOrientation($value); + } elseif ($key === 'defaultFont' || $key === 'default_font') { + $this->setDefaultFont($value); + } elseif ($key === 'dpi') { + $this->setDpi($value); + } elseif ($key === 'fontHeightRatio' || $key === 'font_height_ratio') { + $this->setFontHeightRatio($value); + } elseif ($key === 'isPhpEnabled' || $key === 'is_php_enabled' || $key === 'enable_php') { + $this->setIsPhpEnabled($value); + } elseif ($key === 'isRemoteEnabled' || $key === 'is_remote_enabled' || $key === 'enable_remote') { + $this->setIsRemoteEnabled($value); + } elseif ($key === 'isJavascriptEnabled' || $key === 'is_javascript_enabled' || $key === 'enable_javascript') { + $this->setIsJavascriptEnabled($value); + } elseif ($key === 'isHtml5ParserEnabled' || $key === 'is_html5_parser_enabled' || $key === 'enable_html5_parser') { + $this->setIsHtml5ParserEnabled($value); + } elseif ($key === 'isFontSubsettingEnabled' || $key === 'is_font_subsetting_enabled' || $key === 'enable_font_subsetting') { + $this->setIsFontSubsettingEnabled($value); + } elseif ($key === 'debugPng' || $key === 'debug_png') { + $this->setDebugPng($value); + } elseif ($key === 'debugKeepTemp' || $key === 'debug_keep_temp') { + $this->setDebugKeepTemp($value); + } elseif ($key === 'debugCss' || $key === 'debug_css') { + $this->setDebugCss($value); + } elseif ($key === 'debugLayout' || $key === 'debug_layout') { + $this->setDebugLayout($value); + } elseif ($key === 'debugLayoutLines' || $key === 'debug_layout_lines') { + $this->setDebugLayoutLines($value); + } elseif ($key === 'debugLayoutBlocks' || $key === 'debug_layout_blocks') { + $this->setDebugLayoutBlocks($value); + } elseif ($key === 'debugLayoutInline' || $key === 'debug_layout_inline') { + $this->setDebugLayoutInline($value); + } elseif ($key === 'debugLayoutPaddingBox' || $key === 'debug_layout_padding_box') { + $this->setDebugLayoutPaddingBox($value); + } elseif ($key === 'pdfBackend' || $key === 'pdf_backend') { + $this->setPdfBackend($value); + } elseif ($key === 'pdflibLicense' || $key === 'pdflib_license') { + $this->setPdflibLicense($value); + } elseif ($key === 'adminUsername' || $key === 'admin_username') { + $this->setAdminUsername($value); + } elseif ($key === 'adminPassword' || $key === 'admin_password') { + $this->setAdminPassword($value); + } + } + return $this; + } + + /** + * @param string $key + * @return mixed + */ + public function get($key) + { + if ($key === 'tempDir' || $key === 'temp_dir') { + return $this->getTempDir(); + } elseif ($key === 'fontDir' || $key === 'font_dir') { + return $this->getFontDir(); + } elseif ($key === 'fontCache' || $key === 'font_cache') { + return $this->getFontCache(); + } elseif ($key === 'chroot') { + return $this->getChroot(); + } elseif ($key === 'logOutputFile' || $key === 'log_output_file') { + return $this->getLogOutputFile(); + } elseif ($key === 'defaultMediaType' || $key === 'default_media_type') { + return $this->getDefaultMediaType(); + } elseif ($key === 'defaultPaperSize' || $key === 'default_paper_size') { + return $this->getDefaultPaperSize(); + } elseif ($key === 'defaultPaperOrientation' || $key === 'default_paper_orientation') { + return $this->getDefaultPaperOrientation(); + } elseif ($key === 'defaultFont' || $key === 'default_font') { + return $this->getDefaultFont(); + } elseif ($key === 'dpi') { + return $this->getDpi(); + } elseif ($key === 'fontHeightRatio' || $key === 'font_height_ratio') { + return $this->getFontHeightRatio(); + } elseif ($key === 'isPhpEnabled' || $key === 'is_php_enabled' || $key === 'enable_php') { + return $this->getIsPhpEnabled(); + } elseif ($key === 'isRemoteEnabled' || $key === 'is_remote_enabled' || $key === 'enable_remote') { + return $this->getIsRemoteEnabled(); + } elseif ($key === 'isJavascriptEnabled' || $key === 'is_javascript_enabled' || $key === 'enable_javascript') { + return $this->getIsJavascriptEnabled(); + } elseif ($key === 'isHtml5ParserEnabled' || $key === 'is_html5_parser_enabled' || $key === 'enable_html5_parser') { + return $this->getIsHtml5ParserEnabled(); + } elseif ($key === 'isFontSubsettingEnabled' || $key === 'is_font_subsetting_enabled' || $key === 'enable_font_subsetting') { + return $this->getIsFontSubsettingEnabled(); + } elseif ($key === 'debugPng' || $key === 'debug_png') { + return $this->getDebugPng(); + } elseif ($key === 'debugKeepTemp' || $key === 'debug_keep_temp') { + return $this->getDebugKeepTemp(); + } elseif ($key === 'debugCss' || $key === 'debug_css') { + return $this->getDebugCss(); + } elseif ($key === 'debugLayout' || $key === 'debug_layout') { + return $this->getDebugLayout(); + } elseif ($key === 'debugLayoutLines' || $key === 'debug_layout_lines') { + return $this->getDebugLayoutLines(); + } elseif ($key === 'debugLayoutBlocks' || $key === 'debug_layout_blocks') { + return $this->getDebugLayoutBlocks(); + } elseif ($key === 'debugLayoutInline' || $key === 'debug_layout_inline') { + return $this->getDebugLayoutInline(); + } elseif ($key === 'debugLayoutPaddingBox' || $key === 'debug_layout_padding_box') { + return $this->getDebugLayoutPaddingBox(); + } elseif ($key === 'pdfBackend' || $key === 'pdf_backend') { + return $this->getPdfBackend(); + } elseif ($key === 'pdflibLicense' || $key === 'pdflib_license') { + return $this->getPdflibLicense(); + } elseif ($key === 'adminUsername' || $key === 'admin_username') { + return $this->getAdminUsername(); + } elseif ($key === 'adminPassword' || $key === 'admin_password') { + return $this->getAdminPassword(); + } + return null; + } + + /** + * @param string $adminPassword + * @return $this + */ + public function setAdminPassword($adminPassword) + { + $this->adminPassword = $adminPassword; + return $this; + } + + /** + * @return string + */ + public function getAdminPassword() + { + return $this->adminPassword; + } + + /** + * @param string $adminUsername + * @return $this + */ + public function setAdminUsername($adminUsername) + { + $this->adminUsername = $adminUsername; + return $this; + } + + /** + * @return string + */ + public function getAdminUsername() + { + return $this->adminUsername; + } + + /** + * @param string $pdfBackend + * @return $this + */ + public function setPdfBackend($pdfBackend) + { + $this->pdfBackend = $pdfBackend; + return $this; + } + + /** + * @return string + */ + public function getPdfBackend() + { + return $this->pdfBackend; + } + + /** + * @param string $pdflibLicense + * @return $this + */ + public function setPdflibLicense($pdflibLicense) + { + $this->pdflibLicense = $pdflibLicense; + return $this; + } + + /** + * @return string + */ + public function getPdflibLicense() + { + return $this->pdflibLicense; + } + + /** + * @param string $chroot + * @return $this + */ + public function setChroot($chroot) + { + $this->chroot = $chroot; + return $this; + } + + /** + * @return string + */ + public function getChroot() + { + return $this->chroot; + } + + /** + * @param boolean $debugCss + * @return $this + */ + public function setDebugCss($debugCss) + { + $this->debugCss = $debugCss; + return $this; + } + + /** + * @return boolean + */ + public function getDebugCss() + { + return $this->debugCss; + } + + /** + * @param boolean $debugKeepTemp + * @return $this + */ + public function setDebugKeepTemp($debugKeepTemp) + { + $this->debugKeepTemp = $debugKeepTemp; + return $this; + } + + /** + * @return boolean + */ + public function getDebugKeepTemp() + { + return $this->debugKeepTemp; + } + + /** + * @param boolean $debugLayout + * @return $this + */ + public function setDebugLayout($debugLayout) + { + $this->debugLayout = $debugLayout; + return $this; + } + + /** + * @return boolean + */ + public function getDebugLayout() + { + return $this->debugLayout; + } + + /** + * @param boolean $debugLayoutBlocks + * @return $this + */ + public function setDebugLayoutBlocks($debugLayoutBlocks) + { + $this->debugLayoutBlocks = $debugLayoutBlocks; + return $this; + } + + /** + * @return boolean + */ + public function getDebugLayoutBlocks() + { + return $this->debugLayoutBlocks; + } + + /** + * @param boolean $debugLayoutInline + * @return $this + */ + public function setDebugLayoutInline($debugLayoutInline) + { + $this->debugLayoutInline = $debugLayoutInline; + return $this; + } + + /** + * @return boolean + */ + public function getDebugLayoutInline() + { + return $this->debugLayoutInline; + } + + /** + * @param boolean $debugLayoutLines + * @return $this + */ + public function setDebugLayoutLines($debugLayoutLines) + { + $this->debugLayoutLines = $debugLayoutLines; + return $this; + } + + /** + * @return boolean + */ + public function getDebugLayoutLines() + { + return $this->debugLayoutLines; + } + + /** + * @param boolean $debugLayoutPaddingBox + * @return $this + */ + public function setDebugLayoutPaddingBox($debugLayoutPaddingBox) + { + $this->debugLayoutPaddingBox = $debugLayoutPaddingBox; + return $this; + } + + /** + * @return boolean + */ + public function getDebugLayoutPaddingBox() + { + return $this->debugLayoutPaddingBox; + } + + /** + * @param boolean $debugPng + * @return $this + */ + public function setDebugPng($debugPng) + { + $this->debugPng = $debugPng; + return $this; + } + + /** + * @return boolean + */ + public function getDebugPng() + { + return $this->debugPng; + } + + /** + * @param string $defaultFont + * @return $this + */ + public function setDefaultFont($defaultFont) + { + $this->defaultFont = $defaultFont; + return $this; + } + + /** + * @return string + */ + public function getDefaultFont() + { + return $this->defaultFont; + } + + /** + * @param string $defaultMediaType + * @return $this + */ + public function setDefaultMediaType($defaultMediaType) + { + $this->defaultMediaType = $defaultMediaType; + return $this; + } + + /** + * @return string + */ + public function getDefaultMediaType() + { + return $this->defaultMediaType; + } + + /** + * @param string $defaultPaperSize + * @return $this + */ + public function setDefaultPaperSize($defaultPaperSize) + { + $this->defaultPaperSize = $defaultPaperSize; + return $this; + } + + /** + * @param string $defaultPaperOrientation + * @return $this + */ + public function setDefaultPaperOrientation($defaultPaperOrientation) + { + $this->defaultPaperOrientation = $defaultPaperOrientation; + return $this; + } + + /** + * @return string + */ + public function getDefaultPaperSize() + { + return $this->defaultPaperSize; + } + + /** + * @return string + */ + public function getDefaultPaperOrientation() + { + return $this->defaultPaperOrientation; + } + + /** + * @param int $dpi + * @return $this + */ + public function setDpi($dpi) + { + $this->dpi = $dpi; + return $this; + } + + /** + * @return int + */ + public function getDpi() + { + return $this->dpi; + } + + /** + * @param string $fontCache + * @return $this + */ + public function setFontCache($fontCache) + { + $this->fontCache = $fontCache; + return $this; + } + + /** + * @return string + */ + public function getFontCache() + { + return $this->fontCache; + } + + /** + * @param string $fontDir + * @return $this + */ + public function setFontDir($fontDir) + { + $this->fontDir = $fontDir; + return $this; + } + + /** + * @return string + */ + public function getFontDir() + { + return $this->fontDir; + } + + /** + * @param float $fontHeightRatio + * @return $this + */ + public function setFontHeightRatio($fontHeightRatio) + { + $this->fontHeightRatio = $fontHeightRatio; + return $this; + } + + /** + * @return float + */ + public function getFontHeightRatio() + { + return $this->fontHeightRatio; + } + + /** + * @param boolean $isFontSubsettingEnabled + * @return $this + */ + public function setIsFontSubsettingEnabled($isFontSubsettingEnabled) + { + $this->isFontSubsettingEnabled = $isFontSubsettingEnabled; + return $this; + } + + /** + * @return boolean + */ + public function getIsFontSubsettingEnabled() + { + return $this->isFontSubsettingEnabled; + } + + /** + * @return boolean + */ + public function isFontSubsettingEnabled() + { + return $this->getIsFontSubsettingEnabled(); + } + + /** + * @param boolean $isHtml5ParserEnabled + * @return $this + */ + public function setIsHtml5ParserEnabled($isHtml5ParserEnabled) + { + $this->isHtml5ParserEnabled = $isHtml5ParserEnabled; + return $this; + } + + /** + * @return boolean + */ + public function getIsHtml5ParserEnabled() + { + return $this->isHtml5ParserEnabled; + } + + /** + * @return boolean + */ + public function isHtml5ParserEnabled() + { + return $this->getIsHtml5ParserEnabled(); + } + + /** + * @param boolean $isJavascriptEnabled + * @return $this + */ + public function setIsJavascriptEnabled($isJavascriptEnabled) + { + $this->isJavascriptEnabled = $isJavascriptEnabled; + return $this; + } + + /** + * @return boolean + */ + public function getIsJavascriptEnabled() + { + return $this->isJavascriptEnabled; + } + + /** + * @return boolean + */ + public function isJavascriptEnabled() + { + return $this->getIsJavascriptEnabled(); + } + + /** + * @param boolean $isPhpEnabled + * @return $this + */ + public function setIsPhpEnabled($isPhpEnabled) + { + $this->isPhpEnabled = $isPhpEnabled; + return $this; + } + + /** + * @return boolean + */ + public function getIsPhpEnabled() + { + return $this->isPhpEnabled; + } + + /** + * @return boolean + */ + public function isPhpEnabled() + { + return $this->getIsPhpEnabled(); + } + + /** + * @param boolean $isRemoteEnabled + * @return $this + */ + public function setIsRemoteEnabled($isRemoteEnabled) + { + $this->isRemoteEnabled = $isRemoteEnabled; + return $this; + } + + /** + * @return boolean + */ + public function getIsRemoteEnabled() + { + return $this->isRemoteEnabled; + } + + /** + * @return boolean + */ + public function isRemoteEnabled() + { + return $this->getIsRemoteEnabled(); + } + + /** + * @param string $logOutputFile + * @return $this + */ + public function setLogOutputFile($logOutputFile) + { + $this->logOutputFile = $logOutputFile; + return $this; + } + + /** + * @return string + */ + public function getLogOutputFile() + { + return $this->logOutputFile; + } + + /** + * @param string $tempDir + * @return $this + */ + public function setTempDir($tempDir) + { + $this->tempDir = $tempDir; + return $this; + } + + /** + * @return string + */ + public function getTempDir() + { + return $this->tempDir; + } + + /** + * @param string $rootDir + * @return $this + */ + public function setRootDir($rootDir) + { + $this->rootDir = $rootDir; + return $this; + } + + /** + * @return string + */ + public function getRootDir() + { + return $this->rootDir; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/PhpEvaluator.php b/vendor/dompdf/dompdf/src/PhpEvaluator.php new file mode 100644 index 0000000..cdebc7a --- /dev/null +++ b/vendor/dompdf/dompdf/src/PhpEvaluator.php @@ -0,0 +1,63 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf; + +/** + * Executes inline PHP code during the rendering process + * + * @package dompdf + */ +class PhpEvaluator +{ + + /** + * @var Canvas + */ + protected $_canvas; + + /** + * PhpEvaluator constructor. + * @param Canvas $canvas + */ + public function __construct(Canvas $canvas) + { + $this->_canvas = $canvas; + } + + /** + * @param $code + * @param array $vars + */ + public function evaluate($code, $vars = []) + { + if (!$this->_canvas->get_dompdf()->getOptions()->getIsPhpEnabled()) { + return; + } + + // Set up some variables for the inline code + $pdf = $this->_canvas; + $fontMetrics = $pdf->get_dompdf()->getFontMetrics(); + $PAGE_NUM = $pdf->get_page_number(); + $PAGE_COUNT = $pdf->get_page_count(); + + // Override those variables if passed in + foreach ($vars as $k => $v) { + $$k = $v; + } + + eval($code); + } + + /** + * @param Frame $frame + */ + public function render(Frame $frame) + { + $this->evaluate($frame->get_node()->nodeValue); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/Absolute.php b/vendor/dompdf/dompdf/src/Positioner/Absolute.php new file mode 100644 index 0000000..ef34a5c --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/Absolute.php @@ -0,0 +1,118 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Positions absolutely positioned frames + */ +class Absolute extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + $style = $frame->get_style(); + + $p = $frame->find_positionned_parent(); + + list($x, $y, $w, $h) = $frame->get_containing_block(); + + $top = $style->length_in_pt($style->top, $h); + $right = $style->length_in_pt($style->right, $w); + $bottom = $style->length_in_pt($style->bottom, $h); + $left = $style->length_in_pt($style->left, $w); + + if ($p && !($left === "auto" && $right === "auto")) { + // Get the parent's padding box (see http://www.w3.org/TR/CSS21/visuren.html#propdef-top) + list($x, $y, $w, $h) = $p->get_padding_box(); + } + + list($width, $height) = [$frame->get_margin_width(), $frame->get_margin_height()]; + + $orig_style = $frame->get_original_style(); + $orig_width = $orig_style->width; + $orig_height = $orig_style->height; + + /**************************** + * + * Width auto: + * ____________| left=auto | left=fixed | + * right=auto | A | B | + * right=fixed | C | D | + * + * Width fixed: + * ____________| left=auto | left=fixed | + * right=auto | E | F | + * right=fixed | G | H | + *****************************/ + + if ($left === "auto") { + if ($right === "auto") { + // A or E - Keep the frame at the same position + $x = $x + $frame->find_block_parent()->get_current_line_box()->w; + } else { + if ($orig_width === "auto") { + // C + $x += $w - $width - $right; + } else { + // G + $x += $w - $width - $right; + } + } + } else { + if ($right === "auto") { + // B or F + $x += (float)$left; + } else { + if ($orig_width === "auto") { + // D - TODO change width + $x += (float)$left; + } else { + // H - Everything is fixed: left + width win + $x += (float)$left; + } + } + } + + // The same vertically + if ($top === "auto") { + if ($bottom === "auto") { + // A or E - Keep the frame at the same position + $y = $frame->find_block_parent()->get_current_line_box()->y; + } else { + if ($orig_height === "auto") { + // C + $y += (float)$h - $height - (float)$bottom; + } else { + // G + $y += (float)$h - $height - (float)$bottom; + } + } + } else { + if ($bottom === "auto") { + // B or F + $y += (float)$top; + } else { + if ($orig_height === "auto") { + // D - TODO change height + $y += (float)$top; + } else { + // H - Everything is fixed: top + height win + $y += (float)$top; + } + } + } + + $frame->set_position($x, $y); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/AbstractPositioner.php b/vendor/dompdf/dompdf/src/Positioner/AbstractPositioner.php new file mode 100644 index 0000000..2ade6af --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/AbstractPositioner.php @@ -0,0 +1,48 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Base AbstractPositioner class + * + * Defines postioner interface + * + * @access private + * @package dompdf + */ +abstract class AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + * @return mixed + */ + abstract function position(AbstractFrameDecorator $frame); + + /** + * @param AbstractFrameDecorator $frame + * @param $offset_x + * @param $offset_y + * @param bool $ignore_self + */ + function move(AbstractFrameDecorator $frame, $offset_x, $offset_y, $ignore_self = false) + { + list($x, $y) = $frame->get_position(); + + if (!$ignore_self) { + $frame->set_position($x + $offset_x, $y + $offset_y); + } + + foreach ($frame->get_children() as $child) { + $child->move($offset_x, $offset_y); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/Block.php b/vendor/dompdf/dompdf/src/Positioner/Block.php new file mode 100644 index 0000000..0c340bc --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/Block.php @@ -0,0 +1,54 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Positions block frames + * + * @access private + * @package dompdf + */ +class Block extends AbstractPositioner { + + function position(AbstractFrameDecorator $frame) + { + $style = $frame->get_style(); + $cb = $frame->get_containing_block(); + $p = $frame->find_block_parent(); + + if ($p) { + $float = $style->float; + + if (!$float || $float === "none") { + $p->add_line(true); + } + $y = $p->get_current_line_box()->y; + + } else { + $y = $cb["y"]; + } + + $x = $cb["x"]; + + // Relative positionning + if ($style->position === "relative") { + $top = (float)$style->length_in_pt($style->top, $cb["h"]); + //$right = (float)$style->length_in_pt($style->right, $cb["w"]); + //$bottom = (float)$style->length_in_pt($style->bottom, $cb["h"]); + $left = (float)$style->length_in_pt($style->left, $cb["w"]); + + $x += $left; + $y += $top; + } + + $frame->set_position($x, $y); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/Fixed.php b/vendor/dompdf/dompdf/src/Positioner/Fixed.php new file mode 100644 index 0000000..556254b --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/Fixed.php @@ -0,0 +1,89 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Positions fixely positioned frames + */ +class Fixed extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + $style = $frame->get_original_style(); + $root = $frame->get_root(); + $initialcb = $root->get_containing_block(); + $initialcb_style = $root->get_style(); + + $p = $frame->find_block_parent(); + if ($p) { + $p->add_line(); + } + + // Compute the margins of the @page style + $margin_top = (float)$initialcb_style->length_in_pt($initialcb_style->margin_top, $initialcb["h"]); + $margin_right = (float)$initialcb_style->length_in_pt($initialcb_style->margin_right, $initialcb["w"]); + $margin_bottom = (float)$initialcb_style->length_in_pt($initialcb_style->margin_bottom, $initialcb["h"]); + $margin_left = (float)$initialcb_style->length_in_pt($initialcb_style->margin_left, $initialcb["w"]); + + // The needed computed style of the element + $height = (float)$style->length_in_pt($style->height, $initialcb["h"]); + $width = (float)$style->length_in_pt($style->width, $initialcb["w"]); + + $top = $style->length_in_pt($style->top, $initialcb["h"]); + $right = $style->length_in_pt($style->right, $initialcb["w"]); + $bottom = $style->length_in_pt($style->bottom, $initialcb["h"]); + $left = $style->length_in_pt($style->left, $initialcb["w"]); + + $y = $margin_top; + if (isset($top)) { + $y = (float)$top + $margin_top; + if ($top === "auto") { + $y = $margin_top; + if (isset($bottom) && $bottom !== "auto") { + $y = $initialcb["h"] - $bottom - $margin_bottom; + if ($frame->is_auto_height()) { + $y -= $height; + } else { + $y -= $frame->get_margin_height(); + } + } + } + } + + $x = $margin_left; + if (isset($left)) { + $x = (float)$left + $margin_left; + if ($left === "auto") { + $x = $margin_left; + if (isset($right) && $right !== "auto") { + $x = $initialcb["w"] - $right - $margin_right; + if ($frame->is_auto_width()) { + $x -= $width; + } else { + $x -= $frame->get_margin_width(); + } + } + } + } + + $frame->set_position($x, $y); + + $children = $frame->get_children(); + foreach ($children as $child) { + $child->set_position($x, $y); + } + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Positioner/Inline.php b/vendor/dompdf/dompdf/src/Positioner/Inline.php new file mode 100644 index 0000000..bcea2ba --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/Inline.php @@ -0,0 +1,77 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; +use Dompdf\FrameDecorator\Inline as InlineFrameDecorator; +use Dompdf\Exception; + +/** + * Positions inline frames + * + * @package dompdf + */ +class Inline extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + * @throws Exception + */ + function position(AbstractFrameDecorator $frame) + { + /** + * Find our nearest block level parent and access its lines property. + * @var BlockFrameDecorator + */ + $p = $frame->find_block_parent(); + + // Debugging code: + + // Helpers::pre_r("\nPositioning:"); + // Helpers::pre_r("Me: " . $frame->get_node()->nodeName . " (" . spl_object_hash($frame->get_node()) . ")"); + // Helpers::pre_r("Parent: " . $p->get_node()->nodeName . " (" . spl_object_hash($p->get_node()) . ")"); + + // End debugging + + if (!$p) { + throw new Exception("No block-level parent found. Not good."); + } + + $f = $frame; + + $cb = $f->get_containing_block(); + $line = $p->get_current_line_box(); + + // Skip the page break if in a fixed position element + $is_fixed = false; + while ($f = $f->get_parent()) { + if ($f->get_style()->position === "fixed") { + $is_fixed = true; + break; + } + } + + $f = $frame; + + if (!$is_fixed && $f->get_parent() && + $f->get_parent() instanceof InlineFrameDecorator && + $f->is_text_node() + ) { + $min_max = $f->get_reflower()->get_min_max_width(); + + // If the frame doesn't fit in the current line, a line break occurs + if ($min_max["min"] > ($cb["w"] - $line->left - $line->w - $line->right)) { + $p->add_line(); + } + } + + $f->set_position($cb["x"] + $line->w, $line->y); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/ListBullet.php b/vendor/dompdf/dompdf/src/Positioner/ListBullet.php new file mode 100644 index 0000000..70bc283 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/ListBullet.php @@ -0,0 +1,78 @@ + + * @author Helmut Tischer + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Positions list bullets + * + * @package dompdf + */ +class ListBullet extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + + // Bullets & friends are positioned an absolute distance to the left of + // the content edge of their parent element + $cb = $frame->get_containing_block(); + + // Note: this differs from most frames in that we must position + // ourselves after determining our width + $x = $cb["x"] - $frame->get_width(); + + $p = $frame->find_block_parent(); + + $y = $p->get_current_line_box()->y; + + // This is a bit of a hack... + $n = $frame->get_next_sibling(); + if ($n) { + $style = $n->get_style(); + $line_height = $style->line_height; + // TODO: should offset take into account the line height of the next sibling (per previous logic)? + // $offset = (float)$style->length_in_pt($line_height, $n->get_containing_block("h")) - $frame->get_height(); + $offset = $line_height - $frame->get_height(); + $y += $offset / 2; + } + + // Now the position is the left top of the block which should be marked with the bullet. + // We tried to find out the y of the start of the first text character within the block. + // But the top margin/padding does not fit, neither from this nor from the next sibling + // The "bit of a hack" above does not work also. + + // Instead let's position the bullet vertically centered to the block which should be marked. + // But for get_next_sibling() the get_containing_block is all zero, and for find_block_parent() + // the get_containing_block is paper width and the entire list as height. + + // if ($p) { + // //$cb = $n->get_containing_block(); + // $cb = $p->get_containing_block(); + // $y += $cb["h"]/2; + // print 'cb:'.$cb["x"].':'.$cb["y"].':'.$cb["w"].':'.$cb["h"].':'; + // } + + // Todo: + // For now give up on the above. Use Guesswork with font y-pos in the middle of the line spacing + + /*$style = $p->get_style(); + $font_size = $style->font_size; + $line_height = (float)$style->length_in_pt($style->line_height, $font_size); + $y += ($line_height - $font_size) / 2; */ + + //Position is x-end y-top of character position of the bullet. + $frame->set_position($x, $y); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/NullPositioner.php b/vendor/dompdf/dompdf/src/Positioner/NullPositioner.php new file mode 100644 index 0000000..afdef19 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/NullPositioner.php @@ -0,0 +1,28 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Dummy positioner + * + * @package dompdf + */ +class NullPositioner extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + return; + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/TableCell.php b/vendor/dompdf/dompdf/src/Positioner/TableCell.php new file mode 100644 index 0000000..42b0042 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/TableCell.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; +use Dompdf\FrameDecorator\Table; + +/** + * Positions table cells + * + * @package dompdf + */ +class TableCell extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + $table = Table::find_parent_table($frame); + $cellmap = $table->get_cellmap(); + $frame->set_position($cellmap->get_frame_position($frame)); + } +} diff --git a/vendor/dompdf/dompdf/src/Positioner/TableRow.php b/vendor/dompdf/dompdf/src/Positioner/TableRow.php new file mode 100644 index 0000000..aee2045 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Positioner/TableRow.php @@ -0,0 +1,36 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace Dompdf\Positioner; + +use Dompdf\FrameDecorator\AbstractFrameDecorator; + +/** + * Positions table rows + * + * @package dompdf + */ +class TableRow extends AbstractPositioner +{ + + /** + * @param AbstractFrameDecorator $frame + */ + function position(AbstractFrameDecorator $frame) + { + $cb = $frame->get_containing_block(); + $p = $frame->get_prev_sibling(); + + if ($p) { + $y = $p->get_position("y") + $p->get_margin_height(); + } else { + $y = $cb["y"]; + } + $frame->set_position($cb["x"], $y); + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer.php b/vendor/dompdf/dompdf/src/Renderer.php new file mode 100644 index 0000000..535fec7 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer.php @@ -0,0 +1,295 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf; + +use Dompdf\Renderer\AbstractRenderer; +use Dompdf\Renderer\Block; +use Dompdf\Renderer\Image; +use Dompdf\Renderer\ListBullet; +use Dompdf\Renderer\TableCell; +use Dompdf\Renderer\TableRowGroup; +use Dompdf\Renderer\Text; + +/** + * Concrete renderer + * + * Instantiates several specific renderers in order to render any given frame. + * + * @package dompdf + */ +class Renderer extends AbstractRenderer +{ + + /** + * Array of renderers for specific frame types + * + * @var AbstractRenderer[] + */ + protected $_renderers; + + /** + * Cache of the callbacks array + * + * @var array + */ + private $_callbacks; + + /** + * Advance the canvas to the next page + */ + function new_page() + { + $this->_canvas->new_page(); + } + + /** + * Render frames recursively + * + * @param Frame $frame the frame to render + */ + public function render(Frame $frame) + { + global $_dompdf_debug; + + $this->_check_callbacks("begin_frame", $frame); + + if ($_dompdf_debug) { + echo $frame; + flush(); + } + + $style = $frame->get_style(); + + if (in_array($style->visibility, ["hidden", "collapse"])) { + return; + } + + $display = $style->display; + + // Starts the CSS transformation + if ($style->transform && is_array($style->transform)) { + $this->_canvas->save(); + list($x, $y) = $frame->get_padding_box(); + $origin = $style->transform_origin; + + foreach ($style->transform as $transform) { + list($function, $values) = $transform; + if ($function === "matrix") { + $function = "transform"; + } + + $values = array_map("floatval", $values); + $values[] = $x + (float)$style->length_in_pt($origin[0], (float)$style->length_in_pt($style->width)); + $values[] = $y + (float)$style->length_in_pt($origin[1], (float)$style->length_in_pt($style->height)); + + call_user_func_array([$this->_canvas, $function], $values); + } + } + + switch ($display) { + + case "block": + case "list-item": + case "inline-block": + case "table": + case "inline-table": + $this->_render_frame("block", $frame); + break; + + case "inline": + if ($frame->is_text_node()) { + $this->_render_frame("text", $frame); + } else { + $this->_render_frame("inline", $frame); + } + break; + + case "table-cell": + $this->_render_frame("table-cell", $frame); + break; + + case "table-row-group": + case "table-header-group": + case "table-footer-group": + $this->_render_frame("table-row-group", $frame); + break; + + case "-dompdf-list-bullet": + $this->_render_frame("list-bullet", $frame); + break; + + case "-dompdf-image": + $this->_render_frame("image", $frame); + break; + + case "none": + $node = $frame->get_node(); + + if ($node->nodeName === "script") { + if ($node->getAttribute("type") === "text/php" || + $node->getAttribute("language") === "php" + ) { + // Evaluate embedded php scripts + $this->_render_frame("php", $frame); + } elseif ($node->getAttribute("type") === "text/javascript" || + $node->getAttribute("language") === "javascript" + ) { + // Insert JavaScript + $this->_render_frame("javascript", $frame); + } + } + + // Don't render children, so skip to next iter + return; + + default: + break; + + } + + // Starts the overflow: hidden box + if ($style->overflow === "hidden") { + list($x, $y, $w, $h) = $frame->get_padding_box(); + + // get border radii + $style = $frame->get_style(); + list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); + + if ($tl + $tr + $br + $bl > 0) { + $this->_canvas->clipping_roundrectangle($x, $y, (float)$w, (float)$h, $tl, $tr, $br, $bl); + } else { + $this->_canvas->clipping_rectangle($x, $y, (float)$w, (float)$h); + } + } + + $stack = []; + + foreach ($frame->get_children() as $child) { + // < 0 : nagative z-index + // = 0 : no z-index, no stacking context + // = 1 : stacking context without z-index + // > 1 : z-index + $child_style = $child->get_style(); + $child_z_index = $child_style->z_index; + $z_index = 0; + + if ($child_z_index !== "auto") { + $z_index = intval($child_z_index) + 1; + } elseif ($child_style->float !== "none" || $child->is_positionned()) { + $z_index = 1; + } + + $stack[$z_index][] = $child; + } + + ksort($stack); + + foreach ($stack as $by_index) { + foreach ($by_index as $child) { + $this->render($child); + } + } + + // Ends the overflow: hidden box + if ($style->overflow === "hidden") { + $this->_canvas->clipping_end(); + } + + if ($style->transform && is_array($style->transform)) { + $this->_canvas->restore(); + } + + // Check for end frame callback + $this->_check_callbacks("end_frame", $frame); + } + + /** + * Check for callbacks that need to be performed when a given event + * gets triggered on a frame + * + * @param string $event the type of event + * @param Frame $frame the frame that event is triggered on + */ + protected function _check_callbacks($event, $frame) + { + if (!isset($this->_callbacks)) { + $this->_callbacks = $this->_dompdf->getCallbacks(); + } + + if (is_array($this->_callbacks) && isset($this->_callbacks[$event])) { + $info = [0 => $this->_canvas, "canvas" => $this->_canvas, + 1 => $frame, "frame" => $frame]; + $fs = $this->_callbacks[$event]; + foreach ($fs as $f) { + if (is_callable($f)) { + if (is_array($f)) { + $f[0]->{$f[1]}($info); + } else { + $f($info); + } + } + } + } + } + + /** + * Render a single frame + * + * Creates Renderer objects on demand + * + * @param string $type type of renderer to use + * @param Frame $frame the frame to render + */ + protected function _render_frame($type, $frame) + { + + if (!isset($this->_renderers[$type])) { + + switch ($type) { + case "block": + $this->_renderers[$type] = new Block($this->_dompdf); + break; + + case "inline": + $this->_renderers[$type] = new Renderer\Inline($this->_dompdf); + break; + + case "text": + $this->_renderers[$type] = new Text($this->_dompdf); + break; + + case "image": + $this->_renderers[$type] = new Image($this->_dompdf); + break; + + case "table-cell": + $this->_renderers[$type] = new TableCell($this->_dompdf); + break; + + case "table-row-group": + $this->_renderers[$type] = new TableRowGroup($this->_dompdf); + break; + + case "list-bullet": + $this->_renderers[$type] = new ListBullet($this->_dompdf); + break; + + case "php": + $this->_renderers[$type] = new PhpEvaluator($this->_canvas); + break; + + case "javascript": + $this->_renderers[$type] = new JavascriptEmbedder($this->_dompdf); + break; + + } + } + + $this->_renderers[$type]->render($frame); + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php b/vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php new file mode 100644 index 0000000..8c8d2d4 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/AbstractRenderer.php @@ -0,0 +1,1020 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Adapter\CPDF; +use Dompdf\Css\Color; +use Dompdf\Css\Style; +use Dompdf\Dompdf; +use Dompdf\Helpers; +use Dompdf\Frame; +use Dompdf\Image\Cache; + +/** + * Base renderer class + * + * @package dompdf + */ +abstract class AbstractRenderer +{ + + /** + * Rendering backend + * + * @var \Dompdf\Canvas + */ + protected $_canvas; + + /** + * Current dompdf instance + * + * @var Dompdf + */ + protected $_dompdf; + + /** + * Class constructor + * + * @param Dompdf $dompdf The current dompdf instance + */ + function __construct(Dompdf $dompdf) + { + $this->_dompdf = $dompdf; + $this->_canvas = $dompdf->getCanvas(); + } + + /** + * Render a frame. + * + * Specialized in child classes + * + * @param Frame $frame The frame to render + */ + abstract function render(Frame $frame); + + /** + * Render a background image over a rectangular area + * + * @param string $url The background image to load + * @param float $x The left edge of the rectangular area + * @param float $y The top edge of the rectangular area + * @param float $width The width of the rectangular area + * @param float $height The height of the rectangular area + * @param Style $style The associated Style object + * + * @throws \Exception + */ + protected function _background_image($url, $x, $y, $width, $height, $style) + { + if (!function_exists("imagecreatetruecolor")) { + throw new \Exception("The PHP GD extension is required, but is not installed."); + } + + $sheet = $style->get_stylesheet(); + + // Skip degenerate cases + if ($width == 0 || $height == 0) { + return; + } + + $box_width = $width; + $box_height = $height; + + //debugpng + if ($this->_dompdf->getOptions()->getDebugPng()) { + print '[_background_image ' . $url . ']'; + } + + list($img, $type, /*$msg*/) = Cache::resolve_url( + $url, + $sheet->get_protocol(), + $sheet->get_host(), + $sheet->get_base_path(), + $this->_dompdf + ); + + // Bail if the image is no good + if (Cache::is_broken($img)) { + return; + } + + //Try to optimize away reading and composing of same background multiple times + //Postponing read with imagecreatefrom ...() + //final composition parameters and name not known yet + //Therefore read dimension directly from file, instead of creating gd object first. + //$img_w = imagesx($src); $img_h = imagesy($src); + + list($img_w, $img_h) = Helpers::dompdf_getimagesize($img, $this->_dompdf->getHttpContext()); + if (!isset($img_w) || $img_w == 0 || !isset($img_h) || $img_h == 0) { + return; + } + + // save for later check if file needs to be resized. + $org_img_w = $img_w; + $org_img_h = $img_h; + + $repeat = $style->background_repeat; + $dpi = $this->_dompdf->getOptions()->getDpi(); + + //Increase background resolution and dependent box size according to image resolution to be placed in + //Then image can be copied in without resize + $bg_width = round((float)($width * $dpi) / 72); + $bg_height = round((float)($height * $dpi) / 72); + + list($img_w, $img_h) = $this->_resize_background_image( + $img_w, + $img_h, + $bg_width, + $bg_height, + $style->background_size, + $dpi + ); + //Need %bg_x, $bg_y as background pos, where img starts, converted to pixel + + list($bg_x, $bg_y) = $style->background_position; + + if (Helpers::is_percent($bg_x)) { + // The point $bg_x % from the left edge of the image is placed + // $bg_x % from the left edge of the background rectangle + $p = ((float)$bg_x) / 100.0; + $x1 = $p * $img_w; + $x2 = $p * $bg_width; + + $bg_x = $x2 - $x1; + } else { + $bg_x = (float)($style->length_in_pt($bg_x) * $dpi) / 72; + } + + $bg_x = round($bg_x + (float)$style->length_in_pt($style->border_left_width) * $dpi / 72); + + if (Helpers::is_percent($bg_y)) { + // The point $bg_y % from the left edge of the image is placed + // $bg_y % from the left edge of the background rectangle + $p = ((float)$bg_y) / 100.0; + $y1 = $p * $img_h; + $y2 = $p * $bg_height; + + $bg_y = $y2 - $y1; + } else { + $bg_y = (float)($style->length_in_pt($bg_y) * $dpi) / 72; + } + + $bg_y = round($bg_y + (float)$style->length_in_pt($style->border_top_width) * $dpi / 72); + + //clip background to the image area on partial repeat. Nothing to do if img off area + //On repeat, normalize start position to the tile at immediate left/top or 0/0 of area + //On no repeat with positive offset: move size/start to have offset==0 + //Handle x/y Dimensions separately + + if ($repeat !== "repeat" && $repeat !== "repeat-x") { + //No repeat x + if ($bg_x < 0) { + $bg_width = $img_w + $bg_x; + } else { + $x += ($bg_x * 72) / $dpi; + $bg_width = $bg_width - $bg_x; + if ($bg_width > $img_w) { + $bg_width = $img_w; + } + $bg_x = 0; + } + + if ($bg_width <= 0) { + return; + } + + $width = (float)($bg_width * 72) / $dpi; + } else { + //repeat x + if ($bg_x < 0) { + $bg_x = -((-$bg_x) % $img_w); + } else { + $bg_x = $bg_x % $img_w; + if ($bg_x > 0) { + $bg_x -= $img_w; + } + } + } + + if ($repeat !== "repeat" && $repeat !== "repeat-y") { + //no repeat y + if ($bg_y < 0) { + $bg_height = $img_h + $bg_y; + } else { + $y += ($bg_y * 72) / $dpi; + $bg_height = $bg_height - $bg_y; + if ($bg_height > $img_h) { + $bg_height = $img_h; + } + $bg_y = 0; + } + if ($bg_height <= 0) { + return; + } + $height = (float)($bg_height * 72) / $dpi; + } else { + //repeat y + if ($bg_y < 0) { + $bg_y = -((-$bg_y) % $img_h); + } else { + $bg_y = $bg_y % $img_h; + if ($bg_y > 0) { + $bg_y -= $img_h; + } + } + } + + //Optimization, if repeat has no effect + if ($repeat === "repeat" && $bg_y <= 0 && $img_h + $bg_y >= $bg_height) { + $repeat = "repeat-x"; + } + + if ($repeat === "repeat" && $bg_x <= 0 && $img_w + $bg_x >= $bg_width) { + $repeat = "repeat-y"; + } + + if (($repeat === "repeat-x" && $bg_x <= 0 && $img_w + $bg_x >= $bg_width) || + ($repeat === "repeat-y" && $bg_y <= 0 && $img_h + $bg_y >= $bg_height) + ) { + $repeat = "no-repeat"; + } + + //Use filename as indicator only + //different names for different variants to have different copies in the pdf + //This is not dependent of background color of box! .'_'.(is_array($bg_color) ? $bg_color["hex"] : $bg_color) + //Note: Here, bg_* are the start values, not end values after going through the tile loops! + + $filedummy = $img; + + $is_png = false; + $filedummy .= '_' . $bg_width . '_' . $bg_height . '_' . $bg_x . '_' . $bg_y . '_' . $repeat; + + //Optimization to avoid multiple times rendering the same image. + //If check functions are existing and identical image already cached, + //then skip creation of duplicate, because it is not needed by addImagePng + if ($this->_canvas instanceof CPDF && $this->_canvas->get_cpdf()->image_iscached($filedummy)) { + $bg = null; + } else { + // Create a new image to fit over the background rectangle + $bg = imagecreatetruecolor($bg_width, $bg_height); + + switch (strtolower($type)) { + case "png": + $is_png = true; + imagesavealpha($bg, true); + imagealphablending($bg, false); + $src = imagecreatefrompng($img); + break; + + case "jpeg": + $src = imagecreatefromjpeg($img); + break; + + case "gif": + $src = imagecreatefromgif($img); + break; + + case "bmp": + $src = Helpers::imagecreatefrombmp($img); + break; + + default: + return; // Unsupported image type + } + + if ($src == null) { + return; + } + + if ($img_w != $org_img_w || $img_h != $org_img_h) { + $newSrc = imagescale($src, $img_w, $img_h); + imagedestroy($src); + $src = $newSrc; + } + + if ($src == null) { + return; + } + + //Background color if box is not relevant here + //Non transparent image: box clipped to real size. Background non relevant. + //Transparent image: The image controls the transparency and lets shine through whatever background. + //However on transparent image preset the composed image with the transparency color, + //to keep the transparency when copying over the non transparent parts of the tiles. + $ti = imagecolortransparent($src); + $palletsize = imagecolorstotal($src); + + if ($ti >= 0 && $ti < $palletsize) { + $tc = imagecolorsforindex($src, $ti); + $ti = imagecolorallocate($bg, $tc['red'], $tc['green'], $tc['blue']); + imagefill($bg, 0, 0, $ti); + imagecolortransparent($bg, $ti); + } + + //This has only an effect for the non repeatable dimension. + //compute start of src and dest coordinates of the single copy + if ($bg_x < 0) { + $dst_x = 0; + $src_x = -$bg_x; + } else { + $src_x = 0; + $dst_x = $bg_x; + } + + if ($bg_y < 0) { + $dst_y = 0; + $src_y = -$bg_y; + } else { + $src_y = 0; + $dst_y = $bg_y; + } + + //For historical reasons exchange meanings of variables: + //start_* will be the start values, while bg_* will be the temporary start values in the loops + $start_x = $bg_x; + $start_y = $bg_y; + + // Copy regions from the source image to the background + if ($repeat === "no-repeat") { + // Simply place the image on the background + imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $img_h); + + } else if ($repeat === "repeat-x") { + for ($bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w) { + if ($bg_x < 0) { + $dst_x = 0; + $src_x = -$bg_x; + $w = $img_w + $bg_x; + } else { + $dst_x = $bg_x; + $src_x = 0; + $w = $img_w; + } + imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $img_h); + } + } else if ($repeat === "repeat-y") { + + for ($bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h) { + if ($bg_y < 0) { + $dst_y = 0; + $src_y = -$bg_y; + $h = $img_h + $bg_y; + } else { + $dst_y = $bg_y; + $src_y = 0; + $h = $img_h; + } + imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $img_w, $h); + } + } else if ($repeat === "repeat") { + for ($bg_y = $start_y; $bg_y < $bg_height; $bg_y += $img_h) { + for ($bg_x = $start_x; $bg_x < $bg_width; $bg_x += $img_w) { + if ($bg_x < 0) { + $dst_x = 0; + $src_x = -$bg_x; + $w = $img_w + $bg_x; + } else { + $dst_x = $bg_x; + $src_x = 0; + $w = $img_w; + } + + if ($bg_y < 0) { + $dst_y = 0; + $src_y = -$bg_y; + $h = $img_h + $bg_y; + } else { + $dst_y = $bg_y; + $src_y = 0; + $h = $img_h; + } + imagecopy($bg, $src, $dst_x, $dst_y, $src_x, $src_y, $w, $h); + } + } + } else { + print 'Unknown repeat!'; + } + + imagedestroy($src); + + } /* End optimize away creation of duplicates */ + + $this->_canvas->clipping_rectangle($x, $y, $box_width, $box_height); + + //img: image url string + //img_w, img_h: original image size in px + //width, height: box size in pt + //bg_width, bg_height: box size in px + //x, y: left/top edge of box on page in pt + //start_x, start_y: placement of image relative to pattern + //$repeat: repeat mode + //$bg: GD object of result image + //$src: GD object of original image + //When using cpdf and optimization to direct png creation from gd object is available, + //don't create temp file, but place gd object directly into the pdf + if (!$is_png && $this->_canvas instanceof CPDF) { + // Note: CPDF_Adapter image converts y position + $this->_canvas->get_cpdf()->addImagePng($filedummy, $x, $this->_canvas->get_height() - $y - $height, $width, $height, $bg); + } else { + $tmp_dir = $this->_dompdf->getOptions()->getTempDir(); + $tmp_name = @tempnam($tmp_dir, "bg_dompdf_img_"); + @unlink($tmp_name); + $tmp_file = "$tmp_name.png"; + + //debugpng + if ($this->_dompdf->getOptions()->getDebugPng()) { + print '[_background_image ' . $tmp_file . ']'; + } + + imagepng($bg, $tmp_file); + $this->_canvas->image($tmp_file, $x, $y, $width, $height); + imagedestroy($bg); + + //debugpng + if ($this->_dompdf->getOptions()->getDebugPng()) { + print '[_background_image unlink ' . $tmp_file . ']'; + } + + if (!$this->_dompdf->getOptions()->getDebugKeepTemp()) { + unlink($tmp_file); + } + } + + $this->_canvas->clipping_end(); + } + + /** + * @param $style + * @param $width + * @return array + */ + protected function _get_dash_pattern($style, $width) + { + $pattern = []; + + switch ($style) { + default: + /*case "solid": + case "double": + case "groove": + case "inset": + case "outset": + case "ridge":*/ + case "none": + break; + + case "dotted": + if ($width <= 1) { + $pattern = [$width, $width * 2]; + } else { + $pattern = [$width]; + } + break; + + case "dashed": + $pattern = [3 * $width]; + break; + } + + return $pattern; + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_none($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + return; + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_hidden($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + return; + } + + // Border rendering functions + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_dotted($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dotted", $r1, $r2); + } + + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_dashed($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "dashed", $r1, $r2); + } + + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_solid($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + // TODO: Solve rendering where one corner is beveled (radius == 0), one corner isn't. + if ($corner_style !== "bevel" || $r1 > 0 || $r2 > 0) { + // do it the simple way + $this->_border_line($x, $y, $length, $color, $widths, $side, $corner_style, "solid", $r1, $r2); + return; + } + + list($top, $right, $bottom, $left) = $widths; + + // All this polygon business is for beveled corners... + switch ($side) { + case "top": + $points = [$x, $y, + $x + $length, $y, + $x + $length - $right, $y + $top, + $x + $left, $y + $top]; + $this->_canvas->polygon($points, $color, null, null, true); + break; + + case "bottom": + $points = [$x, $y, + $x + $length, $y, + $x + $length - $right, $y - $bottom, + $x + $left, $y - $bottom]; + $this->_canvas->polygon($points, $color, null, null, true); + break; + + case "left": + $points = [$x, $y, + $x, $y + $length, + $x + $left, $y + $length - $bottom, + $x + $left, $y + $top]; + $this->_canvas->polygon($points, $color, null, null, true); + break; + + case "right": + $points = [$x, $y, + $x, $y + $length, + $x - $right, $y + $length - $bottom, + $x - $right, $y + $top]; + $this->_canvas->polygon($points, $color, null, null, true); + break; + + default: + return; + } + } + + /** + * @param $side + * @param $ratio + * @param $top + * @param $right + * @param $bottom + * @param $left + * @param $x + * @param $y + * @param $length + * @param $r1 + * @param $r2 + */ + protected function _apply_ratio($side, $ratio, $top, $right, $bottom, $left, &$x, &$y, &$length, &$r1, &$r2) + { + switch ($side) { + case "top": + $r1 -= $left * $ratio; + $r2 -= $right * $ratio; + $x += $left * $ratio; + $y += $top * $ratio; + $length -= $left * $ratio + $right * $ratio; + break; + + case "bottom": + $r1 -= $right * $ratio; + $r2 -= $left * $ratio; + $x += $left * $ratio; + $y -= $bottom * $ratio; + $length -= $left * $ratio + $right * $ratio; + break; + + case "left": + $r1 -= $top * $ratio; + $r2 -= $bottom * $ratio; + $x += $left * $ratio; + $y += $top * $ratio; + $length -= $top * $ratio + $bottom * $ratio; + break; + + case "right": + $r1 -= $bottom * $ratio; + $r2 -= $top * $ratio; + $x -= $right * $ratio; + $y += $top * $ratio; + $length -= $top * $ratio + $bottom * $ratio; + break; + + default: + return; + } + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_double($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + list($top, $right, $bottom, $left) = $widths; + + $third_widths = [$top / 3, $right / 3, $bottom / 3, $left / 3]; + + // draw the outer border + $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2); + + $this->_apply_ratio($side, 2 / 3, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); + + $this->_border_solid($x, $y, $length, $color, $third_widths, $side, $corner_style, $r1, $r2); + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_groove($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + list($top, $right, $bottom, $left) = $widths; + + $half_widths = [$top / 2, $right / 2, $bottom / 2, $left / 2]; + + $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); + + $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); + + $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_ridge($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + list($top, $right, $bottom, $left) = $widths; + + $half_widths = [$top / 2, $right / 2, $bottom / 2, $left / 2]; + + $this->_border_outset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); + + $this->_apply_ratio($side, 0.5, $top, $right, $bottom, $left, $x, $y, $length, $r1, $r2); + + $this->_border_inset($x, $y, $length, $color, $half_widths, $side, $corner_style, $r1, $r2); + } + + /** + * @param $c + * @return mixed + */ + protected function _tint($c) + { + if (!is_numeric($c)) { + return $c; + } + + return min(1, $c + 0.16); + } + + /** + * @param $c + * @return mixed + */ + protected function _shade($c) + { + if (!is_numeric($c)) { + return $c; + } + + return max(0, $c - 0.33); + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_inset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + switch ($side) { + case "top": + case "left": + $shade = array_map([$this, "_shade"], $color); + $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2); + break; + + case "bottom": + case "right": + $tint = array_map([$this, "_tint"], $color); + $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2); + break; + + default: + return; + } + } + + /** + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param int $r1 + * @param int $r2 + */ + protected function _border_outset($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $r1 = 0, $r2 = 0) + { + switch ($side) { + case "top": + case "left": + $tint = array_map([$this, "_tint"], $color); + $this->_border_solid($x, $y, $length, $tint, $widths, $side, $corner_style, $r1, $r2); + break; + + case "bottom": + case "right": + $shade = array_map([$this, "_shade"], $color); + $this->_border_solid($x, $y, $length, $shade, $widths, $side, $corner_style, $r1, $r2); + break; + + default: + return; + } + } + + /** + * Draws a solid, dotted, or dashed line, observing the border radius + * + * @param $x + * @param $y + * @param $length + * @param $color + * @param $widths + * @param $side + * @param string $corner_style + * @param $pattern_name + * @param int $r1 + * @param int $r2 + * + * @var $top + */ + protected function _border_line($x, $y, $length, $color, $widths, $side, $corner_style = "bevel", $pattern_name, $r1 = 0, $r2 = 0) + { + /** used by $$side */ + list($top, $right, $bottom, $left) = $widths; + $width = $$side; + + $pattern = $this->_get_dash_pattern($pattern_name, $width); + + $half_width = $width / 2; + $r1 -= $half_width; + $r2 -= $half_width; + $adjust = $r1 / 80; + $length -= $width; + + switch ($side) { + case "top": + $x += $half_width; + $y += $half_width; + + if ($r1 > 0) { + $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 90 - $adjust, 135 + $adjust, $color, $width, $pattern); + } + + $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern); + + if ($r2 > 0) { + $this->_canvas->arc($x + $length - $r2, $y + $r2, $r2, $r2, 45 - $adjust, 90 + $adjust, $color, $width, $pattern); + } + break; + + case "bottom": + $x += $half_width; + $y -= $half_width; + + if ($r1 > 0) { + $this->_canvas->arc($x + $r1, $y - $r1, $r1, $r1, 225 - $adjust, 270 + $adjust, $color, $width, $pattern); + } + + $this->_canvas->line($x + $r1, $y, $x + $length - $r2, $y, $color, $width, $pattern); + + if ($r2 > 0) { + $this->_canvas->arc($x + $length - $r2, $y - $r2, $r2, $r2, 270 - $adjust, 315 + $adjust, $color, $width, $pattern); + } + break; + + case "left": + $y += $half_width; + $x += $half_width; + + if ($r1 > 0) { + $this->_canvas->arc($x + $r1, $y + $r1, $r1, $r1, 135 - $adjust, 180 + $adjust, $color, $width, $pattern); + } + + $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern); + + if ($r2 > 0) { + $this->_canvas->arc($x + $r2, $y + $length - $r2, $r2, $r2, 180 - $adjust, 225 + $adjust, $color, $width, $pattern); + } + break; + + case "right": + $y += $half_width; + $x -= $half_width; + + if ($r1 > 0) { + $this->_canvas->arc($x - $r1, $y + $r1, $r1, $r1, 0 - $adjust, 45 + $adjust, $color, $width, $pattern); + } + + $this->_canvas->line($x, $y + $r1, $x, $y + $length - $r2, $color, $width, $pattern); + + if ($r2 > 0) { + $this->_canvas->arc($x - $r2, $y + $length - $r2, $r2, $r2, 315 - $adjust, 360 + $adjust, $color, $width, $pattern); + } + break; + } + } + + /** + * @param $opacity + */ + protected function _set_opacity($opacity) + { + if (is_numeric($opacity) && $opacity <= 1.0 && $opacity >= 0.0) { + $this->_canvas->set_opacity($opacity); + } + } + + /** + * @param $box + * @param string $color + * @param array $style + */ + protected function _debug_layout($box, $color = "red", $style = []) + { + $this->_canvas->rectangle($box[0], $box[1], $box[2], $box[3], Color::parse($color), 0.1, $style); + } + + /** + * @param float $img_width + * @param float $img_height + * @param float $container_width + * @param float $container_height + * @param array|string $bg_resize + * @param int $dpi + * @return array + */ + protected function _resize_background_image( + $img_width, + $img_height, + $container_width, + $container_height, + $bg_resize, + $dpi + ) { + // We got two some specific numbers and/or auto definitions + if (is_array($bg_resize)) { + $is_auto_width = $bg_resize[0] === 'auto'; + if ($is_auto_width) { + $new_img_width = $img_width; + } else { + $new_img_width = $bg_resize[0]; + if (Helpers::is_percent($new_img_width)) { + $new_img_width = round(($container_width / 100) * (float)$new_img_width); + } else { + $new_img_width = round($new_img_width * $dpi / 72); + } + } + + $is_auto_height = $bg_resize[1] === 'auto'; + if ($is_auto_height) { + $new_img_height = $img_height; + } else { + $new_img_height = $bg_resize[1]; + if (Helpers::is_percent($new_img_height)) { + $new_img_height = round(($container_height / 100) * (float)$new_img_height); + } else { + $new_img_height = round($new_img_height * $dpi / 72); + } + } + + // if one of both was set to auto the other one needs to scale proportionally + if ($is_auto_width !== $is_auto_height) { + if ($is_auto_height) { + $new_img_height = round($new_img_width * ($img_height / $img_width)); + } else { + $new_img_width = round($new_img_height * ($img_width / $img_height)); + } + } + } else { + $container_ratio = $container_height / $container_width; + + if ($bg_resize === 'cover' || $bg_resize === 'contain') { + $img_ratio = $img_height / $img_width; + + if ( + ($bg_resize === 'cover' && $container_ratio > $img_ratio) || + ($bg_resize === 'contain' && $container_ratio < $img_ratio) + ) { + $new_img_height = $container_height; + $new_img_width = round($container_height / $img_ratio); + } else { + $new_img_width = $container_width; + $new_img_height = round($container_width * $img_ratio); + } + } else { + $new_img_width = $img_width; + $new_img_height = $img_height; + } + } + + return [$new_img_width, $new_img_height]; + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/Block.php b/vendor/dompdf/dompdf/src/Renderer/Block.php new file mode 100644 index 0000000..1a054e3 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/Block.php @@ -0,0 +1,266 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\AbstractFrameDecorator; +use Dompdf\Helpers; + +/** + * Renders block frames + * + * @package dompdf + */ +class Block extends AbstractRenderer +{ + + /** + * @param Frame $frame + */ + function render(Frame $frame) + { + $style = $frame->get_style(); + $node = $frame->get_node(); + $dompdf = $this->_dompdf; + $options = $dompdf->getOptions(); + + list($x, $y, $w, $h) = $frame->get_border_box(); + + $this->_set_opacity($frame->get_opacity($style->opacity)); + + if ($node->nodeName === "body") { + $h = $frame->get_containing_block("h") - (float)$style->length_in_pt([ + $style->margin_top, + $style->border_top_width, + $style->border_bottom_width, + $style->margin_bottom], + (float)$style->length_in_pt($style->width)); + } + + // Handle anchors & links + if ($node->nodeName === "a" && $href = $node->getAttribute("href")) { + $href = Helpers::build_url($dompdf->getProtocol(), $dompdf->getBaseHost(), $dompdf->getBasePath(), $href); + $this->_canvas->add_link($href, $x, $y, (float)$w, (float)$h); + } + + // Draw our background, border and content + list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); + + if ($tl + $tr + $br + $bl > 0) { + $this->_canvas->clipping_roundrectangle($x, $y, (float)$w, (float)$h, $tl, $tr, $br, $bl); + } + + if (($bg = $style->background_color) !== "transparent") { + $this->_canvas->filled_rectangle($x, $y, (float)$w, (float)$h, $bg); + } + + if (($url = $style->background_image) && $url !== "none") { + $this->_background_image($url, $x, $y, $w, $h, $style); + } + + if ($tl + $tr + $br + $bl > 0) { + $this->_canvas->clipping_end(); + } + + $border_box = [$x, $y, $w, $h]; + $this->_render_border($frame, $border_box); + $this->_render_outline($frame, $border_box); + + if ($options->getDebugLayout()) { + if ($options->getDebugLayoutBlocks()) { + $this->_debug_layout($frame->get_border_box(), "red"); + if ($options->getDebugLayoutPaddingBox()) { + $this->_debug_layout($frame->get_padding_box(), "red", [0.5, 0.5]); + } + } + + if ($options->getDebugLayoutLines() && $frame->get_decorator()) { + foreach ($frame->get_decorator()->get_line_boxes() as $line) { + $frame->_debug_layout([$line->x, $line->y, $line->w, $line->h], "orange"); + } + } + } + + $id = $frame->get_node()->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + } + + /** + * @param AbstractFrameDecorator $frame + * @param null $border_box + * @param string $corner_style + */ + protected function _render_border(AbstractFrameDecorator $frame, $border_box = null, $corner_style = "bevel") + { + $style = $frame->get_style(); + $bp = $style->get_border_properties(); + + if (empty($border_box)) { + $border_box = $frame->get_border_box(); + } + + // find the radius + $radius = $style->get_computed_border_radius($border_box[2], $border_box[3]); // w, h + + // Short-cut: If all the borders are "solid" with the same color and style, and no radius, we'd better draw a rectangle + if ( + in_array($bp["top"]["style"], ["solid", "dashed", "dotted"]) && + $bp["top"] == $bp["right"] && + $bp["right"] == $bp["bottom"] && + $bp["bottom"] == $bp["left"] && + array_sum($radius) == 0 + ) { + $props = $bp["top"]; + if ($props["color"] === "transparent" || $props["width"] <= 0) { + return; + } + + list($x, $y, $w, $h) = $border_box; + $width = (float)$style->length_in_pt($props["width"]); + $pattern = $this->_get_dash_pattern($props["style"], $width); + $this->_canvas->rectangle($x + $width / 2, $y + $width / 2, (float)$w - $width, (float)$h - $width, $props["color"], $width, $pattern); + return; + } + + // Do it the long way + $widths = [ + (float)$style->length_in_pt($bp["top"]["width"]), + (float)$style->length_in_pt($bp["right"]["width"]), + (float)$style->length_in_pt($bp["bottom"]["width"]), + (float)$style->length_in_pt($bp["left"]["width"]) + ]; + + foreach ($bp as $side => $props) { + list($x, $y, $w, $h) = $border_box; + $length = 0; + $r1 = 0; + $r2 = 0; + + if (!$props["style"] || + $props["style"] === "none" || + $props["width"] <= 0 || + $props["color"] == "transparent" + ) { + continue; + } + + switch ($side) { + case "top": + $length = (float)$w; + $r1 = $radius["top-left"]; + $r2 = $radius["top-right"]; + break; + + case "bottom": + $length = (float)$w; + $y += (float)$h; + $r1 = $radius["bottom-left"]; + $r2 = $radius["bottom-right"]; + break; + + case "left": + $length = (float)$h; + $r1 = $radius["top-left"]; + $r2 = $radius["bottom-left"]; + break; + + case "right": + $length = (float)$h; + $x += (float)$w; + $r1 = $radius["top-right"]; + $r2 = $radius["bottom-right"]; + break; + default: + break; + } + $method = "_border_" . $props["style"]; + + // draw rounded corners + $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style, $r1, $r2); + } + } + + /** + * @param AbstractFrameDecorator $frame + * @param null $border_box + * @param string $corner_style + */ + protected function _render_outline(AbstractFrameDecorator $frame, $border_box = null, $corner_style = "bevel") + { + $style = $frame->get_style(); + + $props = [ + "width" => $style->outline_width, + "style" => $style->outline_style, + "color" => $style->outline_color, + ]; + + if (!$props["style"] || $props["style"] === "none" || $props["width"] <= 0) { + return; + } + + if (empty($border_box)) { + $border_box = $frame->get_border_box(); + } + + $offset = (float)$style->length_in_pt($props["width"]); + $pattern = $this->_get_dash_pattern($props["style"], $offset); + + // If the outline style is "solid" we'd better draw a rectangle + if (in_array($props["style"], ["solid", "dashed", "dotted"])) { + $border_box[0] -= $offset / 2; + $border_box[1] -= $offset / 2; + $border_box[2] += $offset; + $border_box[3] += $offset; + + list($x, $y, $w, $h) = $border_box; + $this->_canvas->rectangle($x, $y, (float)$w, (float)$h, $props["color"], $offset, $pattern); + return; + } + + $border_box[0] -= $offset; + $border_box[1] -= $offset; + $border_box[2] += $offset * 2; + $border_box[3] += $offset * 2; + + $method = "_border_" . $props["style"]; + $widths = array_fill(0, 4, (float)$style->length_in_pt($props["width"])); + $sides = ["top", "right", "left", "bottom"]; + $length = 0; + + foreach ($sides as $side) { + list($x, $y, $w, $h) = $border_box; + + switch ($side) { + case "top": + $length = (float)$w; + break; + + case "bottom": + $length = (float)$w; + $y += (float)$h; + break; + + case "left": + $length = (float)$h; + break; + + case "right": + $length = (float)$h; + $x += (float)$w; + break; + default: + break; + } + + $this->$method($x, $y, $length, $props["color"], $widths, $side, $corner_style); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/Image.php b/vendor/dompdf/dompdf/src/Renderer/Image.php new file mode 100644 index 0000000..afcaa90 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/Image.php @@ -0,0 +1,143 @@ + + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Frame; +use Dompdf\Image\Cache; + +/** + * Image renderer + * + * @access private + * @package dompdf + */ +class Image extends Block +{ + + /** + * @param Frame $frame + */ + function render(Frame $frame) + { + // Render background & borders + $style = $frame->get_style(); + $cb = $frame->get_containing_block(); + list($x, $y, $w, $h) = $frame->get_border_box(); + + if ($w === 0.0 || $h === 0.0) { + return; + } + + $this->_set_opacity($frame->get_opacity($style->opacity)); + + list($tl, $tr, $br, $bl) = $style->get_computed_border_radius($w, $h); + + $has_border_radius = $tl + $tr + $br + $bl > 0; + + if ($has_border_radius) { + $this->_canvas->clipping_roundrectangle($x, $y, (float)$w, (float)$h, $tl, $tr, $br, $bl); + } + + if (($bg = $style->background_color) !== "transparent") { + $this->_canvas->filled_rectangle($x, $y, (float)$w, (float)$h, $bg); + } + + if (($url = $style->background_image) && $url !== "none") { + $this->_background_image($url, $x, $y, $w, $h, $style); + } + + if ($has_border_radius) { + $this->_canvas->clipping_end(); + } + + $this->_render_border($frame); + $this->_render_outline($frame); + + list($x, $y) = $frame->get_padding_box(); + + $x += (float)$style->length_in_pt($style->padding_left, $cb["w"]); + $y += (float)$style->length_in_pt($style->padding_top, $cb["h"]); + + $w = (float)$style->length_in_pt($style->width, $cb["w"]); + $h = (float)$style->length_in_pt($style->height, $cb["h"]); + + if ($has_border_radius) { + list($wt, $wr, $wb, $wl) = [ + $style->border_top_width, + $style->border_right_width, + $style->border_bottom_width, + $style->border_left_width, + ]; + + // we have to get the "inner" radius + if ($tl > 0) { + $tl -= ($wt + $wl) / 2; + } + if ($tr > 0) { + $tr -= ($wt + $wr) / 2; + } + if ($br > 0) { + $br -= ($wb + $wr) / 2; + } + if ($bl > 0) { + $bl -= ($wb + $wl) / 2; + } + + $this->_canvas->clipping_roundrectangle($x, $y, $w, $h, $tl, $tr, $br, $bl); + } + + $src = $frame->get_image_url(); + $alt = null; + + if (Cache::is_broken($src) && + $alt = $frame->get_node()->getAttribute("alt") + ) { + $font = $style->font_family; + $size = $style->font_size; + $spacing = $style->word_spacing; + $this->_canvas->text( + $x, + $y, + $alt, + $font, + $size, + $style->color, + $spacing + ); + } else { + $this->_canvas->image($src, $x, $y, $w, $h, $style->image_resolution); + } + + if ($has_border_radius) { + $this->_canvas->clipping_end(); + } + + if ($msg = $frame->get_image_msg()) { + $parts = preg_split("/\s*\n\s*/", $msg); + $height = 10; + $_y = $alt ? $y + $h - count($parts) * $height : $y; + + foreach ($parts as $i => $_part) { + $this->_canvas->text($x, $_y + $i * $height, $_part, "times", $height * 0.8, [0.5, 0.5, 0.5]); + } + } + + if ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutBlocks()) { + $this->_debug_layout($frame->get_border_box(), "blue"); + if ($this->_dompdf->getOptions()->getDebugLayoutPaddingBox()) { + $this->_debug_layout($frame->get_padding_box(), "blue", [0.5, 0.5]); + } + } + + $id = $frame->get_node()->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/Inline.php b/vendor/dompdf/dompdf/src/Renderer/Inline.php new file mode 100644 index 0000000..a258782 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/Inline.php @@ -0,0 +1,158 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Frame; +use Dompdf\Helpers; + +/** + * Renders inline frames + * + * @access private + * @package dompdf + */ +class Inline extends AbstractRenderer +{ + function render(Frame $frame) + { + if (!$frame->get_first_child()) { + return; // No children, no service + } + + $style = $frame->get_style(); + $dompdf = $this->_dompdf; + + // Draw the left border if applicable + $bp = $style->get_border_properties(); + $widths = [ + (float)$style->length_in_pt($bp["top"]["width"]), + (float)$style->length_in_pt($bp["right"]["width"]), + (float)$style->length_in_pt($bp["bottom"]["width"]), + (float)$style->length_in_pt($bp["left"]["width"]) + ]; + + // Draw the background & border behind each child. To do this we need + // to figure out just how much space each child takes: + list($x, $y) = $frame->get_first_child()->get_position(); + + $this->_set_opacity($frame->get_opacity($style->opacity)); + + $do_debug_layout_line = $dompdf->getOptions()->getDebugLayout() + && $dompdf->getOptions()->getDebugLayoutInline(); + + list($w, $h) = $this->get_child_size($frame, $do_debug_layout_line); + + // make sure the border and background start inside the left margin + $left_margin = (float)$style->length_in_pt($style->margin_left); + $x += $left_margin; + + // Handle the last child + if (($bg = $style->background_color) !== "transparent") { + $this->_canvas->filled_rectangle($x + $widths[3], $y + $widths[0], $w, $h, $bg); + } + + //On continuation lines (after line break) of inline elements, the style got copied. + //But a non repeatable background image should not be repeated on the next line. + //But removing the background image above has never an effect, and removing it below + //removes it always, even on the initial line. + //Need to handle it elsewhere, e.g. on certain ...clone()... usages. + // Repeat not given: default is Style::__construct + // ... && (!($repeat = $style->background_repeat) || $repeat === "repeat" ... + //different position? $this->_background_image($url, $x, $y, $w, $h, $style); + if (($url = $style->background_image) && $url !== "none") { + $this->_background_image($url, $x + $widths[3], $y + $widths[0], $w, $h, $style); + } + + // Add the border widths + $w += (float)$widths[1] + (float)$widths[3]; + $h += (float)$widths[0] + (float)$widths[2]; + + // If this is the first row, draw the left border too + if ($bp["left"]["style"] !== "none" && $bp["left"]["color"] !== "transparent" && $widths[3] > 0) { + $method = "_border_" . $bp["left"]["style"]; + $this->$method($x, $y, $h, $bp["left"]["color"], $widths, "left"); + } + + // Draw the top & bottom borders + if ($bp["top"]["style"] !== "none" && $bp["top"]["color"] !== "transparent" && $widths[0] > 0) { + $method = "_border_" . $bp["top"]["style"]; + $this->$method($x, $y, $w, $bp["top"]["color"], $widths, "top"); + } + + if ($bp["bottom"]["style"] !== "none" && $bp["bottom"]["color"] !== "transparent" && $widths[2] > 0) { + $method = "_border_" . $bp["bottom"]["style"]; + $this->$method($x, $y + $h, $w, $bp["bottom"]["color"], $widths, "bottom"); + } + + // Helpers::var_dump(get_class($frame->get_next_sibling())); + // $last_row = get_class($frame->get_next_sibling()) !== 'Inline'; + // Draw the right border if this is the last row + if ($bp["right"]["style"] !== "none" && $bp["right"]["color"] !== "transparent" && $widths[1] > 0) { + $method = "_border_" . $bp["right"]["style"]; + $this->$method($x + $w, $y, $h, $bp["right"]["color"], $widths, "right"); + } + + $node = $frame->get_node(); + $id = $node->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + + // Only two levels of links frames + $is_link_node = $node->nodeName === "a"; + if ($is_link_node) { + if (($name = $node->getAttribute("name"))) { + $this->_canvas->add_named_dest($name); + } + } + + if ($frame->get_parent() && $frame->get_parent()->get_node()->nodeName === "a") { + $link_node = $frame->get_parent()->get_node(); + } + + // Handle anchors & links + if ($is_link_node) { + if ($href = $node->getAttribute("href")) { + $href = Helpers::build_url($dompdf->getProtocol(), $dompdf->getBaseHost(), $dompdf->getBasePath(), $href); + $this->_canvas->add_link($href, $x, $y, $w, $h); + } + } + } + + protected function get_child_size(Frame $frame, bool $do_debug_layout_line): array { + $w = 0.0; + $h = 0.0; + + foreach ($frame->get_children() as $child) { + if ($child->get_node()->nodeValue === ' ' && $child->get_prev_sibling() && !$child->get_next_sibling()) { + break; + } + list($child_x, $child_y, $child_w, $child_h) = $child->get_padding_box(); + + $child_h2 = 0.0; + + if ($child_w === 'auto') { + list($child_w, $child_h2) = $this->get_child_size($child, $do_debug_layout_line); + $w += (float)$child_w; + } else { + $w += (float)$child_w; + } + + $h = max($h, $child_h, $child_h2); + + if ($do_debug_layout_line) { + $this->_debug_layout($child->get_border_box(), "blue"); + if ($this->_dompdf->getOptions()->getDebugLayoutPaddingBox()) { + $this->_debug_layout($child->get_padding_box(), "blue", [0.5, 0.5]); + } + } + } + + return [$w, $h]; + } +} \ No newline at end of file diff --git a/vendor/dompdf/dompdf/src/Renderer/ListBullet.php b/vendor/dompdf/dompdf/src/Renderer/ListBullet.php new file mode 100644 index 0000000..d3df029 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/ListBullet.php @@ -0,0 +1,257 @@ + + * @author Helmut Tischer + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Helpers; +use Dompdf\Frame; +use Dompdf\Image\Cache; +use Dompdf\FrameDecorator\ListBullet as ListBulletFrameDecorator; + +/** + * Renders list bullets + * + * @access private + * @package dompdf + */ +class ListBullet extends AbstractRenderer +{ + /** + * @param $type + * @return mixed|string + */ + static function get_counter_chars($type) + { + static $cache = []; + + if (isset($cache[$type])) { + return $cache[$type]; + } + + $uppercase = false; + $text = ""; + + switch ($type) { + case "decimal-leading-zero": + case "decimal": + case "1": + return "0123456789"; + + case "upper-alpha": + case "upper-latin": + case "A": + $uppercase = true; + case "lower-alpha": + case "lower-latin": + case "a": + $text = "abcdefghijklmnopqrstuvwxyz"; + break; + + case "upper-roman": + case "I": + $uppercase = true; + case "lower-roman": + case "i": + $text = "ivxlcdm"; + break; + + case "lower-greek": + for ($i = 0; $i < 24; $i++) { + $text .= Helpers::unichr($i + 944); + } + break; + } + + if ($uppercase) { + $text = strtoupper($text); + } + + return $cache[$type] = "$text."; + } + + /** + * @param integer $n + * @param string $type + * @param integer $pad + * + * @return string + */ + private function make_counter($n, $type, $pad = null) + { + $n = intval($n); + $text = ""; + $uppercase = false; + + switch ($type) { + case "decimal-leading-zero": + case "decimal": + case "1": + if ($pad) { + $text = str_pad($n, $pad, "0", STR_PAD_LEFT); + } else { + $text = $n; + } + break; + + case "upper-alpha": + case "upper-latin": + case "A": + $uppercase = true; + case "lower-alpha": + case "lower-latin": + case "a": + $text = chr(($n % 26) + ord('a') - 1); + break; + + case "upper-roman": + case "I": + $uppercase = true; + case "lower-roman": + case "i": + $text = Helpers::dec2roman($n); + break; + + case "lower-greek": + $text = Helpers::unichr($n + 944); + break; + } + + if ($uppercase) { + $text = strtoupper($text); + } + + return "$text."; + } + + /** + * @param Frame $frame + */ + function render(Frame $frame) + { + $style = $frame->get_style(); + $font_size = $style->font_size; + $line_height = $style->line_height; + + $this->_set_opacity($frame->get_opacity($style->opacity)); + + $li = $frame->get_parent(); + + // Don't render bullets twice if if was split + if ($li->_splitted) { + return; + } + + // Handle list-style-image + // If list style image is requested but missing, fall back to predefined types + if ($style->list_style_image !== "none" && !Cache::is_broken($img = $frame->get_image_url())) { + list($x, $y) = $frame->get_position(); + + //For expected size and aspect, instead of box size, use image natural size scaled to DPI. + // Resample the bullet image to be consistent with 'auto' sized images + // See also Image::get_min_max_width + // Tested php ver: value measured in px, suffix "px" not in value: rtrim unnecessary. + //$w = $frame->get_width(); + //$h = $frame->get_height(); + list($width, $height) = Helpers::dompdf_getimagesize($img, $this->_dompdf->getHttpContext()); + $dpi = $this->_dompdf->getOptions()->getDpi(); + $w = ((float)rtrim($width, "px") * 72) / $dpi; + $h = ((float)rtrim($height, "px") * 72) / $dpi; + + $x -= $w; + $y -= ($line_height - $font_size) / 2; //Reverse hinting of list_bullet_positioner + + $this->_canvas->image($img, $x, $y, $w, $h); + } else { + $bullet_style = $style->list_style_type; + + $fill = false; + + switch ($bullet_style) { + default: + /** @noinspection PhpMissingBreakStatementInspection */ + case "disc": + $fill = true; + + case "circle": + list($x, $y) = $frame->get_position(); + $r = ($font_size * (ListBulletFrameDecorator::BULLET_SIZE /*-ListBulletFrameDecorator::BULLET_THICKNESS*/)) / 2; + $x -= $font_size * (ListBulletFrameDecorator::BULLET_SIZE / 2); + $y += ($font_size * (1 - ListBulletFrameDecorator::BULLET_DESCENT)) / 2; + $o = $font_size * ListBulletFrameDecorator::BULLET_THICKNESS; + $this->_canvas->circle($x, $y, $r, $style->color, $o, null, $fill); + break; + + case "square": + list($x, $y) = $frame->get_position(); + $w = $font_size * ListBulletFrameDecorator::BULLET_SIZE; + $x -= $w; + $y += ($font_size * (1 - ListBulletFrameDecorator::BULLET_DESCENT - ListBulletFrameDecorator::BULLET_SIZE)) / 2; + $this->_canvas->filled_rectangle($x, $y, $w, $w, $style->color); + break; + + case "decimal-leading-zero": + case "decimal": + case "lower-alpha": + case "lower-latin": + case "lower-roman": + case "lower-greek": + case "upper-alpha": + case "upper-latin": + case "upper-roman": + case "1": // HTML 4.0 compatibility + case "a": + case "i": + case "A": + case "I": + $pad = null; + if ($bullet_style === "decimal-leading-zero") { + $pad = strlen($li->get_parent()->get_node()->getAttribute("dompdf-children-count")); + } + + $node = $frame->get_node(); + + if (!$node->hasAttribute("dompdf-counter")) { + return; + } + + $index = $node->getAttribute("dompdf-counter"); + $text = $this->make_counter($index, $bullet_style, $pad); + + if (trim($text) == "") { + return; + } + + $spacing = 0; + $font_family = $style->font_family; + + $line = $li->get_containing_line(); + list($x, $y) = [$frame->get_position("x"), $line->y]; + + $x -= $this->_dompdf->getFontMetrics()->getTextWidth($text, $font_family, $font_size, $spacing); + + // Take line-height into account + // TODO: should the line height take into account the line height of the containing block (per previous logic) + // $line_height = (float)$style->length_in_pt($style->line_height, $frame->get_containing_block("h")); + $line_height = $style->line_height; + $y += ($line_height - $font_size) / 4; // FIXME I thought it should be 2, but 4 gives better results + + $this->_canvas->text($x, $y, $text, + $font_family, $font_size, + $style->color, $spacing); + + case "none": + break; + } + } + + $id = $frame->get_node()->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/TableCell.php b/vendor/dompdf/dompdf/src/Renderer/TableCell.php new file mode 100644 index 0000000..25bdb56 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/TableCell.php @@ -0,0 +1,219 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Frame; +use Dompdf\FrameDecorator\Table; + +/** + * Renders table cells + * + * @package dompdf + */ +class TableCell extends Block +{ + + /** + * @param Frame $frame + */ + function render(Frame $frame) + { + $style = $frame->get_style(); + + if (trim($frame->get_node()->nodeValue) === "" && $style->empty_cells === "hide") { + return; + } + + $id = $frame->get_node()->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + + $this->_set_opacity($frame->get_opacity($style->opacity)); + list($x, $y, $w, $h) = $frame->get_border_box(); + + + $table = Table::find_parent_table($frame); + + if ($table->get_style()->border_collapse !== "collapse") { + if (($bg = $style->background_color) !== "transparent") { + $this->_canvas->filled_rectangle($x, $y, (float)$w, (float)$h, $bg); + } + + if (($url = $style->background_image) && $url !== "none") { + $this->_background_image($url, $x, $y, $w, $h, $style); + } + + $this->_render_border($frame); + $this->_render_outline($frame); + return; + } + + // The collapsed case is slightly complicated... + // @todo Add support for outlines here + + $background_position_x = $x; $background_position_y = $y; $background_width = (float)$w; $background_height = (float)$h; + $border_right_width = 0; $border_left_width = 0; $border_top_width = 0; $border_bottom_width = 0; + $border_right_length = 0; $border_left_length = 0; $border_top_length = 0; $border_bottom_length = 0; + + $cellmap = $table->get_cellmap(); + $cells = $cellmap->get_spanned_cells($frame); + + if (is_null($cells)) { + return; + } + + $num_rows = $cellmap->get_num_rows(); + $num_cols = $cellmap->get_num_cols(); + + // Determine the top row spanned by this cell + $i = $cells["rows"][0]; + $top_row = $cellmap->get_row($i); + + // Determine if this cell borders on the bottom of the table. If so, + // then we draw its bottom border. Otherwise the next row down will + // draw its top border instead. + if (in_array($num_rows - 1, $cells["rows"])) { + $draw_bottom = true; + $bottom_row = $cellmap->get_row($num_rows - 1); + } else { + $draw_bottom = false; + } + + // Draw the horizontal borders + $border_function_calls = []; + foreach ($cells["columns"] as $j) { + $bp = $cellmap->get_border_properties($i, $j); + $col = $cellmap->get_column($j); + + $x = $col["x"] - $bp["left"]["width"] / 2; + $y = $top_row["y"] - $bp["top"]["width"] / 2; + $w = $col["used-width"] + ($bp["left"]["width"] + $bp["right"]["width"]) / 2; + + if ($bp["top"]["width"] > 0) { + $widths = [ + (float)$bp["top"]["width"], + (float)$bp["right"]["width"], + (float)$bp["bottom"]["width"], + (float)$bp["left"]["width"] + ]; + + $border_top_width = max($border_top_width, $widths[0]); + + $method = "_border_" . $bp["top"]["style"]; + $border_function_calls[] = [$method, [$x, $y, $w, $bp["top"]["color"], $widths, "top", "square"]]; + } + + if ($draw_bottom) { + $bp = $cellmap->get_border_properties($num_rows - 1, $j); + if ($bp["bottom"]["width"] <= 0) { + continue; + } + + $widths = [ + (float)$bp["top"]["width"], + (float)$bp["right"]["width"], + (float)$bp["bottom"]["width"], + (float)$bp["left"]["width"] + ]; + + $y = $bottom_row["y"] + $bottom_row["height"] + $bp["bottom"]["width"] / 2; + $border_bottom_width = max($border_bottom_width, $widths[2]); + + $method = "_border_" . $bp["bottom"]["style"]; + $border_function_calls[] = [$method, [$x, $y, $w, $bp["bottom"]["color"], $widths, "bottom", "square"]]; + } else { + $adjacent_bp = $cellmap->get_border_properties($i+1, $j); + $border_bottom_width = max($border_bottom_width, $adjacent_bp["top"]["width"]); + } + } + + $j = $cells["columns"][0]; + + $left_col = $cellmap->get_column($j); + + if (in_array($num_cols - 1, $cells["columns"])) { + $draw_right = true; + $right_col = $cellmap->get_column($num_cols - 1); + } else { + $draw_right = false; + } + + // Draw the vertical borders + foreach ($cells["rows"] as $i) { + $bp = $cellmap->get_border_properties($i, $j); + $row = $cellmap->get_row($i); + + $x = $left_col["x"] - $bp["left"]["width"] / 2; + $y = $row["y"] - $bp["top"]["width"] / 2; + $h = $row["height"] + ($bp["top"]["width"] + $bp["bottom"]["width"]) / 2; + + if ($bp["left"]["width"] > 0) { + $widths = [ + (float)$bp["top"]["width"], + (float)$bp["right"]["width"], + (float)$bp["bottom"]["width"], + (float)$bp["left"]["width"] + ]; + + $border_left_width = max($border_left_width, $widths[3]); + + $method = "_border_" . $bp["left"]["style"]; + $border_function_calls[] = [$method, [$x, $y, $h, $bp["left"]["color"], $widths, "left", "square"]]; + } + + if ($draw_right) { + $bp = $cellmap->get_border_properties($i, $num_cols - 1); + if ($bp["right"]["width"] <= 0) { + continue; + } + + $widths = [ + (float)$bp["top"]["width"], + (float)$bp["right"]["width"], + (float)$bp["bottom"]["width"], + (float)$bp["left"]["width"] + ]; + + $x = $right_col["x"] + $right_col["used-width"] + $bp["right"]["width"] / 2; + $border_right_width = max($border_right_width, $widths[1]); + + $method = "_border_" . $bp["right"]["style"]; + $border_function_calls[] = [$method, [$x, $y, $h, $bp["right"]["color"], $widths, "right", "square"]]; + } else { + $adjacent_bp = $cellmap->get_border_properties($i, $j+1); + $border_right_width = max($border_right_width, $adjacent_bp["left"]["width"]); + } + } + + // Draw our background, border and content + if (($bg = $style->background_color) !== "transparent") { + $this->_canvas->filled_rectangle( + $background_position_x + ($border_left_width/2), + $background_position_y + ($border_top_width/2), + (float)$background_width - (($border_left_width + $border_right_width)/2), + (float)$background_height - (($border_top_width + $border_bottom_width)/2), + $bg + ); + } + if (($url = $style->background_image) && $url !== "none") { + $this->_background_image( + $url, + $background_position_x + ($border_left_width/2), + $background_position_y + ($border_top_width/2), + (float)$background_width - (($border_left_width + $border_right_width)/2), + (float)$background_height - (($border_top_width + $border_bottom_width)/2), + $style + ); + } + foreach ($border_function_calls as $border_function_call_params) + { + call_user_func_array([$this, $border_function_call_params[0]], $border_function_call_params[1]); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/TableRowGroup.php b/vendor/dompdf/dompdf/src/Renderer/TableRowGroup.php new file mode 100644 index 0000000..41ddd87 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/TableRowGroup.php @@ -0,0 +1,50 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Frame; + +/** + * Renders block frames + * + * @package dompdf + */ +class TableRowGroup extends Block +{ + + /** + * @param Frame $frame + */ + function render(Frame $frame) + { + $style = $frame->get_style(); + + $this->_set_opacity($frame->get_opacity($style->opacity)); + + $this->_render_border($frame); + $this->_render_outline($frame); + + if ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutBlocks()) { + $this->_debug_layout($frame->get_border_box(), "red"); + if ($this->_dompdf->getOptions()->getDebugLayoutPaddingBox()) { + $this->_debug_layout($frame->get_padding_box(), "red", [0.5, 0.5]); + } + } + + if ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutLines() && $frame->get_decorator()) { + foreach ($frame->get_decorator()->get_line_boxes() as $line) { + $frame->_debug_layout([$line->x, $line->y, $line->w, $line->h], "orange"); + } + } + + $id = $frame->get_node()->getAttribute("id"); + if (strlen($id) > 0) { + $this->_canvas->add_named_dest($id); + } + } +} diff --git a/vendor/dompdf/dompdf/src/Renderer/Text.php b/vendor/dompdf/dompdf/src/Renderer/Text.php new file mode 100644 index 0000000..ed458d9 --- /dev/null +++ b/vendor/dompdf/dompdf/src/Renderer/Text.php @@ -0,0 +1,167 @@ + + * @author Helmut Tischer + * @author Fabien Ménager + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace Dompdf\Renderer; + +use Dompdf\Adapter\CPDF; +use Dompdf\Frame; + +/** + * Renders text frames + * + * @package dompdf + */ +class Text extends AbstractRenderer +{ + /** Thickness of underline. Screen: 0.08, print: better less, e.g. 0.04 */ + const DECO_THICKNESS = 0.02; + + //Tweaking if $base and $descent are not accurate. + //Check method_exists( $this->_canvas, "get_cpdf" ) + //- For cpdf these can and must stay 0, because font metrics are used directly. + //- For other renderers, if different values are wanted, separate the parameter sets. + // But $size and $size-$height seem to be accurate enough + + /** Relative to bottom of text, as fraction of height */ + const UNDERLINE_OFFSET = 0.0; + + /** Relative to top of text */ + const OVERLINE_OFFSET = 0.0; + + /** Relative to centre of text. */ + const LINETHROUGH_OFFSET = 0.0; + + /** How far to extend lines past either end, in pt */ + const DECO_EXTENSION = 0.0; + + /** + * @param \Dompdf\FrameDecorator\Text $frame + */ + function render(Frame $frame) + { + $text = $frame->get_text(); + if (trim($text) === "") { + return; + } + + $style = $frame->get_style(); + list($x, $y) = $frame->get_position(); + $cb = $frame->get_containing_block(); + + if (($ml = $style->margin_left) === "auto" || $ml === "none") { + $ml = 0; + } + + if (($pl = $style->padding_left) === "auto" || $pl === "none") { + $pl = 0; + } + + if (($bl = $style->border_left_width) === "auto" || $bl === "none") { + $bl = 0; + } + + $x += (float)$style->length_in_pt([$ml, $pl, $bl], $cb["w"]); + + $font = $style->font_family; + $size = $style->font_size; + $frame_font_size = $frame->get_dompdf()->getFontMetrics()->getFontHeight($font, $size); + $word_spacing = $frame->get_text_spacing() + (float)$style->length_in_pt($style->word_spacing); + $char_spacing = (float)$style->length_in_pt($style->letter_spacing); + $width = $style->width; + + /*$text = str_replace( + array("{PAGE_NUM}"), + array($this->_canvas->get_page_number()), + $text + );*/ + + $this->_canvas->text($x, $y, $text, + $font, $size, + $style->color, $word_spacing, $char_spacing); + + $line = $frame->get_containing_line(); + + // FIXME Instead of using the tallest frame to position, + // the decoration, the text should be well placed + if (false && $line->tallest_frame) { + $base_frame = $line->tallest_frame; + $style = $base_frame->get_style(); + $size = $style->font_size; + } + + $line_thickness = $size * self::DECO_THICKNESS; + $underline_offset = $size * self::UNDERLINE_OFFSET; + $overline_offset = $size * self::OVERLINE_OFFSET; + $linethrough_offset = $size * self::LINETHROUGH_OFFSET; + $underline_position = -0.08; + + if ($this->_canvas instanceof CPDF) { + $cpdf_font = $this->_canvas->get_cpdf()->fonts[$style->font_family]; + + if (isset($cpdf_font["UnderlinePosition"])) { + $underline_position = $cpdf_font["UnderlinePosition"] / 1000; + } + + if (isset($cpdf_font["UnderlineThickness"])) { + $line_thickness = $size * ($cpdf_font["UnderlineThickness"] / 1000); + } + } + + $descent = $size * $underline_position; + $base = $frame_font_size; + + // Handle text decoration: + // http://www.w3.org/TR/CSS21/text.html#propdef-text-decoration + + // Draw all applicable text-decorations. Start with the root and work our way down. + $p = $frame; + $stack = []; + while ($p = $p->get_parent()) { + $stack[] = $p; + } + + while (isset($stack[0])) { + $f = array_pop($stack); + + if (($text_deco = $f->get_style()->text_decoration) === "none") { + continue; + } + + $deco_y = $y; //$line->y; + $color = $f->get_style()->color; + + switch ($text_deco) { + default: + continue 2; + + case "underline": + $deco_y += $base - $descent + $underline_offset + $line_thickness / 2; + break; + + case "overline": + $deco_y += $overline_offset + $line_thickness / 2; + break; + + case "line-through": + $deco_y += $base * 0.7 + $linethrough_offset; + break; + } + + $dx = 0; + $x1 = $x - self::DECO_EXTENSION; + $x2 = $x + $width + $dx + self::DECO_EXTENSION; + $this->_canvas->line($x1, $deco_y, $x2, $deco_y, $color, $line_thickness); + } + + if ($this->_dompdf->getOptions()->getDebugLayout() && $this->_dompdf->getOptions()->getDebugLayoutLines()) { + $text_width = $this->_dompdf->getFontMetrics()->getTextWidth($text, $font, $size); + $this->_debug_layout([$x, $y, $text_width + ($line->wc - 1) * $word_spacing, $frame_font_size], "orange", [0.5, 0.5]); + } + } +} diff --git a/vendor/fzaninotto/faker b/vendor/fzaninotto/faker new file mode 160000 index 0000000..ac73e52 --- /dev/null +++ b/vendor/fzaninotto/faker @@ -0,0 +1 @@ +Subproject commit ac73e5287024f5e98dd6d0bf10e6a6f7877b7513 diff --git a/vendor/kint-php/kint/LICENSE b/vendor/kint-php/kint/LICENSE new file mode 100644 index 0000000..01718d4 --- /dev/null +++ b/vendor/kint-php/kint/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Jonathan Vollebregt (jnvsor@gmail.com), Rokas Šleinius (raveren@gmail.com) + +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/kint-php/kint/README.md b/vendor/kint-php/kint/README.md new file mode 100644 index 0000000..b23f346 --- /dev/null +++ b/vendor/kint-php/kint/README.md @@ -0,0 +1,82 @@ +# Kint - debugging helper for PHP developers + +[![](https://travis-ci.org/kint-php/kint.svg?branch=master)](https://travis-ci.org/kint-php/kint) + +![Screenshot](https://kint-php.github.io/kint/images/intro.png) + +## What am I looking at? + +At first glance Kint is just a pretty replacement for **[var_dump()](https://secure.php.net/function.var_dump)**, **[print_r()](https://secure.php.net/function.print_r)** and **[debug_backtrace()](https://secure.php.net/function.debug_backtrace)**. + +However, it's much, *much* more than that. You will eventually wonder how you developed without it. + +## Installation + +One of the main goals of Kint is to be **zero setup**. + +[Download the file](https://raw.githubusercontent.com/kint-php/kint/master/build/kint.phar) and simply +```php ++ sign will open/close it and all its children. +* Triple clicking the + sign in will open/close everything on the page. +* Add heavy classes to the blacklist to improve performance: + `Kint\Parser\BlacklistPlugin::$shallow_blacklist[] = 'Psr\Container\ContainerInterface';` +* To change display theme, use `Kint\Renderer\RichRenderer::$theme = 'theme.css';`. You can pass the absolute path to a CSS file, or use one of the built in themes: + * `original.css` (default) + * `solarized.css` + * `solarized-dark.css` + * `aante-light.css` +* Kint has *keyboard shortcuts*! When Kint is visible, press D on the keyboard and you will be able to traverse the tree with arrows, HJKL, and TAB keys - and expand/collapse nodes with SPACE or ENTER. +* You can write plugins and wrapper functions to customize dump behavior! +* Read [the full documentation](https://kint-php.github.io/kint/) for more information + +## Authors + +[**Jonathan Vollebregt** (jnvsor)](https://github.com/jnvsor) +[**Rokas Šleinius** (raveren)](https://github.com/raveren) + +## License + +Licensed under the MIT License diff --git a/vendor/kint-php/kint/composer.json b/vendor/kint-php/kint/composer.json new file mode 100644 index 0000000..9fe64a4 --- /dev/null +++ b/vendor/kint-php/kint/composer.json @@ -0,0 +1,83 @@ +{ + "name": "kint-php/kint", + "description": "Kint - debugging tool for PHP developers", + "keywords": ["kint", "php", "debug"], + "type": "library", + "homepage": "https://kint-php.github.io/kint/", + "license": "MIT", + "authors": [ + { + "name": "Jonathan Vollebregt", + "homepage": "https://github.com/jnvsor" + }, + { + "name": "Rokas Šleinius", + "homepage": "https://github.com/raveren" + }, + { + "name": "Contributors", + "homepage": "https://github.com/kint-php/kint/graphs/contributors" + } + ], + "require": { + "php": ">=5.3.6" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "phpunit/phpunit": "^4.0", + "symfony/finder": "^2.0 || ^3.0 || ^4.0", + "seld/phar-utils": "^1.0", + "vimeo/psalm": "^3.0" + }, + "autoload": { + "files": ["init.php"], + "psr-4": { + "Kint\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Kint\\Test\\": "tests/" + } + }, + "config": { + "platform": { + "php": "7.3" + } + }, + "scripts": { + "post-update-cmd": "npm ci", + "post-install-cmd": "@post-update-cmd", + "clean": [ + "rm -rf resources/compiled/", + "rm -rf build/" + ], + "format": [ + "@format:php", + "@format:js", + "@format:sass" + ], + "format:php": "php-cs-fixer fix", + "format:js": "npm run format:js", + "format:sass": "npm run format:sass", + "build": [ + "@build:sass", + "@build:js", + "@build:php" + ], + "build:sass": "npm run build:sass", + "build:js": "npm run build:js", + "build:php": "php ./build.php", + "analyze": "psalm --show-info=false" + }, + "suggest": { + "kint-php/kint-twig": "Provides d() and s() functions in twig templates", + "kint-php/kint-js": "Provides a simplified dump to console.log()", + "ext-mbstring": "Provides string encoding detection", + "ext-iconv": "Provides fallback detection for ambiguous legacy string encodings such as the Windows and ISO 8859 code pages", + "ext-ctype": "Simple data type tests", + "symfony/polyfill-mbstring": "Replacement for ext-mbstring if missing", + "symfony/polyfill-iconv": "Replacement for ext-iconv if missing", + "symfony/polyfill-ctype": "Replacement for ext-ctype if missing" + } +} diff --git a/vendor/kint-php/kint/init.php b/vendor/kint-php/kint/init.php new file mode 100644 index 0000000..952e041 --- /dev/null +++ b/vendor/kint-php/kint/init.php @@ -0,0 +1,62 @@ += 0)); +\define('KINT_PHP70', (\version_compare(PHP_VERSION, '7.0') >= 0)); +\define('KINT_PHP72', (\version_compare(PHP_VERSION, '7.2') >= 0)); +\define('KINT_PHP73', (\version_compare(PHP_VERSION, '7.3') >= 0)); +\define('KINT_PHP74', (\version_compare(PHP_VERSION, '7.4') >= 0)); + +// Dynamic default settings +Kint::$file_link_format = \ini_get('xdebug.file_link_format'); +if (isset($_SERVER['DOCUMENT_ROOT'])) { + Kint::$app_root_dirs = array( + $_SERVER['DOCUMENT_ROOT'] => '', + \realpath($_SERVER['DOCUMENT_ROOT']) => '', + ); +} + +Utils::composerSkipFlags(); + +if ((!\defined('KINT_SKIP_FACADE') || !KINT_SKIP_FACADE) && !\class_exists('Kint')) { + \class_alias('Kint\\Kint', 'Kint'); +} + +if (!\defined('KINT_SKIP_HELPERS') || !KINT_SKIP_HELPERS) { + require_once __DIR__.'/init_helpers.php'; +} diff --git a/vendor/kint-php/kint/init_helpers.php b/vendor/kint-php/kint/init_helpers.php new file mode 100644 index 0000000..b961d67 --- /dev/null +++ b/vendor/kint-php/kint/init_helpers.php @@ -0,0 +1,84 @@ +dl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxwYXRoIGQ9Ik02IDdoMThsLTkgMTV6bTAgMzBoMThsLTkgMTV6bTAgNDVoMThsLTktMTV6bTAgMzBoMThsLTktMTV6bTAgMTJsMTggMThtLTE4IDBsMTgtMTgiIGZpbGw9IiM1NTUiLz48cGF0aCBkPSJNNiAxMjZsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlPSIjNTU1Ii8+PC9zdmc+") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #d7d7d7}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#06f;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:red}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #d7d7d7;background:#f8f8f8;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#f8f8f8;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#f8f8f8}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #d7d7d7;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#f8f8f8;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#f8f8f8;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f8f8f8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#f8f8f8;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #d7d7d7}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#f8f8f8;border:1px solid #d7d7d7;border-top:0}.kint-rich ul.kint-tabs>li{background:#f8f8f8;border:1px solid #d7d7d7;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#aaa;color:red}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#f8f8f8;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#aaa;color:red}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #d7d7d7;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#aaa}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #d7d7d7;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#f8f8f8;color:#1d1e1e}.kint-rich table td{background:#f8f8f8;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #aaa inset}.kint-rich table tr:hover var{color:red}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #f8f8f8}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #aaa;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#f8f8f8}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #aaa,0 1px #aaa,1px 0 #aaa,0 -1px #aaa;color:#f8f8f8;font-weight:bold}.kint-rich .kint-focused{box-shadow:0 0 3px 2px red}.kint-rich dt{font-weight:normal}.kint-rich dt.kint-parent{margin-top:4px}.kint-rich dl dl{margin-top:4px;padding-left:25px;border-left:none}.kint-rich>dl>dt{background:#f8f8f8}.kint-rich ul{margin:0;padding-left:0}.kint-rich ul:not(.kint-tabs)>li{border-left:0}.kint-rich ul.kint-tabs{background:#f8f8f8;border:1px solid #d7d7d7;border-width:0 1px 1px 1px;padding:4px 0 0 12px;margin-left:-1px;margin-top:-1px}.kint-rich ul.kint-tabs li,.kint-rich ul.kint-tabs li+li{margin:0 0 0 4px}.kint-rich ul.kint-tabs li{border-bottom-width:0;height:25px}.kint-rich ul.kint-tabs li:first-child{margin-left:0}.kint-rich ul.kint-tabs li.kint-active-tab{border-top:1px solid #d7d7d7;background:#fff;font-weight:bold;padding-top:0;border-bottom:1px solid #fff !important;margin-bottom:-1px}.kint-rich ul.kint-tabs li.kint-active-tab:hover{border-bottom:1px solid #fff}.kint-rich ul>li>pre{border:1px solid #d7d7d7}.kint-rich dt:hover+dd>ul{border-color:#aaa}.kint-rich pre{background:#fff;margin-top:4px;margin-left:25px}.kint-rich .kint-source{margin-left:-1px}.kint-rich .kint-source .kint-highlight{background:#cfc}.kint-rich .kint-parent.kint-show>.kint-search{border-bottom-width:1px}.kint-rich table td{background:#fff}.kint-rich table td>dl{padding:0;margin:0}.kint-rich table td>dl>dt.kint-parent{margin:0}.kint-rich table td:first-child,.kint-rich table td,.kint-rich table th{padding:2px 4px}.kint-rich table dd,.kint-rich table dt{background:#fff}.kint-rich table tr:hover>td{box-shadow:none;background:#cfc} diff --git a/vendor/kint-php/kint/resources/compiled/microtime.js b/vendor/kint-php/kint/resources/compiled/microtime.js new file mode 100644 index 0000000..20e3445 --- /dev/null +++ b/vendor/kint-php/kint/resources/compiled/microtime.js @@ -0,0 +1 @@ +void 0===window.kintMicrotimeInitialized&&(window.kintMicrotimeInitialized=1,window.addEventListener("load",function(){"use strict";var c={},i=Array.prototype.slice.call(document.querySelectorAll("[data-kint-microtime-group]"),0);i.forEach(function(i){if(i.querySelector(".kint-microtime-lap")){var t=i.getAttribute("data-kint-microtime-group"),e=parseFloat(i.querySelector(".kint-microtime-lap").innerHTML),r=parseFloat(i.querySelector(".kint-microtime-avg").innerHTML);void 0===c[t]&&(c[t]={}),(void 0===c[t].min||c[t].min>e)&&(c[t].min=e),(void 0===c[t].max||c[t].maxdl dl{padding:0 0 0 12px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMCAxNTAiPjxnIHN0cm9rZS13aWR0aD0iMiIgZmlsbD0iI0ZGRiI+PHBhdGggZD0iTTEgMWgyOHYyOEgxem01IDE0aDE4bS05IDlWNk0xIDYxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzM3OSIvPjxwYXRoIGQ9Ik0xIDMxaDI4djI4SDF6bTUgMTRoMThtLTkgOVYzNk0xIDkxaDI4djI4SDF6bTUgMTRoMTgiIHN0cm9rZT0iIzVBMyIvPjxwYXRoIGQ9Ik0xIDEyMWgyOHYyOEgxem01IDVsMTggMThtLTE4IDBsMTgtMTgiIHN0cm9rZT0iI0NDQyIvPjwvZz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #b6cedb}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#0092db;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#5cb730}.kint-rich dfn{font-style:normal;font-family:monospace;color:#1d1e1e}.kint-rich pre{color:#1d1e1e;margin:0 0 0 12px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #b6cedb;background:#e0eaef;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(29,30,30,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#e0eaef;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#1d1e1e;background:#e0eaef}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #b6cedb;border-top-width:0;border-bottom-width:0;padding:4px;float:right !important;margin:-4px 0;color:#1d1e1e;background:#c1d4df;height:24px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#d0d0d0;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#e8e8e8}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#c1d4df;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#1d1e1e}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#1d1e1e;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#1d1e1e;border-bottom:1px dotted #1d1e1e}.kint-rich ul{list-style:none;padding-left:12px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #b6cedb}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 12px;padding-left:0;background:#e0eaef;border:1px solid #b6cedb;border-top:0}.kint-rich ul.kint-tabs>li{background:#c1d4df;border:1px solid #b6cedb;cursor:pointer;display:inline-block;height:24px;margin:2px;padding:0 12px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#0092db;color:#5cb730}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#e0eaef;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:20px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#0092db;color:#5cb730}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #b6cedb;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#0092db}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #b6cedb;padding:2px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#c1d4df;color:#1d1e1e}.kint-rich table td{background:#e0eaef;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #0092db inset}.kint-rich table tr:hover var{color:#5cb730}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:4px;padding-bottom:4px;border-bottom:1px solid #c1d4df}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #0092db;padding-right:8px;margin-right:8px}.kint-rich pre.kint-source>div.kint-highlight{background:#c1d4df}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #0092db,0 1px #0092db,1px 0 #0092db,0 -1px #0092db;color:#e0eaef;font-weight:bold}.kint-rich>dl>dt{background:linear-gradient(to bottom, #e3ecf0 0, #c0d4df 100%)}.kint-rich ul.kint-tabs{background:linear-gradient(to bottom, #9dbed0 0px, #b2ccda 100%)}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li{background:#e0eaef}.kint-rich>dl:not(.kint-trace)>dd>ul.kint-tabs li.kint-active-tab{background:#c1d4df}.kint-rich>dl.kint-trace>dt{background:linear-gradient(to bottom, #c0d4df 0px, #e3ecf0 100%)}.kint-rich .kint-source .kint-highlight{background:#f0eb96} diff --git a/vendor/kint-php/kint/resources/compiled/plain.css b/vendor/kint-php/kint/resources/compiled/plain.css new file mode 100644 index 0000000..ba1eba0 --- /dev/null +++ b/vendor/kint-php/kint/resources/compiled/plain.css @@ -0,0 +1 @@ +.kint-plain{background:rgba(255,255,255,0.9);white-space:pre;display:block;font-family:monospace;color:#222}.kint-plain i{color:#d00;font-style:normal}.kint-plain u{color:#030;text-decoration:none;font-weight:bold}.kint-plain .kint-microtime-lap{font-weight:bold;text-shadow:1px 0 #fff, 0 1px #fff, -1px 0 #fff, 0 -1px #fff} diff --git a/vendor/kint-php/kint/resources/compiled/plain.js b/vendor/kint-php/kint/resources/compiled/plain.js new file mode 100644 index 0000000..9791fc9 --- /dev/null +++ b/vendor/kint-php/kint/resources/compiled/plain.js @@ -0,0 +1 @@ +void 0===window.kintPlain&&(window.kintPlain=function(){"use strict";var i={initLoad:function(){i.style=window.kintShared.dedupe("style.kint-plain-style",i.style),i.script=window.kintShared.dedupe("script.kint-plain-script",i.script)},style:null,script:null};return i}()),window.kintShared.runOnce(window.kintPlain.initLoad); diff --git a/vendor/kint-php/kint/resources/compiled/rich.js b/vendor/kint-php/kint/resources/compiled/rich.js new file mode 100644 index 0000000..18fb072 --- /dev/null +++ b/vendor/kint-php/kint/resources/compiled/rich.js @@ -0,0 +1 @@ +void 0===window.kintRich&&(window.kintRich=function(){"use strict";var n={selectText:function(e){var t=window.getSelection(),a=document.createRange();a.selectNodeContents(e),t.removeAllRanges(),t.addRange(a)},each:function(e,t){Array.prototype.slice.call(document.querySelectorAll(e),0).forEach(t)},hasClass:function(e,t){return!!e.classList&&(void 0===t&&(t="kint-show"),e.classList.contains(t))},addClass:function(e,t){void 0===t&&(t="kint-show"),e.classList.add(t)},removeClass:function(e,t){return void 0===t&&(t="kint-show"),e.classList.remove(t),e},toggle:function(e,t){var a=n.getChildren(e);a&&(void 0===t&&(t=n.hasClass(e)),t?n.removeClass(e):n.addClass(e),1===a.childNodes.length&&(a=a.childNodes[0].childNodes[0])&&n.hasClass(a,"kint-parent")&&n.toggle(a,t))},toggleChildren:function(e,t){var a=n.getChildren(e);if(a){var r=a.getElementsByClassName("kint-parent"),o=r.length;for(void 0===t&&(t=!n.hasClass(e));o--;)n.toggle(r[o],t)}},toggleAll:function(e){for(var t=document.getElementsByClassName("kint-parent"),a=t.length,r=!n.hasClass(e.parentNode);a--;)n.toggle(t[a],r)},switchTab:function(e){var t,a=e.previousSibling,r=0;for(n.removeClass(e.parentNode.getElementsByClassName("kint-active-tab")[0],"kint-active-tab"),n.addClass(e,"kint-active-tab");a;)1===a.nodeType&&r++,a=a.previousSibling;t=e.parentNode.nextSibling.childNodes;for(var o=0;o"},openInNewWindow:function(e){var t=window.open();t&&(t.document.open(),t.document.write(n.mktag("html")+n.mktag("head")+n.mktag("title")+"Kint ("+(new Date).toISOString()+")"+n.mktag("/title")+n.mktag('meta charset="utf-8"')+document.getElementsByClassName("kint-rich-script")[0].outerHTML+document.getElementsByClassName("kint-rich-style")[0].outerHTML+n.mktag("/head")+n.mktag("body")+'
'+e.parentNode.outerHTML+"
"+n.mktag("/body")),t.document.close())},sortTable:function(e,a){var t=e.tBodies[0];[].slice.call(e.tBodies[0].rows).sort(function(e,t){if(e=e.cells[a].textContent.trim().toLocaleLowerCase(),t=t.cells[a].textContent.trim().toLocaleLowerCase(),isNaN(e)||isNaN(t)){if(isNaN(e)&&!isNaN(t))return 1;if(isNaN(t)&&!isNaN(e))return-1}else e=parseFloat(e),t=parseFloat(t);return eli:not(.kint-active-tab)",function(e){0===e.offsetWidth&&0===e.offsetHeight||n.keyboardNav.targets.push(e)})},sync:function(e){var t=document.querySelector(".kint-focused");if(t&&n.removeClass(t,"kint-focused"),n.keyboardNav.active){var a=n.keyboardNav.targets[n.keyboardNav.target];n.addClass(a,"kint-focused"),e||n.keyboardNav.scroll(a)}},scroll:function(e){var t=function(e){return e.offsetTop+(e.offsetParent?t(e.offsetParent):0)},a=t(e);if(n.folder){var r=n.folder.querySelector("dd.kint-folder");r.scrollTo(0,a-r.clientHeight/2)}else window.scrollTo(0,a-window.innerHeight/2)},moveCursor:function(e){for(n.keyboardNav.target+=e;n.keyboardNav.target<0;)n.keyboardNav.target+=n.keyboardNav.targets.length;for(;n.keyboardNav.target>=n.keyboardNav.targets.length;)n.keyboardNav.target-=n.keyboardNav.targets.length;n.keyboardNav.sync()},setCursor:function(e){n.keyboardNav.fetchTargets();for(var t=0;tdl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #586e75}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#93a1a1}.kint-rich pre{color:#839496;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #586e75;background:#002b36;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(131,148,150,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#002b36;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#839496;background:#002b36}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #586e75;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#93a1a1;background:#073642;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#252525;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#1b1b1b}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#073642;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#839496}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#839496;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#93a1a1;border-bottom:1px dotted #93a1a1}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #586e75}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#002b36;border:1px solid #586e75;border-top:0}.kint-rich ul.kint-tabs>li{background:#073642;border:1px solid #586e75;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#002b36;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #586e75;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #586e75;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#073642;color:#93a1a1}.kint-rich table td{background:#002b36;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #073642}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#073642}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#002b36;font-weight:bold}body{background:#073642;color:#fff}.kint-rich{box-shadow:0 0 5px 3px #073642}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px}.kint-rich footer li{color:#ddd} diff --git a/vendor/kint-php/kint/resources/compiled/solarized.css b/vendor/kint-php/kint/resources/compiled/solarized.css new file mode 100644 index 0000000..db5da0d --- /dev/null +++ b/vendor/kint-php/kint/resources/compiled/solarized.css @@ -0,0 +1 @@ +.kint-rich{font-size:13px;overflow-x:auto;white-space:nowrap;background:rgba(255,255,255,0.9)}.kint-rich.kint-folder{position:fixed;bottom:0;left:0;right:0;z-index:999999;width:100%;margin:0;display:none}.kint-rich.kint-folder.kint-show{display:block}.kint-rich.kint-folder dd.kint-folder{max-height:calc(100vh - 100px);padding-right:10px;overflow-y:scroll}.kint-rich::selection,.kint-rich::-moz-selection,.kint-rich::-webkit-selection{background:#268bd2;color:#657b83}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #2aa198}.kint-rich,.kint-rich::before,.kint-rich::after,.kint-rich *,.kint-rich *::before,.kint-rich *::after{box-sizing:border-box;border-radius:0;color:#657b83;float:none !important;font-family:Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;line-height:15px;margin:0;padding:0;text-align:left}.kint-rich{margin:10px 0}.kint-rich dt,.kint-rich dl{width:auto}.kint-rich dt,.kint-rich div.access-path{background:#fdf6e3;border:1px solid #93a1a1;color:#657b83;display:block;font-weight:bold;list-style:none outside none;overflow:auto;padding:5px}.kint-rich dt:hover,.kint-rich div.access-path:hover{border-color:#268bd2}.kint-rich>dl dl{padding:0 0 0 15px}.kint-rich dt.kint-parent>nav,.kint-rich>footer>nav{background:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB2aWV3Qm94PSIwIDAgMzAgMTUwIj48ZGVmcz48cGF0aCBzdHJva2UtbGluZWpvaW49InJvdW5kIiBkPSJNNCAzYTI0IDMyIDAgMCAxIDAgMjQgNDAgMjAtMTAgMCAxIDIzLTEyQTQwIDIwIDEwIDAgMSA0IDN6IiBpZD0iYSIvPjwvZGVmcz48ZyBmaWxsPSIjOTNhMWExIiBzdHJva2U9IiM5M2ExYTEiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxnIGZpbGw9IiM1ODZlNzUiIHN0cm9rZT0iIzU4NmU3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMCAzMCkiPjx1c2UgeGxpbms6aHJlZj0iI2EiLz48dXNlIHhsaW5rOmhyZWY9IiNhIiB0cmFuc2Zvcm09InJvdGF0ZSg5MCAtMTUgNDUpIi8+PC9nPjxwYXRoIGQ9Ik02IDEyNmwxOCAxOG0tMTggMGwxOC0xOCIgc3Ryb2tlLXdpZHRoPSIyIiBzdHJva2U9IiM1ODZlNzUiLz48L3N2Zz4=") no-repeat scroll 0 0/15px 75px transparent;cursor:pointer;display:inline-block;height:15px;width:15px;margin-right:3px;vertical-align:middle}.kint-rich dt.kint-parent:hover>nav,.kint-rich>footer>nav:hover{background-position:0 25%}.kint-rich dt.kint-parent.kint-show>nav,.kint-rich>footer.kint-show>nav{background-position:0 50%}.kint-rich dt.kint-parent.kint-show:hover>nav,.kint-rich>footer.kint-show>nav:hover{background-position:0 75%}.kint-rich dt.kint-parent.kint-locked>nav{background-position:0 100%}.kint-rich dt.kint-parent+dd{display:none;border-left:1px dashed #93a1a1}.kint-rich dt.kint-parent.kint-show+dd{display:block}.kint-rich var,.kint-rich var a{color:#268bd2;font-style:normal}.kint-rich dt:hover var,.kint-rich dt:hover var a{color:#2aa198}.kint-rich dfn{font-style:normal;font-family:monospace;color:#586e75}.kint-rich pre{color:#657b83;margin:0 0 0 15px;padding:5px;overflow-y:hidden;border-top:0;border:1px solid #93a1a1;background:#fdf6e3;display:block;word-break:normal}.kint-rich .kint-popup-trigger,.kint-rich .kint-access-path-trigger,.kint-rich .kint-search-trigger{background:rgba(101,123,131,0.8);border-radius:3px;height:16px;font-size:16px;margin-left:5px;font-weight:bold;width:16px;text-align:center;float:right !important;cursor:pointer;color:#fdf6e3;position:relative;overflow:hidden;line-height:17.6px}.kint-rich .kint-popup-trigger:hover,.kint-rich .kint-access-path-trigger:hover,.kint-rich .kint-search-trigger:hover{color:#657b83;background:#fdf6e3}.kint-rich dt.kint-parent>.kint-popup-trigger{line-height:19.2px}.kint-rich .kint-search-trigger{font-size:20px}.kint-rich input.kint-search{display:none;border:1px solid #93a1a1;border-top-width:0;border-bottom-width:0;padding:5px;float:right !important;margin:-5px 0;color:#586e75;background:#eee8d5;height:26px;width:160px;position:relative;z-index:100}.kint-rich input.kint-search.kint-show{display:block}.kint-rich .kint-search-root ul.kint-tabs>li:not(.kint-search-match){background:#e2e2e2;opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match){opacity:0.5}.kint-rich .kint-search-root dl:not(.kint-search-match)>dt{background:#f0f0f0}.kint-rich .kint-search-root dl:not(.kint-search-match) dl,.kint-rich .kint-search-root dl:not(.kint-search-match) ul.kint-tabs>li:not(.kint-search-match){opacity:1}.kint-rich div.access-path{background:#eee8d5;display:none;margin-top:5px;padding:4px;white-space:pre}.kint-rich div.access-path.kint-show{display:block}.kint-rich footer{padding:0 3px 3px;font-size:9px;background:transparent}.kint-rich footer>.kint-popup-trigger{background:transparent;color:#657b83}.kint-rich footer nav{height:10px;width:10px;background-size:10px 50px}.kint-rich footer>ol{display:none;margin-left:32px}.kint-rich footer.kint-show>ol{display:block}.kint-rich a{color:#657b83;text-shadow:none;text-decoration:underline}.kint-rich a:hover{color:#586e75;border-bottom:1px dotted #586e75}.kint-rich ul{list-style:none;padding-left:15px}.kint-rich ul:not(.kint-tabs) li{border-left:1px dashed #93a1a1}.kint-rich ul:not(.kint-tabs) li>dl{border-left:none}.kint-rich ul.kint-tabs{margin:0 0 0 15px;padding-left:0;background:#fdf6e3;border:1px solid #93a1a1;border-top:0}.kint-rich ul.kint-tabs>li{background:#eee8d5;border:1px solid #93a1a1;cursor:pointer;display:inline-block;height:30px;margin:3px;padding:0 15px;vertical-align:top}.kint-rich ul.kint-tabs>li:hover,.kint-rich ul.kint-tabs>li.kint-active-tab:hover{border-color:#268bd2;color:#2aa198}.kint-rich ul.kint-tabs>li.kint-active-tab{background:#fdf6e3;border-top:0;margin-top:-1px;height:27px;line-height:24px}.kint-rich ul.kint-tabs>li:not(.kint-active-tab){line-height:25px}.kint-rich ul.kint-tabs li+li{margin-left:0}.kint-rich ul:not(.kint-tabs)>li:not(:first-child){display:none}.kint-rich dt:hover+dd>ul>li.kint-active-tab{border-color:#268bd2;color:#2aa198}.kint-rich dt>.kint-color-preview{width:16px;height:16px;display:inline-block;vertical-align:middle;margin-left:10px;border:1px solid #93a1a1;background-color:#ccc;background-image:url('data:image/svg+xml;utf8,');background-size:100%}.kint-rich dt>.kint-color-preview:hover{border-color:#268bd2}.kint-rich dt>.kint-color-preview>div{width:100%;height:100%}.kint-rich table{border-collapse:collapse;empty-cells:show;border-spacing:0}.kint-rich table *{font-size:12px}.kint-rich table dt{background:none;padding:2.5px}.kint-rich table dt .kint-parent{min-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.kint-rich table td,.kint-rich table th{border:1px solid #93a1a1;padding:2.5px;vertical-align:center}.kint-rich table th{cursor:alias}.kint-rich table td:first-child,.kint-rich table th{font-weight:bold;background:#eee8d5;color:#586e75}.kint-rich table td{background:#fdf6e3;white-space:pre}.kint-rich table td>dl{padding:0}.kint-rich table pre{border-top:0;border-right:0}.kint-rich table thead th:first-child{background:none;border:0}.kint-rich table tr:hover>td{box-shadow:0 0 1px 0 #268bd2 inset}.kint-rich table tr:hover var{color:#2aa198}.kint-rich table ul.kint-tabs li.kint-active-tab{height:20px;line-height:17px}.kint-rich pre.kint-source{margin-left:-1px}.kint-rich pre.kint-source[data-kint-filename]:before{display:block;content:attr(data-kint-filename);margin-bottom:5px;padding-bottom:5px;border-bottom:1px solid #eee8d5}.kint-rich pre.kint-source>div:before{display:inline-block;content:counter(kint-l);counter-increment:kint-l;border-right:1px solid #268bd2;padding-right:10px;margin-right:10px}.kint-rich pre.kint-source>div.kint-highlight{background:#eee8d5}.kint-rich .kint-microtime-lap{text-shadow:-1px 0 #268bd2,0 1px #268bd2,1px 0 #268bd2,0 -1px #268bd2;color:#fdf6e3;font-weight:bold}.kint-rich .kint-focused{box-shadow:0 0 3px 2px #859900 inset;border-radius:7px}.kint-rich>dl>dt,.kint-rich ul.kint-tabs{box-shadow:4px 0 2px -3px #268bd2 inset}.kint-rich ul.kint-tabs li.kint-active-tab{padding-top:7px;height:34px} diff --git a/vendor/kint-php/kint/src/CallFinder.php b/vendor/kint-php/kint/src/CallFinder.php new file mode 100644 index 0000000..e7192a8 --- /dev/null +++ b/vendor/kint-php/kint/src/CallFinder.php @@ -0,0 +1,473 @@ + true, + T_COMMENT => true, + T_DOC_COMMENT => true, + T_INLINE_HTML => true, + T_OPEN_TAG => true, + T_OPEN_TAG_WITH_ECHO => true, + T_WHITESPACE => true, + ); + + /** + * Things we need to do specially for operator tokens: + * - Refuse to strip spaces around them + * - Wrap the access path in parentheses if there + * are any of these in the final short parameter. + */ + private static $operator = array( + T_AND_EQUAL => true, + T_BOOLEAN_AND => true, + T_BOOLEAN_OR => true, + T_ARRAY_CAST => true, + T_BOOL_CAST => true, + T_CLONE => true, + T_CONCAT_EQUAL => true, + T_DEC => true, + T_DIV_EQUAL => true, + T_DOUBLE_CAST => true, + T_INC => true, + T_INCLUDE => true, + T_INCLUDE_ONCE => true, + T_INSTANCEOF => true, + T_INT_CAST => true, + T_IS_EQUAL => true, + T_IS_GREATER_OR_EQUAL => true, + T_IS_IDENTICAL => true, + T_IS_NOT_EQUAL => true, + T_IS_NOT_IDENTICAL => true, + T_IS_SMALLER_OR_EQUAL => true, + T_LOGICAL_AND => true, + T_LOGICAL_OR => true, + T_LOGICAL_XOR => true, + T_MINUS_EQUAL => true, + T_MOD_EQUAL => true, + T_MUL_EQUAL => true, + T_NEW => true, + T_OBJECT_CAST => true, + T_OR_EQUAL => true, + T_PLUS_EQUAL => true, + T_REQUIRE => true, + T_REQUIRE_ONCE => true, + T_SL => true, + T_SL_EQUAL => true, + T_SR => true, + T_SR_EQUAL => true, + T_STRING_CAST => true, + T_UNSET_CAST => true, + T_XOR_EQUAL => true, + '!' => true, + '%' => true, + '&' => true, + '*' => true, + '+' => true, + '-' => true, + '.' => true, + '/' => true, + ':' => true, + '<' => true, + '=' => true, + '>' => true, + '?' => true, + '^' => true, + '|' => true, + '~' => true, + ); + + private static $strip = array( + '(' => true, + ')' => true, + '[' => true, + ']' => true, + '{' => true, + '}' => true, + T_OBJECT_OPERATOR => true, + T_DOUBLE_COLON => true, + T_NS_SEPARATOR => true, + ); + + public static function getFunctionCalls($source, $line, $function) + { + static $up = array( + '(' => true, + '[' => true, + '{' => true, + T_CURLY_OPEN => true, + T_DOLLAR_OPEN_CURLY_BRACES => true, + ); + static $down = array( + ')' => true, + ']' => true, + '}' => true, + ); + static $modifiers = array( + '!' => true, + '@' => true, + '~' => true, + '+' => true, + '-' => true, + ); + static $identifier = array( + T_DOUBLE_COLON => true, + T_STRING => true, + T_NS_SEPARATOR => true, + ); + + if (KINT_PHP56) { + self::$operator[T_POW] = true; + self::$operator[T_POW_EQUAL] = true; + } + + if (KINT_PHP70) { + self::$operator[T_SPACESHIP] = true; + } + + if (KINT_PHP74) { + self::$operator[T_COALESCE_EQUAL] = true; + } + + $tokens = \token_get_all($source); + $cursor = 1; + $function_calls = array(); + /** @var array Performance optimization preventing backwards loops */ + $prev_tokens = array(null, null, null); + + if (\is_array($function)) { + $class = \explode('\\', $function[0]); + $class = \strtolower(\end($class)); + $function = \strtolower($function[1]); + } else { + $class = null; + $function = \strtolower($function); + } + + // Loop through tokens + foreach ($tokens as $index => $token) { + if (!\is_array($token)) { + continue; + } + + // Count newlines for line number instead of using $token[2] + // since certain situations (String tokens after whitespace) may + // not have the correct line number unless you do this manually + $cursor += \substr_count($token[1], "\n"); + if ($cursor > $line) { + break; + } + + // Store the last real tokens for later + if (isset(self::$ignore[$token[0]])) { + continue; + } + + $prev_tokens = array($prev_tokens[1], $prev_tokens[2], $token); + + // Check if it's the right type to be the function we're looking for + if (T_STRING !== $token[0] || \strtolower($token[1]) !== $function) { + continue; + } + + // Check if it's a function call + $nextReal = self::realTokenIndex($tokens, $index); + if (!isset($nextReal, $tokens[$nextReal]) || '(' !== $tokens[$nextReal]) { + continue; + } + + // Check if it matches the signature + if (null === $class) { + if ($prev_tokens[1] && \in_array($prev_tokens[1][0], array(T_DOUBLE_COLON, T_OBJECT_OPERATOR), true)) { + continue; + } + } else { + if (!$prev_tokens[1] || T_DOUBLE_COLON !== $prev_tokens[1][0]) { + continue; + } + + if (!$prev_tokens[0] || T_STRING !== $prev_tokens[0][0] || \strtolower($prev_tokens[0][1]) !== $class) { + continue; + } + } + + $inner_cursor = $cursor; + $depth = 1; // The depth respective to the function call + $offset = $nextReal + 1; // The start of the function call + $instring = false; // Whether we're in a string or not + $realtokens = false; // Whether the current scope contains anything meaningful or not + $paramrealtokens = false; // Whether the current parameter contains anything meaningful + $params = array(); // All our collected parameters + $shortparam = array(); // The short version of the parameter + $param_start = $offset; // The distance to the start of the parameter + + // Loop through the following tokens until the function call ends + while (isset($tokens[$offset])) { + $token = $tokens[$offset]; + + // Ensure that the $inner_cursor is correct and + // that $token is either a T_ constant or a string + if (\is_array($token)) { + $inner_cursor += \substr_count($token[1], "\n"); + } + + if (!isset(self::$ignore[$token[0]]) && !isset($down[$token[0]])) { + $paramrealtokens = $realtokens = true; + } + + // If it's a token that makes us to up a level, increase the depth + if (isset($up[$token[0]])) { + if (1 === $depth) { + $shortparam[] = $token; + $realtokens = false; + } + + ++$depth; + } elseif (isset($down[$token[0]])) { + --$depth; + + // If this brings us down to the parameter level, and we've had + // real tokens since going up, fill the $shortparam with an ellipsis + if (1 === $depth) { + if ($realtokens) { + $shortparam[] = '...'; + } + $shortparam[] = $token; + } + } elseif ('"' === $token[0]) { + // Strings use the same symbol for up and down, but we can + // only ever be inside one string, so just use a bool for that + if ($instring) { + --$depth; + if (1 === $depth) { + $shortparam[] = '...'; + } + } else { + ++$depth; + } + + $instring = !$instring; + + $shortparam[] = '"'; + } elseif (1 === $depth) { + if (',' === $token[0]) { + $params[] = array( + 'full' => \array_slice($tokens, $param_start, $offset - $param_start), + 'short' => $shortparam, + ); + $shortparam = array(); + $paramrealtokens = false; + $param_start = $offset + 1; + } elseif (T_CONSTANT_ENCAPSED_STRING === $token[0] && \strlen($token[1]) > 2) { + $shortparam[] = $token[1][0].'...'.$token[1][0]; + } else { + $shortparam[] = $token; + } + } + + // Depth has dropped to 0 (So we've hit the closing paren) + if ($depth <= 0) { + if ($paramrealtokens) { + $params[] = array( + 'full' => \array_slice($tokens, $param_start, $offset - $param_start), + 'short' => $shortparam, + ); + } + + break; + } + + ++$offset; + } + + // If we're not passed (or at) the line at the end + // of the function call, we're too early so skip it + if ($inner_cursor < $line) { + continue; + } + + // Format the final output parameters + foreach ($params as &$param) { + $name = self::tokensFormatted($param['short']); + $expression = false; + foreach ($name as $token) { + if (self::tokenIsOperator($token)) { + $expression = true; + break; + } + } + + $param = array( + 'name' => self::tokensToString($name), + 'path' => self::tokensToString(self::tokensTrim($param['full'])), + 'expression' => $expression, + ); + } + + // Get the modifiers + --$index; + + while (isset($tokens[$index])) { + if (!isset(self::$ignore[$tokens[$index][0]]) && !isset($identifier[$tokens[$index][0]])) { + break; + } + + --$index; + } + + $mods = array(); + + while (isset($tokens[$index])) { + if (isset(self::$ignore[$tokens[$index][0]])) { + --$index; + continue; + } + + if (isset($modifiers[$tokens[$index][0]])) { + $mods[] = $tokens[$index]; + --$index; + continue; + } + + break; + } + + $function_calls[] = array( + 'parameters' => $params, + 'modifiers' => $mods, + ); + } + + return $function_calls; + } + + private static function realTokenIndex(array $tokens, $index) + { + ++$index; + + while (isset($tokens[$index])) { + if (!isset(self::$ignore[$tokens[$index][0]])) { + return $index; + } + + ++$index; + } + + return null; + } + + /** + * We need a separate method to check if tokens are operators because we + * occasionally add "..." to short parameter versions. If we simply check + * for `$token[0]` then "..." will incorrectly match the "." operator. + * + * @param array|string $token The token to check + * + * @return bool + */ + private static function tokenIsOperator($token) + { + return '...' !== $token && isset(self::$operator[$token[0]]); + } + + private static function tokensToString(array $tokens) + { + $out = ''; + + foreach ($tokens as $token) { + if (\is_string($token)) { + $out .= $token; + } elseif (\is_array($token)) { + $out .= $token[1]; + } + } + + return $out; + } + + private static function tokensTrim(array $tokens) + { + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + unset($tokens[$index]); + } else { + break; + } + } + + $tokens = \array_reverse($tokens); + + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + unset($tokens[$index]); + } else { + break; + } + } + + return \array_reverse($tokens); + } + + private static function tokensFormatted(array $tokens) + { + $space = false; + + $tokens = self::tokensTrim($tokens); + + $output = array(); + $last = null; + + foreach ($tokens as $index => $token) { + if (isset(self::$ignore[$token[0]])) { + if ($space) { + continue; + } + + $next = $tokens[self::realTokenIndex($tokens, $index)]; + + if (isset(self::$strip[$last[0]]) && !self::tokenIsOperator($next)) { + continue; + } + + if (isset(self::$strip[$next[0]]) && $last && !self::tokenIsOperator($last)) { + continue; + } + + $token = ' '; + $space = true; + } else { + $space = false; + $last = $token; + } + + $output[] = $token; + } + + return $output; + } +} diff --git a/vendor/kint-php/kint/src/Kint.php b/vendor/kint-php/kint/src/Kint.php new file mode 100644 index 0000000..e0ce963 --- /dev/null +++ b/vendor/kint-php/kint/src/Kint.php @@ -0,0 +1,756 @@ + '', + * app_path() => '', + * config_path() => '', + * database_path() => '', + * public_path() => '', + * resource_path() => '', + * storage_path() => '', + * ]; + * + * Defaults to [$_SERVER['DOCUMENT_ROOT'] => ''] + */ + public static $app_root_dirs = array(); + + /** + * @var int max array/object levels to go deep, if zero no limits are applied + */ + public static $max_depth = 6; + + /** + * @var bool expand all trees by default for rich view + */ + public static $expanded = false; + + /** + * @var bool enable detection when Kint is command line. + * + * Formats output with whitespace only; does not HTML-escape it + */ + public static $cli_detection = true; + + /** + * @var array Kint aliases. Add debug functions in Kint wrappers here to fix modifiers and backtraces + */ + public static $aliases = array( + array('Kint\\Kint', 'dump'), + array('Kint\\Kint', 'trace'), + array('Kint\\Kint', 'dumpArray'), + ); + + /** + * @var array Array of modes to renderer class names + */ + public static $renderers = array( + self::MODE_RICH => 'Kint\\Renderer\\RichRenderer', + self::MODE_PLAIN => 'Kint\\Renderer\\PlainRenderer', + self::MODE_TEXT => 'Kint\\Renderer\\TextRenderer', + self::MODE_CLI => 'Kint\\Renderer\\CliRenderer', + ); + + public static $plugins = array( + 'Kint\\Parser\\ArrayObjectPlugin', + 'Kint\\Parser\\Base64Plugin', + 'Kint\\Parser\\BlacklistPlugin', + 'Kint\\Parser\\ClassMethodsPlugin', + 'Kint\\Parser\\ClassStaticsPlugin', + 'Kint\\Parser\\ClosurePlugin', + 'Kint\\Parser\\ColorPlugin', + 'Kint\\Parser\\DateTimePlugin', + 'Kint\\Parser\\FsPathPlugin', + 'Kint\\Parser\\IteratorPlugin', + 'Kint\\Parser\\JsonPlugin', + 'Kint\\Parser\\MicrotimePlugin', + 'Kint\\Parser\\SimpleXMLElementPlugin', + 'Kint\\Parser\\SplFileInfoPlugin', + 'Kint\\Parser\\SplObjectStoragePlugin', + 'Kint\\Parser\\StreamPlugin', + 'Kint\\Parser\\TablePlugin', + 'Kint\\Parser\\ThrowablePlugin', + 'Kint\\Parser\\TimestampPlugin', + 'Kint\\Parser\\TracePlugin', + 'Kint\\Parser\\XmlPlugin', + ); + + protected static $plugin_pool = array(); + + protected $parser; + protected $renderer; + + public function __construct(Parser $p, Renderer $r) + { + $this->parser = $p; + $this->renderer = $r; + } + + public function setParser(Parser $p) + { + $this->parser = $p; + } + + public function getParser() + { + return $this->parser; + } + + public function setRenderer(Renderer $r) + { + $this->renderer = $r; + } + + public function getRenderer() + { + return $this->renderer; + } + + public function setStatesFromStatics(array $statics) + { + $this->renderer->setStatics($statics); + + $this->parser->setDepthLimit(isset($statics['max_depth']) ? $statics['max_depth'] : false); + $this->parser->clearPlugins(); + + if (!isset($statics['plugins'])) { + return; + } + + $plugins = array(); + + foreach ($statics['plugins'] as $plugin) { + if ($plugin instanceof Plugin) { + $plugins[] = $plugin; + } elseif (\is_string($plugin) && \is_subclass_of($plugin, 'Kint\\Parser\\Plugin')) { + if (!isset(self::$plugin_pool[$plugin])) { + $p = new $plugin(); + self::$plugin_pool[$plugin] = $p; + } + $plugins[] = self::$plugin_pool[$plugin]; + } + } + + $plugins = $this->renderer->filterParserPlugins($plugins); + + foreach ($plugins as $plugin) { + $this->parser->addPlugin($plugin); + } + } + + public function setStatesFromCallInfo(array $info) + { + $this->renderer->setCallInfo($info); + + if (isset($info['modifiers']) && \is_array($info['modifiers']) && \in_array('+', $info['modifiers'], true)) { + $this->parser->setDepthLimit(false); + } + + $this->parser->setCallerClass(isset($info['caller']['class']) ? $info['caller']['class'] : null); + } + + /** + * Renders a list of vars including the pre and post renders. + * + * @param array $vars Data to dump + * @param BasicObject[] $base Base objects + * + * @return string + */ + public function dumpAll(array $vars, array $base) + { + if (\array_keys($vars) !== \array_keys($base)) { + throw new InvalidArgumentException('Kint::dumpAll requires arrays of identical size and keys as arguments'); + } + + $output = $this->renderer->preRender(); + + if ($vars === array()) { + $output .= $this->renderer->renderNothing(); + } + + foreach ($vars as $key => $arg) { + if (!$base[$key] instanceof BasicObject) { + throw new InvalidArgumentException('Kint::dumpAll requires all elements of the second argument to be BasicObject instances'); + } + $output .= $this->dumpVar($arg, $base[$key]); + } + + $output .= $this->renderer->postRender(); + + return $output; + } + + /** + * Dumps and renders a var. + * + * @param mixed $var Data to dump + * @param BasicObject $base Base object + * + * @return string + */ + public function dumpVar(&$var, BasicObject $base) + { + return $this->renderer->render( + $this->parser->parse($var, $base) + ); + } + + /** + * Gets all static settings at once. + * + * @return array Current static settings + */ + public static function getStatics() + { + return array( + 'aliases' => self::$aliases, + 'app_root_dirs' => self::$app_root_dirs, + 'cli_detection' => self::$cli_detection, + 'display_called_from' => self::$display_called_from, + 'enabled_mode' => self::$enabled_mode, + 'expanded' => self::$expanded, + 'file_link_format' => self::$file_link_format, + 'max_depth' => self::$max_depth, + 'mode_default' => self::$mode_default, + 'mode_default_cli' => self::$mode_default_cli, + 'plugins' => self::$plugins, + 'renderers' => self::$renderers, + 'return' => self::$return, + ); + } + + /** + * Creates a Kint instances based on static settings. + * + * Also calls setStatesFromStatics for you + * + * @param array $statics array of statics as returned by getStatics + * + * @return null|\Kint\Kint + */ + public static function createFromStatics(array $statics) + { + $mode = false; + + if (isset($statics['enabled_mode'])) { + $mode = $statics['enabled_mode']; + + if (true === $statics['enabled_mode'] && isset($statics['mode_default'])) { + $mode = $statics['mode_default']; + + if (PHP_SAPI === 'cli' && !empty($statics['cli_detection']) && isset($statics['mode_default_cli'])) { + $mode = $statics['mode_default_cli']; + } + } + } + + if (!$mode) { + return null; + } + + if (!isset($statics['renderers'][$mode])) { + $renderer = new TextRenderer(); + } else { + /** @var Renderer */ + $renderer = new $statics['renderers'][$mode](); + } + + return new self(new Parser(), $renderer); + } + + /** + * Creates base objects given parameter info. + * + * @param array $params Parameters as returned from getCallInfo + * @param int $argc Number of arguments the helper was called with + * + * @return BasicObject[] Base objects for the arguments + */ + public static function getBasesFromParamInfo(array $params, $argc) + { + static $blacklist = array( + 'null', + 'true', + 'false', + 'array(...)', + 'array()', + '[...]', + '[]', + '(...)', + '()', + '"..."', + 'b"..."', + "'...'", + "b'...'", + ); + + $params = \array_values($params); + $bases = array(); + + for ($i = 0; $i < $argc; ++$i) { + if (isset($params[$i])) { + $param = $params[$i]; + } else { + $param = null; + } + + if (!isset($param['name']) || \is_numeric($param['name'])) { + $name = null; + } elseif (\in_array(\strtolower($param['name']), $blacklist, true)) { + $name = null; + } else { + $name = $param['name']; + } + + if (isset($param['path'])) { + $access_path = $param['path']; + + if (!empty($param['expression'])) { + $access_path = '('.$access_path.')'; + } + } else { + $access_path = '$'.$i; + } + + $bases[] = BasicObject::blank($name, $access_path); + } + + return $bases; + } + + /** + * Gets call info from the backtrace, alias, and argument count. + * + * Aliases must be normalized beforehand (Utils::normalizeAliases) + * + * @param array $aliases Call aliases as found in Kint::$aliases + * @param array[] $trace Backtrace + * @param int $argc Number of arguments + * + * @return array{params:null|array, modifiers:array, callee:null|array, caller:null|array, trace:array[]} Call info + */ + public static function getCallInfo(array $aliases, array $trace, $argc) + { + $found = false; + $callee = null; + $caller = null; + $miniTrace = array(); + + foreach ($trace as $index => $frame) { + if (Utils::traceFrameIsListed($frame, $aliases)) { + $found = true; + $miniTrace = array(); + } + + if (!Utils::traceFrameIsListed($frame, array('spl_autoload_call'))) { + $miniTrace[] = $frame; + } + } + + if ($found) { + $callee = \reset($miniTrace) ?: null; + + /** @var null|array Psalm bug workaround */ + $caller = \next($miniTrace) ?: null; + } + + foreach ($miniTrace as $index => $frame) { + if ((0 === $index && $callee === $frame) || isset($frame['file'], $frame['line'])) { + unset($frame['object'], $frame['args']); + $miniTrace[$index] = $frame; + } else { + unset($miniTrace[$index]); + } + } + + $miniTrace = \array_values($miniTrace); + + $call = self::getSingleCall($callee ?: array(), $argc); + + $ret = array( + 'params' => null, + 'modifiers' => array(), + 'callee' => $callee, + 'caller' => $caller, + 'trace' => $miniTrace, + ); + + if ($call) { + $ret['params'] = $call['parameters']; + $ret['modifiers'] = $call['modifiers']; + } + + return $ret; + } + + /** + * Dumps a backtrace. + * + * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true)) + * + * @return int|string + */ + public static function trace() + { + if (!self::$enabled_mode) { + return 0; + } + + Utils::normalizeAliases(self::$aliases); + + $args = \func_get_args(); + + $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); + + $statics = self::getStatics(); + + if (\in_array('~', $call_info['modifiers'], true)) { + $statics['enabled_mode'] = self::MODE_TEXT; + } + + $kintstance = self::createFromStatics($statics); + if (!$kintstance) { + // Should never happen + return 0; // @codeCoverageIgnore + } + + if (\in_array('-', $call_info['modifiers'], true)) { + while (\ob_get_level()) { + \ob_end_clean(); + } + } + + $kintstance->setStatesFromStatics($statics); + $kintstance->setStatesFromCallInfo($call_info); + + $trimmed_trace = array(); + $trace = \debug_backtrace(true); + + foreach ($trace as $frame) { + if (Utils::traceFrameIsListed($frame, self::$aliases)) { + $trimmed_trace = array(); + } + + $trimmed_trace[] = $frame; + } + + $output = $kintstance->dumpAll( + array($trimmed_trace), + array(BasicObject::blank('Kint\\Kint::trace()', 'debug_backtrace(true)')) + ); + + if (self::$return || \in_array('@', $call_info['modifiers'], true)) { + return $output; + } + + echo $output; + + if (\in_array('-', $call_info['modifiers'], true)) { + \flush(); // @codeCoverageIgnore + } + + return 0; + } + + /** + * Dumps some data. + * + * Functionally equivalent to Kint::dump(1) or Kint::dump(debug_backtrace(true)) + * + * @return int|string + */ + public static function dump() + { + if (!self::$enabled_mode) { + return 0; + } + + Utils::normalizeAliases(self::$aliases); + + $args = \func_get_args(); + + $call_info = self::getCallInfo(self::$aliases, \debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS), \count($args)); + + $statics = self::getStatics(); + + if (\in_array('~', $call_info['modifiers'], true)) { + $statics['enabled_mode'] = self::MODE_TEXT; + } + + $kintstance = self::createFromStatics($statics); + if (!$kintstance) { + // Should never happen + return 0; // @codeCoverageIgnore + } + + if (\in_array('-', $call_info['modifiers'], true)) { + while (\ob_get_level()) { + \ob_end_clean(); + } + } + + $kintstance->setStatesFromStatics($statics); + $kintstance->setStatesFromCallInfo($call_info); + + // If the call is Kint::dump(1) then dump a backtrace instead + if ($args === array(1) && (!isset($call_info['params'][0]['name']) || '1' === $call_info['params'][0]['name'])) { + $args = \debug_backtrace(true); + $trace = array(); + + foreach ($args as $index => $frame) { + if (Utils::traceFrameIsListed($frame, self::$aliases)) { + $trace = array(); + } + + $trace[] = $frame; + } + + if (isset($call_info['callee']['function'])) { + $tracename = $call_info['callee']['function'].'(1)'; + if (isset($call_info['callee']['class'], $call_info['callee']['type'])) { + $tracename = $call_info['callee']['class'].$call_info['callee']['type'].$tracename; + } + } else { + $tracename = 'Kint\\Kint::dump(1)'; + } + + $tracebase = BasicObject::blank($tracename, 'debug_backtrace(true)'); + + $output = $kintstance->dumpAll(array($trace), array($tracebase)); + } else { + $bases = self::getBasesFromParamInfo( + isset($call_info['params']) ? $call_info['params'] : array(), + \count($args) + ); + $output = $kintstance->dumpAll($args, $bases); + } + + if (self::$return || \in_array('@', $call_info['modifiers'], true)) { + return $output; + } + + echo $output; + + if (\in_array('-', $call_info['modifiers'], true)) { + \flush(); // @codeCoverageIgnore + } + + return 0; + } + + /** + * generic path display callback, can be configured in app_root_dirs; purpose is + * to show relevant path info and hide as much of the path as possible. + * + * @param string $file + * + * @return string + */ + public static function shortenPath($file) + { + $file = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $file)), 'strlen')); + + $longest_match = 0; + $match = '/'; + + foreach (self::$app_root_dirs as $path => $alias) { + if (empty($path)) { + continue; + } + + $path = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', $path)), 'strlen')); + + if (\array_slice($file, 0, \count($path)) === $path && \count($path) > $longest_match) { + $longest_match = \count($path); + $match = $alias; + } + } + + if ($longest_match) { + $file = \array_merge(array($match), \array_slice($file, $longest_match)); + + return \implode('/', $file); + } + + // fallback to find common path with Kint dir + $kint = \array_values(\array_filter(\explode('/', \str_replace('\\', '/', KINT_DIR)), 'strlen')); + + foreach ($file as $i => $part) { + if (!isset($kint[$i]) || $kint[$i] !== $part) { + return ($i ? '.../' : '/').\implode('/', \array_slice($file, $i)); + } + } + + return '/'.\implode('/', $file); + } + + public static function getIdeLink($file, $line) + { + return \str_replace(array('%f', '%l'), array($file, $line), self::$file_link_format); + } + + /** + * Returns specific function call info from a stack trace frame, or null if no match could be found. + * + * @param array $frame The stack trace frame in question + * @param int $argc The amount of arguments received + * + * @return null|array{parameters:array, modifiers:array} params and modifiers, or null if a specific call could not be determined + */ + protected static function getSingleCall(array $frame, $argc) + { + if (!isset($frame['file'], $frame['line'], $frame['function']) || !\is_readable($frame['file'])) { + return null; + } + + if (empty($frame['class'])) { + $callfunc = $frame['function']; + } else { + $callfunc = array($frame['class'], $frame['function']); + } + + $calls = CallFinder::getFunctionCalls( + \file_get_contents($frame['file']), + $frame['line'], + $callfunc + ); + + $return = null; + + foreach ($calls as $call) { + $is_unpack = false; + + // Handle argument unpacking as a last resort + if (KINT_PHP56) { + foreach ($call['parameters'] as $i => &$param) { + if (0 === \strpos($param['name'], '...')) { + if ($i < $argc && $i === \count($call['parameters']) - 1) { + for ($j = 1; $j + $i < $argc; ++$j) { + $call['parameters'][] = array( + 'name' => 'array_values('.\substr($param['name'], 3).')['.$j.']', + 'path' => 'array_values('.\substr($param['path'], 3).')['.$j.']', + 'expression' => false, + ); + } + + $param['name'] = 'reset('.\substr($param['name'], 3).')'; + $param['path'] = 'reset('.\substr($param['path'], 3).')'; + $param['expression'] = false; + } else { + $call['parameters'] = \array_slice($call['parameters'], 0, $i); + } + + $is_unpack = true; + break; + } + + if ($i >= $argc) { + continue 2; + } + } + } + + if ($is_unpack || \count($call['parameters']) === $argc) { + if (null === $return) { + $return = $call; + } else { + // If we have multiple calls on the same line with the same amount of arguments, + // we can't be sure which it is so just return null and let them figure it out + return null; + } + } + } + + return $return; + } +} diff --git a/vendor/kint-php/kint/src/Object/BasicObject.php b/vendor/kint-php/kint/src/Object/BasicObject.php new file mode 100644 index 0000000..d69347e --- /dev/null +++ b/vendor/kint-php/kint/src/Object/BasicObject.php @@ -0,0 +1,248 @@ +representations[$rep->getName()])) { + return false; + } + + if (null === $pos) { + $this->representations[$rep->getName()] = $rep; + } else { + $this->representations = \array_merge( + \array_slice($this->representations, 0, $pos), + array($rep->getName() => $rep), + \array_slice($this->representations, $pos) + ); + } + + return true; + } + + public function replaceRepresentation(Representation $rep, $pos = null) + { + if (null === $pos) { + $this->representations[$rep->getName()] = $rep; + } else { + $this->removeRepresentation($rep); + $this->addRepresentation($rep, $pos); + } + } + + public function removeRepresentation($rep) + { + if ($rep instanceof Representation) { + unset($this->representations[$rep->getName()]); + } elseif (\is_string($rep)) { + unset($this->representations[$rep]); + } + } + + public function getRepresentation($name) + { + if (isset($this->representations[$name])) { + return $this->representations[$name]; + } + } + + public function getRepresentations() + { + return $this->representations; + } + + public function clearRepresentations() + { + $this->representations = array(); + } + + public function getType() + { + return $this->type; + } + + public function getModifiers() + { + $out = $this->getAccess(); + + if ($this->const) { + $out .= ' const'; + } + + if ($this->static) { + $out .= ' static'; + } + + if (\strlen($out)) { + return \ltrim($out); + } + } + + public function getAccess() + { + switch ($this->access) { + case self::ACCESS_PRIVATE: + return 'private'; + case self::ACCESS_PROTECTED: + return 'protected'; + case self::ACCESS_PUBLIC: + return 'public'; + } + } + + public function getName() + { + return $this->name; + } + + public function getOperator() + { + switch ($this->operator) { + case self::OPERATOR_ARRAY: + return '=>'; + case self::OPERATOR_OBJECT: + return '->'; + case self::OPERATOR_STATIC: + return '::'; + } + } + + public function getSize() + { + return $this->size; + } + + public function getValueShort() + { + if ($rep = $this->value) { + if ('boolean' === $this->type) { + return $rep->contents ? 'true' : 'false'; + } + + if ('integer' === $this->type || 'double' === $this->type) { + return $rep->contents; + } + } + } + + public function getAccessPath() + { + return $this->access_path; + } + + public function transplant(BasicObject $old) + { + $this->name = $old->name; + $this->size = $old->size; + $this->access_path = $old->access_path; + $this->access = $old->access; + $this->static = $old->static; + $this->const = $old->const; + $this->type = $old->type; + $this->depth = $old->depth; + $this->owner_class = $old->owner_class; + $this->operator = $old->operator; + $this->reference = $old->reference; + $this->value = $old->value; + $this->representations += $old->representations; + $this->hints = \array_merge($this->hints, $old->hints); + } + + /** + * Creates a new basic object with a name and access path. + * + * @param null|string $name + * @param null|string $access_path + * + * @return \Kint\Object\BasicObject + */ + public static function blank($name = null, $access_path = null) + { + $o = new self(); + $o->name = $name; + $o->access_path = $access_path; + + return $o; + } + + public static function sortByAccess(BasicObject $a, BasicObject $b) + { + static $sorts = array( + self::ACCESS_PUBLIC => 1, + self::ACCESS_PROTECTED => 2, + self::ACCESS_PRIVATE => 3, + self::ACCESS_NONE => 4, + ); + + return $sorts[$a->access] - $sorts[$b->access]; + } + + public static function sortByName(BasicObject $a, BasicObject $b) + { + $ret = \strnatcasecmp($a->name, $b->name); + + if (0 === $ret) { + return (int) \is_int($b->name) - (int) \is_int($a->name); + } + + return $ret; + } +} diff --git a/vendor/kint-php/kint/src/Object/BlobObject.php b/vendor/kint-php/kint/src/Object/BlobObject.php new file mode 100644 index 0000000..66d508f --- /dev/null +++ b/vendor/kint-php/kint/src/Object/BlobObject.php @@ -0,0 +1,177 @@ +encoding) { + return 'binary '.$this->type; + } + + if ('ASCII' === $this->encoding) { + return $this->type; + } + + return $this->encoding.' '.$this->type; + } + + public function getValueShort() + { + if ($rep = $this->value) { + return '"'.$rep->contents.'"'; + } + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->encoding = $old->encoding; + } + } + + public static function strlen($string, $encoding = false) + { + if (\function_exists('mb_strlen')) { + if (false === $encoding) { + $encoding = self::detectEncoding($string); + } + + if ($encoding && 'ASCII' !== $encoding) { + return \mb_strlen($string, $encoding); + } + } + + return \strlen($string); + } + + public static function substr($string, $start, $length = null, $encoding = false) + { + if (\function_exists('mb_substr')) { + if (false === $encoding) { + $encoding = self::detectEncoding($string); + } + + if ($encoding && 'ASCII' !== $encoding) { + return \mb_substr($string, $start, $length, $encoding); + } + } + + // Special case for substr/mb_substr discrepancy + if ('' === $string) { + return ''; + } + + return \substr($string, $start, isset($length) ? $length : PHP_INT_MAX); + } + + public static function detectEncoding($string) + { + if (\function_exists('mb_detect_encoding')) { + if ($ret = \mb_detect_encoding($string, self::$char_encodings, true)) { + return $ret; + } + } + + // Pretty much every character encoding uses first 32 bytes as control + // characters. If it's not a multi-byte format it's safe to say matching + // any control character besides tab, nl, and cr means it's binary. + if (\preg_match('/[\\x00-\\x08\\x0B\\x0C\\x0E-\\x1F]/', $string)) { + return false; + } + + if (\function_exists('iconv')) { + foreach (self::$legacy_encodings as $encoding) { + if (@\iconv($encoding, $encoding, $string) === $string) { + return $encoding; + } + } + } elseif (!\function_exists('mb_detect_encoding')) { // @codeCoverageIgnore + // If a user has neither mb_detect_encoding, nor iconv, nor the + // polyfills, there's not much we can do about it... + // Pretend it's ASCII and pray the browser renders it properly. + return 'ASCII'; // @codeCoverageIgnore + } + + return false; + } +} diff --git a/vendor/kint-php/kint/src/Object/ClosureObject.php b/vendor/kint-php/kint/src/Object/ClosureObject.php new file mode 100644 index 0000000..344eceb --- /dev/null +++ b/vendor/kint-php/kint/src/Object/ClosureObject.php @@ -0,0 +1,68 @@ +access_path) { + return parent::getAccessPath().'('.$this->getParams().')'; + } + } + + public function getSize() + { + } + + public function getParams() + { + if (null !== $this->paramcache) { + return $this->paramcache; + } + + $out = array(); + + foreach ($this->parameters as $p) { + $type = $p->getType(); + + $ref = $p->reference ? '&' : ''; + + if ($type) { + $out[] = $type.' '.$ref.$p->getName(); + } else { + $out[] = $ref.$p->getName(); + } + } + + return $this->paramcache = \implode(', ', $out); + } +} diff --git a/vendor/kint-php/kint/src/Object/DateTimeObject.php b/vendor/kint-php/kint/src/Object/DateTimeObject.php new file mode 100644 index 0000000..f8b1b3f --- /dev/null +++ b/vendor/kint-php/kint/src/Object/DateTimeObject.php @@ -0,0 +1,53 @@ +dt = clone $dt; + } + + public function getValueShort() + { + $stamp = $this->dt->format('Y-m-d H:i:s'); + if ((int) ($micro = $this->dt->format('u'))) { + $stamp .= '.'.$micro; + } + $stamp .= $this->dt->format('P T'); + + return $stamp; + } +} diff --git a/vendor/kint-php/kint/src/Object/InstanceObject.php b/vendor/kint-php/kint/src/Object/InstanceObject.php new file mode 100644 index 0000000..943b33d --- /dev/null +++ b/vendor/kint-php/kint/src/Object/InstanceObject.php @@ -0,0 +1,78 @@ +classname; + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->classname = $old->classname; + $this->hash = $old->hash; + $this->filename = $old->filename; + $this->startline = $old->startline; + } + } + + public static function sortByHierarchy($a, $b) + { + if (\is_string($a) && \is_string($b)) { + $aclass = $a; + $bclass = $b; + } elseif (!($a instanceof BasicObject) || !($b instanceof BasicObject)) { + return 0; + } elseif ($a instanceof self && $b instanceof self) { + $aclass = $a->classname; + $bclass = $b->classname; + } else { + return 0; + } + + if (\is_subclass_of($aclass, $bclass)) { + return -1; + } + + if (\is_subclass_of($bclass, $aclass)) { + return 1; + } + + return 0; + } +} diff --git a/vendor/kint-php/kint/src/Object/MethodObject.php b/vendor/kint-php/kint/src/Object/MethodObject.php new file mode 100644 index 0000000..78d49de --- /dev/null +++ b/vendor/kint-php/kint/src/Object/MethodObject.php @@ -0,0 +1,253 @@ +name = $method->getName(); + $this->filename = $method->getFileName(); + $this->startline = $method->getStartLine(); + $this->endline = $method->getEndLine(); + $this->internal = $method->isInternal(); + $this->docstring = $method->getDocComment(); + $this->return_reference = $method->returnsReference(); + + foreach ($method->getParameters() as $param) { + $this->parameters[] = new ParameterObject($param); + } + + if (KINT_PHP70) { + $this->returntype = $method->getReturnType(); + if ($this->returntype) { + $this->returntype = Utils::getTypeString($this->returntype); + } + } + + if ($method instanceof ReflectionMethod) { + $this->static = $method->isStatic(); + $this->operator = $this->static ? BasicObject::OPERATOR_STATIC : BasicObject::OPERATOR_OBJECT; + $this->abstract = $method->isAbstract(); + $this->final = $method->isFinal(); + $this->owner_class = $method->getDeclaringClass()->name; + $this->access = BasicObject::ACCESS_PUBLIC; + if ($method->isProtected()) { + $this->access = BasicObject::ACCESS_PROTECTED; + } elseif ($method->isPrivate()) { + $this->access = BasicObject::ACCESS_PRIVATE; + } + } + + if ($this->internal) { + return; + } + + $docstring = new DocstringRepresentation( + $this->docstring, + $this->filename, + $this->startline + ); + + $docstring->implicit_label = true; + $this->addRepresentation($docstring); + $this->value = $docstring; + } + + public function setAccessPathFrom(InstanceObject $parent) + { + static $magic = array( + '__call' => true, + '__callstatic' => true, + '__clone' => true, + '__construct' => true, + '__debuginfo' => true, + '__destruct' => true, + '__get' => true, + '__invoke' => true, + '__isset' => true, + '__set' => true, + '__set_state' => true, + '__sleep' => true, + '__tostring' => true, + '__unset' => true, + '__wakeup' => true, + ); + + $name = \strtolower($this->name); + + if ('__construct' === $name) { + $this->access_path = 'new \\'.$parent->getType(); + } elseif ('__invoke' === $name) { + $this->access_path = $parent->access_path; + } elseif ('__clone' === $name) { + $this->access_path = 'clone '.$parent->access_path; + $this->showparams = false; + } elseif ('__tostring' === $name) { + $this->access_path = '(string) '.$parent->access_path; + $this->showparams = false; + } elseif (isset($magic[$name])) { + $this->access_path = null; + } elseif ($this->static) { + $this->access_path = '\\'.$this->owner_class.'::'.$this->name; + } else { + $this->access_path = $parent->access_path.'->'.$this->name; + } + } + + public function getValueShort() + { + if (!$this->value || !($this->value instanceof DocstringRepresentation)) { + return parent::getValueShort(); + } + + $ds = $this->value->getDocstringWithoutComments(); + + if (!$ds) { + return null; + } + + $ds = \explode("\n", $ds); + + $out = ''; + + foreach ($ds as $line) { + if (0 === \strlen(\trim($line)) || '@' === $line[0]) { + break; + } + + $out .= $line.' '; + } + + if (\strlen($out)) { + return \rtrim($out); + } + } + + public function getModifiers() + { + $mods = array( + $this->abstract ? 'abstract' : null, + $this->final ? 'final' : null, + $this->getAccess(), + $this->static ? 'static' : null, + ); + + $out = ''; + + foreach ($mods as $word) { + if (null !== $word) { + $out .= $word.' '; + } + } + + if (\strlen($out)) { + return \rtrim($out); + } + } + + public function getAccessPath() + { + if (null !== $this->access_path) { + if ($this->showparams) { + return parent::getAccessPath().'('.$this->getParams().')'; + } + + return parent::getAccessPath(); + } + } + + public function getParams() + { + if (null !== $this->paramcache) { + return $this->paramcache; + } + + $out = array(); + + foreach ($this->parameters as $p) { + $type = $p->getType(); + if ($type) { + $type .= ' '; + } + + $default = $p->getDefault(); + if ($default) { + $default = ' = '.$default; + } + + $ref = $p->reference ? '&' : ''; + + $out[] = $type.$ref.$p->getName().$default; + } + + return $this->paramcache = \implode(', ', $out); + } + + public function getPhpDocUrl() + { + if (!$this->internal) { + return null; + } + + if ($this->owner_class) { + $class = \strtolower($this->owner_class); + } else { + $class = 'function'; + } + + $funcname = \str_replace('_', '-', \strtolower($this->name)); + + if (0 === \strpos($funcname, '--') && 0 !== \strpos($funcname, '-', 2)) { + $funcname = \substr($funcname, 2); + } + + return 'https://secure.php.net/'.$class.'.'.$funcname; + } +} diff --git a/vendor/kint-php/kint/src/Object/ParameterObject.php b/vendor/kint-php/kint/src/Object/ParameterObject.php new file mode 100644 index 0000000..4bed551 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/ParameterObject.php @@ -0,0 +1,100 @@ +getType()) { + $this->type_hint = Utils::getTypeString($type); + } + } else { + if ($param->isArray()) { + $this->type_hint = 'array'; + } else { + try { + if ($this->type_hint = $param->getClass()) { + $this->type_hint = $this->type_hint->name; + } + } catch (ReflectionException $e) { + \preg_match('/\\[\\s\\<\\w+?>\\s([\\w]+)/s', $param->__toString(), $matches); + $this->type_hint = isset($matches[1]) ? $matches[1] : ''; + } + } + } + + $this->reference = $param->isPassedByReference(); + $this->name = $param->getName(); + $this->position = $param->getPosition(); + + if ($param->isDefaultValueAvailable()) { + /** @var mixed Psalm bug workaround */ + $default = $param->getDefaultValue(); + switch (\gettype($default)) { + case 'NULL': + $this->default = 'null'; + break; + case 'boolean': + $this->default = $default ? 'true' : 'false'; + break; + case 'array': + $this->default = \count($default) ? 'array(...)' : 'array()'; + break; + default: + $this->default = \var_export($default, true); + break; + } + } + } + + public function getType() + { + return $this->type_hint; + } + + public function getName() + { + return '$'.$this->name; + } + + public function getDefault() + { + return $this->default; + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/ColorRepresentation.php b/vendor/kint-php/kint/src/Object/Representation/ColorRepresentation.php new file mode 100644 index 0000000..d6a072f --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/ColorRepresentation.php @@ -0,0 +1,576 @@ + 'f0f8ff', + 'antiquewhite' => 'faebd7', + 'aqua' => '00ffff', + 'aquamarine' => '7fffd4', + 'azure' => 'f0ffff', + 'beige' => 'f5f5dc', + 'bisque' => 'ffe4c4', + 'black' => '000000', + 'blanchedalmond' => 'ffebcd', + 'blue' => '0000ff', + 'blueviolet' => '8a2be2', + 'brown' => 'a52a2a', + 'burlywood' => 'deb887', + 'cadetblue' => '5f9ea0', + 'chartreuse' => '7fff00', + 'chocolate' => 'd2691e', + 'coral' => 'ff7f50', + 'cornflowerblue' => '6495ed', + 'cornsilk' => 'fff8dc', + 'crimson' => 'dc143c', + 'cyan' => '00ffff', + 'darkblue' => '00008b', + 'darkcyan' => '008b8b', + 'darkgoldenrod' => 'b8860b', + 'darkgray' => 'a9a9a9', + 'darkgreen' => '006400', + 'darkgrey' => 'a9a9a9', + 'darkkhaki' => 'bdb76b', + 'darkmagenta' => '8b008b', + 'darkolivegreen' => '556b2f', + 'darkorange' => 'ff8c00', + 'darkorchid' => '9932cc', + 'darkred' => '8b0000', + 'darksalmon' => 'e9967a', + 'darkseagreen' => '8fbc8f', + 'darkslateblue' => '483d8b', + 'darkslategray' => '2f4f4f', + 'darkslategrey' => '2f4f4f', + 'darkturquoise' => '00ced1', + 'darkviolet' => '9400d3', + 'deeppink' => 'ff1493', + 'deepskyblue' => '00bfff', + 'dimgray' => '696969', + 'dimgrey' => '696969', + 'dodgerblue' => '1e90ff', + 'firebrick' => 'b22222', + 'floralwhite' => 'fffaf0', + 'forestgreen' => '228b22', + 'fuchsia' => 'ff00ff', + 'gainsboro' => 'dcdcdc', + 'ghostwhite' => 'f8f8ff', + 'gold' => 'ffd700', + 'goldenrod' => 'daa520', + 'gray' => '808080', + 'green' => '008000', + 'greenyellow' => 'adff2f', + 'grey' => '808080', + 'honeydew' => 'f0fff0', + 'hotpink' => 'ff69b4', + 'indianred' => 'cd5c5c', + 'indigo' => '4b0082', + 'ivory' => 'fffff0', + 'khaki' => 'f0e68c', + 'lavender' => 'e6e6fa', + 'lavenderblush' => 'fff0f5', + 'lawngreen' => '7cfc00', + 'lemonchiffon' => 'fffacd', + 'lightblue' => 'add8e6', + 'lightcoral' => 'f08080', + 'lightcyan' => 'e0ffff', + 'lightgoldenrodyellow' => 'fafad2', + 'lightgray' => 'd3d3d3', + 'lightgreen' => '90ee90', + 'lightgrey' => 'd3d3d3', + 'lightpink' => 'ffb6c1', + 'lightsalmon' => 'ffa07a', + 'lightseagreen' => '20b2aa', + 'lightskyblue' => '87cefa', + 'lightslategray' => '778899', + 'lightslategrey' => '778899', + 'lightsteelblue' => 'b0c4de', + 'lightyellow' => 'ffffe0', + 'lime' => '00ff00', + 'limegreen' => '32cd32', + 'linen' => 'faf0e6', + 'magenta' => 'ff00ff', + 'maroon' => '800000', + 'mediumaquamarine' => '66cdaa', + 'mediumblue' => '0000cd', + 'mediumorchid' => 'ba55d3', + 'mediumpurple' => '9370db', + 'mediumseagreen' => '3cb371', + 'mediumslateblue' => '7b68ee', + 'mediumspringgreen' => '00fa9a', + 'mediumturquoise' => '48d1cc', + 'mediumvioletred' => 'c71585', + 'midnightblue' => '191970', + 'mintcream' => 'f5fffa', + 'mistyrose' => 'ffe4e1', + 'moccasin' => 'ffe4b5', + 'navajowhite' => 'ffdead', + 'navy' => '000080', + 'oldlace' => 'fdf5e6', + 'olive' => '808000', + 'olivedrab' => '6b8e23', + 'orange' => 'ffa500', + 'orangered' => 'ff4500', + 'orchid' => 'da70d6', + 'palegoldenrod' => 'eee8aa', + 'palegreen' => '98fb98', + 'paleturquoise' => 'afeeee', + 'palevioletred' => 'db7093', + 'papayawhip' => 'ffefd5', + 'peachpuff' => 'ffdab9', + 'peru' => 'cd853f', + 'pink' => 'ffc0cb', + 'plum' => 'dda0dd', + 'powderblue' => 'b0e0e6', + 'purple' => '800080', + 'rebeccapurple' => '663399', + 'red' => 'ff0000', + 'rosybrown' => 'bc8f8f', + 'royalblue' => '4169e1', + 'saddlebrown' => '8b4513', + 'salmon' => 'fa8072', + 'sandybrown' => 'f4a460', + 'seagreen' => '2e8b57', + 'seashell' => 'fff5ee', + 'sienna' => 'a0522d', + 'silver' => 'c0c0c0', + 'skyblue' => '87ceeb', + 'slateblue' => '6a5acd', + 'slategray' => '708090', + 'slategrey' => '708090', + 'snow' => 'fffafa', + 'springgreen' => '00ff7f', + 'steelblue' => '4682b4', + 'tan' => 'd2b48c', + 'teal' => '008080', + 'thistle' => 'd8bfd8', + 'tomato' => 'ff6347', + // To quote MDN: + // "Technically, transparent is a shortcut for rgba(0,0,0,0)." + 'transparent' => '00000000', + 'turquoise' => '40e0d0', + 'violet' => 'ee82ee', + 'wheat' => 'f5deb3', + 'white' => 'ffffff', + 'whitesmoke' => 'f5f5f5', + 'yellow' => 'ffff00', + 'yellowgreen' => '9acd32', + ); + + public $r = 0; + public $g = 0; + public $b = 0; + public $a = 1.0; + public $variant; + public $implicit_label = true; + public $hints = array('color'); + + public function __construct($value) + { + parent::__construct('Color'); + + $this->contents = $value; + $this->setValues($value); + } + + public function getColor($variant = null) + { + if (!$variant) { + $variant = $this->variant; + } + + switch ($variant) { + case self::COLOR_NAME: + $hex = \sprintf('%02x%02x%02x', $this->r, $this->g, $this->b); + $hex_alpha = \sprintf('%02x%02x%02x%02x', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); + + return \array_search($hex, self::$color_map, true) ?: \array_search($hex_alpha, self::$color_map, true); + case self::COLOR_HEX_3: + if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11) { + return \sprintf( + '#%1X%1X%1X', + \round($this->r / 0x11), + \round($this->g / 0x11), + \round($this->b / 0x11) + ); + } + + return false; + case self::COLOR_HEX_6: + return \sprintf('#%02X%02X%02X', $this->r, $this->g, $this->b); + case self::COLOR_RGB: + if (1.0 === $this->a) { + return \sprintf('rgb(%d, %d, %d)', $this->r, $this->g, $this->b); + } + + return \sprintf('rgb(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4)); + case self::COLOR_RGBA: + return \sprintf('rgba(%d, %d, %d, %s)', $this->r, $this->g, $this->b, \round($this->a, 4)); + case self::COLOR_HSL: + $val = self::rgbToHsl($this->r, $this->g, $this->b); + if (1.0 === $this->a) { + return \vsprintf('hsl(%d, %d%%, %d%%)', $val); + } + + return \sprintf('hsl(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4)); + case self::COLOR_HSLA: + $val = self::rgbToHsl($this->r, $this->g, $this->b); + + return \sprintf('hsla(%d, %d%%, %d%%, %s)', $val[0], $val[1], $val[2], \round($this->a, 4)); + case self::COLOR_HEX_4: + if (0 === $this->r % 0x11 && 0 === $this->g % 0x11 && 0 === $this->b % 0x11 && 0 === ($this->a * 255) % 0x11) { + return \sprintf( + '#%1X%1X%1X%1X', + \round($this->r / 0x11), + \round($this->g / 0x11), + \round($this->b / 0x11), + \round($this->a * 0xF) + ); + } + + return false; + + case self::COLOR_HEX_8: + return \sprintf('#%02X%02X%02X%02X', $this->r, $this->g, $this->b, \round($this->a * 0xFF)); + } + + return false; + } + + public function hasAlpha($variant = null) + { + if (null === $variant) { + $variant = $this->variant; + } + + switch ($variant) { + case self::COLOR_NAME: + case self::COLOR_RGB: + case self::COLOR_HSL: + return \abs($this->a - 1) >= 0.0001; + case self::COLOR_RGBA: + case self::COLOR_HSLA: + case self::COLOR_HEX_4: + case self::COLOR_HEX_8: + return true; + default: + return false; + } + } + + protected function setValues($value) + { + $value = \strtolower(\trim($value)); + // Find out which variant of color input it is + if (isset(self::$color_map[$value])) { + if (!$this->setValuesFromHex(self::$color_map[$value])) { + return; + } + + $variant = self::COLOR_NAME; + } elseif ('#' === $value[0]) { + $variant = $this->setValuesFromHex(\substr($value, 1)); + + if (!$variant) { + return; + } + } else { + $variant = $this->setValuesFromFunction($value); + + if (!$variant) { + return; + } + } + + // If something has gone horribly wrong + if ($this->r > 0xFF || $this->g > 0xFF || $this->b > 0xFF || $this->a > 1) { + $this->variant = null; // @codeCoverageIgnore + } else { + $this->variant = $variant; + $this->r = (int) $this->r; + $this->g = (int) $this->g; + $this->b = (int) $this->b; + $this->a = (float) $this->a; + } + } + + protected function setValuesFromHex($hex) + { + if (!\ctype_xdigit($hex)) { + return null; + } + + switch (\strlen($hex)) { + case 3: + $variant = self::COLOR_HEX_3; + break; + case 6: + $variant = self::COLOR_HEX_6; + break; + case 4: + $variant = self::COLOR_HEX_4; + break; + case 8: + $variant = self::COLOR_HEX_8; + break; + default: + return null; + } + + switch ($variant) { + case self::COLOR_HEX_4: + $this->a = \hexdec($hex[3]) / 0xF; + // no break + case self::COLOR_HEX_3: + $this->r = \hexdec($hex[0]) * 0x11; + $this->g = \hexdec($hex[1]) * 0x11; + $this->b = \hexdec($hex[2]) * 0x11; + break; + case self::COLOR_HEX_8: + $this->a = \hexdec(\substr($hex, 6, 2)) / 0xFF; + // no break + case self::COLOR_HEX_6: + $hex = \str_split($hex, 2); + $this->r = \hexdec($hex[0]); + $this->g = \hexdec($hex[1]); + $this->b = \hexdec($hex[2]); + break; + } + + return $variant; + } + + protected function setValuesFromFunction($value) + { + if (!\preg_match('/^((?:rgb|hsl)a?)\\s*\\(([0-9\\.%,\\s\\/\\-]+)\\)$/i', $value, $match)) { + return null; + } + + switch (\strtolower($match[1])) { + case 'rgb': + $variant = self::COLOR_RGB; + break; + case 'rgba': + $variant = self::COLOR_RGBA; + break; + case 'hsl': + $variant = self::COLOR_HSL; + break; + case 'hsla': + $variant = self::COLOR_HSLA; + break; + default: + return null; // @codeCoverageIgnore + } + + $params = \preg_replace('/[,\\s\\/]+/', ',', \trim($match[2])); + $params = \explode(',', $params); + $params = \array_map('trim', $params); + + if (\count($params) < 3 || \count($params) > 4) { + return null; + } + + foreach ($params as $i => &$color) { + if (false !== \strpos($color, '%')) { + $color = (float) \str_replace('%', '', $color); + + if (3 === $i) { + $color = $color / 100; + } elseif (\in_array($variant, array(self::COLOR_RGB, self::COLOR_RGBA), true)) { + $color = \round($color / 100 * 0xFF); + } + } + + $color = (float) $color; + + if (0 === $i && \in_array($variant, array(self::COLOR_HSL, self::COLOR_HSLA), true)) { + $color = ($color % 360 + 360) % 360; + } + } + + /** @var float[] Psalm bug workaround */ + $params = \array_map('floatval', $params); + + switch ($variant) { + case self::COLOR_RGBA: + case self::COLOR_RGB: + if (\min($params) < 0 || \max($params) > 0xFF) { + return null; + } + break; + case self::COLOR_HSLA: + case self::COLOR_HSL: + if (\min($params) < 0 || $params[0] > 360 || \max($params[1], $params[2]) > 100) { + return null; + } + break; + } + + if (4 === \count($params)) { + if ($params[3] > 1) { + return null; + } + + $this->a = $params[3]; + } + + if (self::COLOR_HSLA === $variant || self::COLOR_HSL === $variant) { + $params = self::hslToRgb($params[0], $params[1], $params[2]); + } + + list($this->r, $this->g, $this->b) = $params; + + return $variant; + } + + /** + * Turns HSL color to RGB. Black magic. + * + * @param float $h Hue + * @param float $s Saturation + * @param float $l Lightness + * + * @return int[] RGB array + */ + public static function hslToRgb($h, $s, $l) + { + if (\min($h, $s, $l) < 0) { + throw new InvalidArgumentException('The parameters for hslToRgb should be no less than 0'); + } + + if ($h > 360 || \max($s, $l) > 100) { + throw new InvalidArgumentException('The parameters for hslToRgb should be no more than 360, 100, and 100 respectively'); + } + + $h /= 360; + $s /= 100; + $l /= 100; + + $m2 = ($l <= 0.5) ? $l * ($s + 1) : $l + $s - $l * $s; + $m1 = $l * 2 - $m2; + + return array( + (int) \round(self::hueToRgb($m1, $m2, $h + 1 / 3) * 0xFF), + (int) \round(self::hueToRgb($m1, $m2, $h) * 0xFF), + (int) \round(self::hueToRgb($m1, $m2, $h - 1 / 3) * 0xFF), + ); + } + + /** + * Converts RGB to HSL. Color inversion of previous black magic is white magic? + * + * @param float|int $red Red + * @param float|int $green Green + * @param float|int $blue Blue + * + * @return float[] HSL array + */ + public static function rgbToHsl($red, $green, $blue) + { + if (\min($red, $green, $blue) < 0) { + throw new InvalidArgumentException('The parameters for rgbToHsl should be no less than 0'); + } + + if (\max($red, $green, $blue) > 0xFF) { + throw new InvalidArgumentException('The parameters for rgbToHsl should be no more than 255'); + } + + $clrMin = \min($red, $green, $blue); + $clrMax = \max($red, $green, $blue); + $deltaMax = $clrMax - $clrMin; + + $L = ($clrMax + $clrMin) / 510; + + if (0 == $deltaMax) { + $H = 0; + $S = 0; + } else { + if (0.5 > $L) { + $S = $deltaMax / ($clrMax + $clrMin); + } else { + $S = $deltaMax / (510 - $clrMax - $clrMin); + } + + if ($clrMax === $red) { + $H = ($green - $blue) / (6.0 * $deltaMax); + + if (0 > $H) { + $H += 1.0; + } + } elseif ($clrMax === $green) { + $H = 1 / 3 + ($blue - $red) / (6.0 * $deltaMax); + } else { + $H = 2 / 3 + ($red - $green) / (6.0 * $deltaMax); + } + } + + return array( + (float) ($H * 360 % 360), + (float) ($S * 100), + (float) ($L * 100), + ); + } + + /** + * Helper function for hslToRgb. Even blacker magic. + * + * + * @param float $m1 + * @param float $m2 + * @param float $hue + * + * @return float Color value + */ + private static function hueToRgb($m1, $m2, $hue) + { + $hue = ($hue < 0) ? $hue + 1 : (($hue > 1) ? $hue - 1 : $hue); + if ($hue * 6 < 1) { + return $m1 + ($m2 - $m1) * $hue * 6; + } + if ($hue * 2 < 1) { + return $m2; + } + if ($hue * 3 < 2) { + return $m1 + ($m2 - $m1) * (2 / 3 - $hue) * 6; + } + + return $m1; + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/DocstringRepresentation.php b/vendor/kint-php/kint/src/Object/Representation/DocstringRepresentation.php new file mode 100644 index 0000000..488d8d6 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/DocstringRepresentation.php @@ -0,0 +1,73 @@ +file = $file; + $this->line = $line; + $this->class = $class; + $this->contents = $docstring; + } + + /** + * Returns the representation's docstring without surrounding comments. + * + * Note that this will not work flawlessly. + * + * On comments with whitespace after the stars the lines will begin with + * whitespace, since we can't accurately guess how much of an indentation + * is required. + * + * And on lines without stars on the left this may eat bullet points. + * + * Long story short: If you want the docstring read the contents. If you + * absolutely must have it without comments (ie renderValueShort) this will + * probably do. + * + * @return null|string Docstring with comments stripped + */ + public function getDocstringWithoutComments() + { + if (!$this->contents) { + return null; + } + + $string = \substr($this->contents, 3, -2); + $string = \preg_replace('/^\\s*\\*\\s*?(\\S|$)/m', '\\1', $string); + + return \trim($string); + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/MicrotimeRepresentation.php b/vendor/kint-php/kint/src/Object/Representation/MicrotimeRepresentation.php new file mode 100644 index 0000000..b9f4dac --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/MicrotimeRepresentation.php @@ -0,0 +1,71 @@ +seconds = (int) $seconds; + $this->microseconds = (int) $microseconds; + + $this->group = $group; + $this->lap = $lap; + $this->total = $total; + $this->i = $i; + + if ($i) { + $this->avg = $total / $i; + } + + $this->mem = \memory_get_usage(); + $this->mem_real = \memory_get_usage(true); + $this->mem_peak = \memory_get_peak_usage(); + $this->mem_peak_real = \memory_get_peak_usage(true); + } + + public function getDateTime() + { + return DateTime::createFromFormat('U u', $this->seconds.' '.\str_pad($this->microseconds, 6, '0', STR_PAD_LEFT)); + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/Representation.php b/vendor/kint-php/kint/src/Object/Representation/Representation.php new file mode 100644 index 0000000..0c911a4 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/Representation.php @@ -0,0 +1,71 @@ +label = $label; + + if (null === $name) { + $name = $label; + } + + $this->setName($name); + } + + public function getLabel() + { + if (\is_array($this->contents) && \count($this->contents) > 1) { + return $this->label.' ('.\count($this->contents).')'; + } + + return $this->label; + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + $this->name = \preg_replace('/[^a-z0-9]+/', '_', \strtolower($name)); + } + + public function labelIsImplicit() + { + return $this->implicit_label; + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/SourceRepresentation.php b/vendor/kint-php/kint/src/Object/Representation/SourceRepresentation.php new file mode 100644 index 0000000..c2cf120 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/SourceRepresentation.php @@ -0,0 +1,72 @@ +filename = $filename; + $this->line = $line; + + $start_line = \max($line - $padding, 1); + $length = $line + $padding + 1 - $start_line; + $this->source = self::getSource($filename, $start_line, $length); + if (null !== $this->source) { + $this->contents = \implode("\n", $this->source); + } + } + + /** + * Gets section of source code. + * + * @param string $filename Full path to file + * @param int $start_line The first line to display (1 based) + * @param null|int $length Amount of lines to show + * + * @return null|array + */ + public static function getSource($filename, $start_line = 1, $length = null) + { + if (!$filename || !\file_exists($filename) || !\is_readable($filename)) { + return null; + } + + $source = \preg_split("/\r\n|\n|\r/", \file_get_contents($filename)); + $source = \array_combine(\range(1, \count($source)), $source); + $source = \array_slice($source, $start_line - 1, $length, true); + + return $source; + } +} diff --git a/vendor/kint-php/kint/src/Object/Representation/SplFileInfoRepresentation.php b/vendor/kint-php/kint/src/Object/Representation/SplFileInfoRepresentation.php new file mode 100644 index 0000000..3df50e6 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/Representation/SplFileInfoRepresentation.php @@ -0,0 +1,177 @@ +getRealPath()) { + $this->realpath = $fileInfo->getRealPath(); + $this->perms = $fileInfo->getPerms(); + $this->size = $fileInfo->getSize(); + $this->owner = $fileInfo->getOwner(); + $this->group = $fileInfo->getGroup(); + $this->ctime = $fileInfo->getCTime(); + $this->mtime = $fileInfo->getMTime(); + } + + $this->path = $fileInfo->getPathname(); + + $this->is_dir = $fileInfo->isDir(); + $this->is_file = $fileInfo->isFile(); + $this->is_link = $fileInfo->isLink(); + + if ($this->is_link) { + $this->linktarget = $fileInfo->getLinkTarget(); + } + + switch ($this->perms & 0xF000) { + case 0xC000: + $this->typename = 'Socket'; + $this->typeflag = 's'; + break; + case 0x6000: + $this->typename = 'Block device'; + $this->typeflag = 'b'; + break; + case 0x2000: + $this->typename = 'Character device'; + $this->typeflag = 'c'; + break; + case 0x1000: + $this->typename = 'Named pipe'; + $this->typeflag = 'p'; + break; + default: + if ($this->is_file) { + if ($this->is_link) { + $this->typename = 'File symlink'; + $this->typeflag = 'l'; + } else { + $this->typename = 'File'; + $this->typeflag = '-'; + } + } elseif ($this->is_dir) { + if ($this->is_link) { + $this->typename = 'Directory symlink'; + $this->typeflag = 'l'; + } else { + $this->typename = 'Directory'; + $this->typeflag = 'd'; + } + } + break; + } + + $this->flags = array($this->typeflag); + + // User + $this->flags[] = (($this->perms & 0400) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0200) ? 'w' : '-'); + if ($this->perms & 0100) { + $this->flags[] = ($this->perms & 04000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 04000) ? 'S' : '-'; + } + + // Group + $this->flags[] = (($this->perms & 0040) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0020) ? 'w' : '-'); + if ($this->perms & 0010) { + $this->flags[] = ($this->perms & 02000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 02000) ? 'S' : '-'; + } + + // Other + $this->flags[] = (($this->perms & 0004) ? 'r' : '-'); + $this->flags[] = (($this->perms & 0002) ? 'w' : '-'); + if ($this->perms & 0001) { + $this->flags[] = ($this->perms & 01000) ? 's' : 'x'; + } else { + $this->flags[] = ($this->perms & 01000) ? 'S' : '-'; + } + + $this->contents = \implode($this->flags).' '.$this->owner.' '.$this->group; + $this->contents .= ' '.$this->getSize().' '.$this->getMTime().' '; + + if ($this->is_link && $this->linktarget) { + $this->contents .= $this->path.' -> '.$this->linktarget; + } elseif (null !== $this->realpath && \strlen($this->realpath) < \strlen($this->path)) { + $this->contents .= $this->realpath; + } else { + $this->contents .= $this->path; + } + } + + public function getLabel() + { + return $this->typename.' ('.$this->getSize().')'; + } + + public function getSize() + { + if ($this->size) { + $size = Utils::getHumanReadableBytes($this->size); + + return \round($size['value'], 2).$size['unit']; + } + } + + public function getMTime() + { + $year = \date('Y', $this->mtime); + + if ($year !== \date('Y')) { + return \date('M d Y', $this->mtime); + } + + return \date('M d H:i', $this->mtime); + } +} diff --git a/vendor/kint-php/kint/src/Object/ResourceObject.php b/vendor/kint-php/kint/src/Object/ResourceObject.php new file mode 100644 index 0000000..a43f85d --- /dev/null +++ b/vendor/kint-php/kint/src/Object/ResourceObject.php @@ -0,0 +1,49 @@ +resource_type) { + return $this->resource_type.' resource'; + } + + return 'resource'; + } + + public function transplant(BasicObject $old) + { + parent::transplant($old); + + if ($old instanceof self) { + $this->resource_type = $old->resource_type; + } + } +} diff --git a/vendor/kint-php/kint/src/Object/StreamObject.php b/vendor/kint-php/kint/src/Object/StreamObject.php new file mode 100644 index 0000000..358f274 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/StreamObject.php @@ -0,0 +1,54 @@ +stream_meta = $meta; + } + + public function getValueShort() + { + if (empty($this->stream_meta['uri'])) { + return; + } + + $uri = $this->stream_meta['uri']; + + if (\stream_is_local($uri)) { + return Kint::shortenPath($uri); + } + + return $uri; + } +} diff --git a/vendor/kint-php/kint/src/Object/ThrowableObject.php b/vendor/kint-php/kint/src/Object/ThrowableObject.php new file mode 100644 index 0000000..2a86d57 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/ThrowableObject.php @@ -0,0 +1,54 @@ +message = $throw->getMessage(); + } + + public function getValueShort() + { + if (\strlen($this->message)) { + return '"'.$this->message.'"'; + } + } +} diff --git a/vendor/kint-php/kint/src/Object/TraceFrameObject.php b/vendor/kint-php/kint/src/Object/TraceFrameObject.php new file mode 100644 index 0000000..4259aee --- /dev/null +++ b/vendor/kint-php/kint/src/Object/TraceFrameObject.php @@ -0,0 +1,100 @@ +transplant($base); + + $this->trace = array( + 'function' => isset($raw_frame['function']) ? $raw_frame['function'] : null, + 'line' => isset($raw_frame['line']) ? $raw_frame['line'] : null, + 'file' => isset($raw_frame['file']) ? $raw_frame['file'] : null, + 'class' => isset($raw_frame['class']) ? $raw_frame['class'] : null, + 'type' => isset($raw_frame['type']) ? $raw_frame['type'] : null, + 'object' => null, + 'args' => null, + ); + + if ($this->trace['class'] && \method_exists($this->trace['class'], $this->trace['function'])) { + $func = new ReflectionMethod($this->trace['class'], $this->trace['function']); + $this->trace['function'] = new MethodObject($func); + } elseif (!$this->trace['class'] && \function_exists($this->trace['function'])) { + $func = new ReflectionFunction($this->trace['function']); + $this->trace['function'] = new MethodObject($func); + } + + foreach ($this->value->contents as $frame_prop) { + if ('object' === $frame_prop->name) { + $this->trace['object'] = $frame_prop; + $this->trace['object']->name = null; + $this->trace['object']->operator = BasicObject::OPERATOR_NONE; + } + if ('args' === $frame_prop->name) { + $this->trace['args'] = $frame_prop->value->contents; + + if ($this->trace['function'] instanceof MethodObject) { + foreach (\array_values($this->trace['function']->parameters) as $param) { + if (isset($this->trace['args'][$param->position])) { + $this->trace['args'][$param->position]->name = $param->getName(); + } + } + } + } + } + + $this->clearRepresentations(); + + if (isset($this->trace['file'], $this->trace['line']) && \is_readable($this->trace['file'])) { + $this->addRepresentation(new SourceRepresentation($this->trace['file'], $this->trace['line'])); + } + + if ($this->trace['args']) { + $args = new Representation('Arguments'); + $args->contents = $this->trace['args']; + $this->addRepresentation($args); + } + + if ($this->trace['object']) { + $callee = new Representation('object'); + $callee->label = 'Callee object ['.$this->trace['object']->classname.']'; + $callee->contents[] = $this->trace['object']; + $this->addRepresentation($callee); + } + } +} diff --git a/vendor/kint-php/kint/src/Object/TraceObject.php b/vendor/kint-php/kint/src/Object/TraceObject.php new file mode 100644 index 0000000..a780b08 --- /dev/null +++ b/vendor/kint-php/kint/src/Object/TraceObject.php @@ -0,0 +1,45 @@ +size) { + return 'empty'; + } + + return parent::getSize(); + } +} diff --git a/vendor/kint-php/kint/src/Parser/ArrayObjectPlugin.php b/vendor/kint-php/kint/src/Parser/ArrayObjectPlugin.php new file mode 100644 index 0000000..286d255 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ArrayObjectPlugin.php @@ -0,0 +1,63 @@ +getFlags(); + + if (ArrayObject::STD_PROP_LIST === $flags) { + return; + } + + $var->setFlags(ArrayObject::STD_PROP_LIST); + + $o = $this->parser->parse($var, $o); + + $var->setFlags($flags); + + $this->parser->haltParse(); + } +} diff --git a/vendor/kint-php/kint/src/Parser/Base64Plugin.php b/vendor/kint-php/kint/src/Parser/Base64Plugin.php new file mode 100644 index 0000000..3d7d6bc --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/Base64Plugin.php @@ -0,0 +1,95 @@ +depth = $o->depth + 1; + $base_obj->name = 'base64_decode('.$o->name.')'; + + if ($o->access_path) { + $base_obj->access_path = 'base64_decode('.$o->access_path.')'; + } + + $r = new Representation('Base64'); + $r->contents = $this->parser->parse($data, $base_obj); + + if (\strlen($var) > self::$min_length_soft) { + $o->addRepresentation($r, 0); + } else { + $o->addRepresentation($r); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/BinaryPlugin.php b/vendor/kint-php/kint/src/Parser/BinaryPlugin.php new file mode 100644 index 0000000..327c297 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/BinaryPlugin.php @@ -0,0 +1,49 @@ +encoding, array('ASCII', 'UTF-8'), true)) { + $o->value->hints[] = 'binary'; + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/BlacklistPlugin.php b/vendor/kint-php/kint/src/Parser/BlacklistPlugin.php new file mode 100644 index 0000000..b37e45f --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/BlacklistPlugin.php @@ -0,0 +1,143 @@ +parseObject($var, $o); + } + if (\is_array($var)) { + return $this->parseArray($var, $o); + } + } + + protected function parseObject(&$var, BasicObject &$o) + { + foreach (self::$blacklist as $class) { + if ($var instanceof $class) { + return $this->blacklistObject($var, $o); + } + } + + if ($o->depth <= 0) { + return; + } + + foreach (self::$shallow_blacklist as $class) { + if ($var instanceof $class) { + return $this->blacklistObject($var, $o); + } + } + } + + protected function blacklistObject(&$var, BasicObject &$o) + { + $object = new InstanceObject(); + $object->transplant($o); + $object->classname = \get_class($var); + $object->hash = \spl_object_hash($var); + $object->clearRepresentations(); + $object->value = null; + $object->size = null; + $object->hints[] = 'blacklist'; + + $o = $object; + + $this->parser->haltParse(); + } + + protected function parseArray(array &$var, BasicObject &$o) + { + if (\count($var) > self::$array_limit) { + return $this->blacklistArray($var, $o); + } + + if ($o->depth <= 0) { + return; + } + + if (\count($var) > self::$shallow_array_limit) { + return $this->blacklistArray($var, $o); + } + } + + protected function blacklistArray(array &$var, BasicObject &$o) + { + $object = new BasicObject(); + $object->transplant($o); + $object->value = null; + $object->size = \count($var); + $object->hints[] = 'blacklist'; + + $o = $object; + + $this->parser->haltParse(); + } +} diff --git a/vendor/kint-php/kint/src/Parser/ClassMethodsPlugin.php b/vendor/kint-php/kint/src/Parser/ClassMethodsPlugin.php new file mode 100644 index 0000000..e4c2371 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ClassMethodsPlugin.php @@ -0,0 +1,113 @@ +getMethods() as $method) { + $methods[] = new MethodObject($method); + } + + \usort($methods, array('Kint\\Parser\\ClassMethodsPlugin', 'sort')); + + self::$cache[$class] = $methods; + } + + if (!empty(self::$cache[$class])) { + $rep = new Representation('Available methods', 'methods'); + + // Can't cache access paths + foreach (self::$cache[$class] as $m) { + $method = clone $m; + $method->depth = $o->depth + 1; + + if (!$this->parser->childHasPath($o, $method)) { + $method->access_path = null; + } else { + $method->setAccessPathFrom($o); + } + + if ($method->owner_class !== $class && $ds = $method->getRepresentation('docstring')) { + $ds = clone $ds; + $ds->class = $method->owner_class; + $method->replaceRepresentation($ds); + } + + $rep->contents[] = $method; + } + + $o->addRepresentation($rep); + } + } + + private static function sort(MethodObject $a, MethodObject $b) + { + $sort = ((int) $a->static) - ((int) $b->static); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + $sort = InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + if ($sort) { + return $sort; + } + + return $a->startline - $b->startline; + } +} diff --git a/vendor/kint-php/kint/src/Parser/ClassStaticsPlugin.php b/vendor/kint-php/kint/src/Parser/ClassStaticsPlugin.php new file mode 100644 index 0000000..0ba58ca --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ClassStaticsPlugin.php @@ -0,0 +1,122 @@ +getConstants() as $name => $val) { + $const = BasicObject::blank($name, '\\'.$class.'::'.$name); + $const->const = true; + $const->depth = $o->depth + 1; + $const->owner_class = $class; + $const->operator = BasicObject::OPERATOR_STATIC; + $const = $this->parser->parse($val, $const); + + $consts[] = $const; + } + + self::$cache[$class] = $consts; + } + + $statics = new Representation('Static class properties', 'statics'); + $statics->contents = self::$cache[$class]; + + foreach ($reflection->getProperties(ReflectionProperty::IS_STATIC) as $static) { + $prop = new BasicObject(); + $prop->name = '$'.$static->getName(); + $prop->depth = $o->depth + 1; + $prop->static = true; + $prop->operator = BasicObject::OPERATOR_STATIC; + $prop->owner_class = $static->getDeclaringClass()->name; + + $prop->access = BasicObject::ACCESS_PUBLIC; + if ($static->isProtected()) { + $prop->access = BasicObject::ACCESS_PROTECTED; + } elseif ($static->isPrivate()) { + $prop->access = BasicObject::ACCESS_PRIVATE; + } + + if ($this->parser->childHasPath($o, $prop)) { + $prop->access_path = '\\'.$prop->owner_class.'::'.$prop->name; + } + + $static->setAccessible(true); + $static = $static->getValue(); + $statics->contents[] = $this->parser->parse($static, $prop); + } + + if (empty($statics->contents)) { + return; + } + + \usort($statics->contents, array('Kint\\Parser\\ClassStaticsPlugin', 'sort')); + + $o->addRepresentation($statics); + } + + private static function sort(BasicObject $a, BasicObject $b) + { + $sort = ((int) $a->const) - ((int) $b->const); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + } +} diff --git a/vendor/kint-php/kint/src/Parser/ClosurePlugin.php b/vendor/kint-php/kint/src/Parser/ClosurePlugin.php new file mode 100644 index 0000000..73e367b --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ClosurePlugin.php @@ -0,0 +1,94 @@ +transplant($o); + $o = $object; + $object->removeRepresentation('properties'); + + $closure = new ReflectionFunction($var); + + $o->filename = $closure->getFileName(); + $o->startline = $closure->getStartLine(); + + foreach ($closure->getParameters() as $param) { + $o->parameters[] = new ParameterObject($param); + } + + $p = new Representation('Parameters'); + $p->contents = &$o->parameters; + $o->addRepresentation($p, 0); + + $statics = array(); + + if (\method_exists($closure, 'getClosureThis') && $v = $closure->getClosureThis()) { + $statics = array('this' => $v); + } + + if (\count($statics = $statics + $closure->getStaticVariables())) { + $statics_parsed = array(); + + foreach ($statics as $name => &$static) { + $obj = BasicObject::blank('$'.$name); + $obj->depth = $o->depth + 1; + $statics_parsed[$name] = $this->parser->parse($static, $obj); + if (null === $statics_parsed[$name]->value) { + $statics_parsed[$name]->access_path = null; + } + } + + $r = new Representation('Uses'); + $r->contents = $statics_parsed; + $o->addRepresentation($r, 0); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/ColorPlugin.php b/vendor/kint-php/kint/src/Parser/ColorPlugin.php new file mode 100644 index 0000000..0d748f2 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ColorPlugin.php @@ -0,0 +1,63 @@ + 32) { + return; + } + + $trimmed = \strtolower(\trim($var)); + + if (!isset(ColorRepresentation::$color_map[$trimmed]) && !\preg_match('/^(?:(?:rgb|hsl)[^\\)]{6,}\\)|#[0-9a-fA-F]{3,8})$/', $trimmed)) { + return; + } + + $rep = new ColorRepresentation($var); + + if ($rep->variant) { + $o->removeRepresentation($o->value); + $o->addRepresentation($rep, 0); + $o->hints[] = 'color'; + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/DOMDocumentPlugin.php b/vendor/kint-php/kint/src/Parser/DOMDocumentPlugin.php new file mode 100644 index 0000000..ec08d31 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/DOMDocumentPlugin.php @@ -0,0 +1,328 @@ + 'DOMNode', + 'firstChild' => 'DOMNode', + 'lastChild' => 'DOMNode', + 'previousSibling' => 'DOMNode', + 'nextSibling' => 'DOMNode', + 'ownerDocument' => 'DOMDocument', + ); + + /** + * Show all properties and methods. + * + * @var bool + */ + public static $verbose = false; + + public function getTypes() + { + return array('object'); + } + + public function getTriggers() + { + return Parser::TRIGGER_SUCCESS; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + if (!$o instanceof InstanceObject) { + return; + } + + if ($var instanceof DOMNamedNodeMap || $var instanceof DOMNodeList) { + return $this->parseList($var, $o, $trigger); + } + + if ($var instanceof DOMNode) { + return $this->parseNode($var, $o); + } + } + + protected function parseList(&$var, InstanceObject &$o, $trigger) + { + // Recursion should never happen, should always be stopped at the parent + // DOMNode. Depth limit on the other hand we're going to skip since + // that would show an empty iterator and rather useless. Let the depth + // limit hit the children (DOMNodeList only has DOMNode as children) + if ($trigger & Parser::TRIGGER_RECURSION) { + return; + } + + $o->size = $var->length; + if (0 === $o->size) { + $o->replaceRepresentation(new Representation('Iterator')); + $o->size = null; + + return; + } + + // Depth limit + // Make empty iterator representation since we need it in DOMNode to point out depth limits + if ($this->parser->getDepthLimit() && $o->depth + 1 >= $this->parser->getDepthLimit()) { + $b = new BasicObject(); + $b->name = $o->classname.' Iterator Contents'; + $b->access_path = 'iterator_to_array('.$o->access_path.')'; + $b->depth = $o->depth + 1; + $b->hints[] = 'depth_limit'; + + $r = new Representation('Iterator'); + $r->contents = array($b); + $o->replaceRepresentation($r, 0); + + return; + } + + $data = \iterator_to_array($var); + + $r = new Representation('Iterator'); + $o->replaceRepresentation($r, 0); + + foreach ($data as $key => $item) { + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $item->nodeName; + + if ($o->access_path) { + if ($var instanceof DOMNamedNodeMap) { + $base_obj->access_path = $o->access_path.'->getNamedItem('.\var_export($key, true).')'; + } elseif ($var instanceof DOMNodeList) { + $base_obj->access_path = $o->access_path.'->item('.\var_export($key, true).')'; + } else { + $base_obj->access_path = 'iterator_to_array('.$o->access_path.')'; + } + } + + $r->contents[] = $this->parser->parse($item, $base_obj); + } + } + + protected function parseNode(&$var, InstanceObject &$o) + { + // Fill the properties + // They can't be enumerated through reflection or casting, + // so we have to trust the docs and try them one at a time + $known_properties = array( + 'nodeValue', + 'childNodes', + 'attributes', + ); + + if (self::$verbose) { + $known_properties = array( + 'nodeName', + 'nodeValue', + 'nodeType', + 'parentNode', + 'childNodes', + 'firstChild', + 'lastChild', + 'previousSibling', + 'nextSibling', + 'attributes', + 'ownerDocument', + 'namespaceURI', + 'prefix', + 'localName', + 'baseURI', + 'textContent', + ); + } + + $childNodes = array(); + $attributes = array(); + + $rep = $o->value; + + foreach ($known_properties as $prop) { + $prop_obj = $this->parseProperty($o, $prop, $var); + $rep->contents[] = $prop_obj; + + if ('childNodes' === $prop) { + $childNodes = $prop_obj->getRepresentation('iterator'); + } elseif ('attributes' === $prop) { + $attributes = $prop_obj->getRepresentation('iterator'); + } + } + + if (!self::$verbose) { + $o->removeRepresentation('methods'); + $o->removeRepresentation('properties'); + } + + // Attributes and comments and text nodes don't + // need children or attributes of their own + if (\in_array($o->classname, array('DOMAttr', 'DOMText', 'DOMComment'), true)) { + return; + } + + // Set the attributes + if ($attributes) { + $a = new Representation('Attributes'); + foreach ($attributes->contents as $attribute) { + $a->contents[] = self::textualNodeToString($attribute); + } + $o->addRepresentation($a, 0); + } + + // Set the children + if ($childNodes) { + $c = new Representation('Children'); + + if (1 === \count($childNodes->contents) && ($node = \reset($childNodes->contents)) && \in_array('depth_limit', $node->hints, true)) { + $n = new InstanceObject(); + $n->transplant($node); + $n->name = 'childNodes'; + $n->classname = 'DOMNodeList'; + $c->contents = array($n); + } else { + foreach ($childNodes->contents as $index => $node) { + // Shortcircuit text nodes to plain strings + if ('DOMText' === $node->classname || 'DOMComment' === $node->classname) { + $node = self::textualNodeToString($node); + + // And remove them if they're empty + if (\ctype_space($node->value->contents) || '' === $node->value->contents) { + continue; + } + } + + $c->contents[] = $node; + } + } + + $o->addRepresentation($c, 0); + } + + if (isset($c) && \count($c->contents)) { + $o->size = \count($c->contents); + } + + if (!$o->size) { + $o->size = null; + } + } + + protected function parseProperty(InstanceObject $o, $prop, &$var) + { + // Duplicating (And slightly optimizing) the Parser::parseObject() code here + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->owner_class = $o->classname; + $base_obj->name = $prop; + $base_obj->operator = BasicObject::OPERATOR_OBJECT; + $base_obj->access = BasicObject::ACCESS_PUBLIC; + + if (null !== $o->access_path) { + $base_obj->access_path = $o->access_path; + + if (\preg_match('/^[A-Za-z0-9_]+$/', $base_obj->name)) { + $base_obj->access_path .= '->'.$base_obj->name; + } else { + $base_obj->access_path .= '->{'.\var_export($base_obj->name, true).'}'; + } + } + + if (!isset($var->{$prop})) { + $base_obj->type = 'null'; + } elseif (isset(self::$blacklist[$prop])) { + $b = new InstanceObject(); + $b->transplant($base_obj); + $base_obj = $b; + + $base_obj->hints[] = 'blacklist'; + $base_obj->classname = self::$blacklist[$prop]; + } elseif ('attributes' === $prop) { + $base_obj = $this->parser->parseDeep($var->{$prop}, $base_obj); + } else { + $base_obj = $this->parser->parse($var->{$prop}, $base_obj); + } + + return $base_obj; + } + + protected static function textualNodeToString(InstanceObject $o) + { + if (empty($o->value) || empty($o->value->contents) || empty($o->classname)) { + return; + } + + if (!\in_array($o->classname, array('DOMText', 'DOMAttr', 'DOMComment'), true)) { + return; + } + + foreach ($o->value->contents as $property) { + if ('nodeValue' === $property->name) { + $ret = clone $property; + $ret->name = $o->name; + + return $ret; + } + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/DateTimePlugin.php b/vendor/kint-php/kint/src/Parser/DateTimePlugin.php new file mode 100644 index 0000000..f2cebb6 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/DateTimePlugin.php @@ -0,0 +1,55 @@ +transplant($o); + + $o = $object; + } +} diff --git a/vendor/kint-php/kint/src/Parser/FsPathPlugin.php b/vendor/kint-php/kint/src/Parser/FsPathPlugin.php new file mode 100644 index 0000000..3a8d1e0 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/FsPathPlugin.php @@ -0,0 +1,72 @@ + 2048) { + return; + } + + if (!\preg_match('/[\\/\\'.DIRECTORY_SEPARATOR.']/', $var)) { + return; + } + + if (\preg_match('/[?<>"*|]/', $var)) { + return; + } + + if (!@\file_exists($var)) { + return; + } + + if (\in_array($var, self::$blacklist, true)) { + return; + } + + $r = new SplFileInfoRepresentation(new SplFileInfo($var)); + $r->hints[] = 'fspath'; + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/kint-php/kint/src/Parser/IteratorPlugin.php b/vendor/kint-php/kint/src/Parser/IteratorPlugin.php new file mode 100644 index 0000000..0487a38 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/IteratorPlugin.php @@ -0,0 +1,110 @@ +name = $class.' Iterator Contents'; + $b->access_path = 'iterator_to_array('.$o->access_path.', true)'; + $b->depth = $o->depth + 1; + $b->hints[] = 'blacklist'; + + $r = new Representation('Iterator'); + $r->contents = array($b); + + $o->addRepresentation($r); + + return; + } + } + + /** @var array|false */ + $data = \iterator_to_array($var); + + if (false === $data) { + return; + } + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'iterator_to_array('.$o->access_path.')'; + } + + $r = new Representation('Iterator'); + $r->contents = $this->parser->parse($data, $base_obj); + $r->contents = $r->contents->value->contents; + + $primary = $o->getRepresentations(); + $primary = \reset($primary); + if ($primary && $primary === $o->value && $primary->contents === array()) { + $o->addRepresentation($r, 0); + } else { + $o->addRepresentation($r); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/JsonPlugin.php b/vendor/kint-php/kint/src/Parser/JsonPlugin.php new file mode 100644 index 0000000..84b2519 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/JsonPlugin.php @@ -0,0 +1,73 @@ +depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'json_decode('.$o->access_path.', true)'; + } + + $r = new Representation('Json'); + $r->contents = $this->parser->parse($json, $base_obj); + + if (!\in_array('depth_limit', $r->contents->hints, true)) { + $r->contents = $r->contents->value->contents; + } + + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/kint-php/kint/src/Parser/MicrotimePlugin.php b/vendor/kint-php/kint/src/Parser/MicrotimePlugin.php new file mode 100644 index 0000000..5062b59 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/MicrotimePlugin.php @@ -0,0 +1,105 @@ +depth) { + return; + } + + if (\is_string($var)) { + if ('microtime()' !== $o->name || !\preg_match('/^0\\.[0-9]{8} [0-9]{10}$/', $var)) { + return; + } + + $usec = (int) \substr($var, 2, 6); + $sec = (int) \substr($var, 11, 10); + } else { + if ('microtime(...)' !== $o->name) { + return; + } + + $sec = \floor($var); + $usec = $var - $sec; + $usec = \floor($usec * 1000000); + } + + $time = $sec + ($usec / 1000000); + + if (null !== self::$last) { + $last_time = self::$last[0] + (self::$last[1] / 1000000); + $lap = $time - $last_time; + ++self::$times; + } else { + $lap = null; + self::$start = $time; + } + + self::$last = array($sec, $usec); + + if (null !== $lap) { + $total = $time - self::$start; + $r = new MicrotimeRepresentation($sec, $usec, self::$group, $lap, $total, self::$times); + } else { + $r = new MicrotimeRepresentation($sec, $usec, self::$group); + } + $r->contents = $var; + $r->implicit_label = true; + + $o->removeRepresentation($o->value); + $o->addRepresentation($r); + $o->hints[] = 'microtime'; + } + + public static function clean() + { + self::$last = null; + self::$start = null; + self::$times = 0; + ++self::$group; + } +} diff --git a/vendor/kint-php/kint/src/Parser/MysqliPlugin.php b/vendor/kint-php/kint/src/Parser/MysqliPlugin.php new file mode 100644 index 0000000..265299b --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/MysqliPlugin.php @@ -0,0 +1,129 @@ + true, + 'connect_errno' => true, + 'connect_error' => true, + ); + + // These are readable on empty mysqli objects, but not on failed connections + protected $empty_readable = array( + 'client_info' => true, + 'errno' => true, + 'error' => true, + ); + + // These are only readable on connected mysqli objects + protected $connected_readable = array( + 'affected_rows' => true, + 'error_list' => true, + 'field_count' => true, + 'host_info' => true, + 'info' => true, + 'insert_id' => true, + 'server_info' => true, + 'server_version' => true, + 'stat' => true, + 'sqlstate' => true, + 'protocol_version' => true, + 'thread_id' => true, + 'warning_count' => true, + ); + + public function getTypes() + { + return array('object'); + } + + public function getTriggers() + { + return Parser::TRIGGER_COMPLETE; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + if (!$var instanceof Mysqli) { + return; + } + + $connected = false; + $empty = false; + + if (\is_string(@$var->sqlstate)) { + $connected = true; + } elseif (\is_string(@$var->client_info)) { + $empty = true; + } + + foreach ($o->value->contents as $key => $obj) { + if (isset($this->connected_readable[$obj->name])) { + if (!$connected) { + continue; + } + } elseif (isset($this->empty_readable[$obj->name])) { + if (!$connected && !$empty) { + continue; + } + } elseif (!isset($this->always_readable[$obj->name])) { + continue; + } + + if ('null' !== $obj->type) { + continue; + } + + $param = $var->{$obj->name}; + + if (null === $param) { + continue; + } + + $base = BasicObject::blank($obj->name, $obj->access_path); + + $base->depth = $obj->depth; + $base->owner_class = $obj->owner_class; + $base->operator = $obj->operator; + $base->access = $obj->access; + $base->reference = $obj->reference; + + $o->value->contents[$key] = $this->parser->parse($param, $base); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/Parser.php b/vendor/kint-php/kint/src/Parser/Parser.php new file mode 100644 index 0000000..b7f81c6 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/Parser.php @@ -0,0 +1,604 @@ +marker = \uniqid("kint\0", true); + + $this->caller_class = $caller; + + if ($depth_limit) { + $this->depth_limit = $depth_limit; + } + } + + /** + * Set the caller class. + * + * @param null|string $caller Caller class name + */ + public function setCallerClass($caller = null) + { + $this->noRecurseCall(); + + $this->caller_class = $caller; + } + + public function getCallerClass() + { + return $this->caller_class; + } + + /** + * Set the depth limit. + * + * @param false|int $depth_limit Maximum depth to parse data + */ + public function setDepthLimit($depth_limit = false) + { + $this->noRecurseCall(); + + $this->depth_limit = $depth_limit; + } + + public function getDepthLimit() + { + return $this->depth_limit; + } + + /** + * Disables the depth limit and parses a variable. + * + * This should not be used unless you know what you're doing! + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + public function parseDeep(&$var, BasicObject $o) + { + $depth_limit = $this->depth_limit; + $this->depth_limit = false; + + $out = $this->parse($var, $o); + + $this->depth_limit = $depth_limit; + + return $out; + } + + /** + * Parses a variable into a Kint object structure. + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + public function parse(&$var, BasicObject $o) + { + $o->type = \strtolower(\gettype($var)); + + if (!$this->applyPlugins($var, $o, self::TRIGGER_BEGIN)) { + return $o; + } + + switch ($o->type) { + case 'array': + return $this->parseArray($var, $o); + case 'boolean': + case 'double': + case 'integer': + case 'null': + return $this->parseGeneric($var, $o); + case 'object': + return $this->parseObject($var, $o); + case 'resource': + return $this->parseResource($var, $o); + case 'string': + return $this->parseString($var, $o); + default: + return $this->parseUnknown($var, $o); + } + } + + public function addPlugin(Plugin $p) + { + if (!$types = $p->getTypes()) { + return false; + } + + if (!$triggers = $p->getTriggers()) { + return false; + } + + $p->setParser($this); + + foreach ($types as $type) { + if (!isset($this->plugins[$type])) { + $this->plugins[$type] = array( + self::TRIGGER_BEGIN => array(), + self::TRIGGER_SUCCESS => array(), + self::TRIGGER_RECURSION => array(), + self::TRIGGER_DEPTH_LIMIT => array(), + ); + } + + foreach ($this->plugins[$type] as $trigger => &$pool) { + if ($triggers & $trigger) { + $pool[] = $p; + } + } + } + + return true; + } + + public function clearPlugins() + { + $this->plugins = array(); + } + + public function haltParse() + { + $this->parse_break = true; + } + + public function childHasPath(InstanceObject $parent, BasicObject $child) + { + if ('object' === $parent->type && (null !== $parent->access_path || $child->static || $child->const)) { + if (BasicObject::ACCESS_PUBLIC === $child->access) { + return true; + } + + if (BasicObject::ACCESS_PRIVATE === $child->access && $this->caller_class) { + if ($this->caller_class === $child->owner_class) { + return true; + } + } elseif (BasicObject::ACCESS_PROTECTED === $child->access && $this->caller_class) { + if ($this->caller_class === $child->owner_class) { + return true; + } + + if (\is_subclass_of($this->caller_class, $child->owner_class)) { + return true; + } + + if (\is_subclass_of($child->owner_class, $this->caller_class)) { + return true; + } + } + } + + return false; + } + + /** + * Returns an array without the recursion marker in it. + * + * DO NOT pass an array that has had it's marker removed back + * into the parser, it will result in an extra recursion + * + * @param array $array Array potentially containing a recursion marker + * + * @return array Array with recursion marker removed + */ + public function getCleanArray(array $array) + { + unset($array[$this->marker]); + + return $array; + } + + protected function noRecurseCall() + { + $bt = \debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT | DEBUG_BACKTRACE_IGNORE_ARGS); + + $caller_frame = array( + 'function' => __FUNCTION__, + ); + + while (isset($bt[0]['object']) && $bt[0]['object'] === $this) { + $caller_frame = \array_shift($bt); + } + + foreach ($bt as $frame) { + if (isset($frame['object']) && $frame['object'] === $this) { + throw new DomainException(__CLASS__.'::'.$caller_frame['function'].' cannot be called from inside a parse'); + } + } + } + + private function parseGeneric(&$var, BasicObject $o) + { + $rep = new Representation('Contents'); + $rep->contents = $var; + $rep->implicit_label = true; + $o->addRepresentation($rep); + $o->value = $rep; + + $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS); + + return $o; + } + + /** + * Parses a string into a Kint BlobObject structure. + * + * @param string $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseString(&$var, BasicObject $o) + { + $string = new BlobObject(); + $string->transplant($o); + $string->encoding = BlobObject::detectEncoding($var); + $string->size = BlobObject::strlen($var, $string->encoding); + + $rep = new Representation('Contents'); + $rep->contents = $var; + $rep->implicit_label = true; + + $string->addRepresentation($rep); + $string->value = $rep; + + $this->applyPlugins($var, $string, self::TRIGGER_SUCCESS); + + return $string; + } + + /** + * Parses an array into a Kint object structure. + * + * @param array $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseArray(array &$var, BasicObject $o) + { + $array = new BasicObject(); + $array->transplant($o); + $array->size = \count($var); + + if (isset($var[$this->marker])) { + --$array->size; + $array->hints[] = 'recursion'; + + $this->applyPlugins($var, $array, self::TRIGGER_RECURSION); + + return $array; + } + + $rep = new Representation('Contents'); + $rep->implicit_label = true; + $array->addRepresentation($rep); + $array->value = $rep; + + if (!$array->size) { + $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS); + + return $array; + } + + if ($this->depth_limit && $o->depth >= $this->depth_limit) { + $array->hints[] = 'depth_limit'; + + $this->applyPlugins($var, $array, self::TRIGGER_DEPTH_LIMIT); + + return $array; + } + + $copy = \array_values($var); + + // It's really really hard to access numeric string keys in arrays, + // and it's really really hard to access integer properties in + // objects, so we just use array_values and index by counter to get + // at it reliably for reference testing. This also affects access + // paths since it's pretty much impossible to access these things + // without complicated stuff you should never need to do. + $i = 0; + + // Set the marker for recursion + $var[$this->marker] = $array->depth; + + $refmarker = new stdClass(); + + foreach ($var as $key => &$val) { + if ($key === $this->marker) { + continue; + } + + $child = new BasicObject(); + $child->name = $key; + $child->depth = $array->depth + 1; + $child->access = BasicObject::ACCESS_NONE; + $child->operator = BasicObject::OPERATOR_ARRAY; + + if (null !== $array->access_path) { + if (\is_string($key) && (string) (int) $key === $key) { + $child->access_path = 'array_values('.$array->access_path.')['.$i.']'; // @codeCoverageIgnore + } else { + $child->access_path = $array->access_path.'['.\var_export($key, true).']'; + } + } + + $stash = $val; + $copy[$i] = $refmarker; + if ($val === $refmarker) { + $child->reference = true; + $val = $stash; + } + + $rep->contents[] = $this->parse($val, $child); + ++$i; + } + + $this->applyPlugins($var, $array, self::TRIGGER_SUCCESS); + unset($var[$this->marker]); + + return $array; + } + + /** + * Parses an object into a Kint InstanceObject structure. + * + * @param object $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseObject(&$var, BasicObject $o) + { + $hash = \spl_object_hash($var); + $values = (array) $var; + + $object = new InstanceObject(); + $object->transplant($o); + $object->classname = \get_class($var); + $object->hash = $hash; + $object->size = \count($values); + + if (isset($this->object_hashes[$hash])) { + $object->hints[] = 'recursion'; + + $this->applyPlugins($var, $object, self::TRIGGER_RECURSION); + + return $object; + } + + $this->object_hashes[$hash] = $object; + + if ($this->depth_limit && $o->depth >= $this->depth_limit) { + $object->hints[] = 'depth_limit'; + + $this->applyPlugins($var, $object, self::TRIGGER_DEPTH_LIMIT); + unset($this->object_hashes[$hash]); + + return $object; + } + + $reflector = new ReflectionObject($var); + + if ($reflector->isUserDefined()) { + $object->filename = $reflector->getFileName(); + $object->startline = $reflector->getStartLine(); + } + + $rep = new Representation('Properties'); + + $copy = \array_values($values); + $refmarker = new stdClass(); + $i = 0; + + // Reflection will not show parent classes private properties, and if a + // property was unset it will happly trigger a notice looking for it. + foreach ($values as $key => &$val) { + // Casting object to array: + // private properties show in the form "\0$owner_class_name\0$property_name"; + // protected properties show in the form "\0*\0$property_name"; + // public properties show in the form "$property_name"; + // http://www.php.net/manual/en/language.types.array.php#language.types.array.casting + + $child = new BasicObject(); + $child->depth = $object->depth + 1; + $child->owner_class = $object->classname; + $child->operator = BasicObject::OPERATOR_OBJECT; + $child->access = BasicObject::ACCESS_PUBLIC; + + $split_key = \explode("\0", $key, 3); + + if (3 === \count($split_key) && '' === $split_key[0]) { + $child->name = $split_key[2]; + if ('*' === $split_key[1]) { + $child->access = BasicObject::ACCESS_PROTECTED; + } else { + $child->access = BasicObject::ACCESS_PRIVATE; + $child->owner_class = $split_key[1]; + } + } elseif (KINT_PHP72) { + $child->name = (string) $key; + } else { + $child->name = $key; // @codeCoverageIgnore + } + + if ($this->childHasPath($object, $child)) { + $child->access_path = $object->access_path; + + if (!KINT_PHP72 && \is_int($child->name)) { + $child->access_path = 'array_values((array) '.$child->access_path.')['.$i.']'; // @codeCoverageIgnore + } elseif (\preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $child->name)) { + $child->access_path .= '->'.$child->name; + } else { + $child->access_path .= '->{'.\var_export((string) $child->name, true).'}'; + } + } + + $stash = $val; + $copy[$i] = $refmarker; + if ($val === $refmarker) { + $child->reference = true; + $val = $stash; + } + + $rep->contents[] = $this->parse($val, $child); + ++$i; + } + + $object->addRepresentation($rep); + $object->value = $rep; + $this->applyPlugins($var, $object, self::TRIGGER_SUCCESS); + unset($this->object_hashes[$hash]); + + return $object; + } + + /** + * Parses a resource into a Kint ResourceObject structure. + * + * @param resource $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseResource(&$var, BasicObject $o) + { + $resource = new ResourceObject(); + $resource->transplant($o); + $resource->resource_type = \get_resource_type($var); + + $this->applyPlugins($var, $resource, self::TRIGGER_SUCCESS); + + return $resource; + } + + /** + * Parses an unknown into a Kint object structure. + * + * @param mixed $var The input variable + * @param BasicObject $o The base object + * + * @return BasicObject + */ + private function parseUnknown(&$var, BasicObject $o) + { + $o->type = 'unknown'; + $this->applyPlugins($var, $o, self::TRIGGER_SUCCESS); + + return $o; + } + + /** + * Applies plugins for an object type. + * + * @param mixed $var variable + * @param BasicObject $o Kint object parsed so far + * @param int $trigger The trigger to check for the plugins + * + * @return bool Continue parsing + */ + private function applyPlugins(&$var, BasicObject &$o, $trigger) + { + $break_stash = $this->parse_break; + + /** @var bool Psalm bug workaround */ + $this->parse_break = false; + + $plugins = array(); + + if (isset($this->plugins[$o->type][$trigger])) { + $plugins = $this->plugins[$o->type][$trigger]; + } + + foreach ($plugins as $plugin) { + try { + $plugin->parse($var, $o, $trigger); + } catch (Exception $e) { + \trigger_error( + 'An exception ('.\get_class($e).') was thrown in '.$e->getFile().' on line '.$e->getLine().' while executing Kint Parser Plugin "'.\get_class($plugin).'". Error message: '.$e->getMessage(), + E_USER_WARNING + ); + } + + if ($this->parse_break) { + $this->parse_break = $break_stash; + + return false; + } + } + + $this->parse_break = $break_stash; + + return true; + } +} diff --git a/vendor/kint-php/kint/src/Parser/Plugin.php b/vendor/kint-php/kint/src/Parser/Plugin.php new file mode 100644 index 0000000..51d5f0b --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/Plugin.php @@ -0,0 +1,55 @@ +parser = $p; + } + + /** + * An array of types (As returned by gettype) for all data this plugin can operate on. + * + * @return array List of types + */ + public function getTypes() + { + return array(); + } + + public function getTriggers() + { + return Parser::TRIGGER_NONE; + } + + abstract public function parse(&$variable, BasicObject &$o, $trigger); +} diff --git a/vendor/kint-php/kint/src/Parser/ProxyPlugin.php b/vendor/kint-php/kint/src/Parser/ProxyPlugin.php new file mode 100644 index 0000000..3376d3a --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ProxyPlugin.php @@ -0,0 +1,66 @@ +types = $types; + $this->triggers = $triggers; + $this->callback = $callback; + } + + public function getTypes() + { + return $this->types; + } + + public function getTriggers() + { + return $this->triggers; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + return \call_user_func_array($this->callback, array(&$var, &$o, $trigger, $this->parser)); + } +} diff --git a/vendor/kint-php/kint/src/Parser/SerializePlugin.php b/vendor/kint-php/kint/src/Parser/SerializePlugin.php new file mode 100644 index 0000000..c5dadb8 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/SerializePlugin.php @@ -0,0 +1,108 @@ + Unserialization can result in code being loaded and executed due to + * > object instantiation and autoloading, and a malicious user may be able + * > to exploit this. + * + * The natural way to stop that from happening is to just refuse to unserialize + * stuff by default. Which is what we're doing for anything that's not scalar. + * + * @var bool + */ + public static $safe_mode = true; + public static $options = array(true); + + public function getTypes() + { + return array('string'); + } + + public function getTriggers() + { + return Parser::TRIGGER_SUCCESS; + } + + public function parse(&$var, BasicObject &$o, $trigger) + { + $trimmed = \rtrim($var); + + if ('N;' !== $trimmed && !\preg_match('/^(?:[COabis]:\\d+[:;]|d:\\d+(?:\\.\\d+);)/', $trimmed)) { + return; + } + + if (!self::$safe_mode || !\in_array($trimmed[0], array('C', 'O', 'a'), true)) { + // Second parameter only supported on PHP 7 + if (KINT_PHP70) { + // Suppress warnings on unserializeable variable + $data = @\unserialize($trimmed, self::$options); + } else { + $data = @\unserialize($trimmed); + } + + if (false === $data && 'b:0;' !== \substr($trimmed, 0, 4)) { + return; + } + } + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = 'unserialize('.$o->name.')'; + + if ($o->access_path) { + $base_obj->access_path = 'unserialize('.$o->access_path; + if (!KINT_PHP70 || self::$options === array(true)) { + $base_obj->access_path .= ')'; + } elseif (self::$options === array(false)) { + $base_obj->access_path .= ', false)'; + } else { + $base_obj->access_path .= ', Serialize::$options)'; + } + } + + $r = new Representation('Serialized'); + + if (isset($data)) { + $r->contents = $this->parser->parse($data, $base_obj); + } else { + $base_obj->hints[] = 'blacklist'; + $r->contents = $base_obj; + } + + $o->addRepresentation($r, 0); + } +} diff --git a/vendor/kint-php/kint/src/Parser/SimpleXMLElementPlugin.php b/vendor/kint-php/kint/src/Parser/SimpleXMLElementPlugin.php new file mode 100644 index 0000000..b90c863 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/SimpleXMLElementPlugin.php @@ -0,0 +1,154 @@ +hints[] = 'simplexml_element'; + + if (!self::$verbose) { + $o->removeRepresentation('properties'); + $o->removeRepresentation('iterator'); + $o->removeRepresentation('methods'); + } + + // Attributes + $a = new Representation('Attributes'); + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = '(string) '.$o->access_path; + } + + if ($attribs = $var->attributes()) { + $attribs = \iterator_to_array($attribs); + $attribs = \array_map('strval', $attribs); + } else { + $attribs = array(); + } + + // XML attributes are by definition strings and don't have children, + // so up the depth limit in case we're just below the limit since + // there won't be any recursive stuff anyway. + $a->contents = $this->parser->parseDeep($attribs, $base_obj)->value->contents; + + $o->addRepresentation($a, 0); + + // Children + // We need to check children() separately from the values we already parsed because + // text contents won't show up in children() but they will show up in properties. + // + // Why do we still need to check for attributes if we already have an attributes() + // method? Hell if I know! + $children = $var->children(); + + if ($o->value) { + $c = new Representation('Children'); + + foreach ($o->value->contents as $value) { + if ('@attributes' === $value->name) { + continue; + } + + if (isset($children->{$value->name})) { + $i = 0; + + while (isset($children->{$value->name}[$i])) { + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $value->name; + if ($value->access_path) { + $base_obj->access_path = $value->access_path.'['.$i.']'; + } + + $value = $this->parser->parse($children->{$value->name}[$i], $base_obj); + + if ($value->access_path && 'string' === $value->type) { + $value->access_path = '(string) '.$value->access_path; + } + + $c->contents[] = $value; + + ++$i; + } + } + } + + $o->size = \count($c->contents); + + if (!$o->size) { + $o->size = null; + + if (\strlen((string) $var)) { + $base_obj = new BlobObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $o->name; + if ($o->access_path) { + $base_obj->access_path = '(string) '.$o->access_path; + } + + $value = (string) $var; + + $c = new Representation('Contents'); + $c->implicit_label = true; + $c->contents = array($this->parser->parseDeep($value, $base_obj)); + } + } + + $o->addRepresentation($c, 0); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/SplFileInfoPlugin.php b/vendor/kint-php/kint/src/Parser/SplFileInfoPlugin.php new file mode 100644 index 0000000..8b72193 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/SplFileInfoPlugin.php @@ -0,0 +1,55 @@ +addRepresentation($r, 0); + $o->size = $r->getSize(); + } +} diff --git a/vendor/kint-php/kint/src/Parser/SplObjectStoragePlugin.php b/vendor/kint-php/kint/src/Parser/SplObjectStoragePlugin.php new file mode 100644 index 0000000..03ff301 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/SplObjectStoragePlugin.php @@ -0,0 +1,54 @@ +getRepresentation('iterator'))) { + return; + } + + $r = $o->getRepresentation('iterator'); + if ($r) { + $o->size = !\is_array($r->contents) ? null : \count($r->contents); + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/StreamPlugin.php b/vendor/kint-php/kint/src/Parser/StreamPlugin.php new file mode 100644 index 0000000..464a3ff --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/StreamPlugin.php @@ -0,0 +1,78 @@ +resource_type) { + return; + } + + if (!$meta = \stream_get_meta_data($var)) { + return; + } + + $rep = new Representation('Stream'); + $rep->implicit_label = true; + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth; + + if ($o->access_path) { + $base_obj->access_path = 'stream_get_meta_data('.$o->access_path.')'; + } + + $rep->contents = $this->parser->parse($meta, $base_obj); + + if (!\in_array('depth_limit', $rep->contents->hints, true)) { + $rep->contents = $rep->contents->value->contents; + } + + $o->addRepresentation($rep, 0); + $o->value = $rep; + + $stream = new StreamObject($meta); + $stream->transplant($o); + $o = $stream; + } +} diff --git a/vendor/kint-php/kint/src/Parser/TablePlugin.php b/vendor/kint-php/kint/src/Parser/TablePlugin.php new file mode 100644 index 0000000..510c4ff --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/TablePlugin.php @@ -0,0 +1,87 @@ +value->contents)) { + return; + } + + $array = $this->parser->getCleanArray($var); + + if (\count($array) < 2) { + return; + } + + // Ensure this is an array of arrays and that all child arrays have the + // same keys. We don't care about their children - if there's another + // "table" inside we'll just make another one down the value tab + $keys = null; + foreach ($array as $elem) { + if (!\is_array($elem) || \count($elem) < 2) { + return; + } + + if (null === $keys) { + $keys = \array_keys($elem); + } elseif (\array_keys($elem) !== $keys) { + return; + } + } + + // Ensure none of the child arrays are recursion or depth limit. We + // don't care if their children are since they are the table cells + foreach ($o->value->contents as $childarray) { + if (empty($childarray->value->contents)) { + return; + } + } + + // Objects by reference for the win! We can do a copy-paste of the value + // representation contents and just slap a new hint on there and hey + // presto we have our table representation with no extra memory used! + $table = new Representation('Table'); + $table->contents = $o->value->contents; + $table->hints[] = 'table'; + $o->addRepresentation($table, 0); + } +} diff --git a/vendor/kint-php/kint/src/Parser/ThrowablePlugin.php b/vendor/kint-php/kint/src/Parser/ThrowablePlugin.php new file mode 100644 index 0000000..8490d1d --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ThrowablePlugin.php @@ -0,0 +1,60 @@ +transplant($o); + $r = new SourceRepresentation($var->getFile(), $var->getLine()); + $r->showfilename = true; + $throw->addRepresentation($r, 0); + + $o = $throw; + } +} diff --git a/vendor/kint-php/kint/src/Parser/TimestampPlugin.php b/vendor/kint-php/kint/src/Parser/TimestampPlugin.php new file mode 100644 index 0000000..72958d6 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/TimestampPlugin.php @@ -0,0 +1,71 @@ +value->label = 'Timestamp'; + $o->value->hints[] = 'timestamp'; + } + } +} diff --git a/vendor/kint-php/kint/src/Parser/ToStringPlugin.php b/vendor/kint-php/kint/src/Parser/ToStringPlugin.php new file mode 100644 index 0000000..8b7a65f --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/ToStringPlugin.php @@ -0,0 +1,67 @@ +hasMethod('__toString')) { + return; + } + + foreach (self::$blacklist as $class) { + if ($var instanceof $class) { + return; + } + } + + $r = new Representation('toString'); + $r->contents = (string) $var; + + $o->addRepresentation($r); + } +} diff --git a/vendor/kint-php/kint/src/Parser/TracePlugin.php b/vendor/kint-php/kint/src/Parser/TracePlugin.php new file mode 100644 index 0000000..3554993 --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/TracePlugin.php @@ -0,0 +1,92 @@ +value) { + return; + } + + $trace = $this->parser->getCleanArray($var); + + if (\count($trace) !== \count($o->value->contents) || !Utils::isTrace($trace)) { + return; + } + + $traceobj = new TraceObject(); + $traceobj->transplant($o); + $rep = $traceobj->value; + + $old_trace = $rep->contents; + + Utils::normalizeAliases(self::$blacklist); + + $rep->contents = array(); + + foreach ($old_trace as $frame) { + $index = $frame->name; + + if (!isset($trace[$index]['function'])) { + // Something's very very wrong here, but it's probably a plugin's fault + continue; + } + + if (Utils::traceFrameIsListed($trace[$index], self::$blacklist)) { + continue; + } + + $rep->contents[$index] = new TraceFrameObject($frame, $trace[$index]); + } + + \ksort($rep->contents); + $rep->contents = \array_values($rep->contents); + + $traceobj->clearRepresentations(); + $traceobj->addRepresentation($rep); + $traceobj->size = \count($rep->contents); + $o = $traceobj; + } +} diff --git a/vendor/kint-php/kint/src/Parser/XmlPlugin.php b/vendor/kint-php/kint/src/Parser/XmlPlugin.php new file mode 100644 index 0000000..0947e9a --- /dev/null +++ b/vendor/kint-php/kint/src/Parser/XmlPlugin.php @@ -0,0 +1,150 @@ +access_path); + + if (empty($xml)) { + return; + } + + list($xml, $access_path, $name) = $xml; + + $base_obj = new BasicObject(); + $base_obj->depth = $o->depth + 1; + $base_obj->name = $name; + $base_obj->access_path = $access_path; + + $r = new Representation('XML'); + $r->contents = $this->parser->parse($xml, $base_obj); + + $o->addRepresentation($r, 0); + } + + protected static function xmlToSimpleXML($var, $parent_path) + { + try { + $errors = \libxml_use_internal_errors(true); + $xml = \simplexml_load_string($var); + \libxml_use_internal_errors($errors); + } catch (Exception $e) { + if (isset($errors)) { + \libxml_use_internal_errors($errors); + } + + return; + } + + if (!$xml) { + return; + } + + if (null === $parent_path) { + $access_path = null; + } else { + $access_path = 'simplexml_load_string('.$parent_path.')'; + } + + $name = $xml->getName(); + + return array($xml, $access_path, $name); + } + + /** + * Get the DOMDocument info. + * + * The documentation of DOMDocument::loadXML() states that while you can + * call it statically, it will give an E_STRICT warning. On my system it + * actually gives an E_DEPRECATED warning, but it works so we'll just add + * an error-silencing '@' to the access path. + * + * If it errors loading then we wouldn't have gotten this far in the first place. + * + * @param string $var The XML string + * @param null|string $parent_path The path to the parent, in this case the XML string + * + * @return null|array The root element DOMNode, the access path, and the root element name + */ + protected static function xmlToDOMDocument($var, $parent_path) + { + // There's no way to check validity in DOMDocument without making errors. For shame! + if (!self::xmlToSimpleXML($var, $parent_path)) { + return null; + } + + $xml = new DOMDocument(); + $xml->loadXML($var); + $xml = $xml->firstChild; + + if (null === $parent_path) { + $access_path = null; + } else { + $access_path = '@\\DOMDocument::loadXML('.$parent_path.')->firstChild'; + } + + $name = $xml->nodeName; + + return array($xml, $access_path, $name); + } +} diff --git a/vendor/kint-php/kint/src/Renderer/CliRenderer.php b/vendor/kint-php/kint/src/Renderer/CliRenderer.php new file mode 100644 index 0000000..0d0846a --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/CliRenderer.php @@ -0,0 +1,152 @@ +windows_output = KINT_WIN; + } + + if (!self::$terminal_width) { + if (!KINT_WIN && self::$detect_width) { + self::$terminal_width = \exec('tput cols'); + } + + if (self::$terminal_width < self::$min_terminal_width) { + self::$terminal_width = self::$default_width; + } + } + + $this->colors = $this->windows_output ? false : self::$cli_colors; + + $this->header_width = self::$terminal_width; + } + + public function colorValue($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[32m".\str_replace("\n", "\x1b[0m\n\x1b[32m", $string)."\x1b[0m"; + } + + public function colorType($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[35;1m".\str_replace("\n", "\x1b[0m\n\x1b[35;1m", $string)."\x1b[0m"; + } + + public function colorTitle($string) + { + if (!$this->colors) { + return $string; + } + + return "\x1b[36m".\str_replace("\n", "\x1b[0m\n\x1b[36m", $string)."\x1b[0m"; + } + + public function renderTitle(BasicObject $o) + { + if ($this->windows_output) { + return $this->utf8ToWindows(parent::renderTitle($o)); + } + + return parent::renderTitle($o); + } + + public function preRender() + { + return PHP_EOL; + } + + public function postRender() + { + if ($this->windows_output) { + return $this->utf8ToWindows(parent::postRender()); + } + + return parent::postRender(); + } + + public function escape($string, $encoding = false) + { + return \str_replace("\x1b", '\\x1b', $string); + } + + protected function utf8ToWindows($string) + { + return \str_replace( + array('┌', 'â•', 'â”', '│', 'â””', '─', '┘'), + array("\xda", "\xdc", "\xbf", "\xb3", "\xc0", "\xc4", "\xd9"), + $string + ); + } +} diff --git a/vendor/kint-php/kint/src/Renderer/PlainRenderer.php b/vendor/kint-php/kint/src/Renderer/PlainRenderer.php new file mode 100644 index 0000000..493a774 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/PlainRenderer.php @@ -0,0 +1,237 @@ + array( + array('Kint\\Renderer\\PlainRenderer', 'renderJs'), + array('Kint\\Renderer\\Text\\MicrotimePlugin', 'renderJs'), + ), + 'style' => array( + array('Kint\\Renderer\\PlainRenderer', 'renderCss'), + ), + 'raw' => array(), + ); + + /** + * Path to the CSS file to load by default. + * + * @var string + */ + public static $theme = 'plain.css'; + + /** + * Output htmlentities instead of utf8. + * + * @var bool + */ + public static $disable_utf8 = false; + + public static $needs_pre_render = true; + + public static $always_pre_render = false; + + protected $force_pre_render = false; + protected $pre_render; + + public function __construct() + { + parent::__construct(); + + $this->pre_render = self::$needs_pre_render; + + if (self::$always_pre_render) { + $this->setPreRender(true); + } + } + + public function setCallInfo(array $info) + { + parent::setCallInfo($info); + + if (\in_array('@', $this->call_info['modifiers'], true)) { + $this->setPreRender(true); + } + } + + public function setStatics(array $statics) + { + parent::setStatics($statics); + + if (!empty($statics['return'])) { + $this->setPreRender(true); + } + } + + public function setPreRender($pre_render) + { + $this->pre_render = $pre_render; + $this->force_pre_render = true; + } + + public function getPreRender() + { + return $this->pre_render; + } + + public function colorValue($string) + { + return ''.$string.''; + } + + public function colorType($string) + { + return ''.$string.''; + } + + public function colorTitle($string) + { + return ''.$string.''; + } + + public function renderTitle(BasicObject $o) + { + if (self::$disable_utf8) { + return $this->utf8ToHtmlentity(parent::renderTitle($o)); + } + + return parent::renderTitle($o); + } + + public function preRender() + { + $output = ''; + + if ($this->pre_render) { + foreach (self::$pre_render_sources as $type => $values) { + $contents = ''; + foreach ($values as $v) { + $contents .= \call_user_func($v, $this); + } + + if (!\strlen($contents)) { + continue; + } + + switch ($type) { + case 'script': + $output .= ''; + break; + case 'style': + $output .= ''; + break; + default: + $output .= $contents; + } + } + + // Don't pre-render on every dump + if (!$this->force_pre_render) { + self::$needs_pre_render = false; + } + } + + return $output.'
'; + } + + public function postRender() + { + if (self::$disable_utf8) { + return $this->utf8ToHtmlentity(parent::postRender()).'
'; + } + + return parent::postRender().''; + } + + public function ideLink($file, $line) + { + $path = $this->escape(Kint::shortenPath($file)).':'.$line; + $ideLink = Kint::getIdeLink($file, $line); + + if (!$ideLink) { + return $path; + } + + $class = ''; + + if (\preg_match('/https?:\\/\\//i', $ideLink)) { + $class = 'class="kint-ide-link" '; + } + + return ''.$path.''; + } + + public function escape($string, $encoding = false) + { + if (false === $encoding) { + $encoding = BlobObject::detectEncoding($string); + } + + $original_encoding = $encoding; + + if (false === $encoding || 'ASCII' === $encoding) { + $encoding = 'UTF-8'; + } + + $string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding); + + // this call converts all non-ASCII characters into numeirc htmlentities + if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) { + $string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding); + } + + return $string; + } + + protected function utf8ToHtmlentity($string) + { + return \str_replace( + array('┌', 'â•', 'â”', '│', 'â””', '─', '┘'), + array('┌', '═', '┐', '│', '└', '─', '┘'), + $string + ); + } + + protected static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/plain.js'); + } + + protected static function renderCss() + { + if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { + return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); + } + + return \file_get_contents(self::$theme); + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Renderer.php b/vendor/kint-php/kint/src/Renderer/Renderer.php new file mode 100644 index 0000000..cf8b0a7 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Renderer.php @@ -0,0 +1,185 @@ +call_info = array( + 'params' => $info['params'], + 'modifiers' => $info['modifiers'], + 'callee' => $info['callee'], + 'caller' => $info['caller'], + 'trace' => $info['trace'], + ); + } + + public function getCallInfo() + { + return $this->call_info; + } + + public function setStatics(array $statics) + { + $this->statics = $statics; + $this->setShowTrace(!empty($statics['display_called_from'])); + } + + public function getStatics() + { + return $this->statics; + } + + public function setShowTrace($show_trace) + { + $this->show_trace = $show_trace; + } + + public function getShowTrace() + { + return $this->show_trace; + } + + /** + * Returns the first compatible plugin available. + * + * @param array $plugins Array of hints to class strings + * @param array $hints Array of object hints + * + * @return array Array of hints to class strings filtered and sorted by object hints + */ + public function matchPlugins(array $plugins, array $hints) + { + $out = array(); + + foreach ($hints as $key) { + if (isset($plugins[$key])) { + $out[$key] = $plugins[$key]; + } + } + + return $out; + } + + public function filterParserPlugins(array $plugins) + { + return $plugins; + } + + public function preRender() + { + return ''; + } + + public function postRender() + { + return ''; + } + + public static function sortPropertiesFull(BasicObject $a, BasicObject $b) + { + $sort = BasicObject::sortByAccess($a, $b); + if ($sort) { + return $sort; + } + + $sort = BasicObject::sortByName($a, $b); + if ($sort) { + return $sort; + } + + return InstanceObject::sortByHierarchy($a->owner_class, $b->owner_class); + } + + /** + * Sorts an array of BasicObject. + * + * @param BasicObject[] $contents Object properties to sort + * @param int $sort + * + * @return BasicObject[] + */ + public static function sortProperties(array $contents, $sort) + { + switch ($sort) { + case self::SORT_VISIBILITY: + /** @var array Containers to quickly stable sort by type */ + $containers = array( + BasicObject::ACCESS_PUBLIC => array(), + BasicObject::ACCESS_PROTECTED => array(), + BasicObject::ACCESS_PRIVATE => array(), + BasicObject::ACCESS_NONE => array(), + ); + + foreach ($contents as $item) { + $containers[$item->access][] = $item; + } + + return \call_user_func_array('array_merge', $containers); + case self::SORT_FULL: + \usort($contents, array('Kint\\Renderer\\Renderer', 'sortPropertiesFull')); + // no break + default: + return $contents; + } + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/BinaryPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/BinaryPlugin.php new file mode 100644 index 0000000..5b4d613 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/BinaryPlugin.php @@ -0,0 +1,51 @@ +'; + + $chunks = \str_split($r->contents, self::$line_length); + + foreach ($chunks as $index => $chunk) { + $out .= \sprintf('%08X', $index * self::$line_length).":\t"; + $out .= \implode(' ', \str_split(\str_pad(\bin2hex($chunk), 2 * self::$line_length, ' '), self::$chunk_length)); + $out .= "\t".\preg_replace('/[^\\x20-\\x7E]/', '.', $chunk)."\n"; + } + + $out .= ''; + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/BlacklistPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/BlacklistPlugin.php new file mode 100644 index 0000000..fcfedc1 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/BlacklistPlugin.php @@ -0,0 +1,36 @@ +'.$this->renderLockedHeader($o, 'Blacklisted').''; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/CallablePlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/CallablePlugin.php new file mode 100644 index 0000000..5834017 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/CallablePlugin.php @@ -0,0 +1,174 @@ +renderMethod($o); + } + + if ($o instanceof ClosureObject) { + return $this->renderClosure($o); + } + + return $this->renderCallable($o); + } + + protected function renderClosure(ClosureObject $o) + { + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')'; + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; + } + + protected function renderCallable(BasicObject $o) + { + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).''; + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + return '
'.$this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header).$children.'
'; + } + + protected function renderMethod(MethodObject $o) + { + if (!empty(self::$method_cache[$o->owner_class][$o->name])) { + $children = self::$method_cache[$o->owner_class][$o->name]['children']; + + $header = $this->renderer->renderHeaderWrapper( + $o, + (bool) \strlen($children), + self::$method_cache[$o->owner_class][$o->name]['header'] + ); + + return '
'.$header.$children.'
'; + } + + $children = $this->renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers()) || $o->return_reference) { + $header .= ''.$s; + + if ($o->return_reference) { + if ($s) { + $header .= ' '; + } + $header .= $this->renderer->escape('&'); + } + + $header .= ' '; + } + + if (null !== ($s = $o->getName())) { + $function = $this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).')'; + + if (null !== ($url = $o->getPhpDocUrl())) { + $function = ''.$function.''; + } + + $header .= ''.$function.''; + } + + if (!empty($o->returntype)) { + $header .= ': '; + + if ($o->return_reference) { + $header .= $this->renderer->escape('&'); + } + + $header .= $this->renderer->escape($o->returntype).''; + } elseif ($o->docstring) { + if (\preg_match('/@return\\s+(.*)\\r?\\n/m', $o->docstring, $matches)) { + if (\trim($matches[1])) { + $header .= ': '.$this->renderer->escape(\trim($matches[1])).''; + } + } + } + + if (null !== ($s = $o->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= ' '.$this->renderer->escape($s); + } + + if (\strlen($o->owner_class) && \strlen($o->name)) { + self::$method_cache[$o->owner_class][$o->name] = array( + 'header' => $header, + 'children' => $children, + ); + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/ClosurePlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/ClosurePlugin.php new file mode 100644 index 0000000..79a9926 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/ClosurePlugin.php @@ -0,0 +1,59 @@ +renderer->renderChildren($o); + + if (!($o instanceof ClosureObject)) { + $header = $this->renderer->renderHeader($o); + } else { + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).'('.$this->renderer->escape($o->getParams()).') '; + } + + $header .= 'Closure '; + $header .= $this->renderer->escape(Kint::shortenPath($o->filename)).':'.(int) $o->startline; + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/ColorPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/ColorPlugin.php new file mode 100644 index 0000000..241a815 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/ColorPlugin.php @@ -0,0 +1,100 @@ +getRepresentation('color'); + + if (!$r instanceof ColorRepresentation) { + return; + } + + $children = $this->renderer->renderChildren($o); + + $header = $this->renderer->renderHeader($o); + $header .= '
'; + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } + + public function renderTab(Representation $r) + { + if (!$r instanceof ColorRepresentation) { + return; + } + + $out = ''; + + if ($color = $r->getColor(ColorRepresentation::COLOR_NAME)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_3)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_6)) { + $out .= ''.$color."\n"; + } + + if ($r->hasAlpha()) { + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_4)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HEX_8)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_RGBA)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HSLA)) { + $out .= ''.$color."\n"; + } + } else { + if ($color = $r->getColor(ColorRepresentation::COLOR_RGB)) { + $out .= ''.$color."\n"; + } + if ($color = $r->getColor(ColorRepresentation::COLOR_HSL)) { + $out .= ''.$color."\n"; + } + } + + if (!\strlen($out)) { + return false; + } + + return '
'.$out.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/DepthLimitPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/DepthLimitPlugin.php new file mode 100644 index 0000000..cd92b41 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/DepthLimitPlugin.php @@ -0,0 +1,36 @@ +'.$this->renderLockedHeader($o, 'Depth Limit').''; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/DocstringPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/DocstringPlugin.php new file mode 100644 index 0000000..19c5309 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/DocstringPlugin.php @@ -0,0 +1,70 @@ +contents) as $line) { + $docstring[] = \trim($line); + } + + $docstring = \implode("\n", $docstring); + + $location = array(); + + if ($r->class) { + $location[] = 'Inherited from '.$this->renderer->escape($r->class); + } + if ($r->file && $r->line) { + $location[] = 'Defined in '.$this->renderer->escape(Kint::shortenPath($r->file)).':'.((int) $r->line); + } + + $location = \implode("\n", $location); + + if ($location) { + if (\strlen($docstring)) { + $docstring .= "\n\n"; + } + + $location = ''.$location.''; + } elseif (0 === \strlen($docstring)) { + return ''; + } + + return '
'.$this->renderer->escape($docstring).$location.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/MicrotimePlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/MicrotimePlugin.php new file mode 100644 index 0000000..a56bb23 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/MicrotimePlugin.php @@ -0,0 +1,68 @@ +getDateTime()->format('Y-m-d H:i:s.u'); + if (null !== $r->lap) { + $out .= '
SINCE LAST CALL: '.\round($r->lap, 4).'s.'; + } + if (null !== $r->total) { + $out .= '
SINCE START: '.\round($r->total, 4).'s.'; + } + if (null !== $r->avg) { + $out .= '
AVERAGE DURATION: '.\round($r->avg, 4).'s.'; + } + + $bytes = Utils::getHumanReadableBytes($r->mem); + $out .= '
MEMORY USAGE: '.$r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_real); + $out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $bytes = Utils::getHumanReadableBytes($r->mem_peak); + $out .= '
PEAK MEMORY USAGE: '.$r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_peak_real); + $out .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + return '
'.$out.'
'; + } + + public static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/microtime.js'); + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/ObjectPluginInterface.php b/vendor/kint-php/kint/src/Renderer/Rich/ObjectPluginInterface.php new file mode 100644 index 0000000..f46aa29 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/ObjectPluginInterface.php @@ -0,0 +1,33 @@ +renderer = $r; + } + + /** + * Renders a locked header. + * + * @param BasicObject $o + * @param string $content + */ + public function renderLockedHeader(BasicObject $o, $content) + { + $header = '
'; + + if (RichRenderer::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) { + $header .= ''; + } + + $header .= ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).' '; + + if ($s = $o->getOperator()) { + $header .= $this->renderer->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + $s = $this->renderer->escape($s); + + if ($o->reference) { + $s = '&'.$s; + } + + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getSize())) { + $header .= '('.$this->renderer->escape($s).') '; + } + + $header .= $content; + + if (!empty($ap)) { + $header .= '
'.$this->renderer->escape($ap).'
'; + } + + return $header.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/PluginInterface.php b/vendor/kint-php/kint/src/Renderer/Rich/PluginInterface.php new file mode 100644 index 0000000..79828e7 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/PluginInterface.php @@ -0,0 +1,33 @@ +'.$this->renderLockedHeader($o, 'Recursion').''; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/SimpleXMLElementPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/SimpleXMLElementPlugin.php new file mode 100644 index 0000000..6c18931 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/SimpleXMLElementPlugin.php @@ -0,0 +1,81 @@ +renderer->renderChildren($o); + + $header = ''; + + if (null !== ($s = $o->getModifiers())) { + $header .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $header .= ''.$this->renderer->escape($s).' '; + + if ($s = $o->getOperator()) { + $header .= $this->renderer->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + $s = $this->renderer->escape($s); + + if ($o->reference) { + $s = '&'.$s; + } + + $header .= ''.$this->renderer->escape($s).' '; + } + + if (null !== ($s = $o->getSize())) { + $header .= '('.$this->renderer->escape($s).') '; + } + + if (null === $s && $c = $o->getRepresentation('contents')) { + $c = \reset($c->contents); + + if ($c && null !== ($s = $c->getValueShort())) { + if (RichRenderer::$strlen_max && BlobObject::strlen($s) > RichRenderer::$strlen_max) { + $s = \substr($s, 0, RichRenderer::$strlen_max).'...'; + } + $header .= $this->renderer->escape($s); + } + } + + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/SourcePlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/SourcePlugin.php new file mode 100644 index 0000000..5443dbf --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/SourcePlugin.php @@ -0,0 +1,79 @@ +source)) { + return false; + } + + $source = $r->source; + + // Trim empty lines from the start and end of the source + foreach ($source as $linenum => $line) { + if (\strlen(\trim($line)) || $linenum === $r->line) { + break; + } + + unset($source[$linenum]); + } + + foreach (\array_reverse($source, true) as $linenum => $line) { + if (\strlen(\trim($line)) || $linenum === $r->line) { + break; + } + + unset($source[$linenum]); + } + + $output = ''; + + foreach ($source as $linenum => $line) { + if ($linenum === $r->line) { + $output .= '
'.$this->renderer->escape($line)."\n".'
'; + } else { + $output .= '
'.$this->renderer->escape($line)."\n".'
'; + } + } + + if ($output) { + \reset($source); + + $data = ''; + if ($r->showfilename) { + $data = ' data-kint-filename="'.$this->renderer->escape($r->filename).'"'; + } + + return '
'.$output.'
'; + } + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/TabPluginInterface.php b/vendor/kint-php/kint/src/Renderer/Rich/TabPluginInterface.php new file mode 100644 index 0000000..7cdbde7 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/TabPluginInterface.php @@ -0,0 +1,33 @@ +'; + + $firstrow = \reset($r->contents); + + foreach ($firstrow->value->contents as $field) { + $out .= ''; + } + + $out .= ''; + + foreach ($r->contents as $row) { + $out .= ''; + + foreach ($row->value->contents as $field) { + $out .= 'getType())) { + $type = $this->renderer->escape($s); + + if ($field->reference) { + $ref = '&'; + $type = $ref.$type; + } + + if (null !== ($s = $field->getSize())) { + $size .= ' ('.$this->renderer->escape($s).')'; + } + } + + if ($type) { + $out .= ' title="'.$type.$size.'"'; + } + + $out .= '>'; + + switch ($field->type) { + case 'boolean': + $out .= $field->value->contents ? ''.$ref.'true' : ''.$ref.'false'; + break; + case 'integer': + case 'double': + $out .= (string) $field->value->contents; + break; + case 'null': + $out .= ''.$ref.'null'; + break; + case 'string': + if ($field->encoding) { + $val = $field->value->contents; + if (RichRenderer::$strlen_max && self::$respect_str_length && BlobObject::strlen($val) > RichRenderer::$strlen_max) { + $val = \substr($val, 0, RichRenderer::$strlen_max).'...'; + } + + $out .= $this->renderer->escape($val); + } else { + $out .= ''.$type.''; + } + break; + case 'array': + $out .= ''.$ref.'array'.$size; + break; + case 'object': + $out .= ''.$ref.$this->renderer->escape($field->classname).''.$size; + break; + case 'resource': + $out .= ''.$ref.'resource'; + break; + default: + $out .= ''.$ref.'unknown'; + break; + } + + if (\in_array('blacklist', $field->hints, true)) { + $out .= ' Blacklisted'; + } elseif (\in_array('recursion', $field->hints, true)) { + $out .= ' Recursion'; + } elseif (\in_array('depth_limit', $field->hints, true)) { + $out .= ' Depth Limit'; + } + + $out .= ''; + } + + $out .= ''; + } + + $out .= '
'.$this->renderer->escape($field->name).'
'; + $out .= $this->renderer->escape($row->name); + $out .= '
'; + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/TimestampPlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/TimestampPlugin.php new file mode 100644 index 0000000..6e3a2f8 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/TimestampPlugin.php @@ -0,0 +1,42 @@ +contents); + + if ($dt) { + return '
'.$dt->setTimeZone(new DateTimeZone('UTC'))->format('Y-m-d H:i:s T').'
'; + } + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Rich/TraceFramePlugin.php b/vendor/kint-php/kint/src/Renderer/Rich/TraceFramePlugin.php new file mode 100644 index 0000000..6ca19bb --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Rich/TraceFramePlugin.php @@ -0,0 +1,68 @@ +trace['file']) && !empty($o->trace['line'])) { + $header = ''.$this->renderer->ideLink($o->trace['file'], (int) $o->trace['line']).' '; + } else { + $header = 'PHP internal call '; + } + + if ($o->trace['class']) { + $header .= $this->renderer->escape($o->trace['class'].$o->trace['type']); + } + + if (\is_string($o->trace['function'])) { + $function = $this->renderer->escape($o->trace['function'].'()'); + } else { + $function = $this->renderer->escape( + $o->trace['function']->getName().'('.$o->trace['function']->getParams().')' + ); + + if (null !== ($url = $o->trace['function']->getPhpDocUrl())) { + $function = ''.$function.''; + } + } + + $header .= ''.$function.''; + + $children = $this->renderer->renderChildren($o); + $header = $this->renderer->renderHeaderWrapper($o, (bool) \strlen($children), $header); + + return '
'.$header.$children.'
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/RichRenderer.php b/vendor/kint-php/kint/src/Renderer/RichRenderer.php new file mode 100644 index 0000000..dcd39ee --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/RichRenderer.php @@ -0,0 +1,612 @@ + 'Kint\\Renderer\\Rich\\BlacklistPlugin', + 'callable' => 'Kint\\Renderer\\Rich\\CallablePlugin', + 'closure' => 'Kint\\Renderer\\Rich\\ClosurePlugin', + 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', + 'depth_limit' => 'Kint\\Renderer\\Rich\\DepthLimitPlugin', + 'recursion' => 'Kint\\Renderer\\Rich\\RecursionPlugin', + 'simplexml_element' => 'Kint\\Renderer\\Rich\\SimpleXMLElementPlugin', + 'trace_frame' => 'Kint\\Renderer\\Rich\\TraceFramePlugin', + ); + + /** + * RichRenderer tab plugins should implement Kint\Renderer\Rich\TabPluginInterface. + */ + public static $tab_plugins = array( + 'binary' => 'Kint\\Renderer\\Rich\\BinaryPlugin', + 'color' => 'Kint\\Renderer\\Rich\\ColorPlugin', + 'docstring' => 'Kint\\Renderer\\Rich\\DocstringPlugin', + 'microtime' => 'Kint\\Renderer\\Rich\\MicrotimePlugin', + 'source' => 'Kint\\Renderer\\Rich\\SourcePlugin', + 'table' => 'Kint\\Renderer\\Rich\\TablePlugin', + 'timestamp' => 'Kint\\Renderer\\Rich\\TimestampPlugin', + ); + + public static $pre_render_sources = array( + 'script' => array( + array('Kint\\Renderer\\RichRenderer', 'renderJs'), + array('Kint\\Renderer\\Rich\\MicrotimePlugin', 'renderJs'), + ), + 'style' => array( + array('Kint\\Renderer\\RichRenderer', 'renderCss'), + ), + 'raw' => array(), + ); + + /** + * Whether or not to render access paths. + * + * Access paths can become incredibly heavy with very deep and wide + * structures. Given mostly public variables it will typically make + * up one quarter of the output HTML size. + * + * If this is an unacceptably large amount and your browser is groaning + * under the weight of the access paths - your first order of buisiness + * should be to get a new browser. Failing that, use this to turn them off. + * + * @var bool + */ + public static $access_paths = true; + + /** + * The maximum length of a string before it is truncated. + * + * Falsey to disable + * + * @var int + */ + public static $strlen_max = 80; + + /** + * Path to the CSS file to load by default. + * + * @var string + */ + public static $theme = 'original.css'; + + /** + * Assume types and sizes don't need to be escaped. + * + * Turn this off if you use anything but ascii in your class names, + * but it'll cause a slowdown of around 10% + * + * @var bool + */ + public static $escape_types = false; + + /** + * Move all dumps to a folder at the bottom of the body. + * + * @var bool + */ + public static $folder = true; + + /** + * Sort mode for object properties. + * + * @var int + */ + public static $sort = self::SORT_NONE; + + public static $needs_pre_render = true; + public static $needs_folder_render = true; + + public static $always_pre_render = false; + + protected $plugin_objs = array(); + protected $expand = false; + protected $force_pre_render = false; + protected $pre_render; + protected $use_folder; + + public function __construct() + { + $this->pre_render = self::$needs_pre_render; + $this->use_folder = self::$folder; + + if (self::$always_pre_render) { + $this->setForcePreRender(); + } + } + + public function setCallInfo(array $info) + { + parent::setCallInfo($info); + + if (\in_array('!', $this->call_info['modifiers'], true)) { + $this->setExpand(true); + $this->use_folder = false; + } + + if (\in_array('@', $this->call_info['modifiers'], true)) { + $this->setForcePreRender(); + } + } + + public function setStatics(array $statics) + { + parent::setStatics($statics); + + if (!empty($statics['expanded'])) { + $this->setExpand(true); + } + + if (!empty($statics['return'])) { + $this->setForcePreRender(); + } + } + + public function setExpand($expand) + { + $this->expand = $expand; + } + + public function getExpand() + { + return $this->expand; + } + + public function setForcePreRender() + { + $this->force_pre_render = true; + $this->pre_render = true; + } + + public function setPreRender($pre_render) + { + $this->setForcePreRender(); // TODO: Remove line in next major version + $this->pre_render = $pre_render; + } + + public function getPreRender() + { + return $this->pre_render; + } + + public function setUseFolder($use_folder) + { + $this->use_folder = $use_folder; + } + + public function getUseFolder() + { + return $this->use_folder; + } + + public function render(BasicObject $o) + { + if ($plugin = $this->getPlugin(self::$object_plugins, $o->hints)) { + if (\strlen($output = $plugin->renderObject($o))) { + return $output; + } + } + + $children = $this->renderChildren($o); + $header = $this->renderHeaderWrapper($o, (bool) \strlen($children), $this->renderHeader($o)); + + return '
'.$header.$children.'
'; + } + + public function renderNothing() + { + return '
No argument
'; + } + + public function renderHeaderWrapper(BasicObject $o, $has_children, $contents) + { + $out = 'expand) { + $out .= ' kint-show'; + } + + $out .= '"'; + } + + $out .= '>'; + + if (self::$access_paths && $o->depth > 0 && $ap = $o->getAccessPath()) { + $out .= ''; + } + + if ($has_children) { + $out .= ''; + + if (0 === $o->depth) { + $out .= ''; + $out .= ''; + } + + $out .= ''; + } + + $out .= $contents; + + if (!empty($ap)) { + $out .= '
'.$this->escape($ap).'
'; + } + + return $out.''; + } + + public function renderHeader(BasicObject $o) + { + $output = ''; + + if (null !== ($s = $o->getModifiers())) { + $output .= ''.$s.' '; + } + + if (null !== ($s = $o->getName())) { + $output .= ''.$this->escape($s).' '; + + if ($s = $o->getOperator()) { + $output .= $this->escape($s, 'ASCII').' '; + } + } + + if (null !== ($s = $o->getType())) { + if (self::$escape_types) { + $s = $this->escape($s); + } + + if ($o->reference) { + $s = '&'.$s; + } + + $output .= ''.$s.' '; + } + + if (null !== ($s = $o->getSize())) { + if (self::$escape_types) { + $s = $this->escape($s); + } + $output .= '('.$s.') '; + } + + if (null !== ($s = $o->getValueShort())) { + $s = \preg_replace('/\\s+/', ' ', $s); + + if (self::$strlen_max) { + $s = Utils::truncateString($s, self::$strlen_max); + } + + $output .= $this->escape($s); + } + + return \trim($output); + } + + public function renderChildren(BasicObject $o) + { + $contents = array(); + $tabs = array(); + + foreach ($o->getRepresentations() as $rep) { + $result = $this->renderTab($o, $rep); + if (\strlen($result)) { + $contents[] = $result; + $tabs[] = $rep; + } + } + + if (empty($tabs)) { + return ''; + } + + $output = '
'; + + if (1 === \count($tabs) && $tabs[0]->labelIsImplicit()) { + $output .= \reset($contents); + } else { + $output .= '
    '; + + foreach ($tabs as $i => $tab) { + if (0 === $i) { + $output .= '
  • '; + } else { + $output .= '
  • '; + } + + $output .= $this->escape($tab->getLabel()).'
  • '; + } + + $output .= '
    '; + + foreach ($contents as $tab) { + $output .= '
  • '.$tab.'
  • '; + } + + $output .= '
'; + } + + return $output.'
'; + } + + public function preRender() + { + $output = ''; + + if ($this->pre_render) { + foreach (self::$pre_render_sources as $type => $values) { + $contents = ''; + foreach ($values as $v) { + $contents .= \call_user_func($v, $this); + } + + if (!\strlen($contents)) { + continue; + } + + switch ($type) { + case 'script': + $output .= ''; + break; + case 'style': + $output .= ''; + break; + default: + $output .= $contents; + } + } + + // Don't pre-render on every dump + if (!$this->force_pre_render) { + self::$needs_pre_render = false; + } + } + + $output .= '
'; + + return $output; + } + + public function postRender() + { + if (!$this->show_trace) { + return '
'; + } + + $output = '
'; + $output .= ' '; + + if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) { + $output .= ''; + } + + if (isset($this->call_info['callee']['file'])) { + $output .= 'Called from '.$this->ideLink( + $this->call_info['callee']['file'], + $this->call_info['callee']['line'] + ); + } + + if (isset($this->call_info['callee']['function']) && ( + !empty($this->call_info['callee']['class']) || + !\in_array( + $this->call_info['callee']['function'], + array('include', 'include_once', 'require', 'require_once'), + true + ) + ) + ) { + $output .= ' ['; + if (isset($this->call_info['callee']['class'])) { + $output .= $this->call_info['callee']['class']; + } + if (isset($this->call_info['callee']['type'])) { + $output .= $this->call_info['callee']['type']; + } + $output .= $this->call_info['callee']['function'].'()]'; + } + + if (!empty($this->call_info['trace']) && \count($this->call_info['trace']) > 1) { + $output .= '
    '; + foreach ($this->call_info['trace'] as $index => $step) { + if (!$index) { + continue; + } + + $output .= '
  1. '.$this->ideLink($step['file'], $step['line']); // closing tag not required + if (isset($step['function']) + && !\in_array($step['function'], array('include', 'include_once', 'require', 'require_once'), true) + ) { + $output .= ' ['; + if (isset($step['class'])) { + $output .= $step['class']; + } + if (isset($step['type'])) { + $output .= $step['type']; + } + $output .= $step['function'].'()]'; + } + } + $output .= '
'; + } + + $output .= '
'; + + return $output; + } + + public function escape($string, $encoding = false) + { + if (false === $encoding) { + $encoding = BlobObject::detectEncoding($string); + } + + $original_encoding = $encoding; + + if (false === $encoding || 'ASCII' === $encoding) { + $encoding = 'UTF-8'; + } + + $string = \htmlspecialchars($string, ENT_NOQUOTES, $encoding); + + // this call converts all non-ASCII characters into numeirc htmlentities + if (\function_exists('mb_encode_numericentity') && 'ASCII' !== $original_encoding) { + $string = \mb_encode_numericentity($string, array(0x80, 0xffff, 0, 0xffff), $encoding); + } + + return $string; + } + + public function ideLink($file, $line) + { + $path = $this->escape(Kint::shortenPath($file)).':'.$line; + $ideLink = Kint::getIdeLink($file, $line); + + if (!$ideLink) { + return $path; + } + + $class = ''; + + if (\preg_match('/https?:\\/\\//i', $ideLink)) { + $class = 'class="kint-ide-link" '; + } + + return ''.$path.''; + } + + protected function renderTab(BasicObject $o, Representation $rep) + { + if ($plugin = $this->getPlugin(self::$tab_plugins, $rep->hints)) { + if (\strlen($output = $plugin->renderTab($rep))) { + return $output; + } + } + + if (\is_array($rep->contents)) { + $output = ''; + + if ($o instanceof InstanceObject && 'properties' === $rep->getName()) { + foreach (self::sortProperties($rep->contents, self::$sort) as $obj) { + $output .= $this->render($obj); + } + } else { + foreach ($rep->contents as $obj) { + $output .= $this->render($obj); + } + } + + return $output; + } + + if (\is_string($rep->contents)) { + $show_contents = false; + + // If it is the value representation of a string and its whitespace + // was truncated in the header, always display the full string + if ('string' !== $o->type || $o->value !== $rep) { + $show_contents = true; + } else { + if (\preg_match('/(:?[\\r\\n\\t\\f\\v]| {2})/', $rep->contents)) { + $show_contents = true; + } elseif (self::$strlen_max && BlobObject::strlen($o->getValueShort()) > self::$strlen_max) { + $show_contents = true; + } + + if (empty($o->encoding)) { + $show_contents = false; + } + } + + if ($show_contents) { + return '
'.$this->escape($rep->contents)."\n
"; + } + } + + if ($rep->contents instanceof BasicObject) { + return $this->render($rep->contents); + } + } + + protected function getPlugin(array $plugins, array $hints) + { + if ($plugins = $this->matchPlugins($plugins, $hints)) { + $plugin = \end($plugins); + + if (!isset($this->plugin_objs[$plugin])) { + $this->plugin_objs[$plugin] = new $plugin($this); + } + + return $this->plugin_objs[$plugin]; + } + } + + protected static function renderJs() + { + return \file_get_contents(KINT_DIR.'/resources/compiled/shared.js').\file_get_contents(KINT_DIR.'/resources/compiled/rich.js'); + } + + protected static function renderCss() + { + if (\file_exists(KINT_DIR.'/resources/compiled/'.self::$theme)) { + return \file_get_contents(KINT_DIR.'/resources/compiled/'.self::$theme); + } + + return \file_get_contents(self::$theme); + } + + protected static function renderFolder() + { + return '
Kint
'; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/BlacklistPlugin.php b/vendor/kint-php/kint/src/Renderer/Text/BlacklistPlugin.php new file mode 100644 index 0000000..127d32a --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/BlacklistPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('BLACKLISTED').PHP_EOL; + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/DepthLimitPlugin.php b/vendor/kint-php/kint/src/Renderer/Text/DepthLimitPlugin.php new file mode 100644 index 0000000..310b87e --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/DepthLimitPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('DEPTH LIMIT').PHP_EOL; + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/MicrotimePlugin.php b/vendor/kint-php/kint/src/Renderer/Text/MicrotimePlugin.php new file mode 100644 index 0000000..9128032 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/MicrotimePlugin.php @@ -0,0 +1,128 @@ +renderer instanceof PlainRenderer) { + $this->useJs = true; + } + } + + public function render(BasicObject $o) + { + $r = $o->getRepresentation('microtime'); + + if (!$r instanceof MicrotimeRepresentation) { + return false; + } + + $out = ''; + + if (0 == $o->depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o); + $out .= $this->renderer->renderChildren($o).PHP_EOL; + + $indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width); + + if ($this->useJs) { + $out .= ''; + } + + $out .= $indent.$this->renderer->colorType('TIME:').' '; + $out .= $this->renderer->colorValue($r->getDateTime()->format('Y-m-d H:i:s.u')).PHP_EOL; + + if (null !== $r->lap) { + $out .= $indent.$this->renderer->colorType('SINCE LAST CALL:').' '; + + $lap = \round($r->lap, 4); + + if ($this->useJs) { + $lap = ''.$lap.''; + } + + $out .= $this->renderer->colorValue($lap.'s').'.'.PHP_EOL; + } + if (null !== $r->total) { + $out .= $indent.$this->renderer->colorType('SINCE START:').' '; + $out .= $this->renderer->colorValue(\round($r->total, 4).'s').'.'.PHP_EOL; + } + if (null !== $r->avg) { + $out .= $indent.$this->renderer->colorType('AVERAGE DURATION:').' '; + + $avg = \round($r->avg, 4); + + if ($this->useJs) { + $avg = ''.$avg.''; + } + + $out .= $this->renderer->colorValue($avg.'s').'.'.PHP_EOL; + } + + $bytes = Utils::getHumanReadableBytes($r->mem); + $mem = $r->mem.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_real); + $mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $out .= $indent.$this->renderer->colorType('MEMORY USAGE:').' '; + $out .= $this->renderer->colorValue($mem).'.'.PHP_EOL; + + $bytes = Utils::getHumanReadableBytes($r->mem_peak); + $mem = $r->mem_peak.' bytes ('.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + $bytes = Utils::getHumanReadableBytes($r->mem_peak_real); + $mem .= ' (real '.\round($bytes['value'], 3).' '.$bytes['unit'].')'; + + $out .= $indent.$this->renderer->colorType('PEAK MEMORY USAGE:').' '; + $out .= $this->renderer->colorValue($mem).'.'.PHP_EOL; + + if ($this->useJs) { + $out .= ''; + } + + return $out; + } + + public static function renderJs() + { + return RichPlugin::renderJs(); + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/Plugin.php b/vendor/kint-php/kint/src/Renderer/Text/Plugin.php new file mode 100644 index 0000000..9de25c1 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/Plugin.php @@ -0,0 +1,41 @@ +renderer = $r; + } + + abstract public function render(BasicObject $o); +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/RecursionPlugin.php b/vendor/kint-php/kint/src/Renderer/Text/RecursionPlugin.php new file mode 100644 index 0000000..72c2257 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/RecursionPlugin.php @@ -0,0 +1,44 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).' '.$this->renderer->colorValue('RECURSION').PHP_EOL; + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/Text/TracePlugin.php b/vendor/kint-php/kint/src/Renderer/Text/TracePlugin.php new file mode 100644 index 0000000..5833840 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/Text/TracePlugin.php @@ -0,0 +1,111 @@ +depth) { + $out .= $this->renderer->colorTitle($this->renderer->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderer->renderHeader($o).':'.PHP_EOL; + + $indent = \str_repeat(' ', ($o->depth + 1) * $this->renderer->indent_width); + + $i = 1; + foreach ($o->value->contents as $frame) { + $framedesc = $indent.\str_pad($i.': ', 4, ' '); + + if ($frame->trace['file']) { + $framedesc .= $this->renderer->ideLink($frame->trace['file'], $frame->trace['line']).PHP_EOL; + } else { + $framedesc .= 'PHP internal call'.PHP_EOL; + } + + $framedesc .= $indent.' '; + + if ($frame->trace['class']) { + $framedesc .= $this->renderer->escape($frame->trace['class']); + + if ($frame->trace['object']) { + $framedesc .= $this->renderer->escape('->'); + } else { + $framedesc .= '::'; + } + } + + if (\is_string($frame->trace['function'])) { + $framedesc .= $this->renderer->escape($frame->trace['function']).'(...)'; + } elseif ($frame->trace['function'] instanceof MethodObject) { + $framedesc .= $this->renderer->escape($frame->trace['function']->getName()); + $framedesc .= '('.$this->renderer->escape($frame->trace['function']->getParams()).')'; + } + + $out .= $this->renderer->colorType($framedesc).PHP_EOL.PHP_EOL; + + if ($source = $frame->getRepresentation('source')) { + $line_wanted = $source->line; + $source = $source->source; + + // Trim empty lines from the start and end of the source + foreach ($source as $linenum => $line) { + if (\trim($line) || $linenum === $line_wanted) { + break; + } + + unset($source[$linenum]); + } + + foreach (\array_reverse($source, true) as $linenum => $line) { + if (\trim($line) || $linenum === $line_wanted) { + break; + } + + unset($source[$linenum]); + } + + foreach ($source as $lineno => $line) { + if ($lineno == $line_wanted) { + $out .= $indent.$this->renderer->colorValue($this->renderer->escape($line)).PHP_EOL; + } else { + $out .= $indent.$this->renderer->escape($line).PHP_EOL; + } + } + } + + ++$i; + } + + return $out; + } +} diff --git a/vendor/kint-php/kint/src/Renderer/TextRenderer.php b/vendor/kint-php/kint/src/Renderer/TextRenderer.php new file mode 100644 index 0000000..43b6c40 --- /dev/null +++ b/vendor/kint-php/kint/src/Renderer/TextRenderer.php @@ -0,0 +1,346 @@ + 'Kint\\Renderer\\Text\\BlacklistPlugin', + 'depth_limit' => 'Kint\\Renderer\\Text\\DepthLimitPlugin', + 'microtime' => 'Kint\\Renderer\\Text\\MicrotimePlugin', + 'recursion' => 'Kint\\Renderer\\Text\\RecursionPlugin', + 'trace' => 'Kint\\Renderer\\Text\\TracePlugin', + ); + + /** + * Parser plugins must be instanceof one of these or + * it will be removed for performance reasons. + */ + public static $parser_plugin_whitelist = array( + 'Kint\\Parser\\BlacklistPlugin', + 'Kint\\Parser\\MicrotimePlugin', + 'Kint\\Parser\\StreamPlugin', + 'Kint\\Parser\\TracePlugin', + ); + + /** + * The maximum length of a string before it is truncated. + * + * Falsey to disable + * + * @var int + */ + public static $strlen_max = 0; + + /** + * The default width of the terminal for headers. + * + * @var int + */ + public static $default_width = 80; + + /** + * Indentation width. + * + * @var int + */ + public static $default_indent = 4; + + /** + * Decorate the header and footer. + * + * @var bool + */ + public static $decorations = true; + + /** + * Sort mode for object properties. + * + * @var int + */ + public static $sort = self::SORT_NONE; + + public $header_width = 80; + public $indent_width = 4; + + protected $plugin_objs = array(); + + public function __construct() + { + $this->header_width = self::$default_width; + $this->indent_width = self::$default_indent; + } + + public function render(BasicObject $o) + { + if ($plugin = $this->getPlugin(self::$plugins, $o->hints)) { + if (\strlen($output = $plugin->render($o))) { + return $output; + } + } + + $out = ''; + + if (0 == $o->depth) { + $out .= $this->colorTitle($this->renderTitle($o)).PHP_EOL; + } + + $out .= $this->renderHeader($o); + $out .= $this->renderChildren($o).PHP_EOL; + + return $out; + } + + public function renderNothing() + { + if (self::$decorations) { + return $this->colorTitle( + $this->boxText('No argument', $this->header_width) + ).PHP_EOL; + } + + return $this->colorTitle('No argument').PHP_EOL; + } + + public function boxText($text, $width) + { + $out = '┌'.\str_repeat('─', $width - 2).'â”'.PHP_EOL; + + if (\strlen($text)) { + $text = Utils::truncateString($text, $width - 4); + $text = \str_pad($text, $width - 4); + + $out .= '│ '.$this->escape($text).' │'.PHP_EOL; + } + + $out .= 'â””'.\str_repeat('─', $width - 2).'┘'; + + return $out; + } + + public function renderTitle(BasicObject $o) + { + $name = (string) $o->getName(); + + if (self::$decorations) { + return $this->boxText($name, $this->header_width); + } + + return Utils::truncateString($name, $this->header_width); + } + + public function renderHeader(BasicObject $o) + { + $output = array(); + + if ($o->depth) { + if (null !== ($s = $o->getModifiers())) { + $output[] = $s; + } + + if (null !== $o->name) { + $output[] = $this->escape(\var_export($o->name, true)); + + if (null !== ($s = $o->getOperator())) { + $output[] = $this->escape($s); + } + } + } + + if (null !== ($s = $o->getType())) { + if ($o->reference) { + $s = '&'.$s; + } + + $output[] = $this->colorType($this->escape($s)); + } + + if (null !== ($s = $o->getSize())) { + $output[] = '('.$this->escape($s).')'; + } + + if (null !== ($s = $o->getValueShort())) { + if (self::$strlen_max) { + $s = Utils::truncateString($s, self::$strlen_max); + } + $output[] = $this->colorValue($this->escape($s)); + } + + return \str_repeat(' ', $o->depth * $this->indent_width).\implode(' ', $output); + } + + public function renderChildren(BasicObject $o) + { + if ('array' === $o->type) { + $output = ' ['; + } elseif ('object' === $o->type) { + $output = ' ('; + } else { + return ''; + } + + $children = ''; + + if ($o->value && \is_array($o->value->contents)) { + if ($o instanceof InstanceObject && 'properties' === $o->value->getName()) { + foreach (self::sortProperties($o->value->contents, self::$sort) as $obj) { + $children .= $this->render($obj); + } + } else { + foreach ($o->value->contents as $child) { + $children .= $this->render($child); + } + } + } + + if ($children) { + $output .= PHP_EOL.$children; + $output .= \str_repeat(' ', $o->depth * $this->indent_width); + } + + if ('array' === $o->type) { + $output .= ']'; + } else { + $output .= ')'; + } + + return $output; + } + + public function colorValue($string) + { + return $string; + } + + public function colorType($string) + { + return $string; + } + + public function colorTitle($string) + { + return $string; + } + + public function postRender() + { + if (self::$decorations) { + $output = \str_repeat('â•', $this->header_width); + } else { + $output = ''; + } + + if (!$this->show_trace) { + return $this->colorTitle($output); + } + + if ($output) { + $output .= PHP_EOL; + } + + return $this->colorTitle($output.$this->calledFrom().PHP_EOL); + } + + public function filterParserPlugins(array $plugins) + { + $return = array(); + + foreach ($plugins as $index => $plugin) { + foreach (self::$parser_plugin_whitelist as $whitelist) { + if ($plugin instanceof $whitelist) { + $return[] = $plugin; + continue 2; + } + } + } + + return $return; + } + + public function ideLink($file, $line) + { + return $this->escape(Kint::shortenPath($file)).':'.$line; + } + + public function escape($string, $encoding = false) + { + return $string; + } + + protected function calledFrom() + { + $output = ''; + + if (isset($this->call_info['callee']['file'])) { + $output .= 'Called from '.$this->ideLink( + $this->call_info['callee']['file'], + $this->call_info['callee']['line'] + ); + } + + if (isset($this->call_info['callee']['function']) && ( + !empty($this->call_info['callee']['class']) || + !\in_array( + $this->call_info['callee']['function'], + array('include', 'include_once', 'require', 'require_once'), + true + ) + ) + ) { + $output .= ' ['; + if (isset($this->call_info['callee']['class'])) { + $output .= $this->call_info['callee']['class']; + } + if (isset($this->call_info['callee']['type'])) { + $output .= $this->call_info['callee']['type']; + } + $output .= $this->call_info['callee']['function'].'()]'; + } + + return $output; + } + + protected function getPlugin(array $plugins, array $hints) + { + if ($plugins = $this->matchPlugins($plugins, $hints)) { + $plugin = \end($plugins); + + if (!isset($this->plugin_objs[$plugin])) { + $this->plugin_objs[$plugin] = new $plugin($this); + } + + return $this->plugin_objs[$plugin]; + } + } +} diff --git a/vendor/kint-php/kint/src/Utils.php b/vendor/kint-php/kint/src/Utils.php new file mode 100644 index 0000000..27a2491 --- /dev/null +++ b/vendor/kint-php/kint/src/Utils.php @@ -0,0 +1,240 @@ + (float) ($value / \pow(1024, $i)), + 'unit' => $unit[$i], + ); + } + + public static function isSequential(array $array) + { + return \array_keys($array) === \range(0, \count($array) - 1); + } + + public static function composerGetExtras($key = 'kint') + { + $extras = array(); + + if (0 === \strpos(KINT_DIR, 'phar://')) { + // Only run inside phar file, so skip for code coverage + return $extras; // @codeCoverageIgnore + } + + $folder = KINT_DIR.'/vendor'; + + for ($i = 0; $i < 4; ++$i) { + $installed = $folder.'/composer/installed.json'; + + if (\file_exists($installed) && \is_readable($installed)) { + $packages = \json_decode(\file_get_contents($installed), true); + + foreach ($packages as $package) { + if (isset($package['extra'][$key]) && \is_array($package['extra'][$key])) { + $extras = \array_replace($extras, $package['extra'][$key]); + } + } + + $folder = \dirname($folder); + + if (\file_exists($folder.'/composer.json') && \is_readable($folder.'/composer.json')) { + $composer = \json_decode(\file_get_contents($folder.'/composer.json'), true); + + if (isset($composer['extra'][$key]) && \is_array($composer['extra'][$key])) { + $extras = \array_replace($extras, $composer['extra'][$key]); + } + } + + break; + } + + $folder = \dirname($folder); + } + + return $extras; + } + + /** + * @codeCoverageIgnore + */ + public static function composerSkipFlags() + { + $extras = self::composerGetExtras(); + + if (!empty($extras['disable-facade']) && !\defined('KINT_SKIP_FACADE')) { + \define('KINT_SKIP_FACADE', true); + } + + if (!empty($extras['disable-helpers']) && !\defined('KINT_SKIP_HELPERS')) { + \define('KINT_SKIP_HELPERS', true); + } + } + + public static function isTrace(array $trace) + { + if (!self::isSequential($trace)) { + return false; + } + + static $bt_structure = array( + 'function' => 'string', + 'line' => 'integer', + 'file' => 'string', + 'class' => 'string', + 'object' => 'object', + 'type' => 'string', + 'args' => 'array', + ); + + $file_found = false; + + foreach ($trace as $frame) { + if (!\is_array($frame) || !isset($frame['function'])) { + return false; + } + + foreach ($frame as $key => $val) { + if (!isset($bt_structure[$key])) { + return false; + } + + if (\gettype($val) !== $bt_structure[$key]) { + return false; + } + + if ('file' === $key) { + $file_found = true; + } + } + } + + return $file_found; + } + + public static function traceFrameIsListed(array $frame, array $matches) + { + if (isset($frame['class'])) { + $called = array(\strtolower($frame['class']), \strtolower($frame['function'])); + } else { + $called = \strtolower($frame['function']); + } + + return \in_array($called, $matches, true); + } + + public static function normalizeAliases(array &$aliases) + { + static $name_regex = '[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*'; + + foreach ($aliases as $index => &$alias) { + if (\is_array($alias) && 2 === \count($alias)) { + $alias = \array_values(\array_filter($alias, 'is_string')); + + if (2 === \count($alias) && + \preg_match('/^'.$name_regex.'$/', $alias[1]) && + \preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias[0]) + ) { + $alias = array( + \strtolower(\ltrim($alias[0], '\\')), + \strtolower($alias[1]), + ); + } else { + unset($aliases[$index]); + continue; + } + } elseif (\is_string($alias)) { + if (\preg_match('/^\\\\?('.$name_regex.'\\\\)*'.$name_regex.'$/', $alias)) { + $alias = \explode('\\', \strtolower($alias)); + $alias = \end($alias); + } else { + unset($aliases[$index]); + continue; + } + } else { + unset($aliases[$index]); + } + } + + $aliases = \array_values($aliases); + } + + public static function truncateString($input, $length = PHP_INT_MAX, $end = '...', $encoding = false) + { + $length = (int) $length; + $endlength = BlobObject::strlen($end); + + if ($endlength >= $length) { + throw new InvalidArgumentException('Can\'t truncate a string to '.$length.' characters if ending with string '.$endlength.' characters long'); + } + + if (BlobObject::strlen($input, $encoding) > $length) { + return BlobObject::substr($input, 0, $length - $endlength, $encoding).$end; + } + + return $input; + } + + public static function getTypeString(ReflectionType $type) + { + if ($type instanceof ReflectionNamedType) { + return $type->getName(); + } + + return (string) $type; // @codeCoverageIgnore + } +} diff --git a/vendor/laminas/laminas-escaper/CHANGELOG.md b/vendor/laminas/laminas-escaper/CHANGELOG.md new file mode 100644 index 0000000..086e889 --- /dev/null +++ b/vendor/laminas/laminas-escaper/CHANGELOG.md @@ -0,0 +1,73 @@ +# Changelog + +All notable changes to this project will be documented in this file, in reverse chronological order by release. + +## 2.6.1 - 2019-09-05 + +### Added + +- [zendframework/zend-escaper#32](https://github.com/zendframework/zend-escaper/pull/32) adds support for PHP 7.3. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 2.6.0 - 2018-04-25 + +### Added + +- [zendframework/zend-escaper#28](https://github.com/zendframework/zend-escaper/pull/28) adds support for PHP 7.1 and 7.2. + +### Changed + +- [zendframework/zend-escaper#25](https://github.com/zendframework/zend-escaper/pull/25) changes the behavior of the `Escaper` constructor; it now raises an + exception for non-null, non-string `$encoding` arguments. + +### Deprecated + +- Nothing. + +### Removed + +- [zendframework/zend-escaper#28](https://github.com/zendframework/zend-escaper/pull/28) removes support for PHP 5.5. + +- [zendframework/zend-escaper#28](https://github.com/zendframework/zend-escaper/pull/28) removes support for HHVM. + +### Fixed + +- Nothing. + +## 2.5.2 - 2016-06-30 + +### Added + +- [zendframework/zend-escaper#11](https://github.com/zendframework/zend-escaper/pull/11), + [zendframework/zend-escaper#12](https://github.com/zendframework/zend-escaper/pull/12), and + [zendframework/zend-escaper#13](https://github.com/zendframework/zend-escaper/pull/13) prepare and + publish documentation to https://docs.laminas.dev/laminas-escaper/ + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [zendframework/zend-escaper#3](https://github.com/zendframework/zend-escaper/pull/3) updates the + the escaping mechanism to add support for escaping characters outside the Basic + Multilingual Plane when escaping for JS, CSS, or HTML attributes. diff --git a/vendor/laminas/laminas-escaper/COPYRIGHT.md b/vendor/laminas/laminas-escaper/COPYRIGHT.md new file mode 100644 index 0000000..c4fc4fe --- /dev/null +++ b/vendor/laminas/laminas-escaper/COPYRIGHT.md @@ -0,0 +1,2 @@ +Copyright (c) 2019, Laminas Foundation. +All rights reserved. (https://getlaminas.org/) diff --git a/vendor/laminas/laminas-escaper/LICENSE.md b/vendor/laminas/laminas-escaper/LICENSE.md new file mode 100644 index 0000000..09f53ed --- /dev/null +++ b/vendor/laminas/laminas-escaper/LICENSE.md @@ -0,0 +1,27 @@ +Copyright (c) 2019, Laminas Foundation +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 Laminas Foundation 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. diff --git a/vendor/laminas/laminas-escaper/README.md b/vendor/laminas/laminas-escaper/README.md new file mode 100644 index 0000000..a779778 --- /dev/null +++ b/vendor/laminas/laminas-escaper/README.md @@ -0,0 +1,28 @@ +# laminas-escaper + +[![Build Status](https://travis-ci.org/laminas/laminas-escaper.svg?branch=master)](https://travis-ci.org/laminas/laminas-escaper) +[![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-escaper/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-escaper?branch=master) + +The OWASP Top 10 web security risks study lists Cross-Site Scripting (XSS) in +second place. PHP’s sole functionality against XSS is limited to two functions +of which one is commonly misapplied. Thus, the laminas-escaper component was written. +It offers developers a way to escape output and defend from XSS and related +vulnerabilities by introducing contextual escaping based on peer-reviewed rules. + +## Installation + +Run the following to install this library: + +```bash +$ composer require laminas/laminas-escaper +``` + +## Documentation + +Browse the documentation online at https://docs.laminas.dev/laminas-escaper/ + +## Support + +* [Issues](https://github.com/laminas/laminas-escaper/issues/) +* [Chat](https://laminas.dev/chat/) +* [Forum](https://discourse.laminas.dev/) diff --git a/vendor/laminas/laminas-escaper/composer.json b/vendor/laminas/laminas-escaper/composer.json new file mode 100644 index 0000000..c39174f --- /dev/null +++ b/vendor/laminas/laminas-escaper/composer.json @@ -0,0 +1,58 @@ +{ + "name": "laminas/laminas-escaper", + "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", + "license": "BSD-3-Clause", + "keywords": [ + "laminas", + "escaper" + ], + "homepage": "https://laminas.dev", + "support": { + "docs": "https://docs.laminas.dev/laminas-escaper/", + "issues": "https://github.com/laminas/laminas-escaper/issues", + "source": "https://github.com/laminas/laminas-escaper", + "rss": "https://github.com/laminas/laminas-escaper/releases.atom", + "chat": "https://laminas.dev/chat", + "forum": "https://discourse.laminas.dev" + }, + "config": { + "sort-packages": true + }, + "extra": { + "branch-alias": { + "dev-master": "2.6.x-dev", + "dev-develop": "2.7.x-dev" + } + }, + "require": { + "php": "^5.6 || ^7.0", + "laminas/laminas-zendframework-bridge": "^1.0" + }, + "require-dev": { + "laminas/laminas-coding-standard": "~1.0.0", + "phpunit/phpunit": "^5.7.27 || ^6.5.8 || ^7.1.2" + }, + "autoload": { + "psr-4": { + "Laminas\\Escaper\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "LaminasTest\\Escaper\\": "test/" + } + }, + "scripts": { + "check": [ + "@cs-check", + "@test" + ], + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" + }, + "replace": { + "zendframework/zend-escaper": "self.version" + } +} diff --git a/vendor/laminas/laminas-escaper/src/Escaper.php b/vendor/laminas/laminas-escaper/src/Escaper.php new file mode 100644 index 0000000..9f903a5 --- /dev/null +++ b/vendor/laminas/laminas-escaper/src/Escaper.php @@ -0,0 +1,391 @@ + 'quot', // quotation mark + 38 => 'amp', // ampersand + 60 => 'lt', // less-than sign + 62 => 'gt', // greater-than sign + ]; + + /** + * Current encoding for escaping. If not UTF-8, we convert strings from this encoding + * pre-escaping and back to this encoding post-escaping. + * + * @var string + */ + protected $encoding = 'utf-8'; + + /** + * Holds the value of the special flags passed as second parameter to + * htmlspecialchars(). + * + * @var int + */ + protected $htmlSpecialCharsFlags; + + /** + * Static Matcher which escapes characters for HTML Attribute contexts + * + * @var callable + */ + protected $htmlAttrMatcher; + + /** + * Static Matcher which escapes characters for Javascript contexts + * + * @var callable + */ + protected $jsMatcher; + + /** + * Static Matcher which escapes characters for CSS Attribute contexts + * + * @var callable + */ + protected $cssMatcher; + + /** + * List of all encoding supported by this class + * + * @var array + */ + protected $supportedEncodings = [ + 'iso-8859-1', 'iso8859-1', 'iso-8859-5', 'iso8859-5', + 'iso-8859-15', 'iso8859-15', 'utf-8', 'cp866', + 'ibm866', '866', 'cp1251', 'windows-1251', + 'win-1251', '1251', 'cp1252', 'windows-1252', + '1252', 'koi8-r', 'koi8-ru', 'koi8r', + 'big5', '950', 'gb2312', '936', + 'big5-hkscs', 'shift_jis', 'sjis', 'sjis-win', + 'cp932', '932', 'euc-jp', 'eucjp', + 'eucjp-win', 'macroman' + ]; + + /** + * Constructor: Single parameter allows setting of global encoding for use by + * the current object. + * + * @param string $encoding + * @throws Exception\InvalidArgumentException + */ + public function __construct($encoding = null) + { + if ($encoding !== null) { + if (! is_string($encoding)) { + throw new Exception\InvalidArgumentException( + get_class($this) . ' constructor parameter must be a string, received ' . gettype($encoding) + ); + } + if ($encoding === '') { + throw new Exception\InvalidArgumentException( + get_class($this) . ' constructor parameter does not allow a blank value' + ); + } + + $encoding = strtolower($encoding); + if (! in_array($encoding, $this->supportedEncodings)) { + throw new Exception\InvalidArgumentException( + 'Value of \'' . $encoding . '\' passed to ' . get_class($this) + . ' constructor parameter is invalid. Provide an encoding supported by htmlspecialchars()' + ); + } + + $this->encoding = $encoding; + } + + // We take advantage of ENT_SUBSTITUTE flag to correctly deal with invalid UTF-8 sequences. + $this->htmlSpecialCharsFlags = ENT_QUOTES | ENT_SUBSTITUTE; + + // set matcher callbacks + $this->htmlAttrMatcher = [$this, 'htmlAttrMatcher']; + $this->jsMatcher = [$this, 'jsMatcher']; + $this->cssMatcher = [$this, 'cssMatcher']; + } + + /** + * Return the encoding that all output/input is expected to be encoded in. + * + * @return string + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Escape a string for the HTML Body context where there are very few characters + * of special meaning. Internally this will use htmlspecialchars(). + * + * @param string $string + * @return string + */ + public function escapeHtml($string) + { + return htmlspecialchars($string, $this->htmlSpecialCharsFlags, $this->encoding); + } + + /** + * Escape a string for the HTML Attribute context. We use an extended set of characters + * to escape that are not covered by htmlspecialchars() to cover cases where an attribute + * might be unquoted or quoted illegally (e.g. backticks are valid quotes for IE). + * + * @param string $string + * @return string + */ + public function escapeHtmlAttr($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9,\.\-_]/iSu', $this->htmlAttrMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Escape a string for the Javascript context. This does not use json_encode(). An extended + * set of characters are escaped beyond ECMAScript's rules for Javascript literal string + * escaping in order to prevent misinterpretation of Javascript as HTML leading to the + * injection of special characters and entities. The escaping used should be tolerant + * of cases where HTML escaping was not applied on top of Javascript escaping correctly. + * Backslash escaping is not used as it still leaves the escaped character as-is and so + * is not useful in a HTML context. + * + * @param string $string + * @return string + */ + public function escapeJs($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9,\._]/iSu', $this->jsMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Escape a string for the URI or Parameter contexts. This should not be used to escape + * an entire URI - only a subcomponent being inserted. The function is a simple proxy + * to rawurlencode() which now implements RFC 3986 since PHP 5.3 completely. + * + * @param string $string + * @return string + */ + public function escapeUrl($string) + { + return rawurlencode($string); + } + + /** + * Escape a string for the CSS context. CSS escaping can be applied to any string being + * inserted into CSS and escapes everything except alphanumerics. + * + * @param string $string + * @return string + */ + public function escapeCss($string) + { + $string = $this->toUtf8($string); + if ($string === '' || ctype_digit($string)) { + return $string; + } + + $result = preg_replace_callback('/[^a-z0-9]/iSu', $this->cssMatcher, $string); + return $this->fromUtf8($result); + } + + /** + * Callback function for preg_replace_callback that applies HTML Attribute + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function htmlAttrMatcher($matches) + { + $chr = $matches[0]; + $ord = ord($chr); + + /** + * The following replaces characters undefined in HTML with the + * hex entity for the Unicode replacement character. + */ + if (($ord <= 0x1f && $chr != "\t" && $chr != "\n" && $chr != "\r") + || ($ord >= 0x7f && $ord <= 0x9f) + ) { + return '�'; + } + + /** + * Check if the current character to escape has a name entity we should + * replace it with while grabbing the integer value of the character. + */ + if (strlen($chr) > 1) { + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); + } + + $hex = bin2hex($chr); + $ord = hexdec($hex); + if (isset(static::$htmlNamedEntityMap[$ord])) { + return '&' . static::$htmlNamedEntityMap[$ord] . ';'; + } + + /** + * Per OWASP recommendations, we'll use upper hex entities + * for any other characters where a named entity does not exist. + */ + if ($ord > 255) { + return sprintf('&#x%04X;', $ord); + } + return sprintf('&#x%02X;', $ord); + } + + /** + * Callback function for preg_replace_callback that applies Javascript + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function jsMatcher($matches) + { + $chr = $matches[0]; + if (strlen($chr) == 1) { + return sprintf('\\x%02X', ord($chr)); + } + $chr = $this->convertEncoding($chr, 'UTF-16BE', 'UTF-8'); + $hex = strtoupper(bin2hex($chr)); + if (strlen($hex) <= 4) { + return sprintf('\\u%04s', $hex); + } + $highSurrogate = substr($hex, 0, 4); + $lowSurrogate = substr($hex, 4, 4); + return sprintf('\\u%04s\\u%04s', $highSurrogate, $lowSurrogate); + } + + /** + * Callback function for preg_replace_callback that applies CSS + * escaping to all matches. + * + * @param array $matches + * @return string + */ + protected function cssMatcher($matches) + { + $chr = $matches[0]; + if (strlen($chr) == 1) { + $ord = ord($chr); + } else { + $chr = $this->convertEncoding($chr, 'UTF-32BE', 'UTF-8'); + $ord = hexdec(bin2hex($chr)); + } + return sprintf('\\%X ', $ord); + } + + /** + * Converts a string to UTF-8 from the base encoding. The base encoding is set via this + * class' constructor. + * + * @param string $string + * @throws Exception\RuntimeException + * @return string + */ + protected function toUtf8($string) + { + if ($this->getEncoding() === 'utf-8') { + $result = $string; + } else { + $result = $this->convertEncoding($string, 'UTF-8', $this->getEncoding()); + } + + if (! $this->isUtf8($result)) { + throw new Exception\RuntimeException( + sprintf('String to be escaped was not valid UTF-8 or could not be converted: %s', $result) + ); + } + + return $result; + } + + /** + * Converts a string from UTF-8 to the base encoding. The base encoding is set via this + * class' constructor. + * @param string $string + * @return string + */ + protected function fromUtf8($string) + { + if ($this->getEncoding() === 'utf-8') { + return $string; + } + + return $this->convertEncoding($string, $this->getEncoding(), 'UTF-8'); + } + + /** + * Checks if a given string appears to be valid UTF-8 or not. + * + * @param string $string + * @return bool + */ + protected function isUtf8($string) + { + return ($string === '' || preg_match('/^./su', $string)); + } + + /** + * Encoding conversion helper which wraps iconv and mbstring where they exist or throws + * and exception where neither is available. + * + * @param string $string + * @param string $to + * @param array|string $from + * @throws Exception\RuntimeException + * @return string + */ + protected function convertEncoding($string, $to, $from) + { + if (function_exists('iconv')) { + $result = iconv($from, $to, $string); + } elseif (function_exists('mb_convert_encoding')) { + $result = mb_convert_encoding($string, $to, $from); + } else { + throw new Exception\RuntimeException( + get_class($this) + . ' requires either the iconv or mbstring extension to be installed' + . ' when escaping for non UTF-8 strings.' + ); + } + + if ($result === false) { + return ''; // return non-fatal blank string on encoding errors from users + } + return $result; + } +} diff --git a/vendor/laminas/laminas-escaper/src/Exception/ExceptionInterface.php b/vendor/laminas/laminas-escaper/src/Exception/ExceptionInterface.php new file mode 100644 index 0000000..7ebe04e --- /dev/null +++ b/vendor/laminas/laminas-escaper/src/Exception/ExceptionInterface.php @@ -0,0 +1,13 @@ + laminas-project.flf. + +## 0.3.5 - 2019-11-06 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#25](https://github.com/laminas/laminas-zendframework-bridge/pull/25) adds entries for ZendHttp and ZendModule, which are file name segments in files from the zend-feed and zend-config-aggregator-module packages, respectively. + +## 0.3.4 - 2019-11-06 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#24](https://github.com/laminas/laminas-zendframework-bridge/pull/24) adds a rule to never rewrite the string `Doctrine\Zend`. + +- [#23](https://github.com/laminas/laminas-zendframework-bridge/pull/23) adds a missing map for each of ZendAcl and ZendRbac, which occur in the zend-expressive-authorization-acl and zend-expressive-authorization-rbac packages, respectively. + +## 0.3.3 - 2019-11-06 + +### Added + +- [#22](https://github.com/laminas/laminas-zendframework-bridge/pull/22) adds configuration post-processing features, exposed both as a laminas-config-aggregator post processor (for use with Expressive applications) and as a laminas-modulemanager `EVENT_MERGE_CONFIG` listener (for use with MVC applications). When registered, it will post-process the configuration, replacing known Zend Framework-specific strings with their Laminas replacements. A ruleset is provided that ensures dependency configuration is rewritten in a safe manner, routing configuration is skipped, and certain top-level configuration keys are matched exactly (instead of potentially as substrings or word stems). A later release of laminas-migration will auto-register these tools in applications when possible. + +### Changed + +- [#22](https://github.com/laminas/laminas-zendframework-bridge/pull/22) removes support for PHP versions prior to PHP 5.6. We have decided to only support supported PHP versions, whether that support is via php.net or commercial. The lowest supported PHP version we have found is 5.6. Users wishing to migrate to Laminas must at least update to PHP 5.6 before doing so. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 0.3.2 - 2019-10-30 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- [#21](https://github.com/laminas/laminas-zendframework-bridge/pull/21) removes rewriting of the Amazon library, as it is not moving to Laminas. + +- [#21](https://github.com/laminas/laminas-zendframework-bridge/pull/21) removes rewriting of the GCM and APNS libraries, as they are not moving to Laminas. + +### Fixed + +- [#21](https://github.com/laminas/laminas-zendframework-bridge/pull/21) fixes how the recaptcha and twitter library package and namespaces are rewritten. + +## 0.3.1 - 2019-04-25 + +### Added + +- [#20](https://github.com/laminas/laminas-zendframework-bridge/pull/20) provides an additional autoloader that is _prepended_ to the autoloader + stack. This new autoloader will create class aliases for interfaces, classes, + and traits referenced in type hints and class declarations, ensuring PHP is + able to resolve them correctly during class_alias operations. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 0.3.0 - 2019-04-12 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- [#16](https://github.com/laminas/laminas-zendframework-bridge/pull/16) removes the `RewriteRules::classRewrite()` method, as it is no longer + needed due to internal refactoring. + +### Fixed + +- [#16](https://github.com/laminas/laminas-zendframework-bridge/pull/16) fixes how the rewrite rules detect the word `Zend` in subnamespaces and + class names to be both more robust and simpler. + +## 0.2.5 - 2019-04-11 + +### Added + +- [#12](https://github.com/laminas/laminas-zendframework-bridge/pull/12) adds functionality for ensuring we alias namespaces and classes that + include the word `Zend` in them; e.g., `Zend\Expressive\ZendView\ZendViewRendererFactory` + will now alias to `Expressive\LaminasView\LaminasViewRendererFactory`. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 0.2.4 - 2019-04-11 + +### Added + +- [#11](https://github.com/laminas/laminas-zendframework-bridge/pull/11) adds maps for the Expressive router adapter packages. + +- [#10](https://github.com/laminas/laminas-zendframework-bridge/pull/10) adds a map for the Psr7Bridge package, as it used `Zend` within a subnamespace. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. + +## 0.2.3 - 2019-04-10 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#9](https://github.com/laminas/laminas-zendframework-bridge/pull/9) fixes the mapping for the Problem Details package. + +## 0.2.2 - 2019-04-10 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Added a check that the discovered alias exists as a class, interface, or trait + before attempting to call `class_alias()`. + +## 0.2.1 - 2019-04-10 + +### Added + +- Nothing. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- [#8](https://github.com/laminas/laminas-zendframework-bridge/pull/8) fixes mappings for each of zend-expressive-authentication-zendauthentication, + zend-expressive-zendrouter, and zend-expressive-zendviewrenderer. + +## 0.2.0 - 2019-04-01 + +### Added + +- Nothing. + +### Changed + +- [#4](https://github.com/laminas/laminas-zendframework-bridge/pull/4) rewrites the autoloader to be class-based, via the class + `Laminas\ZendFrameworkBridge\Autoloader`. Additionally, the new approach + provides a performance boost by using a balanced tree algorithm, ensuring + matches occur faster. + +### Deprecated + +- Nothing. + +### Removed + +- [#4](https://github.com/laminas/laminas-zendframework-bridge/pull/4) removes function aliasing. Function aliasing will move to the packages that + provide functions. + +### Fixed + +- Nothing. + +## 0.1.0 - 2019-03-27 + +### Added + +- Adds an autoloader file that registers with `spl_autoload_register` a routine + for aliasing legacy ZF class/interface/trait names to Laminas Project + equivalents. + +- Adds autoloader files for aliasing legacy ZF package functions to Laminas + Project equivalents. + +### Changed + +- Nothing. + +### Deprecated + +- Nothing. + +### Removed + +- Nothing. + +### Fixed + +- Nothing. diff --git a/vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md b/vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md new file mode 100644 index 0000000..0a8cccc --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md @@ -0,0 +1 @@ +Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. (https://getlaminas.org/) diff --git a/vendor/laminas/laminas-zendframework-bridge/LICENSE.md b/vendor/laminas/laminas-zendframework-bridge/LICENSE.md new file mode 100644 index 0000000..10b40f1 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/LICENSE.md @@ -0,0 +1,26 @@ +Copyright (c) 2020 Laminas Project a Series of LF Projects, LLC. + +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 Laminas Foundation 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. diff --git a/vendor/laminas/laminas-zendframework-bridge/README.md b/vendor/laminas/laminas-zendframework-bridge/README.md new file mode 100644 index 0000000..fd79538 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/README.md @@ -0,0 +1,24 @@ +# laminas-zendframework-bridge + +[![Build Status](https://travis-ci.com/laminas/laminas-zendframework-bridge.svg?branch=master)](https://travis-ci.com/laminas/laminas-zendframework-bridge) +[![Coverage Status](https://coveralls.io/repos/github/laminas/laminas-zendframework-bridge/badge.svg?branch=master)](https://coveralls.io/github/laminas/laminas-zendframework-bridge?branch=master) + +This library provides a custom autoloader that aliases legacy Zend Framework, +Apigility, and Expressive classes to their replacements under the Laminas +Project. + +This package should be installed only if you are also using the composer plugin +that installs Laminas packages to replace ZF/Apigility/Expressive packages. + +## Installation + +Run the following to install this library: + +```bash +$ composer require laminas/laminas-zendframework-bridge +``` + +## Support + +* [Issues](https://github.com/laminas/laminas-zendframework-bridge/issues/) +* [Forum](https://discourse.laminas.dev/) diff --git a/vendor/laminas/laminas-zendframework-bridge/composer.json b/vendor/laminas/laminas-zendframework-bridge/composer.json new file mode 100644 index 0000000..34af15a --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/composer.json @@ -0,0 +1,58 @@ +{ + "name": "laminas/laminas-zendframework-bridge", + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "license": "BSD-3-Clause", + "keywords": [ + "autoloading", + "laminas", + "zf", + "zendframework" + ], + "support": { + "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", + "source": "https://github.com/laminas/laminas-zendframework-bridge", + "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", + "forum": "https://discourse.laminas.dev/" + }, + "require": { + "php": "^5.6 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", + "squizlabs/php_codesniffer": "^3.5" + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "autoload-dev": { + "files": [ + "test/classes.php" + ], + "psr-4": { + "LaminasTest\\ZendFrameworkBridge\\": "test/", + "LaminasTest\\ZendFrameworkBridge\\TestAsset\\": "test/TestAsset/classes/", + "Laminas\\ApiTools\\": "test/TestAsset/LaminasApiTools/", + "Mezzio\\": "test/TestAsset/Mezzio/", + "Laminas\\": "test/TestAsset/Laminas/" + } + }, + "extra": { + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "config": { + "sort-packages": true + }, + "scripts": { + "cs-check": "phpcs", + "cs-fix": "phpcbf", + "test": "phpunit --colors=always", + "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/config/replacements.php b/vendor/laminas/laminas-zendframework-bridge/config/replacements.php new file mode 100644 index 0000000..f534435 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/config/replacements.php @@ -0,0 +1,372 @@ + 'zendframework/zendframework', + 'zend-developer-tools/toolbar/bjy' => 'zend-developer-tools/toolbar/bjy', + 'zend-developer-tools/toolbar/doctrine' => 'zend-developer-tools/toolbar/doctrine', + + // NAMESPACES + // Zend Framework components + 'Zend\\AuraDi\\Config' => 'Laminas\\AuraDi\\Config', + 'Zend\\Authentication' => 'Laminas\\Authentication', + 'Zend\\Barcode' => 'Laminas\\Barcode', + 'Zend\\Cache' => 'Laminas\\Cache', + 'Zend\\Captcha' => 'Laminas\\Captcha', + 'Zend\\Code' => 'Laminas\\Code', + 'ZendCodingStandard\\Sniffs' => 'LaminasCodingStandard\\Sniffs', + 'ZendCodingStandard\\Utils' => 'LaminasCodingStandard\\Utils', + 'Zend\\ComponentInstaller' => 'Laminas\\ComponentInstaller', + 'Zend\\Config' => 'Laminas\\Config', + 'Zend\\ConfigAggregator' => 'Laminas\\ConfigAggregator', + 'Zend\\ConfigAggregatorModuleManager' => 'Laminas\\ConfigAggregatorModuleManager', + 'Zend\\ConfigAggregatorParameters' => 'Laminas\\ConfigAggregatorParameters', + 'Zend\\Console' => 'Laminas\\Console', + 'Zend\\ContainerConfigTest' => 'Laminas\\ContainerConfigTest', + 'Zend\\Crypt' => 'Laminas\\Crypt', + 'Zend\\Db' => 'Laminas\\Db', + 'ZendDeveloperTools' => 'Laminas\\DeveloperTools', + 'Zend\\Di' => 'Laminas\\Di', + 'Zend\\Diactoros' => 'Laminas\\Diactoros', + 'ZendDiagnostics\\Check' => 'Laminas\\Diagnostics\\Check', + 'ZendDiagnostics\\Result' => 'Laminas\\Diagnostics\\Result', + 'ZendDiagnostics\\Runner' => 'Laminas\\Diagnostics\\Runner', + 'Zend\\Dom' => 'Laminas\\Dom', + 'Zend\\Escaper' => 'Laminas\\Escaper', + 'Zend\\EventManager' => 'Laminas\\EventManager', + 'Zend\\Feed' => 'Laminas\\Feed', + 'Zend\\File' => 'Laminas\\File', + 'Zend\\Filter' => 'Laminas\\Filter', + 'Zend\\Form' => 'Laminas\\Form', + 'Zend\\Http' => 'Laminas\\Http', + 'Zend\\HttpHandlerRunner' => 'Laminas\\HttpHandlerRunner', + 'Zend\\Hydrator' => 'Laminas\\Hydrator', + 'Zend\\I18n' => 'Laminas\\I18n', + 'Zend\\InputFilter' => 'Laminas\\InputFilter', + 'Zend\\Json' => 'Laminas\\Json', + 'Zend\\Ldap' => 'Laminas\\Ldap', + 'Zend\\Loader' => 'Laminas\\Loader', + 'Zend\\Log' => 'Laminas\\Log', + 'Zend\\Mail' => 'Laminas\\Mail', + 'Zend\\Math' => 'Laminas\\Math', + 'Zend\\Memory' => 'Laminas\\Memory', + 'Zend\\Mime' => 'Laminas\\Mime', + 'Zend\\ModuleManager' => 'Laminas\\ModuleManager', + 'Zend\\Mvc' => 'Laminas\\Mvc', + 'Zend\\Navigation' => 'Laminas\\Navigation', + 'Zend\\Paginator' => 'Laminas\\Paginator', + 'Zend\\Permissions' => 'Laminas\\Permissions', + 'Zend\\Pimple\\Config' => 'Laminas\\Pimple\\Config', + 'Zend\\ProblemDetails' => 'Mezzio\\ProblemDetails', + 'Zend\\ProgressBar' => 'Laminas\\ProgressBar', + 'Zend\\Psr7Bridge' => 'Laminas\\Psr7Bridge', + 'Zend\\Router' => 'Laminas\\Router', + 'Zend\\Serializer' => 'Laminas\\Serializer', + 'Zend\\Server' => 'Laminas\\Server', + 'Zend\\ServiceManager' => 'Laminas\\ServiceManager', + 'ZendService\\ReCaptcha' => 'Laminas\\ReCaptcha', + 'ZendService\\Twitter' => 'Laminas\\Twitter', + 'Zend\\Session' => 'Laminas\\Session', + 'Zend\\SkeletonInstaller' => 'Laminas\\SkeletonInstaller', + 'Zend\\Soap' => 'Laminas\\Soap', + 'Zend\\Stdlib' => 'Laminas\\Stdlib', + 'Zend\\Stratigility' => 'Laminas\\Stratigility', + 'Zend\\Tag' => 'Laminas\\Tag', + 'Zend\\Test' => 'Laminas\\Test', + 'Zend\\Text' => 'Laminas\\Text', + 'Zend\\Uri' => 'Laminas\\Uri', + 'Zend\\Validator' => 'Laminas\\Validator', + 'Zend\\View' => 'Laminas\\View', + 'ZendXml' => 'Laminas\\Xml', + 'Zend\\Xml2Json' => 'Laminas\\Xml2Json', + 'Zend\\XmlRpc' => 'Laminas\\XmlRpc', + 'ZendOAuth' => 'Laminas\\OAuth', + + // class ZendAcl in zend-expressive-authorization-acl + 'ZendAcl' => 'LaminasAcl', + 'Zend\\Expressive\\Authorization\\Acl\\ZendAcl' => 'Mezzio\\Authorization\\Acl\\LaminasAcl', + // class ZendHttpClientDecorator in zend-feed + 'ZendHttp' => 'LaminasHttp', + // class ZendModuleProvider in zend-config-aggregator-modulemanager + 'ZendModule' => 'LaminasModule', + // class ZendRbac in zend-expressive-authorization-rbac + 'ZendRbac' => 'LaminasRbac', + 'Zend\\Expressive\\Authorization\\Rbac\\ZendRbac' => 'Mezzio\\Authorization\\Rbac\\LaminasRbac', + // class ZendRouter in zend-expressive-router-zendrouter + 'ZendRouter' => 'LaminasRouter', + 'Zend\\Expressive\\Router\\ZendRouter' => 'Mezzio\\Router\\LaminasRouter', + // class ZendViewRenderer in zend-expressive-zendviewrenderer + 'ZendViewRenderer' => 'LaminasViewRenderer', + 'Zend\\Expressive\\ZendView\\ZendViewRenderer' => 'Mezzio\\LaminasView\\LaminasViewRenderer', + 'a\\Zend' => 'a\\Zend', + 'b\\Zend' => 'b\\Zend', + 'c\\Zend' => 'c\\Zend', + 'd\\Zend' => 'd\\Zend', + 'e\\Zend' => 'e\\Zend', + 'f\\Zend' => 'f\\Zend', + 'g\\Zend' => 'g\\Zend', + 'h\\Zend' => 'h\\Zend', + 'i\\Zend' => 'i\\Zend', + 'j\\Zend' => 'j\\Zend', + 'k\\Zend' => 'k\\Zend', + 'l\\Zend' => 'l\\Zend', + 'm\\Zend' => 'm\\Zend', + 'n\\Zend' => 'n\\Zend', + 'o\\Zend' => 'o\\Zend', + 'p\\Zend' => 'p\\Zend', + 'q\\Zend' => 'q\\Zend', + 'r\\Zend' => 'r\\Zend', + 's\\Zend' => 's\\Zend', + 't\\Zend' => 't\\Zend', + 'u\\Zend' => 'u\\Zend', + 'v\\Zend' => 'v\\Zend', + 'w\\Zend' => 'w\\Zend', + 'x\\Zend' => 'x\\Zend', + 'y\\Zend' => 'y\\Zend', + 'z\\Zend' => 'z\\Zend', + + // Expressive + 'Zend\\Expressive' => 'Mezzio', + 'ZendAuthentication' => 'LaminasAuthentication', + 'ZendAcl' => 'LaminasAcl', + 'ZendRbac' => 'LaminasRbac', + 'ZendRouter' => 'LaminasRouter', + 'ExpressiveUrlGenerator' => 'MezzioUrlGenerator', + 'ExpressiveInstaller' => 'MezzioInstaller', + + // Apigility + 'ZF\\Apigility' => 'Laminas\\ApiTools', + 'ZF\\ApiProblem' => 'Laminas\\ApiTools\\ApiProblem', + 'ZF\\AssetManager' => 'Laminas\\ApiTools\\AssetManager', + 'ZF\\ComposerAutoloading' => 'Laminas\\ComposerAutoloading', + 'ZF\\Configuration' => 'Laminas\\ApiTools\\Configuration', + 'ZF\\ContentNegotiation' => 'Laminas\\ApiTools\\ContentNegotiation', + 'ZF\\ContentValidation' => 'Laminas\\ApiTools\\ContentValidation', + 'ZF\\DevelopmentMode' => 'Laminas\\DevelopmentMode', + 'ZF\\Doctrine\\QueryBuilder' => 'Laminas\\ApiTools\\Doctrine\\QueryBuilder', + 'ZF\\Hal' => 'Laminas\\ApiTools\\Hal', + 'ZF\\HttpCache' => 'Laminas\\ApiTools\\HttpCache', + 'ZF\\MvcAuth' => 'Laminas\\ApiTools\\MvcAuth', + 'ZF\\OAuth2' => 'Laminas\\ApiTools\\OAuth2', + 'ZF\\Rest' => 'Laminas\\ApiTools\\Rest', + 'ZF\\Rpc' => 'Laminas\\ApiTools\\Rpc', + 'ZF\\Versioning' => 'Laminas\\ApiTools\\Versioning', + 'a\\ZF' => 'a\\ZF', + 'b\\ZF' => 'b\\ZF', + 'c\\ZF' => 'c\\ZF', + 'd\\ZF' => 'd\\ZF', + 'e\\ZF' => 'e\\ZF', + 'f\\ZF' => 'f\\ZF', + 'g\\ZF' => 'g\\ZF', + 'h\\ZF' => 'h\\ZF', + 'i\\ZF' => 'i\\ZF', + 'j\\ZF' => 'j\\ZF', + 'k\\ZF' => 'k\\ZF', + 'l\\ZF' => 'l\\ZF', + 'm\\ZF' => 'm\\ZF', + 'n\\ZF' => 'n\\ZF', + 'o\\ZF' => 'o\\ZF', + 'p\\ZF' => 'p\\ZF', + 'q\\ZF' => 'q\\ZF', + 'r\\ZF' => 'r\\ZF', + 's\\ZF' => 's\\ZF', + 't\\ZF' => 't\\ZF', + 'u\\ZF' => 'u\\ZF', + 'v\\ZF' => 'v\\ZF', + 'w\\ZF' => 'w\\ZF', + 'x\\ZF' => 'x\\ZF', + 'y\\ZF' => 'y\\ZF', + 'z\\ZF' => 'z\\ZF', + + 'ApigilityModuleInterface' => 'ApiToolsModuleInterface', + 'ApigilityProviderInterface' => 'ApiToolsProviderInterface', + 'ApigilityVersionController' => 'ApiToolsVersionController', + + // PACKAGES + // ZF components, MVC + 'zendframework/skeleton-application' => 'laminas/skeleton-application', + 'zendframework/zend-auradi-config' => 'laminas/laminas-auradi-config', + 'zendframework/zend-authentication' => 'laminas/laminas-authentication', + 'zendframework/zend-barcode' => 'laminas/laminas-barcode', + 'zendframework/zend-cache' => 'laminas/laminas-cache', + 'zendframework/zend-captcha' => 'laminas/laminas-captcha', + 'zendframework/zend-code' => 'laminas/laminas-code', + 'zendframework/zend-coding-standard' => 'laminas/laminas-coding-standard', + 'zendframework/zend-component-installer' => 'laminas/laminas-component-installer', + 'zendframework/zend-composer-autoloading' => 'laminas/laminas-composer-autoloading', + 'zendframework/zend-config-aggregator' => 'laminas/laminas-config-aggregator', + 'zendframework/zend-config' => 'laminas/laminas-config', + 'zendframework/zend-console' => 'laminas/laminas-console', + 'zendframework/zend-container-config-test' => 'laminas/laminas-container-config-test', + 'zendframework/zend-crypt' => 'laminas/laminas-crypt', + 'zendframework/zend-db' => 'laminas/laminas-db', + 'zendframework/zend-developer-tools' => 'laminas/laminas-developer-tools', + 'zendframework/zend-diactoros' => 'laminas/laminas-diactoros', + 'zendframework/zenddiagnostics' => 'laminas/laminas-diagnostics', + 'zendframework/zend-di' => 'laminas/laminas-di', + 'zendframework/zend-dom' => 'laminas/laminas-dom', + 'zendframework/zend-escaper' => 'laminas/laminas-escaper', + 'zendframework/zend-eventmanager' => 'laminas/laminas-eventmanager', + 'zendframework/zend-feed' => 'laminas/laminas-feed', + 'zendframework/zend-file' => 'laminas/laminas-file', + 'zendframework/zend-filter' => 'laminas/laminas-filter', + 'zendframework/zend-form' => 'laminas/laminas-form', + 'zendframework/zend-httphandlerrunner' => 'laminas/laminas-httphandlerrunner', + 'zendframework/zend-http' => 'laminas/laminas-http', + 'zendframework/zend-hydrator' => 'laminas/laminas-hydrator', + 'zendframework/zend-i18n' => 'laminas/laminas-i18n', + 'zendframework/zend-i18n-resources' => 'laminas/laminas-i18n-resources', + 'zendframework/zend-inputfilter' => 'laminas/laminas-inputfilter', + 'zendframework/zend-json' => 'laminas/laminas-json', + 'zendframework/zend-json-server' => 'laminas/laminas-json-server', + 'zendframework/zend-ldap' => 'laminas/laminas-ldap', + 'zendframework/zend-loader' => 'laminas/laminas-loader', + 'zendframework/zend-log' => 'laminas/laminas-log', + 'zendframework/zend-mail' => 'laminas/laminas-mail', + 'zendframework/zend-math' => 'laminas/laminas-math', + 'zendframework/zend-memory' => 'laminas/laminas-memory', + 'zendframework/zend-mime' => 'laminas/laminas-mime', + 'zendframework/zend-modulemanager' => 'laminas/laminas-modulemanager', + 'zendframework/zend-mvc' => 'laminas/laminas-mvc', + 'zendframework/zend-navigation' => 'laminas/laminas-navigation', + 'zendframework/zend-oauth' => 'laminas/laminas-oauth', + 'zendframework/zend-paginator' => 'laminas/laminas-paginator', + 'zendframework/zend-permissions-acl' => 'laminas/laminas-permissions-acl', + 'zendframework/zend-permissions-rbac' => 'laminas/laminas-permissions-rbac', + 'zendframework/zend-pimple-config' => 'laminas/laminas-pimple-config', + 'zendframework/zend-progressbar' => 'laminas/laminas-progressbar', + 'zendframework/zend-psr7bridge' => 'laminas/laminas-psr7bridge', + 'zendframework/zend-recaptcha' => 'laminas/laminas-recaptcha', + 'zendframework/zend-router' => 'laminas/laminas-router', + 'zendframework/zend-serializer' => 'laminas/laminas-serializer', + 'zendframework/zend-server' => 'laminas/laminas-server', + 'zendframework/zend-servicemanager' => 'laminas/laminas-servicemanager', + 'zendframework/zendservice-recaptcha' => 'laminas/laminas-recaptcha', + 'zendframework/zendservice-twitter' => 'laminas/laminas-twitter', + 'zendframework/zend-session' => 'laminas/laminas-session', + 'zendframework/zend-skeleton-installer' => 'laminas/laminas-skeleton-installer', + 'zendframework/zend-soap' => 'laminas/laminas-soap', + 'zendframework/zend-stdlib' => 'laminas/laminas-stdlib', + 'zendframework/zend-stratigility' => 'laminas/laminas-stratigility', + 'zendframework/zend-tag' => 'laminas/laminas-tag', + 'zendframework/zend-test' => 'laminas/laminas-test', + 'zendframework/zend-text' => 'laminas/laminas-text', + 'zendframework/zend-uri' => 'laminas/laminas-uri', + 'zendframework/zend-validator' => 'laminas/laminas-validator', + 'zendframework/zend-view' => 'laminas/laminas-view', + 'zendframework/zend-xml2json' => 'laminas/laminas-xml2json', + 'zendframework/zend-xml' => 'laminas/laminas-xml', + 'zendframework/zend-xmlrpc' => 'laminas/laminas-xmlrpc', + + // Expressive packages + 'zendframework/zend-expressive' => 'mezzio/mezzio', + 'zendframework/zend-expressive-zendrouter' => 'mezzio/mezzio-laminasrouter', + 'zendframework/zend-problem-details' => 'mezzio/mezzio-problem-details', + 'zendframework/zend-expressive-zendviewrenderer' => 'mezzio/mezzio-laminasviewrenderer', + + // Apigility packages + 'zfcampus/apigility-documentation' => 'laminas-api-tools/documentation', + 'zfcampus/statuslib-example' => 'laminas-api-tools/statuslib-example', + 'zfcampus/zf-apigility' => 'laminas-api-tools/api-tools', + 'zfcampus/zf-api-problem' => 'laminas-api-tools/api-tools-api-problem', + 'zfcampus/zf-asset-manager' => 'laminas-api-tools/api-tools-asset-manager', + 'zfcampus/zf-configuration' => 'laminas-api-tools/api-tools-configuration', + 'zfcampus/zf-content-negotiation' => 'laminas-api-tools/api-tools-content-negotiation', + 'zfcampus/zf-content-validation' => 'laminas-api-tools/api-tools-content-validation', + 'zfcampus/zf-development-mode' => 'laminas/laminas-development-mode', + 'zfcampus/zf-doctrine-querybuilder' => 'laminas-api-tools/api-tools-doctrine-querybuilder', + 'zfcampus/zf-hal' => 'laminas-api-tools/api-tools-hal', + 'zfcampus/zf-http-cache' => 'laminas-api-tools/api-tools-http-cache', + 'zfcampus/zf-mvc-auth' => 'laminas-api-tools/api-tools-mvc-auth', + 'zfcampus/zf-oauth2' => 'laminas-api-tools/api-tools-oauth2', + 'zfcampus/zf-rest' => 'laminas-api-tools/api-tools-rest', + 'zfcampus/zf-rpc' => 'laminas-api-tools/api-tools-rpc', + 'zfcampus/zf-versioning' => 'laminas-api-tools/api-tools-versioning', + + // CONFIG KEYS, SCRIPT NAMES, ETC + // ZF components + '::fromZend' => '::fromLaminas', // psr7bridge + '::toZend' => '::toLaminas', // psr7bridge + 'use_zend_loader' => 'use_laminas_loader', // zend-modulemanager + 'zend-config' => 'laminas-config', + 'zend-developer-tools/' => 'laminas-developer-tools/', + 'zend-tag-cloud' => 'laminas-tag-cloud', + 'zenddevelopertools' => 'laminas-developer-tools', + 'zendbarcode' => 'laminasbarcode', + 'ZendBarcode' => 'LaminasBarcode', + 'zendcache' => 'laminascache', + 'ZendCache' => 'LaminasCache', + 'zendconfig' => 'laminasconfig', + 'ZendConfig' => 'LaminasConfig', + 'zendfeed' => 'laminasfeed', + 'ZendFeed' => 'LaminasFeed', + 'zendfilter' => 'laminasfilter', + 'ZendFilter' => 'LaminasFilter', + 'zendform' => 'laminasform', + 'ZendForm' => 'LaminasForm', + 'zendi18n' => 'laminasi18n', + 'ZendI18n' => 'LaminasI18n', + 'zendinputfilter' => 'laminasinputfilter', + 'ZendInputFilter' => 'LaminasInputFilter', + 'zendlog' => 'laminaslog', + 'ZendLog' => 'LaminasLog', + 'zendmail' => 'laminasmail', + 'ZendMail' => 'LaminasMail', + 'zendmvc' => 'laminasmvc', + 'ZendMvc' => 'LaminasMvc', + 'zendpaginator' => 'laminaspaginator', + 'ZendPaginator' => 'LaminasPaginator', + 'zendserializer' => 'laminasserializer', + 'ZendSerializer' => 'LaminasSerializer', + 'zendtag' => 'laminastag', + 'ZendTag' => 'LaminasTag', + 'zendtext' => 'laminastext', + 'ZendText' => 'LaminasText', + 'zendvalidator' => 'laminasvalidator', + 'ZendValidator' => 'LaminasValidator', + 'zendview' => 'laminasview', + 'ZendView' => 'LaminasView', + 'zend-framework.flf' => 'laminas-project.flf', + + // Expressive-related + "'zend-expressive'" => "'mezzio'", + '"zend-expressive"' => '"mezzio"', + 'zend-expressive.' => 'mezzio.', + 'zend-expressive-authorization' => 'mezzio-authorization', + 'zend-expressive-hal' => 'mezzio-hal', + 'zend-expressive-session' => 'mezzio-session', + 'zend-expressive-swoole' => 'mezzio-swoole', + 'zend-expressive-tooling' => 'mezzio-tooling', + + // Apigility-related + "'zf-apigility'" => "'api-tools'", + '"zf-apigility"' => '"api-tools"', + 'zf-apigility/' => 'api-tools/', + 'zf-apigility-admin' => 'api-tools-admin', + 'zf-content-negotiation' => 'api-tools-content-negotiation', + 'zf-hal' => 'api-tools-hal', + 'zf-rest' => 'api-tools-rest', + 'zf-rpc' => 'api-tools-rpc', + 'zf-content-validation' => 'api-tools-content-validation', + 'zf-apigility-ui' => 'api-tools-ui', + 'zf-apigility-documentation-blueprint' => 'api-tools-documentation-blueprint', + 'zf-apigility-documentation-swagger' => 'api-tools-documentation-swagger', + 'zf-apigility-welcome' => 'api-tools-welcome', + 'zf-api-problem' => 'api-tools-api-problem', + 'zf-configuration' => 'api-tools-configuration', + 'zf-http-cache' => 'api-tools-http-cache', + 'zf-mvc-auth' => 'api-tools-mvc-auth', + 'zf-oauth2' => 'api-tools-oauth2', + 'zf-versioning' => 'api-tools-versioning', + 'ZfApigilityDoctrineQueryProviderManager' => 'LaminasApiToolsDoctrineQueryProviderManager', + 'ZfApigilityDoctrineQueryCreateFilterManager' => 'LaminasApiToolsDoctrineQueryCreateFilterManager', + 'zf-apigility-doctrine' => 'api-tools-doctrine', + 'zf-development-mode' => 'laminas-development-mode', + 'zf-doctrine-querybuilder' => 'api-tools-doctrine-querybuilder', + + // 3rd party Apigility packages + 'api-skeletons/zf-' => 'api-skeletons/zf-', // api-skeletons packages + 'zf-oauth2-' => 'zf-oauth2-', // api-skeletons OAuth2-related packages + 'ZF\\OAuth2\\Client' => 'ZF\\OAuth2\\Client', // api-skeletons/zf-oauth2-client + 'ZF\\OAuth2\\Doctrine' => 'ZF\\OAuth2\\Doctrine', // api-skeletons/zf-oauth2-doctrine +]; diff --git a/vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php b/vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php new file mode 100644 index 0000000..6048766 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php @@ -0,0 +1,172 @@ +loadClass($class)) { + $legacy = $namespaces[$check] + . strtr(substr($class, strlen($check)), [ + 'ApiTools' => 'Apigility', + 'Mezzio' => 'Expressive', + 'Laminas' => 'Zend', + ]); + class_alias($class, $legacy); + } + }; + } + + /** + * @return callable + */ + private static function createAppendAutoloader(array $namespaces, ArrayObject $loaded) + { + /** + * @param string $class Class name to autoload + * @return void + */ + return static function ($class) use ($namespaces, $loaded) { + $segments = explode('\\', $class); + + if ($segments[0] === 'ZendService' && isset($segments[1])) { + $segments[0] .= '\\' . $segments[1]; + unset($segments[1]); + $segments = array_values($segments); + } + + $i = 0; + $check = ''; + + // We are checking segments of the namespace to match quicker + while (isset($segments[$i + 1], $namespaces[$check . $segments[$i] . '\\'])) { + $check .= $segments[$i] . '\\'; + ++$i; + } + + if ($check === '') { + return; + } + + $alias = $namespaces[$check] + . strtr(substr($class, strlen($check)), [ + 'Apigility' => 'ApiTools', + 'Expressive' => 'Mezzio', + 'Zend' => 'Laminas', + 'AbstractZendServer' => 'AbstractZendServer', + 'ZendServerDisk' => 'ZendServerDisk', + 'ZendServerShm' => 'ZendServerShm', + 'ZendMonitor' => 'ZendMonitor', + ]); + + $loaded[$alias] = true; + if (class_exists($alias) || interface_exists($alias) || trait_exists($alias)) { + class_alias($alias, $class); + } + }; + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php b/vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php new file mode 100644 index 0000000..bac7b97 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php @@ -0,0 +1,434 @@ + true, + 'factories' => true, + 'invokables' => true, + 'services' => true, + ]; + + /** @var array String keys => string values */ + private $exactReplacements = [ + 'zend-expressive' => 'mezzio', + 'zf-apigility' => 'api-tools', + ]; + + /** @var Replacements */ + private $replacements; + + /** @var callable[] */ + private $rulesets; + + public function __construct() + { + $this->replacements = new Replacements(); + + /* Define the rulesets for replacements. + * + * Each ruleset has the following signature: + * + * @param mixed $value + * @param string[] $keys Full nested key hierarchy leading to the value + * @return null|callable + * + * If no match is made, a null is returned, allowing it to fallback to + * the next ruleset in the list. If a match is made, a callback is returned, + * and that will be used to perform the replacement on the value. + * + * The callback should have the following signature: + * + * @param mixed $value + * @param string[] $keys + * @return mixed The transformed value + */ + $this->rulesets = [ + // Exact values + function ($value) { + return is_string($value) && isset($this->exactReplacements[$value]) + ? [$this, 'replaceExactValue'] + : null; + }, + + // Router (MVC applications) + // We do not want to rewrite these. + function ($value, array $keys) { + $key = array_pop($keys); + // Only worried about a top-level "router" key. + return $key === 'router' && count($keys) === 0 && is_array($value) + ? [$this, 'noopReplacement'] + : null; + }, + + // service- and pluginmanager handling + function ($value) { + return is_array($value) && array_intersect_key(self::SERVICE_MANAGER_KEYS_OF_INTEREST, $value) !== [] + ? [$this, 'replaceDependencyConfiguration'] + : null; + }, + + // Array values + function ($value, array $keys) { + return 0 !== count($keys) && is_array($value) + ? [$this, '__invoke'] + : null; + }, + ]; + } + + /** + * @param string[] $keys Hierarchy of keys, for determining location in + * nested configuration. + * @return array + */ + public function __invoke(array $config, array $keys = []) + { + $rewritten = []; + + foreach ($config as $key => $value) { + // Determine new key from replacements + $newKey = is_string($key) ? $this->replace($key, $keys) : $key; + + // Keep original values with original key, if the key has changed, but only at the top-level. + if (empty($keys) && $newKey !== $key) { + $rewritten[$key] = $value; + } + + // Perform value replacements, if any + $newValue = $this->replace($value, $keys, $newKey); + + // Key does not already exist and/or is not an array value + if (! array_key_exists($newKey, $rewritten) || ! is_array($rewritten[$newKey])) { + // Do not overwrite existing values with null values + $rewritten[$newKey] = array_key_exists($newKey, $rewritten) && null === $newValue + ? $rewritten[$newKey] + : $newValue; + continue; + } + + // New value is null; nothing to do. + if (null === $newValue) { + continue; + } + + // Key already exists as an array value, but $value is not an array + if (! is_array($newValue)) { + $rewritten[$newKey][] = $newValue; + continue; + } + + // Key already exists as an array value, and $value is also an array + $rewritten[$newKey] = static::merge($rewritten[$newKey], $newValue); + } + + return $rewritten; + } + + /** + * Perform substitutions as needed on an individual value. + * + * The $key is provided to allow fine-grained selection of rewrite rules. + * + * @param mixed $value + * @param string[] $keys Key hierarchy + * @param null|int|string $key + * @return mixed + */ + private function replace($value, array $keys, $key = null) + { + // Add new key to the list of keys. + // We do not need to remove it later, as we are working on a copy of the array. + array_push($keys, $key); + + // Identify rewrite strategy and perform replacements + $rewriteRule = $this->replacementRuleMatch($value, $keys); + return $rewriteRule($value, $keys); + } + + /** + * Merge two arrays together. + * + * If an integer key exists in both arrays, the value from the second array + * will be appended to the first array. If both values are arrays, they are + * merged together, else the value of the second array overwrites the one + * of the first array. + * + * Based on zend-stdlib Zend\Stdlib\ArrayUtils::merge + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * + * @return array + */ + public static function merge(array $a, array $b) + { + foreach ($b as $key => $value) { + if (! isset($a[$key]) && ! array_key_exists($key, $a)) { + $a[$key] = $value; + continue; + } + + if (null === $value && array_key_exists($key, $a)) { + // Leave as-is if value from $b is null + continue; + } + + if (is_int($key)) { + $a[] = $value; + continue; + } + + if (is_array($value) && is_array($a[$key])) { + $a[$key] = static::merge($a[$key], $value); + continue; + } + + $a[$key] = $value; + } + + return $a; + } + + /** + * @param mixed $value + * @param null|int|string $key + * @return callable Callable to invoke with value + */ + private function replacementRuleMatch($value, $key = null) + { + foreach ($this->rulesets as $ruleset) { + $result = $ruleset($value, $key); + if (is_callable($result)) { + return $result; + } + } + return [$this, 'fallbackReplacement']; + } + + /** + * Replace a value using the translation table, if the value is a string. + * + * @param mixed $value + * @return mixed + */ + private function fallbackReplacement($value) + { + return is_string($value) + ? $this->replacements->replace($value) + : $value; + } + + /** + * Replace a value matched exactly. + * + * @param mixed $value + * @return mixed + */ + private function replaceExactValue($value) + { + return $this->exactReplacements[$value]; + } + + private function replaceDependencyConfiguration(array $config) + { + $aliases = isset($config['aliases']) && is_array($config['aliases']) + ? $this->replaceDependencyAliases($config['aliases']) + : []; + + if ($aliases) { + $config['aliases'] = $aliases; + } + + $config = $this->replaceDependencyInvokables($config); + $config = $this->replaceDependencyFactories($config); + $config = $this->replaceDependencyServices($config); + + $keys = self::SERVICE_MANAGER_KEYS_OF_INTEREST; + foreach ($config as $key => $data) { + if (isset($keys[$key])) { + continue; + } + + $config[$key] = is_array($data) ? $this->__invoke($data, [$key]) : $data; + } + + return $config; + } + + /** + * Rewrite dependency aliases array + * + * In this case, we want to keep the alias as-is, but rewrite the target. + * + * We need also provide an additional alias if the alias key is a legacy class. + * + * @return array + */ + private function replaceDependencyAliases(array $aliases) + { + foreach ($aliases as $alias => $target) { + if (! is_string($alias) || ! is_string($target)) { + continue; + } + + $newTarget = $this->replacements->replace($target); + $newAlias = $this->replacements->replace($alias); + + $notIn = [$newTarget]; + $name = $newTarget; + while (isset($aliases[$name])) { + $notIn[] = $aliases[$name]; + $name = $aliases[$name]; + } + + if ($newAlias === $alias && ! in_array($alias, $notIn, true)) { + $aliases[$alias] = $newTarget; + continue; + } + + if (isset($aliases[$newAlias])) { + continue; + } + + if (! in_array($newAlias, $notIn, true)) { + $aliases[$alias] = $newAlias; + $aliases[$newAlias] = $newTarget; + } + } + + return $aliases; + } + + /** + * Rewrite dependency invokables array + * + * In this case, we want to keep the alias as-is, but rewrite the target. + * + * We need also provide an additional alias if invokable is defined with + * an alias which is a legacy class. + * + * @return array + */ + private function replaceDependencyInvokables(array $config) + { + if (empty($config['invokables']) || ! is_array($config['invokables'])) { + return $config; + } + + foreach ($config['invokables'] as $alias => $target) { + if (! is_string($alias)) { + continue; + } + + $newTarget = $this->replacements->replace($target); + $newAlias = $this->replacements->replace($alias); + + if ($alias === $target || isset($config['aliases'][$newAlias])) { + $config['invokables'][$alias] = $newTarget; + continue; + } + + $config['invokables'][$newAlias] = $newTarget; + + if ($newAlias === $alias) { + continue; + } + + $config['aliases'][$alias] = $newAlias; + + unset($config['invokables'][$alias]); + } + + return $config; + } + + /** + * @param mixed $value + * @return mixed Returns $value verbatim. + */ + private function noopReplacement($value) + { + return $value; + } + + private function replaceDependencyFactories(array $config) + { + if (empty($config['factories']) || ! is_array($config['factories'])) { + return $config; + } + + foreach ($config['factories'] as $service => $factory) { + if (! is_string($service)) { + continue; + } + + $replacedService = $this->replacements->replace($service); + $factory = is_string($factory) ? $this->replacements->replace($factory) : $factory; + $config['factories'][$replacedService] = $factory; + + if ($replacedService === $service) { + continue; + } + + unset($config['factories'][$service]); + if (isset($config['aliases'][$service])) { + continue; + } + + $config['aliases'][$service] = $replacedService; + } + + return $config; + } + + private function replaceDependencyServices(array $config) + { + if (empty($config['services']) || ! is_array($config['services'])) { + return $config; + } + + foreach ($config['services'] as $service => $serviceInstance) { + if (! is_string($service)) { + continue; + } + + $replacedService = $this->replacements->replace($service); + $serviceInstance = is_array($serviceInstance) ? $this->__invoke($serviceInstance) : $serviceInstance; + + $config['services'][$replacedService] = $serviceInstance; + + if ($service === $replacedService) { + continue; + } + + unset($config['services'][$service]); + + if (isset($config['aliases'][$service])) { + continue; + } + + $config['aliases'][$service] = $replacedService; + } + + return $config; + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/src/Module.php b/vendor/laminas/laminas-zendframework-bridge/src/Module.php new file mode 100644 index 0000000..d10cb43 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/Module.php @@ -0,0 +1,54 @@ +getEventManager() + ->attach('mergeConfig', [$this, 'onMergeConfig']); + } + + /** + * Perform substitutions in the merged configuration. + * + * Rewrites keys and values matching known ZF classes, namespaces, and + * configuration keys to their Laminas equivalents. + * + * Type-hinting deliberately omitted to allow unit testing + * without dependencies on packages that do not exist yet. + * + * @param ModuleEvent $event + */ + public function onMergeConfig($event) + { + /** @var ConfigMergerInterface */ + $configMerger = $event->getConfigListener(); + $processor = new ConfigPostProcessor(); + $configMerger->setMergedConfig( + $processor( + $configMerger->getMergedConfig($returnAsObject = false) + ) + ); + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/src/Replacements.php b/vendor/laminas/laminas-zendframework-bridge/src/Replacements.php new file mode 100644 index 0000000..ca445c0 --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/Replacements.php @@ -0,0 +1,46 @@ +replacements = array_merge( + require __DIR__ . '/../config/replacements.php', + $additionalReplacements + ); + + // Provide multiple variants of strings containing namespace separators + foreach ($this->replacements as $original => $replacement) { + if (false === strpos($original, '\\')) { + continue; + } + $this->replacements[str_replace('\\', '\\\\', $original)] = str_replace('\\', '\\\\', $replacement); + $this->replacements[str_replace('\\', '\\\\\\\\', $original)] = str_replace('\\', '\\\\\\\\', $replacement); + } + } + + /** + * @param string $value + * @return string + */ + public function replace($value) + { + return strtr($value, $this->replacements); + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php b/vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php new file mode 100644 index 0000000..8dc999f --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php @@ -0,0 +1,79 @@ + 'Mezzio\\ProblemDetails\\', + 'Zend\\Expressive\\' => 'Mezzio\\', + + // Laminas + 'Zend\\' => 'Laminas\\', + 'ZF\\ComposerAutoloading\\' => 'Laminas\\ComposerAutoloading\\', + 'ZF\\DevelopmentMode\\' => 'Laminas\\DevelopmentMode\\', + + // Apigility + 'ZF\\Apigility\\' => 'Laminas\\ApiTools\\', + 'ZF\\' => 'Laminas\\ApiTools\\', + + // ZendXml, API wrappers, zend-http OAuth support, zend-diagnostics, ZendDeveloperTools + 'ZendXml\\' => 'Laminas\\Xml\\', + 'ZendOAuth\\' => 'Laminas\\OAuth\\', + 'ZendDiagnostics\\' => 'Laminas\\Diagnostics\\', + 'ZendService\\ReCaptcha\\' => 'Laminas\\ReCaptcha\\', + 'ZendService\\Twitter\\' => 'Laminas\\Twitter\\', + 'ZendDeveloperTools\\' => 'Laminas\\DeveloperTools\\', + ]; + } + + /** + * @return array + */ + public static function namespaceReverse() + { + return [ + // ZendXml, ZendOAuth, ZendDiagnostics, ZendDeveloperTools + 'Laminas\\Xml\\' => 'ZendXml\\', + 'Laminas\\OAuth\\' => 'ZendOAuth\\', + 'Laminas\\Diagnostics\\' => 'ZendDiagnostics\\', + 'Laminas\\DeveloperTools\\' => 'ZendDeveloperTools\\', + + // Zend Service + 'Laminas\\ReCaptcha\\' => 'ZendService\\ReCaptcha\\', + 'Laminas\\Twitter\\' => 'ZendService\\Twitter\\', + + // Zend + 'Laminas\\' => 'Zend\\', + + // Expressive + 'Mezzio\\ProblemDetails\\' => 'Zend\\ProblemDetails\\', + 'Mezzio\\' => 'Zend\\Expressive\\', + + // Laminas to ZfCampus + 'Laminas\\ComposerAutoloading\\' => 'ZF\\ComposerAutoloading\\', + 'Laminas\\DevelopmentMode\\' => 'ZF\\DevelopmentMode\\', + + // Apigility + 'Laminas\\ApiTools\\Admin\\' => 'ZF\\Apigility\\Admin\\', + 'Laminas\\ApiTools\\Doctrine\\' => 'ZF\\Apigility\\Doctrine\\', + 'Laminas\\ApiTools\\Documentation\\' => 'ZF\\Apigility\\Documentation\\', + 'Laminas\\ApiTools\\Example\\' => 'ZF\\Apigility\\Example\\', + 'Laminas\\ApiTools\\Provider\\' => 'ZF\\Apigility\\Provider\\', + 'Laminas\\ApiTools\\Welcome\\' => 'ZF\\Apiglity\\Welcome\\', + 'Laminas\\ApiTools\\' => 'ZF\\', + ]; + } +} diff --git a/vendor/laminas/laminas-zendframework-bridge/src/autoload.php b/vendor/laminas/laminas-zendframework-bridge/src/autoload.php new file mode 100644 index 0000000..9f2f2ad --- /dev/null +++ b/vendor/laminas/laminas-zendframework-bridge/src/autoload.php @@ -0,0 +1,9 @@ + 5.3.2 + + +0.11.1 (2011-12-04) +------------------- + + * fixed issue #28: `mkdir()` overwrites existing directories/files + + +0.11.0 (2011-11-29) +------------------- + + * implemented issue #20: `vfsStream::create()` removes old structure + * implemented issue #4: possibility to copy structure from existing file system + * fixed issue #23: `unlink()` should not remove any directory + * fixed issue #25: `vfsStreamDirectory::hasChild()` gives false positives for nested paths, patch provided by Andrew Coulton + * fixed issue #26: opening a file for reading only should not update its modification time, reported and initial patch provided by Ludovic Chabant + + +0.10.1 (2011-08-22) +------------------- + + * fixed issue #16: replace `vfsStreamContent` to `vfsStreamContainer` for autocompletion + * fixed issue #17: `vfsStream::create()` has issues with numeric directories, patch provided by mathieuk + + +0.10.0 (2011-07-22) +------------------- + + * added new method `vfsStreamContainer::hasChildren()` and `vfsStreamDirectory::hasChildren()` + * implemented issue #14: less verbose way to initialize vfsStream + * implemented issue #13: remove deprecated method `vfsStreamContent::setFilemtime()` + * implemented issue #6: locking meachanism for files + * ensured that `stream_set_blocking()`, `stream_set_timeout()` and `stream_set_write_buffer()` on vfsStream urls have the same behaviour with PHP 5.2 and 5.3 + * implemented issue #10: method to print directory structure + + +0.9.0 (2011-07-13) +------------------ + + * implemented feature request issue #7: add support for `fileatime()` and `filectime()` + * fixed issue #3: add support for `streamWrapper::stream_cast()` + * fixed issue #9: resolve path not called everywhere its needed + * deprecated `vfsStreamAbstractContent::setFilemtime()`, use `vfsStreamAbstractContent::lastModified()` instead, will be removed with 0.10.0 + + +0.8.0 (2010-10-08) +------------------ + + * implemented enhancement #6: use `vfsStream::umask()` to influence initial file mode for files and directories + * implemented enhancement #19: support of .. in the url, patch provided by Guislain Duthieuw + * fixed issue #18: `getChild()` returns NULL when child's name contains parent name + * fixed bug with incomplete error message when accessing non-existing files on root level + + +0.7.0 (2010-06-08) +------------------ + + * added new `vfsStream::setup()` method to simplify vfsStream usage + * fixed issue #15: `mkdir()` creates a subfolder in a folder without permissions + + +0.6.0 (2010-02-15) +------------------ + + * added support for `$mode` param when opening files, implements enhancement #7 and fixes issue #13 + * `vfsStreamWrapper::stream_open()` now evaluates `$options` for `STREAM_REPORT_ERRORS` + + +0.5.0 (2010-01-25) +------------------ + + * added support for `rename()`, patch provided by Benoit Aubuchon + * added support for . as directory alias so that `vfs://foo/.` resolves to `vfs://foo`, can be used as workaround for bug #8 + + +0.4.0 (2009-07-13) +------------------ + + * added support for file modes, users and groups (with restrictions, see http://code.google.com/p/bovigo/wiki/vfsStreamDocsKnownIssues) + * fixed bug #5: `vfsStreamDirectory::addChild()` does not replace child with same name + * fixed bug with `is_writable()` because of missing `stat()` fields, patch provided by Sergey Galkin + + +0.3.2 (2009-02-16) +------------------ + + * support trailing slashes on directories in vfsStream urls, patch provided by Gabriel Birke + * fixed bug #4: vfsstream can only be read once, reported by Christoph Bloemer + * enabled multiple iterations at the same time over the same directory + + +0.3.1 (2008-02-18) +------------------ + + * fixed path/directory separator issues under linux systems + * fixed uid/gid issues under linux systems + + +0.3.0 (2008-01-02) +------------------ + + * added support for `rmdir()` + * added `vfsStream::newDirectory()`, dropped `vfsStreamDirectory::ceate()` + * added new interface `vfsStreamContainer` + * added `vfsStreamContent::at()` which allows code like `$file = vfsStream::newFile('file.txt.')->withContent('foo')->at($otherDir);` + * added `vfsStreamContent::lastModified()`, made `vfsStreamContent::setFilemtime()` an alias for this + * moved from Stubbles development environment to bovigo + * refactorings to reduce crap index of various methods + + +0.2.0 (2007-12-29) +------------------ + + * moved `vfsStreamWrapper::PROTOCOL` to `vfsStream::SCHEME` + * added new `vfsStream::url()` method to assist in creating correct vfsStream urls + * added `vfsStream::path()` method as opposite to `vfsStream::url()` + * a call to `vfsStreamWrapper::register()` will now reset the root to null, implemented on request from David Zuelke + * added support for `is_readable()`, `is_dir()`, `is_file()` + * added `vfsStream::newFile()` to be able to do `$file = vfsStream::newFile("foo.txt")->withContent("bar");` + + +0.1.0 (2007-12-14) +------------------ + + * Initial release. diff --git a/vendor/mikey179/vfsstream/LICENSE b/vendor/mikey179/vfsstream/LICENSE new file mode 100644 index 0000000..1d41ab9 --- /dev/null +++ b/vendor/mikey179/vfsstream/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2007-2015, Frank Kleine +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 Stubbles 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. diff --git a/vendor/mikey179/vfsstream/README.md b/vendor/mikey179/vfsstream/README.md new file mode 100644 index 0000000..a1b47ee --- /dev/null +++ b/vendor/mikey179/vfsstream/README.md @@ -0,0 +1,8 @@ +You can find documentation in the [wiki](https://github.com/mikey179/vfsStream/wiki). + +Also you might want to check [vfsStream examples](https://github.com/mikey179/vfsStream-examples). + + +[![Build Status](https://secure.travis-ci.org/mikey179/vfsStream.png)](http://travis-ci.org/mikey179/vfsStream) [![Build Status Windows](https://ci.appveyor.com/api/projects/status/6whqgluyeggspjp1/branch/master?svg=true)](https://ci.appveyor.com/project/mikey179/vfsstream) [![Coverage Status](https://coveralls.io/repos/github/bovigo/vfsStream/badge.svg?branch=v1.x)](https://coveralls.io/github/bovigo/vfsStream?branch=v1.x) + +[![Latest Stable Version](https://poser.pugx.org/mikey179/vfsStream/version.png)](https://packagist.org/packages/mikey179/vfsStream) [![Latest Unstable Version](https://poser.pugx.org/mikey179/vfsStream/v/unstable.png)](//packagist.org/packages/mikey179/vfsStream) diff --git a/vendor/mikey179/vfsstream/appveyor.yml b/vendor/mikey179/vfsstream/appveyor.yml new file mode 100644 index 0000000..e7fdf00 --- /dev/null +++ b/vendor/mikey179/vfsstream/appveyor.yml @@ -0,0 +1,22 @@ +build: false +shallow_clone: true + +cache: + - .\php -> appveyor.yml + +init: + - set PATH=%PATH%;.\php + - set COMPOSER_NO_INTERACTION=1 + - set CACHED=0 + +install: + - if exist .\php (set CACHED=1) else (mkdir .\php) + - if %CACHED%==0 cd .\php + - if %CACHED%==0 curl --fail --location --silent --show-error -o php.zip https://windows.php.net/downloads/releases/archives/php-7.0.7-nts-Win32-VC14-x64.zip + - if %CACHED%==0 appveyor DownloadFile https://getcomposer.org/composer.phar + - if %CACHED%==0 7z x php.zip -y + - if %CACHED%==0 cd .. + +test_script: + - php -d extension_dir=.\php\ext -d extension=php_openssl.dll .\php\composer.phar install + - vendor/bin/phpunit.bat --coverage-text diff --git a/vendor/mikey179/vfsstream/composer.json b/vendor/mikey179/vfsstream/composer.json new file mode 100644 index 0000000..9d1f3f0 --- /dev/null +++ b/vendor/mikey179/vfsstream/composer.json @@ -0,0 +1,33 @@ +{ + "name": "mikey179/vfsstream", + "type": "library", + "homepage": "http://vfs.bovigo.org/", + "description": "Virtual file system to mock the real file system in unit tests.", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Frank Kleine", + "homepage": "http://frankkleine.de/", + "role": "Developer" + } + ], + "support": { + "issues": "https://github.com/bovigo/vfsStream/issues", + "source": "https://github.com/bovigo/vfsStream/tree/master", + "wiki": "https://github.com/bovigo/vfsStream/wiki" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.5|^5.0" + }, + "autoload": { + "psr-0": { "org\\bovigo\\vfs\\": "src/main/php" } + }, + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + } +} diff --git a/vendor/mikey179/vfsstream/phpunit.xml.dist b/vendor/mikey179/vfsstream/phpunit.xml.dist new file mode 100644 index 0000000..1e6720a --- /dev/null +++ b/vendor/mikey179/vfsstream/phpunit.xml.dist @@ -0,0 +1,44 @@ + + + + + ./src/test/phpt + ./src/test/php + + + + + + src/main/php + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/DotDirectory.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/DotDirectory.php new file mode 100644 index 0000000..b17b979 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/DotDirectory.php @@ -0,0 +1,35 @@ +amount = $amount; + } + + /** + * create with unlimited space + * + * @return Quota + */ + public static function unlimited() + { + return new self(self::UNLIMITED); + } + + /** + * checks if a quota is set + * + * @return bool + */ + public function isLimited() + { + return self::UNLIMITED < $this->amount; + } + + /** + * checks if given used space exceeda quota limit + * + * + * @param int $usedSpace + * @return int + */ + public function spaceLeft($usedSpace) + { + if (self::UNLIMITED === $this->amount) { + return $usedSpace; + } + + if ($usedSpace >= $this->amount) { + return 0; + } + + $spaceLeft = $this->amount - $usedSpace; + if (0 >= $spaceLeft) { + return 0; + } + + return $spaceLeft; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/FileContent.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/FileContent.php new file mode 100644 index 0000000..606fe5e --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/FileContent.php @@ -0,0 +1,71 @@ +size = $size; + } + + /** + * create large file with given size in kilobyte + * + * @param int $kilobyte + * @return LargeFileContent + */ + public static function withKilobytes($kilobyte) + { + return new self($kilobyte * 1024); + } + + /** + * create large file with given size in megabyte + * + * @param int $megabyte + * @return LargeFileContent + */ + public static function withMegabytes($megabyte) + { + return self::withKilobytes($megabyte * 1024); + } + + /** + * create large file with given size in gigabyte + * + * @param int $gigabyte + * @return LargeFileContent + */ + public static function withGigabytes($gigabyte) + { + return self::withMegabytes($gigabyte * 1024); + } + + /** + * returns actual content + * + * @return string + */ + public function content() + { + return $this->doRead(0, $this->size); + } + + /** + * returns size of content + * + * @return int + */ + public function size() + { + return $this->size; + } + + /** + * actual reading of given byte count starting at given offset + * + * @param int $offset + * @param int $count + */ + protected function doRead($offset, $count) + { + if (($offset + $count) > $this->size) { + $count = $this->size - $offset; + } + + $result = ''; + for ($i = 0; $i < $count; $i++) { + if (isset($this->content[$i + $offset])) { + $result .= $this->content[$i + $offset]; + } else { + $result .= ' '; + } + } + + return $result; + } + + /** + * actual writing of data with specified length at given offset + * + * @param string $data + * @param int $offset + * @param int $length + */ + protected function doWrite($data, $offset, $length) + { + for ($i = 0; $i < $length; $i++) { + $this->content[$i + $offset] = substr($data, $i, 1); + } + + if ($offset >= $this->size) { + $this->size += $length; + } elseif (($offset + $length) > $this->size) { + $this->size = $offset + $length; + } + } + + /** + * Truncates a file to a given length + * + * @param int $size length to truncate file to + * @return bool + */ + public function truncate($size) + { + $this->size = $size; + foreach (array_filter(array_keys($this->content), + function($pos) use ($size) + { + return $pos >= $size; + } + ) as $removePos) { + unset($this->content[$removePos]); + } + + return true; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/SeekableFileContent.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/SeekableFileContent.php new file mode 100644 index 0000000..e4c3d9b --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/SeekableFileContent.php @@ -0,0 +1,134 @@ +doRead($this->offset, $count); + $this->offset += $count; + return $data; + } + + /** + * actual reading of given byte count starting at given offset + * + * @param int $offset + * @param int $count + */ + protected abstract function doRead($offset, $count); + + /** + * seeks to the given offset + * + * @param int $offset + * @param int $whence + * @return bool + */ + public function seek($offset, $whence) + { + $newOffset = $this->offset; + switch ($whence) { + case SEEK_CUR: + $newOffset += $offset; + break; + + case SEEK_END: + $newOffset = $this->size() + $offset; + break; + + case SEEK_SET: + $newOffset = $offset; + break; + + default: + return false; + } + + if ($newOffset<0) { + return false; + } + $this->offset = $newOffset; + return true; + } + + /** + * checks whether pointer is at end of file + * + * @return bool + */ + public function eof() + { + return $this->size() <= $this->offset; + } + + /** + * writes an amount of data + * + * @param string $data + * @return amount of written bytes + */ + public function write($data) + { + $dataLength = strlen($data); + $this->doWrite($data, $this->offset, $dataLength); + $this->offset += $dataLength; + return $dataLength; + } + + /** + * actual writing of data with specified length at given offset + * + * @param string $data + * @param int $offset + * @param int $length + */ + protected abstract function doWrite($data, $offset, $length); + + /** + * for backwards compatibility with vfsStreamFile::bytesRead() + * + * @return int + * @deprecated + */ + public function bytesRead() + { + return $this->offset; + } + + /** + * for backwards compatibility with vfsStreamFile::readUntilEnd() + * + * @return string + * @deprecated + */ + public function readUntilEnd() + { + return substr($this->content(), $this->offset); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/StringBasedFileContent.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/StringBasedFileContent.php new file mode 100644 index 0000000..77adf8e --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/content/StringBasedFileContent.php @@ -0,0 +1,97 @@ +content = $content; + } + + /** + * returns actual content + * + * @return string + */ + public function content() + { + return $this->content; + } + + /** + * returns size of content + * + * @return int + */ + public function size() + { + return strlen($this->content); + } + + /** + * actual reading of length starting at given offset + * + * @param int $offset + * @param int $count + */ + protected function doRead($offset, $count) + { + return (string) substr($this->content, $offset, $count); + } + + /** + * actual writing of data with specified length at given offset + * + * @param string $data + * @param int $offset + * @param int $length + */ + protected function doWrite($data, $offset, $length) + { + $this->content = substr($this->content, 0, $offset) + . $data + . substr($this->content, $offset + $length); + } + + /** + * Truncates a file to a given length + * + * @param int $size length to truncate file to + * @return bool + */ + public function truncate($size) + { + if ($size > $this->size()) { + // Pad with null-chars if we're "truncating up" + $this->content .= str_repeat("\0", $size - $this->size()); + } else { + $this->content = substr($this->content, 0, $size); + } + + return true; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php new file mode 100644 index 0000000..1eb382d --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStream.php @@ -0,0 +1,479 @@ + + * array('Core' = array('AbstractFactory' => array('test.php' => 'some text content', + * 'other.php' => 'Some more text content', + * 'Invalid.csv' => 'Something else', + * ), + * 'AnEmptyFolder' => array(), + * 'badlocation.php' => 'some bad content', + * ) + * ) + * + * the resulting directory tree will look like this: + *
+     * root
+     * \- Core
+     *  |- badlocation.php
+     *  |- AbstractFactory
+     *  | |- test.php
+     *  | |- other.php
+     *  | \- Invalid.csv
+     *  \- AnEmptyFolder
+     * 
+ * Arrays will become directories with their key as directory name, and + * strings becomes files with their key as file name and their value as file + * content. + * + * @param string $rootDirName name of root directory + * @param int $permissions file permissions of root directory + * @param array $structure directory structure to add under root directory + * @return \org\bovigo\vfs\vfsStreamDirectory + * @since 0.7.0 + * @see https://github.com/mikey179/vfsStream/issues/14 + * @see https://github.com/mikey179/vfsStream/issues/20 + */ + public static function setup($rootDirName = 'root', $permissions = null, array $structure = array()) + { + vfsStreamWrapper::register(); + return self::create($structure, vfsStreamWrapper::setRoot(self::newDirectory($rootDirName, $permissions))); + } + + /** + * creates vfsStream directory structure from an array and adds it to given base dir + * + * Assumed $structure contains an array like this: + * + * array('Core' = array('AbstractFactory' => array('test.php' => 'some text content', + * 'other.php' => 'Some more text content', + * 'Invalid.csv' => 'Something else', + * ), + * 'AnEmptyFolder' => array(), + * 'badlocation.php' => 'some bad content', + * ) + * ) + * + * the resulting directory tree will look like this: + *
+     * baseDir
+     * \- Core
+     *  |- badlocation.php
+     *  |- AbstractFactory
+     *  | |- test.php
+     *  | |- other.php
+     *  | \- Invalid.csv
+     *  \- AnEmptyFolder
+     * 
+ * Arrays will become directories with their key as directory name, and + * strings becomes files with their key as file name and their value as file + * content. + * + * If no baseDir is given it will try to add the structure to the existing + * root directory without replacing existing childs except those with equal + * names. + * + * @param array $structure directory structure to add under root directory + * @param vfsStreamDirectory $baseDir base directory to add structure to + * @return vfsStreamDirectory + * @throws \InvalidArgumentException + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/14 + * @see https://github.com/mikey179/vfsStream/issues/20 + */ + public static function create(array $structure, vfsStreamDirectory $baseDir = null) + { + if (null === $baseDir) { + $baseDir = vfsStreamWrapper::getRoot(); + } + + if (null === $baseDir) { + throw new \InvalidArgumentException('No baseDir given and no root directory set.'); + } + + return self::addStructure($structure, $baseDir); + } + + /** + * helper method to create subdirectories recursively + * + * @param array $structure subdirectory structure to add + * @param vfsStreamDirectory $baseDir directory to add the structure to + * @return vfsStreamDirectory + */ + protected static function addStructure(array $structure, vfsStreamDirectory $baseDir) + { + foreach ($structure as $name => $data) { + $name = (string) $name; + if (is_array($data) === true) { + self::addStructure($data, self::newDirectory($name)->at($baseDir)); + } elseif (is_string($data) === true) { + $matches = null; + preg_match('/^\[(.*)\]$/', $name, $matches); + if ($matches !== array()) { + self::newBlock($matches[1])->withContent($data)->at($baseDir); + } else { + self::newFile($name)->withContent($data)->at($baseDir); + } + } elseif ($data instanceof FileContent) { + self::newFile($name)->withContent($data)->at($baseDir); + } elseif ($data instanceof vfsStreamFile) { + $baseDir->addChild($data); + } + } + + return $baseDir; + } + + /** + * copies the file system structure from given path into the base dir + * + * If no baseDir is given it will try to add the structure to the existing + * root directory without replacing existing childs except those with equal + * names. + * File permissions are copied as well. + * Please note that file contents will only be copied if their file size + * does not exceed the given $maxFileSize which defaults to 1024 KB. In case + * the file is larger file content will be mocked, see + * https://github.com/mikey179/vfsStream/wiki/MockingLargeFiles. + * + * @param string $path path to copy the structure from + * @param vfsStreamDirectory $baseDir directory to add the structure to + * @param int $maxFileSize maximum file size of files to copy content from + * @return vfsStreamDirectory + * @throws \InvalidArgumentException + * @since 0.11.0 + * @see https://github.com/mikey179/vfsStream/issues/4 + */ + public static function copyFromFileSystem($path, vfsStreamDirectory $baseDir = null, $maxFileSize = 1048576) + { + if (null === $baseDir) { + $baseDir = vfsStreamWrapper::getRoot(); + } + + if (null === $baseDir) { + throw new \InvalidArgumentException('No baseDir given and no root directory set.'); + } + + $dir = new \DirectoryIterator($path); + foreach ($dir as $fileinfo) { + switch (filetype($fileinfo->getPathname())) { + case 'file': + if ($fileinfo->getSize() <= $maxFileSize) { + $content = file_get_contents($fileinfo->getPathname()); + } else { + $content = new LargeFileContent($fileinfo->getSize()); + } + + self::newFile( + $fileinfo->getFilename(), + octdec(substr(sprintf('%o', $fileinfo->getPerms()), -4)) + ) + ->withContent($content) + ->at($baseDir); + break; + + case 'dir': + if (!$fileinfo->isDot()) { + self::copyFromFileSystem( + $fileinfo->getPathname(), + self::newDirectory( + $fileinfo->getFilename(), + octdec(substr(sprintf('%o', $fileinfo->getPerms()), -4)) + )->at($baseDir), + $maxFileSize + ); + } + + break; + + case 'block': + self::newBlock( + $fileinfo->getFilename(), + octdec(substr(sprintf('%o', $fileinfo->getPerms()), -4)) + )->at($baseDir); + break; + } + } + + return $baseDir; + } + + /** + * returns a new file with given name + * + * @param string $name name of file to create + * @param int $permissions permissions of file to create + * @return vfsStreamFile + */ + public static function newFile($name, $permissions = null) + { + return new vfsStreamFile($name, $permissions); + } + + /** + * returns a new directory with given name + * + * If the name contains slashes, a new directory structure will be created. + * The returned directory will always be the parent directory of this + * directory structure. + * + * @param string $name name of directory to create + * @param int $permissions permissions of directory to create + * @return vfsStreamDirectory + */ + public static function newDirectory($name, $permissions = null) + { + if ('/' === substr($name, 0, 1)) { + $name = substr($name, 1); + } + + $firstSlash = strpos($name, '/'); + if (false === $firstSlash) { + return new vfsStreamDirectory($name, $permissions); + } + + $ownName = substr($name, 0, $firstSlash); + $subDirs = substr($name, $firstSlash + 1); + $directory = new vfsStreamDirectory($ownName, $permissions); + if (is_string($subDirs) && strlen($subDirs) > 0) { + self::newDirectory($subDirs, $permissions)->at($directory); + } + + return $directory; + } + + /** + * returns a new block with the given name + * + * @param string $name name of the block device + * @param int $permissions permissions of block to create + * @return vfsStreamBlock + */ + public static function newBlock($name, $permissions = null) + { + return new vfsStreamBlock($name, $permissions); + } + + /** + * returns current user + * + * If the system does not support posix_getuid() the current user will be root (0). + * + * @return int + */ + public static function getCurrentUser() + { + return function_exists('posix_getuid') ? posix_getuid() : self::OWNER_ROOT; + } + + /** + * returns current group + * + * If the system does not support posix_getgid() the current group will be root (0). + * + * @return int + */ + public static function getCurrentGroup() + { + return function_exists('posix_getgid') ? posix_getgid() : self::GROUP_ROOT; + } + + /** + * use visitor to inspect a content structure + * + * If the given content is null it will fall back to use the current root + * directory of the stream wrapper. + * + * Returns given visitor for method chaining comfort. + * + * @param vfsStreamVisitor $visitor the visitor who inspects + * @param vfsStreamContent $content directory structure to inspect + * @return vfsStreamVisitor + * @throws \InvalidArgumentException + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/10 + */ + public static function inspect(vfsStreamVisitor $visitor, vfsStreamContent $content = null) + { + if (null !== $content) { + return $visitor->visit($content); + } + + $root = vfsStreamWrapper::getRoot(); + if (null === $root) { + throw new \InvalidArgumentException('No content given and no root directory set.'); + } + + return $visitor->visitDirectory($root); + } + + /** + * sets quota to given amount of bytes + * + * @param int $bytes + * @since 1.1.0 + */ + public static function setQuota($bytes) + { + vfsStreamWrapper::setQuota(new Quota($bytes)); + } + + /** + * checks if vfsStream lists dotfiles in directory listings + * + * @return bool + * @since 1.3.0 + */ + public static function useDotfiles() + { + return self::$dotFiles; + } + + /** + * disable dotfiles in directory listings + * + * @since 1.3.0 + */ + public static function disableDotfiles() + { + self::$dotFiles = false; + } + + /** + * enable dotfiles in directory listings + * + * @since 1.3.0 + */ + public static function enableDotfiles() + { + self::$dotFiles = true; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamAbstractContent.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamAbstractContent.php new file mode 100644 index 0000000..7db2be2 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamAbstractContent.php @@ -0,0 +1,418 @@ +name = "{$name}"; + $time = time(); + if (null === $permissions) { + $permissions = $this->getDefaultPermissions() & ~vfsStream::umask(); + } + + $this->lastAccessed = $time; + $this->lastAttributeModified = $time; + $this->lastModified = $time; + $this->permissions = $permissions; + $this->user = vfsStream::getCurrentUser(); + $this->group = vfsStream::getCurrentGroup(); + } + + /** + * returns default permissions for concrete implementation + * + * @return int + * @since 0.8.0 + */ + protected abstract function getDefaultPermissions(); + + /** + * returns the file name of the content + * + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * renames the content + * + * @param string $newName + */ + public function rename($newName) + { + $this->name = "{$newName}"; + } + + /** + * checks whether the container can be applied to given name + * + * @param string $name + * @return bool + */ + public function appliesTo($name) + { + if ($name === $this->name) { + return true; + } + + $segment_name = $this->name.'/'; + return (strncmp($segment_name, $name, strlen($segment_name)) == 0); + } + + /** + * returns the type of the container + * + * @return int + */ + public function getType() + { + return $this->type; + } + + /** + * sets the last modification time of the stream content + * + * @param int $filemtime + * @return $this + */ + public function lastModified($filemtime) + { + $this->lastModified = $filemtime; + return $this; + } + + /** + * returns the last modification time of the stream content + * + * @return int + */ + public function filemtime() + { + return $this->lastModified; + } + + /** + * sets last access time of the stream content + * + * @param int $fileatime + * @return $this + * @since 0.9 + */ + public function lastAccessed($fileatime) + { + $this->lastAccessed = $fileatime; + return $this; + } + + /** + * returns the last access time of the stream content + * + * @return int + * @since 0.9 + */ + public function fileatime() + { + return $this->lastAccessed; + } + + /** + * sets the last attribute modification time of the stream content + * + * @param int $filectime + * @return $this + * @since 0.9 + */ + public function lastAttributeModified($filectime) + { + $this->lastAttributeModified = $filectime; + return $this; + } + + /** + * returns the last attribute modification time of the stream content + * + * @return int + * @since 0.9 + */ + public function filectime() + { + return $this->lastAttributeModified; + } + + /** + * adds content to given container + * + * @param vfsStreamContainer $container + * @return $this + */ + public function at(vfsStreamContainer $container) + { + $container->addChild($this); + return $this; + } + + /** + * change file mode to given permissions + * + * @param int $permissions + * @return $this + */ + public function chmod($permissions) + { + $this->permissions = $permissions; + $this->lastAttributeModified = time(); + clearstatcache(); + return $this; + } + + /** + * returns permissions + * + * @return int + */ + public function getPermissions() + { + return $this->permissions; + } + + /** + * checks whether content is readable + * + * @param int $user id of user to check for + * @param int $group id of group to check for + * @return bool + */ + public function isReadable($user, $group) + { + if ($this->user === $user) { + $check = 0400; + } elseif ($this->group === $group) { + $check = 0040; + } else { + $check = 0004; + } + + return (bool) ($this->permissions & $check); + } + + /** + * checks whether content is writable + * + * @param int $user id of user to check for + * @param int $group id of group to check for + * @return bool + */ + public function isWritable($user, $group) + { + if ($this->user === $user) { + $check = 0200; + } elseif ($this->group === $group) { + $check = 0020; + } else { + $check = 0002; + } + + return (bool) ($this->permissions & $check); + } + + /** + * checks whether content is executable + * + * @param int $user id of user to check for + * @param int $group id of group to check for + * @return bool + */ + public function isExecutable($user, $group) + { + if ($this->user === $user) { + $check = 0100; + } elseif ($this->group === $group) { + $check = 0010; + } else { + $check = 0001; + } + + return (bool) ($this->permissions & $check); + } + + /** + * change owner of file to given user + * + * @param int $user + * @return $this + */ + public function chown($user) + { + $this->user = $user; + $this->lastAttributeModified = time(); + return $this; + } + + /** + * checks whether file is owned by given user + * + * @param int $user + * @return bool + */ + public function isOwnedByUser($user) + { + return $this->user === $user; + } + + /** + * returns owner of file + * + * @return int + */ + public function getUser() + { + return $this->user; + } + + /** + * change owner group of file to given group + * + * @param int $group + * @return $this + */ + public function chgrp($group) + { + $this->group = $group; + $this->lastAttributeModified = time(); + return $this; + } + + /** + * checks whether file is owned by group + * + * @param int $group + * @return bool + */ + public function isOwnedByGroup($group) + { + return $this->group === $group; + } + + /** + * returns owner group of file + * + * @return int + */ + public function getGroup() + { + return $this->group; + } + + /** + * sets parent path + * + * @param string $parentPath + * @internal only to be set by parent + * @since 1.2.0 + */ + public function setParentPath($parentPath) + { + $this->parentPath = $parentPath; + } + + /** + * returns path to this content + * + * @return string + * @since 1.2.0 + */ + public function path() + { + if (null === $this->parentPath) { + return $this->name; + } + + return $this->parentPath . '/' . $this->name; + } + + /** + * returns complete vfsStream url for this content + * + * @return string + * @since 1.2.0 + */ + public function url() + { + return vfsStream::url($this->path()); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamBlock.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamBlock.php new file mode 100644 index 0000000..128a96a --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamBlock.php @@ -0,0 +1,34 @@ +type = vfsStreamContent::TYPE_BLOCK; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContainer.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContainer.php new file mode 100644 index 0000000..74faa9a --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContainer.php @@ -0,0 +1,61 @@ +children = $children; + if (vfsStream::useDotfiles()) { + array_unshift($this->children, new DotDirectory('.'), new DotDirectory('..')); + } + + reset($this->children); + } + + /** + * resets children pointer + */ + public function rewind() + { + reset($this->children); + } + + /** + * returns the current child + * + * @return vfsStreamContent + */ + public function current() + { + $child = current($this->children); + if (false === $child) { + return null; + } + + return $child; + } + + /** + * returns the name of the current child + * + * @return string + */ + public function key() + { + $child = current($this->children); + if (false === $child) { + return null; + } + + return $child->getName(); + } + + /** + * iterates to next child + */ + public function next() + { + next($this->children); + } + + /** + * checks if the current value is valid + * + * @return bool + */ + public function valid() + { + return (false !== current($this->children)); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContent.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContent.php new file mode 100644 index 0000000..03b5bab --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamContent.php @@ -0,0 +1,213 @@ +type = vfsStreamContent::TYPE_DIR; + parent::__construct($name, $permissions); + } + + /** + * returns default permissions for concrete implementation + * + * @return int + * @since 0.8.0 + */ + protected function getDefaultPermissions() + { + return 0777; + } + + /** + * returns size of directory + * + * The size of a directory is always 0 bytes. To calculate the summarized + * size of all children in the directory use sizeSummarized(). + * + * @return int + */ + public function size() + { + return 0; + } + + /** + * returns summarized size of directory and its children + * + * @return int + */ + public function sizeSummarized() + { + $size = 0; + foreach ($this->children as $child) { + if ($child->getType() === vfsStreamContent::TYPE_DIR) { + $size += $child->sizeSummarized(); + } else { + $size += $child->size(); + } + } + + return $size; + } + + /** + * renames the content + * + * @param string $newName + * @throws vfsStreamException + */ + public function rename($newName) + { + if (strstr($newName, '/') !== false) { + throw new vfsStreamException('Directory name can not contain /.'); + } + + parent::rename($newName); + } + + + /** + * sets parent path + * + * @param string $parentPath + * @internal only to be set by parent + * @since 1.2.0 + */ + public function setParentPath($parentPath) + { + parent::setParentPath($parentPath); + foreach ($this->children as $child) { + $child->setParentPath($this->path()); + } + } + + /** + * adds child to the directory + * + * @param vfsStreamContent $child + */ + public function addChild(vfsStreamContent $child) + { + $child->setParentPath($this->path()); + $this->children[$child->getName()] = $child; + $this->updateModifications(); + } + + /** + * removes child from the directory + * + * @param string $name + * @return bool + */ + public function removeChild($name) + { + foreach ($this->children as $key => $child) { + if ($child->appliesTo($name)) { + $child->setParentPath(null); + unset($this->children[$key]); + $this->updateModifications(); + return true; + } + } + + return false; + } + + /** + * updates internal timestamps + */ + protected function updateModifications() + { + $time = time(); + $this->lastAttributeModified = $time; + $this->lastModified = $time; + } + + /** + * checks whether the container contains a child with the given name + * + * @param string $name + * @return bool + */ + public function hasChild($name) + { + return ($this->getChild($name) !== null); + } + + /** + * returns the child with the given name + * + * @param string $name + * @return vfsStreamContent + */ + public function getChild($name) + { + $childName = $this->getRealChildName($name); + foreach ($this->children as $child) { + if ($child->getName() === $childName) { + return $child; + } + + if ($child->appliesTo($childName) === true && $child->hasChild($childName) === true) { + return $child->getChild($childName); + } + } + + return null; + } + + /** + * helper method to detect the real child name + * + * @param string $name + * @return string + */ + protected function getRealChildName($name) + { + if ($this->appliesTo($name) === true) { + return self::getChildName($name, $this->name); + } + + return $name; + } + + /** + * helper method to calculate the child name + * + * @param string $name + * @param string $ownName + * @return string + */ + protected static function getChildName($name, $ownName) + { + if ($name === $ownName) { + return $name; + } + + return substr($name, strlen($ownName) + 1); + } + + /** + * checks whether directory contains any children + * + * @return bool + * @since 0.10.0 + */ + public function hasChildren() + { + return (count($this->children) > 0); + } + + /** + * returns a list of children for this directory + * + * @return vfsStreamContent[] + */ + public function getChildren() + { + return array_values($this->children); + } + + /** + * returns iterator for the children + * + * @return vfsStreamContainerIterator + */ + public function getIterator() + { + return new vfsStreamContainerIterator($this->children); + } + + /** + * checks whether dir is a dot dir + * + * @return bool + */ + public function isDot() + { + if ('.' === $this->name || '..' === $this->name) { + return true; + } + + return false; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamException.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamException.php new file mode 100644 index 0000000..b78afd1 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamException.php @@ -0,0 +1,19 @@ +content = new StringBasedFileContent(null); + $this->type = vfsStreamContent::TYPE_FILE; + parent::__construct($name, $permissions); + } + + /** + * returns default permissions for concrete implementation + * + * @return int + * @since 0.8.0 + */ + protected function getDefaultPermissions() + { + return 0666; + } + + /** + * checks whether the container can be applied to given name + * + * @param string $name + * @return bool + */ + public function appliesTo($name) + { + return ($name === $this->name); + } + + /** + * alias for withContent() + * + * @param string $content + * @return vfsStreamFile + * @see withContent() + */ + public function setContent($content) + { + return $this->withContent($content); + } + + /** + * sets the contents of the file + * + * Setting content with this method does not change the time when the file + * was last modified. + * + * @param string]FileContent $content + * @return vfsStreamFile + * @throws \InvalidArgumentException + */ + public function withContent($content) + { + if (is_string($content)) { + $this->content = new StringBasedFileContent($content); + } elseif ($content instanceof FileContent) { + $this->content = $content; + } else { + throw new \InvalidArgumentException('Given content must either be a string or an instance of org\bovigo\vfs\content\FileContent'); + } + + return $this; + } + + /** + * returns the contents of the file + * + * Getting content does not change the time when the file + * was last accessed. + * + * @return string + */ + public function getContent() + { + return $this->content->content(); + } + + /** + * simply open the file + * + * @since 0.9 + */ + public function open() + { + $this->content->seek(0, SEEK_SET); + $this->lastAccessed = time(); + } + + /** + * open file and set pointer to end of file + * + * @since 0.9 + */ + public function openForAppend() + { + $this->content->seek(0, SEEK_END); + $this->lastAccessed = time(); + } + + /** + * open file and truncate content + * + * @since 0.9 + */ + public function openWithTruncate() + { + $this->open(); + $this->content->truncate(0); + $time = time(); + $this->lastAccessed = $time; + $this->lastModified = $time; + } + + /** + * reads the given amount of bytes from content + * + * Using this method changes the time when the file was last accessed. + * + * @param int $count + * @return string + */ + public function read($count) + { + $this->lastAccessed = time(); + return $this->content->read($count); + } + + /** + * returns the content until its end from current offset + * + * Using this method changes the time when the file was last accessed. + * + * @return string + * @deprecated since 1.3.0 + */ + public function readUntilEnd() + { + $this->lastAccessed = time(); + return $this->content->readUntilEnd(); + } + + /** + * writes an amount of data + * + * Using this method changes the time when the file was last modified. + * + * @param string $data + * @return amount of written bytes + */ + public function write($data) + { + $this->lastModified = time(); + return $this->content->write($data); + } + + /** + * Truncates a file to a given length + * + * @param int $size length to truncate file to + * @return bool + * @since 1.1.0 + */ + public function truncate($size) + { + $this->content->truncate($size); + $this->lastModified = time(); + return true; + } + + /** + * checks whether pointer is at end of file + * + * @return bool + */ + public function eof() + { + return $this->content->eof(); + } + + /** + * returns the current position within the file + * + * @return int + * @deprecated since 1.3.0 + */ + public function getBytesRead() + { + return $this->content->bytesRead(); + } + + /** + * seeks to the given offset + * + * @param int $offset + * @param int $whence + * @return bool + */ + public function seek($offset, $whence) + { + return $this->content->seek($offset, $whence); + } + + /** + * returns size of content + * + * @return int + */ + public function size() + { + return $this->content->size(); + } + + + /** + * locks file for + * + * @param resource|vfsStreamWrapper $resource + * @param int $operation + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/6 + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function lock($resource, $operation) + { + if ((LOCK_NB & $operation) == LOCK_NB) { + $operation = $operation - LOCK_NB; + } + + // call to lock file on the same file handler firstly releases the lock + $this->unlock($resource); + + if (LOCK_EX === $operation) { + if ($this->isLocked()) { + return false; + } + + $this->setExclusiveLock($resource); + } elseif(LOCK_SH === $operation) { + if ($this->hasExclusiveLock()) { + return false; + } + + $this->addSharedLock($resource); + } + + return true; + } + + /** + * Removes lock from file acquired by given resource + * + * @param resource|vfsStreamWrapper $resource + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function unlock($resource) { + if ($this->hasExclusiveLock($resource)) { + $this->exclusiveLock = null; + } + if ($this->hasSharedLock($resource)) { + unset($this->sharedLock[$this->getResourceId($resource)]); + } + } + + /** + * Set exlusive lock on file by given resource + * + * @param resource|vfsStreamWrapper $resource + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + protected function setExclusiveLock($resource) { + $this->exclusiveLock = $this->getResourceId($resource); + } + + /** + * Add shared lock on file by given resource + * + * @param resource|vfsStreamWrapper $resource + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + protected function addSharedLock($resource) { + $this->sharedLock[$this->getResourceId($resource)] = true; + } + + /** + * checks whether file is locked + * + * @param resource|vfsStreamWrapper $resource + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/6 + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function isLocked($resource = null) + { + return $this->hasSharedLock($resource) || $this->hasExclusiveLock($resource); + } + + /** + * checks whether file is locked in shared mode + * + * @param resource|vfsStreamWrapper $resource + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/6 + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function hasSharedLock($resource = null) + { + if (null !== $resource) { + return isset($this->sharedLock[$this->getResourceId($resource)]); + } + + return !empty($this->sharedLock); + } + + /** + * Returns unique resource id + * + * @param resource|vfsStreamWrapper $resource + * @return string + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function getResourceId($resource) { + if (is_resource($resource)) { + $data = stream_get_meta_data($resource); + $resource = $data['wrapper_data']; + } + + return spl_object_hash($resource); + } + + /** + * checks whether file is locked in exclusive mode + * + * @param resource|vfsStreamWrapper $resource + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/6 + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function hasExclusiveLock($resource = null) + { + if (null !== $resource) { + return $this->exclusiveLock === $this->getResourceId($resource); + } + + return null !== $this->exclusiveLock; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamWrapper.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamWrapper.php new file mode 100644 index 0000000..368b2fb --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/vfsStreamWrapper.php @@ -0,0 +1,1012 @@ +getName() === $path) { + return self::$root; + } + + if ($this->isInRoot($path) && self::$root->hasChild($path) === true) { + return self::$root->getChild($path); + } + + return null; + } + + /** + * helper method to detect whether given path is in root path + * + * @param string $path + * @return bool + */ + private function isInRoot($path) + { + return substr($path, 0, strlen(self::$root->getName())) === self::$root->getName(); + } + + /** + * returns content for given path but only when it is of given type + * + * @param string $path + * @param int $type + * @return vfsStreamContent + */ + protected function getContentOfType($path, $type) + { + $content = $this->getContent($path); + if (null !== $content && $content->getType() === $type) { + return $content; + } + + return null; + } + + /** + * splits path into its dirname and the basename + * + * @param string $path + * @return string[] + */ + protected function splitPath($path) + { + $lastSlashPos = strrpos($path, '/'); + if (false === $lastSlashPos) { + return array('dirname' => '', 'basename' => $path); + } + + return array('dirname' => substr($path, 0, $lastSlashPos), + 'basename' => substr($path, $lastSlashPos + 1) + ); + } + + /** + * helper method to resolve a path from /foo/bar/. to /foo/bar + * + * @param string $path + * @return string + */ + protected function resolvePath($path) + { + $newPath = array(); + foreach (explode('/', $path) as $pathPart) { + if ('.' !== $pathPart) { + if ('..' !== $pathPart) { + $newPath[] = $pathPart; + } elseif (count($newPath) > 1) { + array_pop($newPath); + } + } + } + + return implode('/', $newPath); + } + + /** + * open the stream + * + * @param string $path the path to open + * @param string $mode mode for opening + * @param string $options options for opening + * @param string $opened_path full path that was actually opened + * @return bool + */ + public function stream_open($path, $mode, $options, $opened_path) + { + $extended = ((strstr($mode, '+') !== false) ? (true) : (false)); + $mode = str_replace(array('t', 'b', '+'), '', $mode); + if (in_array($mode, array('r', 'w', 'a', 'x', 'c')) === false) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Illegal mode ' . $mode . ', use r, w, a, x or c, flavoured with t, b and/or +', E_USER_WARNING); + } + + return false; + } + + $this->mode = $this->calculateMode($mode, $extended); + $path = $this->resolvePath(vfsStream::path($path)); + $this->content = $this->getContentOfType($path, vfsStreamContent::TYPE_FILE); + if (null !== $this->content) { + if (self::WRITE === $mode) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('File ' . $path . ' already exists, can not open with mode x', E_USER_WARNING); + } + + return false; + } + + if ( + (self::TRUNCATE === $mode || self::APPEND === $mode) && + $this->content->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false + ) { + return false; + } + + if (self::TRUNCATE === $mode) { + $this->content->openWithTruncate(); + } elseif (self::APPEND === $mode) { + $this->content->openForAppend(); + } else { + if (!$this->content->isReadable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup())) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Permission denied', E_USER_WARNING); + } + return false; + } + $this->content->open(); + } + + return true; + } + + $content = $this->createFile($path, $mode, $options); + if (false === $content) { + return false; + } + + $this->content = $content; + return true; + } + + /** + * creates a file at given path + * + * @param string $path the path to open + * @param string $mode mode for opening + * @param string $options options for opening + * @return bool + */ + private function createFile($path, $mode = null, $options = null) + { + $names = $this->splitPath($path); + if (empty($names['dirname']) === true) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('File ' . $names['basename'] . ' does not exist', E_USER_WARNING); + } + + return false; + } + + $dir = $this->getContentOfType($names['dirname'], vfsStreamContent::TYPE_DIR); + if (null === $dir) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Directory ' . $names['dirname'] . ' does not exist', E_USER_WARNING); + } + + return false; + } elseif ($dir->hasChild($names['basename']) === true) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Directory ' . $names['dirname'] . ' already contains a director named ' . $names['basename'], E_USER_WARNING); + } + + return false; + } + + if (self::READ === $mode) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Can not open non-existing file ' . $path . ' for reading', E_USER_WARNING); + } + + return false; + } + + if ($dir->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + if (($options & STREAM_REPORT_ERRORS) === STREAM_REPORT_ERRORS) { + trigger_error('Can not create new file in non-writable path ' . $names['dirname'], E_USER_WARNING); + } + + return false; + } + + return vfsStream::newFile($names['basename'])->at($dir); + } + + /** + * calculates the file mode + * + * @param string $mode opening mode: r, w, a or x + * @param bool $extended true if + was set with opening mode + * @return int + */ + protected function calculateMode($mode, $extended) + { + if (true === $extended) { + return self::ALL; + } + + if (self::READ === $mode) { + return self::READONLY; + } + + return self::WRITEONLY; + } + + /** + * closes the stream + * + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function stream_close() + { + $this->content->lock($this, LOCK_UN); + } + + /** + * read the stream up to $count bytes + * + * @param int $count amount of bytes to read + * @return string + */ + public function stream_read($count) + { + if (self::WRITEONLY === $this->mode) { + return ''; + } + + if ($this->content->isReadable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return ''; + } + + return $this->content->read($count); + } + + /** + * writes data into the stream + * + * @param string $data + * @return int amount of bytes written + */ + public function stream_write($data) + { + if (self::READONLY === $this->mode) { + return 0; + } + + if ($this->content->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return 0; + } + + if (self::$quota->isLimited()) { + $data = substr($data, 0, self::$quota->spaceLeft(self::$root->sizeSummarized())); + } + + return $this->content->write($data); + } + + /** + * truncates a file to a given length + * + * @param int $size length to truncate file to + * @return bool + * @since 1.1.0 + */ + public function stream_truncate($size) + { + if (self::READONLY === $this->mode) { + return false; + } + + if ($this->content->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return false; + } + + if ($this->content->getType() !== vfsStreamContent::TYPE_FILE) { + return false; + } + + if (self::$quota->isLimited() && $this->content->size() < $size) { + $maxSize = self::$quota->spaceLeft(self::$root->sizeSummarized()); + if (0 === $maxSize) { + return false; + } + + if ($size > $maxSize) { + $size = $maxSize; + } + } + + return $this->content->truncate($size); + } + + /** + * sets metadata like owner, user or permissions + * + * @param string $path + * @param int $option + * @param mixed $var + * @return bool + * @since 1.1.0 + */ + public function stream_metadata($path, $option, $var) + { + $path = $this->resolvePath(vfsStream::path($path)); + $content = $this->getContent($path); + switch ($option) { + case STREAM_META_TOUCH: + if (null === $content) { + $content = $this->createFile($path, null, STREAM_REPORT_ERRORS); + // file creation may not be allowed at provided path + if (false === $content) { + return false; + } + } + + $currentTime = time(); + $content->lastModified(((isset($var[0])) ? ($var[0]) : ($currentTime))) + ->lastAccessed(((isset($var[1])) ? ($var[1]) : ($currentTime))); + return true; + + case STREAM_META_OWNER_NAME: + return false; + + case STREAM_META_OWNER: + if (null === $content) { + return false; + } + + return $this->doPermChange($path, + $content, + function() use ($content, $var) + { + $content->chown($var); + } + ); + + case STREAM_META_GROUP_NAME: + return false; + + case STREAM_META_GROUP: + if (null === $content) { + return false; + } + + return $this->doPermChange($path, + $content, + function() use ($content, $var) + { + $content->chgrp($var); + } + ); + + case STREAM_META_ACCESS: + if (null === $content) { + return false; + } + + return $this->doPermChange($path, + $content, + function() use ($content, $var) + { + $content->chmod($var); + } + ); + + default: + return false; + } + } + + /** + * executes given permission change when necessary rights allow such a change + * + * @param string $path + * @param vfsStreamAbstractContent $content + * @param \Closure $change + * @return bool + */ + private function doPermChange($path, vfsStreamAbstractContent $content, \Closure $change) + { + if (!$content->isOwnedByUser(vfsStream::getCurrentUser())) { + return false; + } + + if (self::$root->getName() !== $path) { + $names = $this->splitPath($path); + $parent = $this->getContent($names['dirname']); + if (!$parent->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup())) { + return false; + } + } + + $change(); + return true; + } + + /** + * checks whether stream is at end of file + * + * @return bool + */ + public function stream_eof() + { + return $this->content->eof(); + } + + /** + * returns the current position of the stream + * + * @return int + */ + public function stream_tell() + { + return $this->content->getBytesRead(); + } + + /** + * seeks to the given offset + * + * @param int $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence) + { + return $this->content->seek($offset, $whence); + } + + /** + * flushes unstored data into storage + * + * @return bool + */ + public function stream_flush() + { + return true; + } + + /** + * returns status of stream + * + * @return array + */ + public function stream_stat() + { + $fileStat = array('dev' => 0, + 'ino' => 0, + 'mode' => $this->content->getType() | $this->content->getPermissions(), + 'nlink' => 0, + 'uid' => $this->content->getUser(), + 'gid' => $this->content->getGroup(), + 'rdev' => 0, + 'size' => $this->content->size(), + 'atime' => $this->content->fileatime(), + 'mtime' => $this->content->filemtime(), + 'ctime' => $this->content->filectime(), + 'blksize' => -1, + 'blocks' => -1 + ); + return array_merge(array_values($fileStat), $fileStat); + } + + /** + * retrieve the underlaying resource + * + * Please note that this method always returns false as there is no + * underlaying resource to return. + * + * @param int $cast_as + * @since 0.9.0 + * @see https://github.com/mikey179/vfsStream/issues/3 + * @return bool + */ + public function stream_cast($cast_as) + { + return false; + } + + /** + * set lock status for stream + * + * @param int $operation + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/6 + * @see https://github.com/mikey179/vfsStream/issues/31 + * @see https://github.com/mikey179/vfsStream/issues/40 + */ + public function stream_lock($operation) + { + if ((LOCK_NB & $operation) == LOCK_NB) { + $operation = $operation - LOCK_NB; + } + + return $this->content->lock($this, $operation); + } + + /** + * sets options on the stream + * + * @param int $option key of option to set + * @param int $arg1 + * @param int $arg2 + * @return bool + * @since 0.10.0 + * @see https://github.com/mikey179/vfsStream/issues/15 + * @see http://www.php.net/manual/streamwrapper.stream-set-option.php + */ + public function stream_set_option($option, $arg1, $arg2) + { + switch ($option) { + case STREAM_OPTION_BLOCKING: + // break omitted + + case STREAM_OPTION_READ_TIMEOUT: + // break omitted + + case STREAM_OPTION_WRITE_BUFFER: + // break omitted + + default: + // nothing to do here + } + + return false; + } + + /** + * remove the data under the given path + * + * @param string $path + * @return bool + */ + public function unlink($path) + { + $realPath = $this->resolvePath(vfsStream::path($path)); + $content = $this->getContent($realPath); + if (null === $content) { + trigger_error('unlink(' . $path . '): No such file or directory', E_USER_WARNING); + return false; + } + + if ($content->getType() !== vfsStreamContent::TYPE_FILE) { + trigger_error('unlink(' . $path . '): Operation not permitted', E_USER_WARNING); + return false; + } + + return $this->doUnlink($realPath); + } + + /** + * removes a path + * + * @param string $path + * @return bool + */ + protected function doUnlink($path) + { + if (self::$root->getName() === $path) { + // delete root? very brave. :) + self::$root = null; + clearstatcache(); + return true; + } + + $names = $this->splitPath($path); + $content = $this->getContent($names['dirname']); + if (!$content->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup())) { + return false; + } + + clearstatcache(); + return $content->removeChild($names['basename']); + } + + /** + * rename from one path to another + * + * @param string $path_from + * @param string $path_to + * @return bool + * @author Benoit Aubuchon + */ + public function rename($path_from, $path_to) + { + $srcRealPath = $this->resolvePath(vfsStream::path($path_from)); + $dstRealPath = $this->resolvePath(vfsStream::path($path_to)); + $srcContent = $this->getContent($srcRealPath); + if (null == $srcContent) { + trigger_error(' No such file or directory', E_USER_WARNING); + return false; + } + $dstNames = $this->splitPath($dstRealPath); + $dstParentContent = $this->getContent($dstNames['dirname']); + if (null == $dstParentContent) { + trigger_error('No such file or directory', E_USER_WARNING); + return false; + } + if (!$dstParentContent->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup())) { + trigger_error('Permission denied', E_USER_WARNING); + return false; + } + if ($dstParentContent->getType() !== vfsStreamContent::TYPE_DIR) { + trigger_error('Target is not a directory', E_USER_WARNING); + return false; + } + + // remove old source first, so we can rename later + // (renaming first would lead to not being able to remove the old path) + if (!$this->doUnlink($srcRealPath)) { + return false; + } + + $dstContent = $srcContent; + // Renaming the filename + $dstContent->rename($dstNames['basename']); + // Copying to the destination + $dstParentContent->addChild($dstContent); + return true; + } + + /** + * creates a new directory + * + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + public function mkdir($path, $mode, $options) + { + $umask = vfsStream::umask(); + if (0 < $umask) { + $permissions = $mode & ~$umask; + } else { + $permissions = $mode; + } + + $path = $this->resolvePath(vfsStream::path($path)); + if (null !== $this->getContent($path)) { + trigger_error('mkdir(): Path vfs://' . $path . ' exists', E_USER_WARNING); + return false; + } + + if (null === self::$root) { + self::$root = vfsStream::newDirectory($path, $permissions); + return true; + } + + $maxDepth = count(explode('/', $path)); + $names = $this->splitPath($path); + $newDirs = $names['basename']; + $dir = null; + $i = 0; + while ($dir === null && $i < $maxDepth) { + $dir = $this->getContent($names['dirname']); + $names = $this->splitPath($names['dirname']); + if (null == $dir) { + $newDirs = $names['basename'] . '/' . $newDirs; + } + + $i++; + } + + if (null === $dir + || $dir->getType() !== vfsStreamContent::TYPE_DIR + || $dir->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return false; + } + + $recursive = ((STREAM_MKDIR_RECURSIVE & $options) !== 0) ? (true) : (false); + if (strpos($newDirs, '/') !== false && false === $recursive) { + return false; + } + + vfsStream::newDirectory($newDirs, $permissions)->at($dir); + return true; + } + + /** + * removes a directory + * + * @param string $path + * @param int $options + * @return bool + * @todo consider $options with STREAM_MKDIR_RECURSIVE + */ + public function rmdir($path, $options) + { + $path = $this->resolvePath(vfsStream::path($path)); + $child = $this->getContentOfType($path, vfsStreamContent::TYPE_DIR); + if (null === $child) { + return false; + } + + // can only remove empty directories + if (count($child->getChildren()) > 0) { + return false; + } + + if (self::$root->getName() === $path) { + // delete root? very brave. :) + self::$root = null; + clearstatcache(); + return true; + } + + $names = $this->splitPath($path); + $dir = $this->getContentOfType($names['dirname'], vfsStreamContent::TYPE_DIR); + if ($dir->isWritable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return false; + } + + clearstatcache(); + return $dir->removeChild($child->getName()); + } + + /** + * opens a directory + * + * @param string $path + * @param int $options + * @return bool + */ + public function dir_opendir($path, $options) + { + $path = $this->resolvePath(vfsStream::path($path)); + $this->dir = $this->getContentOfType($path, vfsStreamContent::TYPE_DIR); + if (null === $this->dir || $this->dir->isReadable(vfsStream::getCurrentUser(), vfsStream::getCurrentGroup()) === false) { + return false; + } + + $this->dirIterator = $this->dir->getIterator(); + return true; + } + + /** + * reads directory contents + * + * @return string + */ + public function dir_readdir() + { + $dir = $this->dirIterator->current(); + if (null === $dir) { + return false; + } + + $this->dirIterator->next(); + return $dir->getName(); + } + + /** + * reset directory iteration + * + * @return bool + */ + public function dir_rewinddir() + { + return $this->dirIterator->rewind(); + } + + /** + * closes directory + * + * @return bool + */ + public function dir_closedir() + { + $this->dirIterator = null; + return true; + } + + /** + * returns status of url + * + * @param string $path path of url to return status for + * @param int $flags flags set by the stream API + * @return array + */ + public function url_stat($path, $flags) + { + $content = $this->getContent($this->resolvePath(vfsStream::path($path))); + if (null === $content) { + if (($flags & STREAM_URL_STAT_QUIET) != STREAM_URL_STAT_QUIET) { + trigger_error(' No such file or directory: ' . $path, E_USER_WARNING); + } + + return false; + + } + + $fileStat = array('dev' => 0, + 'ino' => 0, + 'mode' => $content->getType() | $content->getPermissions(), + 'nlink' => 0, + 'uid' => $content->getUser(), + 'gid' => $content->getGroup(), + 'rdev' => 0, + 'size' => $content->size(), + 'atime' => $content->fileatime(), + 'mtime' => $content->filemtime(), + 'ctime' => $content->filectime(), + 'blksize' => -1, + 'blocks' => -1 + ); + return array_merge(array_values($fileStat), $fileStat); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitor.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitor.php new file mode 100644 index 0000000..f9e597b --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitor.php @@ -0,0 +1,64 @@ +getType()) { + case vfsStreamContent::TYPE_BLOCK: + $this->visitBlockDevice($content); + break; + + case vfsStreamContent::TYPE_FILE: + $this->visitFile($content); + break; + + case vfsStreamContent::TYPE_DIR: + if (!$content->isDot()) { + $this->visitDirectory($content); + } + + break; + + default: + throw new \InvalidArgumentException('Unknown content type ' . $content->getType() . ' for ' . $content->getName()); + } + + return $this; + } + + /** + * visit a block device and process it + * + * @param vfsStreamBlock $block + * @return vfsStreamVisitor + */ + public function visitBlockDevice(vfsStreamBlock $block) + { + return $this->visitFile($block); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitor.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitor.php new file mode 100644 index 0000000..15b0bc0 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitor.php @@ -0,0 +1,107 @@ +out = $out; + } + + /** + * visit a file and process it + * + * @param vfsStreamFile $file + * @return vfsStreamPrintVisitor + */ + public function visitFile(vfsStreamFile $file) + { + $this->printContent($file->getName()); + return $this; + } + + /** + * visit a block device and process it + * + * @param vfsStreamBlock $block + * @return vfsStreamPrintVisitor + */ + public function visitBlockDevice(vfsStreamBlock $block) + { + $name = '[' . $block->getName() . ']'; + $this->printContent($name); + return $this; + } + + /** + * visit a directory and process it + * + * @param vfsStreamDirectory $dir + * @return vfsStreamPrintVisitor + */ + public function visitDirectory(vfsStreamDirectory $dir) + { + $this->printContent($dir->getName()); + $this->depth++; + foreach ($dir as $child) { + $this->visit($child); + } + + $this->depth--; + return $this; + } + + /** + * helper method to print the content + * + * @param string $name + */ + protected function printContent($name) + { + fwrite($this->out, str_repeat(' ', $this->depth) . '- ' . $name . "\n"); + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitor.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitor.php new file mode 100644 index 0000000..47acc45 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitor.php @@ -0,0 +1,111 @@ +reset(); + } + + /** + * visit a file and process it + * + * @param vfsStreamFile $file + * @return vfsStreamStructureVisitor + */ + public function visitFile(vfsStreamFile $file) + { + $this->current[$file->getName()] = $file->getContent(); + return $this; + } + + /** + * visit a block device and process it + * + * @param vfsStreamBlock $block + * @return vfsStreamStructureVisitor + */ + public function visitBlockDevice(vfsStreamBlock $block) + { + $this->current['[' . $block->getName() . ']'] = $block->getContent(); + return $this; + } + + /** + * visit a directory and process it + * + * @param vfsStreamDirectory $dir + * @return vfsStreamStructureVisitor + */ + public function visitDirectory(vfsStreamDirectory $dir) + { + $this->current[$dir->getName()] = array(); + $tmp =& $this->current; + $this->current =& $tmp[$dir->getName()]; + foreach ($dir as $child) { + $this->visit($child); + } + + $this->current =& $tmp; + return $this; + } + + /** + * returns structure of visited contents + * + * @return array + * @api + */ + public function getStructure() + { + return $this->structure; + } + + /** + * resets structure so visitor could be reused + * + * @return vfsStreamStructureVisitor + */ + public function reset() + { + $this->structure = array(); + $this->current =& $this->structure; + return $this; + } +} diff --git a/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamVisitor.php b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamVisitor.php new file mode 100644 index 0000000..2170105 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/main/php/org/bovigo/vfs/visitor/vfsStreamVisitor.php @@ -0,0 +1,55 @@ +getMockBuilder($originalClassName) + ->setMethods($methods) + ->getMock() + ; + } + + return parent::getMock($originalClassName, $methods, $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $cloneArguments, $callOriginalMethods, $proxyTarget); + } +} + +// The only deprecation warnings we need to ignore/handle are in PHP 7.4 so far +if (PHP_VERSION_ID >= 70400) { + function customErrorHandler($errno, $errstr, $errfile, $errline) { + // We know about this deprecation warning exists and it's already been + // fixed in the 2.x branch. For BC reasons in the 1.x branch, we'll + // ignore this warning to let tests pass. + if ($errno === E_DEPRECATED) { + if ($errstr === "Function ReflectionType::__toString() is deprecated") { + return true; + } + } + + // Any other error should be left up to PHPUnit to handle + return \PHPUnit_Util_ErrorHandler::handleError($errno, $errstr, $errfile, $errline); + } + + set_error_handler("customErrorHandler"); +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/DirectoryIterationTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/DirectoryIterationTestCase.php new file mode 100644 index 0000000..4f30b03 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/DirectoryIterationTestCase.php @@ -0,0 +1,318 @@ +assertEquals($expectedCount, + $actualCount, + 'Directory foo contains ' . $expectedCount . ' children, but got ' . $actualCount . ' children while iterating over directory contents' + ); + } + + /** + * @param \Closure $dotFilesSwitch + * @param string[] $expectedDirectories + * @test + * @dataProvider provideSwitchWithExpectations + */ + public function directoryIteration(\Closure $dotFilesSwitch, array $expectedDirectories) + { + $dotFilesSwitch(); + $dir = dir($this->fooURL); + $i = 0; + while (false !== ($entry = $dir->read())) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + $dir->rewind(); + $i = 0; + while (false !== ($entry = $dir->read())) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + $dir->close(); + } + + /** + * @param \Closure $dotFilesSwitch + * @param string[] $expectedDirectories + * @test + * @dataProvider provideSwitchWithExpectations + */ + public function directoryIterationWithDot(\Closure $dotFilesSwitch, array $expectedDirectories) + { + $dotFilesSwitch(); + $dir = dir($this->fooURL . '/.'); + $i = 0; + while (false !== ($entry = $dir->read())) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + $dir->rewind(); + $i = 0; + while (false !== ($entry = $dir->read())) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + $dir->close(); + } + + /** + * assure that a directory iteration works as expected + * + * @param \Closure $dotFilesSwitch + * @param string[] $expectedDirectories + * @test + * @dataProvider provideSwitchWithExpectations + * @group regression + * @group bug_2 + */ + public function directoryIterationWithOpenDir_Bug_2(\Closure $dotFilesSwitch, array $expectedDirectories) + { + $dotFilesSwitch(); + $handle = opendir($this->fooURL); + $i = 0; + while (false !== ($entry = readdir($handle))) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + + rewinddir($handle); + $i = 0; + while (false !== ($entry = readdir($handle))) { + $i++; + $this->assertTrue(in_array($entry, $expectedDirectories)); + } + + $this->assertDirectoryCount(count($expectedDirectories), $i); + closedir($handle); + } + + /** + * assure that a directory iteration works as expected + * + * @author Christoph Bloemer + * @param \Closure $dotFilesSwitch + * @param string[] $expectedDirectories + * @test + * @dataProvider provideSwitchWithExpectations + * @group regression + * @group bug_4 + */ + public function directoryIteration_Bug_4(\Closure $dotFilesSwitch, array $expectedDirectories) + { + $dotFilesSwitch(); + $dir = $this->fooURL; + $list1 = array(); + if ($handle = opendir($dir)) { + while (false !== ($listItem = readdir($handle))) { + if ('.' != $listItem && '..' != $listItem) { + if (is_file($dir . '/' . $listItem) === true) { + $list1[] = 'File:[' . $listItem . ']'; + } elseif (is_dir($dir . '/' . $listItem) === true) { + $list1[] = 'Folder:[' . $listItem . ']'; + } + } + } + + closedir($handle); + } + + $list2 = array(); + if ($handle = opendir($dir)) { + while (false !== ($listItem = readdir($handle))) { + if ('.' != $listItem && '..' != $listItem) { + if (is_file($dir . '/' . $listItem) === true) { + $list2[] = 'File:[' . $listItem . ']'; + } elseif (is_dir($dir . '/' . $listItem) === true) { + $list2[] = 'Folder:[' . $listItem . ']'; + } + } + } + + closedir($handle); + } + + $this->assertEquals($list1, $list2); + $this->assertEquals(2, count($list1)); + $this->assertEquals(2, count($list2)); + } + + /** + * assure that a directory iteration works as expected + * + * @param \Closure $dotFilesSwitch + * @param string[] $expectedDirectories + * @test + * @dataProvider provideSwitchWithExpectations + */ + public function directoryIterationShouldBeIndependent(\Closure $dotFilesSwitch, array $expectedDirectories) + { + $dotFilesSwitch(); + $list1 = array(); + $list2 = array(); + $handle1 = opendir($this->fooURL); + if (false !== ($listItem = readdir($handle1))) { + $list1[] = $listItem; + } + + $handle2 = opendir($this->fooURL); + if (false !== ($listItem = readdir($handle2))) { + $list2[] = $listItem; + } + + if (false !== ($listItem = readdir($handle1))) { + $list1[] = $listItem; + } + + if (false !== ($listItem = readdir($handle2))) { + $list2[] = $listItem; + } + + closedir($handle1); + closedir($handle2); + $this->assertEquals($list1, $list2); + $this->assertEquals(2, count($list1)); + $this->assertEquals(2, count($list2)); + } + + /** + * @test + * @group issue_50 + */ + public function recursiveDirectoryIterationWithDotsEnabled() + { + vfsStream::enableDotfiles(); + vfsStream::setup(); + $structure = array( + 'Core' => array( + 'AbstractFactory' => array( + 'test.php' => 'some text content', + 'other.php' => 'Some more text content', + 'Invalid.csv' => 'Something else', + ), + 'AnEmptyFolder' => array(), + 'badlocation.php' => 'some bad content', + ) + ); + $root = vfsStream::create($structure); + $rootPath = vfsStream::url($root->getName()); + + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($rootPath), + \RecursiveIteratorIterator::CHILD_FIRST); + $pathes = array(); + foreach ($iterator as $fullFileName => $fileSPLObject) { + $pathes[] = $fullFileName; + } + + $this->assertEquals(array('vfs://root'.DIRECTORY_SEPARATOR.'.', + 'vfs://root'.DIRECTORY_SEPARATOR.'..', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'.', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'..', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'.', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'..', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'test.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'other.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'Invalid.csv', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AnEmptyFolder'.DIRECTORY_SEPARATOR.'.', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AnEmptyFolder'.DIRECTORY_SEPARATOR.'..', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AnEmptyFolder', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'badlocation.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core' + ), + $pathes + ); + } + + /** + * @test + * @group issue_50 + */ + public function recursiveDirectoryIterationWithDotsDisabled() + { + vfsStream::disableDotfiles(); + vfsStream::setup(); + $structure = array( + 'Core' => array( + 'AbstractFactory' => array( + 'test.php' => 'some text content', + 'other.php' => 'Some more text content', + 'Invalid.csv' => 'Something else', + ), + 'AnEmptyFolder' => array(), + 'badlocation.php' => 'some bad content', + ) + ); + $root = vfsStream::create($structure); + $rootPath = vfsStream::url($root->getName()); + + $iterator = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($rootPath), + \RecursiveIteratorIterator::CHILD_FIRST); + $pathes = array(); + foreach ($iterator as $fullFileName => $fileSPLObject) { + $pathes[] = $fullFileName; + } + + $this->assertEquals(array('vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'test.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'other.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory'.DIRECTORY_SEPARATOR.'Invalid.csv', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AbstractFactory', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'AnEmptyFolder', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core'.DIRECTORY_SEPARATOR.'badlocation.php', + 'vfs://root'.DIRECTORY_SEPARATOR.'Core' + ), + $pathes + ); + } +} \ No newline at end of file diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/FilenameTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/FilenameTestCase.php new file mode 100644 index 0000000..5326bd4 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/FilenameTestCase.php @@ -0,0 +1,88 @@ +rootDir = vfsStream::url('root'); + $this->lostAndFound = $this->rootDir . '/lost+found/'; + mkdir($this->lostAndFound); + } + + /** + * @test + */ + public function worksWithCorrectName() + { + $results = array(); + $it = new \RecursiveDirectoryIterator($this->lostAndFound); + foreach ($it as $f) { + $results[] = $f->getPathname(); + } + + $this->assertEquals( + array( + 'vfs://root/lost+found' . DIRECTORY_SEPARATOR . '.', + 'vfs://root/lost+found' . DIRECTORY_SEPARATOR . '..' + ), + $results + ); + } + + /** + * @test + * @expectedException UnexpectedValueException + * @expectedExceptionMessage failed to open dir + */ + public function doesNotWorkWithInvalidName() + { + $results = array(); + $it = new \RecursiveDirectoryIterator($this->rootDir . '/lost found/'); + foreach ($it as $f) { + $results[] = $f->getPathname(); + } + } + + /** + * @test + */ + public function returnsCorrectNames() + { + $results = array(); + $it = new \RecursiveDirectoryIterator($this->rootDir); + foreach ($it as $f) { + $results[] = $f->getPathname(); + } + + $this->assertEquals( + array( + 'vfs://root' . DIRECTORY_SEPARATOR . '.', + 'vfs://root' . DIRECTORY_SEPARATOR . '..', + 'vfs://root' . DIRECTORY_SEPARATOR . 'lost+found' + ), + $results + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/Issue104TestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/Issue104TestCase.php new file mode 100644 index 0000000..895f601 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/Issue104TestCase.php @@ -0,0 +1,52 @@ + array( + 'schema.xsd' => ' + + ', + ) + ); + vfsStream::setup('root', null, $structure); + $doc = new \DOMDocument(); + $this->assertTrue($doc->load(vfsStream::url('root/foo bar/schema.xsd'))); + } + + /** + * @test + */ + public function vfsStreamCanHandleUrlEncodedPath() + { + $content = ' + + '; + $structure = array('foo bar' => array( + 'schema.xsd' => $content, + ) + ); + vfsStream::setup('root', null, $structure); + $this->assertEquals( + $content, + file_get_contents(vfsStream::url('root/foo bar/schema.xsd')) + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/PermissionsTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/PermissionsTestCase.php new file mode 100644 index 0000000..e99a55a --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/PermissionsTestCase.php @@ -0,0 +1,118 @@ + array('test.file' => '')); + $this->root = vfsStream::setup('root', null, $structure); + } + + /** + * @test + * @group issue_52 + */ + public function canNotChangePermissionWhenDirectoryNotWriteable() + { + $this->root->getChild('test_directory')->chmod(0444); + $this->assertFalse(@chmod(vfsStream::url('root/test_directory/test.file'), 0777)); + } + + /** + * @test + * @group issue_53 + */ + public function canNotChangePermissionWhenFileNotOwned() + { + $this->root->getChild('test_directory')->getChild('test.file')->chown(vfsStream::OWNER_USER_1); + $this->assertFalse(@chmod(vfsStream::url('root/test_directory/test.file'), 0777)); + } + + /** + * @test + * @group issue_52 + */ + public function canNotChangeOwnerWhenDirectoryNotWriteable() + { + $this->root->getChild('test_directory')->chmod(0444); + $this->assertFalse(@chown(vfsStream::url('root/test_directory/test.file'), vfsStream::OWNER_USER_2)); + } + + /** + * @test + * @group issue_53 + */ + public function canNotChangeOwnerWhenFileNotOwned() + { + $this->root->getChild('test_directory')->getChild('test.file')->chown(vfsStream::OWNER_USER_1); + $this->assertFalse(@chown(vfsStream::url('root/test_directory/test.file'), vfsStream::OWNER_USER_2)); + } + + /** + * @test + * @group issue_52 + */ + public function canNotChangeGroupWhenDirectoryNotWriteable() + { + $this->root->getChild('test_directory')->chmod(0444); + $this->assertFalse(@chgrp(vfsStream::url('root/test_directory/test.file'), vfsStream::GROUP_USER_2)); + } + + /** + * @test + * @group issue_53 + */ + public function canNotChangeGroupWhenFileNotOwned() + { + $this->root->getChild('test_directory')->getChild('test.file')->chown(vfsStream::OWNER_USER_1); + $this->assertFalse(@chgrp(vfsStream::url('root/test_directory/test.file'), vfsStream::GROUP_USER_2)); + } + + /** + * @test + * @group issue_107 + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage Can not create new file in non-writable path root + * @requires PHP 5.4 + * @since 1.5.0 + */ + public function touchOnNonWriteableDirectoryTriggersError() + { + $this->root->chmod(0555); + touch($this->root->url() . '/touch.txt'); + } + + /** + * @test + * @group issue_107 + * @requires PHP 5.4 + * @since 1.5.0 + */ + public function touchOnNonWriteableDirectoryDoesNotCreateFile() + { + $this->root->chmod(0555); + $this->assertFalse(@touch($this->root->url() . '/touch.txt')); + $this->assertFalse($this->root->hasChild('touch.txt')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/QuotaTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/QuotaTestCase.php new file mode 100644 index 0000000..8c0f5b2 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/QuotaTestCase.php @@ -0,0 +1,80 @@ +quota = new Quota(10); + } + + /** + * @test + */ + public function unlimitedQuotaIsNotLimited() + { + $this->assertFalse(Quota::unlimited()->isLimited()); + } + + /** + * @test + */ + public function limitedQuotaIsLimited() + { + $this->assertTrue($this->quota->isLimited()); + } + + /** + * @test + */ + public function unlimitedQuotaHasAlwaysSpaceLeft() + { + $this->assertEquals(303, Quota::unlimited()->spaceLeft(303)); + } + + /** + * @test + */ + public function hasNoSpaceLeftWhenUsedSpaceIsLargerThanQuota() + { + $this->assertEquals(0, $this->quota->spaceLeft(11)); + } + + /** + * @test + */ + public function hasNoSpaceLeftWhenUsedSpaceIsEqualToQuota() + { + $this->assertEquals(0, $this->quota->spaceLeft(10)); + } + + /** + * @test + */ + public function hasSpaceLeftWhenUsedSpaceIsLowerThanQuota() + { + $this->assertEquals(1, $this->quota->spaceLeft(9)); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/UnlinkTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/UnlinkTestCase.php new file mode 100644 index 0000000..c33a4c2 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/UnlinkTestCase.php @@ -0,0 +1,58 @@ + array('test.file' => '')); + $root = vfsStream::setup('root', null, $structure); + $root->getChild('test_directory')->chmod(0777); + $root->getChild('test_directory')->getChild('test.file')->chmod(0444); + $this->assertTrue(@unlink(vfsStream::url('root/test_directory/test.file'))); + } + + /** + * @test + * @group issue_51 + */ + public function canNotRemoveWritableFileFromNonWritableDirectory() + { + $structure = array('test_directory' => array('test.file' => '')); + $root = vfsStream::setup('root', null, $structure); + $root->getChild('test_directory')->chmod(0444); + $root->getChild('test_directory')->getChild('test.file')->chmod(0777); + $this->assertFalse(@unlink(vfsStream::url('root/test_directory/test.file'))); + } + + /** + * @test + * @since 1.4.0 + * @group issue_68 + */ + public function unlinkNonExistingFileTriggersError() + { + vfsStream::setup(); + try { + $this->assertFalse(unlink('vfs://root/foo.txt')); + } catch (\PHPUnit_Framework_Error $fe) { + $this->assertEquals('unlink(vfs://root/foo.txt): No such file or directory', $fe->getMessage()); + } + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/LargeFileContentTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/LargeFileContentTestCase.php new file mode 100644 index 0000000..c9015e1 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/LargeFileContentTestCase.php @@ -0,0 +1,225 @@ +largeFileContent = new LargeFileContent(100); + } + + /** + * @test + */ + public function hasSizeOriginallyGiven() + { + $this->assertEquals(100, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function contentIsFilledUpWithSpacesIfNoDataWritten() + { + $this->assertEquals( + str_repeat(' ', 100), + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function readReturnsSpacesWhenNothingWrittenAtOffset() + { + $this->assertEquals( + str_repeat(' ', 10), + $this->largeFileContent->read(10) + ); + } + + /** + * @test + */ + public function readReturnsContentFilledWithSpaces() + { + $this->largeFileContent->write('foobarbaz'); + $this->largeFileContent->seek(0, SEEK_SET); + $this->assertEquals( + 'foobarbaz ', + $this->largeFileContent->read(10) + ); + } + + /** + * @test + */ + public function writesDataAtStartWhenOffsetNotMoved() + { + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals( + 'foobarbaz' . str_repeat(' ', 91), + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function writeDataAtStartDoesNotIncreaseSize() + { + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals(100, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function writesDataAtOffsetWhenOffsetMoved() + { + $this->largeFileContent->seek(50, SEEK_SET); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals( + str_repeat(' ', 50) . 'foobarbaz' . str_repeat(' ', 41), + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function writeDataInBetweenDoesNotIncreaseSize() + { + $this->largeFileContent->seek(50, SEEK_SET); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals(100, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function writesDataOverEndWhenOffsetAndDataLengthLargerThanSize() + { + $this->largeFileContent->seek(95, SEEK_SET); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals( + str_repeat(' ', 95) . 'foobarbaz', + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function writeDataOverLastOffsetIncreasesSize() + { + $this->largeFileContent->seek(95, SEEK_SET); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals(104, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function writesDataAfterEndWhenOffsetAfterEnd() + { + $this->largeFileContent->seek(0, SEEK_END); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals( + str_repeat(' ', 100) . 'foobarbaz', + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function writeDataAfterLastOffsetIncreasesSize() + { + $this->largeFileContent->seek(0, SEEK_END); + $this->assertEquals(9, $this->largeFileContent->write('foobarbaz')); + $this->assertEquals(109, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function truncateReducesSize() + { + $this->assertTrue($this->largeFileContent->truncate(50)); + $this->assertEquals(50, $this->largeFileContent->size()); + } + + /** + * @test + */ + public function truncateRemovesWrittenContentAfterOffset() + { + $this->largeFileContent->seek(45, SEEK_SET); + $this->largeFileContent->write('foobarbaz'); + $this->assertTrue($this->largeFileContent->truncate(50)); + $this->assertEquals( + str_repeat(' ', 45) . 'fooba', + $this->largeFileContent->content() + ); + } + + /** + * @test + */ + public function createInstanceWithKilobytes() + { + $this->assertEquals( + 100 * 1024, + LargeFileContent::withKilobytes(100) + ->size() + ); + } + + /** + * @test + */ + public function createInstanceWithMegabytes() + { + $this->assertEquals( + 100 * 1024 * 1024, + LargeFileContent::withMegabytes(100) + ->size() + ); + } + + /** + * @test + */ + public function createInstanceWithGigabytes() + { + $this->assertEquals( + 100 * 1024 * 1024 * 1024, + LargeFileContent::withGigabytes(100) + ->size() + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/StringBasedFileContentTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/StringBasedFileContentTestCase.php new file mode 100644 index 0000000..137a092 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/content/StringBasedFileContentTestCase.php @@ -0,0 +1,232 @@ +stringBasedFileContent = new StringBasedFileContent('foobarbaz'); + } + + /** + * @test + */ + public function hasContentOriginallySet() + { + $this->assertEquals('foobarbaz', $this->stringBasedFileContent->content()); + } + + /** + * @test + */ + public function hasNotReachedEofAfterCreation() + { + $this->assertFalse($this->stringBasedFileContent->eof()); + } + + /** + * @test + */ + public function sizeEqualsLengthOfGivenString() + { + $this->assertEquals(9, $this->stringBasedFileContent->size()); + } + + /** + * @test + */ + public function readReturnsSubstringWithRequestedLength() + { + $this->assertEquals('foo', $this->stringBasedFileContent->read(3)); + } + + /** + * @test + */ + public function readMovesOffset() + { + $this->assertEquals('foo', $this->stringBasedFileContent->read(3)); + $this->assertEquals('bar', $this->stringBasedFileContent->read(3)); + $this->assertEquals('baz', $this->stringBasedFileContent->read(3)); + } + + /** + * @test + */ + public function reaMoreThanSizeReturnsWholeContent() + { + $this->assertEquals('foobarbaz', $this->stringBasedFileContent->read(10)); + } + + /** + * @test + */ + public function readAfterEndReturnsEmptyString() + { + // Read more than the length of the string to test substr() returning + // false. + $this->stringBasedFileContent->read(10); + $this->assertSame('', $this->stringBasedFileContent->read(3)); + } + + /** + * @test + */ + public function readDoesNotChangeSize() + { + $this->stringBasedFileContent->read(3); + $this->assertEquals(9, $this->stringBasedFileContent->size()); + } + + /** + * @test + */ + public function readLessThenSizeDoesNotReachEof() + { + $this->stringBasedFileContent->read(3); + $this->assertFalse($this->stringBasedFileContent->eof()); + } + + /** + * @test + */ + public function readSizeReachesEof() + { + $this->stringBasedFileContent->read(9); + $this->assertTrue($this->stringBasedFileContent->eof()); + } + + /** + * @test + */ + public function readMoreThanSizeReachesEof() + { + $this->stringBasedFileContent->read(10); + $this->assertTrue($this->stringBasedFileContent->eof()); + } + + /** + * @test + */ + public function seekWithInvalidOptionReturnsFalse() + { + $this->assertFalse($this->stringBasedFileContent->seek(0, 55)); + } + + /** + * @test + */ + public function canSeekToGivenOffset() + { + $this->assertTrue($this->stringBasedFileContent->seek(5, SEEK_SET)); + $this->assertEquals('rbaz', $this->stringBasedFileContent->read(10)); + } + + /** + * @test + */ + public function canSeekFromCurrentOffset() + { + $this->assertTrue($this->stringBasedFileContent->seek(5, SEEK_SET)); + $this->assertTrue($this->stringBasedFileContent->seek(2, SEEK_CUR)); + $this->assertEquals('az', $this->stringBasedFileContent->read(10)); + } + + /** + * @test + */ + public function canSeekToEnd() + { + $this->assertTrue($this->stringBasedFileContent->seek(0, SEEK_END)); + $this->assertEquals('', $this->stringBasedFileContent->read(10)); + } + + /** + * @test + */ + public function writeOverwritesExistingContentWhenOffsetNotAtEof() + { + $this->assertEquals(3, $this->stringBasedFileContent->write('bar')); + $this->assertEquals('barbarbaz', $this->stringBasedFileContent->content()); + } + + /** + * @test + */ + public function writeAppendsContentWhenOffsetAtEof() + { + $this->assertTrue($this->stringBasedFileContent->seek(0, SEEK_END)); + $this->assertEquals(3, $this->stringBasedFileContent->write('bar')); + $this->assertEquals('foobarbazbar', $this->stringBasedFileContent->content()); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateRemovesSuperflouosContent() + { + $this->assertTrue($this->stringBasedFileContent->truncate(6)); + $this->assertEquals('foobar', $this->stringBasedFileContent->content()); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateDecreasesSize() + { + $this->assertTrue($this->stringBasedFileContent->truncate(6)); + $this->assertEquals(6, $this->stringBasedFileContent->size()); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateToGreaterSizeAddsZeroBytes() + { + $this->assertTrue($this->stringBasedFileContent->truncate(25)); + $this->assertEquals( + "foobarbaz\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + $this->stringBasedFileContent->content() + ); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateToGreaterSizeIncreasesSize() + { + $this->assertTrue($this->stringBasedFileContent->truncate(25)); + $this->assertEquals(25, $this->stringBasedFileContent->size()); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/proxy/vfsStreamWrapperRecordingProxy.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/proxy/vfsStreamWrapperRecordingProxy.php new file mode 100644 index 0000000..1ed84b5 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/proxy/vfsStreamWrapperRecordingProxy.php @@ -0,0 +1,325 @@ + + */ + public static function getMethodCalls($path) + { + if (isset(self::$calledMethods[$path]) === true) { + return self::$calledMethods[$path]; + } + + return array(); + } + + /** + * helper method for setting up vfsStream with the proxy + * + * @param string $rootDirName optional name of root directory + * @param int $permissions optional file permissions of root directory + * @return vfsStreamDirectory + * @throws vfsStreamException + */ + public static function setup($rootDirName = 'root', $permissions = null) + { + self::$root = vfsStream::newDirectory($rootDirName, $permissions); + if (true === self::$registered) { + return self::$root; + } + + if (@stream_wrapper_register(vfsStream::SCHEME, __CLASS__) === false) { + throw new vfsStreamException('A handler has already been registered for the ' . vfsStream::SCHEME . ' protocol.'); + } + + self::$registered = true; + return self::$root; + } + + /** + * open the stream + * + * @param string $path the path to open + * @param string $mode mode for opening + * @param string $options options for opening + * @param string $opened_path full path that was actually opened + * @return bool + */ + public function stream_open($path, $mode, $options, $opened_path) + { + $this->path = $path; + self::recordMethodCall('stream_open', $this->path); + return parent::stream_open($path, $mode, $options, $opened_path); + } + + /** + * closes the stream + */ + public function stream_close() + { + self::recordMethodCall('stream_close', $this->path); + return parent::stream_close(); + } + + /** + * read the stream up to $count bytes + * + * @param int $count amount of bytes to read + * @return string + */ + public function stream_read($count) + { + self::recordMethodCall('stream_read', $this->path); + return parent::stream_read($count); + } + + /** + * writes data into the stream + * + * @param string $data + * @return int amount of bytes written + */ + public function stream_write($data) + { + self::recordMethodCall('stream_write', $this->path); + return parent::stream_write($data); + } + + /** + * checks whether stream is at end of file + * + * @return bool + */ + public function stream_eof() + { + self::recordMethodCall('stream_eof', $this->path); + return parent::stream_eof(); + } + + /** + * returns the current position of the stream + * + * @return int + */ + public function stream_tell() + { + self::recordMethodCall('stream_tell', $this->path); + return parent::stream_tell(); + } + + /** + * seeks to the given offset + * + * @param int $offset + * @param int $whence + * @return bool + */ + public function stream_seek($offset, $whence) + { + self::recordMethodCall('stream_seek', $this->path); + return parent::stream_seek($offset, $whence); + } + + /** + * flushes unstored data into storage + * + * @return bool + */ + public function stream_flush() + { + self::recordMethodCall('stream_flush', $this->path); + return parent::stream_flush(); + } + + /** + * returns status of stream + * + * @return array + */ + public function stream_stat() + { + self::recordMethodCall('stream_stat', $this->path); + return parent::stream_stat(); + } + + /** + * retrieve the underlaying resource + * + * @param int $cast_as + * @return bool + */ + public function stream_cast($cast_as) + { + self::recordMethodCall('stream_cast', $this->path); + return parent::stream_cast($cast_as); + } + + /** + * set lock status for stream + * + * @param int $operation + * @return bool + */ + public function stream_lock($operation) + { + self::recordMethodCall('stream_link', $this->path); + return parent::stream_lock($operation); + } + + /** + * remove the data under the given path + * + * @param string $path + * @return bool + */ + public function unlink($path) + { + self::recordMethodCall('unlink', $path); + return parent::unlink($path); + } + + /** + * rename from one path to another + * + * @param string $path_from + * @param string $path_to + * @return bool + */ + public function rename($path_from, $path_to) + { + self::recordMethodCall('rename', $path_from); + return parent::rename($path_from, $path_to); + } + + /** + * creates a new directory + * + * @param string $path + * @param int $mode + * @param int $options + * @return bool + */ + public function mkdir($path, $mode, $options) + { + self::recordMethodCall('mkdir', $path); + return parent::mkdir($path, $mode, $options); + } + + /** + * removes a directory + * + * @param string $path + * @param int $options + * @return bool + */ + public function rmdir($path, $options) + { + self::recordMethodCall('rmdir', $path); + return parent::rmdir($path, $options); + } + + /** + * opens a directory + * + * @param string $path + * @param int $options + * @return bool + */ + public function dir_opendir($path, $options) + { + $this->path = $path; + self::recordMethodCall('dir_opendir', $this->path); + return parent::dir_opendir($path, $options); + } + + /** + * reads directory contents + * + * @return string + */ + public function dir_readdir() + { + self::recordMethodCall('dir_readdir', $this->path); + return parent::dir_readdir(); + } + + /** + * reset directory iteration + * + * @return bool + */ + public function dir_rewinddir() + { + self::recordMethodCall('dir_rewinddir', $this->path); + return parent::dir_rewinddir(); + } + + /** + * closes directory + * + * @return bool + */ + public function dir_closedir() + { + self::recordMethodCall('dir_closedir', $this->path); + return parent::dir_closedir(); + } + + /** + * returns status of url + * + * @param string $path path of url to return status for + * @param int $flags flags set by the stream API + * @return array + */ + public function url_stat($path, $flags) + { + self::recordMethodCall('url_stat', $path); + return parent::url_stat($path, $flags); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamAbstractContentTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamAbstractContentTestCase.php new file mode 100644 index 0000000..faff3d6 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamAbstractContentTestCase.php @@ -0,0 +1,1053 @@ +assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executePermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0100); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executePermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0010); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executePermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0001); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function writePermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0200); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function writePermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0020); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function writePermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0002); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executeAndWritePermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0300); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executeAndWritePermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0030); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function executeAndWritePermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0003); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readPermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0400); + $this->assertTrue($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readPermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0040); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readPermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0004); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndExecutePermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0500); + $this->assertTrue($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndExecutePermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0050); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndExecutePermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0005); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndWritePermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0600); + $this->assertTrue($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndWritePermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0060); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function readAndWritePermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0006); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function allPermissionsForUser() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0700); + $this->assertTrue($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertTrue($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function allPermissionsForGroup() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0070); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + -1 + ) + ); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function allPermissionsForOther() + { + $abstractContent = new TestvfsStreamAbstractContent('foo', 0007); + $this->assertFalse($abstractContent->isReadable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isReadable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isReadable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isWritable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isWritable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isWritable(-1, + -1 + ) + ); + $this->assertFalse($abstractContent->isExecutable(vfsStream::getCurrentUser(), + vfsStream::getCurrentGroup() + ) + ); + $this->assertFalse($abstractContent->isExecutable(-1, + vfsStream::getCurrentGroup() + ) + ); + $this->assertTrue($abstractContent->isExecutable(-1, + -1 + ) + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamBlockTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamBlockTestCase.php new file mode 100644 index 0000000..cd8e1a4 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamBlockTestCase.php @@ -0,0 +1,89 @@ +block = new vfsStreamBlock('foo'); + } + + /** + * test default values and methods + * + * @test + */ + public function defaultValues() + { + $this->assertEquals(vfsStreamContent::TYPE_BLOCK, $this->block->getType()); + $this->assertEquals('foo', $this->block->getName()); + $this->assertTrue($this->block->appliesTo('foo')); + $this->assertFalse($this->block->appliesTo('foo/bar')); + $this->assertFalse($this->block->appliesTo('bar')); + } + + /** + * tests how external functions see this object + * + * @test + */ + public function external() + { + $root = vfsStream::setup('root'); + $root->addChild(vfsStream::newBlock('foo')); + $this->assertEquals('block', filetype(vfsStream::url('root/foo'))); + } + + /** + * tests adding a complex structure + * + * @test + */ + public function addStructure() + { + $structure = array( + 'topLevel' => array( + 'thisIsAFile' => 'file contents', + '[blockDevice]' => 'block contents' + ) + ); + + $root = vfsStream::create($structure); + + $this->assertSame('block', filetype(vfsStream::url('root/topLevel/blockDevice'))); + } + + /** + * tests that a blank name for a block device throws an exception + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + */ + public function createWithEmptyName() + { + $structure = array( + 'topLevel' => array( + 'thisIsAFile' => 'file contents', + '[]' => 'block contents' + ) + ); + + $root = vfsStream::create($structure); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamContainerIteratorTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamContainerIteratorTestCase.php new file mode 100644 index 0000000..934e014 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamContainerIteratorTestCase.php @@ -0,0 +1,111 @@ +dir = new vfsStreamDirectory('foo'); + $this->mockChild1 = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $this->mockChild1->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + $this->dir->addChild($this->mockChild1); + $this->mockChild2 = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $this->mockChild2->expects($this->any()) + ->method('getName') + ->will($this->returnValue('baz')); + $this->dir->addChild($this->mockChild2); + } + + /** + * clean up test environment + */ + public function tearDown() + { + vfsStream::enableDotfiles(); + } + + /** + * @return array + */ + public function provideSwitchWithExpectations() + { + return array(array(function() { vfsStream::disableDotfiles(); }, + array() + ), + array(function() { vfsStream::enableDotfiles(); }, + array('.', '..') + ) + ); + } + + private function getDirName($dir) + { + if (is_string($dir)) { + return $dir; + } + + + return $dir->getName(); + } + + /** + * @param \Closure $dotFilesSwitch + * @param array $dirNames + * @test + * @dataProvider provideSwitchWithExpectations + */ + public function iteration(\Closure $dotFilesSwitch, array $dirs) + { + $dirs[] = $this->mockChild1; + $dirs[] = $this->mockChild2; + $dotFilesSwitch(); + $dirIterator = $this->dir->getIterator(); + foreach ($dirs as $dir) { + $this->assertEquals($this->getDirName($dir), $dirIterator->key()); + $this->assertTrue($dirIterator->valid()); + if (!is_string($dir)) { + $this->assertSame($dir, $dirIterator->current()); + } + + $dirIterator->next(); + } + + $this->assertFalse($dirIterator->valid()); + $this->assertNull($dirIterator->key()); + $this->assertNull($dirIterator->current()); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue134TestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue134TestCase.php new file mode 100644 index 0000000..c1c0dda --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue134TestCase.php @@ -0,0 +1,64 @@ +rootDirectory = vfsStream::newDirectory('/'); + $this->rootDirectory->addChild(vfsStream::newDirectory('var/log/app')); + + } + + /** + * Test: should save directory name as string internal + * + * @small + */ + public function testShouldSaveDirectoryNameAsStringInternal() + { + $dir = $this->rootDirectory->getChild('var/log/app'); + + $dir->addChild(vfsStream::newDirectory(80)); + + static::assertNotNull($this->rootDirectory->getChild('var/log/app/80')); + } + + + + /** + * Test: should rename directory name as string internal + * + * @small + */ + public function testShouldRenameDirectoryNameAsStringInternal() + { + $dir = $this->rootDirectory->getChild('var/log/app'); + + $dir->addChild(vfsStream::newDirectory(80)); + + $child = $this->rootDirectory->getChild('var/log/app/80'); + $child->rename(90); + + static::assertNotNull($this->rootDirectory->getChild('var/log/app/90')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue18TestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue18TestCase.php new file mode 100644 index 0000000..fdf45b2 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryIssue18TestCase.php @@ -0,0 +1,80 @@ +rootDirectory = vfsStream::newDirectory('/'); + $this->rootDirectory->addChild(vfsStream::newDirectory('var/log/app')); + $dir = $this->rootDirectory->getChild('var/log/app'); + $dir->addChild(vfsStream::newDirectory('app1')); + $dir->addChild(vfsStream::newDirectory('app2')); + $dir->addChild(vfsStream::newDirectory('foo')); + } + + /** + * @test + */ + public function shouldContainThreeSubdirectories() + { + $this->assertEquals(3, + count($this->rootDirectory->getChild('var/log/app')->getChildren()) + ); + } + + /** + * @test + */ + public function shouldContainSubdirectoryFoo() + { + $this->assertTrue($this->rootDirectory->getChild('var/log/app')->hasChild('foo')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $this->rootDirectory->getChild('var/log/app')->getChild('foo') + ); + } + + /** + * @test + */ + public function shouldContainSubdirectoryApp1() + { + $this->assertTrue($this->rootDirectory->getChild('var/log/app')->hasChild('app1')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $this->rootDirectory->getChild('var/log/app')->getChild('app1') + ); + } + + /** + * @test + */ + public function shouldContainSubdirectoryApp2() + { + $this->assertTrue($this->rootDirectory->getChild('var/log/app')->hasChild('app2')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $this->rootDirectory->getChild('var/log/app')->getChild('app2') + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryTestCase.php new file mode 100644 index 0000000..19ed51b --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamDirectoryTestCase.php @@ -0,0 +1,334 @@ +dir = new vfsStreamDirectory('foo'); + } + + /** + * assure that a directory seperator inside the name throws an exception + * + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + */ + public function invalidCharacterInName() + { + $dir = new vfsStreamDirectory('foo/bar'); + } + + /** + * test default values and methods + * + * @test + */ + public function defaultValues() + { + $this->assertEquals(vfsStreamContent::TYPE_DIR, $this->dir->getType()); + $this->assertEquals('foo', $this->dir->getName()); + $this->assertTrue($this->dir->appliesTo('foo')); + $this->assertTrue($this->dir->appliesTo('foo/bar')); + $this->assertFalse($this->dir->appliesTo('bar')); + $this->assertEquals(array(), $this->dir->getChildren()); + } + + /** + * test renaming the directory + * + * @test + */ + public function rename() + { + $this->dir->rename('bar'); + $this->assertEquals('bar', $this->dir->getName()); + $this->assertFalse($this->dir->appliesTo('foo')); + $this->assertFalse($this->dir->appliesTo('foo/bar')); + $this->assertTrue($this->dir->appliesTo('bar')); + } + + /** + * renaming the directory to an invalid name throws a vfsStreamException + * + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + */ + public function renameToInvalidNameThrowsvfsStreamException() + { + $this->dir->rename('foo/baz'); + } + + /** + * @test + * @since 0.10.0 + */ + public function hasNoChildrenByDefault() + { + $this->assertFalse($this->dir->hasChildren()); + } + + /** + * @test + * @since 0.10.0 + */ + public function hasChildrenReturnsTrueIfAtLeastOneChildPresent() + { + $mockChild = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild->expects($this->any()) + ->method('appliesTo') + ->will($this->returnValue(false)); + $mockChild->expects($this->any()) + ->method('getName') + ->will($this->returnValue('baz')); + $this->dir->addChild($mockChild); + $this->assertTrue($this->dir->hasChildren()); + } + + /** + * @test + */ + public function hasChildReturnsFalseForNonExistingChild() + { + $this->assertFalse($this->dir->hasChild('bar')); + } + + /** + * @test + */ + public function getChildReturnsNullForNonExistingChild() + { + $this->assertNull($this->dir->getChild('bar')); + } + + /** + * @test + */ + public function removeChildReturnsFalseForNonExistingChild() + { + $this->assertFalse($this->dir->removeChild('bar')); + } + + /** + * @test + */ + public function nonExistingChild() + { + $mockChild = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild->expects($this->any()) + ->method('appliesTo') + ->will($this->returnValue(false)); + $mockChild->expects($this->any()) + ->method('getName') + ->will($this->returnValue('baz')); + $this->dir->addChild($mockChild); + $this->assertFalse($this->dir->removeChild('bar')); + } + + /** + * test that adding, handling and removing of a child works as expected + * + * @test + */ + public function childHandling() + { + $mockChild = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild->expects($this->any()) + ->method('getType') + ->will($this->returnValue(vfsStreamContent::TYPE_FILE)); + $mockChild->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + $mockChild->expects($this->any()) + ->method('appliesTo') + ->with($this->equalTo('bar')) + ->will($this->returnValue(true)); + $mockChild->expects($this->once()) + ->method('size') + ->will($this->returnValue(5)); + $this->dir->addChild($mockChild); + $this->assertTrue($this->dir->hasChild('bar')); + $bar = $this->dir->getChild('bar'); + $this->assertSame($mockChild, $bar); + $this->assertEquals(array($mockChild), $this->dir->getChildren()); + $this->assertEquals(0, $this->dir->size()); + $this->assertEquals(5, $this->dir->sizeSummarized()); + $this->assertTrue($this->dir->removeChild('bar')); + $this->assertEquals(array(), $this->dir->getChildren()); + $this->assertEquals(0, $this->dir->size()); + $this->assertEquals(0, $this->dir->sizeSummarized()); + } + + /** + * test that adding, handling and removing of a child works as expected + * + * @test + */ + public function childHandlingWithSubdirectory() + { + $mockChild = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild->expects($this->any()) + ->method('getType') + ->will($this->returnValue(vfsStreamContent::TYPE_FILE)); + $mockChild->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + $mockChild->expects($this->once()) + ->method('size') + ->will($this->returnValue(5)); + $subdir = new vfsStreamDirectory('subdir'); + $subdir->addChild($mockChild); + $this->dir->addChild($subdir); + $this->assertTrue($this->dir->hasChild('subdir')); + $this->assertSame($subdir, $this->dir->getChild('subdir')); + $this->assertEquals(array($subdir), $this->dir->getChildren()); + $this->assertEquals(0, $this->dir->size()); + $this->assertEquals(5, $this->dir->sizeSummarized()); + $this->assertTrue($this->dir->removeChild('subdir')); + $this->assertEquals(array(), $this->dir->getChildren()); + $this->assertEquals(0, $this->dir->size()); + $this->assertEquals(0, $this->dir->sizeSummarized()); + } + + /** + * dd + * + * @test + * @group regression + * @group bug_5 + */ + public function addChildReplacesChildWithSameName_Bug_5() + { + $mockChild1 = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild1->expects($this->any()) + ->method('getType') + ->will($this->returnValue(vfsStreamContent::TYPE_FILE)); + $mockChild1->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + $mockChild2 = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild2->expects($this->any()) + ->method('getType') + ->will($this->returnValue(vfsStreamContent::TYPE_FILE)); + $mockChild2->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + $this->dir->addChild($mockChild1); + $this->assertTrue($this->dir->hasChild('bar')); + $this->assertSame($mockChild1, $this->dir->getChild('bar')); + $this->dir->addChild($mockChild2); + $this->assertTrue($this->dir->hasChild('bar')); + $this->assertSame($mockChild2, $this->dir->getChild('bar')); + } + + /** + * When testing for a nested path, verify that directory separators are respected properly + * so that subdir1/subdir2 is not considered equal to subdir1Xsubdir2. + * + * @test + * @group bug_24 + * @group regression + */ + public function explicitTestForSeparatorWithNestedPaths_Bug_24() + { + $mockChild = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockChild->expects($this->any()) + ->method('getType') + ->will($this->returnValue(vfsStreamContent::TYPE_FILE)); + $mockChild->expects($this->any()) + ->method('getName') + ->will($this->returnValue('bar')); + + $subdir1 = new vfsStreamDirectory('subdir1'); + $this->dir->addChild($subdir1); + + $subdir2 = new vfsStreamDirectory('subdir2'); + $subdir1->addChild($subdir2); + + $subdir2->addChild($mockChild); + + $this->assertTrue($this->dir->hasChild('subdir1'), "Level 1 path with separator exists"); + $this->assertTrue($this->dir->hasChild('subdir1/subdir2'), "Level 2 path with separator exists"); + $this->assertTrue($this->dir->hasChild('subdir1/subdir2/bar'), "Level 3 path with separator exists"); + $this->assertFalse($this->dir->hasChild('subdir1.subdir2'), "Path with period does not exist"); + $this->assertFalse($this->dir->hasChild('subdir1.subdir2/bar'), "Nested path with period does not exist"); + } + + + /** + * setting and retrieving permissions for a directory + * + * @test + * @group permissions + */ + public function permissions() + { + $this->assertEquals(0777, $this->dir->getPermissions()); + $this->assertSame($this->dir, $this->dir->chmod(0755)); + $this->assertEquals(0755, $this->dir->getPermissions()); + } + + /** + * setting and retrieving permissions for a directory + * + * @test + * @group permissions + */ + public function permissionsSet() + { + $this->dir = new vfsStreamDirectory('foo', 0755); + $this->assertEquals(0755, $this->dir->getPermissions()); + $this->assertSame($this->dir, $this->dir->chmod(0700)); + $this->assertEquals(0700, $this->dir->getPermissions()); + } + + /** + * setting and retrieving owner of a file + * + * @test + * @group permissions + */ + public function owner() + { + $this->assertEquals(vfsStream::getCurrentUser(), $this->dir->getUser()); + $this->assertTrue($this->dir->isOwnedByUser(vfsStream::getCurrentUser())); + $this->assertSame($this->dir, $this->dir->chown(vfsStream::OWNER_USER_1)); + $this->assertEquals(vfsStream::OWNER_USER_1, $this->dir->getUser()); + $this->assertTrue($this->dir->isOwnedByUser(vfsStream::OWNER_USER_1)); + } + + /** + * setting and retrieving owner group of a file + * + * @test + * @group permissions + */ + public function group() + { + $this->assertEquals(vfsStream::getCurrentGroup(), $this->dir->getGroup()); + $this->assertTrue($this->dir->isOwnedByGroup(vfsStream::getCurrentGroup())); + $this->assertSame($this->dir, $this->dir->chgrp(vfsStream::GROUP_USER_1)); + $this->assertEquals(vfsStream::GROUP_USER_1, $this->dir->getGroup()); + $this->assertTrue($this->dir->isOwnedByGroup(vfsStream::GROUP_USER_1)); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamExLockTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamExLockTestCase.php new file mode 100644 index 0000000..66ad14d --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamExLockTestCase.php @@ -0,0 +1,55 @@ +at($root); + + } + + /** + * This test verifies the current behaviour where vfsStream URLs do not work + * with file_put_contents() and LOCK_EX. The test is intended to break once + * PHP changes this so we get notified about the change. + * + * @test + */ + public function filePutContentsLockShouldReportError() + { + @file_put_contents(vfsStream::url('root/testfile'), "some string\n", LOCK_EX); + $php_error = error_get_last(); + $this->assertEquals("file_put_contents(): Exclusive locks may only be set for regular files", $php_error['message']); + } + + /** + * @test + */ + public function flockSouldPass() + { + $fp = fopen(vfsStream::url('root/testfile'), 'w'); + flock($fp, LOCK_EX); + fwrite($fp, "another string\n"); + flock($fp, LOCK_UN); + fclose($fp); + $this->assertEquals("another string\n", file_get_contents(vfsStream::url('root/testfile'))); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamFileTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamFileTestCase.php new file mode 100644 index 0000000..82b74f1 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamFileTestCase.php @@ -0,0 +1,337 @@ +file = new vfsStreamFile('foo'); + } + + /** + * test default values and methods + * + * @test + */ + public function defaultValues() + { + $this->assertEquals(vfsStreamContent::TYPE_FILE, $this->file->getType()); + $this->assertEquals('foo', $this->file->getName()); + $this->assertTrue($this->file->appliesTo('foo')); + $this->assertFalse($this->file->appliesTo('foo/bar')); + $this->assertFalse($this->file->appliesTo('bar')); + } + + /** + * test setting and getting the content of a file + * + * @test + */ + public function content() + { + $this->assertNull($this->file->getContent()); + $this->assertSame($this->file, $this->file->setContent('bar')); + $this->assertEquals('bar', $this->file->getContent()); + $this->assertSame($this->file, $this->file->withContent('baz')); + $this->assertEquals('baz', $this->file->getContent()); + } + + /** + * test renaming the directory + * + * @test + */ + public function rename() + { + $this->file->rename('bar'); + $this->assertEquals('bar', $this->file->getName()); + $this->assertFalse($this->file->appliesTo('foo')); + $this->assertFalse($this->file->appliesTo('foo/bar')); + $this->assertTrue($this->file->appliesTo('bar')); + } + + /** + * test reading contents from the file + * + * @test + */ + public function readEmptyFile() + { + $this->assertTrue($this->file->eof()); + $this->assertEquals(0, $this->file->size()); + $this->assertEquals('', $this->file->read(5)); + $this->assertEquals(5, $this->file->getBytesRead()); + $this->assertTrue($this->file->eof()); + } + + /** + * test reading contents from the file + * + * @test + */ + public function read() + { + $this->file->setContent('foobarbaz'); + $this->assertFalse($this->file->eof()); + $this->assertEquals(9, $this->file->size()); + $this->assertEquals('foo', $this->file->read(3)); + $this->assertEquals(3, $this->file->getBytesRead()); + $this->assertFalse($this->file->eof()); + $this->assertEquals(9, $this->file->size()); + $this->assertEquals('bar', $this->file->read(3)); + $this->assertEquals(6, $this->file->getBytesRead()); + $this->assertFalse($this->file->eof()); + $this->assertEquals(9, $this->file->size()); + $this->assertEquals('baz', $this->file->read(3)); + $this->assertEquals(9, $this->file->getBytesRead()); + $this->assertEquals(9, $this->file->size()); + $this->assertTrue($this->file->eof()); + $this->assertEquals('', $this->file->read(3)); + } + + /** + * test seeking to offset + * + * @test + */ + public function seekEmptyFile() + { + $this->assertFalse($this->file->seek(0, 55)); + $this->assertTrue($this->file->seek(0, SEEK_SET)); + $this->assertEquals(0, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(5, SEEK_SET)); + $this->assertEquals(5, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(0, SEEK_CUR)); + $this->assertEquals(5, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(2, SEEK_CUR)); + $this->assertEquals(7, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(0, SEEK_END)); + $this->assertEquals(0, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(2, SEEK_END)); + $this->assertEquals(2, $this->file->getBytesRead()); + } + + /** + * @test + * @since 1.6.5 + */ + public function seekEmptyFileBeforeBeginningDoesNotChangeOffset() + { + $this->assertFalse($this->file->seek(-5, SEEK_SET), 'Seek before beginning of file'); + $this->assertEquals(0, $this->file->getBytesRead()); + } + + /** + * test seeking to offset + * + * @test + */ + public function seekRead() + { + $this->file->setContent('foobarbaz'); + $this->assertFalse($this->file->seek(0, 55)); + $this->assertTrue($this->file->seek(0, SEEK_SET)); + $this->assertEquals('foobarbaz', $this->file->readUntilEnd()); + $this->assertEquals(0, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(5, SEEK_SET)); + $this->assertEquals('rbaz', $this->file->readUntilEnd()); + $this->assertEquals(5, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(0, SEEK_CUR)); + $this->assertEquals('rbaz', $this->file->readUntilEnd()); + $this->assertEquals(5, $this->file->getBytesRead(), 5); + $this->assertTrue($this->file->seek(2, SEEK_CUR)); + $this->assertEquals('az', $this->file->readUntilEnd()); + $this->assertEquals(7, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(0, SEEK_END)); + $this->assertEquals('', $this->file->readUntilEnd()); + $this->assertEquals(9, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(2, SEEK_END)); + $this->assertEquals('', $this->file->readUntilEnd()); + $this->assertEquals(11, $this->file->getBytesRead()); + } + + /** + * @test + * @since 1.6.5 + */ + public function seekFileBeforeBeginningDoesNotChangeOffset() + { + $this->file->setContent('foobarbaz'); + $this->assertFalse($this->file->seek(-5, SEEK_SET), 'Seek before beginning of file'); + $this->assertEquals(0, $this->file->getBytesRead()); + $this->assertTrue($this->file->seek(2, SEEK_CUR)); + $this->assertFalse($this->file->seek(-5, SEEK_SET), 'Seek before beginning of file'); + $this->assertEquals(2, $this->file->getBytesRead()); + $this->assertEquals('obarbaz', $this->file->readUntilEnd()); + $this->assertFalse($this->file->seek(-5, SEEK_CUR), 'Seek before beginning of file'); + $this->assertEquals(2, $this->file->getBytesRead()); + $this->assertEquals('obarbaz', $this->file->readUntilEnd()); + $this->assertFalse($this->file->seek(-20, SEEK_END), 'Seek before beginning of file'); + $this->assertEquals(2, $this->file->getBytesRead()); + $this->assertEquals('obarbaz', $this->file->readUntilEnd()); + } + + /** + * test writing data into the file + * + * @test + */ + public function writeEmptyFile() + { + $this->assertEquals(3, $this->file->write('foo')); + $this->assertEquals('foo', $this->file->getContent()); + $this->assertEquals(3, $this->file->size()); + $this->assertEquals(3, $this->file->write('bar')); + $this->assertEquals('foobar', $this->file->getContent()); + $this->assertEquals(6, $this->file->size()); + } + + /** + * test writing data into the file + * + * @test + */ + public function write() + { + $this->file->setContent('foobarbaz'); + $this->assertTrue($this->file->seek(3, SEEK_SET)); + $this->assertEquals(3, $this->file->write('foo')); + $this->assertEquals('foofoobaz', $this->file->getContent()); + $this->assertEquals(9, $this->file->size()); + $this->assertEquals(3, $this->file->write('bar')); + $this->assertEquals('foofoobar', $this->file->getContent()); + $this->assertEquals(9, $this->file->size()); + } + + /** + * setting and retrieving permissions for a file + * + * @test + * @group permissions + */ + public function permissions() + { + $this->assertEquals(0666, $this->file->getPermissions()); + $this->assertSame($this->file, $this->file->chmod(0644)); + $this->assertEquals(0644, $this->file->getPermissions()); + } + + /** + * setting and retrieving permissions for a file + * + * @test + * @group permissions + */ + public function permissionsSet() + { + $this->file = new vfsStreamFile('foo', 0644); + $this->assertEquals(0644, $this->file->getPermissions()); + $this->assertSame($this->file, $this->file->chmod(0600)); + $this->assertEquals(0600, $this->file->getPermissions()); + } + + /** + * setting and retrieving owner of a file + * + * @test + * @group permissions + */ + public function owner() + { + $this->assertEquals(vfsStream::getCurrentUser(), $this->file->getUser()); + $this->assertTrue($this->file->isOwnedByUser(vfsStream::getCurrentUser())); + $this->assertSame($this->file, $this->file->chown(vfsStream::OWNER_USER_1)); + $this->assertEquals(vfsStream::OWNER_USER_1, $this->file->getUser()); + $this->assertTrue($this->file->isOwnedByUser(vfsStream::OWNER_USER_1)); + } + + /** + * setting and retrieving owner group of a file + * + * @test + * @group permissions + */ + public function group() + { + $this->assertEquals(vfsStream::getCurrentGroup(), $this->file->getGroup()); + $this->assertTrue($this->file->isOwnedByGroup(vfsStream::getCurrentGroup())); + $this->assertSame($this->file, $this->file->chgrp(vfsStream::GROUP_USER_1)); + $this->assertEquals(vfsStream::GROUP_USER_1, $this->file->getGroup()); + $this->assertTrue($this->file->isOwnedByGroup(vfsStream::GROUP_USER_1)); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateRemovesSuperflouosContent() + { + $this->assertEquals(11, $this->file->write("lorem ipsum")); + $this->assertTrue($this->file->truncate(5)); + $this->assertEquals(5, $this->file->size()); + $this->assertEquals('lorem', $this->file->getContent()); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + */ + public function truncateToGreaterSizeAddsZeroBytes() + { + $this->assertEquals(11, $this->file->write("lorem ipsum")); + $this->assertTrue($this->file->truncate(25)); + $this->assertEquals(25, $this->file->size()); + $this->assertEquals("lorem ipsum\0\0\0\0\0\0\0\0\0\0\0\0\0\0", $this->file->getContent()); + } + + /** + * @test + * @group issue_79 + * @since 1.3.0 + */ + public function withContentAcceptsAnyFileContentInstance() + { + $mockFileContent = $this->bc_getMock('org\bovigo\vfs\content\FileContent'); + $mockFileContent->expects($this->once()) + ->method('content') + ->will($this->returnValue('foobarbaz')); + $this->assertEquals( + 'foobarbaz', + $this->file->withContent($mockFileContent) + ->getContent() + ); + } + + /** + * @test + * @group issue_79 + * @expectedException \InvalidArgumentException + * @since 1.3.0 + */ + public function withContentThrowsInvalidArgumentExceptionWhenContentIsNoStringAndNoFileContent() + { + $this->file->withContent(313); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamGlobTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamGlobTestCase.php new file mode 100644 index 0000000..2dec563 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamGlobTestCase.php @@ -0,0 +1,28 @@ +assertEmpty(glob(vfsStream::url('example'), GLOB_MARK)); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamResolveIncludePathTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamResolveIncludePathTestCase.php new file mode 100644 index 0000000..74fb773 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamResolveIncludePathTestCase.php @@ -0,0 +1,61 @@ +backupIncludePath = get_include_path(); + vfsStream::setup(); + mkdir('vfs://root/a/path', 0777, true); + set_include_path('vfs://root/a' . PATH_SEPARATOR . $this->backupIncludePath); + } + + /** + * clean up test environment + */ + public function tearDown() + { + set_include_path($this->backupIncludePath); + } + + /** + * @test + */ + public function knownFileCanBeResolved() + { + file_put_contents('vfs://root/a/path/knownFile.php', ''); + $this->assertEquals('vfs://root/a/path/knownFile.php', stream_resolve_include_path('path/knownFile.php')); + } + + /** + * @test + */ + public function unknownFileCanNotBeResolvedYieldsFalse() + { + $this->assertFalse(@stream_resolve_include_path('path/unknownFile.php')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamTestCase.php new file mode 100644 index 0000000..cc2bad7 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamTestCase.php @@ -0,0 +1,780 @@ +assertEquals('vfs://foo', vfsStream::url('foo')); + $this->assertEquals('vfs://foo/bar.baz', vfsStream::url('foo/bar.baz')); + $this->assertEquals('vfs://foo/bar.baz', vfsStream::url('foo\bar.baz')); + } + + /** + * assure that url2path conversion works correct + * + * @test + */ + public function path() + { + $this->assertEquals('foo', vfsStream::path('vfs://foo')); + $this->assertEquals('foo/bar.baz', vfsStream::path('vfs://foo/bar.baz')); + $this->assertEquals('foo/bar.baz', vfsStream::path('vfs://foo\bar.baz')); + } + + /** + * windows directory separators are converted into default separator + * + * @author Gabriel Birke + * @test + */ + public function pathConvertsWindowsDirectorySeparators() + { + $this->assertEquals('foo/bar', vfsStream::path('vfs://foo\\bar')); + } + + /** + * trailing whitespace should be removed + * + * @author Gabriel Birke + * @test + */ + public function pathRemovesTrailingWhitespace() + { + $this->assertEquals('foo/bar', vfsStream::path('vfs://foo/bar ')); + } + + /** + * trailing slashes are removed + * + * @author Gabriel Birke + * @test + */ + public function pathRemovesTrailingSlash() + { + $this->assertEquals('foo/bar', vfsStream::path('vfs://foo/bar/')); + } + + /** + * trailing slash and whitespace should be removed + * + * @author Gabriel Birke + * @test + */ + public function pathRemovesTrailingSlashAndWhitespace() + { + $this->assertEquals('foo/bar', vfsStream::path('vfs://foo/bar/ ')); + } + + /** + * double slashes should be replaced by single slash + * + * @author Gabriel Birke + * @test + */ + public function pathRemovesDoubleSlashes() + { + // Regular path + $this->assertEquals('my/path', vfsStream::path('vfs://my/path')); + // Path with double slashes + $this->assertEquals('my/path', vfsStream::path('vfs://my//path')); + } + + /** + * test to create a new file + * + * @test + */ + public function newFile() + { + $file = vfsStream::newFile('filename.txt'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamFile', $file); + $this->assertEquals('filename.txt', $file->getName()); + $this->assertEquals(0666, $file->getPermissions()); + } + + /** + * test to create a new file with non-default permissions + * + * @test + * @group permissions + */ + public function newFileWithDifferentPermissions() + { + $file = vfsStream::newFile('filename.txt', 0644); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamFile', $file); + $this->assertEquals('filename.txt', $file->getName()); + $this->assertEquals(0644, $file->getPermissions()); + } + + /** + * test to create a new directory structure + * + * @test + */ + public function newSingleDirectory() + { + $foo = vfsStream::newDirectory('foo'); + $this->assertEquals('foo', $foo->getName()); + $this->assertEquals(0, count($foo->getChildren())); + $this->assertEquals(0777, $foo->getPermissions()); + } + + /** + * test to create a new directory structure with non-default permissions + * + * @test + * @group permissions + */ + public function newSingleDirectoryWithDifferentPermissions() + { + $foo = vfsStream::newDirectory('foo', 0755); + $this->assertEquals('foo', $foo->getName()); + $this->assertEquals(0, count($foo->getChildren())); + $this->assertEquals(0755, $foo->getPermissions()); + } + + /** + * test to create a new directory structure + * + * @test + */ + public function newDirectoryStructure() + { + $foo = vfsStream::newDirectory('foo/bar/baz'); + $this->assertEquals('foo', $foo->getName()); + $this->assertEquals(0777, $foo->getPermissions()); + $this->assertTrue($foo->hasChild('bar')); + $this->assertTrue($foo->hasChild('bar/baz')); + $this->assertFalse($foo->hasChild('baz')); + $bar = $foo->getChild('bar'); + $this->assertEquals('bar', $bar->getName()); + $this->assertEquals(0777, $bar->getPermissions()); + $this->assertTrue($bar->hasChild('baz')); + $baz1 = $bar->getChild('baz'); + $this->assertEquals('baz', $baz1->getName()); + $this->assertEquals(0777, $baz1->getPermissions()); + $baz2 = $foo->getChild('bar/baz'); + $this->assertSame($baz1, $baz2); + } + + /** + * test that correct directory structure is created + * + * @test + */ + public function newDirectoryWithSlashAtStart() + { + $foo = vfsStream::newDirectory('/foo/bar/baz', 0755); + $this->assertEquals('foo', $foo->getName()); + $this->assertEquals(0755, $foo->getPermissions()); + $this->assertTrue($foo->hasChild('bar')); + $this->assertTrue($foo->hasChild('bar/baz')); + $this->assertFalse($foo->hasChild('baz')); + $bar = $foo->getChild('bar'); + $this->assertEquals('bar', $bar->getName()); + $this->assertEquals(0755, $bar->getPermissions()); + $this->assertTrue($bar->hasChild('baz')); + $baz1 = $bar->getChild('baz'); + $this->assertEquals('baz', $baz1->getName()); + $this->assertEquals(0755, $baz1->getPermissions()); + $baz2 = $foo->getChild('bar/baz'); + $this->assertSame($baz1, $baz2); + } + + /** + * @test + * @group setup + * @since 0.7.0 + */ + public function setupRegistersStreamWrapperAndCreatesRootDirectoryWithDefaultNameAndPermissions() + { + $root = vfsStream::setup(); + $this->assertSame($root, vfsStreamWrapper::getRoot()); + $this->assertEquals('root', $root->getName()); + $this->assertEquals(0777, $root->getPermissions()); + } + + /** + * @test + * @group setup + * @since 0.7.0 + */ + public function setupRegistersStreamWrapperAndCreatesRootDirectoryWithGivenNameAndDefaultPermissions() + { + $root = vfsStream::setup('foo'); + $this->assertSame($root, vfsStreamWrapper::getRoot()); + $this->assertEquals('foo', $root->getName()); + $this->assertEquals(0777, $root->getPermissions()); + } + + /** + * @test + * @group setup + * @since 0.7.0 + */ + public function setupRegistersStreamWrapperAndCreatesRootDirectoryWithGivenNameAndPermissions() + { + $root = vfsStream::setup('foo', 0444); + $this->assertSame($root, vfsStreamWrapper::getRoot()); + $this->assertEquals('foo', $root->getName()); + $this->assertEquals(0444, $root->getPermissions()); + } + + /** + * @test + * @group issue_14 + * @group issue_20 + * @since 0.10.0 + */ + public function setupWithEmptyArrayIsEqualToSetup() + { + $root = vfsStream::setup('example', + 0755, + array() + ); + $this->assertEquals('example', $root->getName()); + $this->assertEquals(0755, $root->getPermissions()); + $this->assertFalse($root->hasChildren()); + } + + /** + * @test + * @group issue_14 + * @group issue_20 + * @since 0.10.0 + */ + public function setupArraysAreTurnedIntoSubdirectories() + { + $root = vfsStream::setup('root', + null, + array('test' => array()) + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $root->getChild('test') + ); + $this->assertFalse($root->getChild('test')->hasChildren()); + } + + /** + * @test + * @group issue_14 + * @group issue_20 + * @since 0.10.0 + */ + public function setupStringsAreTurnedIntoFilesWithContent() + { + $root = vfsStream::setup('root', + null, + array('test.txt' => 'some content') + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test.txt')); + $this->assertVfsFile($root->getChild('test.txt'), 'some content'); + } + + /** + * @test + * @group issue_14 + * @group issue_20 + * @since 0.10.0 + */ + public function setupWorksRecursively() + { + $root = vfsStream::setup('root', + null, + array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ) + ) + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test')); + $test = $root->getChild('test'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $test); + $this->assertTrue($test->hasChildren()); + $this->assertTrue($test->hasChild('baz.txt')); + $this->assertVfsFile($test->getChild('baz.txt'), 'world'); + + $this->assertTrue($test->hasChild('foo')); + $foo = $test->getChild('foo'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $foo); + $this->assertTrue($foo->hasChildren()); + $this->assertTrue($foo->hasChild('test.txt')); + $this->assertVfsFile($foo->getChild('test.txt'), 'hello'); + } + + /** + * @test + * @group issue_17 + * @group issue_20 + */ + public function setupCastsNumericDirectoriesToStrings() + { + $root = vfsStream::setup('root', + null, + array(2011 => array ('test.txt' => 'some content')) + ); + $this->assertTrue($root->hasChild('2011')); + + $directory = $root->getChild('2011'); + $this->assertVfsFile($directory->getChild('test.txt'), 'some content'); + + $this->assertTrue(file_exists('vfs://root/2011/test.txt')); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createArraysAreTurnedIntoSubdirectories() + { + $baseDir = vfsStream::create(array('test' => array()), new vfsStreamDirectory('baseDir')); + $this->assertTrue($baseDir->hasChildren()); + $this->assertTrue($baseDir->hasChild('test')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $baseDir->getChild('test') + ); + $this->assertFalse($baseDir->getChild('test')->hasChildren()); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createArraysAreTurnedIntoSubdirectoriesOfRoot() + { + $root = vfsStream::setup(); + $this->assertSame($root, vfsStream::create(array('test' => array()))); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test')); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', + $root->getChild('test') + ); + $this->assertFalse($root->getChild('test')->hasChildren()); + } + + /** + * @test + * @group issue_20 + * @expectedException \InvalidArgumentException + * @since 0.11.0 + */ + public function createThrowsExceptionIfNoBaseDirGivenAndNoRootSet() + { + vfsStream::create(array('test' => array())); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createWorksRecursively() + { + $baseDir = vfsStream::create(array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ) + ), + new vfsStreamDirectory('baseDir') + ); + $this->assertTrue($baseDir->hasChildren()); + $this->assertTrue($baseDir->hasChild('test')); + $test = $baseDir->getChild('test'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $test); + $this->assertTrue($test->hasChildren()); + $this->assertTrue($test->hasChild('baz.txt')); + $this->assertVfsFile($test->getChild('baz.txt'), 'world'); + + $this->assertTrue($test->hasChild('foo')); + $foo = $test->getChild('foo'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $foo); + $this->assertTrue($foo->hasChildren()); + $this->assertTrue($foo->hasChild('test.txt')); + $this->assertVfsFile($foo->getChild('test.txt'), 'hello'); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createWorksRecursivelyWithRoot() + { + $root = vfsStream::setup(); + $this->assertSame($root, + vfsStream::create(array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ) + ) + ) + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test')); + $test = $root->getChild('test'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $test); + $this->assertTrue($test->hasChildren()); + $this->assertTrue($test->hasChild('baz.txt')); + $this->assertVfsFile($test->getChild('baz.txt'), 'world'); + + $this->assertTrue($test->hasChild('foo')); + $foo = $test->getChild('foo'); + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamDirectory', $foo); + $this->assertTrue($foo->hasChildren()); + $this->assertTrue($foo->hasChild('test.txt')); + $this->assertVfsFile($foo->getChild('test.txt'), 'hello'); + } + + /** + * @test + * @group issue_20 + * @since 0.10.0 + */ + public function createStringsAreTurnedIntoFilesWithContent() + { + $baseDir = vfsStream::create(array('test.txt' => 'some content'), new vfsStreamDirectory('baseDir')); + $this->assertTrue($baseDir->hasChildren()); + $this->assertTrue($baseDir->hasChild('test.txt')); + $this->assertVfsFile($baseDir->getChild('test.txt'), 'some content'); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createStringsAreTurnedIntoFilesWithContentWithRoot() + { + $root = vfsStream::setup(); + $this->assertSame($root, + vfsStream::create(array('test.txt' => 'some content')) + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('test.txt')); + $this->assertVfsFile($root->getChild('test.txt'), 'some content'); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createCastsNumericDirectoriesToStrings() + { + $baseDir = vfsStream::create(array(2011 => array ('test.txt' => 'some content')), new vfsStreamDirectory('baseDir')); + $this->assertTrue($baseDir->hasChild('2011')); + + $directory = $baseDir->getChild('2011'); + $this->assertVfsFile($directory->getChild('test.txt'), 'some content'); + } + + /** + * @test + * @group issue_20 + * @since 0.11.0 + */ + public function createCastsNumericDirectoriesToStringsWithRoot() + { + $root = vfsStream::setup(); + $this->assertSame($root, + vfsStream::create(array(2011 => array ('test.txt' => 'some content'))) + ); + $this->assertTrue($root->hasChild('2011')); + + $directory = $root->getChild('2011'); + $this->assertVfsFile($directory->getChild('test.txt'), 'some content'); + } + + /** + * helper function for assertions on vfsStreamFile + * + * @param vfsStreamFile $file + * @param string $content + */ + protected function assertVfsFile(vfsStreamFile $file, $content) + { + $this->assertInstanceOf('org\\bovigo\\vfs\\vfsStreamFile', + $file + ); + $this->assertEquals($content, + $file->getContent() + ); + } + + /** + * @test + * @group issue_10 + * @since 0.10.0 + */ + public function inspectWithContentGivesContentToVisitor() + { + $mockContent = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockVisitor = $this->bc_getMock('org\\bovigo\\vfs\\visitor\\vfsStreamVisitor'); + $mockVisitor->expects($this->once()) + ->method('visit') + ->with($this->equalTo($mockContent)) + ->will($this->returnValue($mockVisitor)); + $this->assertSame($mockVisitor, vfsStream::inspect($mockVisitor, $mockContent)); + } + + /** + * @test + * @group issue_10 + * @since 0.10.0 + */ + public function inspectWithoutContentGivesRootToVisitor() + { + $root = vfsStream::setup(); + $mockVisitor = $this->bc_getMock('org\\bovigo\\vfs\\visitor\\vfsStreamVisitor'); + $mockVisitor->expects($this->once()) + ->method('visitDirectory') + ->with($this->equalTo($root)) + ->will($this->returnValue($mockVisitor)); + $this->assertSame($mockVisitor, vfsStream::inspect($mockVisitor)); + } + + /** + * @test + * @group issue_10 + * @expectedException \InvalidArgumentException + * @since 0.10.0 + */ + public function inspectWithoutContentAndWithoutRootThrowsInvalidArgumentException() + { + $mockVisitor = $this->bc_getMock('org\\bovigo\\vfs\\visitor\\vfsStreamVisitor'); + $mockVisitor->expects($this->never()) + ->method('visit'); + $mockVisitor->expects($this->never()) + ->method('visitDirectory'); + vfsStream::inspect($mockVisitor); + } + + /** + * returns path to file system copy resource directory + * + * @return string + */ + protected function getFileSystemCopyDir() + { + return realpath(dirname(__FILE__) . '/../../../../resources/filesystemcopy'); + } + + /** + * @test + * @group issue_4 + * @expectedException \InvalidArgumentException + * @since 0.11.0 + */ + public function copyFromFileSystemThrowsExceptionIfNoBaseDirGivenAndNoRootSet() + { + vfsStream::copyFromFileSystem($this->getFileSystemCopyDir()); + } + + /** + * @test + * @group issue_4 + * @since 0.11.0 + */ + public function copyFromEmptyFolder() + { + $baseDir = vfsStream::copyFromFileSystem($this->getFileSystemCopyDir() . '/emptyFolder', + vfsStream::newDirectory('test') + ); + $baseDir->removeChild('.gitignore'); + $this->assertFalse($baseDir->hasChildren()); + } + + /** + * @test + * @group issue_4 + * @since 0.11.0 + */ + public function copyFromEmptyFolderWithRoot() + { + $root = vfsStream::setup(); + $this->assertEquals($root, + vfsStream::copyFromFileSystem($this->getFileSystemCopyDir() . '/emptyFolder') + ); + $root->removeChild('.gitignore'); + $this->assertFalse($root->hasChildren()); + } + + /** + * @test + * @group issue_4 + * @since 0.11.0 + */ + public function copyFromWithSubFolders() + { + $baseDir = vfsStream::copyFromFileSystem($this->getFileSystemCopyDir(), + vfsStream::newDirectory('test'), + 3 + ); + $this->assertTrue($baseDir->hasChildren()); + $this->assertTrue($baseDir->hasChild('emptyFolder')); + $this->assertTrue($baseDir->hasChild('withSubfolders')); + $subfolderDir = $baseDir->getChild('withSubfolders'); + $this->assertTrue($subfolderDir->hasChild('subfolder1')); + $this->assertTrue($subfolderDir->getChild('subfolder1')->hasChild('file1.txt')); + $this->assertVfsFile($subfolderDir->getChild('subfolder1/file1.txt'), ' '); + $this->assertTrue($subfolderDir->hasChild('subfolder2')); + $this->assertTrue($subfolderDir->hasChild('aFile.txt')); + $this->assertVfsFile($subfolderDir->getChild('aFile.txt'), 'foo'); + } + + /** + * @test + * @group issue_4 + * @since 0.11.0 + */ + public function copyFromWithSubFoldersWithRoot() + { + $root = vfsStream::setup(); + $this->assertEquals($root, + vfsStream::copyFromFileSystem($this->getFileSystemCopyDir(), + null, + 3 + ) + ); + $this->assertTrue($root->hasChildren()); + $this->assertTrue($root->hasChild('emptyFolder')); + $this->assertTrue($root->hasChild('withSubfolders')); + $subfolderDir = $root->getChild('withSubfolders'); + $this->assertTrue($subfolderDir->hasChild('subfolder1')); + $this->assertTrue($subfolderDir->getChild('subfolder1')->hasChild('file1.txt')); + $this->assertVfsFile($subfolderDir->getChild('subfolder1/file1.txt'), ' '); + $this->assertTrue($subfolderDir->hasChild('subfolder2')); + $this->assertTrue($subfolderDir->hasChild('aFile.txt')); + $this->assertVfsFile($subfolderDir->getChild('aFile.txt'), 'foo'); + } + + /** + * @test + * @group issue_4 + * @group issue_29 + * @since 0.11.2 + */ + public function copyFromPreservesFilePermissions() + { + if (DIRECTORY_SEPARATOR !== '/') { + $this->markTestSkipped('Only applicable on Linux style systems.'); + } + + $copyDir = $this->getFileSystemCopyDir(); + $root = vfsStream::setup(); + $this->assertEquals($root, + vfsStream::copyFromFileSystem($copyDir, + null + ) + ); + $this->assertEquals(fileperms($copyDir . '/withSubfolders') - vfsStreamContent::TYPE_DIR, + $root->getChild('withSubfolders') + ->getPermissions() + ); + $this->assertEquals(fileperms($copyDir . '/withSubfolders/aFile.txt') - vfsStreamContent::TYPE_FILE, + $root->getChild('withSubfolders/aFile.txt') + ->getPermissions() + ); + } + + /** + * To test this the max file size is reduced to something reproduceable. + * + * @test + * @group issue_91 + * @since 1.5.0 + */ + public function copyFromFileSystemMocksLargeFiles() + { + if (DIRECTORY_SEPARATOR !== '/') { + $this->markTestSkipped('Only applicable on Linux style systems.'); + } + + $copyDir = $this->getFileSystemCopyDir(); + $root = vfsStream::setup(); + vfsStream::copyFromFileSystem($copyDir, $root, 3); + $this->assertEquals( + ' ', + $root->getChild('withSubfolders/subfolder1/file1.txt')->getContent() + ); + } + + /** + * @test + * @group issue_121 + * @since 1.6.1 + */ + public function createDirectoryWithTrailingSlashShouldNotCreateSubdirectoryWithEmptyName() + { + $directory = vfsStream::newDirectory('foo/'); + $this->assertFalse($directory->hasChildren()); + } + + /** + * @test + * @group issue_149 + */ + public function addStructureHandlesVfsStreamFileObjects() + { + $structure = array( + 'topLevel' => array( + 'thisIsAFile' => 'file contents', + vfsStream::newFile('anotherFile'), + ), + ); + + vfsStream::setup(); + $root = vfsStream::create($structure); + + $this->assertTrue($root->hasChild('topLevel/anotherFile')); + } + + /** + * @test + * @group issue_149 + */ + public function createHandlesLargeFileContentObjects() + { + $structure = array( + 'topLevel' => array( + 'thisIsAFile' => 'file contents', + 'anotherFile' => LargeFileContent::withMegabytes(2), + ), + ); + + vfsStream::setup(); + $root = vfsStream::create($structure); + + $this->assertTrue($root->hasChild('topLevel/anotherFile')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamUmaskTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamUmaskTestCase.php new file mode 100644 index 0000000..7cac13c --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamUmaskTestCase.php @@ -0,0 +1,194 @@ +assertEquals(vfsStream::umask(), + vfsStream::umask() + ); + $this->assertEquals(0000, + vfsStream::umask() + ); + } + + /** + * @test + */ + public function changingUmaskSettingReturnsOldUmaskSetting() + { + $this->assertEquals(0000, + vfsStream::umask(0022) + ); + $this->assertEquals(0022, + vfsStream::umask() + ); + } + + /** + * @test + */ + public function createFileWithDefaultUmaskSetting() + { + $file = new vfsStreamFile('foo'); + $this->assertEquals(0666, $file->getPermissions()); + } + + /** + * @test + */ + public function createFileWithDifferentUmaskSetting() + { + vfsStream::umask(0022); + $file = new vfsStreamFile('foo'); + $this->assertEquals(0644, $file->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryWithDefaultUmaskSetting() + { + $directory = new vfsStreamDirectory('foo'); + $this->assertEquals(0777, $directory->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryWithDifferentUmaskSetting() + { + vfsStream::umask(0022); + $directory = new vfsStreamDirectory('foo'); + $this->assertEquals(0755, $directory->getPermissions()); + } + + /** + * @test + */ + public function createFileUsingStreamWithDefaultUmaskSetting() + { + $root = vfsStream::setup(); + file_put_contents(vfsStream::url('root/newfile.txt'), 'file content'); + $this->assertEquals(0666, $root->getChild('newfile.txt')->getPermissions()); + } + + /** + * @test + */ + public function createFileUsingStreamWithDifferentUmaskSetting() + { + $root = vfsStream::setup(); + vfsStream::umask(0022); + file_put_contents(vfsStream::url('root/newfile.txt'), 'file content'); + $this->assertEquals(0644, $root->getChild('newfile.txt')->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryUsingStreamWithDefaultUmaskSetting() + { + $root = vfsStream::setup(); + mkdir(vfsStream::url('root/newdir')); + $this->assertEquals(0777, $root->getChild('newdir')->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryUsingStreamWithDifferentUmaskSetting() + { + $root = vfsStream::setup(); + vfsStream::umask(0022); + mkdir(vfsStream::url('root/newdir')); + $this->assertEquals(0755, $root->getChild('newdir')->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryUsingStreamWithExplicit0() + { + $root = vfsStream::setup(); + vfsStream::umask(0022); + mkdir(vfsStream::url('root/newdir'), null); + $this->assertEquals(0000, $root->getChild('newdir')->getPermissions()); + } + + /** + * @test + * + */ + public function createDirectoryUsingStreamWithDifferentUmaskSettingButExplicit0777() + { + $root = vfsStream::setup(); + vfsStream::umask(0022); + mkdir(vfsStream::url('root/newdir'), 0777); + $this->assertEquals(0755, $root->getChild('newdir')->getPermissions()); + } + + /** + * @test + */ + public function createDirectoryUsingStreamWithDifferentUmaskSettingButExplicitModeRequestedByCall() + { + $root = vfsStream::setup(); + vfsStream::umask(0022); + mkdir(vfsStream::url('root/newdir'), 0700); + $this->assertEquals(0700, $root->getChild('newdir')->getPermissions()); + } + + /** + * @test + */ + public function defaultUmaskSettingDoesNotInfluenceSetup() + { + $root = vfsStream::setup(); + $this->assertEquals(0777, $root->getPermissions()); + } + + /** + * @test + */ + public function umaskSettingShouldBeRespectedBySetup() + { + vfsStream::umask(0022); + $root = vfsStream::setup(); + $this->assertEquals(0755, $root->getPermissions()); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperAlreadyRegisteredTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperAlreadyRegisteredTestCase.php new file mode 100644 index 0000000..279a2ce --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperAlreadyRegisteredTestCase.php @@ -0,0 +1,62 @@ +bc_getMock('org\\bovigo\\vfs\\vfsStreamWrapper'); + stream_wrapper_register(vfsStream::SCHEME, get_class($mock)); + } + + /** + * clean up test environment + */ + public function tearDown() + { + TestvfsStreamWrapper::unregister(); + } + + /** + * registering the stream wrapper when another stream wrapper is already + * registered for the vfs scheme should throw an exception + * + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + */ + public function registerOverAnotherStreamWrapper() + { + vfsStreamWrapper::register(); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperBaseTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperBaseTestCase.php new file mode 100644 index 0000000..4c12a45 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperBaseTestCase.php @@ -0,0 +1,98 @@ +fooURL = vfsStream::url('foo'); + $this->barURL = vfsStream::url('foo/bar'); + $this->baz1URL = vfsStream::url('foo/bar/baz1'); + $this->baz2URL = vfsStream::url('foo/baz2'); + $this->foo = new vfsStreamDirectory('foo'); + $this->bar = new vfsStreamDirectory('bar'); + $this->baz1 = vfsStream::newFile('baz1') + ->lastModified(300) + ->lastAccessed(300) + ->lastAttributeModified(300) + ->withContent('baz 1'); + $this->baz2 = vfsStream::newFile('baz2') + ->withContent('baz2') + ->lastModified(400) + ->lastAccessed(400) + ->lastAttributeModified(400); + $this->bar->addChild($this->baz1); + $this->foo->addChild($this->bar); + $this->foo->addChild($this->baz2); + $this->foo->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + $this->bar->lastModified(200) + ->lastAccessed(100) + ->lastAttributeModified(100); + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot($this->foo); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirSeparatorTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirSeparatorTestCase.php new file mode 100644 index 0000000..35fc0ce --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirSeparatorTestCase.php @@ -0,0 +1,72 @@ +root = vfsStream::setup(); + } + + /** + * @test + */ + public function fileCanBeAccessedUsingWinDirSeparator() + { + vfsStream::newFile('foo/bar/baz.txt') + ->at($this->root) + ->withContent('test'); + $this->assertEquals('test', file_get_contents('vfs://root/foo\bar\baz.txt')); + } + + + /** + * @test + */ + public function directoryCanBeCreatedUsingWinDirSeparator() + { + mkdir('vfs://root/dir\bar\foo', true, 0777); + $this->assertTrue($this->root->hasChild('dir')); + $this->assertTrue($this->root->getChild('dir')->hasChild('bar')); + $this->assertTrue($this->root->getChild('dir/bar')->hasChild('foo')); + } + + /** + * @test + */ + public function directoryExitsTestUsingTrailingWinDirSeparator() + { + $structure = array( + 'dir' => array( + 'bar' => array( + ) + ) + ); + vfsStream::create($structure, $this->root); + + $this->assertTrue(file_exists(vfsStream::url('root/').'dir\\')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirTestCase.php new file mode 100644 index 0000000..5f840c4 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperDirTestCase.php @@ -0,0 +1,500 @@ +assertFalse(mkdir(vfsStream::url('another'))); + $this->assertEquals(2, count($this->foo->getChildren())); + $this->assertSame($this->foo, vfsStreamWrapper::getRoot()); + } + + /** + * mkdir() should not overwrite existing root + * + * @test + */ + public function mkdirNoNewRootRecursively() + { + $this->assertFalse(mkdir(vfsStream::url('another/more'), 0777, true)); + $this->assertEquals(2, count($this->foo->getChildren())); + $this->assertSame($this->foo, vfsStreamWrapper::getRoot()); + } + + /** + * assert that mkdir() creates the correct directory structure + * + * @test + * @group permissions + */ + public function mkdirNonRecursively() + { + $this->assertFalse(mkdir($this->barURL . '/another/more')); + $this->assertEquals(2, count($this->foo->getChildren())); + $this->assertTrue(mkdir($this->fooURL . '/another')); + $this->assertEquals(3, count($this->foo->getChildren())); + $this->assertEquals(0777, $this->foo->getChild('another')->getPermissions()); + } + + /** + * assert that mkdir() creates the correct directory structure + * + * @test + * @group permissions + */ + public function mkdirRecursively() + { + $this->assertTrue(mkdir($this->fooURL . '/another/more', 0777, true)); + $this->assertEquals(3, count($this->foo->getChildren())); + $another = $this->foo->getChild('another'); + $this->assertTrue($another->hasChild('more')); + $this->assertEquals(0777, $this->foo->getChild('another')->getPermissions()); + $this->assertEquals(0777, $this->foo->getChild('another')->getChild('more')->getPermissions()); + } + + /** + * @test + * @group issue_9 + * @since 0.9.0 + */ + public function mkdirWithDots() + { + $this->assertTrue(mkdir($this->fooURL . '/another/../more/.', 0777, true)); + $this->assertEquals(3, count($this->foo->getChildren())); + $this->assertTrue($this->foo->hasChild('more')); + } + + /** + * no root > new directory becomes root + * + * @test + * @group permissions + */ + public function mkdirWithoutRootCreatesNewRoot() + { + vfsStreamWrapper::register(); + $this->assertTrue(@mkdir(vfsStream::url('foo'))); + $this->assertEquals(vfsStreamContent::TYPE_DIR, vfsStreamWrapper::getRoot()->getType()); + $this->assertEquals('foo', vfsStreamWrapper::getRoot()->getName()); + $this->assertEquals(0777, vfsStreamWrapper::getRoot()->getPermissions()); + } + + /** + * trying to create a subdirectory of a file should not work + * + * @test + */ + public function mkdirOnFileReturnsFalse() + { + $this->assertFalse(mkdir($this->baz1URL . '/another/more', 0777, true)); + } + + /** + * assert that mkdir() creates the correct directory structure + * + * @test + * @group permissions + */ + public function mkdirNonRecursivelyDifferentPermissions() + { + $this->assertTrue(mkdir($this->fooURL . '/another', 0755)); + $this->assertEquals(0755, $this->foo->getChild('another')->getPermissions()); + } + + /** + * assert that mkdir() creates the correct directory structure + * + * @test + * @group permissions + */ + public function mkdirRecursivelyDifferentPermissions() + { + $this->assertTrue(mkdir($this->fooURL . '/another/more', 0755, true)); + $this->assertEquals(3, count($this->foo->getChildren())); + $another = $this->foo->getChild('another'); + $this->assertTrue($another->hasChild('more')); + $this->assertEquals(0755, $this->foo->getChild('another')->getPermissions()); + $this->assertEquals(0755, $this->foo->getChild('another')->getChild('more')->getPermissions()); + } + + /** + * assert that mkdir() creates the correct directory structure + * + * @test + * @group permissions + */ + public function mkdirRecursivelyUsesDefaultPermissions() + { + $this->foo->chmod(0700); + $this->assertTrue(mkdir($this->fooURL . '/another/more', 0777, true)); + $this->assertEquals(3, count($this->foo->getChildren())); + $another = $this->foo->getChild('another'); + $this->assertTrue($another->hasChild('more')); + $this->assertEquals(0777, $this->foo->getChild('another')->getPermissions()); + $this->assertEquals(0777, $this->foo->getChild('another')->getChild('more')->getPermissions()); + } + + /** + * no root > new directory becomes root + * + * @test + * @group permissions + */ + public function mkdirWithoutRootCreatesNewRootDifferentPermissions() + { + vfsStreamWrapper::register(); + $this->assertTrue(@mkdir(vfsStream::url('foo'), 0755)); + $this->assertEquals(vfsStreamContent::TYPE_DIR, vfsStreamWrapper::getRoot()->getType()); + $this->assertEquals('foo', vfsStreamWrapper::getRoot()->getName()); + $this->assertEquals(0755, vfsStreamWrapper::getRoot()->getPermissions()); + } + + /** + * no root > new directory becomes root + * + * @test + * @group permissions + */ + public function mkdirWithoutRootCreatesNewRootWithDefaultPermissions() + { + vfsStreamWrapper::register(); + $this->assertTrue(@mkdir(vfsStream::url('foo'))); + $this->assertEquals(vfsStreamContent::TYPE_DIR, vfsStreamWrapper::getRoot()->getType()); + $this->assertEquals('foo', vfsStreamWrapper::getRoot()->getName()); + $this->assertEquals(0777, vfsStreamWrapper::getRoot()->getPermissions()); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function mkdirDirCanNotCreateNewDirInNonWritingDirectory() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root')); + vfsStreamWrapper::getRoot()->addChild(new vfsStreamDirectory('restrictedFolder', 0000)); + $this->assertFalse(is_writable(vfsStream::url('root/restrictedFolder/'))); + $this->assertFalse(mkdir(vfsStream::url('root/restrictedFolder/newFolder'))); + $this->assertFalse(vfsStreamWrapper::getRoot()->hasChild('restrictedFolder/newFolder')); + } + + /** + * @test + * @group issue_28 + */ + public function mkDirShouldNotOverwriteExistingDirectories() + { + vfsStream::setup('root'); + $dir = vfsStream::url('root/dir'); + $this->assertTrue(mkdir($dir)); + $this->assertFalse(@mkdir($dir)); + } + + /** + * @test + * @group issue_28 + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage mkdir(): Path vfs://root/dir exists + */ + public function mkDirShouldNotOverwriteExistingDirectoriesAndTriggerE_USER_WARNING() + { + vfsStream::setup('root'); + $dir = vfsStream::url('root/dir'); + $this->assertTrue(mkdir($dir)); + $this->assertFalse(mkdir($dir)); + } + + /** + * @test + * @group issue_28 + */ + public function mkDirShouldNotOverwriteExistingFiles() + { + $root = vfsStream::setup('root'); + vfsStream::newFile('test.txt')->at($root); + $this->assertFalse(@mkdir(vfsStream::url('root/test.txt'))); + } + + /** + * @test + * @group issue_28 + * @expectedException PHPUnit_Framework_Error + * @expectedExceptionMessage mkdir(): Path vfs://root/test.txt exists + */ + public function mkDirShouldNotOverwriteExistingFilesAndTriggerE_USER_WARNING() + { + $root = vfsStream::setup('root'); + vfsStream::newFile('test.txt')->at($root); + $this->assertFalse(mkdir(vfsStream::url('root/test.txt'))); + } + + /** + * @test + * @group issue_131 + * @since 1.6.3 + */ + public function allowsRecursiveMkDirWithDirectoryName0() + { + vfsStream::setup('root'); + $subdir = vfsStream::url('root/a/0'); + mkdir($subdir, 0777, true); + $this->assertFileExists($subdir); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function canNotIterateOverNonReadableDirectory() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0000)); + $this->assertFalse(@opendir(vfsStream::url('root'))); + $this->assertFalse(@dir(vfsStream::url('root'))); + } + + /** + * assert is_dir() returns correct result + * + * @test + */ + public function is_dir() + { + $this->assertTrue(is_dir($this->fooURL)); + $this->assertTrue(is_dir($this->fooURL . '/.')); + $this->assertTrue(is_dir($this->barURL)); + $this->assertTrue(is_dir($this->barURL . '/.')); + $this->assertFalse(is_dir($this->baz1URL)); + $this->assertFalse(is_dir($this->baz2URL)); + $this->assertFalse(is_dir($this->fooURL . '/another')); + $this->assertFalse(is_dir(vfsStream::url('another'))); + } + + /** + * can not unlink without root + * + * @test + */ + public function canNotUnlinkDirectoryWithoutRoot() + { + vfsStreamWrapper::register(); + $this->assertFalse(@rmdir(vfsStream::url('foo'))); + } + + /** + * rmdir() can not remove files + * + * @test + */ + public function rmdirCanNotRemoveFiles() + { + $this->assertFalse(rmdir($this->baz1URL)); + $this->assertFalse(rmdir($this->baz2URL)); + } + + /** + * rmdir() can not remove a non-existing directory + * + * @test + */ + public function rmdirCanNotRemoveNonExistingDirectory() + { + $this->assertFalse(rmdir($this->fooURL . '/another')); + } + + /** + * rmdir() can not remove non-empty directories + * + * @test + */ + public function rmdirCanNotRemoveNonEmptyDirectory() + { + $this->assertFalse(rmdir($this->fooURL)); + $this->assertFalse(rmdir($this->barURL)); + } + + /** + * @test + */ + public function rmdirCanRemoveEmptyDirectory() + { + vfsStream::newDirectory('empty')->at($this->foo); + $this->assertTrue($this->foo->hasChild('empty')); + $this->assertTrue(rmdir($this->fooURL . '/empty')); + $this->assertFalse($this->foo->hasChild('empty')); + } + + /** + * @test + */ + public function rmdirCanRemoveEmptyDirectoryWithDot() + { + vfsStream::newDirectory('empty')->at($this->foo); + $this->assertTrue($this->foo->hasChild('empty')); + $this->assertTrue(rmdir($this->fooURL . '/empty/.')); + $this->assertFalse($this->foo->hasChild('empty')); + } + + /** + * rmdir() can remove empty directories + * + * @test + */ + public function rmdirCanRemoveEmptyRoot() + { + $this->foo->removeChild('bar'); + $this->foo->removeChild('baz2'); + $this->assertTrue(rmdir($this->fooURL)); + $this->assertFalse(file_exists($this->fooURL)); // make sure statcache was cleared + $this->assertNull(vfsStreamWrapper::getRoot()); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function rmdirDirCanNotRemoveDirFromNonWritingDirectory() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0000)); + vfsStreamWrapper::getRoot()->addChild(new vfsStreamDirectory('nonRemovableFolder')); + $this->assertFalse(is_writable(vfsStream::url('root'))); + $this->assertFalse(rmdir(vfsStream::url('root/nonRemovableFolder'))); + $this->assertTrue(vfsStreamWrapper::getRoot()->hasChild('nonRemovableFolder')); + } + + /** + * @test + * @group permissions + * @group bug_17 + */ + public function issue17() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0770)); + vfsStreamWrapper::getRoot()->chgrp(vfsStream::GROUP_USER_1) + ->chown(vfsStream::OWNER_USER_1); + $this->assertFalse(mkdir(vfsStream::url('root/doesNotWork'))); + $this->assertFalse(vfsStreamWrapper::getRoot()->hasChild('doesNotWork')); + } + + /** + * @test + * @group bug_19 + */ + public function accessWithDoubleDotReturnsCorrectContent() + { + $this->assertEquals('baz2', + file_get_contents(vfsStream::url('foo/bar/../baz2')) + ); + } + + /** + * @test + * @group bug_115 + */ + public function accessWithExcessDoubleDotsReturnsCorrectContent() + { + $this->assertEquals('baz2', + file_get_contents(vfsStream::url('foo/../../../../bar/../baz2')) + ); + } + + /** + * @test + * @group bug_115 + */ + public function alwaysResolvesRootDirectoryAsOwnParentWithDoubleDot() + { + vfsStreamWrapper::getRoot()->chown(vfsStream::OWNER_USER_1); + + $this->assertTrue(is_dir(vfsStream::url('foo/..'))); + $stat = stat(vfsStream::url('foo/..')); + $this->assertEquals( + vfsStream::OWNER_USER_1, + $stat['uid'] + ); + } + + + /** + * @test + * @since 0.11.0 + * @group issue_23 + */ + public function unlinkCanNotRemoveNonEmptyDirectory() + { + try { + $this->assertFalse(unlink($this->barURL)); + } catch (\PHPUnit_Framework_Error $fe) { + $this->assertEquals('unlink(vfs://foo/bar): Operation not permitted', $fe->getMessage()); + } + + $this->assertTrue($this->foo->hasChild('bar')); + $this->assertFileExists($this->barURL); + } + + /** + * @test + * @since 0.11.0 + * @group issue_23 + */ + public function unlinkCanNotRemoveEmptyDirectory() + { + vfsStream::newDirectory('empty')->at($this->foo); + try { + $this->assertTrue(unlink($this->fooURL . '/empty')); + } catch (\PHPUnit_Framework_Error $fe) { + $this->assertEquals('unlink(vfs://foo/empty): Operation not permitted', $fe->getMessage()); + } + + $this->assertTrue($this->foo->hasChild('empty')); + $this->assertFileExists($this->fooURL . '/empty'); + } + + /** + * @test + * @group issue_32 + */ + public function canCreateFolderOfSameNameAsParentFolder() + { + $root = vfsStream::setup('testFolder'); + mkdir(vfsStream::url('testFolder') . '/testFolder/subTestFolder', 0777, true); + $this->assertTrue(file_exists(vfsStream::url('testFolder/testFolder/subTestFolder/.'))); + } + + /** + * @test + * @group issue_32 + */ + public function canRetrieveFolderOfSameNameAsParentFolder() + { + $root = vfsStream::setup('testFolder'); + mkdir(vfsStream::url('testFolder') . '/testFolder/subTestFolder', 0777, true); + $this->assertTrue($root->hasChild('testFolder')); + $this->assertNotNull($root->getChild('testFolder')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTestCase.php new file mode 100644 index 0000000..3ac9fb8 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTestCase.php @@ -0,0 +1,457 @@ +assertEquals('baz2', file_get_contents($this->baz2URL)); + $this->assertEquals('baz 1', file_get_contents($this->baz1URL)); + $this->assertFalse(@file_get_contents($this->barURL)); + $this->assertFalse(@file_get_contents($this->fooURL)); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function file_get_contentsNonReadableFile() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root')); + vfsStream::newFile('new.txt', 0000)->at(vfsStreamWrapper::getRoot())->withContent('content'); + $this->assertEquals('', @file_get_contents(vfsStream::url('root/new.txt'))); + } + + /** + * assert that file_put_contents() delivers correct file contents + * + * @test + */ + public function file_put_contentsExistingFile() + { + $this->assertEquals(14, file_put_contents($this->baz2URL, 'baz is not bar')); + $this->assertEquals('baz is not bar', $this->baz2->getContent()); + $this->assertEquals(6, file_put_contents($this->baz1URL, 'foobar')); + $this->assertEquals('foobar', $this->baz1->getContent()); + $this->assertFalse(@file_put_contents($this->barURL, 'This does not work.')); + $this->assertFalse(@file_put_contents($this->fooURL, 'This does not work, too.')); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function file_put_contentsExistingFileNonWritableDirectory() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0000)); + vfsStream::newFile('new.txt')->at(vfsStreamWrapper::getRoot())->withContent('content'); + $this->assertEquals(15, @file_put_contents(vfsStream::url('root/new.txt'), 'This does work.')); + $this->assertEquals('This does work.', file_get_contents(vfsStream::url('root/new.txt'))); + + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function file_put_contentsExistingNonWritableFile() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root')); + vfsStream::newFile('new.txt', 0400)->at(vfsStreamWrapper::getRoot())->withContent('content'); + $this->assertFalse(@file_put_contents(vfsStream::url('root/new.txt'), 'This does not work.')); + $this->assertEquals('content', file_get_contents(vfsStream::url('root/new.txt'))); + } + + /** + * assert that file_put_contents() delivers correct file contents + * + * @test + */ + public function file_put_contentsNonExistingFile() + { + $this->assertEquals(14, file_put_contents($this->fooURL . '/baznot.bar', 'baz is not bar')); + $this->assertEquals(3, count($this->foo->getChildren())); + $this->assertEquals(14, file_put_contents($this->barURL . '/baznot.bar', 'baz is not bar')); + $this->assertEquals(2, count($this->bar->getChildren())); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function file_put_contentsNonExistingFileNonWritableDirectory() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0000)); + $this->assertFalse(@file_put_contents(vfsStream::url('root/new.txt'), 'This does not work.')); + $this->assertFalse(file_exists(vfsStream::url('root/new.txt'))); + + } + + /** + * using a file pointer should work without any problems + * + * @test + */ + public function usingFilePointer() + { + $fp = fopen($this->baz1URL, 'r'); + $this->assertEquals(0, ftell($fp)); + $this->assertFalse(feof($fp)); + $this->assertEquals(0, fseek($fp, 2)); + $this->assertEquals(2, ftell($fp)); + $this->assertEquals(0, fseek($fp, 1, SEEK_CUR)); + $this->assertEquals(3, ftell($fp)); + $this->assertEquals(0, fseek($fp, 1, SEEK_END)); + $this->assertEquals(6, ftell($fp)); + $this->assertTrue(feof($fp)); + $this->assertEquals(0, fseek($fp, 2)); + $this->assertFalse(feof($fp)); + $this->assertEquals(2, ftell($fp)); + $this->assertEquals('z', fread($fp, 1)); + $this->assertEquals(3, ftell($fp)); + $this->assertEquals(' 1', fread($fp, 8092)); + $this->assertEquals(5, ftell($fp)); + $this->assertTrue(fclose($fp)); + } + + /** + * assert is_file() returns correct result + * + * @test + */ + public function is_file() + { + $this->assertFalse(is_file($this->fooURL)); + $this->assertFalse(is_file($this->barURL)); + $this->assertTrue(is_file($this->baz1URL)); + $this->assertTrue(is_file($this->baz2URL)); + $this->assertFalse(is_file($this->fooURL . '/another')); + $this->assertFalse(is_file(vfsStream::url('another'))); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function issue13CanNotOverwriteFiles() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + file_put_contents($vfsFile, 'd'); + $this->assertEquals('d', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function appendContentIfOpenedWithModeA() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'ab'); + fwrite($fp, 'd'); + fclose($fp); + $this->assertEquals('testd', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canOverwriteNonExistingFileWithModeX() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + $fp = fopen($vfsFile, 'xb'); + fwrite($fp, 'test'); + fclose($fp); + $this->assertEquals('test', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotOverwriteExistingFileWithModeX() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $this->assertFalse(@fopen($vfsFile, 'xb')); + $this->assertEquals('test', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotOpenNonExistingFileReadonly() + { + $this->assertFalse(@fopen(vfsStream::url('foo/doesNotExist.txt'), 'rb')); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotOpenNonExistingFileReadAndWrite() + { + $this->assertFalse(@fopen(vfsStream::url('foo/doesNotExist.txt'), 'rb+')); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotOpenWithIllegalMode() + { + $this->assertFalse(@fopen($this->baz2URL, 'invalid')); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotWriteToReadOnlyFile() + { + $fp = fopen($this->baz2URL, 'rb'); + $this->assertEquals('baz2', fread($fp, 4096)); + $this->assertEquals(0, fwrite($fp, 'foo')); + fclose($fp); + $this->assertEquals('baz2', file_get_contents($this->baz2URL)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotReadFromWriteOnlyFileWithModeW() + { + $fp = fopen($this->baz2URL, 'wb'); + $this->assertEquals('', fread($fp, 4096)); + $this->assertEquals(3, fwrite($fp, 'foo')); + fseek($fp, 0); + $this->assertEquals('', fread($fp, 4096)); + fclose($fp); + $this->assertEquals('foo', file_get_contents($this->baz2URL)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotReadFromWriteOnlyFileWithModeA() + { + $fp = fopen($this->baz2URL, 'ab'); + $this->assertEquals('', fread($fp, 4096)); + $this->assertEquals(3, fwrite($fp, 'foo')); + fseek($fp, 0); + $this->assertEquals('', fread($fp, 4096)); + fclose($fp); + $this->assertEquals('baz2foo', file_get_contents($this->baz2URL)); + } + + /** + * @test + * @group issue7 + * @group issue13 + */ + public function canNotReadFromWriteOnlyFileWithModeX() + { + $vfsFile = vfsStream::url('foo/modeXtest.txt'); + $fp = fopen($vfsFile, 'xb'); + $this->assertEquals('', fread($fp, 4096)); + $this->assertEquals(3, fwrite($fp, 'foo')); + fseek($fp, 0); + $this->assertEquals('', fread($fp, 4096)); + fclose($fp); + $this->assertEquals('foo', file_get_contents($vfsFile)); + } + + /** + * @test + * @group permissions + * @group bug_15 + */ + public function canNotRemoveFileFromDirectoryWithoutWritePermissions() + { + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(new vfsStreamDirectory('root', 0000)); + vfsStream::newFile('new.txt')->at(vfsStreamWrapper::getRoot()); + $this->assertFalse(unlink(vfsStream::url('root/new.txt'))); + $this->assertTrue(file_exists(vfsStream::url('root/new.txt'))); + } + + /** + * @test + * @group issue_30 + */ + public function truncatesFileWhenOpenedWithModeW() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'wb'); + $this->assertEquals('', file_get_contents($vfsFile)); + fclose($fp); + } + + /** + * @test + * @group issue_30 + */ + public function createsNonExistingFileWhenOpenedWithModeC() + { + $vfsFile = vfsStream::url('foo/tobecreated.txt'); + $fp = fopen($vfsFile, 'cb'); + fwrite($fp, 'some content'); + $this->assertTrue($this->foo->hasChild('tobecreated.txt')); + fclose($fp); + $this->assertEquals('some content', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue_30 + */ + public function createsNonExistingFileWhenOpenedWithModeCplus() + { + $vfsFile = vfsStream::url('foo/tobecreated.txt'); + $fp = fopen($vfsFile, 'cb+'); + fwrite($fp, 'some content'); + $this->assertTrue($this->foo->hasChild('tobecreated.txt')); + fclose($fp); + $this->assertEquals('some content', file_get_contents($vfsFile)); + } + + /** + * @test + * @group issue_30 + */ + public function doesNotTruncateFileWhenOpenedWithModeC() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'cb'); + $this->assertEquals('test', file_get_contents($vfsFile)); + fclose($fp); + } + + /** + * @test + * @group issue_30 + */ + public function setsPointerToStartWhenOpenedWithModeC() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'cb'); + $this->assertEquals(0, ftell($fp)); + fclose($fp); + } + + /** + * @test + * @group issue_30 + */ + public function doesNotTruncateFileWhenOpenedWithModeCplus() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'cb+'); + $this->assertEquals('test', file_get_contents($vfsFile)); + fclose($fp); + } + + /** + * @test + * @group issue_30 + */ + public function setsPointerToStartWhenOpenedWithModeCplus() + { + $vfsFile = vfsStream::url('foo/overwrite.txt'); + file_put_contents($vfsFile, 'test'); + $fp = fopen($vfsFile, 'cb+'); + $this->assertEquals(0, ftell($fp)); + fclose($fp); + } + + /** + * @test + */ + public function cannotOpenExistingNonwritableFileWithModeA() + { + $this->baz1->chmod(0400); + $this->assertFalse(@fopen($this->baz1URL, 'a')); + } + + /** + * @test + */ + public function cannotOpenExistingNonwritableFileWithModeW() + { + $this->baz1->chmod(0400); + $this->assertFalse(@fopen($this->baz1URL, 'w')); + } + + /** + * @test + */ + public function cannotOpenNonReadableFileWithModeR() + { + $this->baz1->chmod(0); + $this->assertFalse(@fopen($this->baz1URL, 'r')); + } + + /** + * @test + */ + public function cannotRenameToNonWritableDir() + { + $this->bar->chmod(0); + $this->assertFalse(@rename($this->baz2URL, vfsStream::url('foo/bar/baz3'))); + } + + /** + * @test + * @group issue_38 + */ + public function cannotReadFileFromNonReadableDir() + { + $this->markTestSkipped("Issue #38."); + $this->bar->chmod(0); + $this->assertFalse(@file_get_contents($this->baz1URL)); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTimesTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTimesTestCase.php new file mode 100644 index 0000000..cd3ea22 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFileTimesTestCase.php @@ -0,0 +1,314 @@ +lastModified(50) + ->lastAccessed(50) + ->lastAttributeModified(50); + $this->fooUrl = vfsStream::url('root/foo.txt'); + $this->barUrl = vfsStream::url('root/bar'); + $this->bazUrl = vfsStream::url('root/bar/baz.txt'); + } + + /** + * helper assertion for the tests + * + * @param string $url url to check + * @param vfsStreamContent $content content to compare + */ + protected function assertFileTimesEqualStreamTimes($url, vfsStreamContent $content) + { + $this->assertEquals(filemtime($url), $content->filemtime()); + $this->assertEquals(fileatime($url), $content->fileatime()); + $this->assertEquals(filectime($url), $content->filectime()); + } + + /** + * @test + * @group issue_7 + * @group issue_26 + */ + public function openFileChangesAttributeTimeOnly() + { + $file = vfsStream::newFile('foo.txt') + ->withContent('test') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + fclose(fopen($this->fooUrl, 'rb')); + $this->assertGreaterThan(time() - 2, fileatime($this->fooUrl)); + $this->assertLessThanOrEqual(time(), fileatime($this->fooUrl)); + $this->assertLessThanOrEqual(100, filemtime($this->fooUrl)); + $this->assertEquals(100, filectime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, $file); + } + + /** + * @test + * @group issue_7 + * @group issue_26 + */ + public function fileGetContentsChangesAttributeTimeOnly() + { + $file = vfsStream::newFile('foo.txt') + ->withContent('test') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + file_get_contents($this->fooUrl); + $this->assertGreaterThan(time() - 2, fileatime($this->fooUrl)); + $this->assertLessThanOrEqual(time(), fileatime($this->fooUrl)); + $this->assertLessThanOrEqual(100, filemtime($this->fooUrl)); + $this->assertEquals(100, filectime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, $file); + } + + /** + * @test + * @group issue_7 + * @group issue_26 + */ + public function openFileWithTruncateChangesAttributeAndModificationTime() + { + $file = vfsStream::newFile('foo.txt') + ->withContent('test') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + fclose(fopen($this->fooUrl, 'wb')); + $this->assertGreaterThan(time() - 2, filemtime($this->fooUrl)); + $this->assertGreaterThan(time() - 2, fileatime($this->fooUrl)); + $this->assertLessThanOrEqual(time(), filemtime($this->fooUrl)); + $this->assertLessThanOrEqual(time(), fileatime($this->fooUrl)); + $this->assertEquals(100, filectime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, $file); + } + + /** + * @test + * @group issue_7 + */ + public function readFileChangesAccessTime() + { + $file = vfsStream::newFile('foo.txt') + ->withContent('test') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + $fp = fopen($this->fooUrl, 'rb'); + $openTime = time(); + sleep(2); + fread($fp, 1024); + fclose($fp); + $this->assertLessThanOrEqual($openTime, filemtime($this->fooUrl)); + $this->assertLessThanOrEqual($openTime + 3, fileatime($this->fooUrl)); + $this->assertEquals(100, filectime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, $file); + } + + /** + * @test + * @group issue_7 + */ + public function writeFileChangesModificationTime() + { + $file = vfsStream::newFile('foo.txt') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + $fp = fopen($this->fooUrl, 'wb'); + $openTime = time(); + sleep(2); + fwrite($fp, 'test'); + fclose($fp); + $this->assertLessThanOrEqual($openTime + 3, filemtime($this->fooUrl)); + $this->assertLessThanOrEqual($openTime, fileatime($this->fooUrl)); + $this->assertEquals(100, filectime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, $file); + + } + + /** + * @test + * @group issue_7 + */ + public function createNewFileSetsAllTimesToCurrentTime() + { + file_put_contents($this->fooUrl, 'test'); + $this->assertLessThanOrEqual(time(), filemtime($this->fooUrl)); + $this->assertEquals(fileatime($this->fooUrl), filectime($this->fooUrl)); + $this->assertEquals(fileatime($this->fooUrl), filemtime($this->fooUrl)); + $this->assertFileTimesEqualStreamTimes($this->fooUrl, vfsStreamWrapper::getRoot()->getChild('foo.txt')); + } + + /** + * @test + * @group issue_7 + */ + public function createNewFileChangesAttributeAndModificationTimeOfContainingDirectory() + { + $dir = vfsStream::newDirectory('bar') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + file_put_contents($this->bazUrl, 'test'); + $this->assertLessThanOrEqual(time(), filemtime($this->barUrl)); + $this->assertLessThanOrEqual(time(), filectime($this->barUrl)); + $this->assertEquals(100, fileatime($this->barUrl)); + $this->assertFileTimesEqualStreamTimes($this->barUrl, $dir); + } + + /** + * @test + * @group issue_7 + */ + public function addNewFileNameWithLinkFunctionChangesAttributeTimeOfOriginalFile() + { + $this->markTestSkipped('Links are currently not supported by vfsStream.'); + } + + /** + * @test + * @group issue_7 + */ + public function addNewFileNameWithLinkFunctionChangesAttributeAndModificationTimeOfDirectoryContainingLink() + { + $this->markTestSkipped('Links are currently not supported by vfsStream.'); + } + + /** + * @test + * @group issue_7 + */ + public function removeFileChangesAttributeAndModificationTimeOfContainingDirectory() + { + $dir = vfsStream::newDirectory('bar') + ->at(vfsStreamWrapper::getRoot()); + $file = vfsStream::newFile('baz.txt') + ->at($dir) + ->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + $dir->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + unlink($this->bazUrl); + $this->assertLessThanOrEqual(time(), filemtime($this->barUrl)); + $this->assertLessThanOrEqual(time(), filectime($this->barUrl)); + $this->assertEquals(100, fileatime($this->barUrl)); + $this->assertFileTimesEqualStreamTimes($this->barUrl, $dir); + } + + /** + * @test + * @group issue_7 + */ + public function renameFileChangesAttributeAndModificationTimeOfAffectedDirectories() + { + $target = vfsStream::newDirectory('target') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(200) + ->lastAccessed(200) + ->lastAttributeModified(200); + $source = vfsStream::newDirectory('bar') + ->at(vfsStreamWrapper::getRoot()); + $file = vfsStream::newFile('baz.txt') + ->at($source) + ->lastModified(300) + ->lastAccessed(300) + ->lastAttributeModified(300); + $source->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + rename($this->bazUrl, vfsStream::url('root/target/baz.txt')); + $this->assertLessThanOrEqual(time(), filemtime($this->barUrl)); + $this->assertLessThanOrEqual(time(), filectime($this->barUrl)); + $this->assertEquals(100, fileatime($this->barUrl)); + $this->assertFileTimesEqualStreamTimes($this->barUrl, $source); + $this->assertLessThanOrEqual(time(), filemtime(vfsStream::url('root/target'))); + $this->assertLessThanOrEqual(time(), filectime(vfsStream::url('root/target'))); + $this->assertEquals(200, fileatime(vfsStream::url('root/target'))); + $this->assertFileTimesEqualStreamTimes(vfsStream::url('root/target'), $target); + } + + /** + * @test + * @group issue_7 + */ + public function renameFileDoesNotChangeFileTimesOfFileItself() + { + $target = vfsStream::newDirectory('target') + ->at(vfsStreamWrapper::getRoot()) + ->lastModified(200) + ->lastAccessed(200) + ->lastAttributeModified(200); + $source = vfsStream::newDirectory('bar') + ->at(vfsStreamWrapper::getRoot()); + $file = vfsStream::newFile('baz.txt') + ->at($source) + ->lastModified(300) + ->lastAccessed(300) + ->lastAttributeModified(300); + $source->lastModified(100) + ->lastAccessed(100) + ->lastAttributeModified(100); + rename($this->bazUrl, vfsStream::url('root/target/baz.txt')); + $this->assertEquals(300, filemtime(vfsStream::url('root/target/baz.txt'))); + $this->assertEquals(300, filectime(vfsStream::url('root/target/baz.txt'))); + $this->assertEquals(300, fileatime(vfsStream::url('root/target/baz.txt'))); + $this->assertFileTimesEqualStreamTimes(vfsStream::url('root/target/baz.txt'), $file); + } + + /** + * @test + * @group issue_7 + */ + public function changeFileAttributesChangesAttributeTimeOfFileItself() + { + $this->markTestSkipped('Changing file attributes via stream wrapper for self-defined streams is not supported by PHP.'); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFlockTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFlockTestCase.php new file mode 100644 index 0000000..3fb137f --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperFlockTestCase.php @@ -0,0 +1,439 @@ +root = vfsStream::setup(); + } + + /** + * @test + */ + public function fileIsNotLockedByDefault() + { + $this->assertFalse(vfsStream::newFile('foo.txt')->isLocked()); + } + + /** + * @test + */ + public function streamIsNotLockedByDefault() + { + file_put_contents(vfsStream::url('root/foo.txt'), 'content'); + $this->assertFalse($this->root->getChild('foo.txt')->isLocked()); + } + + /** + * @test + */ + public function canAquireSharedLock() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertTrue(flock($fp, LOCK_SH)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + + } + + /** + * @test + */ + public function canAquireSharedLockWithNonBlockingFlockCall() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertTrue(flock($fp, LOCK_SH | LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + + } + + /** + * @test + */ + public function canAquireEclusiveLock() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertTrue(flock($fp, LOCK_EX)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @test + */ + public function canAquireEclusiveLockWithNonBlockingFlockCall() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertTrue(flock($fp, LOCK_EX | LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @test + */ + public function canRemoveLock() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_EX); + $this->assertTrue(flock($fp, LOCK_UN)); + $this->assertFalse($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canRemoveLockWhenNotLocked() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertTrue(flock($fp, LOCK_UN)); + $this->assertFalse($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertFalse($file->hasSharedLock($fp)); + $this->assertFalse($file->hasExclusiveLock()); + $this->assertFalse($file->hasExclusiveLock($fp)); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canRemoveSharedLockWithoutRemovingSharedLockOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_SH); + $file->lock($fp2, LOCK_SH); + $this->assertTrue(flock($fp1, LOCK_UN)); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasSharedLock($fp1)); + $this->assertTrue($file->hasSharedLock($fp2)); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canNotRemoveSharedLockAcquiredOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_SH); + $this->assertTrue(flock($fp2, LOCK_UN)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canNotRemoveExlusiveLockAcquiredOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_EX); + $this->assertTrue(flock($fp2, LOCK_UN)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp1); + fclose($fp2); + } + + /** + * @test + */ + public function canRemoveLockWithNonBlockingFlockCall() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_EX); + $this->assertTrue(flock($fp, LOCK_UN | LOCK_NB)); + $this->assertFalse($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canNotAquireExclusiveLockIfAlreadyExclusivelyLockedOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_EX); + $this->assertFalse(flock($fp2, LOCK_EX + LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + $this->assertTrue($file->hasExclusiveLock($fp1)); + $this->assertFalse($file->hasExclusiveLock($fp2)); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canAquireExclusiveLockIfAlreadySelfExclusivelyLocked() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_EX); + $this->assertTrue(flock($fp, LOCK_EX + LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canNotAquireExclusiveLockIfAlreadySharedLockedOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_SH); + $this->assertFalse(flock($fp2, LOCK_EX)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canAquireExclusiveLockIfAlreadySelfSharedLocked() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_SH); + $this->assertTrue(flock($fp, LOCK_EX)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canNotAquireSharedLockIfAlreadyExclusivelyLockedOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_EX); + $this->assertFalse(flock($fp2, LOCK_SH + LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canAquireSharedLockIfAlreadySelfExclusivelyLocked() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_EX); + $this->assertTrue(flock($fp, LOCK_SH + LOCK_NB)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canAquireSharedLockIfAlreadySelfSharedLocked() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_SH); + $this->assertTrue(flock($fp, LOCK_SH)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function canAquireSharedLockIfAlreadySharedLockedOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp1, LOCK_SH); + $this->assertTrue(flock($fp2, LOCK_SH)); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertTrue($file->hasSharedLock($fp1)); + $this->assertTrue($file->hasSharedLock($fp2)); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp1); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/31 + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_31 + * @group issue_40 + */ + public function removesExclusiveLockOnStreamClose() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_EX); + fclose($fp); + $this->assertFalse($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/31 + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_31 + * @group issue_40 + */ + public function removesSharedLockOnStreamClose() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp, LOCK_SH); + fclose($fp); + $this->assertFalse($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertFalse($file->hasExclusiveLock()); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function notRemovesExclusiveLockOnStreamCloseIfExclusiveLockAcquiredOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp2, LOCK_EX); + fclose($fp1); + $this->assertTrue($file->isLocked()); + $this->assertFalse($file->hasSharedLock()); + $this->assertTrue($file->hasExclusiveLock()); + $this->assertTrue($file->hasExclusiveLock($fp2)); + fclose($fp2); + } + + /** + * @see https://github.com/mikey179/vfsStream/issues/40 + * @test + * @group issue_40 + */ + public function notRemovesSharedLockOnStreamCloseIfSharedLockAcquiredOnOtherFileHandler() + { + $file = vfsStream::newFile('foo.txt')->at($this->root); + $fp1 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $fp2 = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $file->lock($fp2, LOCK_SH); + fclose($fp1); + $this->assertTrue($file->isLocked()); + $this->assertTrue($file->hasSharedLock()); + $this->assertTrue($file->hasSharedLock($fp2)); + $this->assertFalse($file->hasExclusiveLock()); + fclose($fp2); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperLargeFileTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperLargeFileTestCase.php new file mode 100644 index 0000000..fb5d9fd --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperLargeFileTestCase.php @@ -0,0 +1,81 @@ +largeFile = vfsStream::newFile('large.txt') + ->withContent(LargeFileContent::withGigabytes(100)) + ->at($root); + } + + /** + * @test + */ + public function hasLargeFileSize() + { + if (PHP_INT_MAX == 2147483647) { + $this->markTestSkipped('Requires 64-bit version of PHP'); + } + + $this->assertEquals( + 100 * 1024 * 1024 * 1024, + filesize($this->largeFile->url()) + ); + } + + /** + * @test + */ + public function canReadFromLargeFile() + { + $fp = fopen($this->largeFile->url(), 'rb'); + $data = fread($fp, 15); + fclose($fp); + $this->assertEquals(str_repeat(' ', 15), $data); + } + + /** + * @test + */ + public function canWriteIntoLargeFile() + { + $fp = fopen($this->largeFile->url(), 'rb+'); + fseek($fp, 100 * 1024 * 1024, SEEK_SET); + fwrite($fp, 'foobarbaz'); + fclose($fp); + $this->largeFile->seek((100 * 1024 * 1024) - 3, SEEK_SET); + $this->assertEquals( + ' foobarbaz ', + $this->largeFile->read(15) + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperQuotaTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperQuotaTestCase.php new file mode 100644 index 0000000..9503190 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperQuotaTestCase.php @@ -0,0 +1,223 @@ +root = vfsStream::setup(); + vfsStream::setQuota(10); + } + + /** + * @test + */ + public function writeLessThanQuotaWritesEverything() + { + $this->assertEquals(9, file_put_contents(vfsStream::url('root/file.txt'), '123456789')); + $this->assertEquals('123456789', $this->root->getChild('file.txt')->getContent()); + } + + /** + * @test + */ + public function writeUpToQotaWritesEverything() + { + $this->assertEquals(10, file_put_contents(vfsStream::url('root/file.txt'), '1234567890')); + $this->assertEquals('1234567890', $this->root->getChild('file.txt')->getContent()); + } + + /** + * @test + */ + public function writeMoreThanQotaWritesOnlyUpToQuota() + { + try { + file_put_contents(vfsStream::url('root/file.txt'), '12345678901'); + } catch (\PHPUnit_Framework_Error $e) { + $this->assertEquals('file_put_contents(): Only 10 of 11 bytes written, possibly out of free disk space', + $e->getMessage() + ); + } + + $this->assertEquals('1234567890', $this->root->getChild('file.txt')->getContent()); + } + + /** + * @test + */ + public function considersAllFilesForQuota() + { + vfsStream::newFile('foo.txt') + ->withContent('foo') + ->at(vfsStream::newDirectory('bar') + ->at($this->root) + ); + try { + file_put_contents(vfsStream::url('root/file.txt'), '12345678901'); + } catch (\PHPUnit_Framework_Error $e) { + $this->assertEquals('file_put_contents(): Only 7 of 11 bytes written, possibly out of free disk space', + $e->getMessage() + ); + } + + $this->assertEquals('1234567', $this->root->getChild('file.txt')->getContent()); + } + + /** + * @test + * @group issue_33 + */ + public function truncateToLessThanQuotaWritesEverything() + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + $fp = fopen(vfsStream::url('root/file.txt'), 'w+'); + $this->assertTrue(ftruncate($fp, 9)); + fclose($fp); + $this->assertEquals(9, + $this->root->getChild('file.txt')->size() + ); + $this->assertEquals("\0\0\0\0\0\0\0\0\0", + $this->root->getChild('file.txt')->getContent() + ); + } + + /** + * @test + * @group issue_33 + */ + public function truncateUpToQotaWritesEverything() + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + $fp = fopen(vfsStream::url('root/file.txt'), 'w+'); + $this->assertTrue(ftruncate($fp, 10)); + fclose($fp); + $this->assertEquals(10, + $this->root->getChild('file.txt')->size() + ); + $this->assertEquals("\0\0\0\0\0\0\0\0\0\0", + $this->root->getChild('file.txt')->getContent() + ); + } + + /** + * @test + * @group issue_33 + */ + public function truncateToMoreThanQotaWritesOnlyUpToQuota() + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + $fp = fopen(vfsStream::url('root/file.txt'), 'w+'); + $this->assertTrue(ftruncate($fp, 11)); + fclose($fp); + $this->assertEquals(10, + $this->root->getChild('file.txt')->size() + ); + $this->assertEquals("\0\0\0\0\0\0\0\0\0\0", + $this->root->getChild('file.txt')->getContent() + ); + } + + /** + * @test + * @group issue_33 + */ + public function truncateConsidersAllFilesForQuota() + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + vfsStream::newFile('bar.txt') + ->withContent('bar') + ->at(vfsStream::newDirectory('bar') + ->at($this->root) + ); + $fp = fopen(vfsStream::url('root/file.txt'), 'w+'); + $this->assertTrue(ftruncate($fp, 11)); + fclose($fp); + $this->assertEquals(7, + $this->root->getChild('file.txt')->size() + ); + $this->assertEquals("\0\0\0\0\0\0\0", + $this->root->getChild('file.txt')->getContent() + ); + } + + /** + * @test + * @group issue_33 + */ + public function canNotTruncateToGreaterLengthWhenDiscQuotaReached() + { + if (version_compare(PHP_VERSION, '5.4.0', '<')) { + $this->markTestSkipped('Requires PHP 5.4'); + } + + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + vfsStream::newFile('bar.txt') + ->withContent('1234567890') + ->at(vfsStream::newDirectory('bar') + ->at($this->root) + ); + $fp = fopen(vfsStream::url('root/file.txt'), 'w+'); + $this->assertFalse(ftruncate($fp, 11)); + fclose($fp); + $this->assertEquals(0, + $this->root->getChild('file.txt')->size() + ); + $this->assertEquals('', + $this->root->getChild('file.txt')->getContent() + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperSetOptionTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperSetOptionTestCase.php new file mode 100644 index 0000000..ff2ab14 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperSetOptionTestCase.php @@ -0,0 +1,75 @@ +root = vfsStream::setup(); + vfsStream::newFile('foo.txt')->at($this->root); + } + + /** + * @test + */ + public function setBlockingDoesNotWork() + { + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertFalse(stream_set_blocking($fp, 1)); + fclose($fp); + } + + /** + * @test + */ + public function removeBlockingDoesNotWork() + { + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertFalse(stream_set_blocking($fp, 0)); + fclose($fp); + } + + /** + * @test + */ + public function setTimeoutDoesNotWork() + { + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertFalse(stream_set_timeout($fp, 1)); + fclose($fp); + } + + /** + * @test + */ + public function setWriteBufferDoesNotWork() + { + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $this->assertEquals(-1, stream_set_write_buffer($fp, 512)); + fclose($fp); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperStreamSelectTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperStreamSelectTestCase.php new file mode 100644 index 0000000..9dc2530 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperStreamSelectTestCase.php @@ -0,0 +1,34 @@ +at($root)->withContent('testContent'); + + $fp = fopen(vfsStream::url('root/foo.txt'), 'rb'); + $readarray = array($fp); + $writearray = array(); + $exceptarray = array(); + stream_select($readarray, $writearray, $exceptarray, 1); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperTestCase.php new file mode 100644 index 0000000..f2b3234 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperTestCase.php @@ -0,0 +1,789 @@ +assertSame($this->foo, vfsStreamWrapper::getRoot()); + vfsStreamWrapper::register(); + $this->assertNull(vfsStreamWrapper::getRoot()); + } + + /** + * @test + * @since 0.11.0 + */ + public function setRootReturnsRoot() + { + vfsStreamWrapper::register(); + $root = vfsStream::newDirectory('root'); + $this->assertSame($root, vfsStreamWrapper::setRoot($root)); + } + + /** + * assure that filesize is returned correct + * + * @test + */ + public function filesize() + { + $this->assertEquals(0, filesize($this->fooURL)); + $this->assertEquals(0, filesize($this->fooURL . '/.')); + $this->assertEquals(0, filesize($this->barURL)); + $this->assertEquals(0, filesize($this->barURL . '/.')); + $this->assertEquals(4, filesize($this->baz2URL)); + $this->assertEquals(5, filesize($this->baz1URL)); + } + + /** + * assert that file_exists() delivers correct result + * + * @test + */ + public function file_exists() + { + $this->assertTrue(file_exists($this->fooURL)); + $this->assertTrue(file_exists($this->fooURL . '/.')); + $this->assertTrue(file_exists($this->barURL)); + $this->assertTrue(file_exists($this->barURL . '/.')); + $this->assertTrue(file_exists($this->baz1URL)); + $this->assertTrue(file_exists($this->baz2URL)); + $this->assertFalse(file_exists($this->fooURL . '/another')); + $this->assertFalse(file_exists(vfsStream::url('another'))); + } + + /** + * assert that filemtime() delivers correct result + * + * @test + */ + public function filemtime() + { + $this->assertEquals(100, filemtime($this->fooURL)); + $this->assertEquals(100, filemtime($this->fooURL . '/.')); + $this->assertEquals(200, filemtime($this->barURL)); + $this->assertEquals(200, filemtime($this->barURL . '/.')); + $this->assertEquals(300, filemtime($this->baz1URL)); + $this->assertEquals(400, filemtime($this->baz2URL)); + } + + /** + * @test + * @group issue_23 + */ + public function unlinkRemovesFilesOnly() + { + $this->assertTrue(unlink($this->baz2URL)); + $this->assertFalse(file_exists($this->baz2URL)); // make sure statcache was cleared + $this->assertEquals(array($this->bar), $this->foo->getChildren()); + $this->assertFalse(@unlink($this->fooURL . '/another')); + $this->assertFalse(@unlink(vfsStream::url('another'))); + $this->assertEquals(array($this->bar), $this->foo->getChildren()); + } + + /** + * @test + * @group issue_49 + */ + public function unlinkReturnsFalseWhenFileDoesNotExist() + { + vfsStream::setup()->addChild(vfsStream::newFile('foo.blubb')); + $this->assertFalse(@unlink(vfsStream::url('foo.blubb2'))); + } + + /** + * @test + * @group issue_49 + */ + public function unlinkReturnsFalseWhenFileDoesNotExistAndFileWithSameNameExistsInRoot() + { + vfsStream::setup()->addChild(vfsStream::newFile('foo.blubb')); + $this->assertFalse(@unlink(vfsStream::url('foo.blubb'))); + } + + /** + * assert dirname() returns correct directory name + * + * @test + */ + public function dirname() + { + $this->assertEquals($this->fooURL, dirname($this->barURL)); + $this->assertEquals($this->barURL, dirname($this->baz1URL)); + # returns "vfs:" instead of "." + # however this seems not to be fixable because dirname() does not + # call the stream wrapper + #$this->assertEquals(dirname(vfsStream::url('doesNotExist')), '.'); + } + + /** + * assert basename() returns correct file name + * + * @test + */ + public function basename() + { + $this->assertEquals('bar', basename($this->barURL)); + $this->assertEquals('baz1', basename($this->baz1URL)); + $this->assertEquals('doesNotExist', basename(vfsStream::url('doesNotExist'))); + } + + /** + * assert is_readable() works correct + * + * @test + */ + public function is_readable() + { + $this->assertTrue(is_readable($this->fooURL)); + $this->assertTrue(is_readable($this->fooURL . '/.')); + $this->assertTrue(is_readable($this->barURL)); + $this->assertTrue(is_readable($this->barURL . '/.')); + $this->assertTrue(is_readable($this->baz1URL)); + $this->assertTrue(is_readable($this->baz2URL)); + $this->assertFalse(is_readable($this->fooURL . '/another')); + $this->assertFalse(is_readable(vfsStream::url('another'))); + + $this->foo->chmod(0222); + $this->assertFalse(is_readable($this->fooURL)); + + $this->baz1->chmod(0222); + $this->assertFalse(is_readable($this->baz1URL)); + } + + /** + * assert is_writable() works correct + * + * @test + */ + public function is_writable() + { + $this->assertTrue(is_writable($this->fooURL)); + $this->assertTrue(is_writable($this->fooURL . '/.')); + $this->assertTrue(is_writable($this->barURL)); + $this->assertTrue(is_writable($this->barURL . '/.')); + $this->assertTrue(is_writable($this->baz1URL)); + $this->assertTrue(is_writable($this->baz2URL)); + $this->assertFalse(is_writable($this->fooURL . '/another')); + $this->assertFalse(is_writable(vfsStream::url('another'))); + + $this->foo->chmod(0444); + $this->assertFalse(is_writable($this->fooURL)); + + $this->baz1->chmod(0444); + $this->assertFalse(is_writable($this->baz1URL)); + } + + /** + * assert is_executable() works correct + * + * @test + */ + public function is_executable() + { + $this->assertFalse(is_executable($this->baz1URL)); + $this->baz1->chmod(0766); + $this->assertTrue(is_executable($this->baz1URL)); + $this->assertFalse(is_executable($this->baz2URL)); + } + + /** + * assert is_executable() works correct + * + * @test + */ + public function directoriesAndNonExistingFilesAreSometimesExecutable() + { + // Inconsistent behavior has been fixed in 7.3 + // see https://github.com/php/php-src/commit/94b4abdbc4d + if (PHP_VERSION_ID >= 70300) { + $this->assertTrue(is_executable($this->fooURL)); + $this->assertTrue(is_executable($this->fooURL . '/.')); + $this->assertTrue(is_executable($this->barURL)); + $this->assertTrue(is_executable($this->barURL . '/.')); + } else { + $this->assertFalse(is_executable($this->fooURL)); + $this->assertFalse(is_executable($this->fooURL . '/.')); + $this->assertFalse(is_executable($this->barURL)); + $this->assertFalse(is_executable($this->barURL . '/.')); + } + + $this->assertFalse(is_executable($this->fooURL . '/another')); + $this->assertFalse(is_executable(vfsStream::url('another'))); + } + + /** + * file permissions + * + * @test + * @group permissions + */ + public function chmod() + { + $this->assertEquals(40777, decoct(fileperms($this->fooURL))); + $this->assertEquals(40777, decoct(fileperms($this->fooURL . '/.'))); + $this->assertEquals(40777, decoct(fileperms($this->barURL))); + $this->assertEquals(40777, decoct(fileperms($this->barURL . '/.'))); + $this->assertEquals(100666, decoct(fileperms($this->baz1URL))); + $this->assertEquals(100666, decoct(fileperms($this->baz2URL))); + + $this->foo->chmod(0755); + $this->bar->chmod(0700); + $this->baz1->chmod(0644); + $this->baz2->chmod(0600); + $this->assertEquals(40755, decoct(fileperms($this->fooURL))); + $this->assertEquals(40755, decoct(fileperms($this->fooURL . '/.'))); + $this->assertEquals(40700, decoct(fileperms($this->barURL))); + $this->assertEquals(40700, decoct(fileperms($this->barURL . '/.'))); + $this->assertEquals(100644, decoct(fileperms($this->baz1URL))); + $this->assertEquals(100600, decoct(fileperms($this->baz2URL))); + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function chmodModifiesPermissions() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->assertFalse(@chmod($this->fooURL, 0755)); + $this->assertFalse(@chmod($this->barURL, 0711)); + $this->assertFalse(@chmod($this->baz1URL, 0644)); + $this->assertFalse(@chmod($this->baz2URL, 0664)); + $this->assertEquals(40777, decoct(fileperms($this->fooURL))); + $this->assertEquals(40777, decoct(fileperms($this->barURL))); + $this->assertEquals(100666, decoct(fileperms($this->baz1URL))); + $this->assertEquals(100666, decoct(fileperms($this->baz2URL))); + } else { + $this->assertTrue(chmod($this->fooURL, 0755)); + $this->assertTrue(chmod($this->barURL, 0711)); + $this->assertTrue(chmod($this->baz1URL, 0644)); + $this->assertTrue(chmod($this->baz2URL, 0664)); + $this->assertEquals(40755, decoct(fileperms($this->fooURL))); + $this->assertEquals(40711, decoct(fileperms($this->barURL))); + $this->assertEquals(100644, decoct(fileperms($this->baz1URL))); + $this->assertEquals(100664, decoct(fileperms($this->baz2URL))); + } + } + + /** + * @test + * @group permissions + */ + public function fileownerIsCurrentUserByDefault() + { + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->fooURL)); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->fooURL . '/.')); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->barURL)); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->barURL . '/.')); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->baz1URL)); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->baz2URL)); + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function chownChangesUser() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->foo->chown(vfsStream::OWNER_USER_1); + $this->bar->chown(vfsStream::OWNER_USER_1); + $this->baz1->chown(vfsStream::OWNER_USER_2); + $this->baz2->chown(vfsStream::OWNER_USER_2); + } else { + chown($this->fooURL, vfsStream::OWNER_USER_1); + chown($this->barURL, vfsStream::OWNER_USER_1); + chown($this->baz1URL, vfsStream::OWNER_USER_2); + chown($this->baz2URL, vfsStream::OWNER_USER_2); + } + + $this->assertEquals(vfsStream::OWNER_USER_1, fileowner($this->fooURL)); + $this->assertEquals(vfsStream::OWNER_USER_1, fileowner($this->fooURL . '/.')); + $this->assertEquals(vfsStream::OWNER_USER_1, fileowner($this->barURL)); + $this->assertEquals(vfsStream::OWNER_USER_1, fileowner($this->barURL . '/.')); + $this->assertEquals(vfsStream::OWNER_USER_2, fileowner($this->baz1URL)); + $this->assertEquals(vfsStream::OWNER_USER_2, fileowner($this->baz2URL)); + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function chownDoesNotWorkOnVfsStreamUrls() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->assertFalse(@chown($this->fooURL, vfsStream::OWNER_USER_2)); + $this->assertEquals(vfsStream::getCurrentUser(), fileowner($this->fooURL)); + } + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function groupIsCurrentGroupByDefault() + { + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->fooURL)); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->fooURL . '/.')); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->barURL)); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->barURL . '/.')); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->baz1URL)); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->baz2URL)); + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function chgrp() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->foo->chgrp(vfsStream::GROUP_USER_1); + $this->bar->chgrp(vfsStream::GROUP_USER_1); + $this->baz1->chgrp(vfsStream::GROUP_USER_2); + $this->baz2->chgrp(vfsStream::GROUP_USER_2); + } else { + chgrp($this->fooURL, vfsStream::GROUP_USER_1); + chgrp($this->barURL, vfsStream::GROUP_USER_1); + chgrp($this->baz1URL, vfsStream::GROUP_USER_2); + chgrp($this->baz2URL, vfsStream::GROUP_USER_2); + } + + $this->assertEquals(vfsStream::GROUP_USER_1, filegroup($this->fooURL)); + $this->assertEquals(vfsStream::GROUP_USER_1, filegroup($this->fooURL . '/.')); + $this->assertEquals(vfsStream::GROUP_USER_1, filegroup($this->barURL)); + $this->assertEquals(vfsStream::GROUP_USER_1, filegroup($this->barURL . '/.')); + $this->assertEquals(vfsStream::GROUP_USER_2, filegroup($this->baz1URL)); + $this->assertEquals(vfsStream::GROUP_USER_2, filegroup($this->baz2URL)); + } + + /** + * @test + * @group issue_11 + * @group permissions + */ + public function chgrpDoesNotWorkOnVfsStreamUrls() + { + if (version_compare(phpversion(), '5.4.0', '<')) { + $this->assertFalse(@chgrp($this->fooURL, vfsStream::GROUP_USER_2)); + $this->assertEquals(vfsStream::getCurrentGroup(), filegroup($this->fooURL)); + } + } + + /** + * @test + * @author Benoit Aubuchon + */ + public function renameDirectory() + { + // move foo/bar to foo/baz3 + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(rename($this->barURL, $baz3URL)); + $this->assertFileExists($baz3URL); + $this->assertFileNotExists($this->barURL); + } + + /** + * @test + */ + public function renameDirectoryWithDots() + { + // move foo/bar to foo/baz3 + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(rename($this->barURL . '/.', $baz3URL)); + $this->assertFileExists($baz3URL); + $this->assertFileNotExists($this->barURL); + } + + /** + * @test + * @group issue_9 + * @since 0.9.0 + */ + public function renameDirectoryWithDotsInTarget() + { + // move foo/bar to foo/baz3 + $baz3URL = vfsStream::url('foo/../baz3/.'); + $this->assertTrue(rename($this->barURL . '/.', $baz3URL)); + $this->assertFileExists($baz3URL); + $this->assertFileNotExists($this->barURL); + } + + /** + * @test + * @author Benoit Aubuchon + */ + public function renameDirectoryOverwritingExistingFile() + { + // move foo/bar to foo/baz2 + $this->assertTrue(rename($this->barURL, $this->baz2URL)); + $this->assertFileExists(vfsStream::url('foo/baz2/baz1')); + $this->assertFileNotExists($this->barURL); + } + + /** + * @test + * @expectedException PHPUnit_Framework_Error + */ + public function renameFileIntoFile() + { + // foo/baz2 is a file, so it can not be turned into a directory + $baz3URL = vfsStream::url('foo/baz2/baz3'); + $this->assertTrue(rename($this->baz1URL, $baz3URL)); + $this->assertFileExists($baz3URL); + $this->assertFileNotExists($this->baz1URL); + } + + /** + * @test + * @author Benoit Aubuchon + */ + public function renameFileToDirectory() + { + // move foo/bar/baz1 to foo/baz3 + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(rename($this->baz1URL, $baz3URL)); + $this->assertFileExists($this->barURL); + $this->assertFileExists($baz3URL); + $this->assertFileNotExists($this->baz1URL); + } + + /** + * assert that trying to rename from a non existing file trigger a warning + * + * @expectedException PHPUnit_Framework_Error + * @test + */ + public function renameOnSourceFileNotFound() + { + rename(vfsStream::url('notfound'), $this->baz1URL); + } + /** + * assert that trying to rename to a directory that is not found trigger a warning + + * @expectedException PHPUnit_Framework_Error + * @test + */ + public function renameOnDestinationDirectoryFileNotFound() + { + rename($this->baz1URL, vfsStream::url('foo/notfound/file2')); + } + /** + * stat() and fstat() should return the same result + * + * @test + */ + public function statAndFstatReturnSameResult() + { + $fp = fopen($this->baz2URL, 'r'); + $this->assertEquals(stat($this->baz2URL), + fstat($fp) + ); + fclose($fp); + } + + /** + * stat() returns full data + * + * @test + */ + public function statReturnsFullDataForFiles() + { + $this->assertEquals(array(0 => 0, + 1 => 0, + 2 => 0100666, + 3 => 0, + 4 => vfsStream::getCurrentUser(), + 5 => vfsStream::getCurrentGroup(), + 6 => 0, + 7 => 4, + 8 => 400, + 9 => 400, + 10 => 400, + 11 => -1, + 12 => -1, + 'dev' => 0, + 'ino' => 0, + 'mode' => 0100666, + 'nlink' => 0, + 'uid' => vfsStream::getCurrentUser(), + 'gid' => vfsStream::getCurrentGroup(), + 'rdev' => 0, + 'size' => 4, + 'atime' => 400, + 'mtime' => 400, + 'ctime' => 400, + 'blksize' => -1, + 'blocks' => -1 + ), + stat($this->baz2URL) + ); + } + + /** + * @test + */ + public function statReturnsFullDataForDirectories() + { + $this->assertEquals(array(0 => 0, + 1 => 0, + 2 => 0040777, + 3 => 0, + 4 => vfsStream::getCurrentUser(), + 5 => vfsStream::getCurrentGroup(), + 6 => 0, + 7 => 0, + 8 => 100, + 9 => 100, + 10 => 100, + 11 => -1, + 12 => -1, + 'dev' => 0, + 'ino' => 0, + 'mode' => 0040777, + 'nlink' => 0, + 'uid' => vfsStream::getCurrentUser(), + 'gid' => vfsStream::getCurrentGroup(), + 'rdev' => 0, + 'size' => 0, + 'atime' => 100, + 'mtime' => 100, + 'ctime' => 100, + 'blksize' => -1, + 'blocks' => -1 + ), + stat($this->fooURL) + ); + } + + /** + * @test + */ + public function statReturnsFullDataForDirectoriesWithDot() + { + $this->assertEquals(array(0 => 0, + 1 => 0, + 2 => 0040777, + 3 => 0, + 4 => vfsStream::getCurrentUser(), + 5 => vfsStream::getCurrentGroup(), + 6 => 0, + 7 => 0, + 8 => 100, + 9 => 100, + 10 => 100, + 11 => -1, + 12 => -1, + 'dev' => 0, + 'ino' => 0, + 'mode' => 0040777, + 'nlink' => 0, + 'uid' => vfsStream::getCurrentUser(), + 'gid' => vfsStream::getCurrentGroup(), + 'rdev' => 0, + 'size' => 0, + 'atime' => 100, + 'mtime' => 100, + 'ctime' => 100, + 'blksize' => -1, + 'blocks' => -1 + ), + stat($this->fooURL . '/.') + ); + } + + /** + * @test + * @expectedException PHPUnit_Framework_Error + */ + public function openFileWithoutDirectory() + { + vfsStreamWrapper::register(); + $this->assertFalse(file_get_contents(vfsStream::url('file.txt'))); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + * @requires PHP 5.4.0 + */ + public function truncateRemovesSuperflouosContent() + { + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + $handle = fopen($this->baz1URL, "r+"); + $this->assertTrue(ftruncate($handle, 0)); + $this->assertEquals(0, filesize($this->baz1URL)); + $this->assertEquals('', file_get_contents($this->baz1URL)); + fclose($handle); + } + + /** + * @test + * @group issue_33 + * @since 1.1.0 + * @requires PHP 5.4.0 + */ + public function truncateToGreaterSizeAddsZeroBytes() + { + if (strstr(PHP_VERSION, 'hiphop') !== false) { + $this->markTestSkipped('Not supported on hhvm'); + } + + $handle = fopen($this->baz1URL, "r+"); + $this->assertTrue(ftruncate($handle, 25)); + $this->assertEquals(25, filesize($this->baz1URL)); + $this->assertEquals("baz 1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + file_get_contents($this->baz1URL)); + fclose($handle); + } + + /** + * @test + * @group issue_11 + * @requires PHP 5.4.0 + */ + public function touchCreatesNonExistingFile() + { + $this->assertTrue(touch($this->fooURL . '/new.txt')); + $this->assertTrue($this->foo->hasChild('new.txt')); + } + + /** + * @test + * @group issue_11 + * @requires PHP 5.4.0 + */ + public function touchChangesAccessAndModificationTimeForFile() + { + $this->assertTrue(touch($this->baz1URL, 303, 313)); + $this->assertEquals(303, $this->baz1->filemtime()); + $this->assertEquals(313, $this->baz1->fileatime()); + } + + /** + * @test + * @group issue_11 + * @group issue_80 + * @requires PHP 5.4.0 + */ + public function touchChangesTimesToCurrentTimestampWhenNoTimesGiven() + { + $this->assertTrue(touch($this->baz1URL)); + $this->assertEquals(time(), $this->baz1->filemtime(), '', 1); + $this->assertEquals(time(), $this->baz1->fileatime(), '', 1); + } + + /** + * @test + * @group issue_11 + * @requires PHP 5.4.0 + */ + public function touchWithModifiedTimeChangesAccessAndModifiedTime() + { + $this->assertTrue(touch($this->baz1URL, 303)); + $this->assertEquals(303, $this->baz1->filemtime()); + $this->assertEquals(303, $this->baz1->fileatime()); + } + + /** + * @test + * @group issue_11 + * @requires PHP 5.4.0 + */ + public function touchChangesAccessAndModificationTimeForDirectory() + { + $this->assertTrue(touch($this->fooURL, 303, 313)); + $this->assertEquals(303, $this->foo->filemtime()); + $this->assertEquals(313, $this->foo->fileatime()); + } + + /** + * @test + * @group issue_34 + * @since 1.2.0 + */ + public function pathesAreCorrectlySet() + { + $this->assertEquals(vfsStream::path($this->fooURL), $this->foo->path()); + $this->assertEquals(vfsStream::path($this->barURL), $this->bar->path()); + $this->assertEquals(vfsStream::path($this->baz1URL), $this->baz1->path()); + $this->assertEquals(vfsStream::path($this->baz2URL), $this->baz2->path()); + } + + /** + * @test + * @group issue_34 + * @since 1.2.0 + */ + public function urlsAreCorrectlySet() + { + $this->assertEquals($this->fooURL, $this->foo->url()); + $this->assertEquals($this->barURL, $this->bar->url()); + $this->assertEquals($this->baz1URL, $this->baz1->url()); + $this->assertEquals($this->baz2URL, $this->baz2->url()); + } + + /** + * @test + * @group issue_34 + * @since 1.2.0 + */ + public function pathIsUpdatedAfterMove() + { + // move foo/bar/baz1 to foo/baz3 + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(rename($this->baz1URL, $baz3URL)); + $this->assertEquals(vfsStream::path($baz3URL), $this->baz1->path()); + } + + /** + * @test + * @group issue_34 + * @since 1.2.0 + */ + public function urlIsUpdatedAfterMove() + { + // move foo/bar/baz1 to foo/baz3 + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(rename($this->baz1URL, $baz3URL)); + $this->assertEquals($baz3URL, $this->baz1->url()); + } + + /** + * @test + */ + public function fileCopy() + { + $baz3URL = vfsStream::url('foo/baz3'); + $this->assertTrue(copy($this->baz1URL, $baz3URL)); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperUnregisterTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperUnregisterTestCase.php new file mode 100644 index 0000000..4e27685 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperUnregisterTestCase.php @@ -0,0 +1,75 @@ +assertNotContains(vfsStream::SCHEME, stream_get_wrappers()); + } + + /** + * Unregistering a third party wrapper for vfs:// fails. + * + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + * @runInSeparateProcess + */ + public function unregisterThirdPartyVfsScheme() + { + // Unregister possible registered URL wrapper. + vfsStreamWrapper::unregister(); + + $mock = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamWrapper'); + stream_wrapper_register(vfsStream::SCHEME, get_class($mock)); + + vfsStreamWrapper::unregister(); + } + + /** + * Unregistering when not in registered state will fail. + * + * @test + * @expectedException org\bovigo\vfs\vfsStreamException + * @runInSeparateProcess + */ + public function unregisterWhenNotInRegisteredState() + { + vfsStreamWrapper::register(); + stream_wrapper_unregister(vfsStream::SCHEME); + vfsStreamWrapper::unregister(); + } + + /** + * Unregistering while not registers won't fail. + * + * @test + */ + public function unregisterWhenNotRegistered() + { + // Unregister possible registered URL wrapper. + vfsStreamWrapper::unregister(); + + $this->assertNotContains(vfsStream::SCHEME, stream_get_wrappers()); + vfsStreamWrapper::unregister(); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperWithoutRootTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperWithoutRootTestCase.php new file mode 100644 index 0000000..8267a32 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamWrapperWithoutRootTestCase.php @@ -0,0 +1,63 @@ + no directory to open + * + * @test + */ + public function canNotOpenDirectory() + { + $this->assertFalse(@dir(vfsStream::url('foo'))); + } + + /** + * can not unlink without root + * + * @test + */ + public function canNotUnlink() + { + $this->assertFalse(@unlink(vfsStream::url('foo'))); + } + + /** + * can not open a file without root + * + * @test + */ + public function canNotOpen() + { + $this->assertFalse(@fopen(vfsStream::url('foo'), 'r')); + } + + /** + * can not rename a file without root + * + * @test + */ + public function canNotRename() + { + $this->assertFalse(@rename(vfsStream::url('foo'), vfsStream::url('bar'))); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamZipTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamZipTestCase.php new file mode 100644 index 0000000..210642c --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/vfsStreamZipTestCase.php @@ -0,0 +1,52 @@ +markTestSkipped('No ext/zip installed, skipping test.'); + } + + $this->markTestSkipped('Zip extension can not work with vfsStream urls.'); + + vfsStreamWrapper::register(); + vfsStreamWrapper::setRoot(vfsStream::newDirectory('root')); + + } + + /** + * @test + */ + public function createZipArchive() + { + $zip = new ZipArchive(); + $this->assertTrue($zip->open(vfsStream::url('root/test.zip'), ZipArchive::CREATE)); + $this->assertTrue($zip->addFromString("testfile1.txt", "#1 This is a test string added as testfile1.txt.\n")); + $this->assertTrue($zip->addFromString("testfile2.txt", "#2 This is a test string added as testfile2.txt.\n")); + $zip->setArchiveComment('a test'); + var_dump($zip); + $this->assertTrue($zip->close()); + var_dump($zip->getStatusString()); + var_dump($zip->close()); + var_dump($zip->getStatusString()); + var_dump($zip); + var_dump(file_exists(vfsStream::url('root/test.zip'))); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitorTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitorTestCase.php new file mode 100644 index 0000000..dfb3ed5 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamAbstractVisitorTestCase.php @@ -0,0 +1,98 @@ +abstractVisitor = $this->bc_getMock('org\\bovigo\\vfs\\visitor\\vfsStreamAbstractVisitor', + array('visitFile', 'visitDirectory') + ); + } + + /** + * @test + * @expectedException \InvalidArgumentException + */ + public function visitThrowsInvalidArgumentExceptionOnUnknownContentType() + { + $mockContent = $this->bc_getMock('org\\bovigo\\vfs\\vfsStreamContent'); + $mockContent->expects($this->any()) + ->method('getType') + ->will($this->returnValue('invalid')); + $this->assertSame($this->abstractVisitor, + $this->abstractVisitor->visit($mockContent) + ); + } + + /** + * @test + */ + public function visitWithFileCallsVisitFile() + { + $file = new vfsStreamFile('foo.txt'); + $this->abstractVisitor->expects($this->once()) + ->method('visitFile') + ->with($this->equalTo($file)); + $this->assertSame($this->abstractVisitor, + $this->abstractVisitor->visit($file) + ); + } + + /** + * tests that a block device eventually calls out to visit file + * + * @test + */ + public function visitWithBlockCallsVisitFile() + { + $block = new vfsStreamBlock('foo'); + $this->abstractVisitor->expects($this->once()) + ->method('visitFile') + ->with($this->equalTo($block)); + $this->assertSame($this->abstractVisitor, + $this->abstractVisitor->visit($block) + ); + } + + /** + * @test + */ + public function visitWithDirectoryCallsVisitDirectory() + { + $dir = new vfsStreamDirectory('bar'); + $this->abstractVisitor->expects($this->once()) + ->method('visitDirectory') + ->with($this->equalTo($dir)); + $this->assertSame($this->abstractVisitor, + $this->abstractVisitor->visit($dir) + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitorTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitorTestCase.php new file mode 100644 index 0000000..294bd77 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamPrintVisitorTestCase.php @@ -0,0 +1,102 @@ +at(vfsStream::setup()); + $printVisitor = new vfsStreamPrintVisitor(fopen('vfs://root/foo.txt', 'wb')); + $this->assertSame($printVisitor, + $printVisitor->visitFile(vfsStream::newFile('bar.txt')) + ); + $this->assertEquals("- bar.txt\n", $output->getContent()); + } + + /** + * @test + */ + public function visitFileWritesBlockDeviceToStream() + { + $output = vfsStream::newFile('foo.txt') + ->at(vfsStream::setup()); + $printVisitor = new vfsStreamPrintVisitor(fopen('vfs://root/foo.txt', 'wb')); + $this->assertSame($printVisitor, + $printVisitor->visitBlockDevice(vfsStream::newBlock('bar')) + ); + $this->assertEquals("- [bar]\n", $output->getContent()); + } + + /** + * @test + */ + public function visitDirectoryWritesDirectoryNameToStream() + { + $output = vfsStream::newFile('foo.txt') + ->at(vfsStream::setup()); + $printVisitor = new vfsStreamPrintVisitor(fopen('vfs://root/foo.txt', 'wb')); + $this->assertSame($printVisitor, + $printVisitor->visitDirectory(vfsStream::newDirectory('baz')) + ); + $this->assertEquals("- baz\n", $output->getContent()); + } + + /** + * @test + */ + public function visitRecursiveDirectoryStructure() + { + $root = vfsStream::setup('root', + null, + array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ), + 'foo.txt' => '' + ) + ); + $printVisitor = new vfsStreamPrintVisitor(fopen('vfs://root/foo.txt', 'wb')); + $this->assertSame($printVisitor, + $printVisitor->visitDirectory($root) + ); + $this->assertEquals("- root\n - test\n - foo\n - test.txt\n - baz.txt\n - foo.txt\n", file_get_contents('vfs://root/foo.txt')); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitorTestCase.php b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitorTestCase.php new file mode 100644 index 0000000..c9df234 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/php/org/bovigo/vfs/visitor/vfsStreamStructureVisitorTestCase.php @@ -0,0 +1,85 @@ +assertEquals(array('foo.txt' => 'test'), + $structureVisitor->visitFile(vfsStream::newFile('foo.txt') + ->withContent('test') + ) + ->getStructure() + ); + } + + /** + * @test + */ + public function visitFileCreatesStructureForBlock() + { + $structureVisitor = new vfsStreamStructureVisitor(); + $this->assertEquals(array('[foo]' => 'test'), + $structureVisitor->visitBlockDevice(vfsStream::newBlock('foo') + ->withContent('test') + ) + ->getStructure() + ); + } + + /** + * @test + */ + public function visitDirectoryCreatesStructureForDirectory() + { + $structureVisitor = new vfsStreamStructureVisitor(); + $this->assertEquals(array('baz' => array()), + $structureVisitor->visitDirectory(vfsStream::newDirectory('baz')) + ->getStructure() + ); + } + + /** + * @test + */ + public function visitRecursiveDirectoryStructure() + { + $root = vfsStream::setup('root', + null, + array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ), + 'foo.txt' => '' + ) + ); + $structureVisitor = new vfsStreamStructureVisitor(); + $this->assertEquals(array('root' => array('test' => array('foo' => array('test.txt' => 'hello'), + 'baz.txt' => 'world' + ), + 'foo.txt' => '' + ), + ), + $structureVisitor->visitDirectory($root) + ->getStructure() + ); + } +} diff --git a/vendor/mikey179/vfsstream/src/test/phpt/bug71287.phpt b/vendor/mikey179/vfsstream/src/test/phpt/bug71287.phpt new file mode 100644 index 0000000..ea2efb7 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/phpt/bug71287.phpt @@ -0,0 +1,23 @@ +--TEST-- +Reproduce octal output from stream wrapper invocation + +See https://bugs.php.net/bug.php?id=71287 +See https://github.com/mikey179/vfsStream/issues/120 +--FILE-- + +--EXPECTF-- +Warning: file_put_contents(): Only 7 of 9 bytes written, possibly out of free disk space in %s on line %d \ No newline at end of file diff --git a/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/emptyFolder/.gitignore b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/emptyFolder/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/aFile.txt b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/aFile.txt new file mode 100644 index 0000000..1910281 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/aFile.txt @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder1/file1.txt b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder1/file1.txt new file mode 100644 index 0000000..f6ea049 --- /dev/null +++ b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder1/file1.txt @@ -0,0 +1 @@ +foobar \ No newline at end of file diff --git a/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder2/.gitignore b/vendor/mikey179/vfsstream/src/test/resources/filesystemcopy/withSubfolders/subfolder2/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/vendor/myclabs/deep-copy/.github/FUNDING.yml b/vendor/myclabs/deep-copy/.github/FUNDING.yml new file mode 100644 index 0000000..b8da664 --- /dev/null +++ b/vendor/myclabs/deep-copy/.github/FUNDING.yml @@ -0,0 +1,12 @@ +# These are supported funding model platforms + +github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] +patreon: # Replace with a single Patreon username +open_collective: # Replace with a single Open Collective username +ko_fi: # Replace with a single Ko-fi username +tidelift: "packagist/myclabs/deep-copy" +community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry +liberapay: # Replace with a single Liberapay username +issuehunt: # Replace with a single IssueHunt username +otechie: # Replace with a single Otechie username +custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/vendor/myclabs/deep-copy/LICENSE b/vendor/myclabs/deep-copy/LICENSE new file mode 100644 index 0000000..c3e8350 --- /dev/null +++ b/vendor/myclabs/deep-copy/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 My C-Sense + +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/myclabs/deep-copy/README.md b/vendor/myclabs/deep-copy/README.md new file mode 100644 index 0000000..007ad5b --- /dev/null +++ b/vendor/myclabs/deep-copy/README.md @@ -0,0 +1,375 @@ +# DeepCopy + +DeepCopy helps you create deep copies (clones) of your objects. It is designed to handle cycles in the association graph. + +[![Build Status](https://travis-ci.org/myclabs/DeepCopy.png?branch=1.x)](https://travis-ci.org/myclabs/DeepCopy) +[![Coverage Status](https://coveralls.io/repos/myclabs/DeepCopy/badge.png?branch=1.x)](https://coveralls.io/r/myclabs/DeepCopy?branch=1.x) +[![Scrutinizer Quality Score](https://scrutinizer-ci.com/g/myclabs/DeepCopy/badges/quality-score.png?s=2747100c19b275f93a777e3297c6c12d1b68b934)](https://scrutinizer-ci.com/g/myclabs/DeepCopy/) +[![Total Downloads](https://poser.pugx.org/myclabs/deep-copy/downloads.svg)](https://packagist.org/packages/myclabs/deep-copy) + +## Table of Contents + +1. [How](#how) +1. [Why](#why) + 1. [Using simply `clone`](#using-simply-clone) + 1. [Overridding `__clone()`](#overridding-__clone) + 1. [With `DeepCopy`](#with-deepcopy) +1. [How it works](#how-it-works) +1. [Going further](#going-further) + 1. [Matchers](#matchers) + 1. [Property name](#property-name) + 1. [Specific property](#specific-property) + 1. [Type](#type) + 1. [Filters](#filters) + 1. [`SetNullFilter`](#setnullfilter-filter) + 1. [`KeepFilter`](#keepfilter-filter) + 1. [`DoctrineCollectionFilter`](#doctrinecollectionfilter-filter) + 1. [`DoctrineEmptyCollectionFilter`](#doctrineemptycollectionfilter-filter) + 1. [`DoctrineProxyFilter`](#doctrineproxyfilter-filter) + 1. [`ReplaceFilter`](#replacefilter-type-filter) + 1. [`ShallowCopyFilter`](#shallowcopyfilter-type-filter) +1. [Edge cases](#edge-cases) +1. [Contributing](#contributing) + 1. [Tests](#tests) + + +## How? + +Install with Composer: + +```json +composer require myclabs/deep-copy +``` + +Use simply: + +```php +use DeepCopy\DeepCopy; + +$copier = new DeepCopy(); +$myCopy = $copier->copy($myObject); +``` + + +## Why? + +- How do you create copies of your objects? + +```php +$myCopy = clone $myObject; +``` + +- How do you create **deep** copies of your objects (i.e. copying also all the objects referenced in the properties)? + +You use [`__clone()`](http://www.php.net/manual/en/language.oop5.cloning.php#object.clone) and implement the behavior +yourself. + +- But how do you handle **cycles** in the association graph? + +Now you're in for a big mess :( + +![association graph](doc/graph.png) + + +### Using simply `clone` + +![Using clone](doc/clone.png) + + +### Overridding `__clone()` + +![Overridding __clone](doc/deep-clone.png) + + +### With `DeepCopy` + +![With DeepCopy](doc/deep-copy.png) + + +## How it works + +DeepCopy recursively traverses all the object's properties and clones them. To avoid cloning the same object twice it +keeps a hash map of all instances and thus preserves the object graph. + +To use it: + +```php +use function DeepCopy\deep_copy; + +$copy = deep_copy($var); +``` + +Alternatively, you can create your own `DeepCopy` instance to configure it differently for example: + +```php +use DeepCopy\DeepCopy; + +$copier = new DeepCopy(true); + +$copy = $copier->copy($var); +``` + +You may want to roll your own deep copy function: + +```php +namespace Acme; + +use DeepCopy\DeepCopy; + +function deep_copy($var) +{ + static $copier = null; + + if (null === $copier) { + $copier = new DeepCopy(true); + } + + return $copier->copy($var); +} +``` + + +## Going further + +You can add filters to customize the copy process. + +The method to add a filter is `DeepCopy\DeepCopy::addFilter($filter, $matcher)`, +with `$filter` implementing `DeepCopy\Filter\Filter` +and `$matcher` implementing `DeepCopy\Matcher\Matcher`. + +We provide some generic filters and matchers. + + +### Matchers + + - `DeepCopy\Matcher` applies on a object attribute. + - `DeepCopy\TypeMatcher` applies on any element found in graph, including array elements. + + +#### Property name + +The `PropertyNameMatcher` will match a property by its name: + +```php +use DeepCopy\Matcher\PropertyNameMatcher; + +// Will apply a filter to any property of any objects named "id" +$matcher = new PropertyNameMatcher('id'); +``` + + +#### Specific property + +The `PropertyMatcher` will match a specific property of a specific class: + +```php +use DeepCopy\Matcher\PropertyMatcher; + +// Will apply a filter to the property "id" of any objects of the class "MyClass" +$matcher = new PropertyMatcher('MyClass', 'id'); +``` + + +#### Type + +The `TypeMatcher` will match any element by its type (instance of a class or any value that could be parameter of +[gettype()](http://php.net/manual/en/function.gettype.php) function): + +```php +use DeepCopy\TypeMatcher\TypeMatcher; + +// Will apply a filter to any object that is an instance of Doctrine\Common\Collections\Collection +$matcher = new TypeMatcher('Doctrine\Common\Collections\Collection'); +``` + + +### Filters + +- `DeepCopy\Filter` applies a transformation to the object attribute matched by `DeepCopy\Matcher` +- `DeepCopy\TypeFilter` applies a transformation to any element matched by `DeepCopy\TypeMatcher` + + +#### `SetNullFilter` (filter) + +Let's say for example that you are copying a database record (or a Doctrine entity), so you want the copy not to have +any ID: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\SetNullFilter; +use DeepCopy\Matcher\PropertyNameMatcher; + +$object = MyClass::load(123); +echo $object->id; // 123 + +$copier = new DeepCopy(); +$copier->addFilter(new SetNullFilter(), new PropertyNameMatcher('id')); + +$copy = $copier->copy($object); + +echo $copy->id; // null +``` + + +#### `KeepFilter` (filter) + +If you want a property to remain untouched (for example, an association to an object): + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\KeepFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new KeepFilter(), new PropertyMatcher('MyClass', 'category')); + +$copy = $copier->copy($object); +// $copy->category has not been touched +``` + + +#### `DoctrineCollectionFilter` (filter) + +If you use Doctrine and want to copy an entity, you will need to use the `DoctrineCollectionFilter`: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineCollectionFilter; +use DeepCopy\Matcher\PropertyTypeMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineCollectionFilter(), new PropertyTypeMatcher('Doctrine\Common\Collections\Collection')); + +$copy = $copier->copy($object); +``` + + +#### `DoctrineEmptyCollectionFilter` (filter) + +If you use Doctrine and want to copy an entity who contains a `Collection` that you want to be reset, you can use the +`DoctrineEmptyCollectionFilter` + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineEmptyCollectionFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineEmptyCollectionFilter(), new PropertyMatcher('MyClass', 'myProperty')); + +$copy = $copier->copy($object); + +// $copy->myProperty will return an empty collection +``` + + +#### `DoctrineProxyFilter` (filter) + +If you use Doctrine and use cloning on lazy loaded entities, you might encounter errors mentioning missing fields on a +Doctrine proxy class (...\\\_\_CG\_\_\Proxy). +You can use the `DoctrineProxyFilter` to load the actual entity behind the Doctrine proxy class. +**Make sure, though, to put this as one of your very first filters in the filter chain so that the entity is loaded +before other filters are applied!** + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\Doctrine\DoctrineProxyFilter; +use DeepCopy\Matcher\Doctrine\DoctrineProxyMatcher; + +$copier = new DeepCopy(); +$copier->addFilter(new DoctrineProxyFilter(), new DoctrineProxyMatcher()); + +$copy = $copier->copy($object); + +// $copy should now contain a clone of all entities, including those that were not yet fully loaded. +``` + + +#### `ReplaceFilter` (type filter) + +1. If you want to replace the value of a property: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\Filter\ReplaceFilter; +use DeepCopy\Matcher\PropertyMatcher; + +$copier = new DeepCopy(); +$callback = function ($currentValue) { + return $currentValue . ' (copy)' +}; +$copier->addFilter(new ReplaceFilter($callback), new PropertyMatcher('MyClass', 'title')); + +$copy = $copier->copy($object); + +// $copy->title will contain the data returned by the callback, e.g. 'The title (copy)' +``` + +2. If you want to replace whole element: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\TypeFilter\ReplaceFilter; +use DeepCopy\TypeMatcher\TypeMatcher; + +$copier = new DeepCopy(); +$callback = function (MyClass $myClass) { + return get_class($myClass); +}; +$copier->addTypeFilter(new ReplaceFilter($callback), new TypeMatcher('MyClass')); + +$copy = $copier->copy([new MyClass, 'some string', new MyClass]); + +// $copy will contain ['MyClass', 'some string', 'MyClass'] +``` + + +The `$callback` parameter of the `ReplaceFilter` constructor accepts any PHP callable. + + +#### `ShallowCopyFilter` (type filter) + +Stop *DeepCopy* from recursively copying element, using standard `clone` instead: + +```php +use DeepCopy\DeepCopy; +use DeepCopy\TypeFilter\ShallowCopyFilter; +use DeepCopy\TypeMatcher\TypeMatcher; +use Mockery as m; + +$this->deepCopy = new DeepCopy(); +$this->deepCopy->addTypeFilter( + new ShallowCopyFilter, + new TypeMatcher(m\MockInterface::class) +); + +$myServiceWithMocks = new MyService(m::mock(MyDependency1::class), m::mock(MyDependency2::class)); +// All mocks will be just cloned, not deep copied +``` + + +## Edge cases + +The following structures cannot be deep-copied with PHP Reflection. As a result they are shallow cloned and filters are +not applied. There is two ways for you to handle them: + +- Implement your own `__clone()` method +- Use a filter with a type matcher + + +## Contributing + +DeepCopy is distributed under the MIT license. + + +### Tests + +Running the tests is simple: + +```php +vendor/bin/phpunit +``` + +### Support + +Get professional support via [the Tidelift Subscription](https://tidelift.com/subscription/pkg/packagist-myclabs-deep-copy?utm_source=packagist-myclabs-deep-copy&utm_medium=referral&utm_campaign=readme). diff --git a/vendor/myclabs/deep-copy/composer.json b/vendor/myclabs/deep-copy/composer.json new file mode 100644 index 0000000..45656c9 --- /dev/null +++ b/vendor/myclabs/deep-copy/composer.json @@ -0,0 +1,38 @@ +{ + "name": "myclabs/deep-copy", + "type": "library", + "description": "Create deep copies (clones) of your objects", + "keywords": ["clone", "copy", "duplicate", "object", "object graph"], + "license": "MIT", + + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "autoload-dev": { + "psr-4": { + "DeepCopy\\": "fixtures/", + "DeepCopyTest\\": "tests/DeepCopyTest/" + } + }, + + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + + "config": { + "sort-packages": true + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php b/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php new file mode 100644 index 0000000..15e5c68 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/DeepCopy.php @@ -0,0 +1,298 @@ + Filter, 'matcher' => Matcher] pairs. + */ + private $filters = []; + + /** + * Type Filters to apply. + * + * @var array Array of ['filter' => Filter, 'matcher' => Matcher] pairs. + */ + private $typeFilters = []; + + /** + * @var bool + */ + private $skipUncloneable = false; + + /** + * @var bool + */ + private $useCloneMethod; + + /** + * @param bool $useCloneMethod If set to true, when an object implements the __clone() function, it will be used + * instead of the regular deep cloning. + */ + public function __construct($useCloneMethod = false) + { + $this->useCloneMethod = $useCloneMethod; + + $this->addTypeFilter(new ArrayObjectFilter($this), new TypeMatcher(ArrayObject::class)); + $this->addTypeFilter(new DateIntervalFilter(), new TypeMatcher(DateInterval::class)); + $this->addTypeFilter(new SplDoublyLinkedListFilter($this), new TypeMatcher(SplDoublyLinkedList::class)); + } + + /** + * If enabled, will not throw an exception when coming across an uncloneable property. + * + * @param $skipUncloneable + * + * @return $this + */ + public function skipUncloneable($skipUncloneable = true) + { + $this->skipUncloneable = $skipUncloneable; + + return $this; + } + + /** + * Deep copies the given object. + * + * @param mixed $object + * + * @return mixed + */ + public function copy($object) + { + $this->hashMap = []; + + return $this->recursiveCopy($object); + } + + public function addFilter(Filter $filter, Matcher $matcher) + { + $this->filters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + public function prependFilter(Filter $filter, Matcher $matcher) + { + array_unshift($this->filters, [ + 'matcher' => $matcher, + 'filter' => $filter, + ]); + } + + public function addTypeFilter(TypeFilter $filter, TypeMatcher $matcher) + { + $this->typeFilters[] = [ + 'matcher' => $matcher, + 'filter' => $filter, + ]; + } + + private function recursiveCopy($var) + { + // Matches Type Filter + if ($filter = $this->getFirstMatchedTypeFilter($this->typeFilters, $var)) { + return $filter->apply($var); + } + + // Resource + if (is_resource($var)) { + return $var; + } + + // Array + if (is_array($var)) { + return $this->copyArray($var); + } + + // Scalar + if (! is_object($var)) { + return $var; + } + + // Object + return $this->copyObject($var); + } + + /** + * Copy an array + * @param array $array + * @return array + */ + private function copyArray(array $array) + { + foreach ($array as $key => $value) { + $array[$key] = $this->recursiveCopy($value); + } + + return $array; + } + + /** + * Copies an object. + * + * @param object $object + * + * @throws CloneException + * + * @return object + */ + private function copyObject($object) + { + $objectHash = spl_object_hash($object); + + if (isset($this->hashMap[$objectHash])) { + return $this->hashMap[$objectHash]; + } + + $reflectedObject = new ReflectionObject($object); + $isCloneable = $reflectedObject->isCloneable(); + + if (false === $isCloneable) { + if ($this->skipUncloneable) { + $this->hashMap[$objectHash] = $object; + + return $object; + } + + throw new CloneException( + sprintf( + 'The class "%s" is not cloneable.', + $reflectedObject->getName() + ) + ); + } + + $newObject = clone $object; + $this->hashMap[$objectHash] = $newObject; + + if ($this->useCloneMethod && $reflectedObject->hasMethod('__clone')) { + return $newObject; + } + + if ($newObject instanceof DateTimeInterface || $newObject instanceof DateTimeZone) { + return $newObject; + } + + foreach (ReflectionHelper::getProperties($reflectedObject) as $property) { + $this->copyObjectProperty($newObject, $property); + } + + return $newObject; + } + + private function copyObjectProperty($object, ReflectionProperty $property) + { + // Ignore static properties + if ($property->isStatic()) { + return; + } + + // Apply the filters + foreach ($this->filters as $item) { + /** @var Matcher $matcher */ + $matcher = $item['matcher']; + /** @var Filter $filter */ + $filter = $item['filter']; + + if ($matcher->matches($object, $property->getName())) { + $filter->apply( + $object, + $property->getName(), + function ($object) { + return $this->recursiveCopy($object); + } + ); + + // If a filter matches, we stop processing this property + return; + } + } + + $property->setAccessible(true); + + // Ignore uninitialized properties (for PHP >7.4) + if (method_exists($property, 'isInitialized') && !$property->isInitialized($object)) { + return; + } + + $propertyValue = $property->getValue($object); + + // Copy the property + $property->setValue($object, $this->recursiveCopy($propertyValue)); + } + + /** + * Returns first filter that matches variable, `null` if no such filter found. + * + * @param array $filterRecords Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and + * 'matcher' with value of type {@see TypeMatcher} + * @param mixed $var + * + * @return TypeFilter|null + */ + private function getFirstMatchedTypeFilter(array $filterRecords, $var) + { + $matched = $this->first( + $filterRecords, + function (array $record) use ($var) { + /* @var TypeMatcher $matcher */ + $matcher = $record['matcher']; + + return $matcher->matches($var); + } + ); + + return isset($matched) ? $matched['filter'] : null; + } + + /** + * Returns first element that matches predicate, `null` if no such element found. + * + * @param array $elements Array of ['filter' => Filter, 'matcher' => Matcher] pairs. + * @param callable $predicate Predicate arguments are: element. + * + * @return array|null Associative array with 2 members: 'filter' with value of type {@see TypeFilter} and 'matcher' + * with value of type {@see TypeMatcher} or `null`. + */ + private function first(array $elements, callable $predicate) + { + foreach ($elements as $element) { + if (call_user_func($predicate, $element)) { + return $element; + } + } + + return null; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php new file mode 100644 index 0000000..c046706 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Exception/CloneException.php @@ -0,0 +1,9 @@ +setAccessible(true); + $oldCollection = $reflectionProperty->getValue($object); + + $newCollection = $oldCollection->map( + function ($item) use ($objectCopier) { + return $objectCopier($item); + } + ); + + $reflectionProperty->setValue($object, $newCollection); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php new file mode 100644 index 0000000..7b33fd5 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineEmptyCollectionFilter.php @@ -0,0 +1,28 @@ +setAccessible(true); + + $reflectionProperty->setValue($object, new ArrayCollection()); + } +} \ No newline at end of file diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php new file mode 100644 index 0000000..8bee8f7 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Doctrine/DoctrineProxyFilter.php @@ -0,0 +1,22 @@ +__load(); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php new file mode 100644 index 0000000..85ba18c --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/Filter.php @@ -0,0 +1,18 @@ +callback = $callable; + } + + /** + * Replaces the object property by the result of the callback called with the object property. + * + * {@inheritdoc} + */ + public function apply($object, $property, $objectCopier) + { + $reflectionProperty = ReflectionHelper::getProperty($object, $property); + $reflectionProperty->setAccessible(true); + + $value = call_user_func($this->callback, $reflectionProperty->getValue($object)); + + $reflectionProperty->setValue($object, $value); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php new file mode 100644 index 0000000..bea86b8 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Filter/SetNullFilter.php @@ -0,0 +1,24 @@ +setAccessible(true); + $reflectionProperty->setValue($object, null); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php new file mode 100644 index 0000000..ec8856f --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/Doctrine/DoctrineProxyMatcher.php @@ -0,0 +1,22 @@ +class = $class; + $this->property = $property; + } + + /** + * Matches a specific property of a specific class. + * + * {@inheritdoc} + */ + public function matches($object, $property) + { + return ($object instanceof $this->class) && $property == $this->property; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php new file mode 100644 index 0000000..c8ec0d2 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyNameMatcher.php @@ -0,0 +1,32 @@ +property = $property; + } + + /** + * Matches a property by its name. + * + * {@inheritdoc} + */ + public function matches($object, $property) + { + return $property == $this->property; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php new file mode 100644 index 0000000..a6b0c0b --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Matcher/PropertyTypeMatcher.php @@ -0,0 +1,46 @@ +propertyType = $propertyType; + } + + /** + * {@inheritdoc} + */ + public function matches($object, $property) + { + try { + $reflectionProperty = ReflectionHelper::getProperty($object, $property); + } catch (ReflectionException $exception) { + return false; + } + + $reflectionProperty->setAccessible(true); + + return $reflectionProperty->getValue($object) instanceof $this->propertyType; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php new file mode 100644 index 0000000..742410c --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/Reflection/ReflectionHelper.php @@ -0,0 +1,78 @@ +getProperties() does not return private properties from ancestor classes. + * + * @author muratyaman@gmail.com + * @see http://php.net/manual/en/reflectionclass.getproperties.php + * + * @param ReflectionClass $ref + * + * @return ReflectionProperty[] + */ + public static function getProperties(ReflectionClass $ref) + { + $props = $ref->getProperties(); + $propsArr = array(); + + foreach ($props as $prop) { + $propertyName = $prop->getName(); + $propsArr[$propertyName] = $prop; + } + + if ($parentClass = $ref->getParentClass()) { + $parentPropsArr = self::getProperties($parentClass); + foreach ($propsArr as $key => $property) { + $parentPropsArr[$key] = $property; + } + + return $parentPropsArr; + } + + return $propsArr; + } + + /** + * Retrieves property by name from object and all its ancestors. + * + * @param object|string $object + * @param string $name + * + * @throws PropertyException + * @throws ReflectionException + * + * @return ReflectionProperty + */ + public static function getProperty($object, $name) + { + $reflection = is_object($object) ? new ReflectionObject($object) : new ReflectionClass($object); + + if ($reflection->hasProperty($name)) { + return $reflection->getProperty($name); + } + + if ($parentClass = $reflection->getParentClass()) { + return self::getProperty($parentClass->getName(), $name); + } + + throw new PropertyException( + sprintf( + 'The class "%s" doesn\'t have a property with the given name: "%s".', + is_object($object) ? get_class($object) : $object, + $name + ) + ); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php new file mode 100644 index 0000000..becd1cf --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Date/DateIntervalFilter.php @@ -0,0 +1,33 @@ + $propertyValue) { + $copy->{$propertyName} = $propertyValue; + } + + return $copy; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php new file mode 100644 index 0000000..164f8b8 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ReplaceFilter.php @@ -0,0 +1,30 @@ +callback = $callable; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + return call_user_func($this->callback, $element); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php new file mode 100644 index 0000000..a5fbd7a --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/ShallowCopyFilter.php @@ -0,0 +1,17 @@ +copier = $copier; + } + + /** + * {@inheritdoc} + */ + public function apply($arrayObject) + { + $clone = clone $arrayObject; + foreach ($arrayObject->getArrayCopy() as $k => $v) { + $clone->offsetSet($k, $this->copier->copy($v)); + } + + return $clone; + } +} + diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php new file mode 100644 index 0000000..c5644cf --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/Spl/SplDoublyLinkedList.php @@ -0,0 +1,10 @@ +copier = $copier; + } + + /** + * {@inheritdoc} + */ + public function apply($element) + { + $newElement = clone $element; + + $copy = $this->createCopyClosure(); + + return $copy($newElement); + } + + private function createCopyClosure() + { + $copier = $this->copier; + + $copy = function (SplDoublyLinkedList $list) use ($copier) { + // Replace each element in the list with a deep copy of itself + for ($i = 1; $i <= $list->count(); $i++) { + $copy = $copier->recursiveCopy($list->shift()); + + $list->push($copy); + } + + return $list; + }; + + return Closure::bind($copy, null, DeepCopy::class); + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php new file mode 100644 index 0000000..5785a7d --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/TypeFilter/TypeFilter.php @@ -0,0 +1,13 @@ +type = $type; + } + + /** + * @param mixed $element + * + * @return boolean + */ + public function matches($element) + { + return is_object($element) ? is_a($element, $this->type) : gettype($element) === $this->type; + } +} diff --git a/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php new file mode 100644 index 0000000..55dcc92 --- /dev/null +++ b/vendor/myclabs/deep-copy/src/DeepCopy/deep_copy.php @@ -0,0 +1,20 @@ +copy($value); + } +} diff --git a/vendor/phar-io/manifest/.gitignore b/vendor/phar-io/manifest/.gitignore new file mode 100644 index 0000000..374459d --- /dev/null +++ b/vendor/phar-io/manifest/.gitignore @@ -0,0 +1,7 @@ +/.idea +/.php_cs.cache +/src/autoload.php +/tools +/vendor + +/build diff --git a/vendor/phar-io/manifest/.php_cs b/vendor/phar-io/manifest/.php_cs new file mode 100644 index 0000000..159d6a3 --- /dev/null +++ b/vendor/phar-io/manifest/.php_cs @@ -0,0 +1,67 @@ +files() + ->in('src') + ->in('tests') + ->name('*.php'); + +return Symfony\CS\Config\Config::create() + ->setUsingCache(true) + ->level(\Symfony\CS\FixerInterface::NONE_LEVEL) + ->fixers( + array( + 'align_double_arrow', + 'align_equals', + 'concat_with_spaces', + 'duplicate_semicolon', + 'elseif', + 'empty_return', + 'encoding', + 'eof_ending', + 'extra_empty_lines', + 'function_call_space', + 'function_declaration', + 'indentation', + 'join_function', + 'line_after_namespace', + 'linefeed', + 'list_commas', + 'lowercase_constants', + 'lowercase_keywords', + 'method_argument_space', + 'multiple_use', + 'namespace_no_leading_whitespace', + 'no_blank_lines_after_class_opening', + 'no_empty_lines_after_phpdocs', + 'parenthesis', + 'php_closing_tag', + 'phpdoc_indent', + 'phpdoc_no_access', + 'phpdoc_no_empty_return', + 'phpdoc_no_package', + 'phpdoc_params', + 'phpdoc_scalar', + 'phpdoc_separation', + 'phpdoc_to_comment', + 'phpdoc_trim', + 'phpdoc_types', + 'phpdoc_var_without_name', + 'remove_lines_between_uses', + 'return', + 'self_accessor', + 'short_array_syntax', + 'short_tag', + 'single_line_after_imports', + 'single_quote', + 'spaces_before_semicolon', + 'spaces_cast', + 'ternary_spaces', + 'trailing_spaces', + 'trim_array_spaces', + 'unused_use', + 'visibility', + 'whitespacy_lines' + ) + ) + ->finder($finder); + diff --git a/vendor/phar-io/manifest/.travis.yml b/vendor/phar-io/manifest/.travis.yml new file mode 100644 index 0000000..b4be10f --- /dev/null +++ b/vendor/phar-io/manifest/.travis.yml @@ -0,0 +1,33 @@ +os: +- linux + +language: php + +before_install: + - wget https://phar.io/releases/phive.phar + - wget https://phar.io/releases/phive.phar.asc + - gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0x9B2D5D79 + - gpg --verify phive.phar.asc phive.phar + - chmod +x phive.phar + - sudo mv phive.phar /usr/bin/phive + +install: + - ant setup + +script: ./tools/phpunit + +php: + - 5.6 + - 7.0 + - 7.1 + - 7.0snapshot + - 7.1snapshot + - master + +matrix: + allow_failures: + - php: master + fast_finish: true + +notifications: + email: false diff --git a/vendor/phar-io/manifest/LICENSE b/vendor/phar-io/manifest/LICENSE new file mode 100644 index 0000000..96051b1 --- /dev/null +++ b/vendor/phar-io/manifest/LICENSE @@ -0,0 +1,31 @@ +manifest + +Copyright (c) 2016 Arne Blankerts , Sebastian Heuer , Sebastian Bergmann , and contributors +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 Arne Blankerts nor the names of 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 HOLDER 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. + diff --git a/vendor/phar-io/manifest/README.md b/vendor/phar-io/manifest/README.md new file mode 100644 index 0000000..e6d0b05 --- /dev/null +++ b/vendor/phar-io/manifest/README.md @@ -0,0 +1,30 @@ +# Manifest + +Component for reading [phar.io](https://phar.io/) manifest information from a [PHP Archive (PHAR)](http://php.net/phar). + +[![Build Status](https://travis-ci.org/phar-io/manifest.svg?branch=master)](https://travis-ci.org/phar-io/manifest) +[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/phar-io/manifest/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/phar-io/manifest/?branch=master) +[![SensioLabsInsight](https://insight.sensiolabs.com/projects/d8cc6035-69ad-477d-bd1a-ccc605480fd7/mini.png)](https://insight.sensiolabs.com/projects/d8cc6035-69ad-477d-bd1a-ccc605480fd7) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phar-io/manifest + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phar-io/manifest + +## Usage + +```php +use PharIo\Manifest\ManifestLoader; +use PharIo\Manifest\ManifestSerializer; + +$manifest = ManifestLoader::fromFile('manifest.xml'); + +var_dump($manifest); + +echo (new ManifestSerializer)->serializeToString($manifest); +``` diff --git a/vendor/phar-io/manifest/build.xml b/vendor/phar-io/manifest/build.xml new file mode 100644 index 0000000..fc6eb1a --- /dev/null +++ b/vendor/phar-io/manifest/build.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/composer.json b/vendor/phar-io/manifest/composer.json new file mode 100644 index 0000000..cfaa7fa --- /dev/null +++ b/vendor/phar-io/manifest/composer.json @@ -0,0 +1,42 @@ +{ + "name": "phar-io/manifest", + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "support": { + "issues": "https://github.com/phar-io/manifest/issues" + }, + "require": { + "php": "^5.6 || ^7.0", + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^2.0" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } +} + diff --git a/vendor/phar-io/manifest/composer.lock b/vendor/phar-io/manifest/composer.lock new file mode 100644 index 0000000..d876819 --- /dev/null +++ b/vendor/phar-io/manifest/composer.lock @@ -0,0 +1,69 @@ +{ + "_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#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "f00846dde236d314a19d00d268d737dd", + "packages": [ + { + "name": "phar-io/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2018-07-08T19:19:57+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^5.6 || ^7.0", + "ext-dom": "*", + "ext-phar": "*" + }, + "platform-dev": [] +} diff --git a/vendor/phar-io/manifest/examples/example-01.php b/vendor/phar-io/manifest/examples/example-01.php new file mode 100644 index 0000000..345c407 --- /dev/null +++ b/vendor/phar-io/manifest/examples/example-01.php @@ -0,0 +1,23 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PharIo\Manifest\ManifestLoader; +use PharIo\Manifest\ManifestSerializer; + +require __DIR__ . '/../vendor/autoload.php'; + +$manifest = ManifestLoader::fromFile(__DIR__ . '/../tests/_fixture/phpunit-5.6.5.xml'); + +echo sprintf( + "Manifest for %s (%s):\n\n", + $manifest->getName(), + $manifest->getVersion()->getVersionString() +); +echo (new ManifestSerializer)->serializeToString($manifest); diff --git a/vendor/phar-io/manifest/phive.xml b/vendor/phar-io/manifest/phive.xml new file mode 100644 index 0000000..69f2f91 --- /dev/null +++ b/vendor/phar-io/manifest/phive.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vendor/phar-io/manifest/phpunit.xml b/vendor/phar-io/manifest/phpunit.xml new file mode 100644 index 0000000..2d7708e --- /dev/null +++ b/vendor/phar-io/manifest/phpunit.xml @@ -0,0 +1,20 @@ + + + + tests + + + + + src + + + diff --git a/vendor/phar-io/manifest/src/ManifestDocumentMapper.php b/vendor/phar-io/manifest/src/ManifestDocumentMapper.php new file mode 100644 index 0000000..d41e4f9 --- /dev/null +++ b/vendor/phar-io/manifest/src/ManifestDocumentMapper.php @@ -0,0 +1,193 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; +use PharIo\Version\Exception as VersionException; +use PharIo\Version\VersionConstraintParser; + +class ManifestDocumentMapper { + /** + * @param ManifestDocument $document + * + * @returns Manifest + * + * @throws ManifestDocumentMapperException + */ + public function map(ManifestDocument $document) { + try { + $contains = $document->getContainsElement(); + $type = $this->mapType($contains); + $copyright = $this->mapCopyright($document->getCopyrightElement()); + $requirements = $this->mapRequirements($document->getRequiresElement()); + $bundledComponents = $this->mapBundledComponents($document); + + return new Manifest( + new ApplicationName($contains->getName()), + new Version($contains->getVersion()), + $type, + $copyright, + $requirements, + $bundledComponents + ); + } catch (VersionException $e) { + throw new ManifestDocumentMapperException($e->getMessage(), $e->getCode(), $e); + } catch (Exception $e) { + throw new ManifestDocumentMapperException($e->getMessage(), $e->getCode(), $e); + } + } + + /** + * @param ContainsElement $contains + * + * @return Type + * + * @throws ManifestDocumentMapperException + */ + private function mapType(ContainsElement $contains) { + switch ($contains->getType()) { + case 'application': + return Type::application(); + case 'library': + return Type::library(); + case 'extension': + return $this->mapExtension($contains->getExtensionElement()); + } + + throw new ManifestDocumentMapperException( + sprintf('Unsupported type %s', $contains->getType()) + ); + } + + /** + * @param CopyrightElement $copyright + * + * @return CopyrightInformation + * + * @throws InvalidUrlException + * @throws InvalidEmailException + */ + private function mapCopyright(CopyrightElement $copyright) { + $authors = new AuthorCollection(); + + foreach($copyright->getAuthorElements() as $authorElement) { + $authors->add( + new Author( + $authorElement->getName(), + new Email($authorElement->getEmail()) + ) + ); + } + + $licenseElement = $copyright->getLicenseElement(); + $license = new License( + $licenseElement->getType(), + new Url($licenseElement->getUrl()) + ); + + return new CopyrightInformation( + $authors, + $license + ); + } + + /** + * @param RequiresElement $requires + * + * @return RequirementCollection + * + * @throws ManifestDocumentMapperException + */ + private function mapRequirements(RequiresElement $requires) { + $collection = new RequirementCollection(); + $phpElement = $requires->getPHPElement(); + $parser = new VersionConstraintParser; + + try { + $versionConstraint = $parser->parse($phpElement->getVersion()); + } catch (VersionException $e) { + throw new ManifestDocumentMapperException( + sprintf('Unsupported version constraint - %s', $e->getMessage()), + $e->getCode(), + $e + ); + } + + $collection->add( + new PhpVersionRequirement( + $versionConstraint + ) + ); + + if (!$phpElement->hasExtElements()) { + return $collection; + } + + foreach($phpElement->getExtElements() as $extElement) { + $collection->add( + new PhpExtensionRequirement($extElement->getName()) + ); + } + + return $collection; + } + + /** + * @param ManifestDocument $document + * + * @return BundledComponentCollection + */ + private function mapBundledComponents(ManifestDocument $document) { + $collection = new BundledComponentCollection(); + + if (!$document->hasBundlesElement()) { + return $collection; + } + + foreach($document->getBundlesElement()->getComponentElements() as $componentElement) { + $collection->add( + new BundledComponent( + $componentElement->getName(), + new Version( + $componentElement->getVersion() + ) + ) + ); + } + + return $collection; + } + + /** + * @param ExtensionElement $extension + * + * @return Extension + * + * @throws ManifestDocumentMapperException + */ + private function mapExtension(ExtensionElement $extension) { + try { + $parser = new VersionConstraintParser; + $versionConstraint = $parser->parse($extension->getCompatible()); + + return Type::extension( + new ApplicationName($extension->getFor()), + $versionConstraint + ); + } catch (VersionException $e) { + throw new ManifestDocumentMapperException( + sprintf('Unsupported version constraint - %s', $e->getMessage()), + $e->getCode(), + $e + ); + } + } +} diff --git a/vendor/phar-io/manifest/src/ManifestLoader.php b/vendor/phar-io/manifest/src/ManifestLoader.php new file mode 100644 index 0000000..81c5c90 --- /dev/null +++ b/vendor/phar-io/manifest/src/ManifestLoader.php @@ -0,0 +1,66 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ManifestLoader { + /** + * @param string $filename + * + * @return Manifest + * + * @throws ManifestLoaderException + */ + public static function fromFile($filename) { + try { + return (new ManifestDocumentMapper())->map( + ManifestDocument::fromFile($filename) + ); + } catch (Exception $e) { + throw new ManifestLoaderException( + sprintf('Loading %s failed.', $filename), + $e->getCode(), + $e + ); + } + } + + /** + * @param string $filename + * + * @return Manifest + * + * @throws ManifestLoaderException + */ + public static function fromPhar($filename) { + return self::fromFile('phar://' . $filename . '/manifest.xml'); + } + + /** + * @param string $manifest + * + * @return Manifest + * + * @throws ManifestLoaderException + */ + public static function fromString($manifest) { + try { + return (new ManifestDocumentMapper())->map( + ManifestDocument::fromString($manifest) + ); + } catch (Exception $e) { + throw new ManifestLoaderException( + 'Processing string failed', + $e->getCode(), + $e + ); + } + } +} diff --git a/vendor/phar-io/manifest/src/ManifestSerializer.php b/vendor/phar-io/manifest/src/ManifestSerializer.php new file mode 100644 index 0000000..4c18ddd --- /dev/null +++ b/vendor/phar-io/manifest/src/ManifestSerializer.php @@ -0,0 +1,163 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\AnyVersionConstraint; +use PharIo\Version\Version; +use PharIo\Version\VersionConstraint; +use XMLWriter; + +class ManifestSerializer { + /** + * @var XMLWriter + */ + private $xmlWriter; + + public function serializeToFile(Manifest $manifest, $filename) { + file_put_contents( + $filename, + $this->serializeToString($manifest) + ); + } + + public function serializeToString(Manifest $manifest) { + $this->startDocument(); + + $this->addContains($manifest->getName(), $manifest->getVersion(), $manifest->getType()); + $this->addCopyright($manifest->getCopyrightInformation()); + $this->addRequirements($manifest->getRequirements()); + $this->addBundles($manifest->getBundledComponents()); + + return $this->finishDocument(); + } + + private function startDocument() { + $xmlWriter = new XMLWriter(); + $xmlWriter->openMemory(); + $xmlWriter->setIndent(true); + $xmlWriter->setIndentString(str_repeat(' ', 4)); + $xmlWriter->startDocument('1.0', 'UTF-8'); + $xmlWriter->startElement('phar'); + $xmlWriter->writeAttribute('xmlns', 'https://phar.io/xml/manifest/1.0'); + + $this->xmlWriter = $xmlWriter; + } + + private function finishDocument() { + $this->xmlWriter->endElement(); + $this->xmlWriter->endDocument(); + + return $this->xmlWriter->outputMemory(); + } + + private function addContains($name, Version $version, Type $type) { + $this->xmlWriter->startElement('contains'); + $this->xmlWriter->writeAttribute('name', $name); + $this->xmlWriter->writeAttribute('version', $version->getVersionString()); + + switch (true) { + case $type->isApplication(): { + $this->xmlWriter->writeAttribute('type', 'application'); + break; + } + + case $type->isLibrary(): { + $this->xmlWriter->writeAttribute('type', 'library'); + break; + } + + case $type->isExtension(): { + /* @var $type Extension */ + $this->xmlWriter->writeAttribute('type', 'extension'); + $this->addExtension($type->getApplicationName(), $type->getVersionConstraint()); + break; + } + + default: { + $this->xmlWriter->writeAttribute('type', 'custom'); + } + } + + $this->xmlWriter->endElement(); + } + + private function addCopyright(CopyrightInformation $copyrightInformation) { + $this->xmlWriter->startElement('copyright'); + + foreach($copyrightInformation->getAuthors() as $author) { + $this->xmlWriter->startElement('author'); + $this->xmlWriter->writeAttribute('name', $author->getName()); + $this->xmlWriter->writeAttribute('email', (string) $author->getEmail()); + $this->xmlWriter->endElement(); + } + + $license = $copyrightInformation->getLicense(); + + $this->xmlWriter->startElement('license'); + $this->xmlWriter->writeAttribute('type', $license->getName()); + $this->xmlWriter->writeAttribute('url', $license->getUrl()); + $this->xmlWriter->endElement(); + + $this->xmlWriter->endElement(); + } + + private function addRequirements(RequirementCollection $requirementCollection) { + $phpRequirement = new AnyVersionConstraint(); + $extensions = []; + + foreach($requirementCollection as $requirement) { + if ($requirement instanceof PhpVersionRequirement) { + $phpRequirement = $requirement->getVersionConstraint(); + continue; + } + + if ($requirement instanceof PhpExtensionRequirement) { + $extensions[] = (string) $requirement; + } + } + + $this->xmlWriter->startElement('requires'); + $this->xmlWriter->startElement('php'); + $this->xmlWriter->writeAttribute('version', $phpRequirement->asString()); + + foreach($extensions as $extension) { + $this->xmlWriter->startElement('ext'); + $this->xmlWriter->writeAttribute('name', $extension); + $this->xmlWriter->endElement(); + } + + $this->xmlWriter->endElement(); + $this->xmlWriter->endElement(); + } + + private function addBundles(BundledComponentCollection $bundledComponentCollection) { + if (count($bundledComponentCollection) === 0) { + return; + } + $this->xmlWriter->startElement('bundles'); + + foreach($bundledComponentCollection as $bundledComponent) { + $this->xmlWriter->startElement('component'); + $this->xmlWriter->writeAttribute('name', $bundledComponent->getName()); + $this->xmlWriter->writeAttribute('version', $bundledComponent->getVersion()->getVersionString()); + $this->xmlWriter->endElement(); + } + + $this->xmlWriter->endElement(); + } + + private function addExtension($application, VersionConstraint $versionConstraint) { + $this->xmlWriter->startElement('extension'); + $this->xmlWriter->writeAttribute('for', $application); + $this->xmlWriter->writeAttribute('compatible', $versionConstraint->asString()); + $this->xmlWriter->endElement(); + } +} diff --git a/vendor/phar-io/manifest/src/exceptions/Exception.php b/vendor/phar-io/manifest/src/exceptions/Exception.php new file mode 100644 index 0000000..3ce46f2 --- /dev/null +++ b/vendor/phar-io/manifest/src/exceptions/Exception.php @@ -0,0 +1,14 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +interface Exception { +} diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php b/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php new file mode 100644 index 0000000..a53735a --- /dev/null +++ b/vendor/phar-io/manifest/src/exceptions/InvalidApplicationNameException.php @@ -0,0 +1,16 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class InvalidApplicationNameException extends \InvalidArgumentException implements Exception { + const NotAString = 1; + const InvalidFormat = 2; +} diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php b/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php new file mode 100644 index 0000000..854399b --- /dev/null +++ b/vendor/phar-io/manifest/src/exceptions/InvalidEmailException.php @@ -0,0 +1,14 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class InvalidEmailException extends \InvalidArgumentException implements Exception { +} diff --git a/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php b/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php new file mode 100644 index 0000000..cdd8323 --- /dev/null +++ b/vendor/phar-io/manifest/src/exceptions/InvalidUrlException.php @@ -0,0 +1,14 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class InvalidUrlException extends \InvalidArgumentException implements Exception { +} diff --git a/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php b/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php new file mode 100644 index 0000000..8b40195 --- /dev/null +++ b/vendor/phar-io/manifest/src/exceptions/ManifestDocumentException.php @@ -0,0 +1,6 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class Application extends Type { + /** + * @return bool + */ + public function isApplication() { + return true; + } +} diff --git a/vendor/phar-io/manifest/src/values/ApplicationName.php b/vendor/phar-io/manifest/src/values/ApplicationName.php new file mode 100644 index 0000000..1e71af4 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/ApplicationName.php @@ -0,0 +1,65 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ApplicationName { + /** + * @var string + */ + private $name; + + /** + * ApplicationName constructor. + * + * @param string $name + * + * @throws InvalidApplicationNameException + */ + public function __construct($name) { + $this->ensureIsString($name); + $this->ensureValidFormat($name); + $this->name = $name; + } + + /** + * @return string + */ + public function __toString() { + return $this->name; + } + + public function isEqual(ApplicationName $name) { + return $this->name === $name->name; + } + + /** + * @param string $name + * + * @throws InvalidApplicationNameException + */ + private function ensureValidFormat($name) { + if (!preg_match('#\w/\w#', $name)) { + throw new InvalidApplicationNameException( + sprintf('Format of name "%s" is not valid - expected: vendor/packagename', $name), + InvalidApplicationNameException::InvalidFormat + ); + } + } + + private function ensureIsString($name) { + if (!is_string($name)) { + throw new InvalidApplicationNameException( + 'Name must be a string', + InvalidApplicationNameException::NotAString + ); + } + } +} diff --git a/vendor/phar-io/manifest/src/values/Author.php b/vendor/phar-io/manifest/src/values/Author.php new file mode 100644 index 0000000..8295f51 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Author.php @@ -0,0 +1,57 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class Author { + /** + * @var string + */ + private $name; + + /** + * @var Email + */ + private $email; + + /** + * @param string $name + * @param Email $email + */ + public function __construct($name, Email $email) { + $this->name = $name; + $this->email = $email; + } + + /** + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * @return Email + */ + public function getEmail() { + return $this->email; + } + + /** + * @return string + */ + public function __toString() { + return sprintf( + '%s <%s>', + $this->name, + $this->email + ); + } +} diff --git a/vendor/phar-io/manifest/src/values/AuthorCollection.php b/vendor/phar-io/manifest/src/values/AuthorCollection.php new file mode 100644 index 0000000..d915879 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/AuthorCollection.php @@ -0,0 +1,43 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class AuthorCollection implements \Countable, \IteratorAggregate { + /** + * @var Author[] + */ + private $authors = []; + + public function add(Author $author) { + $this->authors[] = $author; + } + + /** + * @return Author[] + */ + public function getAuthors() { + return $this->authors; + } + + /** + * @return int + */ + public function count() { + return count($this->authors); + } + + /** + * @return AuthorCollectionIterator + */ + public function getIterator() { + return new AuthorCollectionIterator($this); + } +} diff --git a/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php b/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php new file mode 100644 index 0000000..792a050 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/AuthorCollectionIterator.php @@ -0,0 +1,56 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class AuthorCollectionIterator implements \Iterator { + /** + * @var Author[] + */ + private $authors = []; + + /** + * @var int + */ + private $position; + + public function __construct(AuthorCollection $authors) { + $this->authors = $authors->getAuthors(); + } + + public function rewind() { + $this->position = 0; + } + + /** + * @return bool + */ + public function valid() { + return $this->position < count($this->authors); + } + + /** + * @return int + */ + public function key() { + return $this->position; + } + + /** + * @return Author + */ + public function current() { + return $this->authors[$this->position]; + } + + public function next() { + $this->position++; + } +} diff --git a/vendor/phar-io/manifest/src/values/BundledComponent.php b/vendor/phar-io/manifest/src/values/BundledComponent.php new file mode 100644 index 0000000..846d15a --- /dev/null +++ b/vendor/phar-io/manifest/src/values/BundledComponent.php @@ -0,0 +1,48 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; + +class BundledComponent { + /** + * @var string + */ + private $name; + + /** + * @var Version + */ + private $version; + + /** + * @param string $name + * @param Version $version + */ + public function __construct($name, Version $version) { + $this->name = $name; + $this->version = $version; + } + + /** + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * @return Version + */ + public function getVersion() { + return $this->version; + } +} diff --git a/vendor/phar-io/manifest/src/values/BundledComponentCollection.php b/vendor/phar-io/manifest/src/values/BundledComponentCollection.php new file mode 100644 index 0000000..2dbb918 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/BundledComponentCollection.php @@ -0,0 +1,43 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class BundledComponentCollection implements \Countable, \IteratorAggregate { + /** + * @var BundledComponent[] + */ + private $bundledComponents = []; + + public function add(BundledComponent $bundledComponent) { + $this->bundledComponents[] = $bundledComponent; + } + + /** + * @return BundledComponent[] + */ + public function getBundledComponents() { + return $this->bundledComponents; + } + + /** + * @return int + */ + public function count() { + return count($this->bundledComponents); + } + + /** + * @return BundledComponentCollectionIterator + */ + public function getIterator() { + return new BundledComponentCollectionIterator($this); + } +} diff --git a/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php b/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php new file mode 100644 index 0000000..13b8f05 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/BundledComponentCollectionIterator.php @@ -0,0 +1,56 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class BundledComponentCollectionIterator implements \Iterator { + /** + * @var BundledComponent[] + */ + private $bundledComponents = []; + + /** + * @var int + */ + private $position; + + public function __construct(BundledComponentCollection $bundledComponents) { + $this->bundledComponents = $bundledComponents->getBundledComponents(); + } + + public function rewind() { + $this->position = 0; + } + + /** + * @return bool + */ + public function valid() { + return $this->position < count($this->bundledComponents); + } + + /** + * @return int + */ + public function key() { + return $this->position; + } + + /** + * @return BundledComponent + */ + public function current() { + return $this->bundledComponents[$this->position]; + } + + public function next() { + $this->position++; + } +} diff --git a/vendor/phar-io/manifest/src/values/CopyrightInformation.php b/vendor/phar-io/manifest/src/values/CopyrightInformation.php new file mode 100644 index 0000000..ece60b1 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/CopyrightInformation.php @@ -0,0 +1,42 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class CopyrightInformation { + /** + * @var AuthorCollection + */ + private $authors; + + /** + * @var License + */ + private $license; + + public function __construct(AuthorCollection $authors, License $license) { + $this->authors = $authors; + $this->license = $license; + } + + /** + * @return AuthorCollection + */ + public function getAuthors() { + return $this->authors; + } + + /** + * @return License + */ + public function getLicense() { + return $this->license; + } +} diff --git a/vendor/phar-io/manifest/src/values/Email.php b/vendor/phar-io/manifest/src/values/Email.php new file mode 100644 index 0000000..57cce04 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Email.php @@ -0,0 +1,47 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class Email { + /** + * @var string + */ + private $email; + + /** + * @param string $email + * + * @throws InvalidEmailException + */ + public function __construct($email) { + $this->ensureEmailIsValid($email); + + $this->email = $email; + } + + /** + * @return string + */ + public function __toString() { + return $this->email; + } + + /** + * @param string $url + * + * @throws InvalidEmailException + */ + private function ensureEmailIsValid($url) { + if (filter_var($url, \FILTER_VALIDATE_EMAIL) === false) { + throw new InvalidEmailException; + } + } +} diff --git a/vendor/phar-io/manifest/src/values/Extension.php b/vendor/phar-io/manifest/src/values/Extension.php new file mode 100644 index 0000000..90d6a6f --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Extension.php @@ -0,0 +1,75 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; +use PharIo\Version\VersionConstraint; + +class Extension extends Type { + /** + * @var ApplicationName + */ + private $application; + + /** + * @var VersionConstraint + */ + private $versionConstraint; + + /** + * @param ApplicationName $application + * @param VersionConstraint $versionConstraint + */ + public function __construct(ApplicationName $application, VersionConstraint $versionConstraint) { + $this->application = $application; + $this->versionConstraint = $versionConstraint; + } + + /** + * @return ApplicationName + */ + public function getApplicationName() { + return $this->application; + } + + /** + * @return VersionConstraint + */ + public function getVersionConstraint() { + return $this->versionConstraint; + } + + /** + * @return bool + */ + public function isExtension() { + return true; + } + + /** + * @param ApplicationName $name + * + * @return bool + */ + public function isExtensionFor(ApplicationName $name) { + return $this->application->isEqual($name); + } + + /** + * @param ApplicationName $name + * @param Version $version + * + * @return bool + */ + public function isCompatibleWith(ApplicationName $name, Version $version) { + return $this->isExtensionFor($name) && $this->versionConstraint->complies($version); + } +} diff --git a/vendor/phar-io/manifest/src/values/Library.php b/vendor/phar-io/manifest/src/values/Library.php new file mode 100644 index 0000000..a6ff944 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Library.php @@ -0,0 +1,20 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class Library extends Type { + /** + * @return bool + */ + public function isLibrary() { + return true; + } +} diff --git a/vendor/phar-io/manifest/src/values/License.php b/vendor/phar-io/manifest/src/values/License.php new file mode 100644 index 0000000..e278670 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/License.php @@ -0,0 +1,42 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class License { + /** + * @var string + */ + private $name; + + /** + * @var Url + */ + private $url; + + public function __construct($name, Url $url) { + $this->name = $name; + $this->url = $url; + } + + /** + * @return string + */ + public function getName() { + return $this->name; + } + + /** + * @return Url + */ + public function getUrl() { + return $this->url; + } +} diff --git a/vendor/phar-io/manifest/src/values/Manifest.php b/vendor/phar-io/manifest/src/values/Manifest.php new file mode 100644 index 0000000..217acef --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Manifest.php @@ -0,0 +1,138 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; + +class Manifest { + /** + * @var ApplicationName + */ + private $name; + + /** + * @var Version + */ + private $version; + + /** + * @var Type + */ + private $type; + + /** + * @var CopyrightInformation + */ + private $copyrightInformation; + + /** + * @var RequirementCollection + */ + private $requirements; + + /** + * @var BundledComponentCollection + */ + private $bundledComponents; + + public function __construct(ApplicationName $name, Version $version, Type $type, CopyrightInformation $copyrightInformation, RequirementCollection $requirements, BundledComponentCollection $bundledComponents) { + $this->name = $name; + $this->version = $version; + $this->type = $type; + $this->copyrightInformation = $copyrightInformation; + $this->requirements = $requirements; + $this->bundledComponents = $bundledComponents; + } + + /** + * @return ApplicationName + */ + public function getName() { + return $this->name; + } + + /** + * @return Version + */ + public function getVersion() { + return $this->version; + } + + /** + * @return Type + */ + public function getType() { + return $this->type; + } + + /** + * @return CopyrightInformation + */ + public function getCopyrightInformation() { + return $this->copyrightInformation; + } + + /** + * @return RequirementCollection + */ + public function getRequirements() { + return $this->requirements; + } + + /** + * @return BundledComponentCollection + */ + public function getBundledComponents() { + return $this->bundledComponents; + } + + /** + * @return bool + */ + public function isApplication() { + return $this->type->isApplication(); + } + + /** + * @return bool + */ + public function isLibrary() { + return $this->type->isLibrary(); + } + + /** + * @return bool + */ + public function isExtension() { + return $this->type->isExtension(); + } + + /** + * @param ApplicationName $application + * @param Version|null $version + * + * @return bool + */ + public function isExtensionFor(ApplicationName $application, Version $version = null) { + if (!$this->isExtension()) { + return false; + } + + /** @var Extension $type */ + $type = $this->type; + + if ($version !== null) { + return $type->isCompatibleWith($application, $version); + } + + return $type->isExtensionFor($application); + } +} diff --git a/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php b/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php new file mode 100644 index 0000000..6dd9296 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/PhpExtensionRequirement.php @@ -0,0 +1,32 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class PhpExtensionRequirement implements Requirement { + /** + * @var string + */ + private $extension; + + /** + * @param string $extension + */ + public function __construct($extension) { + $this->extension = $extension; + } + + /** + * @return string + */ + public function __toString() { + return $this->extension; + } +} diff --git a/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php b/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php new file mode 100644 index 0000000..8ad3e76 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/PhpVersionRequirement.php @@ -0,0 +1,31 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\VersionConstraint; + +class PhpVersionRequirement implements Requirement { + /** + * @var VersionConstraint + */ + private $versionConstraint; + + public function __construct(VersionConstraint $versionConstraint) { + $this->versionConstraint = $versionConstraint; + } + + /** + * @return VersionConstraint + */ + public function getVersionConstraint() { + return $this->versionConstraint; + } +} diff --git a/vendor/phar-io/manifest/src/values/Requirement.php b/vendor/phar-io/manifest/src/values/Requirement.php new file mode 100644 index 0000000..03bb56d --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Requirement.php @@ -0,0 +1,14 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +interface Requirement { +} diff --git a/vendor/phar-io/manifest/src/values/RequirementCollection.php b/vendor/phar-io/manifest/src/values/RequirementCollection.php new file mode 100644 index 0000000..af0e09b --- /dev/null +++ b/vendor/phar-io/manifest/src/values/RequirementCollection.php @@ -0,0 +1,43 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class RequirementCollection implements \Countable, \IteratorAggregate { + /** + * @var Requirement[] + */ + private $requirements = []; + + public function add(Requirement $requirement) { + $this->requirements[] = $requirement; + } + + /** + * @return Requirement[] + */ + public function getRequirements() { + return $this->requirements; + } + + /** + * @return int + */ + public function count() { + return count($this->requirements); + } + + /** + * @return RequirementCollectionIterator + */ + public function getIterator() { + return new RequirementCollectionIterator($this); + } +} diff --git a/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php b/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php new file mode 100644 index 0000000..9bb7003 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/RequirementCollectionIterator.php @@ -0,0 +1,56 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class RequirementCollectionIterator implements \Iterator { + /** + * @var Requirement[] + */ + private $requirements = []; + + /** + * @var int + */ + private $position; + + public function __construct(RequirementCollection $requirements) { + $this->requirements = $requirements->getRequirements(); + } + + public function rewind() { + $this->position = 0; + } + + /** + * @return bool + */ + public function valid() { + return $this->position < count($this->requirements); + } + + /** + * @return int + */ + public function key() { + return $this->position; + } + + /** + * @return Requirement + */ + public function current() { + return $this->requirements[$this->position]; + } + + public function next() { + $this->position++; + } +} diff --git a/vendor/phar-io/manifest/src/values/Type.php b/vendor/phar-io/manifest/src/values/Type.php new file mode 100644 index 0000000..31fbd44 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Type.php @@ -0,0 +1,60 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\VersionConstraint; + +abstract class Type { + /** + * @return Application + */ + public static function application() { + return new Application; + } + + /** + * @return Library + */ + public static function library() { + return new Library; + } + + /** + * @param ApplicationName $application + * @param VersionConstraint $versionConstraint + * + * @return Extension + */ + public static function extension(ApplicationName $application, VersionConstraint $versionConstraint) { + return new Extension($application, $versionConstraint); + } + + /** + * @return bool + */ + public function isApplication() { + return false; + } + + /** + * @return bool + */ + public function isLibrary() { + return false; + } + + /** + * @return bool + */ + public function isExtension() { + return false; + } +} diff --git a/vendor/phar-io/manifest/src/values/Url.php b/vendor/phar-io/manifest/src/values/Url.php new file mode 100644 index 0000000..37917c8 --- /dev/null +++ b/vendor/phar-io/manifest/src/values/Url.php @@ -0,0 +1,47 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class Url { + /** + * @var string + */ + private $url; + + /** + * @param string $url + * + * @throws InvalidUrlException + */ + public function __construct($url) { + $this->ensureUrlIsValid($url); + + $this->url = $url; + } + + /** + * @return string + */ + public function __toString() { + return $this->url; + } + + /** + * @param string $url + * + * @throws InvalidUrlException + */ + private function ensureUrlIsValid($url) { + if (filter_var($url, \FILTER_VALIDATE_URL) === false) { + throw new InvalidUrlException; + } + } +} diff --git a/vendor/phar-io/manifest/src/xml/AuthorElement.php b/vendor/phar-io/manifest/src/xml/AuthorElement.php new file mode 100644 index 0000000..a32f397 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/AuthorElement.php @@ -0,0 +1,21 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class AuthorElement extends ManifestElement { + public function getName() { + return $this->getAttributeValue('name'); + } + + public function getEmail() { + return $this->getAttributeValue('email'); + } +} diff --git a/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php b/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php new file mode 100644 index 0000000..1240d8c --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/AuthorElementCollection.php @@ -0,0 +1,19 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class AuthorElementCollection extends ElementCollection { + public function current() { + return new AuthorElement( + $this->getCurrentElement() + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/BundlesElement.php b/vendor/phar-io/manifest/src/xml/BundlesElement.php new file mode 100644 index 0000000..b90023e --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/BundlesElement.php @@ -0,0 +1,19 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class BundlesElement extends ManifestElement { + public function getComponentElements() { + return new ComponentElementCollection( + $this->getChildrenByName('component') + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ComponentElement.php b/vendor/phar-io/manifest/src/xml/ComponentElement.php new file mode 100644 index 0000000..64ed6b0 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ComponentElement.php @@ -0,0 +1,21 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ComponentElement extends ManifestElement { + public function getName() { + return $this->getAttributeValue('name'); + } + + public function getVersion() { + return $this->getAttributeValue('version'); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php b/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php new file mode 100644 index 0000000..9d375f9 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ComponentElementCollection.php @@ -0,0 +1,19 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ComponentElementCollection extends ElementCollection { + public function current() { + return new ComponentElement( + $this->getCurrentElement() + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ContainsElement.php b/vendor/phar-io/manifest/src/xml/ContainsElement.php new file mode 100644 index 0000000..8172f33 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ContainsElement.php @@ -0,0 +1,31 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ContainsElement extends ManifestElement { + public function getName() { + return $this->getAttributeValue('name'); + } + + public function getVersion() { + return $this->getAttributeValue('version'); + } + + public function getType() { + return $this->getAttributeValue('type'); + } + + public function getExtensionElement() { + return new ExtensionElement( + $this->getChildByName('extension') + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/CopyrightElement.php b/vendor/phar-io/manifest/src/xml/CopyrightElement.php new file mode 100644 index 0000000..bf7848e --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/CopyrightElement.php @@ -0,0 +1,25 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class CopyrightElement extends ManifestElement { + public function getAuthorElements() { + return new AuthorElementCollection( + $this->getChildrenByName('author') + ); + } + + public function getLicenseElement() { + return new LicenseElement( + $this->getChildByName('license') + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ElementCollection.php b/vendor/phar-io/manifest/src/xml/ElementCollection.php new file mode 100644 index 0000000..284e77b --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ElementCollection.php @@ -0,0 +1,58 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use DOMElement; +use DOMNodeList; + +abstract class ElementCollection implements \Iterator { + /** + * @var DOMNodeList + */ + private $nodeList; + + private $position; + + /** + * ElementCollection constructor. + * + * @param DOMNodeList $nodeList + */ + public function __construct(DOMNodeList $nodeList) { + $this->nodeList = $nodeList; + $this->position = 0; + } + + abstract public function current(); + + /** + * @return DOMElement + */ + protected function getCurrentElement() { + return $this->nodeList->item($this->position); + } + + public function next() { + $this->position++; + } + + public function key() { + return $this->position; + } + + public function valid() { + return $this->position < $this->nodeList->length; + } + + public function rewind() { + $this->position = 0; + } +} diff --git a/vendor/phar-io/manifest/src/xml/ExtElement.php b/vendor/phar-io/manifest/src/xml/ExtElement.php new file mode 100644 index 0000000..7a824ab --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ExtElement.php @@ -0,0 +1,17 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ExtElement extends ManifestElement { + public function getName() { + return $this->getAttributeValue('name'); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ExtElementCollection.php b/vendor/phar-io/manifest/src/xml/ExtElementCollection.php new file mode 100644 index 0000000..17acc62 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ExtElementCollection.php @@ -0,0 +1,20 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ExtElementCollection extends ElementCollection { + public function current() { + return new ExtElement( + $this->getCurrentElement() + ); + } + +} diff --git a/vendor/phar-io/manifest/src/xml/ExtensionElement.php b/vendor/phar-io/manifest/src/xml/ExtensionElement.php new file mode 100644 index 0000000..536c085 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ExtensionElement.php @@ -0,0 +1,21 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class ExtensionElement extends ManifestElement { + public function getFor() { + return $this->getAttributeValue('for'); + } + + public function getCompatible() { + return $this->getAttributeValue('compatible'); + } +} diff --git a/vendor/phar-io/manifest/src/xml/LicenseElement.php b/vendor/phar-io/manifest/src/xml/LicenseElement.php new file mode 100644 index 0000000..ee001df --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/LicenseElement.php @@ -0,0 +1,21 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class LicenseElement extends ManifestElement { + public function getType() { + return $this->getAttributeValue('type'); + } + + public function getUrl() { + return $this->getAttributeValue('url'); + } +} diff --git a/vendor/phar-io/manifest/src/xml/ManifestDocument.php b/vendor/phar-io/manifest/src/xml/ManifestDocument.php new file mode 100644 index 0000000..9b0bd9d --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ManifestDocument.php @@ -0,0 +1,118 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use DOMDocument; +use DOMElement; + +class ManifestDocument { + const XMLNS = 'https://phar.io/xml/manifest/1.0'; + + /** + * @var DOMDocument + */ + private $dom; + + /** + * ManifestDocument constructor. + * + * @param DOMDocument $dom + */ + private function __construct(DOMDocument $dom) { + $this->ensureCorrectDocumentType($dom); + + $this->dom = $dom; + } + + public static function fromFile($filename) { + if (!file_exists($filename)) { + throw new ManifestDocumentException( + sprintf('File "%s" not found', $filename) + ); + } + + return self::fromString( + file_get_contents($filename) + ); + } + + public static function fromString($xmlString) { + $prev = libxml_use_internal_errors(true); + libxml_clear_errors(); + + $dom = new DOMDocument(); + $dom->loadXML($xmlString); + + $errors = libxml_get_errors(); + libxml_use_internal_errors($prev); + + if (count($errors) !== 0) { + throw new ManifestDocumentLoadingException($errors); + } + + return new self($dom); + } + + public function getContainsElement() { + return new ContainsElement( + $this->fetchElementByName('contains') + ); + } + + public function getCopyrightElement() { + return new CopyrightElement( + $this->fetchElementByName('copyright') + ); + } + + public function getRequiresElement() { + return new RequiresElement( + $this->fetchElementByName('requires') + ); + } + + public function hasBundlesElement() { + return $this->dom->getElementsByTagNameNS(self::XMLNS, 'bundles')->length === 1; + } + + public function getBundlesElement() { + return new BundlesElement( + $this->fetchElementByName('bundles') + ); + } + + private function ensureCorrectDocumentType(DOMDocument $dom) { + $root = $dom->documentElement; + + if ($root->localName !== 'phar' || $root->namespaceURI !== self::XMLNS) { + throw new ManifestDocumentException('Not a phar.io manifest document'); + } + } + + /** + * @param $elementName + * + * @return DOMElement + * + * @throws ManifestDocumentException + */ + private function fetchElementByName($elementName) { + $element = $this->dom->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0); + + if (!$element instanceof DOMElement) { + throw new ManifestDocumentException( + sprintf('Element %s missing', $elementName) + ); + } + + return $element; + } +} diff --git a/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php b/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php new file mode 100644 index 0000000..59ac5c6 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ManifestDocumentLoadingException.php @@ -0,0 +1,48 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use LibXMLError; + +class ManifestDocumentLoadingException extends \Exception implements Exception { + /** + * @var LibXMLError[] + */ + private $libxmlErrors; + + /** + * ManifestDocumentLoadingException constructor. + * + * @param LibXMLError[] $libxmlErrors + */ + public function __construct(array $libxmlErrors) { + $this->libxmlErrors = $libxmlErrors; + $first = $this->libxmlErrors[0]; + + parent::__construct( + sprintf( + '%s (Line: %d / Column: %d / File: %s)', + $first->message, + $first->line, + $first->column, + $first->file + ), + $first->code + ); + } + + /** + * @return LibXMLError[] + */ + public function getLibxmlErrors() { + return $this->libxmlErrors; + } +} diff --git a/vendor/phar-io/manifest/src/xml/ManifestElement.php b/vendor/phar-io/manifest/src/xml/ManifestElement.php new file mode 100644 index 0000000..09d07cc --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/ManifestElement.php @@ -0,0 +1,100 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use DOMElement; +use DOMNodeList; + +class ManifestElement { + const XMLNS = 'https://phar.io/xml/manifest/1.0'; + + /** + * @var DOMElement + */ + private $element; + + /** + * ContainsElement constructor. + * + * @param DOMElement $element + */ + public function __construct(DOMElement $element) { + $this->element = $element; + } + + /** + * @param string $name + * + * @return string + * + * @throws ManifestElementException + */ + protected function getAttributeValue($name) { + if (!$this->element->hasAttribute($name)) { + throw new ManifestElementException( + sprintf( + 'Attribute %s not set on element %s', + $name, + $this->element->localName + ) + ); + } + + return $this->element->getAttribute($name); + } + + /** + * @param $elementName + * + * @return DOMElement + * + * @throws ManifestElementException + */ + protected function getChildByName($elementName) { + $element = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->item(0); + + if (!$element instanceof DOMElement) { + throw new ManifestElementException( + sprintf('Element %s missing', $elementName) + ); + } + + return $element; + } + + /** + * @param $elementName + * + * @return DOMNodeList + * + * @throws ManifestElementException + */ + protected function getChildrenByName($elementName) { + $elementList = $this->element->getElementsByTagNameNS(self::XMLNS, $elementName); + + if ($elementList->length === 0) { + throw new ManifestElementException( + sprintf('Element(s) %s missing', $elementName) + ); + } + + return $elementList; + } + + /** + * @param string $elementName + * + * @return bool + */ + protected function hasChild($elementName) { + return $this->element->getElementsByTagNameNS(self::XMLNS, $elementName)->length !== 0; + } +} diff --git a/vendor/phar-io/manifest/src/xml/PhpElement.php b/vendor/phar-io/manifest/src/xml/PhpElement.php new file mode 100644 index 0000000..e7340c0 --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/PhpElement.php @@ -0,0 +1,27 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class PhpElement extends ManifestElement { + public function getVersion() { + return $this->getAttributeValue('version'); + } + + public function hasExtElements() { + return $this->hasChild('ext'); + } + + public function getExtElements() { + return new ExtElementCollection( + $this->getChildrenByName('ext') + ); + } +} diff --git a/vendor/phar-io/manifest/src/xml/RequiresElement.php b/vendor/phar-io/manifest/src/xml/RequiresElement.php new file mode 100644 index 0000000..5f41b2e --- /dev/null +++ b/vendor/phar-io/manifest/src/xml/RequiresElement.php @@ -0,0 +1,19 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +class RequiresElement extends ManifestElement { + public function getPHPElement() { + return new PhpElement( + $this->getChildByName('php') + ); + } +} diff --git a/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php b/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php new file mode 100644 index 0000000..c69d761 --- /dev/null +++ b/vendor/phar-io/manifest/tests/ManifestDocumentMapperTest.php @@ -0,0 +1,110 @@ +assertInstanceOf( + Manifest::class, + $mapper->map($manifestDocument) + ); + } + + public function dataProvider() { + return [ + 'application' => [__DIR__ . '/_fixture/phpunit-5.6.5.xml'], + 'library' => [__DIR__ . '/_fixture/library.xml'], + 'extension' => [__DIR__ . '/_fixture/extension.xml'] + ]; + } + + public function testThrowsExceptionOnUnsupportedType() { + $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/custom.xml'); + $mapper = new ManifestDocumentMapper(); + + $this->expectException(ManifestDocumentMapperException::class); + $mapper->map($manifestDocument); + } + + public function testInvalidVersionInformationThrowsException() { + $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversion.xml'); + $mapper = new ManifestDocumentMapper(); + + $this->expectException(ManifestDocumentMapperException::class); + $mapper->map($manifestDocument); + } + + public function testInvalidVersionConstraintThrowsException() { + $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/invalidversionconstraint.xml'); + $mapper = new ManifestDocumentMapper(); + + $this->expectException(ManifestDocumentMapperException::class); + $mapper->map($manifestDocument); + } + + /** + * @uses \PharIo\Manifest\ExtensionElement + */ + public function testInvalidCompatibleConstraintThrowsException() { + $manifestDocument = ManifestDocument::fromFile(__DIR__ . '/_fixture/extension-invalidcompatible.xml'); + $mapper = new ManifestDocumentMapper(); + + $this->expectException(ManifestDocumentMapperException::class); + $mapper->map($manifestDocument); + } + +} diff --git a/vendor/phar-io/manifest/tests/ManifestLoaderTest.php b/vendor/phar-io/manifest/tests/ManifestLoaderTest.php new file mode 100644 index 0000000..919143a --- /dev/null +++ b/vendor/phar-io/manifest/tests/ManifestLoaderTest.php @@ -0,0 +1,83 @@ +assertInstanceOf( + Manifest::class, + ManifestLoader::fromFile(__DIR__ . '/_fixture/library.xml') + ); + } + + public function testCanBeLoadedFromString() { + $this->assertInstanceOf( + Manifest::class, + ManifestLoader::fromString( + file_get_contents(__DIR__ . '/_fixture/library.xml') + ) + ); + } + + public function testCanBeLoadedFromPhar() { + $this->assertInstanceOf( + Manifest::class, + ManifestLoader::fromPhar(__DIR__ . '/_fixture/test.phar') + ); + + } + + public function testLoadingNonExistingFileThrowsException() { + $this->expectException(ManifestLoaderException::class); + ManifestLoader::fromFile('/not/existing'); + } + + /** + * @uses \PharIo\Manifest\ManifestDocumentLoadingException + */ + public function testLoadingInvalidXmlThrowsException() { + $this->expectException(ManifestLoaderException::class); + ManifestLoader::fromString(''); + } + +} diff --git a/vendor/phar-io/manifest/tests/ManifestSerializerTest.php b/vendor/phar-io/manifest/tests/ManifestSerializerTest.php new file mode 100644 index 0000000..5fdf799 --- /dev/null +++ b/vendor/phar-io/manifest/tests/ManifestSerializerTest.php @@ -0,0 +1,114 @@ +assertXmlStringEqualsXmlString( + $expected, + $serializer->serializeToString($manifest) + ); + } + + public function dataProvider() { + return [ + 'application' => [file_get_contents(__DIR__ . '/_fixture/phpunit-5.6.5.xml')], + 'library' => [file_get_contents(__DIR__ . '/_fixture/library.xml')], + 'extension' => [file_get_contents(__DIR__ . '/_fixture/extension.xml')] + ]; + } + + /** + * @uses \PharIo\Manifest\Library + * @uses \PharIo\Manifest\ApplicationName + */ + public function testCanSerializeToFile() { + $src = __DIR__ . '/_fixture/library.xml'; + $dest = '/tmp/' . uniqid('serializer', true); + $manifest = ManifestLoader::fromFile($src); + $serializer = new ManifestSerializer(); + $serializer->serializeToFile($manifest, $dest); + $this->assertXmlFileEqualsXmlFile($src, $dest); + unlink($dest); + } + + /** + * @uses \PharIo\Manifest\ApplicationName + */ + public function testCanHandleUnknownType() { + $type = $this->getMockForAbstractClass(Type::class); + $manifest = new Manifest( + new ApplicationName('testvendor/testname'), + new Version('1.0.0'), + $type, + new CopyrightInformation( + new AuthorCollection(), + new License('bsd-3', new Url('https://some/uri')) + ), + new RequirementCollection(), + new BundledComponentCollection() + ); + + $serializer = new ManifestSerializer(); + $this->assertXmlStringEqualsXmlFile( + __DIR__ . '/_fixture/custom.xml', + $serializer->serializeToString($manifest) + ); + } +} diff --git a/vendor/phar-io/manifest/tests/_fixture/custom.xml b/vendor/phar-io/manifest/tests/_fixture/custom.xml new file mode 100644 index 0000000..4f43828 --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/custom.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml b/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml new file mode 100644 index 0000000..a78111c --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/extension-invalidcompatible.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/extension.xml b/vendor/phar-io/manifest/tests/_fixture/extension.xml new file mode 100644 index 0000000..a870aee --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/extension.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml b/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml new file mode 100644 index 0000000..788dd4c --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/invalidversion.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml b/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml new file mode 100644 index 0000000..f881f8b --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/invalidversionconstraint.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/library.xml b/vendor/phar-io/manifest/tests/_fixture/library.xml new file mode 100644 index 0000000..a5e2523 --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/library.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/manifest.xml b/vendor/phar-io/manifest/tests/_fixture/manifest.xml new file mode 100644 index 0000000..a5e2523 --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/manifest.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml b/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml new file mode 100644 index 0000000..aadbea2 --- /dev/null +++ b/vendor/phar-io/manifest/tests/_fixture/phpunit-5.6.5.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phar-io/manifest/tests/_fixture/test.phar b/vendor/phar-io/manifest/tests/_fixture/test.phar new file mode 100644 index 0000000000000000000000000000000000000000..d2a3e393ea403e5989aafa4b77d6ae6f07aafe75 GIT binary patch literal 7165 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 literal 0 HcmV?d00001 diff --git a/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php b/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php new file mode 100644 index 0000000..70f7553 --- /dev/null +++ b/vendor/phar-io/manifest/tests/exceptions/ManifestDocumentLoadingExceptionTest.php @@ -0,0 +1,19 @@ +loadXML(''); + $exception = new ManifestDocumentLoadingException(libxml_get_errors()); + libxml_use_internal_errors($prev); + + $this->assertContainsOnlyInstancesOf(LibXMLError::class, $exception->getLibxmlErrors()); + } + +} diff --git a/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php b/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php new file mode 100644 index 0000000..8ed3f3a --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/ApplicationNameTest.php @@ -0,0 +1,57 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +class ApplicationNameTest extends TestCase { + + public function testCanBeCreatedWithValidName() { + $this->assertInstanceOf( + ApplicationName::class, + new ApplicationName('foo/bar') + ); + } + + public function testUsingInvalidFormatForNameThrowsException() { + $this->expectException(InvalidApplicationNameException::class); + $this->expectExceptionCode(InvalidApplicationNameException::InvalidFormat); + new ApplicationName('foo'); + } + + public function testUsingWrongTypeForNameThrowsException() { + $this->expectException(InvalidApplicationNameException::class); + $this->expectExceptionCode(InvalidApplicationNameException::NotAString); + new ApplicationName(123); + } + + public function testReturnsTrueForEqualNamesWhenCompared() { + $app = new ApplicationName('foo/bar'); + $this->assertTrue( + $app->isEqual($app) + ); + } + + public function testReturnsFalseForNonEqualNamesWhenCompared() { + $app1 = new ApplicationName('foo/bar'); + $app2 = new ApplicationName('foo/foo'); + $this->assertFalse( + $app1->isEqual($app2) + ); + } + + public function testCanBeConvertedToString() { + $this->assertEquals( + 'foo/bar', + new ApplicationName('foo/bar') + ); + } +} diff --git a/vendor/phar-io/manifest/tests/values/ApplicationTest.php b/vendor/phar-io/manifest/tests/values/ApplicationTest.php new file mode 100644 index 0000000..86b5da6 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/ApplicationTest.php @@ -0,0 +1,44 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\Application + * @covers PharIo\Manifest\Type + */ +class ApplicationTest extends TestCase { + /** + * @var Application + */ + private $type; + + protected function setUp() { + $this->type = Type::application(); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(Application::class, $this->type); + } + + public function testIsApplication() { + $this->assertTrue($this->type->isApplication()); + } + + public function testIsNotLibrary() { + $this->assertFalse($this->type->isLibrary()); + } + + public function testIsNotExtension() { + $this->assertFalse($this->type->isExtension()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php b/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php new file mode 100644 index 0000000..0fa1b95 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/AuthorCollectionTest.php @@ -0,0 +1,62 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Manifest\AuthorCollection + * @covers \PharIo\Manifest\AuthorCollectionIterator + * + * @uses \PharIo\Manifest\Author + * @uses \PharIo\Manifest\Email + */ +class AuthorCollectionTest extends TestCase { + /** + * @var AuthorCollection + */ + private $collection; + + /** + * @var Author + */ + private $item; + + protected function setUp() { + $this->collection = new AuthorCollection; + $this->item = new Author('Joe Developer', new Email('user@example.com')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(AuthorCollection::class, $this->collection); + } + + public function testCanBeCounted() { + $this->collection->add($this->item); + + $this->assertCount(1, $this->collection); + } + + public function testCanBeIterated() { + $this->collection->add( + new Author('Dummy First', new Email('dummy@example.com')) + ); + $this->collection->add($this->item); + $this->assertContains($this->item, $this->collection); + } + + public function testKeyPositionCanBeRetreived() { + $this->collection->add($this->item); + foreach($this->collection as $key => $item) { + $this->assertEquals(0, $key); + } + } +} diff --git a/vendor/phar-io/manifest/tests/values/AuthorTest.php b/vendor/phar-io/manifest/tests/values/AuthorTest.php new file mode 100644 index 0000000..b7317fa --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/AuthorTest.php @@ -0,0 +1,45 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\Author + * + * @uses PharIo\Manifest\Email + */ +class AuthorTest extends TestCase { + /** + * @var Author + */ + private $author; + + protected function setUp() { + $this->author = new Author('Joe Developer', new Email('user@example.com')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(Author::class, $this->author); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('Joe Developer', $this->author->getName()); + } + + public function testEmailCanBeRetrieved() { + $this->assertEquals('user@example.com', $this->author->getEmail()); + } + + public function testCanBeUsedAsString() { + $this->assertEquals('Joe Developer ', $this->author); + } +} diff --git a/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php b/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php new file mode 100644 index 0000000..66cd0c4 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/BundledComponentCollectionTest.php @@ -0,0 +1,63 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Manifest\BundledComponentCollection + * @covers \PharIo\Manifest\BundledComponentCollectionIterator + * + * @uses \PharIo\Manifest\BundledComponent + * @uses \PharIo\Version\Version + */ +class BundledComponentCollectionTest extends TestCase { + /** + * @var BundledComponentCollection + */ + private $collection; + + /** + * @var BundledComponent + */ + private $item; + + protected function setUp() { + $this->collection = new BundledComponentCollection; + $this->item = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(BundledComponentCollection::class, $this->collection); + } + + public function testCanBeCounted() { + $this->collection->add($this->item); + + $this->assertCount(1, $this->collection); + } + + public function testCanBeIterated() { + $this->collection->add($this->createMock(BundledComponent::class)); + $this->collection->add($this->item); + + $this->assertContains($this->item, $this->collection); + } + + public function testKeyPositionCanBeRetreived() { + $this->collection->add($this->item); + foreach($this->collection as $key => $item) { + $this->assertEquals(0, $key); + } + } + +} diff --git a/vendor/phar-io/manifest/tests/values/BundledComponentTest.php b/vendor/phar-io/manifest/tests/values/BundledComponentTest.php new file mode 100644 index 0000000..01b8e13 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/BundledComponentTest.php @@ -0,0 +1,42 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\BundledComponent + * + * @uses \PharIo\Version\Version + */ +class BundledComponentTest extends TestCase { + /** + * @var BundledComponent + */ + private $bundledComponent; + + protected function setUp() { + $this->bundledComponent = new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(BundledComponent::class, $this->bundledComponent); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('phpunit/php-code-coverage', $this->bundledComponent->getName()); + } + + public function testVersionCanBeRetrieved() { + $this->assertEquals('4.0.2', $this->bundledComponent->getVersion()->getVersionString()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php b/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php new file mode 100644 index 0000000..de738f4 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/CopyrightInformationTest.php @@ -0,0 +1,62 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\CopyrightInformation + * + * @uses PharIo\Manifest\AuthorCollection + * @uses PharIo\Manifest\AuthorCollectionIterator + * @uses PharIo\Manifest\Author + * @uses PharIo\Manifest\Email + * @uses PharIo\Manifest\License + * @uses PharIo\Manifest\Url + */ +class CopyrightInformationTest extends TestCase { + /** + * @var CopyrightInformation + */ + private $copyrightInformation; + + /** + * @var Author + */ + private $author; + + /** + * @var License + */ + private $license; + + protected function setUp() { + $this->author = new Author('Joe Developer', new Email('user@example.com')); + $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); + + $authors = new AuthorCollection; + $authors->add($this->author); + + $this->copyrightInformation = new CopyrightInformation($authors, $this->license); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(CopyrightInformation::class, $this->copyrightInformation); + } + + public function testAuthorsCanBeRetrieved() { + $this->assertContains($this->author, $this->copyrightInformation->getAuthors()); + } + + public function testLicenseCanBeRetrieved() { + $this->assertEquals($this->license, $this->copyrightInformation->getLicense()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/EmailTest.php b/vendor/phar-io/manifest/tests/values/EmailTest.php new file mode 100644 index 0000000..ee38531 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/EmailTest.php @@ -0,0 +1,35 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\Email + */ +class EmailTest extends TestCase { + public function testCanBeCreatedForValidEmail() { + $this->assertInstanceOf(Email::class, new Email('user@example.com')); + } + + public function testCanBeUsedAsString() { + $this->assertEquals('user@example.com', new Email('user@example.com')); + } + + /** + * @covers PharIo\Manifest\InvalidEmailException + */ + public function testCannotBeCreatedForInvalidEmail() { + $this->expectException(InvalidEmailException::class); + + new Email('invalid'); + } +} diff --git a/vendor/phar-io/manifest/tests/values/ExtensionTest.php b/vendor/phar-io/manifest/tests/values/ExtensionTest.php new file mode 100644 index 0000000..1c9d676 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/ExtensionTest.php @@ -0,0 +1,109 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\AnyVersionConstraint; +use PharIo\Version\Version; +use PharIo\Version\VersionConstraint; +use PharIo\Version\VersionConstraintParser; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Manifest\Extension + * @covers \PharIo\Manifest\Type + * + * @uses \PharIo\Version\VersionConstraint + * @uses \PharIo\Manifest\ApplicationName + */ +class ExtensionTest extends TestCase { + /** + * @var Extension + */ + private $type; + + /** + * @var ApplicationName|\PHPUnit_Framework_MockObject_MockObject + */ + private $name; + + protected function setUp() { + $this->name = $this->createMock(ApplicationName::class); + $this->type = Type::extension($this->name, new AnyVersionConstraint); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(Extension::class, $this->type); + } + + public function testIsNotApplication() { + $this->assertFalse($this->type->isApplication()); + } + + public function testIsNotLibrary() { + $this->assertFalse($this->type->isLibrary()); + } + + public function testIsExtension() { + $this->assertTrue($this->type->isExtension()); + } + + public function testApplicationCanBeRetrieved() + { + $this->assertInstanceOf(ApplicationName::class, $this->type->getApplicationName()); + } + + public function testVersionConstraintCanBeRetrieved() { + $this->assertInstanceOf( + VersionConstraint::class, + $this->type->getVersionConstraint() + ); + } + + public function testApplicationCanBeQueried() + { + $this->name->method('isEqual')->willReturn(true); + $this->assertTrue( + $this->type->isExtensionFor($this->createMock(ApplicationName::class)) + ); + } + + public function testCompatibleWithReturnsTrueForMatchingVersionConstraintAndApplicaiton() { + $app = new ApplicationName('foo/bar'); + $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0')); + $version = new Version('1.0.0'); + + $this->assertTrue( + $extension->isCompatibleWith($app, $version) + ); + } + + public function testCompatibleWithReturnsFalseForNotMatchingVersionConstraint() { + $app = new ApplicationName('foo/bar'); + $extension = Type::extension($app, (new VersionConstraintParser)->parse('^1.0')); + $version = new Version('2.0.0'); + + $this->assertFalse( + $extension->isCompatibleWith($app, $version) + ); + } + + public function testCompatibleWithReturnsFalseForNotMatchingApplication() { + $app1 = new ApplicationName('foo/bar'); + $app2 = new ApplicationName('foo/foo'); + $extension = Type::extension($app1, (new VersionConstraintParser)->parse('^1.0')); + $version = new Version('1.0.0'); + + $this->assertFalse( + $extension->isCompatibleWith($app2, $version) + ); + } + +} diff --git a/vendor/phar-io/manifest/tests/values/LibraryTest.php b/vendor/phar-io/manifest/tests/values/LibraryTest.php new file mode 100644 index 0000000..f8d1c64 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/LibraryTest.php @@ -0,0 +1,44 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\Library + * @covers PharIo\Manifest\Type + */ +class LibraryTest extends TestCase { + /** + * @var Library + */ + private $type; + + protected function setUp() { + $this->type = Type::library(); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(Library::class, $this->type); + } + + public function testIsNotApplication() { + $this->assertFalse($this->type->isApplication()); + } + + public function testIsLibrary() { + $this->assertTrue($this->type->isLibrary()); + } + + public function testIsNotExtension() { + $this->assertFalse($this->type->isExtension()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/LicenseTest.php b/vendor/phar-io/manifest/tests/values/LicenseTest.php new file mode 100644 index 0000000..c9c5c3c --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/LicenseTest.php @@ -0,0 +1,41 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\License + * + * @uses PharIo\Manifest\Url + */ +class LicenseTest extends TestCase { + /** + * @var License + */ + private $license; + + protected function setUp() { + $this->license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(License::class, $this->license); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('BSD-3-Clause', $this->license->getName()); + } + + public function testUrlCanBeRetrieved() { + $this->assertEquals('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE', $this->license->getUrl()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/ManifestTest.php b/vendor/phar-io/manifest/tests/values/ManifestTest.php new file mode 100644 index 0000000..cff0a68 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/ManifestTest.php @@ -0,0 +1,187 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\Version; +use PharIo\Version\AnyVersionConstraint; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Manifest\Manifest + * + * @uses \PharIo\Manifest\ApplicationName + * @uses \PharIo\Manifest\Author + * @uses \PharIo\Manifest\AuthorCollection + * @uses \PharIo\Manifest\BundledComponent + * @uses \PharIo\Manifest\BundledComponentCollection + * @uses \PharIo\Manifest\CopyrightInformation + * @uses \PharIo\Manifest\Email + * @uses \PharIo\Manifest\License + * @uses \PharIo\Manifest\RequirementCollection + * @uses \PharIo\Manifest\PhpVersionRequirement + * @uses \PharIo\Manifest\Type + * @uses \PharIo\Manifest\Application + * @uses \PharIo\Manifest\Url + * @uses \PharIo\Version\Version + * @uses \PharIo\Version\VersionConstraint + */ +class ManifestTest extends TestCase { + /** + * @var ApplicationName + */ + private $name; + + /** + * @var Version + */ + private $version; + + /** + * @var Type + */ + private $type; + + /** + * @var CopyrightInformation + */ + private $copyrightInformation; + + /** + * @var RequirementCollection + */ + private $requirements; + + /** + * @var BundledComponentCollection + */ + private $bundledComponents; + + /** + * @var Manifest + */ + private $manifest; + + protected function setUp() { + $this->version = new Version('5.6.5'); + + $this->type = Type::application(); + + $author = new Author('Joe Developer', new Email('user@example.com')); + $license = new License('BSD-3-Clause', new Url('https://github.com/sebastianbergmann/phpunit/blob/master/LICENSE')); + + $authors = new AuthorCollection; + $authors->add($author); + + $this->copyrightInformation = new CopyrightInformation($authors, $license); + + $this->requirements = new RequirementCollection; + $this->requirements->add(new PhpVersionRequirement(new AnyVersionConstraint)); + + $this->bundledComponents = new BundledComponentCollection; + $this->bundledComponents->add(new BundledComponent('phpunit/php-code-coverage', new Version('4.0.2'))); + + $this->name = new ApplicationName('phpunit/phpunit'); + + $this->manifest = new Manifest( + $this->name, + $this->version, + $this->type, + $this->copyrightInformation, + $this->requirements, + $this->bundledComponents + ); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(Manifest::class, $this->manifest); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals($this->name, $this->manifest->getName()); + } + + public function testVersionCanBeRetrieved() { + $this->assertEquals($this->version, $this->manifest->getVersion()); + } + + public function testTypeCanBeRetrieved() { + $this->assertEquals($this->type, $this->manifest->getType()); + } + + public function testTypeCanBeQueried() { + $this->assertTrue($this->manifest->isApplication()); + $this->assertFalse($this->manifest->isLibrary()); + $this->assertFalse($this->manifest->isExtension()); + } + + public function testCopyrightInformationCanBeRetrieved() { + $this->assertEquals($this->copyrightInformation, $this->manifest->getCopyrightInformation()); + } + + public function testRequirementsCanBeRetrieved() { + $this->assertEquals($this->requirements, $this->manifest->getRequirements()); + } + + public function testBundledComponentsCanBeRetrieved() { + $this->assertEquals($this->bundledComponents, $this->manifest->getBundledComponents()); + } + + /** + * @uses \PharIo\Manifest\Extension + */ + public function testExtendedApplicationCanBeQueriedForExtension() + { + $appName = new ApplicationName('foo/bar'); + $manifest = new Manifest( + new ApplicationName('foo/foo'), + new Version('1.0.0'), + Type::extension($appName, new AnyVersionConstraint), + $this->copyrightInformation, + new RequirementCollection, + new BundledComponentCollection + ); + + $this->assertTrue($manifest->isExtensionFor($appName)); + } + + public function testNonExtensionReturnsFalseWhenQueriesForExtension() { + $appName = new ApplicationName('foo/bar'); + $manifest = new Manifest( + new ApplicationName('foo/foo'), + new Version('1.0.0'), + Type::library(), + $this->copyrightInformation, + new RequirementCollection, + new BundledComponentCollection + ); + + $this->assertFalse($manifest->isExtensionFor($appName)); + } + + /** + * @uses \PharIo\Manifest\Extension + */ + public function testExtendedApplicationCanBeQueriedForExtensionWithVersion() + { + $appName = new ApplicationName('foo/bar'); + $manifest = new Manifest( + new ApplicationName('foo/foo'), + new Version('1.0.0'), + Type::extension($appName, new AnyVersionConstraint), + $this->copyrightInformation, + new RequirementCollection, + new BundledComponentCollection + ); + + $this->assertTrue($manifest->isExtensionFor($appName, new Version('1.2.3'))); + } + +} diff --git a/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php b/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php new file mode 100644 index 0000000..ae1c058 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/PhpExtensionRequirementTest.php @@ -0,0 +1,26 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\PhpExtensionRequirement + */ +class PhpExtensionRequirementTest extends TestCase { + public function testCanBeCreated() { + $this->assertInstanceOf(PhpExtensionRequirement::class, new PhpExtensionRequirement('dom')); + } + + public function testCanBeUsedAsString() { + $this->assertEquals('dom', new PhpExtensionRequirement('dom')); + } +} diff --git a/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php b/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php new file mode 100644 index 0000000..67ac41a --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/PhpVersionRequirementTest.php @@ -0,0 +1,38 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\ExactVersionConstraint; +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\PhpVersionRequirement + * + * @uses \PharIo\Version\VersionConstraint + */ +class PhpVersionRequirementTest extends TestCase { + /** + * @var PhpVersionRequirement + */ + private $requirement; + + protected function setUp() { + $this->requirement = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(PhpVersionRequirement::class, $this->requirement); + } + + public function testVersionConstraintCanBeRetrieved() { + $this->assertEquals('7.1.0', $this->requirement->getVersionConstraint()->asString()); + } +} diff --git a/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php b/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php new file mode 100644 index 0000000..2afeb1a --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/RequirementCollectionTest.php @@ -0,0 +1,63 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PharIo\Version\ExactVersionConstraint; +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Manifest\RequirementCollection + * @covers \PharIo\Manifest\RequirementCollectionIterator + * + * @uses \PharIo\Manifest\PhpVersionRequirement + * @uses \PharIo\Version\VersionConstraint + */ +class RequirementCollectionTest extends TestCase { + /** + * @var RequirementCollection + */ + private $collection; + + /** + * @var Requirement + */ + private $item; + + protected function setUp() { + $this->collection = new RequirementCollection; + $this->item = new PhpVersionRequirement(new ExactVersionConstraint('7.1.0')); + } + + public function testCanBeCreated() { + $this->assertInstanceOf(RequirementCollection::class, $this->collection); + } + + public function testCanBeCounted() { + $this->collection->add($this->item); + + $this->assertCount(1, $this->collection); + } + + public function testCanBeIterated() { + $this->collection->add(new PhpVersionRequirement(new ExactVersionConstraint('5.6.0'))); + $this->collection->add($this->item); + + $this->assertContains($this->item, $this->collection); + } + + public function testKeyPositionCanBeRetreived() { + $this->collection->add($this->item); + foreach($this->collection as $key => $item) { + $this->assertEquals(0, $key); + } + } + +} diff --git a/vendor/phar-io/manifest/tests/values/UrlTest.php b/vendor/phar-io/manifest/tests/values/UrlTest.php new file mode 100644 index 0000000..20f09c1 --- /dev/null +++ b/vendor/phar-io/manifest/tests/values/UrlTest.php @@ -0,0 +1,35 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Manifest; + +use PHPUnit\Framework\TestCase; + +/** + * @covers PharIo\Manifest\Url + */ +class UrlTest extends TestCase { + public function testCanBeCreatedForValidUrl() { + $this->assertInstanceOf(Url::class, new Url('https://phar.io/')); + } + + public function testCanBeUsedAsString() { + $this->assertEquals('https://phar.io/', new Url('https://phar.io/')); + } + + /** + * @covers PharIo\Manifest\InvalidUrlException + */ + public function testCannotBeCreatedForInvalidUrl() { + $this->expectException(InvalidUrlException::class); + + new Url('invalid'); + } +} diff --git a/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php new file mode 100644 index 0000000..588558e --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/AuthorElementCollectionTest.php @@ -0,0 +1,18 @@ +loadXML(''); + $collection = new AuthorElementCollection($dom->childNodes); + + foreach($collection as $authorElement) { + $this->assertInstanceOf(AuthorElement::class, $authorElement); + } + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php b/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php new file mode 100644 index 0000000..6fce1d4 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/AuthorElementTest.php @@ -0,0 +1,25 @@ +loadXML(''); + $this->author = new AuthorElement($dom->documentElement); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('Reiner Zufall', $this->author->getName()); + } + + public function testEmailCanBeRetrieved() { + $this->assertEquals('reiner@zufall.de', $this->author->getEmail()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php b/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php new file mode 100644 index 0000000..7872795 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/BundlesElementTest.php @@ -0,0 +1,41 @@ +dom = new DOMDocument(); + $this->dom->loadXML(''); + $this->bundles = new BundlesElement($this->dom->documentElement); + } + + public function testThrowsExceptionWhenGetComponentElementsIsCalledButNodesAreMissing() { + $this->expectException(ManifestElementException::class); + $this->bundles->getComponentElements(); + } + + public function testGetComponentElementsReturnsComponentElementCollection() { + $this->addComponent(); + $this->assertInstanceOf( + ComponentElementCollection::class, $this->bundles->getComponentElements() + ); + } + + private function addComponent() { + $this->dom->documentElement->appendChild( + $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'component') + ); + } +} diff --git a/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php new file mode 100644 index 0000000..9fe2378 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ComponentElementCollectionTest.php @@ -0,0 +1,18 @@ +loadXML(''); + $collection = new ComponentElementCollection($dom->childNodes); + + foreach($collection as $componentElement) { + $this->assertInstanceOf(ComponentElement::class, $componentElement); + } + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php b/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php new file mode 100644 index 0000000..1996585 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ComponentElementTest.php @@ -0,0 +1,25 @@ +loadXML(''); + $this->component = new ComponentElement($dom->documentElement); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('phar-io/phive', $this->component->getName()); + } + + public function testEmailCanBeRetrieved() { + $this->assertEquals('0.6.0', $this->component->getVersion()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php b/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php new file mode 100644 index 0000000..ed08600 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ContainsElementTest.php @@ -0,0 +1,63 @@ +loadXML(''); + $this->domElement = $dom->documentElement; + $this->contains = new ContainsElement($this->domElement); + } + + public function testVersionCanBeRetrieved() { + $this->assertEquals('5.6.5', $this->contains->getVersion()); + } + + public function testThrowsExceptionWhenVersionAttributeIsMissing() { + $this->domElement->removeAttribute('version'); + $this->expectException(ManifestElementException::class); + $this->contains->getVersion(); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('phpunit/phpunit', $this->contains->getName()); + } + + public function testThrowsExceptionWhenNameAttributeIsMissing() { + $this->domElement->removeAttribute('name'); + $this->expectException(ManifestElementException::class); + $this->contains->getName(); + } + + public function testTypeCanBeRetrieved() { + $this->assertEquals('application', $this->contains->getType()); + } + + public function testThrowsExceptionWhenTypeAttributeIsMissing() { + $this->domElement->removeAttribute('type'); + $this->expectException(ManifestElementException::class); + $this->contains->getType(); + } + + public function testGetExtensionElementReturnsExtensionElement() { + $this->domElement->appendChild( + $this->domElement->ownerDocument->createElementNS('https://phar.io/xml/manifest/1.0', 'extension') + ); + $this->assertInstanceOf(ExtensionElement::class, $this->contains->getExtensionElement()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php b/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php new file mode 100644 index 0000000..c74a2ce --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/CopyrightElementTest.php @@ -0,0 +1,52 @@ +dom = new DOMDocument(); + $this->dom->loadXML(''); + $this->copyright = new CopyrightElement($this->dom->documentElement); + } + + public function testThrowsExceptionWhenGetAuthroElementsIsCalledButNodesAreMissing() { + $this->expectException(ManifestElementException::class); + $this->copyright->getAuthorElements(); + } + + public function testThrowsExceptionWhenGetLicenseElementIsCalledButNodeIsMissing() { + $this->expectException(ManifestElementException::class); + $this->copyright->getLicenseElement(); + } + + public function testGetAuthorElementsReturnsAuthorElementCollection() { + $this->dom->documentElement->appendChild( + $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'author') + ); + $this->assertInstanceOf( + AuthorElementCollection::class, $this->copyright->getAuthorElements() + ); + } + + public function testGetLicenseElementReturnsLicenseElement() { + $this->dom->documentElement->appendChild( + $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'license') + ); + $this->assertInstanceOf( + LicenseElement::class, $this->copyright->getLicenseElement() + ); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php b/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php new file mode 100644 index 0000000..7a456d2 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ExtElementCollectionTest.php @@ -0,0 +1,19 @@ +loadXML(''); + $collection = new ExtElementCollection($dom->childNodes); + + foreach($collection as $position => $extElement) { + $this->assertInstanceOf(ExtElement::class, $extElement); + $this->assertEquals(0, $position); + } + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ExtElementTest.php b/vendor/phar-io/manifest/tests/xml/ExtElementTest.php new file mode 100644 index 0000000..db6ecbc --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ExtElementTest.php @@ -0,0 +1,21 @@ +loadXML(''); + $this->ext = new ExtElement($dom->documentElement); + } + + public function testNameCanBeRetrieved() { + $this->assertEquals('dom', $this->ext->getName()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php b/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php new file mode 100644 index 0000000..58965d8 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ExtensionElementTest.php @@ -0,0 +1,25 @@ +loadXML(''); + $this->extension = new ExtensionElement($dom->documentElement); + } + + public function testNForCanBeRetrieved() { + $this->assertEquals('phar-io/phive', $this->extension->getFor()); + } + + public function testCompatibleVersionConstraintCanBeRetrieved() { + $this->assertEquals('~0.6', $this->extension->getCompatible()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php b/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php new file mode 100644 index 0000000..5b1ffcb --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/LicenseElementTest.php @@ -0,0 +1,25 @@ +loadXML(''); + $this->license = new LicenseElement($dom->documentElement); + } + + public function testTypeCanBeRetrieved() { + $this->assertEquals('BSD-3', $this->license->getType()); + } + + public function testUrlCanBeRetrieved() { + $this->assertEquals('https://some.tld/LICENSE', $this->license->getUrl()); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php b/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php new file mode 100644 index 0000000..3dd59bf --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/ManifestDocumentTest.php @@ -0,0 +1,110 @@ +expectException(ManifestDocumentException::class); + ManifestDocument::fromFile('/does/not/exist'); + } + + public function testCanBeCreatedFromFile() { + $this->assertInstanceOf( + ManifestDocument::class, + ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml') + ); + } + + public function testCaneBeConstructedFromString() { + $content = file_get_contents(__DIR__ . '/../_fixture/phpunit-5.6.5.xml'); + $this->assertInstanceOf( + ManifestDocument::class, + ManifestDocument::fromString($content) + ); + } + + public function testThrowsExceptionOnInvalidXML() { + $this->expectException(ManifestDocumentLoadingException::class); + ManifestDocument::fromString(''); + } + + public function testLoadingDocumentWithWrongRootNameThrowsException() { + $this->expectException(ManifestDocumentException::class); + ManifestDocument::fromString(''); + } + + public function testLoadingDocumentWithWrongNamespaceThrowsException() { + $this->expectException(ManifestDocumentException::class); + ManifestDocument::fromString(''); + } + + public function testContainsElementCanBeRetrieved() { + $this->assertInstanceOf( + ContainsElement::class, + $this->loadFixture()->getContainsElement() + ); + } + + public function testRequiresElementCanBeRetrieved() { + $this->assertInstanceOf( + RequiresElement::class, + $this->loadFixture()->getRequiresElement() + ); + } + + public function testCopyrightElementCanBeRetrieved() { + $this->assertInstanceOf( + CopyrightElement::class, + $this->loadFixture()->getCopyrightElement() + ); + } + + public function testBundlesElementCanBeRetrieved() { + $this->assertInstanceOf( + BundlesElement::class, + $this->loadFixture()->getBundlesElement() + ); + } + + public function testThrowsExceptionWhenContainsIsMissing() { + $this->expectException(ManifestDocumentException::class); + $this->loadEmptyFixture()->getContainsElement(); + } + + public function testThrowsExceptionWhenCopyirhgtIsMissing() { + $this->expectException(ManifestDocumentException::class); + $this->loadEmptyFixture()->getCopyrightElement(); + } + + public function testThrowsExceptionWhenRequiresIsMissing() { + $this->expectException(ManifestDocumentException::class); + $this->loadEmptyFixture()->getRequiresElement(); + } + + public function testThrowsExceptionWhenBundlesIsMissing() { + $this->expectException(ManifestDocumentException::class); + $this->loadEmptyFixture()->getBundlesElement(); + } + + public function testHasBundlesReturnsTrueWhenBundlesNodeIsPresent() { + $this->assertTrue( + $this->loadFixture()->hasBundlesElement() + ); + } + + public function testHasBundlesReturnsFalseWhenBundlesNoNodeIsPresent() { + $this->assertFalse( + $this->loadEmptyFixture()->hasBundlesElement() + ); + } + + private function loadFixture() { + return ManifestDocument::fromFile(__DIR__ . '/../_fixture/phpunit-5.6.5.xml'); + } + + private function loadEmptyFixture() { + return ManifestDocument::fromString( + '' + ); + } +} diff --git a/vendor/phar-io/manifest/tests/xml/PhpElementTest.php b/vendor/phar-io/manifest/tests/xml/PhpElementTest.php new file mode 100644 index 0000000..62dd359 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/PhpElementTest.php @@ -0,0 +1,48 @@ +dom = new DOMDocument(); + $this->dom->loadXML(''); + $this->php = new PhpElement($this->dom->documentElement); + } + + public function testVersionConstraintCanBeRetrieved() { + $this->assertEquals('^5.6 || ^7.0', $this->php->getVersion()); + } + + public function testHasExtElementsReturnsFalseWhenNoExtensionsAreRequired() { + $this->assertFalse($this->php->hasExtElements()); + } + + public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired() { + $this->addExtElement(); + $this->assertTrue($this->php->hasExtElements()); + } + + public function testGetExtElementsReturnsExtElementCollection() { + $this->addExtElement(); + $this->assertInstanceOf(ExtElementCollection::class, $this->php->getExtElements()); + } + + private function addExtElement() { + $this->dom->documentElement->appendChild( + $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'ext') + ); + } + +} diff --git a/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php b/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php new file mode 100644 index 0000000..35ddc82 --- /dev/null +++ b/vendor/phar-io/manifest/tests/xml/RequiresElementTest.php @@ -0,0 +1,37 @@ +dom = new DOMDocument(); + $this->dom->loadXML(''); + $this->requires = new RequiresElement($this->dom->documentElement); + } + + public function testThrowsExceptionWhenGetPhpElementIsCalledButElementIsMissing() { + $this->expectException(ManifestElementException::class); + $this->requires->getPHPElement(); + } + + public function testHasExtElementsReturnsTrueWhenExtensionsAreRequired() { + $this->dom->documentElement->appendChild( + $this->dom->createElementNS('https://phar.io/xml/manifest/1.0', 'php') + ); + + $this->assertInstanceOf(PhpElement::class, $this->requires->getPHPElement()); + } + +} diff --git a/vendor/phar-io/version/.gitignore b/vendor/phar-io/version/.gitignore new file mode 100644 index 0000000..1c8f2e6 --- /dev/null +++ b/vendor/phar-io/version/.gitignore @@ -0,0 +1,7 @@ +/.idea +/.php_cs.cache +/composer.lock +/src/autoload.php +/tools +/vendor + diff --git a/vendor/phar-io/version/.php_cs b/vendor/phar-io/version/.php_cs new file mode 100644 index 0000000..159d6a3 --- /dev/null +++ b/vendor/phar-io/version/.php_cs @@ -0,0 +1,67 @@ +files() + ->in('src') + ->in('tests') + ->name('*.php'); + +return Symfony\CS\Config\Config::create() + ->setUsingCache(true) + ->level(\Symfony\CS\FixerInterface::NONE_LEVEL) + ->fixers( + array( + 'align_double_arrow', + 'align_equals', + 'concat_with_spaces', + 'duplicate_semicolon', + 'elseif', + 'empty_return', + 'encoding', + 'eof_ending', + 'extra_empty_lines', + 'function_call_space', + 'function_declaration', + 'indentation', + 'join_function', + 'line_after_namespace', + 'linefeed', + 'list_commas', + 'lowercase_constants', + 'lowercase_keywords', + 'method_argument_space', + 'multiple_use', + 'namespace_no_leading_whitespace', + 'no_blank_lines_after_class_opening', + 'no_empty_lines_after_phpdocs', + 'parenthesis', + 'php_closing_tag', + 'phpdoc_indent', + 'phpdoc_no_access', + 'phpdoc_no_empty_return', + 'phpdoc_no_package', + 'phpdoc_params', + 'phpdoc_scalar', + 'phpdoc_separation', + 'phpdoc_to_comment', + 'phpdoc_trim', + 'phpdoc_types', + 'phpdoc_var_without_name', + 'remove_lines_between_uses', + 'return', + 'self_accessor', + 'short_array_syntax', + 'short_tag', + 'single_line_after_imports', + 'single_quote', + 'spaces_before_semicolon', + 'spaces_cast', + 'ternary_spaces', + 'trailing_spaces', + 'trim_array_spaces', + 'unused_use', + 'visibility', + 'whitespacy_lines' + ) + ) + ->finder($finder); + diff --git a/vendor/phar-io/version/.travis.yml b/vendor/phar-io/version/.travis.yml new file mode 100644 index 0000000..b4be10f --- /dev/null +++ b/vendor/phar-io/version/.travis.yml @@ -0,0 +1,33 @@ +os: +- linux + +language: php + +before_install: + - wget https://phar.io/releases/phive.phar + - wget https://phar.io/releases/phive.phar.asc + - gpg --keyserver hkps.pool.sks-keyservers.net --recv-keys 0x9B2D5D79 + - gpg --verify phive.phar.asc phive.phar + - chmod +x phive.phar + - sudo mv phive.phar /usr/bin/phive + +install: + - ant setup + +script: ./tools/phpunit + +php: + - 5.6 + - 7.0 + - 7.1 + - 7.0snapshot + - 7.1snapshot + - master + +matrix: + allow_failures: + - php: master + fast_finish: true + +notifications: + email: false diff --git a/vendor/phar-io/version/CHANGELOG.md b/vendor/phar-io/version/CHANGELOG.md new file mode 100644 index 0000000..ab9df36 --- /dev/null +++ b/vendor/phar-io/version/CHANGELOG.md @@ -0,0 +1,44 @@ +# Changelog + +All notable changes to phar-io/version are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.0.1] - 08.07.2018 + +### Fixed + +- Versions without a pre-release suffix are now always considered greater +than versions without a pre-release suffix. Example: `3.0.0 > 3.0.0-alpha.1` + +## [2.0.0] - 23.06.2018 + +Changes to public API: + +- `PreReleaseSuffix::construct()`: optional parameter `$number` removed +- `PreReleaseSuffix::isGreaterThan()`: introduced +- `Version::hasPreReleaseSuffix()`: introduced + +### Added + +- [#11](https://github.com/phar-io/version/issues/11): Added support for pre-release version suffixes. Supported values are: + - `dev` + - `beta` (also abbreviated form `b`) + - `rc` + - `alpha` (also abbreviated form `a`) + - `patch` (also abbreviated form `p`) + + All values can be followed by a number, e.g. `beta3`. + + When comparing versions, the pre-release suffix is taken into account. Example: +`1.5.0 > 1.5.0-beta1 > 1.5.0-alpha3 > 1.5.0-alpha2 > 1.5.0-dev11` + +### Changed + +- reorganized the source directories + +### Fixed + +- [#10](https://github.com/phar-io/version/issues/10): Version numbers containing +a numeric suffix as seen in Debian packages are now supported. + +[2.0.1]: https://github.com/phar-io/version/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/phar-io/version/compare/1.0.1...2.0.0 diff --git a/vendor/phar-io/version/LICENSE b/vendor/phar-io/version/LICENSE new file mode 100644 index 0000000..359dbc5 --- /dev/null +++ b/vendor/phar-io/version/LICENSE @@ -0,0 +1,31 @@ +phar-io/version + +Copyright (c) 2016-2017 Arne Blankerts , Sebastian Heuer and contributors +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 Arne Blankerts nor the names of 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 HOLDER 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. + diff --git a/vendor/phar-io/version/README.md b/vendor/phar-io/version/README.md new file mode 100644 index 0000000..76e6e98 --- /dev/null +++ b/vendor/phar-io/version/README.md @@ -0,0 +1,61 @@ +# Version + +Library for handling version information and constraints + +[![Build Status](https://travis-ci.org/phar-io/version.svg?branch=master)](https://travis-ci.org/phar-io/version) + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phar-io/version + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phar-io/version + +## Version constraints + +A Version constraint describes a range of versions or a discrete version number. The format of version numbers follows the schema of [semantic versioning](http://semver.org): `..`. A constraint might contain an operator that describes the range. + +Beside the typical mathematical operators like `<=`, `>=`, there are two special operators: + +*Caret operator*: `^1.0` +can be written as `>=1.0.0 <2.0.0` and read as »every Version within major version `1`«. + +*Tilde operator*: `~1.0.0` +can be written as `>=1.0.0 <1.1.0` and read as »every version within minor version `1.1`. The behavior of tilde operator depends on whether a patch level version is provided or not. If no patch level is provided, tilde operator behaves like the caret operator: `~1.0` is identical to `^1.0`. + +## Usage examples + +Parsing version constraints and check discrete versions for compliance: + +```php + +use PharIo\Version\Version; +use PharIo\Version\VersionConstraintParser; + +$parser = new VersionConstraintParser(); +$caret_constraint = $parser->parse( '^7.0' ); + +$caret_constraint->complies( new Version( '7.0.17' ) ); // true +$caret_constraint->complies( new Version( '7.1.0' ) ); // true +$caret_constraint->complies( new Version( '6.4.34' ) ); // false + +$tilde_constraint = $parser->parse( '~1.1.0' ); + +$tilde_constraint->complies( new Version( '1.1.4' ) ); // true +$tilde_constraint->complies( new Version( '1.2.0' ) ); // false +``` + +As of version 2.0.0, pre-release labels are supported and taken into account when comparing versions: + +```php + +$leftVersion = new PharIo\Version\Version('3.0.0-alpha.1'); +$rightVersion = new PharIo\Version\Version('3.0.0-alpha.2'); + +$leftVersion->isGreaterThan($rightVersion); // false +$rightVersion->isGreaterThan($leftVersion); // true + +``` diff --git a/vendor/phar-io/version/build.xml b/vendor/phar-io/version/build.xml new file mode 100644 index 0000000..943c957 --- /dev/null +++ b/vendor/phar-io/version/build.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phar-io/version/composer.json b/vendor/phar-io/version/composer.json new file mode 100644 index 0000000..891e8b1 --- /dev/null +++ b/vendor/phar-io/version/composer.json @@ -0,0 +1,34 @@ +{ + "name": "phar-io/version", + "description": "Library for handling version information and constraints", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "support": { + "issues": "https://github.com/phar-io/version/issues" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "autoload": { + "classmap": [ + "src/" + ] + } +} + diff --git a/vendor/phar-io/version/phive.xml b/vendor/phar-io/version/phive.xml new file mode 100644 index 0000000..0c3bc6f --- /dev/null +++ b/vendor/phar-io/version/phive.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/vendor/phar-io/version/phpunit.xml b/vendor/phar-io/version/phpunit.xml new file mode 100644 index 0000000..c21ffbc --- /dev/null +++ b/vendor/phar-io/version/phpunit.xml @@ -0,0 +1,19 @@ + + + + tests + + + + + src + + + diff --git a/vendor/phar-io/version/src/PreReleaseSuffix.php b/vendor/phar-io/version/src/PreReleaseSuffix.php new file mode 100644 index 0000000..e936c0e --- /dev/null +++ b/vendor/phar-io/version/src/PreReleaseSuffix.php @@ -0,0 +1,95 @@ + 0, + 'a' => 1, + 'alpha' => 1, + 'b' => 2, + 'beta' => 2, + 'rc' => 3, + 'p' => 4, + 'patch' => 4, + ]; + + /** + * @var string + */ + private $value; + + /** + * @var int + */ + private $valueScore; + + /** + * @var int + */ + private $number = 0; + + /** + * @param string $value + */ + public function __construct($value) { + $this->parseValue($value); + } + + /** + * @return string + */ + public function getValue() { + return $this->value; + } + + /** + * @return int|null + */ + public function getNumber() { + return $this->number; + } + + /** + * @param PreReleaseSuffix $suffix + * + * @return bool + */ + public function isGreaterThan(PreReleaseSuffix $suffix) { + if ($this->valueScore > $suffix->valueScore) { + return true; + } + + if ($this->valueScore < $suffix->valueScore) { + return false; + } + + return $this->getNumber() > $suffix->getNumber(); + } + + /** + * @param $value + * + * @return int + */ + private function mapValueToScore($value) { + if (array_key_exists($value, $this->valueScoreMap)) { + return $this->valueScoreMap[$value]; + } + + return 0; + } + + private function parseValue($value) { + $regex = '/-?(dev|beta|b|rc|alpha|a|patch|p)\.?(\d*).*$/i'; + if (preg_match($regex, $value, $matches) !== 1) { + throw new InvalidPreReleaseSuffixException(sprintf('Invalid label %s', $value)); + } + + $this->value = $matches[1]; + if (isset($matches[2])) { + $this->number = (int)$matches[2]; + } + $this->valueScore = $this->mapValueToScore($this->value); + } +} diff --git a/vendor/phar-io/version/src/Version.php b/vendor/phar-io/version/src/Version.php new file mode 100644 index 0000000..73e1b98 --- /dev/null +++ b/vendor/phar-io/version/src/Version.php @@ -0,0 +1,175 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class Version { + /** + * @var VersionNumber + */ + private $major; + + /** + * @var VersionNumber + */ + private $minor; + + /** + * @var VersionNumber + */ + private $patch; + + /** + * @var PreReleaseSuffix + */ + private $preReleaseSuffix; + + /** + * @var string + */ + private $versionString = ''; + + /** + * @param string $versionString + */ + public function __construct($versionString) { + $this->ensureVersionStringIsValid($versionString); + + $this->versionString = $versionString; + } + + /** + * @return PreReleaseSuffix + */ + public function getPreReleaseSuffix() { + return $this->preReleaseSuffix; + } + + /** + * @return string + */ + public function getVersionString() { + return $this->versionString; + } + + /** + * @return bool + */ + public function hasPreReleaseSuffix() { + return $this->preReleaseSuffix !== null; + } + + /** + * @param Version $version + * + * @return bool + */ + public function isGreaterThan(Version $version) { + if ($version->getMajor()->getValue() > $this->getMajor()->getValue()) { + return false; + } + + if ($version->getMajor()->getValue() < $this->getMajor()->getValue()) { + return true; + } + + if ($version->getMinor()->getValue() > $this->getMinor()->getValue()) { + return false; + } + + if ($version->getMinor()->getValue() < $this->getMinor()->getValue()) { + return true; + } + + if ($version->getPatch()->getValue() > $this->getPatch()->getValue()) { + return false; + } + + if ($version->getPatch()->getValue() < $this->getPatch()->getValue()) { + return true; + } + + if (!$version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) { + return false; + } + + if ($version->hasPreReleaseSuffix() && !$this->hasPreReleaseSuffix()) { + return true; + } + + if (!$version->hasPreReleaseSuffix() && $this->hasPreReleaseSuffix()) { + return false; + } + + return $this->getPreReleaseSuffix()->isGreaterThan($version->getPreReleaseSuffix()); + } + + /** + * @return VersionNumber + */ + public function getMajor() { + return $this->major; + } + + /** + * @return VersionNumber + */ + public function getMinor() { + return $this->minor; + } + + /** + * @return VersionNumber + */ + public function getPatch() { + return $this->patch; + } + + /** + * @param array $matches + */ + private function parseVersion(array $matches) { + $this->major = new VersionNumber($matches['Major']); + $this->minor = new VersionNumber($matches['Minor']); + $this->patch = isset($matches['Patch']) ? new VersionNumber($matches['Patch']) : new VersionNumber(null); + + if (isset($matches['PreReleaseSuffix'])) { + $this->preReleaseSuffix = new PreReleaseSuffix($matches['PreReleaseSuffix']); + } + } + + /** + * @param string $version + * + * @throws InvalidVersionException + */ + private function ensureVersionStringIsValid($version) { + $regex = '/^v? + (?(0|(?:[1-9][0-9]*))) + \\. + (?(0|(?:[1-9][0-9]*))) + (\\. + (?(0|(?:[1-9][0-9]*))) + )? + (?: + - + (?(?:(dev|beta|b|RC|alpha|a|patch|p)\.?\d*)) + )? + $/x'; + + if (preg_match($regex, $version, $matches) !== 1) { + throw new InvalidVersionException( + sprintf("Version string '%s' does not follow SemVer semantics", $version) + ); + } + + $this->parseVersion($matches); + } +} diff --git a/vendor/phar-io/version/src/VersionConstraintParser.php b/vendor/phar-io/version/src/VersionConstraintParser.php new file mode 100644 index 0000000..ed46843 --- /dev/null +++ b/vendor/phar-io/version/src/VersionConstraintParser.php @@ -0,0 +1,122 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class VersionConstraintParser { + /** + * @param string $value + * + * @return VersionConstraint + * + * @throws UnsupportedVersionConstraintException + */ + public function parse($value) { + + if (strpos($value, '||') !== false) { + return $this->handleOrGroup($value); + } + + if (!preg_match('/^[\^~\*]?[\d.\*]+(?:-.*)?$/', $value)) { + throw new UnsupportedVersionConstraintException( + sprintf('Version constraint %s is not supported.', $value) + ); + } + + switch ($value[0]) { + case '~': + return $this->handleTildeOperator($value); + case '^': + return $this->handleCaretOperator($value); + } + + $version = new VersionConstraintValue($value); + + if ($version->getMajor()->isAny()) { + return new AnyVersionConstraint(); + } + + if ($version->getMinor()->isAny()) { + return new SpecificMajorVersionConstraint( + $version->getVersionString(), + $version->getMajor()->getValue() + ); + } + + if ($version->getPatch()->isAny()) { + return new SpecificMajorAndMinorVersionConstraint( + $version->getVersionString(), + $version->getMajor()->getValue(), + $version->getMinor()->getValue() + ); + } + + return new ExactVersionConstraint($version->getVersionString()); + } + + /** + * @param $value + * + * @return OrVersionConstraintGroup + */ + private function handleOrGroup($value) { + $constraints = []; + + foreach (explode('||', $value) as $groupSegment) { + $constraints[] = $this->parse(trim($groupSegment)); + } + + return new OrVersionConstraintGroup($value, $constraints); + } + + /** + * @param string $value + * + * @return AndVersionConstraintGroup + */ + private function handleTildeOperator($value) { + $version = new Version(substr($value, 1)); + $constraints = [ + new GreaterThanOrEqualToVersionConstraint($value, $version) + ]; + + if ($version->getPatch()->isAny()) { + $constraints[] = new SpecificMajorVersionConstraint( + $value, + $version->getMajor()->getValue() + ); + } else { + $constraints[] = new SpecificMajorAndMinorVersionConstraint( + $value, + $version->getMajor()->getValue(), + $version->getMinor()->getValue() + ); + } + + return new AndVersionConstraintGroup($value, $constraints); + } + + /** + * @param string $value + * + * @return AndVersionConstraintGroup + */ + private function handleCaretOperator($value) { + $version = new Version(substr($value, 1)); + + return new AndVersionConstraintGroup( + $value, + [ + new GreaterThanOrEqualToVersionConstraint($value, $version), + new SpecificMajorVersionConstraint($value, $version->getMajor()->getValue()) + ] + ); + } +} diff --git a/vendor/phar-io/version/src/VersionConstraintValue.php b/vendor/phar-io/version/src/VersionConstraintValue.php new file mode 100644 index 0000000..8c975b8 --- /dev/null +++ b/vendor/phar-io/version/src/VersionConstraintValue.php @@ -0,0 +1,123 @@ +versionString = $versionString; + + $this->parseVersion($versionString); + } + + /** + * @return string + */ + public function getLabel() { + return $this->label; + } + + /** + * @return string + */ + public function getBuildMetaData() { + return $this->buildMetaData; + } + + /** + * @return string + */ + public function getVersionString() { + return $this->versionString; + } + + /** + * @return VersionNumber + */ + public function getMajor() { + return $this->major; + } + + /** + * @return VersionNumber + */ + public function getMinor() { + return $this->minor; + } + + /** + * @return VersionNumber + */ + public function getPatch() { + return $this->patch; + } + + /** + * @param $versionString + */ + private function parseVersion($versionString) { + $this->extractBuildMetaData($versionString); + $this->extractLabel($versionString); + + $versionSegments = explode('.', $versionString); + $this->major = new VersionNumber($versionSegments[0]); + + $minorValue = isset($versionSegments[1]) ? $versionSegments[1] : null; + $patchValue = isset($versionSegments[2]) ? $versionSegments[2] : null; + + $this->minor = new VersionNumber($minorValue); + $this->patch = new VersionNumber($patchValue); + } + + /** + * @param string $versionString + */ + private function extractBuildMetaData(&$versionString) { + if (preg_match('/\+(.*)/', $versionString, $matches) == 1) { + $this->buildMetaData = $matches[1]; + $versionString = str_replace($matches[0], '', $versionString); + } + } + + /** + * @param string $versionString + */ + private function extractLabel(&$versionString) { + if (preg_match('/\-(.*)/', $versionString, $matches) == 1) { + $this->label = $matches[1]; + $versionString = str_replace($matches[0], '', $versionString); + } + } +} diff --git a/vendor/phar-io/version/src/VersionNumber.php b/vendor/phar-io/version/src/VersionNumber.php new file mode 100644 index 0000000..ab512ed --- /dev/null +++ b/vendor/phar-io/version/src/VersionNumber.php @@ -0,0 +1,41 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class VersionNumber { + /** + * @var int + */ + private $value; + + /** + * @param mixed $value + */ + public function __construct($value) { + if (is_numeric($value)) { + $this->value = $value; + } + } + + /** + * @return bool + */ + public function isAny() { + return $this->value === null; + } + + /** + * @return int + */ + public function getValue() { + return $this->value; + } +} diff --git a/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php new file mode 100644 index 0000000..b732dbc --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AbstractVersionConstraint.php @@ -0,0 +1,32 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +abstract class AbstractVersionConstraint implements VersionConstraint { + /** + * @var string + */ + private $originalValue = ''; + + /** + * @param string $originalValue + */ + public function __construct($originalValue) { + $this->originalValue = $originalValue; + } + + /** + * @return string + */ + public function asString() { + return $this->originalValue; + } +} diff --git a/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php new file mode 100644 index 0000000..d9efeef --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AndVersionConstraintGroup.php @@ -0,0 +1,43 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class AndVersionConstraintGroup extends AbstractVersionConstraint { + /** + * @var VersionConstraint[] + */ + private $constraints = []; + + /** + * @param string $originalValue + * @param VersionConstraint[] $constraints + */ + public function __construct($originalValue, array $constraints) { + parent::__construct($originalValue); + + $this->constraints = $constraints; + } + + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + foreach ($this->constraints as $constraint) { + if (!$constraint->complies($version)) { + return false; + } + } + + return true; + } +} diff --git a/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php new file mode 100644 index 0000000..13ca2ef --- /dev/null +++ b/vendor/phar-io/version/src/constraints/AnyVersionConstraint.php @@ -0,0 +1,29 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class AnyVersionConstraint implements VersionConstraint { + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + return true; + } + + /** + * @return string + */ + public function asString() { + return '*'; + } +} diff --git a/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php new file mode 100644 index 0000000..b214117 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/ExactVersionConstraint.php @@ -0,0 +1,22 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class ExactVersionConstraint extends AbstractVersionConstraint { + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + return $this->asString() == $version->getVersionString(); + } +} diff --git a/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php new file mode 100644 index 0000000..47039a8 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/GreaterThanOrEqualToVersionConstraint.php @@ -0,0 +1,38 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class GreaterThanOrEqualToVersionConstraint extends AbstractVersionConstraint { + /** + * @var Version + */ + private $minimalVersion; + + /** + * @param string $originalValue + * @param Version $minimalVersion + */ + public function __construct($originalValue, Version $minimalVersion) { + parent::__construct($originalValue); + + $this->minimalVersion = $minimalVersion; + } + + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + return $version->getVersionString() == $this->minimalVersion->getVersionString() + || $version->isGreaterThan($this->minimalVersion); + } +} diff --git a/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php new file mode 100644 index 0000000..274407f --- /dev/null +++ b/vendor/phar-io/version/src/constraints/OrVersionConstraintGroup.php @@ -0,0 +1,43 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class OrVersionConstraintGroup extends AbstractVersionConstraint { + /** + * @var VersionConstraint[] + */ + private $constraints = []; + + /** + * @param string $originalValue + * @param VersionConstraint[] $constraints + */ + public function __construct($originalValue, array $constraints) { + parent::__construct($originalValue); + + $this->constraints = $constraints; + } + + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + foreach ($this->constraints as $constraint) { + if ($constraint->complies($version)) { + return true; + } + } + + return false; + } +} diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php new file mode 100644 index 0000000..3d58905 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/SpecificMajorAndMinorVersionConstraint.php @@ -0,0 +1,48 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class SpecificMajorAndMinorVersionConstraint extends AbstractVersionConstraint { + /** + * @var int + */ + private $major = 0; + + /** + * @var int + */ + private $minor = 0; + + /** + * @param string $originalValue + * @param int $major + * @param int $minor + */ + public function __construct($originalValue, $major, $minor) { + parent::__construct($originalValue); + + $this->major = $major; + $this->minor = $minor; + } + + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + if ($version->getMajor()->getValue() != $this->major) { + return false; + } + + return $version->getMinor()->getValue() == $this->minor; + } +} diff --git a/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php new file mode 100644 index 0000000..bbac47b --- /dev/null +++ b/vendor/phar-io/version/src/constraints/SpecificMajorVersionConstraint.php @@ -0,0 +1,37 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +class SpecificMajorVersionConstraint extends AbstractVersionConstraint { + /** + * @var int + */ + private $major = 0; + + /** + * @param string $originalValue + * @param int $major + */ + public function __construct($originalValue, $major) { + parent::__construct($originalValue); + + $this->major = $major; + } + + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version) { + return $version->getMajor()->getValue() == $this->major; + } +} diff --git a/vendor/phar-io/version/src/constraints/VersionConstraint.php b/vendor/phar-io/version/src/constraints/VersionConstraint.php new file mode 100644 index 0000000..9558163 --- /dev/null +++ b/vendor/phar-io/version/src/constraints/VersionConstraint.php @@ -0,0 +1,26 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +interface VersionConstraint { + /** + * @param Version $version + * + * @return bool + */ + public function complies(Version $version); + + /** + * @return string + */ + public function asString(); + +} diff --git a/vendor/phar-io/version/src/exceptions/Exception.php b/vendor/phar-io/version/src/exceptions/Exception.php new file mode 100644 index 0000000..b99e4dd --- /dev/null +++ b/vendor/phar-io/version/src/exceptions/Exception.php @@ -0,0 +1,14 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +interface Exception { +} diff --git a/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php new file mode 100644 index 0000000..225fe71 --- /dev/null +++ b/vendor/phar-io/version/src/exceptions/InvalidPreReleaseSuffixException.php @@ -0,0 +1,7 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +final class UnsupportedVersionConstraintException extends \RuntimeException implements Exception { +} diff --git a/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php b/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php new file mode 100644 index 0000000..f3e1ba8 --- /dev/null +++ b/vendor/phar-io/version/tests/Integration/VersionConstraintParserTest.php @@ -0,0 +1,146 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\VersionConstraintParser + */ +class VersionConstraintParserTest extends TestCase { + /** + * @dataProvider versionStringProvider + * + * @param string $versionString + * @param VersionConstraint $expectedConstraint + */ + public function testReturnsExpectedConstraint($versionString, VersionConstraint $expectedConstraint) { + $parser = new VersionConstraintParser; + + $this->assertEquals($expectedConstraint, $parser->parse($versionString)); + } + + /** + * @dataProvider unsupportedVersionStringProvider + * + * @param string $versionString + */ + public function testThrowsExceptionIfVersionStringIsNotSupported($versionString) { + $parser = new VersionConstraintParser; + + $this->expectException(UnsupportedVersionConstraintException::class); + + $parser->parse($versionString); + } + + /** + * @return array + */ + public function versionStringProvider() { + return [ + ['1.0.2', new ExactVersionConstraint('1.0.2')], + [ + '~4.6', + new AndVersionConstraintGroup( + '~4.6', + [ + new GreaterThanOrEqualToVersionConstraint('~4.6', new Version('4.6')), + new SpecificMajorVersionConstraint('~4.6', 4) + ] + ) + ], + [ + '~4.6.2', + new AndVersionConstraintGroup( + '~4.6.2', + [ + new GreaterThanOrEqualToVersionConstraint('~4.6.2', new Version('4.6.2')), + new SpecificMajorAndMinorVersionConstraint('~4.6.2', 4, 6) + ] + ) + ], + [ + '^2.6.1', + new AndVersionConstraintGroup( + '^2.6.1', + [ + new GreaterThanOrEqualToVersionConstraint('^2.6.1', new Version('2.6.1')), + new SpecificMajorVersionConstraint('^2.6.1', 2) + ] + ) + ], + ['5.1.*', new SpecificMajorAndMinorVersionConstraint('5.1.*', 5, 1)], + ['5.*', new SpecificMajorVersionConstraint('5.*', 5)], + ['*', new AnyVersionConstraint()], + [ + '1.0.2 || 1.0.5', + new OrVersionConstraintGroup( + '1.0.2 || 1.0.5', + [ + new ExactVersionConstraint('1.0.2'), + new ExactVersionConstraint('1.0.5') + ] + ) + ], + [ + '^5.6 || ^7.0', + new OrVersionConstraintGroup( + '^5.6 || ^7.0', + [ + new AndVersionConstraintGroup( + '^5.6', [ + new GreaterThanOrEqualToVersionConstraint('^5.6', new Version('5.6')), + new SpecificMajorVersionConstraint('^5.6', 5) + ] + ), + new AndVersionConstraintGroup( + '^7.0', [ + new GreaterThanOrEqualToVersionConstraint('^7.0', new Version('7.0')), + new SpecificMajorVersionConstraint('^7.0', 7) + ] + ) + ] + ) + ], + ['7.0.28-1', new ExactVersionConstraint('7.0.28-1')], + [ + '^3.0.0-alpha1', + new AndVersionConstraintGroup( + '^3.0.0-alpha1', + [ + new GreaterThanOrEqualToVersionConstraint('^3.0.0-alpha1', new Version('3.0.0-alpha1')), + new SpecificMajorVersionConstraint('^3.0.0-alpha1', 3) + ] + ) + ], + [ + '^3.0.0-alpha.1', + new AndVersionConstraintGroup( + '^3.0.0-alpha.1', + [ + new GreaterThanOrEqualToVersionConstraint('^3.0.0-alpha.1', new Version('3.0.0-alpha.1')), + new SpecificMajorVersionConstraint('^3.0.0-alpha.1', 3) + ] + ) + ] + ]; + } + + public function unsupportedVersionStringProvider() { + return [ + ['foo'], + ['+1.0.2'], + ['>=2.0'], + ['^5.6 || >= 7.0'], + ['2.0 || foo'] + ]; + } +} diff --git a/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php new file mode 100644 index 0000000..c618566 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/AbstractVersionConstraintTest.php @@ -0,0 +1,25 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\AbstractVersionConstraint + */ +class AbstractVersionConstraintTest extends TestCase { + public function testAsString() { + /** @var AbstractVersionConstraint|\PHPUnit_Framework_MockObject_MockObject $constraint */ + $constraint = $this->getMockForAbstractClass(AbstractVersionConstraint::class, ['foo']); + + $this->assertSame('foo', $constraint->asString()); + } +} diff --git a/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php b/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php new file mode 100644 index 0000000..c2c5ec0 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/AndVersionConstraintGroupTest.php @@ -0,0 +1,52 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\AndVersionConstraintGroup + */ +class AndVersionConstraintGroupTest extends TestCase { + public function testReturnsFalseIfOneConstraintReturnsFalse() { + $firstConstraint = $this->createMock(VersionConstraint::class); + $secondConstraint = $this->createMock(VersionConstraint::class); + + $firstConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(true)); + + $secondConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(false)); + + $group = new AndVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]); + + $this->assertFalse($group->complies(new Version('1.0.0'))); + } + + public function testReturnsTrueIfAllConstraintsReturnsTrue() { + $firstConstraint = $this->createMock(VersionConstraint::class); + $secondConstraint = $this->createMock(VersionConstraint::class); + + $firstConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(true)); + + $secondConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(true)); + + $group = new AndVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]); + + $this->assertTrue($group->complies(new Version('1.0.0'))); + } +} diff --git a/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php new file mode 100644 index 0000000..6883099 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/AnyVersionConstraintTest.php @@ -0,0 +1,41 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\AnyVersionConstraint + */ +class AnyVersionConstraintTest extends TestCase { + public function versionProvider() { + return [ + [new Version('1.0.2')], + [new Version('4.8')], + [new Version('0.1.1-dev')] + ]; + } + + /** + * @dataProvider versionProvider + * + * @param Version $version + */ + public function testReturnsTrue(Version $version) { + $constraint = new AnyVersionConstraint; + + $this->assertTrue($constraint->complies($version)); + } + + public function testAsString() { + $this->assertSame('*', (new AnyVersionConstraint())->asString()); + } +} diff --git a/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php new file mode 100644 index 0000000..ebba024 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/ExactVersionConstraintTest.php @@ -0,0 +1,58 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\ExactVersionConstraint + */ +class ExactVersionConstraintTest extends TestCase { + public function compliantVersionProvider() { + return [ + ['1.0.2', new Version('1.0.2')], + ['4.8.9', new Version('4.8.9')], + ['4.8', new Version('4.8')], + ]; + } + + public function nonCompliantVersionProvider() { + return [ + ['1.0.2', new Version('1.0.3')], + ['4.8.9', new Version('4.7.9')], + ['4.8', new Version('4.8.5')], + ]; + } + + /** + * @dataProvider compliantVersionProvider + * + * @param string $constraintValue + * @param Version $version + */ + public function testReturnsTrueForCompliantVersion($constraintValue, Version $version) { + $constraint = new ExactVersionConstraint($constraintValue); + + $this->assertTrue($constraint->complies($version)); + } + + /** + * @dataProvider nonCompliantVersionProvider + * + * @param string $constraintValue + * @param Version $version + */ + public function testReturnsFalseForNonCompliantVersion($constraintValue, Version $version) { + $constraint = new ExactVersionConstraint($constraintValue); + + $this->assertFalse($constraint->complies($version)); + } +} diff --git a/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php new file mode 100644 index 0000000..3cbb11d --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/GreaterThanOrEqualToVersionConstraintTest.php @@ -0,0 +1,47 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\GreaterThanOrEqualToVersionConstraint + */ +class GreaterThanOrEqualToVersionConstraintTest extends TestCase { + public function versionProvider() { + return [ + // compliant versions + [new Version('1.0.2'), new Version('1.0.2'), true], + [new Version('1.0.2'), new Version('1.0.3'), true], + [new Version('1.0.2'), new Version('1.1.1'), true], + [new Version('1.0.2'), new Version('2.0.0'), true], + [new Version('1.0.2'), new Version('1.0.3'), true], + // non-compliant versions + [new Version('1.0.2'), new Version('1.0.1'), false], + [new Version('1.9.8'), new Version('0.9.9'), false], + [new Version('2.3.1'), new Version('2.2.3'), false], + [new Version('3.0.2'), new Version('2.9.9'), false], + ]; + } + + /** + * @dataProvider versionProvider + * + * @param Version $constraintVersion + * @param Version $version + * @param bool $expectedResult + */ + public function testReturnsTrueForCompliantVersions(Version $constraintVersion, Version $version, $expectedResult) { + $constraint = new GreaterThanOrEqualToVersionConstraint('foo', $constraintVersion); + + $this->assertSame($expectedResult, $constraint->complies($version)); + } +} diff --git a/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php b/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php new file mode 100644 index 0000000..088d557 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/OrVersionConstraintGroupTest.php @@ -0,0 +1,65 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\OrVersionConstraintGroup + */ +class OrVersionConstraintGroupTest extends TestCase { + public function testReturnsTrueIfOneConstraintReturnsFalse() { + $firstConstraint = $this->createMock(VersionConstraint::class); + $secondConstraint = $this->createMock(VersionConstraint::class); + + $firstConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(false)); + + $secondConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(true)); + + $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]); + + $this->assertTrue($group->complies(new Version('1.0.0'))); + } + + public function testReturnsTrueIfAllConstraintsReturnsTrue() { + $firstConstraint = $this->createMock(VersionConstraint::class); + $secondConstraint = $this->createMock(VersionConstraint::class); + + $firstConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(true)); + + $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]); + + $this->assertTrue($group->complies(new Version('1.0.0'))); + } + + public function testReturnsFalseIfAllConstraintsReturnsFalse() { + $firstConstraint = $this->createMock(VersionConstraint::class); + $secondConstraint = $this->createMock(VersionConstraint::class); + + $firstConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(false)); + + $secondConstraint->expects($this->once()) + ->method('complies') + ->will($this->returnValue(false)); + + $group = new OrVersionConstraintGroup('foo', [$firstConstraint, $secondConstraint]); + + $this->assertFalse($group->complies(new Version('1.0.0'))); + } +} diff --git a/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php b/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php new file mode 100644 index 0000000..e09a66d --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/PreReleaseSuffixTest.php @@ -0,0 +1,46 @@ +assertSame($expectedResult, $leftSuffix->isGreaterThan($rightSuffix)); + } + + public function greaterThanProvider() { + return [ + ['alpha1', 'alpha2', false], + ['alpha2', 'alpha1', true], + ['beta1', 'alpha3', true], + ['b1', 'alpha3', true], + ['b1', 'a3', true], + ['dev1', 'alpha2', false], + ['dev1', 'alpha2', false], + ['alpha2', 'dev5', true], + ['rc1', 'beta2', true], + ['patch5', 'rc7', true], + ['alpha1', 'alpha.2', false], + ['alpha.3', 'alpha2', true], + ['alpha.3', 'alpha.2', true], + ]; + } +} diff --git a/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php new file mode 100644 index 0000000..6025889 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/SpecificMajorAndMinorVersionConstraintTest.php @@ -0,0 +1,45 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\SpecificMajorAndMinorVersionConstraint + */ +class SpecificMajorAndMinorVersionConstraintTest extends TestCase { + public function versionProvider() { + return [ + // compliant versions + [1, 0, new Version('1.0.2'), true], + [1, 0, new Version('1.0.3'), true], + [1, 1, new Version('1.1.1'), true], + // non-compliant versions + [2, 9, new Version('0.9.9'), false], + [3, 2, new Version('2.2.3'), false], + [2, 8, new Version('2.9.9'), false], + ]; + } + + /** + * @dataProvider versionProvider + * + * @param int $major + * @param int $minor + * @param Version $version + * @param bool $expectedResult + */ + public function testReturnsTrueForCompliantVersions($major, $minor, Version $version, $expectedResult) { + $constraint = new SpecificMajorAndMinorVersionConstraint('foo', $major, $minor); + + $this->assertSame($expectedResult, $constraint->complies($version)); + } +} diff --git a/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php b/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php new file mode 100644 index 0000000..6dc3b71 --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/SpecificMajorVersionConstraintTest.php @@ -0,0 +1,44 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\SpecificMajorVersionConstraint + */ +class SpecificMajorVersionConstraintTest extends TestCase { + public function versionProvider() { + return [ + // compliant versions + [1, new Version('1.0.2'), true], + [1, new Version('1.0.3'), true], + [1, new Version('1.1.1'), true], + // non-compliant versions + [2, new Version('0.9.9'), false], + [3, new Version('2.2.3'), false], + [3, new Version('2.9.9'), false], + ]; + } + + /** + * @dataProvider versionProvider + * + * @param int $major + * @param Version $version + * @param bool $expectedResult + */ + public function testReturnsTrueForCompliantVersions($major, Version $version, $expectedResult) { + $constraint = new SpecificMajorVersionConstraint('foo', $major); + + $this->assertSame($expectedResult, $constraint->complies($version)); + } +} diff --git a/vendor/phar-io/version/tests/Unit/VersionTest.php b/vendor/phar-io/version/tests/Unit/VersionTest.php new file mode 100644 index 0000000..6b4897a --- /dev/null +++ b/vendor/phar-io/version/tests/Unit/VersionTest.php @@ -0,0 +1,113 @@ +, Sebastian Heuer , Sebastian Bergmann + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace PharIo\Version; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \PharIo\Version\Version + */ +class VersionTest extends TestCase { + /** + * @dataProvider versionProvider + * + * @param string $versionString + * @param string $expectedMajor + * @param string $expectedMinor + * @param string $expectedPatch + * @param string $expectedPreReleaseValue + * @param int $expectedReleaseCount + */ + public function testParsesVersionNumbers( + $versionString, + $expectedMajor, + $expectedMinor, + $expectedPatch, + $expectedPreReleaseValue = '', + $expectedReleaseCount = 0 + ) { + $version = new Version($versionString); + + $this->assertSame($expectedMajor, $version->getMajor()->getValue()); + $this->assertSame($expectedMinor, $version->getMinor()->getValue()); + $this->assertSame($expectedPatch, $version->getPatch()->getValue()); + if ($expectedPreReleaseValue !== '') { + $this->assertSame($expectedPreReleaseValue, $version->getPreReleaseSuffix()->getValue()); + } + if ($expectedReleaseCount !== 0) { + $this->assertSame($expectedReleaseCount, $version->getPreReleaseSuffix()->getNumber()); + } + + $this->assertSame($versionString, $version->getVersionString()); + } + + public function versionProvider() { + return [ + ['0.0.1', '0', '0', '1'], + ['0.1.2', '0', '1', '2'], + ['1.0.0-alpha', '1', '0', '0', 'alpha'], + ['3.4.12-dev3', '3', '4', '12', 'dev', 3], + ]; + } + + /** + * @dataProvider versionGreaterThanProvider + * + * @param Version $versionA + * @param Version $versionB + * @param bool $expectedResult + */ + public function testIsGreaterThan(Version $versionA, Version $versionB, $expectedResult) { + $this->assertSame($expectedResult, $versionA->isGreaterThan($versionB)); + } + + /** + * @return array + */ + public function versionGreaterThanProvider() { + return [ + [new Version('1.0.0'), new Version('1.0.1'), false], + [new Version('1.0.1'), new Version('1.0.0'), true], + [new Version('1.1.0'), new Version('1.0.1'), true], + [new Version('1.1.0'), new Version('2.0.1'), false], + [new Version('1.1.0'), new Version('1.1.0'), false], + [new Version('2.5.8'), new Version('1.6.8'), true], + [new Version('2.5.8'), new Version('2.6.8'), false], + [new Version('2.5.8'), new Version('3.1.2'), false], + [new Version('3.0.0-alpha1'), new Version('3.0.0-alpha2'), false], + [new Version('3.0.0-alpha2'), new Version('3.0.0-alpha1'), true], + [new Version('3.0.0-alpha.1'), new Version('3.0.0'), false], + [new Version('3.0.0'), new Version('3.0.0-alpha.1'), true], + ]; + } + + /** + * @dataProvider invalidVersionStringProvider + * + * @param string $versionString + */ + public function testThrowsExceptionIfVersionStringDoesNotFollowSemVer($versionString) { + $this->expectException(InvalidVersionException::class); + new Version($versionString); + } + + /** + * @return array + */ + public function invalidVersionStringProvider() { + return [ + ['foo'], + ['0.0.1-dev+ABC', '0', '0', '1', 'dev', 'ABC'], + ['1.0.0-x.7.z.92', '1', '0', '0', 'x.7.z.92'] + ]; + } + +} diff --git a/vendor/phenx/php-font-lib/.gitattributes b/vendor/phenx/php-font-lib/.gitattributes new file mode 100644 index 0000000..623abe8 --- /dev/null +++ b/vendor/phenx/php-font-lib/.gitattributes @@ -0,0 +1,12 @@ +*.json text +*.xml text +*.php text +*.LGPL text +*.md text +*.skel text +*.css text +*.inc text +*.js text +*.html text +*.txt text +*.svg text diff --git a/vendor/phenx/php-font-lib/.gitignore b/vendor/phenx/php-font-lib/.gitignore new file mode 100644 index 0000000..d2b601e --- /dev/null +++ b/vendor/phenx/php-font-lib/.gitignore @@ -0,0 +1,5 @@ +.DS_Store +composer.lock +vendor +.idea +.project diff --git a/vendor/phenx/php-font-lib/.htaccess b/vendor/phenx/php-font-lib/.htaccess new file mode 100644 index 0000000..d02bd68 --- /dev/null +++ b/vendor/phenx/php-font-lib/.htaccess @@ -0,0 +1 @@ +#deny from all \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/.travis.yml b/vendor/phenx/php-font-lib/.travis.yml new file mode 100644 index 0000000..a38c93e --- /dev/null +++ b/vendor/phenx/php-font-lib/.travis.yml @@ -0,0 +1,36 @@ +language: php + +env: + - PREFER_LOWEST="--prefer-lowest" + - PREFER_LOWEST="" + +php: + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - 7.3 + - 7.4 + - nightly + +matrix: + include: + - php: 5.4 + dist: trusty + - php: 5.5 + dist: trusty + allow_failures: + - php: nightly + fast_finish: true + +before_script: + - composer dump-autoload + - composer self-update + - composer update --prefer-source $PREFER_LOWEST + +script: bin/phpunit + + +# Use Travis' new container-based infrastructure. +# See http://docs.travis-ci.com/user/migrating-from-legacy/#How-can-I-use-container-based-infrastructure%3F +sudo: false diff --git a/vendor/phenx/php-font-lib/LICENSE b/vendor/phenx/php-font-lib/LICENSE new file mode 100644 index 0000000..bca992d --- /dev/null +++ b/vendor/phenx/php-font-lib/LICENSE @@ -0,0 +1,456 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/README.md b/vendor/phenx/php-font-lib/README.md new file mode 100644 index 0000000..f166ced --- /dev/null +++ b/vendor/phenx/php-font-lib/README.md @@ -0,0 +1,29 @@ +# PHP Font Lib + +[![Build Status](https://travis-ci.org/PhenX/php-font-lib.svg?branch=master)](https://travis-ci.org/PhenX/php-font-lib) + + +This library can be used to: + * Read TrueType, OpenType (with TrueType glyphs), WOFF font files + * Extract basic info (name, style, etc) + * Extract advanced info (horizontal metrics, glyph names, glyph shapes, etc) + * Make an Adobe Font Metrics (AFM) file from a font + +You can find a demo GUI [here](http://pxd.me/php-font-lib/www/font_explorer.html). + +This project was initiated by the need to read font files in the [DOMPDF project](https://github.com/dompdf/dompdf). + +Usage Example +------------- + +``` +$font = \FontLib\Font::load('../../fontfile.ttf'); +$font->parse(); // for getFontWeight() to work this call must be done first! +echo $font->getFontName() .'
'; +echo $font->getFontSubfamily() .'
'; +echo $font->getFontSubfamilyID() .'
'; +echo $font->getFontFullName() .'
'; +echo $font->getFontVersion() .'
'; +echo $font->getFontWeight() .'
'; +echo $font->getFontPostscriptName() .'
'; +``` diff --git a/vendor/phenx/php-font-lib/bower.json b/vendor/phenx/php-font-lib/bower.json new file mode 100644 index 0000000..0a4a45b --- /dev/null +++ b/vendor/phenx/php-font-lib/bower.json @@ -0,0 +1,23 @@ +{ + "name": "php-font-lib", + "version": "0.3.1", + "license": "LGPL-3.0", + "keywords": [ + "font", + "parse", + "export", + "truetype", + "opentype", + "woff" + ], + "homepage": "https://github.com/PhenX/php-font-lib", + "_release": "0.3.1", + "_resolution": { + "type": "version", + "tag": "v0.3.1", + "commit": "d13682b7e27d14a6323c441426f3dde1cd86c751" + }, + "_source": "https://github.com/PhenX/php-font-lib.git", + "_target": "*", + "_originalSource": "https://github.com/PhenX/php-font-lib.git" +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/composer.json b/vendor/phenx/php-font-lib/composer.json new file mode 100644 index 0000000..18cf0ca --- /dev/null +++ b/vendor/phenx/php-font-lib/composer.json @@ -0,0 +1,24 @@ +{ + "name": "phenx/php-font-lib", + "type": "library", + "description": "A library to read, parse, export and make subsets of different types of font files.", + "homepage": "https://github.com/PhenX/php-font-lib", + "license": "LGPL-3.0", + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "autoload": { + "psr-4": { + "FontLib\\": "src/FontLib" + } + }, + "config": { + "bin-dir": "bin" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5 || ^6 || ^7" + } +} diff --git a/vendor/phenx/php-font-lib/index.php b/vendor/phenx/php-font-lib/index.php new file mode 100644 index 0000000..7ed173a --- /dev/null +++ b/vendor/phenx/php-font-lib/index.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map b/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map new file mode 100644 index 0000000..230d4a1 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/adobe-standard-encoding.map @@ -0,0 +1,231 @@ +// Adobe Standard Encoding table for ttf2pt1 +// Thomas Henlich + +=20 U+0020 SPACE +=21 U+0021 EXCLAMATION MARK +=22 U+0022 QUOTATION MARK +=23 U+0023 NUMBER SIGN +=24 U+0024 DOLLAR SIGN +=25 U+0025 PERCENT SIGN +=26 U+0026 AMPERSAND +=27 U+2019 RIGHT SINGLE QUOTATION MARK +=28 U+0028 LEFT PARENTHESIS +=29 U+0029 RIGHT PARENTHESIS +=2A U+002A ASTERISK +=2B U+002B PLUS SIGN +=2C U+002C COMMA +=2D U+002D HYPHEN-MINUS +=2E U+002E FULL STOP +=2F U+002F SOLIDUS +=30 U+0030 DIGIT ZERO +=31 U+0031 DIGIT ONE +=32 U+0032 DIGIT TWO +=33 U+0033 DIGIT THREE +=34 U+0034 DIGIT FOUR +=35 U+0035 DIGIT FIVE +=36 U+0036 DIGIT SIX +=37 U+0037 DIGIT SEVEN +=38 U+0038 DIGIT EIGHT +=39 U+0039 DIGIT NINE +=3A U+003A COLON +=3B U+003B SEMICOLON +=3C U+003C LESS-THAN SIGN +=3D U+003D EQUALS SIGN +=3E U+003E GREATER-THAN SIGN +=3F U+003F QUESTION MARK +=40 U+0040 COMMERCIAL AT +=41 U+0041 LATIN CAPITAL LETTER A +=42 U+0042 LATIN CAPITAL LETTER B +=43 U+0043 LATIN CAPITAL LETTER C +=44 U+0044 LATIN CAPITAL LETTER D +=45 U+0045 LATIN CAPITAL LETTER E +=46 U+0046 LATIN CAPITAL LETTER F +=47 U+0047 LATIN CAPITAL LETTER G +=48 U+0048 LATIN CAPITAL LETTER H +=49 U+0049 LATIN CAPITAL LETTER I +=4A U+004A LATIN CAPITAL LETTER J +=4B U+004B LATIN CAPITAL LETTER K +=4C U+004C LATIN CAPITAL LETTER L +=4D U+004D LATIN CAPITAL LETTER M +=4E U+004E LATIN CAPITAL LETTER N +=4F U+004F LATIN CAPITAL LETTER O +=50 U+0050 LATIN CAPITAL LETTER P +=51 U+0051 LATIN CAPITAL LETTER Q +=52 U+0052 LATIN CAPITAL LETTER R +=53 U+0053 LATIN CAPITAL LETTER S +=54 U+0054 LATIN CAPITAL LETTER T +=55 U+0055 LATIN CAPITAL LETTER U +=56 U+0056 LATIN CAPITAL LETTER V +=57 U+0057 LATIN CAPITAL LETTER W +=58 U+0058 LATIN CAPITAL LETTER X +=59 U+0059 LATIN CAPITAL LETTER Y +=5A U+005A LATIN CAPITAL LETTER Z +=5B U+005B LEFT SQUARE BRACKET +=5C U+005C REVERSE SOLIDUS +=5D U+005D RIGHT SQUARE BRACKET +=5E U+005E CIRCUMFLEX ACCENT +=5F U+005F LOW LINE +=60 U+2018 LEFT SINGLE QUOTATION MARK +=61 U+0061 LATIN SMALL LETTER A +=62 U+0062 LATIN SMALL LETTER B +=63 U+0063 LATIN SMALL LETTER C +=64 U+0064 LATIN SMALL LETTER D +=65 U+0065 LATIN SMALL LETTER E +=66 U+0066 LATIN SMALL LETTER F +=67 U+0067 LATIN SMALL LETTER G +=68 U+0068 LATIN SMALL LETTER H +=69 U+0069 LATIN SMALL LETTER I +=6A U+006A LATIN SMALL LETTER J +=6B U+006B LATIN SMALL LETTER K +=6C U+006C LATIN SMALL LETTER L +=6D U+006D LATIN SMALL LETTER M +=6E U+006E LATIN SMALL LETTER N +=6F U+006F LATIN SMALL LETTER O +=70 U+0070 LATIN SMALL LETTER P +=71 U+0071 LATIN SMALL LETTER Q +=72 U+0072 LATIN SMALL LETTER R +=73 U+0073 LATIN SMALL LETTER S +=74 U+0074 LATIN SMALL LETTER T +=75 U+0075 LATIN SMALL LETTER U +=76 U+0076 LATIN SMALL LETTER V +=77 U+0077 LATIN SMALL LETTER W +=78 U+0078 LATIN SMALL LETTER X +=79 U+0079 LATIN SMALL LETTER Y +=7A U+007A LATIN SMALL LETTER Z +=7B U+007B LEFT CURLY BRACKET +=7C U+007C VERTICAL LINE +=7D U+007D RIGHT CURLY BRACKET +=7E U+007E TILDE +=A1 U+00A1 INVERTED EXCLAMATION MARK +=A2 U+00A2 CENT SIGN +=A3 U+00A3 POUND SIGN +=A4 U+2044 FRACTION SLASH +=A5 U+00A5 YEN SIGN +=A6 U+0192 LATIN SMALL LETTER F WITH HOOK +=A7 U+00A7 SECTION SIGN +=A8 U+00A4 CURRENCY SIGN +=A9 U+0027 APOSTROPHE +=AA U+201C LEFT DOUBLE QUOTATION MARK +=AB U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +=AC U+2039 SINGLE LEFT-POINTING ANGLE QUOTATION MARK +=AD U+203A SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +=AE U+FB01 LATIN SMALL LIGATURE FI +=AF U+FB02 LATIN SMALL LIGATURE FL +=B1 U+2013 EN DASH +=B2 U+2020 DAGGER +=B3 U+2021 DOUBLE DAGGER +=B4 U+00B7 MIDDLE DOT +=B6 U+00B6 PILCROW SIGN +=B7 U+2022 BULLET +=B8 U+201A SINGLE LOW-9 QUOTATION MARK +=B9 U+201E DOUBLE LOW-9 QUOTATION MARK +=BA U+201D RIGHT DOUBLE QUOTATION MARK +=BB U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +=BC U+2026 HORIZONTAL ELLIPSIS +=BD U+2030 PER MILLE SIGN +=BF U+00BF INVERTED QUESTION MARK +=C1 U+0060 GRAVE ACCENT +=C2 U+00B4 ACUTE ACCENT +=C3 U+02C6 MODIFIER LETTER CIRCUMFLEX ACCENT +=C4 U+02DC SMALL TILDE +=C5 U+00AF MACRON +=C6 U+02D8 BREVE +=C7 U+02D9 DOT ABOVE +=C8 U+00A8 DIAERESIS +=CA U+02DA RING ABOVE +=CB U+00B8 CEDILLA +=CD U+02DD DOUBLE ACUTE ACCENT +=CE U+02DB OGONEK +=CF U+02C7 CARON +=D0 U+2014 EM DASH +=E1 U+00C6 LATIN CAPITAL LETTER AE +=E3 U+00AA FEMININE ORDINAL INDICATOR +=E8 U+0141 LATIN CAPITAL LETTER L WITH STROKE +=E9 U+00D8 LATIN CAPITAL LETTER O WITH STROKE +=EA U+0152 LATIN CAPITAL LIGATURE OE +=EB U+00BA MASCULINE ORDINAL INDICATOR +=F1 U+00E6 LATIN SMALL LETTER AE +=F5 U+0131 LATIN SMALL LETTER DOTLESS I +=F8 U+0142 LATIN SMALL LETTER L WITH STROKE +=F9 U+00F8 LATIN SMALL LETTER O WITH STROKE +=FA U+0153 LATIN SMALL LIGATURE OE +=FB U+00DF LATIN SMALL LETTER SHARP S + +// unencoded characters: +=100 U+00E7 LATIN SMALL LETTER C WITH CEDILLA +=101 U+00FF LATIN SMALL LETTER Y WITH DIAERESIS +=102 U+00E3 LATIN SMALL LETTER A WITH TILDE +=103 U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX +=104 U+00B3 SUPERSCRIPT THREE +=105 U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX +=106 U+00FE LATIN SMALL LETTER THORN +=107 U+00E8 LATIN SMALL LETTER E WITH GRAVE +=108 U+00B2 SUPERSCRIPT TWO +=109 U+00E9 LATIN SMALL LETTER E WITH ACUTE +=10A U+00F5 LATIN SMALL LETTER O WITH TILDE +=10B U+00C1 LATIN CAPITAL LETTER A WITH ACUTE +=10C U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX +=10D U+00FD LATIN SMALL LETTER Y WITH ACUTE +=10E U+00FC LATIN SMALL LETTER U WITH DIAERESIS +=10F U+00BE VULGAR FRACTION THREE QUARTERS +=110 U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX +=111 U+00D0 LATIN CAPITAL LETTER ETH +=112 U+00EB LATIN SMALL LETTER E WITH DIAERESIS +=113 U+00F9 LATIN SMALL LETTER U WITH GRAVE +=114 U+2122 TRADE MARK SIGN +=115 U+00F2 LATIN SMALL LETTER O WITH GRAVE +=116 U+0161 LATIN SMALL LETTER S WITH CARON +=117 U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS +=118 U+00FA LATIN SMALL LETTER U WITH ACUTE +=119 U+00E0 LATIN SMALL LETTER A WITH GRAVE +=11A U+00F1 LATIN SMALL LETTER N WITH TILDE +=11B U+00E5 LATIN SMALL LETTER A WITH RING ABOVE +=11C U+017E LATIN SMALL LETTER Z WITH CARON +=11D U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX +=11E U+00D1 LATIN CAPITAL LETTER N WITH TILDE +=11F U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX +=120 U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX +=121 U+00CD LATIN CAPITAL LETTER I WITH ACUTE +=122 U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA +=123 U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS +=124 U+0160 LATIN CAPITAL LETTER S WITH CARON +=125 U+00CC LATIN CAPITAL LETTER I WITH GRAVE +=126 U+00E4 LATIN SMALL LETTER A WITH DIAERESIS +=127 U+00D2 LATIN CAPITAL LETTER O WITH GRAVE +=128 U+00C8 LATIN CAPITAL LETTER E WITH GRAVE +=129 U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS +=12A U+00AE REGISTERED SIGN +=12B U+00D5 LATIN CAPITAL LETTER O WITH TILDE +=12C U+00BC VULGAR FRACTION ONE QUARTER +=12D U+00D9 LATIN CAPITAL LETTER U WITH GRAVE +=12E U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX +=12F U+00DE LATIN CAPITAL LETTER THORN +=130 U+00F7 DIVISION SIGN +=131 U+00C3 LATIN CAPITAL LETTER A WITH TILDE +=132 U+00DA LATIN CAPITAL LETTER U WITH ACUTE +=133 U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX +=134 U+00AC NOT SIGN +=135 U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE +=136 U+00EF LATIN SMALL LETTER I WITH DIAERESIS +=137 U+00ED LATIN SMALL LETTER I WITH ACUTE +=138 U+00E1 LATIN SMALL LETTER A WITH ACUTE +=139 U+00B1 PLUS-MINUS SIGN +=13A U+00D7 MULTIPLICATION SIGN +=13B U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS +=13C U+2212 MINUS SIGN +=13D U+00B9 SUPERSCRIPT ONE +=13E U+00C9 LATIN CAPITAL LETTER E WITH ACUTE +=13F U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX +=140 U+00A9 COPYRIGHT SIGN +=141 U+00C0 LATIN CAPITAL LETTER A WITH GRAVE +=142 U+00F6 LATIN SMALL LETTER O WITH DIAERESIS +=143 U+00F3 LATIN SMALL LETTER O WITH ACUTE +=144 U+00B0 DEGREE SIGN +=145 U+00EC LATIN SMALL LETTER I WITH GRAVE +=146 U+00B5 MICRO SIGN +=147 U+00D3 LATIN CAPITAL LETTER O WITH ACUTE +=148 U+00F0 LATIN SMALL LETTER ETH +=149 U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS +=14A U+00DD LATIN CAPITAL LETTER Y WITH ACUTE +=14B U+00A6 BROKEN BAR +=14C U+00BD VULGAR FRACTION ONE HALF diff --git a/vendor/phenx/php-font-lib/maps/cp1250.map b/vendor/phenx/php-font-lib/maps/cp1250.map new file mode 100644 index 0000000..ec110af --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1250.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+015A Sacute +!8D U+0164 Tcaron +!8E U+017D Zcaron +!8F U+0179 Zacute +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+015B sacute +!9D U+0165 tcaron +!9E U+017E zcaron +!9F U+017A zacute +!A0 U+00A0 space +!A1 U+02C7 caron +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+0104 Aogonek +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+015E Scedilla +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+0105 aogonek +!BA U+015F scedilla +!BB U+00BB guillemotright +!BC U+013D Lcaron +!BD U+02DD hungarumlaut +!BE U+013E lcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/cp1251.map b/vendor/phenx/php-font-lib/maps/cp1251.map new file mode 100644 index 0000000..de6a198 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1251.map @@ -0,0 +1,255 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0402 afii10051 +!81 U+0403 afii10052 +!82 U+201A quotesinglbase +!83 U+0453 afii10100 +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+20AC Euro +!89 U+2030 perthousand +!8A U+0409 afii10058 +!8B U+2039 guilsinglleft +!8C U+040A afii10059 +!8D U+040C afii10061 +!8E U+040B afii10060 +!8F U+040F afii10145 +!90 U+0452 afii10099 +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9A U+0459 afii10106 +!9B U+203A guilsinglright +!9C U+045A afii10107 +!9D U+045C afii10109 +!9E U+045B afii10108 +!9F U+045F afii10193 +!A0 U+00A0 space +!A1 U+040E afii10062 +!A2 U+045E afii10110 +!A3 U+0408 afii10057 +!A4 U+00A4 currency +!A5 U+0490 afii10050 +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+0401 afii10023 +!A9 U+00A9 copyright +!AA U+0404 afii10053 +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+0407 afii10056 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+0406 afii10055 +!B3 U+0456 afii10103 +!B4 U+0491 afii10098 +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0451 afii10071 +!B9 U+2116 afii61352 +!BA U+0454 afii10101 +!BB U+00BB guillemotright +!BC U+0458 afii10105 +!BD U+0405 afii10054 +!BE U+0455 afii10102 +!BF U+0457 afii10104 +!C0 U+0410 afii10017 +!C1 U+0411 afii10018 +!C2 U+0412 afii10019 +!C3 U+0413 afii10020 +!C4 U+0414 afii10021 +!C5 U+0415 afii10022 +!C6 U+0416 afii10024 +!C7 U+0417 afii10025 +!C8 U+0418 afii10026 +!C9 U+0419 afii10027 +!CA U+041A afii10028 +!CB U+041B afii10029 +!CC U+041C afii10030 +!CD U+041D afii10031 +!CE U+041E afii10032 +!CF U+041F afii10033 +!D0 U+0420 afii10034 +!D1 U+0421 afii10035 +!D2 U+0422 afii10036 +!D3 U+0423 afii10037 +!D4 U+0424 afii10038 +!D5 U+0425 afii10039 +!D6 U+0426 afii10040 +!D7 U+0427 afii10041 +!D8 U+0428 afii10042 +!D9 U+0429 afii10043 +!DA U+042A afii10044 +!DB U+042B afii10045 +!DC U+042C afii10046 +!DD U+042D afii10047 +!DE U+042E afii10048 +!DF U+042F afii10049 +!E0 U+0430 afii10065 +!E1 U+0431 afii10066 +!E2 U+0432 afii10067 +!E3 U+0433 afii10068 +!E4 U+0434 afii10069 +!E5 U+0435 afii10070 +!E6 U+0436 afii10072 +!E7 U+0437 afii10073 +!E8 U+0438 afii10074 +!E9 U+0439 afii10075 +!EA U+043A afii10076 +!EB U+043B afii10077 +!EC U+043C afii10078 +!ED U+043D afii10079 +!EE U+043E afii10080 +!EF U+043F afii10081 +!F0 U+0440 afii10082 +!F1 U+0441 afii10083 +!F2 U+0442 afii10084 +!F3 U+0443 afii10085 +!F4 U+0444 afii10086 +!F5 U+0445 afii10087 +!F6 U+0446 afii10088 +!F7 U+0447 afii10089 +!F8 U+0448 afii10090 +!F9 U+0449 afii10091 +!FA U+044A afii10092 +!FB U+044B afii10093 +!FC U+044C afii10094 +!FD U+044D afii10095 +!FE U+044E afii10096 +!FF U+044F afii10097 diff --git a/vendor/phenx/php-font-lib/maps/cp1252.map b/vendor/phenx/php-font-lib/maps/cp1252.map new file mode 100644 index 0000000..dd490e5 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1252.map @@ -0,0 +1,251 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!8E U+017D Zcaron +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9E U+017E zcaron +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp1253.map b/vendor/phenx/php-font-lib/maps/cp1253.map new file mode 100644 index 0000000..4bd826f --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1253.map @@ -0,0 +1,239 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+0385 dieresistonos +!A2 U+0386 Alphatonos +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/vendor/phenx/php-font-lib/maps/cp1254.map b/vendor/phenx/php-font-lib/maps/cp1254.map new file mode 100644 index 0000000..829473b --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1254.map @@ -0,0 +1,249 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8A U+0160 Scaron +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9A U+0161 scaron +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp1255.map b/vendor/phenx/php-font-lib/maps/cp1255.map new file mode 100644 index 0000000..079e10c --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1255.map @@ -0,0 +1,233 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AA afii57636 +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00D7 multiply +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD sfthyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 middot +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00F7 divide +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+05B0 afii57799 +!C1 U+05B1 afii57801 +!C2 U+05B2 afii57800 +!C3 U+05B3 afii57802 +!C4 U+05B4 afii57793 +!C5 U+05B5 afii57794 +!C6 U+05B6 afii57795 +!C7 U+05B7 afii57798 +!C8 U+05B8 afii57797 +!C9 U+05B9 afii57806 +!CB U+05BB afii57796 +!CC U+05BC afii57807 +!CD U+05BD afii57839 +!CE U+05BE afii57645 +!CF U+05BF afii57841 +!D0 U+05C0 afii57842 +!D1 U+05C1 afii57804 +!D2 U+05C2 afii57803 +!D3 U+05C3 afii57658 +!D4 U+05F0 afii57716 +!D5 U+05F1 afii57717 +!D6 U+05F2 afii57718 +!D7 U+05F3 gereshhebrew +!D8 U+05F4 gershayimhebrew +!E0 U+05D0 afii57664 +!E1 U+05D1 afii57665 +!E2 U+05D2 afii57666 +!E3 U+05D3 afii57667 +!E4 U+05D4 afii57668 +!E5 U+05D5 afii57669 +!E6 U+05D6 afii57670 +!E7 U+05D7 afii57671 +!E8 U+05D8 afii57672 +!E9 U+05D9 afii57673 +!EA U+05DA afii57674 +!EB U+05DB afii57675 +!EC U+05DC afii57676 +!ED U+05DD afii57677 +!EE U+05DE afii57678 +!EF U+05DF afii57679 +!F0 U+05E0 afii57680 +!F1 U+05E1 afii57681 +!F2 U+05E2 afii57682 +!F3 U+05E3 afii57683 +!F4 U+05E4 afii57684 +!F5 U+05E5 afii57685 +!F6 U+05E6 afii57686 +!F7 U+05E7 afii57687 +!F8 U+05E8 afii57688 +!F9 U+05E9 afii57689 +!FA U+05EA afii57690 +!FD U+200E afii299 +!FE U+200F afii300 diff --git a/vendor/phenx/php-font-lib/maps/cp1257.map b/vendor/phenx/php-font-lib/maps/cp1257.map new file mode 100644 index 0000000..2f2ecfa --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1257.map @@ -0,0 +1,244 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8D U+00A8 dieresis +!8E U+02C7 caron +!8F U+00B8 cedilla +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!99 U+2122 trademark +!9B U+203A guilsinglright +!9D U+00AF macron +!9E U+02DB ogonek +!A0 U+00A0 space +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00D8 Oslash +!A9 U+00A9 copyright +!AA U+0156 Rcommaaccent +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00C6 AE +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00F8 oslash +!B9 U+00B9 onesuperior +!BA U+0157 rcommaaccent +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00E6 ae +!C0 U+0104 Aogonek +!C1 U+012E Iogonek +!C2 U+0100 Amacron +!C3 U+0106 Cacute +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+0118 Eogonek +!C7 U+0112 Emacron +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0179 Zacute +!CB U+0116 Edotaccent +!CC U+0122 Gcommaaccent +!CD U+0136 Kcommaaccent +!CE U+012A Imacron +!CF U+013B Lcommaaccent +!D0 U+0160 Scaron +!D1 U+0143 Nacute +!D2 U+0145 Ncommaaccent +!D3 U+00D3 Oacute +!D4 U+014C Omacron +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0172 Uogonek +!D9 U+0141 Lslash +!DA U+015A Sacute +!DB U+016A Umacron +!DC U+00DC Udieresis +!DD U+017B Zdotaccent +!DE U+017D Zcaron +!DF U+00DF germandbls +!E0 U+0105 aogonek +!E1 U+012F iogonek +!E2 U+0101 amacron +!E3 U+0107 cacute +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+0119 eogonek +!E7 U+0113 emacron +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+017A zacute +!EB U+0117 edotaccent +!EC U+0123 gcommaaccent +!ED U+0137 kcommaaccent +!EE U+012B imacron +!EF U+013C lcommaaccent +!F0 U+0161 scaron +!F1 U+0144 nacute +!F2 U+0146 ncommaaccent +!F3 U+00F3 oacute +!F4 U+014D omacron +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0173 uogonek +!F9 U+0142 lslash +!FA U+015B sacute +!FB U+016B umacron +!FC U+00FC udieresis +!FD U+017C zdotaccent +!FE U+017E zcaron +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/cp1258.map b/vendor/phenx/php-font-lib/maps/cp1258.map new file mode 100644 index 0000000..fed915f --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp1258.map @@ -0,0 +1,247 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!82 U+201A quotesinglbase +!83 U+0192 florin +!84 U+201E quotedblbase +!85 U+2026 ellipsis +!86 U+2020 dagger +!87 U+2021 daggerdbl +!88 U+02C6 circumflex +!89 U+2030 perthousand +!8B U+2039 guilsinglleft +!8C U+0152 OE +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!98 U+02DC tilde +!99 U+2122 trademark +!9B U+203A guilsinglright +!9C U+0153 oe +!9F U+0178 Ydieresis +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+0300 gravecomb +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+00D1 Ntilde +!D2 U+0309 hookabovecomb +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+01A0 Ohorn +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+01AF Uhorn +!DE U+0303 tildecomb +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+0301 acutecomb +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+00F1 ntilde +!F2 U+0323 dotbelowcomb +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+01A1 ohorn +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+01B0 uhorn +!FE U+20AB dong +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/cp874.map b/vendor/phenx/php-font-lib/maps/cp874.map new file mode 100644 index 0000000..1006e6b --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/cp874.map @@ -0,0 +1,225 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+20AC Euro +!85 U+2026 ellipsis +!91 U+2018 quoteleft +!92 U+2019 quoteright +!93 U+201C quotedblleft +!94 U+201D quotedblright +!95 U+2022 bullet +!96 U+2013 endash +!97 U+2014 emdash +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-1.map b/vendor/phenx/php-font-lib/maps/iso-8859-1.map new file mode 100644 index 0000000..61740a3 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-1.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-11.map b/vendor/phenx/php-font-lib/maps/iso-8859-11.map new file mode 100644 index 0000000..9168812 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-11.map @@ -0,0 +1,248 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0E01 kokaithai +!A2 U+0E02 khokhaithai +!A3 U+0E03 khokhuatthai +!A4 U+0E04 khokhwaithai +!A5 U+0E05 khokhonthai +!A6 U+0E06 khorakhangthai +!A7 U+0E07 ngonguthai +!A8 U+0E08 chochanthai +!A9 U+0E09 chochingthai +!AA U+0E0A chochangthai +!AB U+0E0B sosothai +!AC U+0E0C chochoethai +!AD U+0E0D yoyingthai +!AE U+0E0E dochadathai +!AF U+0E0F topatakthai +!B0 U+0E10 thothanthai +!B1 U+0E11 thonangmonthothai +!B2 U+0E12 thophuthaothai +!B3 U+0E13 nonenthai +!B4 U+0E14 dodekthai +!B5 U+0E15 totaothai +!B6 U+0E16 thothungthai +!B7 U+0E17 thothahanthai +!B8 U+0E18 thothongthai +!B9 U+0E19 nonuthai +!BA U+0E1A bobaimaithai +!BB U+0E1B poplathai +!BC U+0E1C phophungthai +!BD U+0E1D fofathai +!BE U+0E1E phophanthai +!BF U+0E1F fofanthai +!C0 U+0E20 phosamphaothai +!C1 U+0E21 momathai +!C2 U+0E22 yoyakthai +!C3 U+0E23 roruathai +!C4 U+0E24 ruthai +!C5 U+0E25 lolingthai +!C6 U+0E26 luthai +!C7 U+0E27 wowaenthai +!C8 U+0E28 sosalathai +!C9 U+0E29 sorusithai +!CA U+0E2A sosuathai +!CB U+0E2B hohipthai +!CC U+0E2C lochulathai +!CD U+0E2D oangthai +!CE U+0E2E honokhukthai +!CF U+0E2F paiyannoithai +!D0 U+0E30 saraathai +!D1 U+0E31 maihanakatthai +!D2 U+0E32 saraaathai +!D3 U+0E33 saraamthai +!D4 U+0E34 saraithai +!D5 U+0E35 saraiithai +!D6 U+0E36 sarauethai +!D7 U+0E37 saraueethai +!D8 U+0E38 sarauthai +!D9 U+0E39 sarauuthai +!DA U+0E3A phinthuthai +!DF U+0E3F bahtthai +!E0 U+0E40 saraethai +!E1 U+0E41 saraaethai +!E2 U+0E42 saraothai +!E3 U+0E43 saraaimaimuanthai +!E4 U+0E44 saraaimaimalaithai +!E5 U+0E45 lakkhangyaothai +!E6 U+0E46 maiyamokthai +!E7 U+0E47 maitaikhuthai +!E8 U+0E48 maiekthai +!E9 U+0E49 maithothai +!EA U+0E4A maitrithai +!EB U+0E4B maichattawathai +!EC U+0E4C thanthakhatthai +!ED U+0E4D nikhahitthai +!EE U+0E4E yamakkanthai +!EF U+0E4F fongmanthai +!F0 U+0E50 zerothai +!F1 U+0E51 onethai +!F2 U+0E52 twothai +!F3 U+0E53 threethai +!F4 U+0E54 fourthai +!F5 U+0E55 fivethai +!F6 U+0E56 sixthai +!F7 U+0E57 seventhai +!F8 U+0E58 eightthai +!F9 U+0E59 ninethai +!FA U+0E5A angkhankhuthai +!FB U+0E5B khomutthai diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-15.map b/vendor/phenx/php-font-lib/maps/iso-8859-15.map new file mode 100644 index 0000000..6c2b571 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-15.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+20AC Euro +!A5 U+00A5 yen +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+017D Zcaron +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+00D0 Eth +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+00DE Thorn +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+00F0 eth +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+00FE thorn +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-16.map b/vendor/phenx/php-font-lib/maps/iso-8859-16.map new file mode 100644 index 0000000..202c8fe --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-16.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0105 aogonek +!A3 U+0141 Lslash +!A4 U+20AC Euro +!A5 U+201E quotedblbase +!A6 U+0160 Scaron +!A7 U+00A7 section +!A8 U+0161 scaron +!A9 U+00A9 copyright +!AA U+0218 Scommaaccent +!AB U+00AB guillemotleft +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017A zacute +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+010C Ccaron +!B3 U+0142 lslash +!B4 U+017D Zcaron +!B5 U+201D quotedblright +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+017E zcaron +!B9 U+010D ccaron +!BA U+0219 scommaaccent +!BB U+00BB guillemotright +!BC U+0152 OE +!BD U+0153 oe +!BE U+0178 Ydieresis +!BF U+017C zdotaccent +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0106 Cacute +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+015A Sacute +!D8 U+0170 Uhungarumlaut +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0118 Eogonek +!DE U+021A Tcommaaccent +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+0107 cacute +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+015B sacute +!F8 U+0171 uhungarumlaut +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0119 eogonek +!FE U+021B tcommaaccent +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-2.map b/vendor/phenx/php-font-lib/maps/iso-8859-2.map new file mode 100644 index 0000000..65ae09f --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-2.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+02D8 breve +!A3 U+0141 Lslash +!A4 U+00A4 currency +!A5 U+013D Lcaron +!A6 U+015A Sacute +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+015E Scedilla +!AB U+0164 Tcaron +!AC U+0179 Zacute +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+017B Zdotaccent +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0142 lslash +!B4 U+00B4 acute +!B5 U+013E lcaron +!B6 U+015B sacute +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+015F scedilla +!BB U+0165 tcaron +!BC U+017A zacute +!BD U+02DD hungarumlaut +!BE U+017E zcaron +!BF U+017C zdotaccent +!C0 U+0154 Racute +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+0102 Abreve +!C4 U+00C4 Adieresis +!C5 U+0139 Lacute +!C6 U+0106 Cacute +!C7 U+00C7 Ccedilla +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+011A Ecaron +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+010E Dcaron +!D0 U+0110 Dcroat +!D1 U+0143 Nacute +!D2 U+0147 Ncaron +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+0150 Ohungarumlaut +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+0158 Rcaron +!D9 U+016E Uring +!DA U+00DA Uacute +!DB U+0170 Uhungarumlaut +!DC U+00DC Udieresis +!DD U+00DD Yacute +!DE U+0162 Tcommaaccent +!DF U+00DF germandbls +!E0 U+0155 racute +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+0103 abreve +!E4 U+00E4 adieresis +!E5 U+013A lacute +!E6 U+0107 cacute +!E7 U+00E7 ccedilla +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+011B ecaron +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+010F dcaron +!F0 U+0111 dcroat +!F1 U+0144 nacute +!F2 U+0148 ncaron +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+0151 ohungarumlaut +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+0159 rcaron +!F9 U+016F uring +!FA U+00FA uacute +!FB U+0171 uhungarumlaut +!FC U+00FC udieresis +!FD U+00FD yacute +!FE U+0163 tcommaaccent +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-4.map b/vendor/phenx/php-font-lib/maps/iso-8859-4.map new file mode 100644 index 0000000..a7d87bf --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-4.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0104 Aogonek +!A2 U+0138 kgreenlandic +!A3 U+0156 Rcommaaccent +!A4 U+00A4 currency +!A5 U+0128 Itilde +!A6 U+013B Lcommaaccent +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+0160 Scaron +!AA U+0112 Emacron +!AB U+0122 Gcommaaccent +!AC U+0166 Tbar +!AD U+00AD hyphen +!AE U+017D Zcaron +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+0105 aogonek +!B2 U+02DB ogonek +!B3 U+0157 rcommaaccent +!B4 U+00B4 acute +!B5 U+0129 itilde +!B6 U+013C lcommaaccent +!B7 U+02C7 caron +!B8 U+00B8 cedilla +!B9 U+0161 scaron +!BA U+0113 emacron +!BB U+0123 gcommaaccent +!BC U+0167 tbar +!BD U+014A Eng +!BE U+017E zcaron +!BF U+014B eng +!C0 U+0100 Amacron +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+012E Iogonek +!C8 U+010C Ccaron +!C9 U+00C9 Eacute +!CA U+0118 Eogonek +!CB U+00CB Edieresis +!CC U+0116 Edotaccent +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+012A Imacron +!D0 U+0110 Dcroat +!D1 U+0145 Ncommaaccent +!D2 U+014C Omacron +!D3 U+0136 Kcommaaccent +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+0172 Uogonek +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0168 Utilde +!DE U+016A Umacron +!DF U+00DF germandbls +!E0 U+0101 amacron +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+012F iogonek +!E8 U+010D ccaron +!E9 U+00E9 eacute +!EA U+0119 eogonek +!EB U+00EB edieresis +!EC U+0117 edotaccent +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+012B imacron +!F0 U+0111 dcroat +!F1 U+0146 ncommaaccent +!F2 U+014D omacron +!F3 U+0137 kcommaaccent +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+0173 uogonek +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0169 utilde +!FE U+016B umacron +!FF U+02D9 dotaccent diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-5.map b/vendor/phenx/php-font-lib/maps/iso-8859-5.map new file mode 100644 index 0000000..f9cd4ed --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-5.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+0401 afii10023 +!A2 U+0402 afii10051 +!A3 U+0403 afii10052 +!A4 U+0404 afii10053 +!A5 U+0405 afii10054 +!A6 U+0406 afii10055 +!A7 U+0407 afii10056 +!A8 U+0408 afii10057 +!A9 U+0409 afii10058 +!AA U+040A afii10059 +!AB U+040B afii10060 +!AC U+040C afii10061 +!AD U+00AD hyphen +!AE U+040E afii10062 +!AF U+040F afii10145 +!B0 U+0410 afii10017 +!B1 U+0411 afii10018 +!B2 U+0412 afii10019 +!B3 U+0413 afii10020 +!B4 U+0414 afii10021 +!B5 U+0415 afii10022 +!B6 U+0416 afii10024 +!B7 U+0417 afii10025 +!B8 U+0418 afii10026 +!B9 U+0419 afii10027 +!BA U+041A afii10028 +!BB U+041B afii10029 +!BC U+041C afii10030 +!BD U+041D afii10031 +!BE U+041E afii10032 +!BF U+041F afii10033 +!C0 U+0420 afii10034 +!C1 U+0421 afii10035 +!C2 U+0422 afii10036 +!C3 U+0423 afii10037 +!C4 U+0424 afii10038 +!C5 U+0425 afii10039 +!C6 U+0426 afii10040 +!C7 U+0427 afii10041 +!C8 U+0428 afii10042 +!C9 U+0429 afii10043 +!CA U+042A afii10044 +!CB U+042B afii10045 +!CC U+042C afii10046 +!CD U+042D afii10047 +!CE U+042E afii10048 +!CF U+042F afii10049 +!D0 U+0430 afii10065 +!D1 U+0431 afii10066 +!D2 U+0432 afii10067 +!D3 U+0433 afii10068 +!D4 U+0434 afii10069 +!D5 U+0435 afii10070 +!D6 U+0436 afii10072 +!D7 U+0437 afii10073 +!D8 U+0438 afii10074 +!D9 U+0439 afii10075 +!DA U+043A afii10076 +!DB U+043B afii10077 +!DC U+043C afii10078 +!DD U+043D afii10079 +!DE U+043E afii10080 +!DF U+043F afii10081 +!E0 U+0440 afii10082 +!E1 U+0441 afii10083 +!E2 U+0442 afii10084 +!E3 U+0443 afii10085 +!E4 U+0444 afii10086 +!E5 U+0445 afii10087 +!E6 U+0446 afii10088 +!E7 U+0447 afii10089 +!E8 U+0448 afii10090 +!E9 U+0449 afii10091 +!EA U+044A afii10092 +!EB U+044B afii10093 +!EC U+044C afii10094 +!ED U+044D afii10095 +!EE U+044E afii10096 +!EF U+044F afii10097 +!F0 U+2116 afii61352 +!F1 U+0451 afii10071 +!F2 U+0452 afii10099 +!F3 U+0453 afii10100 +!F4 U+0454 afii10101 +!F5 U+0455 afii10102 +!F6 U+0456 afii10103 +!F7 U+0457 afii10104 +!F8 U+0458 afii10105 +!F9 U+0459 afii10106 +!FA U+045A afii10107 +!FB U+045B afii10108 +!FC U+045C afii10109 +!FD U+00A7 section +!FE U+045E afii10110 +!FF U+045F afii10193 diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-7.map b/vendor/phenx/php-font-lib/maps/iso-8859-7.map new file mode 100644 index 0000000..e163796 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-7.map @@ -0,0 +1,250 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+2018 quoteleft +!A2 U+2019 quoteright +!A3 U+00A3 sterling +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AF U+2015 afii00208 +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+0384 tonos +!B5 U+0385 dieresistonos +!B6 U+0386 Alphatonos +!B7 U+00B7 periodcentered +!B8 U+0388 Epsilontonos +!B9 U+0389 Etatonos +!BA U+038A Iotatonos +!BB U+00BB guillemotright +!BC U+038C Omicrontonos +!BD U+00BD onehalf +!BE U+038E Upsilontonos +!BF U+038F Omegatonos +!C0 U+0390 iotadieresistonos +!C1 U+0391 Alpha +!C2 U+0392 Beta +!C3 U+0393 Gamma +!C4 U+0394 Delta +!C5 U+0395 Epsilon +!C6 U+0396 Zeta +!C7 U+0397 Eta +!C8 U+0398 Theta +!C9 U+0399 Iota +!CA U+039A Kappa +!CB U+039B Lambda +!CC U+039C Mu +!CD U+039D Nu +!CE U+039E Xi +!CF U+039F Omicron +!D0 U+03A0 Pi +!D1 U+03A1 Rho +!D3 U+03A3 Sigma +!D4 U+03A4 Tau +!D5 U+03A5 Upsilon +!D6 U+03A6 Phi +!D7 U+03A7 Chi +!D8 U+03A8 Psi +!D9 U+03A9 Omega +!DA U+03AA Iotadieresis +!DB U+03AB Upsilondieresis +!DC U+03AC alphatonos +!DD U+03AD epsilontonos +!DE U+03AE etatonos +!DF U+03AF iotatonos +!E0 U+03B0 upsilondieresistonos +!E1 U+03B1 alpha +!E2 U+03B2 beta +!E3 U+03B3 gamma +!E4 U+03B4 delta +!E5 U+03B5 epsilon +!E6 U+03B6 zeta +!E7 U+03B7 eta +!E8 U+03B8 theta +!E9 U+03B9 iota +!EA U+03BA kappa +!EB U+03BB lambda +!EC U+03BC mu +!ED U+03BD nu +!EE U+03BE xi +!EF U+03BF omicron +!F0 U+03C0 pi +!F1 U+03C1 rho +!F2 U+03C2 sigma1 +!F3 U+03C3 sigma +!F4 U+03C4 tau +!F5 U+03C5 upsilon +!F6 U+03C6 phi +!F7 U+03C7 chi +!F8 U+03C8 psi +!F9 U+03C9 omega +!FA U+03CA iotadieresis +!FB U+03CB upsilondieresis +!FC U+03CC omicrontonos +!FD U+03CD upsilontonos +!FE U+03CE omegatonos diff --git a/vendor/phenx/php-font-lib/maps/iso-8859-9.map b/vendor/phenx/php-font-lib/maps/iso-8859-9.map new file mode 100644 index 0000000..48c123a --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/iso-8859-9.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+0080 .notdef +!81 U+0081 .notdef +!82 U+0082 .notdef +!83 U+0083 .notdef +!84 U+0084 .notdef +!85 U+0085 .notdef +!86 U+0086 .notdef +!87 U+0087 .notdef +!88 U+0088 .notdef +!89 U+0089 .notdef +!8A U+008A .notdef +!8B U+008B .notdef +!8C U+008C .notdef +!8D U+008D .notdef +!8E U+008E .notdef +!8F U+008F .notdef +!90 U+0090 .notdef +!91 U+0091 .notdef +!92 U+0092 .notdef +!93 U+0093 .notdef +!94 U+0094 .notdef +!95 U+0095 .notdef +!96 U+0096 .notdef +!97 U+0097 .notdef +!98 U+0098 .notdef +!99 U+0099 .notdef +!9A U+009A .notdef +!9B U+009B .notdef +!9C U+009C .notdef +!9D U+009D .notdef +!9E U+009E .notdef +!9F U+009F .notdef +!A0 U+00A0 space +!A1 U+00A1 exclamdown +!A2 U+00A2 cent +!A3 U+00A3 sterling +!A4 U+00A4 currency +!A5 U+00A5 yen +!A6 U+00A6 brokenbar +!A7 U+00A7 section +!A8 U+00A8 dieresis +!A9 U+00A9 copyright +!AA U+00AA ordfeminine +!AB U+00AB guillemotleft +!AC U+00AC logicalnot +!AD U+00AD hyphen +!AE U+00AE registered +!AF U+00AF macron +!B0 U+00B0 degree +!B1 U+00B1 plusminus +!B2 U+00B2 twosuperior +!B3 U+00B3 threesuperior +!B4 U+00B4 acute +!B5 U+00B5 mu +!B6 U+00B6 paragraph +!B7 U+00B7 periodcentered +!B8 U+00B8 cedilla +!B9 U+00B9 onesuperior +!BA U+00BA ordmasculine +!BB U+00BB guillemotright +!BC U+00BC onequarter +!BD U+00BD onehalf +!BE U+00BE threequarters +!BF U+00BF questiondown +!C0 U+00C0 Agrave +!C1 U+00C1 Aacute +!C2 U+00C2 Acircumflex +!C3 U+00C3 Atilde +!C4 U+00C4 Adieresis +!C5 U+00C5 Aring +!C6 U+00C6 AE +!C7 U+00C7 Ccedilla +!C8 U+00C8 Egrave +!C9 U+00C9 Eacute +!CA U+00CA Ecircumflex +!CB U+00CB Edieresis +!CC U+00CC Igrave +!CD U+00CD Iacute +!CE U+00CE Icircumflex +!CF U+00CF Idieresis +!D0 U+011E Gbreve +!D1 U+00D1 Ntilde +!D2 U+00D2 Ograve +!D3 U+00D3 Oacute +!D4 U+00D4 Ocircumflex +!D5 U+00D5 Otilde +!D6 U+00D6 Odieresis +!D7 U+00D7 multiply +!D8 U+00D8 Oslash +!D9 U+00D9 Ugrave +!DA U+00DA Uacute +!DB U+00DB Ucircumflex +!DC U+00DC Udieresis +!DD U+0130 Idotaccent +!DE U+015E Scedilla +!DF U+00DF germandbls +!E0 U+00E0 agrave +!E1 U+00E1 aacute +!E2 U+00E2 acircumflex +!E3 U+00E3 atilde +!E4 U+00E4 adieresis +!E5 U+00E5 aring +!E6 U+00E6 ae +!E7 U+00E7 ccedilla +!E8 U+00E8 egrave +!E9 U+00E9 eacute +!EA U+00EA ecircumflex +!EB U+00EB edieresis +!EC U+00EC igrave +!ED U+00ED iacute +!EE U+00EE icircumflex +!EF U+00EF idieresis +!F0 U+011F gbreve +!F1 U+00F1 ntilde +!F2 U+00F2 ograve +!F3 U+00F3 oacute +!F4 U+00F4 ocircumflex +!F5 U+00F5 otilde +!F6 U+00F6 odieresis +!F7 U+00F7 divide +!F8 U+00F8 oslash +!F9 U+00F9 ugrave +!FA U+00FA uacute +!FB U+00FB ucircumflex +!FC U+00FC udieresis +!FD U+0131 dotlessi +!FE U+015F scedilla +!FF U+00FF ydieresis diff --git a/vendor/phenx/php-font-lib/maps/koi8-r.map b/vendor/phenx/php-font-lib/maps/koi8-r.map new file mode 100644 index 0000000..6ad5d05 --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/koi8-r.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2219 periodcentered +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+2553 SF520000 +!A5 U+2554 SF390000 +!A6 U+2555 SF220000 +!A7 U+2556 SF210000 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+255C SF270000 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+2562 SF200000 +!B5 U+2563 SF230000 +!B6 U+2564 SF470000 +!B7 U+2565 SF480000 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+256B SF530000 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/vendor/phenx/php-font-lib/maps/koi8-u.map b/vendor/phenx/php-font-lib/maps/koi8-u.map new file mode 100644 index 0000000..40a7e4f --- /dev/null +++ b/vendor/phenx/php-font-lib/maps/koi8-u.map @@ -0,0 +1,256 @@ +!00 U+0000 .notdef +!01 U+0001 .notdef +!02 U+0002 .notdef +!03 U+0003 .notdef +!04 U+0004 .notdef +!05 U+0005 .notdef +!06 U+0006 .notdef +!07 U+0007 .notdef +!08 U+0008 .notdef +!09 U+0009 .notdef +!0A U+000A .notdef +!0B U+000B .notdef +!0C U+000C .notdef +!0D U+000D .notdef +!0E U+000E .notdef +!0F U+000F .notdef +!10 U+0010 .notdef +!11 U+0011 .notdef +!12 U+0012 .notdef +!13 U+0013 .notdef +!14 U+0014 .notdef +!15 U+0015 .notdef +!16 U+0016 .notdef +!17 U+0017 .notdef +!18 U+0018 .notdef +!19 U+0019 .notdef +!1A U+001A .notdef +!1B U+001B .notdef +!1C U+001C .notdef +!1D U+001D .notdef +!1E U+001E .notdef +!1F U+001F .notdef +!20 U+0020 space +!21 U+0021 exclam +!22 U+0022 quotedbl +!23 U+0023 numbersign +!24 U+0024 dollar +!25 U+0025 percent +!26 U+0026 ampersand +!27 U+0027 quotesingle +!28 U+0028 parenleft +!29 U+0029 parenright +!2A U+002A asterisk +!2B U+002B plus +!2C U+002C comma +!2D U+002D hyphen +!2E U+002E period +!2F U+002F slash +!30 U+0030 zero +!31 U+0031 one +!32 U+0032 two +!33 U+0033 three +!34 U+0034 four +!35 U+0035 five +!36 U+0036 six +!37 U+0037 seven +!38 U+0038 eight +!39 U+0039 nine +!3A U+003A colon +!3B U+003B semicolon +!3C U+003C less +!3D U+003D equal +!3E U+003E greater +!3F U+003F question +!40 U+0040 at +!41 U+0041 A +!42 U+0042 B +!43 U+0043 C +!44 U+0044 D +!45 U+0045 E +!46 U+0046 F +!47 U+0047 G +!48 U+0048 H +!49 U+0049 I +!4A U+004A J +!4B U+004B K +!4C U+004C L +!4D U+004D M +!4E U+004E N +!4F U+004F O +!50 U+0050 P +!51 U+0051 Q +!52 U+0052 R +!53 U+0053 S +!54 U+0054 T +!55 U+0055 U +!56 U+0056 V +!57 U+0057 W +!58 U+0058 X +!59 U+0059 Y +!5A U+005A Z +!5B U+005B bracketleft +!5C U+005C backslash +!5D U+005D bracketright +!5E U+005E asciicircum +!5F U+005F underscore +!60 U+0060 grave +!61 U+0061 a +!62 U+0062 b +!63 U+0063 c +!64 U+0064 d +!65 U+0065 e +!66 U+0066 f +!67 U+0067 g +!68 U+0068 h +!69 U+0069 i +!6A U+006A j +!6B U+006B k +!6C U+006C l +!6D U+006D m +!6E U+006E n +!6F U+006F o +!70 U+0070 p +!71 U+0071 q +!72 U+0072 r +!73 U+0073 s +!74 U+0074 t +!75 U+0075 u +!76 U+0076 v +!77 U+0077 w +!78 U+0078 x +!79 U+0079 y +!7A U+007A z +!7B U+007B braceleft +!7C U+007C bar +!7D U+007D braceright +!7E U+007E asciitilde +!7F U+007F .notdef +!80 U+2500 SF100000 +!81 U+2502 SF110000 +!82 U+250C SF010000 +!83 U+2510 SF030000 +!84 U+2514 SF020000 +!85 U+2518 SF040000 +!86 U+251C SF080000 +!87 U+2524 SF090000 +!88 U+252C SF060000 +!89 U+2534 SF070000 +!8A U+253C SF050000 +!8B U+2580 upblock +!8C U+2584 dnblock +!8D U+2588 block +!8E U+258C lfblock +!8F U+2590 rtblock +!90 U+2591 ltshade +!91 U+2592 shade +!92 U+2593 dkshade +!93 U+2320 integraltp +!94 U+25A0 filledbox +!95 U+2022 bullet +!96 U+221A radical +!97 U+2248 approxequal +!98 U+2264 lessequal +!99 U+2265 greaterequal +!9A U+00A0 space +!9B U+2321 integralbt +!9C U+00B0 degree +!9D U+00B2 twosuperior +!9E U+00B7 periodcentered +!9F U+00F7 divide +!A0 U+2550 SF430000 +!A1 U+2551 SF240000 +!A2 U+2552 SF510000 +!A3 U+0451 afii10071 +!A4 U+0454 afii10101 +!A5 U+2554 SF390000 +!A6 U+0456 afii10103 +!A7 U+0457 afii10104 +!A8 U+2557 SF250000 +!A9 U+2558 SF500000 +!AA U+2559 SF490000 +!AB U+255A SF380000 +!AC U+255B SF280000 +!AD U+0491 afii10098 +!AE U+255D SF260000 +!AF U+255E SF360000 +!B0 U+255F SF370000 +!B1 U+2560 SF420000 +!B2 U+2561 SF190000 +!B3 U+0401 afii10023 +!B4 U+0404 afii10053 +!B5 U+2563 SF230000 +!B6 U+0406 afii10055 +!B7 U+0407 afii10056 +!B8 U+2566 SF410000 +!B9 U+2567 SF450000 +!BA U+2568 SF460000 +!BB U+2569 SF400000 +!BC U+256A SF540000 +!BD U+0490 afii10050 +!BE U+256C SF440000 +!BF U+00A9 copyright +!C0 U+044E afii10096 +!C1 U+0430 afii10065 +!C2 U+0431 afii10066 +!C3 U+0446 afii10088 +!C4 U+0434 afii10069 +!C5 U+0435 afii10070 +!C6 U+0444 afii10086 +!C7 U+0433 afii10068 +!C8 U+0445 afii10087 +!C9 U+0438 afii10074 +!CA U+0439 afii10075 +!CB U+043A afii10076 +!CC U+043B afii10077 +!CD U+043C afii10078 +!CE U+043D afii10079 +!CF U+043E afii10080 +!D0 U+043F afii10081 +!D1 U+044F afii10097 +!D2 U+0440 afii10082 +!D3 U+0441 afii10083 +!D4 U+0442 afii10084 +!D5 U+0443 afii10085 +!D6 U+0436 afii10072 +!D7 U+0432 afii10067 +!D8 U+044C afii10094 +!D9 U+044B afii10093 +!DA U+0437 afii10073 +!DB U+0448 afii10090 +!DC U+044D afii10095 +!DD U+0449 afii10091 +!DE U+0447 afii10089 +!DF U+044A afii10092 +!E0 U+042E afii10048 +!E1 U+0410 afii10017 +!E2 U+0411 afii10018 +!E3 U+0426 afii10040 +!E4 U+0414 afii10021 +!E5 U+0415 afii10022 +!E6 U+0424 afii10038 +!E7 U+0413 afii10020 +!E8 U+0425 afii10039 +!E9 U+0418 afii10026 +!EA U+0419 afii10027 +!EB U+041A afii10028 +!EC U+041B afii10029 +!ED U+041C afii10030 +!EE U+041D afii10031 +!EF U+041E afii10032 +!F0 U+041F afii10033 +!F1 U+042F afii10049 +!F2 U+0420 afii10034 +!F3 U+0421 afii10035 +!F4 U+0422 afii10036 +!F5 U+0423 afii10037 +!F6 U+0416 afii10024 +!F7 U+0412 afii10019 +!F8 U+042C afii10046 +!F9 U+042B afii10045 +!FA U+0417 afii10025 +!FB U+0428 afii10042 +!FC U+042D afii10047 +!FD U+0429 afii10043 +!FE U+0427 afii10041 +!FF U+042A afii10044 diff --git a/vendor/phenx/php-font-lib/phpunit.xml.dist b/vendor/phenx/php-font-lib/phpunit.xml.dist new file mode 100644 index 0000000..c8bb022 --- /dev/null +++ b/vendor/phenx/php-font-lib/phpunit.xml.dist @@ -0,0 +1,19 @@ + + + + + + ./tests/FontLib/ + + + + \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/sample-fonts/IntelClear-Light.ttf b/vendor/phenx/php-font-lib/sample-fonts/IntelClear-Light.ttf new file mode 100644 index 0000000000000000000000000000000000000000..17451c6ace3fe61452ab4bed60c03e6856873260 GIT binary patch literal 96664 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 literal 0 HcmV?d00001 diff --git a/vendor/phenx/php-font-lib/sample-fonts/NotoSansShavian-Regular.ttf b/vendor/phenx/php-font-lib/sample-fonts/NotoSansShavian-Regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..29ebdb5fc2c77895ea77bb7697e462467177b1ea GIT binary patch literal 6020 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 + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +use FontLib\Table\Type\name; +use FontLib\TrueType\File; + +/** + * Adobe Font Metrics file creation utility class. + * + * @package php-font-lib + */ +class AdobeFontMetrics { + private $f; + + /** + * @var File + */ + private $font; + + function __construct(File $font) { + $this->font = $font; + } + + function write($file, $encoding = null) { + $map_data = array(); + + if ($encoding) { + $encoding = preg_replace("/[^a-z0-9-_]/", "", $encoding); + $map_file = dirname(__FILE__) . "/../maps/$encoding.map"; + if (!file_exists($map_file)) { + throw new \Exception("Unkown encoding ($encoding)"); + } + + $map = new EncodingMap($map_file); + $map_data = $map->parse(); + } + + $this->f = fopen($file, "w+"); + + $font = $this->font; + + $this->startSection("FontMetrics", 4.1); + $this->addPair("Notice", "Converted by PHP-font-lib"); + $this->addPair("Comment", "https://github.com/PhenX/php-font-lib"); + + $encoding_scheme = ($encoding ? $encoding : "FontSpecific"); + $this->addPair("EncodingScheme", $encoding_scheme); + + $records = $font->getData("name", "records"); + foreach ($records as $id => $record) { + if (!isset(name::$nameIdCodes[$id]) || preg_match("/[\r\n]/", $record->string)) { + continue; + } + + $this->addPair(name::$nameIdCodes[$id], $record->string); + } + + $os2 = $font->getData("OS/2"); + $this->addPair("Weight", ($os2["usWeightClass"] > 400 ? "Bold" : "Medium")); + + $post = $font->getData("post"); + $this->addPair("ItalicAngle", $post["italicAngle"]); + $this->addPair("IsFixedPitch", ($post["isFixedPitch"] ? "true" : "false")); + $this->addPair("UnderlineThickness", $font->normalizeFUnit($post["underlineThickness"])); + $this->addPair("UnderlinePosition", $font->normalizeFUnit($post["underlinePosition"])); + + $hhea = $font->getData("hhea"); + + if (isset($hhea["ascent"])) { + $this->addPair("FontHeightOffset", $font->normalizeFUnit($hhea["lineGap"])); + $this->addPair("Ascender", $font->normalizeFUnit($hhea["ascent"])); + $this->addPair("Descender", $font->normalizeFUnit($hhea["descent"])); + } + else { + $this->addPair("FontHeightOffset", $font->normalizeFUnit($os2["typoLineGap"])); + $this->addPair("Ascender", $font->normalizeFUnit($os2["typoAscender"])); + $this->addPair("Descender", -abs($font->normalizeFUnit($os2["typoDescender"]))); + } + + $head = $font->getData("head"); + $this->addArray("FontBBox", array( + $font->normalizeFUnit($head["xMin"]), + $font->normalizeFUnit($head["yMin"]), + $font->normalizeFUnit($head["xMax"]), + $font->normalizeFUnit($head["yMax"]), + )); + + $glyphIndexArray = $font->getUnicodeCharMap(); + + if ($glyphIndexArray) { + $hmtx = $font->getData("hmtx"); + $names = $font->getData("post", "names"); + + $this->startSection("CharMetrics", count($hmtx)); + + if ($encoding) { + foreach ($map_data as $code => $value) { + list($c, $name) = $value; + + if (!isset($glyphIndexArray[$c])) { + continue; + } + + $g = $glyphIndexArray[$c]; + + if (!isset($hmtx[$g])) { + $hmtx[$g] = $hmtx[0]; + } + + $this->addMetric(array( + "C" => ($code > 255 ? -1 : $code), + "WX" => $font->normalizeFUnit($hmtx[$g][0]), + "N" => $name, + )); + } + } + else { + foreach ($glyphIndexArray as $c => $g) { + if (!isset($hmtx[$g])) { + $hmtx[$g] = $hmtx[0]; + } + + $this->addMetric(array( + "U" => $c, + "WX" => $font->normalizeFUnit($hmtx[$g][0]), + "N" => (isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $c)), + "G" => $g, + )); + } + } + + $this->endSection("CharMetrics"); + + $kern = $font->getData("kern", "subtable"); + $tree = is_array($kern) ? $kern["tree"] : null; + + if (!$encoding && is_array($tree)) { + $this->startSection("KernData"); + $this->startSection("KernPairs", count($tree, COUNT_RECURSIVE) - count($tree)); + + foreach ($tree as $left => $values) { + if (!is_array($values)) { + continue; + } + if (!isset($glyphIndexArray[$left])) { + continue; + } + + $left_gid = $glyphIndexArray[$left]; + + if (!isset($names[$left_gid])) { + continue; + } + + $left_name = $names[$left_gid]; + + $this->addLine(""); + + foreach ($values as $right => $value) { + if (!isset($glyphIndexArray[$right])) { + continue; + } + + $right_gid = $glyphIndexArray[$right]; + + if (!isset($names[$right_gid])) { + continue; + } + + $right_name = $names[$right_gid]; + $this->addPair("KPX", "$left_name $right_name $value"); + } + } + + $this->endSection("KernPairs"); + $this->endSection("KernData"); + } + } + + $this->endSection("FontMetrics"); + } + + function addLine($line) { + fwrite($this->f, "$line\n"); + } + + function addPair($key, $value) { + $this->addLine("$key $value"); + } + + function addArray($key, $array) { + $this->addLine("$key " . implode(" ", $array)); + } + + function addMetric($data) { + $array = array(); + foreach ($data as $key => $value) { + $array[] = "$key $value"; + } + $this->addLine(implode(" ; ", $array)); + } + + function startSection($name, $value = "") { + $this->addLine("Start$name $value"); + } + + function endSection($name) { + $this->addLine("End$name"); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php b/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php new file mode 100644 index 0000000..cd30545 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Autoloader.php @@ -0,0 +1,43 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Autoloads FontLib classes + * + * @package php-font-lib + */ +class Autoloader { + const PREFIX = 'FontLib'; + + /** + * Register the autoloader + */ + public static function register() { + spl_autoload_register(array(new self, 'autoload')); + } + + /** + * Autoloader + * + * @param string + */ + public static function autoload($class) { + $prefixLength = strlen(self::PREFIX); + if (0 === strncmp(self::PREFIX, $class, $prefixLength)) { + $file = str_replace('\\', DIRECTORY_SEPARATOR, substr($class, $prefixLength)); + $file = realpath(__DIR__ . (empty($file) ? '' : DIRECTORY_SEPARATOR) . $file . '.php'); + if (file_exists($file)) { + require_once $file; + } + } + } +} + +Autoloader::register(); \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php b/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php new file mode 100644 index 0000000..ab10454 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/BinaryStream.php @@ -0,0 +1,444 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Generic font file binary stream. + * + * @package php-font-lib + */ +class BinaryStream { + /** + * @var resource The file pointer + */ + protected $f; + + const uint8 = 1; + const int8 = 2; + const uint16 = 3; + const int16 = 4; + const uint32 = 5; + const int32 = 6; + const shortFrac = 7; + const Fixed = 8; + const FWord = 9; + const uFWord = 10; + const F2Dot14 = 11; + const longDateTime = 12; + const char = 13; + + const modeRead = "rb"; + const modeWrite = "wb"; + const modeReadWrite = "rb+"; + + static function backtrace() { + var_dump(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)); + } + + /** + * Open a font file in read mode + * + * @param string $filename The file name of the font to open + * + * @return bool + */ + public function load($filename) { + return $this->open($filename, self::modeRead); + } + + /** + * Open a font file in a chosen mode + * + * @param string $filename The file name of the font to open + * @param string $mode The opening mode + * + * @throws \Exception + * @return bool + */ + public function open($filename, $mode = self::modeRead) { + if (!in_array($mode, array(self::modeRead, self::modeWrite, self::modeReadWrite))) { + throw new \Exception("Unkown file open mode"); + } + + $this->f = fopen($filename, $mode); + + return $this->f != false; + } + + /** + * Close the internal file pointer + */ + public function close() { + return fclose($this->f) != false; + } + + /** + * Change the internal file pointer + * + * @param resource $fp + * + * @throws \Exception + */ + public function setFile($fp) { + if (!is_resource($fp)) { + throw new \Exception('$fp is not a valid resource'); + } + + $this->f = $fp; + } + + /** + * Create a temporary file in write mode + * + * @param bool $allow_memory Allow in-memory files + * + * @return resource the temporary file pointer resource + */ + public static function getTempFile($allow_memory = true) { + $f = null; + + if ($allow_memory) { + $f = fopen("php://temp", "rb+"); + } + else { + $f = fopen(tempnam(sys_get_temp_dir(), "fnt"), "rb+"); + } + + return $f; + } + + /** + * Move the internal file pinter to $offset bytes + * + * @param int $offset + * + * @return bool True if the $offset position exists in the file + */ + public function seek($offset) { + return fseek($this->f, $offset, SEEK_SET) == 0; + } + + /** + * Gives the current position in the file + * + * @return int The current position + */ + public function pos() { + return ftell($this->f); + } + + public function skip($n) { + fseek($this->f, $n, SEEK_CUR); + } + + public function read($n) { + if ($n < 1) { + return ""; + } + + return fread($this->f, $n); + } + + public function write($data, $length = null) { + if ($data === null || $data === "" || $data === false) { + return 0; + } + + return fwrite($this->f, $data, $length); + } + + public function readUInt8() { + return ord($this->read(1)); + } + + public function readUInt8Many($count) { + return array_values(unpack("C*", $this->read($count))); + } + + public function writeUInt8($data) { + return $this->write(chr($data), 1); + } + + public function readInt8() { + $v = $this->readUInt8(); + + if ($v >= 0x80) { + $v -= 0x100; + } + + return $v; + } + + public function readInt8Many($count) { + return array_values(unpack("c*", $this->read($count))); + } + + public function writeInt8($data) { + if ($data < 0) { + $data += 0x100; + } + + return $this->writeUInt8($data); + } + + public function readUInt16() { + $a = unpack("nn", $this->read(2)); + + return $a["n"]; + } + + public function readUInt16Many($count) { + return array_values(unpack("n*", $this->read($count * 2))); + } + + public function readUFWord() { + return $this->readUInt16(); + } + + public function writeUInt16($data) { + return $this->write(pack("n", $data), 2); + } + + public function writeUFWord($data) { + return $this->writeUInt16($data); + } + + public function readInt16() { + $a = unpack("nn", $this->read(2)); + $v = $a["n"]; + + if ($v >= 0x8000) { + $v -= 0x10000; + } + + return $v; + } + + public function readInt16Many($count) { + $vals = array_values(unpack("n*", $this->read($count * 2))); + foreach ($vals as &$v) { + if ($v >= 0x8000) { + $v -= 0x10000; + } + } + + return $vals; + } + + public function readFWord() { + return $this->readInt16(); + } + + public function writeInt16($data) { + if ($data < 0) { + $data += 0x10000; + } + + return $this->writeUInt16($data); + } + + public function writeFWord($data) { + return $this->writeInt16($data); + } + + public function readUInt32() { + $a = unpack("NN", $this->read(4)); + + return $a["N"]; + } + + public function writeUInt32($data) { + return $this->write(pack("N", $data), 4); + } + + public function readFixed() { + $d = $this->readInt16(); + $d2 = $this->readUInt16(); + + return round($d + $d2 / 0x10000, 4); + } + + public function writeFixed($data) { + $left = floor($data); + $right = ($data - $left) * 0x10000; + + return $this->writeInt16($left) + $this->writeUInt16($right); + } + + public function readLongDateTime() { + $this->readUInt32(); // ignored + $date = $this->readUInt32() - 2082844800; + + # PHP_INT_MIN isn't defined in PHP < 7.0 + $php_int_min = defined("PHP_INT_MIN") ? PHP_INT_MIN : ~PHP_INT_MAX; + + if (is_string($date) || $date > PHP_INT_MAX || $date < $php_int_min) { + $date = 0; + } + + return strftime("%Y-%m-%d %H:%M:%S", $date); + } + + public function writeLongDateTime($data) { + $date = strtotime($data); + $date += 2082844800; + + return $this->writeUInt32(0) + $this->writeUInt32($date); + } + + public function unpack($def) { + $d = array(); + foreach ($def as $name => $type) { + $d[$name] = $this->r($type); + } + + return $d; + } + + public function pack($def, $data) { + $bytes = 0; + foreach ($def as $name => $type) { + $bytes += $this->w($type, $data[$name]); + } + + return $bytes; + } + + /** + * Read a data of type $type in the file from the current position + * + * @param mixed $type The data type to read + * + * @return mixed The data that was read + */ + public function r($type) { + switch ($type) { + case self::uint8: + return $this->readUInt8(); + case self::int8: + return $this->readInt8(); + case self::uint16: + return $this->readUInt16(); + case self::int16: + return $this->readInt16(); + case self::uint32: + return $this->readUInt32(); + case self::int32: + return $this->readUInt32(); + case self::shortFrac: + return $this->readFixed(); + case self::Fixed: + return $this->readFixed(); + case self::FWord: + return $this->readInt16(); + case self::uFWord: + return $this->readUInt16(); + case self::F2Dot14: + return $this->readInt16(); + case self::longDateTime: + return $this->readLongDateTime(); + case self::char: + return $this->read(1); + default: + if (is_array($type)) { + if ($type[0] == self::char) { + return $this->read($type[1]); + } + if ($type[0] == self::uint16) { + return $this->readUInt16Many($type[1]); + } + if ($type[0] == self::int16) { + return $this->readInt16Many($type[1]); + } + if ($type[0] == self::uint8) { + return $this->readUInt8Many($type[1]); + } + if ($type[0] == self::int8) { + return $this->readInt8Many($type[1]); + } + + $ret = array(); + for ($i = 0; $i < $type[1]; $i++) { + $ret[] = $this->r($type[0]); + } + + return $ret; + } + + return null; + } + } + + /** + * Write $data of type $type in the file from the current position + * + * @param mixed $type The data type to write + * @param mixed $data The data to write + * + * @return int The number of bytes read + */ + public function w($type, $data) { + switch ($type) { + case self::uint8: + return $this->writeUInt8($data); + case self::int8: + return $this->writeInt8($data); + case self::uint16: + return $this->writeUInt16($data); + case self::int16: + return $this->writeInt16($data); + case self::uint32: + return $this->writeUInt32($data); + case self::int32: + return $this->writeUInt32($data); + case self::shortFrac: + return $this->writeFixed($data); + case self::Fixed: + return $this->writeFixed($data); + case self::FWord: + return $this->writeInt16($data); + case self::uFWord: + return $this->writeUInt16($data); + case self::F2Dot14: + return $this->writeInt16($data); + case self::longDateTime: + return $this->writeLongDateTime($data); + case self::char: + return $this->write($data, 1); + default: + if (is_array($type)) { + if ($type[0] == self::char) { + return $this->write($data, $type[1]); + } + + $ret = 0; + for ($i = 0; $i < $type[1]; $i++) { + if (isset($data[$i])) { + $ret += $this->w($type[0], $data[$i]); + } + } + + return $ret; + } + + return null; + } + } + + /** + * Converts a Uint32 value to string + * + * @param int $uint32 + * + * @return string The string + */ + public function convertUInt32ToStr($uint32) { + return chr(($uint32 >> 24) & 0xFF) . chr(($uint32 >> 16) & 0xFF) . chr(($uint32 >> 8) & 0xFF) . chr($uint32 & 0xFF); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php b/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php new file mode 100644 index 0000000..13d5925 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EOT/File.php @@ -0,0 +1,160 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\EOT; + +/** + * EOT font file. + * + * @package php-font-lib + */ +class File extends \FontLib\TrueType\File { + const TTEMBED_SUBSET = 0x00000001; + const TTEMBED_TTCOMPRESSED = 0x00000004; + const TTEMBED_FAILIFVARIATIONSIMULATED = 0x00000010; + const TTMBED_EMBEDEUDC = 0x00000020; + const TTEMBED_VALIDATIONTESTS = 0x00000040; // Deprecated + const TTEMBED_WEBOBJECT = 0x00000080; + const TTEMBED_XORENCRYPTDATA = 0x10000000; + + /** + * @var Header + */ + public $header; + + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->header = new Header($this); + $this->header->parse(); + } + + function parse() { + $this->parseHeader(); + + $flags = $this->header->data["Flags"]; + + if ($flags & self::TTEMBED_TTCOMPRESSED) { + $mtx_version = $this->readUInt8(); + $mtx_copy_limit = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + $mtx_offset_1 = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + $mtx_offset_2 = $this->readUInt8() << 16 | $this->readUInt8() << 8 | $this->readUInt8(); + /* + var_dump("$mtx_version $mtx_copy_limit $mtx_offset_1 $mtx_offset_2"); + + $pos = $this->pos(); + $size = $mtx_offset_1 - $pos; + var_dump("pos: $pos"); + var_dump("size: $size");*/ + } + + if ($flags & self::TTEMBED_XORENCRYPTDATA) { + // Process XOR + } + // TODO Read font data ... + } + + /** + * Little endian version of the read method + * + * @param int $n The number of bytes to read + * + * @return string + */ + public function read($n) { + if ($n < 1) { + return ""; + } + + $string = fread($this->f, $n); + $chunks = str_split($string, 2); + $chunks = array_map("strrev", $chunks); + + return implode("", $chunks); + } + + public function readUInt32() { + $uint32 = parent::readUInt32(); + + return $uint32 >> 16 & 0x0000FFFF | $uint32 << 16 & 0xFFFF0000; + } + + /** + * Get font copyright + * + * @return string|null + */ + function getFontCopyright() { + return null; + } + + /** + * Get font name + * + * @return string|null + */ + function getFontName() { + return $this->header->data["FamilyName"]; + } + + /** + * Get font subfamily + * + * @return string|null + */ + function getFontSubfamily() { + return $this->header->data["StyleName"]; + } + + /** + * Get font subfamily ID + * + * @return string|null + */ + function getFontSubfamilyID() { + return $this->header->data["StyleName"]; + } + + /** + * Get font full name + * + * @return string|null + */ + function getFontFullName() { + return $this->header->data["FullName"]; + } + + /** + * Get font version + * + * @return string|null + */ + function getFontVersion() { + return $this->header->data["VersionName"]; + } + + /** + * Get font weight + * + * @return string|null + */ + function getFontWeight() { + return $this->header->data["Weight"]; + } + + /** + * Get font Postscript name + * + * @return string|null + */ + function getFontPostscriptName() { + return null; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php b/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php new file mode 100644 index 0000000..960e36a --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EOT/Header.php @@ -0,0 +1,113 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\EOT; + +use Exception; +use FontLib\Font; + +/** + * TrueType font file header. + * + * @package php-font-lib + * + * @property File $font + */ +class Header extends \FontLib\Header { + protected $def = array( + "format" => self::uint32, + "numTables" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + public function parse() { + $font = $this->font; + + $this->data = $font->unpack(array( + "EOTSize" => self::uint32, + "FontDataSize" => self::uint32, + "Version" => self::uint32, + "Flags" => self::uint32, + "FontPANOSE" => array(self::uint8, 10), + "Charset" => self::uint8, + "Italic" => self::uint8, + "Weight" => self::uint32, + "fsType" => self::uint16, + "MagicNumber" => self::uint16, + "UnicodeRange1" => self::uint32, + "UnicodeRange2" => self::uint32, + "UnicodeRange3" => self::uint32, + "UnicodeRange4" => self::uint32, + "CodePageRange1" => self::uint32, + "CodePageRange2" => self::uint32, + "CheckSumAdjustment" => self::uint32, + "Reserved1" => self::uint32, + "Reserved2" => self::uint32, + "Reserved3" => self::uint32, + "Reserved4" => self::uint32, + )); + + $this->data["Padding1"] = $font->readUInt16(); + $this->readString("FamilyName"); + + $this->data["Padding2"] = $font->readUInt16(); + $this->readString("StyleName"); + + $this->data["Padding3"] = $font->readUInt16(); + $this->readString("VersionName"); + + $this->data["Padding4"] = $font->readUInt16(); + $this->readString("FullName"); + + switch ($this->data["Version"]) { + default: + throw new Exception("Unknown EOT version " . $this->data["Version"]); + + case 0x00010000: + // Nothing to do more + break; + + case 0x00020001: + $this->data["Padding5"] = $font->readUInt16(); + $this->readString("RootString"); + break; + + case 0x00020002: + $this->data["Padding5"] = $font->readUInt16(); + $this->readString("RootString"); + + $this->data["RootStringCheckSum"] = $font->readUInt32(); + $this->data["EUDCCodePage"] = $font->readUInt32(); + + $this->data["Padding6"] = $font->readUInt16(); + $this->readString("Signature"); + + $this->data["EUDCFlags"] = $font->readUInt32(); + $this->data["EUDCFontSize"] = $font->readUInt32(); + break; + } + + if (!empty($this->data["RootString"])) { + $this->data["RootString"] = explode("\0", $this->data["RootString"]); + } + } + + private function readString($name) { + $font = $this->font; + $size = $font->readUInt16(); + + $this->data["{$name}Size"] = $size; + $this->data[$name] = Font::UTF16ToUTF8($font->read($size)); + } + + public function encode() { + //return $this->font->pack($this->def, $this->data); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php b/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php new file mode 100644 index 0000000..2acdebc --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/EncodingMap.php @@ -0,0 +1,37 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +/** + * Encoding map used to map a code point to a Unicode char. + * + * @package php-font-lib + */ +class EncodingMap { + private $f; + + function __construct($file) { + $this->f = fopen($file, "r"); + } + + function parse() { + $map = array(); + + while ($line = fgets($this->f)) { + if (preg_match('/^[\!\=]([0-9A-F]{2,})\s+U\+([0-9A-F]{2})([0-9A-F]{2})\s+([^\s]+)/', $line, $matches)) { + $unicode = (hexdec($matches[2]) << 8) + hexdec($matches[3]); + $map[hexdec($matches[1])] = array($unicode, $matches[4]); + } + } + + ksort($map); + + return $map; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php b/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php new file mode 100644 index 0000000..d97f252 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Exception/FontNotFoundException.php @@ -0,0 +1,11 @@ +message = 'Font not found in: ' . $fontPath; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Font.php b/vendor/phenx/php-font-lib/src/FontLib/Font.php new file mode 100644 index 0000000..ecc216e --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Font.php @@ -0,0 +1,89 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib; + +use FontLib\Exception\FontNotFoundException; + +/** + * Generic font file. + * + * @package php-font-lib + */ +class Font { + static $debug = false; + + /** + * @param string $file The font file + * + * @return TrueType\File|null $file + */ + public static function load($file) { + if(!file_exists($file)){ + throw new FontNotFoundException($file); + } + + $header = file_get_contents($file, false, null, null, 4); + $class = null; + + switch ($header) { + case "\x00\x01\x00\x00": + case "true": + case "typ1": + $class = "TrueType\\File"; + break; + + case "OTTO": + $class = "OpenType\\File"; + break; + + case "wOFF": + $class = "WOFF\\File"; + break; + + case "ttcf": + $class = "TrueType\\Collection"; + break; + + // Unknown type or EOT + default: + $magicNumber = file_get_contents($file, false, null, 34, 2); + + if ($magicNumber === "LP") { + $class = "EOT\\File"; + } + } + + if ($class) { + $class = "FontLib\\$class"; + + /** @var TrueType\File $obj */ + $obj = new $class; + $obj->load($file); + + return $obj; + } + + return null; + } + + static function d($str) { + if (!self::$debug) { + return; + } + echo "$str\n"; + } + + static function UTF16ToUTF8($str) { + return mb_convert_encoding($str, "utf-8", "utf-16"); + } + + static function UTF8ToUTF16($str) { + return mb_convert_encoding($str, "utf-16", "utf-8"); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php new file mode 100644 index 0000000..330db09 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/Outline.php @@ -0,0 +1,110 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ +namespace FontLib\Glyph; + +use FontLib\Table\Type\glyf; +use FontLib\TrueType\File; +use FontLib\BinaryStream; + +/** + * `glyf` font table. + * + * @package php-font-lib + */ +class Outline extends BinaryStream { + /** + * @var \FontLib\Table\Type\glyf + */ + protected $table; + + protected $offset; + protected $size; + + // Data + public $numberOfContours; + public $xMin; + public $yMin; + public $xMax; + public $yMax; + + public $raw; + + /** + * @param glyf $table + * @param $offset + * @param $size + * + * @return Outline + */ + static function init(glyf $table, $offset, $size, BinaryStream $font) { + $font->seek($offset); + + if ($font->readInt16() > -1) { + /** @var OutlineSimple $glyph */ + $glyph = new OutlineSimple($table, $offset, $size); + } + else { + /** @var OutlineComposite $glyph */ + $glyph = new OutlineComposite($table, $offset, $size); + } + + $glyph->parse($font); + + return $glyph; + } + + /** + * @return File + */ + function getFont() { + return $this->table->getFont(); + } + + function __construct(glyf $table, $offset = null, $size = null) { + $this->table = $table; + $this->offset = $offset; + $this->size = $size; + } + + function parse(BinaryStream $font) { + $font->seek($this->offset); + + if (!$this->size) { + return; + } + + $this->raw = $font->read($this->size); + } + + function parseData() { + $font = $this->getFont(); + $font->seek($this->offset); + + $this->numberOfContours = $font->readInt16(); + $this->xMin = $font->readFWord(); + $this->yMin = $font->readFWord(); + $this->xMax = $font->readFWord(); + $this->yMax = $font->readFWord(); + } + + function encode() { + $font = $this->getFont(); + + return $font->write($this->raw, strlen($this->raw)); + } + + function getSVGContours() { + // Inherit + } + + function getGlyphIDs() { + return array(); + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php new file mode 100644 index 0000000..9cafaf4 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComponent.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; +/** + * Glyph outline component + * + * @package php-font-lib + */ +class OutlineComponent { + public $flags; + public $glyphIndex; + public $a, $b, $c, $d, $e, $f; + public $point_compound; + public $point_component; + public $instructions; + + function getMatrix() { + return array( + $this->a, $this->b, + $this->c, $this->d, + $this->e, $this->f, + ); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php new file mode 100644 index 0000000..8ab0d2c --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineComposite.php @@ -0,0 +1,242 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; + +/** + * Composite glyph outline + * + * @package php-font-lib + */ +class OutlineComposite extends Outline { + const ARG_1_AND_2_ARE_WORDS = 0x0001; + const ARGS_ARE_XY_VALUES = 0x0002; + const ROUND_XY_TO_GRID = 0x0004; + const WE_HAVE_A_SCALE = 0x0008; + const MORE_COMPONENTS = 0x0020; + const WE_HAVE_AN_X_AND_Y_SCALE = 0x0040; + const WE_HAVE_A_TWO_BY_TWO = 0x0080; + const WE_HAVE_INSTRUCTIONS = 0x0100; + const USE_MY_METRICS = 0x0200; + const OVERLAP_COMPOUND = 0x0400; + + /** + * @var OutlineComponent[] + */ + public $components = array(); + + function getGlyphIDs() { + if (empty($this->components)) { + $this->parseData(); + } + + $glyphIDs = array(); + foreach ($this->components as $_component) { + $glyphIDs[] = $_component->glyphIndex; + + $_glyph = $this->table->data[$_component->glyphIndex]; + + if ($_glyph !== $this) { + $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs()); + } + } + + return $glyphIDs; + } + + /*function parse() { + //$this->parseData(); + }*/ + + function parseData() { + parent::parseData(); + + $font = $this->getFont(); + + do { + $flags = $font->readUInt16(); + $glyphIndex = $font->readUInt16(); + + $a = 1.0; + $b = 0.0; + $c = 0.0; + $d = 1.0; + $e = 0.0; + $f = 0.0; + + $point_compound = null; + $point_component = null; + + $instructions = null; + + if ($flags & self::ARG_1_AND_2_ARE_WORDS) { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $e = $font->readInt16(); + $f = $font->readInt16(); + } + else { + $point_compound = $font->readUInt16(); + $point_component = $font->readUInt16(); + } + } + else { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $e = $font->readInt8(); + $f = $font->readInt8(); + } + else { + $point_compound = $font->readUInt8(); + $point_component = $font->readUInt8(); + } + } + + if ($flags & self::WE_HAVE_A_SCALE) { + $a = $d = $font->readInt16(); + } + elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { + $a = $font->readInt16(); + $d = $font->readInt16(); + } + elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { + $a = $font->readInt16(); + $b = $font->readInt16(); + $c = $font->readInt16(); + $d = $font->readInt16(); + } + + //if ($flags & self::WE_HAVE_INSTRUCTIONS) { + // + //} + + $component = new OutlineComponent(); + $component->flags = $flags; + $component->glyphIndex = $glyphIndex; + $component->a = $a; + $component->b = $b; + $component->c = $c; + $component->d = $d; + $component->e = $e; + $component->f = $f; + $component->point_compound = $point_compound; + $component->point_component = $point_component; + $component->instructions = $instructions; + + $this->components[] = $component; + } while ($flags & self::MORE_COMPONENTS); + } + + function encode() { + $font = $this->getFont(); + + $gids = $font->getSubset(); + + $size = $font->writeInt16(-1); + $size += $font->writeFWord($this->xMin); + $size += $font->writeFWord($this->yMin); + $size += $font->writeFWord($this->xMax); + $size += $font->writeFWord($this->yMax); + + foreach ($this->components as $_i => $_component) { + $flags = 0; + if ($_component->point_component === null && $_component->point_compound === null) { + $flags |= self::ARGS_ARE_XY_VALUES; + + if (abs($_component->e) > 0x7F || abs($_component->f) > 0x7F) { + $flags |= self::ARG_1_AND_2_ARE_WORDS; + } + } + elseif ($_component->point_component > 0xFF || $_component->point_compound > 0xFF) { + $flags |= self::ARG_1_AND_2_ARE_WORDS; + } + + if ($_component->b == 0 && $_component->c == 0) { + if ($_component->a == $_component->d) { + if ($_component->a != 1.0) { + $flags |= self::WE_HAVE_A_SCALE; + } + } + else { + $flags |= self::WE_HAVE_AN_X_AND_Y_SCALE; + } + } + else { + $flags |= self::WE_HAVE_A_TWO_BY_TWO; + } + + if ($_i < count($this->components) - 1) { + $flags |= self::MORE_COMPONENTS; + } + + $size += $font->writeUInt16($flags); + + $new_gid = array_search($_component->glyphIndex, $gids); + $size += $font->writeUInt16($new_gid); + + if ($flags & self::ARG_1_AND_2_ARE_WORDS) { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $size += $font->writeInt16($_component->e); + $size += $font->writeInt16($_component->f); + } + else { + $size += $font->writeUInt16($_component->point_compound); + $size += $font->writeUInt16($_component->point_component); + } + } + else { + if ($flags & self::ARGS_ARE_XY_VALUES) { + $size += $font->writeInt8($_component->e); + $size += $font->writeInt8($_component->f); + } + else { + $size += $font->writeUInt8($_component->point_compound); + $size += $font->writeUInt8($_component->point_component); + } + } + + if ($flags & self::WE_HAVE_A_SCALE) { + $size += $font->writeInt16($_component->a); + } + elseif ($flags & self::WE_HAVE_AN_X_AND_Y_SCALE) { + $size += $font->writeInt16($_component->a); + $size += $font->writeInt16($_component->d); + } + elseif ($flags & self::WE_HAVE_A_TWO_BY_TWO) { + $size += $font->writeInt16($_component->a); + $size += $font->writeInt16($_component->b); + $size += $font->writeInt16($_component->c); + $size += $font->writeInt16($_component->d); + } + } + + return $size; + } + + public function getSVGContours() { + $contours = array(); + + /** @var \FontLib\Table\Type\glyf $glyph_data */ + $glyph_data = $this->getFont()->getTableObject("glyf"); + + /** @var Outline[] $glyphs */ + $glyphs = $glyph_data->data; + + foreach ($this->components as $component) { + $_glyph = $glyphs[$component->glyphIndex]; + + if ($_glyph !== $this) { + $contours[] = array( + "contours" => $_glyph->getSVGContours(), + "transform" => $component->getMatrix(), + ); + } + } + + return $contours; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php new file mode 100644 index 0000000..3c023de --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Glyph/OutlineSimple.php @@ -0,0 +1,335 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + * @version $Id: Font_Table_glyf.php 46 2012-04-02 20:22:38Z fabien.menager $ + */ + +namespace FontLib\Glyph; + +/** + * `glyf` font table. + * + * @package php-font-lib + */ +class OutlineSimple extends Outline { + const ON_CURVE = 0x01; + const X_SHORT_VECTOR = 0x02; + const Y_SHORT_VECTOR = 0x04; + const REPEAT = 0x08; + const THIS_X_IS_SAME = 0x10; + const THIS_Y_IS_SAME = 0x20; + + public $instructions; + public $points; + + function parseData() { + parent::parseData(); + + if (!$this->size) { + return; + } + + $font = $this->getFont(); + + $noc = $this->numberOfContours; + + if ($noc == 0) { + return; + } + + $endPtsOfContours = $font->r(array(self::uint16, $noc)); + + $instructionLength = $font->readUInt16(); + $this->instructions = $font->r(array(self::uint8, $instructionLength)); + + $count = $endPtsOfContours[$noc - 1] + 1; + + // Flags + $flags = array(); + for ($index = 0; $index < $count; $index++) { + $flags[$index] = $font->readUInt8(); + + if ($flags[$index] & self::REPEAT) { + $repeats = $font->readUInt8(); + + for ($i = 1; $i <= $repeats; $i++) { + $flags[$index + $i] = $flags[$index]; + } + + $index += $repeats; + } + } + + $points = array(); + foreach ($flags as $i => $flag) { + $points[$i]["onCurve"] = $flag & self::ON_CURVE; + $points[$i]["endOfContour"] = in_array($i, $endPtsOfContours); + } + + // X Coords + $x = 0; + for ($i = 0; $i < $count; $i++) { + $flag = $flags[$i]; + + if ($flag & self::THIS_X_IS_SAME) { + if ($flag & self::X_SHORT_VECTOR) { + $x += $font->readUInt8(); + } + } + else { + if ($flag & self::X_SHORT_VECTOR) { + $x -= $font->readUInt8(); + } + else { + $x += $font->readInt16(); + } + } + + $points[$i]["x"] = $x; + } + + // Y Coords + $y = 0; + for ($i = 0; $i < $count; $i++) { + $flag = $flags[$i]; + + if ($flag & self::THIS_Y_IS_SAME) { + if ($flag & self::Y_SHORT_VECTOR) { + $y += $font->readUInt8(); + } + } + else { + if ($flag & self::Y_SHORT_VECTOR) { + $y -= $font->readUInt8(); + } + else { + $y += $font->readInt16(); + } + } + + $points[$i]["y"] = $y; + } + + $this->points = $points; + } + + public function splitSVGPath($path) { + preg_match_all('/([a-z])|(-?\d+(?:\.\d+)?)/i', $path, $matches, PREG_PATTERN_ORDER); + + return $matches[0]; + } + + public function makePoints($path) { + $path = $this->splitSVGPath($path); + $l = count($path); + $i = 0; + + $points = array(); + + while ($i < $l) { + switch ($path[$i]) { + // moveTo + case "M": + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // lineTo + case "L": + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // quadraticCurveTo + case "Q": + $points[] = array( + "onCurve" => false, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + $points[] = array( + "onCurve" => true, + "x" => $path[++$i], + "y" => $path[++$i], + "endOfContour" => false, + ); + break; + + // closePath + /** @noinspection PhpMissingBreakStatementInspection */ + case "z": + $points[count($points) - 1]["endOfContour"] = true; + + default: + $i++; + break; + } + } + + return $points; + } + + function encode() { + if (empty($this->points)) { + return parent::encode(); + } + + return $this->size = $this->encodePoints($this->points); + } + + public function encodePoints($points) { + $endPtsOfContours = array(); + $flags = array(); + $coords_x = array(); + $coords_y = array(); + + $last_x = 0; + $last_y = 0; + $xMin = $yMin = 0xFFFF; + $xMax = $yMax = -0xFFFF; + foreach ($points as $i => $point) { + $flag = 0; + if ($point["onCurve"]) { + $flag |= self::ON_CURVE; + } + + if ($point["endOfContour"]) { + $endPtsOfContours[] = $i; + } + + // Simplified, we could do some optimizations + if ($point["x"] == $last_x) { + $flag |= self::THIS_X_IS_SAME; + } + else { + $x = intval($point["x"]); + $xMin = min($x, $xMin); + $xMax = max($x, $xMax); + $coords_x[] = $x - $last_x; // int16 + } + + // Simplified, we could do some optimizations + if ($point["y"] == $last_y) { + $flag |= self::THIS_Y_IS_SAME; + } + else { + $y = intval($point["y"]); + $yMin = min($y, $yMin); + $yMax = max($y, $yMax); + $coords_y[] = $y - $last_y; // int16 + } + + $flags[] = $flag; + $last_x = $point["x"]; + $last_y = $point["y"]; + } + + $font = $this->getFont(); + + $l = 0; + $l += $font->writeInt16(count($endPtsOfContours)); // endPtsOfContours + $l += $font->writeFWord(isset($this->xMin) ? $this->xMin : $xMin); // xMin + $l += $font->writeFWord(isset($this->yMin) ? $this->yMin : $yMin); // yMin + $l += $font->writeFWord(isset($this->xMax) ? $this->xMax : $xMax); // xMax + $l += $font->writeFWord(isset($this->yMax) ? $this->yMax : $yMax); // yMax + + // Simple glyf + $l += $font->w(array(self::uint16, count($endPtsOfContours)), $endPtsOfContours); // endPtsOfContours + $l += $font->writeUInt16(0); // instructionLength + $l += $font->w(array(self::uint8, count($flags)), $flags); // flags + $l += $font->w(array(self::int16, count($coords_x)), $coords_x); // xCoordinates + $l += $font->w(array(self::int16, count($coords_y)), $coords_y); // yCoordinates + return $l; + } + + public function getSVGContours($points = null) { + $path = ""; + + if (!$points) { + if (empty($this->points)) { + $this->parseData(); + } + + $points = $this->points; + } + + $length = count($points); + $firstIndex = 0; + $count = 0; + + for ($i = 0; $i < $length; $i++) { + $count++; + + if ($points[$i]["endOfContour"]) { + $path .= $this->getSVGPath($points, $firstIndex, $count); + $firstIndex = $i + 1; + $count = 0; + } + } + + return $path; + } + + protected function getSVGPath($points, $startIndex, $count) { + $offset = 0; + $path = ""; + + while ($offset < $count) { + $point = $points[$startIndex + $offset % $count]; + $point_p1 = $points[$startIndex + ($offset + 1) % $count]; + + if ($offset == 0) { + $path .= "M{$point['x']},{$point['y']} "; + } + + if ($point["onCurve"]) { + if ($point_p1["onCurve"]) { + $path .= "L{$point_p1['x']},{$point_p1['y']} "; + $offset++; + } + else { + $point_p2 = $points[$startIndex + ($offset + 2) % $count]; + + if ($point_p2["onCurve"]) { + $path .= "Q{$point_p1['x']},{$point_p1['y']},{$point_p2['x']},{$point_p2['y']} "; + } + else { + $path .= "Q{$point_p1['x']},{$point_p1['y']}," . $this->midValue($point_p1['x'], $point_p2['x']) . "," . $this->midValue($point_p1['y'], $point_p2['y']) . " "; + } + + $offset += 2; + } + } + else { + if ($point_p1["onCurve"]) { + $path .= "Q{$point['x']},{$point['y']},{$point_p1['x']},{$point_p1['y']} "; + } + else { + $path .= "Q{$point['x']},{$point['y']}," . $this->midValue($point['x'], $point_p1['x']) . "," . $this->midValue($point['y'], $point_p1['y']) . " "; + } + + $offset++; + } + } + + $path .= "z "; + + return $path; + } + + function midValue($a, $b) { + return $a + ($b - $a) / 2; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Header.php b/vendor/phenx/php-font-lib/src/FontLib/Header.php new file mode 100644 index 0000000..cbf137e --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Header.php @@ -0,0 +1,37 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib; + +use FontLib\TrueType\File; + +/** + * Font header container. + * + * @package php-font-lib + */ +abstract class Header extends BinaryStream { + /** + * @var File + */ + protected $font; + protected $def = array(); + + public $data; + + public function __construct(File $font) { + $this->font = $font; + } + + public function encode() { + return $this->font->pack($this->def, $this->data); + } + + public function parse() { + $this->data = $this->font->unpack($this->def); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php b/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php new file mode 100644 index 0000000..9c6df96 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/OpenType/File.php @@ -0,0 +1,18 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\OpenType; + +/** + * Open Type font, the same as a TrueType one. + * + * @package php-font-lib + */ +class File extends \FontLib\TrueType\File { + // +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php new file mode 100644 index 0000000..dd75a3e --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/OpenType/TableDirectoryEntry.php @@ -0,0 +1,18 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\OpenType; + +/** + * Open Type Table directory entry, the same as a TrueType one. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends \FontLib\TrueType\TableDirectoryEntry { + +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php new file mode 100644 index 0000000..2b5846d --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/DirectoryEntry.php @@ -0,0 +1,129 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table; + +use FontLib\TrueType\File; +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Generic Font table directory entry. + * + * @package php-font-lib + */ +class DirectoryEntry extends BinaryStream { + /** + * @var File + */ + protected $font; + + /** + * @var Table + */ + protected $font_table; + + public $entryLength = 4; + + public $tag; + public $checksum; + public $offset; + public $length; + + protected $origF; + + static function computeChecksum($data) { + $len = strlen($data); + $mod = $len % 4; + + if ($mod) { + $data = str_pad($data, $len + (4 - $mod), "\0"); + } + + $len = strlen($data); + + $hi = 0x0000; + $lo = 0x0000; + + for ($i = 0; $i < $len; $i += 4) { + $hi += (ord($data[$i]) << 8) + ord($data[$i + 1]); + $lo += (ord($data[$i + 2]) << 8) + ord($data[$i + 3]); + $hi += $lo >> 16; + $lo = $lo & 0xFFFF; + $hi = $hi & 0xFFFF; + } + + return ($hi << 8) + $lo; + } + + function __construct(File $font) { + $this->font = $font; + $this->f = $font->f; + } + + function parse() { + $this->tag = $this->font->read(4); + } + + function open($filename, $mode = self::modeRead) { + // void + } + + function setTable(Table $font_table) { + $this->font_table = $font_table; + } + + function encode($entry_offset) { + Font::d("\n==== $this->tag ===="); + //Font::d("Entry offset = $entry_offset"); + + $data = $this->font_table; + $font = $this->font; + + $table_offset = $font->pos(); + $this->offset = $table_offset; + $table_length = $data->encode(); + + $font->seek($table_offset); + $table_data = $font->read($table_length); + + $font->seek($entry_offset); + + $font->write($this->tag, 4); + $font->writeUInt32(self::computeChecksum($table_data)); + $font->writeUInt32($table_offset); + $font->writeUInt32($table_length); + + Font::d("Bytes written = $table_length"); + + $font->seek($table_offset + $table_length); + } + + /** + * @return File + */ + function getFont() { + return $this->font; + } + + function startRead() { + $this->font->seek($this->offset); + } + + function endRead() { + // + } + + function startWrite() { + $this->font->seek($this->offset); + } + + function endWrite() { + // + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php new file mode 100644 index 0000000..b127112 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Table.php @@ -0,0 +1,93 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table; + +use FontLib\TrueType\File; +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Generic font table. + * + * @package php-font-lib + */ +class Table extends BinaryStream { + /** + * @var DirectoryEntry + */ + protected $entry; + protected $def = array(); + + public $data; + + final public function __construct(DirectoryEntry $entry) { + $this->entry = $entry; + $entry->setTable($this); + } + + /** + * @return File + */ + public function getFont() { + return $this->entry->getFont(); + } + + protected function _encode() { + if (empty($this->data)) { + Font::d(" >> Table is empty"); + + return 0; + } + + return $this->getFont()->pack($this->def, $this->data); + } + + protected function _parse() { + $this->data = $this->getFont()->unpack($this->def); + } + + protected function _parseRaw() { + $this->data = $this->getFont()->read($this->entry->length); + } + + protected function _encodeRaw() { + return $this->getFont()->write($this->data, $this->entry->length); + } + + public function toHTML() { + return "
" . var_export($this->data, true) . "
"; + } + + final public function encode() { + $this->entry->startWrite(); + + if (false && empty($this->def)) { + $length = $this->_encodeRaw(); + } + else { + $length = $this->_encode(); + } + + $this->entry->endWrite(); + + return $length; + } + + final public function parse() { + $this->entry->startRead(); + + if (false && empty($this->def)) { + $this->_parseRaw(); + } + else { + $this->_parse(); + } + + $this->entry->endRead(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php new file mode 100644 index 0000000..7db77e1 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/cmap.php @@ -0,0 +1,298 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `cmap` font table. + * + * @package php-font-lib + */ +class cmap extends Table { + private static $header_format = array( + "version" => self::uint16, + "numberSubtables" => self::uint16, + ); + + private static $subtable_header_format = array( + "platformID" => self::uint16, + "platformSpecificID" => self::uint16, + "offset" => self::uint32, + ); + + private static $subtable_v4_format = array( + "length" => self::uint16, + "language" => self::uint16, + "segCountX2" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + private static $subtable_v12_format = array( + "length" => self::uint32, + "language" => self::uint32, + "ngroups" => self::uint32 + ); + + protected function _parse() { + $font = $this->getFont(); + + $cmap_offset = $font->pos(); + + $data = $font->unpack(self::$header_format); + + $subtables = array(); + for ($i = 0; $i < $data["numberSubtables"]; $i++) { + $subtables[] = $font->unpack(self::$subtable_header_format); + } + + $data["subtables"] = $subtables; + + foreach ($data["subtables"] as $i => &$subtable) { + $font->seek($cmap_offset + $subtable["offset"]); + + $subtable["format"] = $font->readUInt16(); + + // @todo Only CMAP version 4 and 12 + if (($subtable["format"] != 4) && ($subtable["format"] != 12)) { + unset($data["subtables"][$i]); + $data["numberSubtables"]--; + continue; + } + + if ($subtable["format"] == 12) { + + $font->readUInt16(); + + $subtable += $font->unpack(self::$subtable_v12_format); + + $glyphIndexArray = array(); + $endCodes = array(); + $startCodes = array(); + + for ($p = 0; $p < $subtable['ngroups']; $p++) { + + $startCode = $startCodes[] = $font->readUInt32(); + $endCode = $endCodes[] = $font->readUInt32(); + $startGlyphCode = $font->readUInt32(); + + for ($c = $startCode; $c <= $endCode; $c++) { + $glyphIndexArray[$c] = $startGlyphCode; + $startGlyphCode++; + } + } + + $subtable += array( + "startCode" => $startCodes, + "endCode" => $endCodes, + "glyphIndexArray" => $glyphIndexArray, + ); + + } + else if ($subtable["format"] == 4) { + + $subtable += $font->unpack(self::$subtable_v4_format); + + $segCount = $subtable["segCountX2"] / 2; + $subtable["segCount"] = $segCount; + + $endCode = $font->readUInt16Many($segCount); + + $font->readUInt16(); // reservedPad + + $startCode = $font->readUInt16Many($segCount); + $idDelta = $font->readInt16Many($segCount); + + $ro_start = $font->pos(); + $idRangeOffset = $font->readUInt16Many($segCount); + + $glyphIndexArray = array(); + for ($i = 0; $i < $segCount; $i++) { + $c1 = $startCode[$i]; + $c2 = $endCode[$i]; + $d = $idDelta[$i]; + $ro = $idRangeOffset[$i]; + + if ($ro > 0) { + $font->seek($subtable["offset"] + 2 * $i + $ro); + } + + for ($c = $c1; $c <= $c2; $c++) { + if ($ro == 0) { + $gid = ($c + $d) & 0xFFFF; + } + else { + $offset = ($c - $c1) * 2 + $ro; + $offset = $ro_start + 2 * $i + $offset; + + $font->seek($offset); + $gid = $font->readUInt16(); + + if ($gid != 0) { + $gid = ($gid + $d) & 0xFFFF; + } + } + + if ($gid > 0) { + $glyphIndexArray[$c] = $gid; + } + } + } + + $subtable += array( + "endCode" => $endCode, + "startCode" => $startCode, + "idDelta" => $idDelta, + "idRangeOffset" => $idRangeOffset, + "glyphIndexArray" => $glyphIndexArray, + ); + } + } + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + + $subset = $font->getSubset(); + $glyphIndexArray = $font->getUnicodeCharMap(); + + $newGlyphIndexArray = array(); + foreach ($glyphIndexArray as $code => $gid) { + $new_gid = array_search($gid, $subset); + if ($new_gid !== false) { + $newGlyphIndexArray[$code] = $new_gid; + } + } + + ksort($newGlyphIndexArray); // Sort by char code + + $segments = array(); + + $i = -1; + $prevCode = 0xFFFF; + $prevGid = 0xFFFF; + + foreach ($newGlyphIndexArray as $code => $gid) { + if ( + $prevCode + 1 != $code || + $prevGid + 1 != $gid + ) { + $i++; + $segments[$i] = array(); + } + + $segments[$i][] = array($code, $gid); + + $prevCode = $code; + $prevGid = $gid; + } + + $segments[][] = array(0xFFFF, 0xFFFF); + + $startCode = array(); + $endCode = array(); + $idDelta = array(); + + foreach ($segments as $codes) { + $start = reset($codes); + $end = end($codes); + + $startCode[] = $start[0]; + $endCode[] = $end[0]; + $idDelta[] = $start[1] - $start[0]; + } + + $segCount = count($startCode); + $idRangeOffset = array_fill(0, $segCount, 0); + + $searchRange = 1; + $entrySelector = 0; + while ($searchRange * 2 <= $segCount) { + $searchRange *= 2; + $entrySelector++; + } + $searchRange *= 2; + $rangeShift = $segCount * 2 - $searchRange; + + $subtables = array( + array( + // header + "platformID" => 3, // Unicode + "platformSpecificID" => 1, + "offset" => null, + + // subtable + "format" => 4, + "length" => null, + "language" => 0, + "segCount" => $segCount, + "segCountX2" => $segCount * 2, + "searchRange" => $searchRange, + "entrySelector" => $entrySelector, + "rangeShift" => $rangeShift, + "startCode" => $startCode, + "endCode" => $endCode, + "idDelta" => $idDelta, + "idRangeOffset" => $idRangeOffset, + "glyphIndexArray" => $newGlyphIndexArray, + ) + ); + + $data = array( + "version" => 0, + "numberSubtables" => count($subtables), + "subtables" => $subtables, + ); + + $length = $font->pack(self::$header_format, $data); + + $subtable_headers_size = $data["numberSubtables"] * 8; // size of self::$subtable_header_format + $subtable_headers_offset = $font->pos(); + + $length += $font->write(str_repeat("\0", $subtable_headers_size), $subtable_headers_size); + + // write subtables data + foreach ($data["subtables"] as $i => $subtable) { + $length_before = $length; + $data["subtables"][$i]["offset"] = $length; + + $length += $font->writeUInt16($subtable["format"]); + + $before_subheader = $font->pos(); + $length += $font->pack(self::$subtable_v4_format, $subtable); + + $segCount = $subtable["segCount"]; + $length += $font->w(array(self::uint16, $segCount), $subtable["endCode"]); + $length += $font->writeUInt16(0); // reservedPad + $length += $font->w(array(self::uint16, $segCount), $subtable["startCode"]); + $length += $font->w(array(self::int16, $segCount), $subtable["idDelta"]); + $length += $font->w(array(self::uint16, $segCount), $subtable["idRangeOffset"]); + $length += $font->w(array(self::uint16, $segCount), array_values($subtable["glyphIndexArray"])); + + $after_subtable = $font->pos(); + + $subtable["length"] = $length - $length_before; + $font->seek($before_subheader); + $length += $font->pack(self::$subtable_v4_format, $subtable); + + $font->seek($after_subtable); + } + + // write subtables headers + $font->seek($subtable_headers_offset); + foreach ($data["subtables"] as $subtable) { + $font->pack(self::$subtable_header_format, $subtable); + } + + return $length; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php new file mode 100644 index 0000000..1fbec3f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/glyf.php @@ -0,0 +1,154 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; + +use FontLib\Table\Table; +use FontLib\Glyph\Outline; +use FontLib\Glyph\OutlineSimple; + +/** + * `glyf` font table. + * + * @package php-font-lib + * @property Outline[] $data + */ +class glyf extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $loca = $font->getData("loca"); + $real_loca = array_slice($loca, 0, -1); // Not the last dummy loca entry + + $data = array(); + + foreach ($real_loca as $gid => $location) { + $_offset = $offset + $loca[$gid]; + $_size = $loca[$gid + 1] - $loca[$gid]; + $data[$gid] = Outline::init($this, $_offset, $_size, $font); + } + + $this->data = $data; + } + + public function getGlyphIDs($gids = array()) { + $glyphIDs = array(); + + foreach ($gids as $_gid) { + $_glyph = $this->data[$_gid]; + $glyphIDs = array_merge($glyphIDs, $_glyph->getGlyphIDs()); + } + + return array_unique(array_merge($gids, $glyphIDs)); + } + + public function toHTML() { + $max = 160; + $font = $this->getFont(); + + $head = $font->getData("head"); + $head_json = json_encode($head); + + $os2 = $font->getData("OS/2"); + $os2_json = json_encode($os2); + + $hmtx = $font->getData("hmtx"); + $hmtx_json = json_encode($hmtx); + + $names = $font->getData("post", "names"); + $glyphIndexArray = array_flip($font->getUnicodeCharMap()); + + $width = (abs($head["xMin"]) + $head["xMax"]); + $height = (abs($head["yMin"]) + $head["yMax"]); + + $ratio = 1; + if ($width > $max || $height > $max) { + $ratio = max($width, $height) / $max; + $width = round($width / $ratio); + $height = round($height / $ratio); + } + + $n = 500; + + $s = "

" . "Only the first $n simple glyphs are shown (" . count($this->data) . " total) +
Simple glyph
+
Composite glyph
+ Zoom: +

+ "; + + foreach ($this->data as $g => $glyph) { + if ($n-- <= 0) { + break; + } + + $glyph->parseData(); + + $shape = array( + "SVGContours" => $glyph->getSVGContours(), + "xMin" => $glyph->xMin, + "yMin" => $glyph->yMin, + "xMax" => $glyph->xMax, + "yMax" => $glyph->yMax, + ); + $shape_json = json_encode($shape); + + $type = ($glyph instanceof OutlineSimple ? "simple" : "composite"); + $char = isset($glyphIndexArray[$g]) ? $glyphIndexArray[$g] : 0; + $name = isset($names[$g]) ? $names[$g] : sprintf("uni%04x", $char); + $char = $char ? "&#{$glyphIndexArray[$g]};" : ""; + + $s .= "
+ $g + $char + $name + "; + + if ($type == "composite") { + foreach ($glyph->getGlyphIDs() as $_id) { + $s .= "$_id "; + } + } + + $s .= "
+ +
+ "; + } + + return $s; + } + + + protected function _encode() { + $font = $this->getFont(); + $subset = $font->getSubset(); + $data = $this->data; + + $loca = array(); + + $length = 0; + foreach ($subset as $gid) { + $loca[] = $length; + $length += $data[$gid]->encode(); + } + + $loca[] = $length; // dummy loca + $font->getTableObject("loca")->data = $loca; + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php new file mode 100644 index 0000000..6349f14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/head.php @@ -0,0 +1,46 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; +use Exception; + +/** + * `head` font table. + * + * @package php-font-lib + */ +class head extends Table { + protected $def = array( + "tableVersion" => self::Fixed, + "fontRevision" => self::Fixed, + "checkSumAdjustment" => self::uint32, + "magicNumber" => self::uint32, + "flags" => self::uint16, + "unitsPerEm" => self::uint16, + "created" => self::longDateTime, + "modified" => self::longDateTime, + "xMin" => self::FWord, + "yMin" => self::FWord, + "xMax" => self::FWord, + "yMax" => self::FWord, + "macStyle" => self::uint16, + "lowestRecPPEM" => self::uint16, + "fontDirectionHint" => self::int16, + "indexToLocFormat" => self::int16, + "glyphDataFormat" => self::int16, + ); + + protected function _parse() { + parent::_parse(); + + if ($this->data["magicNumber"] != 0x5F0F3CF5) { + throw new Exception("Incorrect magic number (" . dechex($this->data["magicNumber"]) . ")"); + } + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php new file mode 100644 index 0000000..dc60a14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hhea.php @@ -0,0 +1,44 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `hhea` font table. + * + * @package php-font-lib + */ +class hhea extends Table { + protected $def = array( + "version" => self::Fixed, + "ascent" => self::FWord, + "descent" => self::FWord, + "lineGap" => self::FWord, + "advanceWidthMax" => self::uFWord, + "minLeftSideBearing" => self::FWord, + "minRightSideBearing" => self::FWord, + "xMaxExtent" => self::FWord, + "caretSlopeRise" => self::int16, + "caretSlopeRun" => self::int16, + "caretOffset" => self::FWord, + self::int16, + self::int16, + self::int16, + self::int16, + "metricDataFormat" => self::int16, + "numOfLongHorMetrics" => self::uint16, + ); + + function _encode() { + $font = $this->getFont(); + $this->data["numOfLongHorMetrics"] = count($font->getSubset()); + + return parent::_encode(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php new file mode 100644 index 0000000..76e3307 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/hmtx.php @@ -0,0 +1,59 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `hmtx` font table. + * + * @package php-font-lib + */ +class hmtx extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $numOfLongHorMetrics = $font->getData("hhea", "numOfLongHorMetrics"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + + $font->seek($offset); + + $data = array(); + $metrics = $font->readUInt16Many($numOfLongHorMetrics * 2); + for ($gid = 0, $mid = 0; $gid < $numOfLongHorMetrics; $gid++) { + $advanceWidth = isset($metrics[$mid]) ? $metrics[$mid] : 0; + $mid += 1; + $leftSideBearing = isset($metrics[$mid]) ? $metrics[$mid] : 0; + $mid += 1; + $data[$gid] = array($advanceWidth, $leftSideBearing); + } + + if ($numOfLongHorMetrics < $numGlyphs) { + $lastWidth = end($data); + $data = array_pad($data, $numGlyphs, $lastWidth); + } + + $this->data = $data; + } + + protected function _encode() { + $font = $this->getFont(); + $subset = $font->getSubset(); + $data = $this->data; + + $length = 0; + + foreach ($subset as $gid) { + $length += $font->writeUInt16($data[$gid][0]); + $length += $font->writeUInt16($data[$gid][1]); + } + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php new file mode 100644 index 0000000..9875946 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/kern.php @@ -0,0 +1,80 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `kern` font table. + * + * @package php-font-lib + */ +class kern extends Table { + protected function _parse() { + $font = $this->getFont(); + + $data = $font->unpack(array( + "version" => self::uint16, + "nTables" => self::uint16, + + // only the first subtable will be parsed + "subtableVersion" => self::uint16, + "length" => self::uint16, + "coverage" => self::uint16, + )); + + $data["format"] = ($data["coverage"] >> 8); + + $subtable = array(); + + switch ($data["format"]) { + case 0: + $subtable = $font->unpack(array( + "nPairs" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + )); + + $pairs = array(); + $tree = array(); + + $values = $font->readUInt16Many($subtable["nPairs"] * 3); + for ($i = 0, $idx = 0; $i < $subtable["nPairs"]; $i++) { + $left = $values[$idx++]; + $right = $values[$idx++]; + $value = $values[$idx++]; + + if ($value >= 0x8000) { + $value -= 0x10000; + } + + $pairs[] = array( + "left" => $left, + "right" => $right, + "value" => $value, + ); + + $tree[$left][$right] = $value; + } + + //$subtable["pairs"] = $pairs; + $subtable["tree"] = $tree; + break; + + case 1: + case 2: + case 3: + break; + } + + $data["subtable"] = $subtable; + + $this->data = $data; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php new file mode 100644 index 0000000..cbc2a20 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/loca.php @@ -0,0 +1,80 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `loca` font table. + * + * @package php-font-lib + */ +class loca extends Table { + protected function _parse() { + $font = $this->getFont(); + $offset = $font->pos(); + + $indexToLocFormat = $font->getData("head", "indexToLocFormat"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + + $font->seek($offset); + + $data = array(); + + // 2 bytes + if ($indexToLocFormat == 0) { + $d = $font->read(($numGlyphs + 1) * 2); + $loc = unpack("n*", $d); + + for ($i = 0; $i <= $numGlyphs; $i++) { + $data[] = isset($loc[$i + 1]) ? $loc[$i + 1] * 2 : 0; + } + } + + // 4 bytes + else { + if ($indexToLocFormat == 1) { + $d = $font->read(($numGlyphs + 1) * 4); + $loc = unpack("N*", $d); + + for ($i = 0; $i <= $numGlyphs; $i++) { + $data[] = isset($loc[$i + 1]) ? $loc[$i + 1] : 0; + } + } + } + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + $data = $this->data; + + $indexToLocFormat = $font->getData("head", "indexToLocFormat"); + $numGlyphs = $font->getData("maxp", "numGlyphs"); + $length = 0; + + // 2 bytes + if ($indexToLocFormat == 0) { + for ($i = 0; $i <= $numGlyphs; $i++) { + $length += $font->writeUInt16($data[$i] / 2); + } + } + + // 4 bytes + else { + if ($indexToLocFormat == 1) { + for ($i = 0; $i <= $numGlyphs; $i++) { + $length += $font->writeUInt32($data[$i]); + } + } + } + + return $length; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php new file mode 100644 index 0000000..b4ebae0 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/maxp.php @@ -0,0 +1,42 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `maxp` font table. + * + * @package php-font-lib + */ +class maxp extends Table { + protected $def = array( + "version" => self::Fixed, + "numGlyphs" => self::uint16, + "maxPoints" => self::uint16, + "maxContours" => self::uint16, + "maxComponentPoints" => self::uint16, + "maxComponentContours" => self::uint16, + "maxZones" => self::uint16, + "maxTwilightPoints" => self::uint16, + "maxStorage" => self::uint16, + "maxFunctionDefs" => self::uint16, + "maxInstructionDefs" => self::uint16, + "maxStackElements" => self::uint16, + "maxSizeOfInstructions" => self::uint16, + "maxComponentElements" => self::uint16, + "maxComponentDepth" => self::uint16, + ); + + function _encode() { + $font = $this->getFont(); + $this->data["numGlyphs"] = count($font->getSubset()); + + return parent::_encode(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php new file mode 100644 index 0000000..794824d --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/name.php @@ -0,0 +1,193 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; + +use FontLib\Table\Table; +use FontLib\Font; + +/** + * `name` font table. + * + * @package php-font-lib + */ +class name extends Table { + private static $header_format = array( + "format" => self::uint16, + "count" => self::uint16, + "stringOffset" => self::uint16, + ); + + const NAME_COPYRIGHT = 0; + const NAME_NAME = 1; + const NAME_SUBFAMILY = 2; + const NAME_SUBFAMILY_ID = 3; + const NAME_FULL_NAME = 4; + const NAME_VERSION = 5; + const NAME_POSTSCRIPT_NAME = 6; + const NAME_TRADEMARK = 7; + const NAME_MANUFACTURER = 8; + const NAME_DESIGNER = 9; + const NAME_DESCRIPTION = 10; + const NAME_VENDOR_URL = 11; + const NAME_DESIGNER_URL = 12; + const NAME_LICENSE = 13; + const NAME_LICENSE_URL = 14; + const NAME_PREFERRE_FAMILY = 16; + const NAME_PREFERRE_SUBFAMILY = 17; + const NAME_COMPAT_FULL_NAME = 18; + const NAME_SAMPLE_TEXT = 19; + + static $nameIdCodes = array( + 0 => "Copyright", + 1 => "FontName", + 2 => "FontSubfamily", + 3 => "UniqueID", + 4 => "FullName", + 5 => "Version", + 6 => "PostScriptName", + 7 => "Trademark", + 8 => "Manufacturer", + 9 => "Designer", + 10 => "Description", + 11 => "FontVendorURL", + 12 => "FontDesignerURL", + 13 => "LicenseDescription", + 14 => "LicenseURL", + // 15 + 16 => "PreferredFamily", + 17 => "PreferredSubfamily", + 18 => "CompatibleFullName", + 19 => "SampleText", + ); + + static $platforms = array( + 0 => "Unicode", + 1 => "Macintosh", + // 2 => Reserved + 3 => "Microsoft", + ); + + static $platformSpecific = array( + // Unicode + 0 => array( + 0 => "Default semantics", + 1 => "Version 1.1 semantics", + 2 => "ISO 10646 1993 semantics (deprecated)", + 3 => "Unicode 2.0 or later semantics", + ), + + // Macintosh + 1 => array( + 0 => "Roman", + 1 => "Japanese", + 2 => "Traditional Chinese", + 3 => "Korean", + 4 => "Arabic", + 5 => "Hebrew", + 6 => "Greek", + 7 => "Russian", + 8 => "RSymbol", + 9 => "Devanagari", + 10 => "Gurmukhi", + 11 => "Gujarati", + 12 => "Oriya", + 13 => "Bengali", + 14 => "Tamil", + 15 => "Telugu", + 16 => "Kannada", + 17 => "Malayalam", + 18 => "Sinhalese", + 19 => "Burmese", + 20 => "Khmer", + 21 => "Thai", + 22 => "Laotian", + 23 => "Georgian", + 24 => "Armenian", + 25 => "Simplified Chinese", + 26 => "Tibetan", + 27 => "Mongolian", + 28 => "Geez", + 29 => "Slavic", + 30 => "Vietnamese", + 31 => "Sindhi", + ), + + // Microsoft + 3 => array( + 0 => "Symbol", + 1 => "Unicode BMP (UCS-2)", + 2 => "ShiftJIS", + 3 => "PRC", + 4 => "Big5", + 5 => "Wansung", + 6 => "Johab", + // 7 => Reserved + // 8 => Reserved + // 9 => Reserved + 10 => "Unicode UCS-4", + ), + ); + + protected function _parse() { + $font = $this->getFont(); + + $tableOffset = $font->pos(); + + $data = $font->unpack(self::$header_format); + + $records = array(); + for ($i = 0; $i < $data["count"]; $i++) { + $record = new nameRecord(); + $record_data = $font->unpack(nameRecord::$format); + $record->map($record_data); + + $records[] = $record; + } + + $names = array(); + foreach ($records as $record) { + $font->seek($tableOffset + $data["stringOffset"] + $record->offset); + $s = $font->read($record->length); + $record->string = Font::UTF16ToUTF8($s); + $names[$record->nameID] = $record; + } + + $data["records"] = $names; + + $this->data = $data; + } + + protected function _encode() { + $font = $this->getFont(); + + /** @var nameRecord[] $records */ + $records = $this->data["records"]; + $count_records = count($records); + + $this->data["count"] = $count_records; + $this->data["stringOffset"] = 6 + $count_records * 12; // 6 => uint16 * 3, 12 => sizeof self::$record_format + + $length = $font->pack(self::$header_format, $this->data); + + $offset = 0; + foreach ($records as $record) { + $record->length = mb_strlen($record->getUTF16(), "8bit"); + $record->offset = $offset; + $offset += $record->length; + $length += $font->pack(nameRecord::$format, (array)$record); + } + + foreach ($records as $record) { + $str = $record->getUTF16(); + $length += $font->write($str, mb_strlen($str, "8bit")); + } + + return $length; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php new file mode 100644 index 0000000..2073c20 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/nameRecord.php @@ -0,0 +1,53 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ +namespace FontLib\Table\Type; + +use FontLib\Font; +use FontLib\BinaryStream; + +/** + * Font table name record. + * + * @package php-font-lib + */ +class nameRecord extends BinaryStream { + public $platformID; + public $platformSpecificID; + public $languageID; + public $nameID; + public $length; + public $offset; + public $string; + + public static $format = array( + "platformID" => self::uint16, + "platformSpecificID" => self::uint16, + "languageID" => self::uint16, + "nameID" => self::uint16, + "length" => self::uint16, + "offset" => self::uint16, + ); + + public function map($data) { + foreach ($data as $key => $value) { + $this->$key = $value; + } + } + + public function getUTF8() { + return $this->string; + } + + public function getUTF16() { + return Font::UTF8ToUTF16($this->string); + } + + function __toString() { + return $this->string; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php new file mode 100644 index 0000000..19a3e21 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/os2.php @@ -0,0 +1,47 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; + +/** + * `OS/2` font table. + * + * @package php-font-lib + */ +class os2 extends Table { + protected $def = array( + "version" => self::uint16, + "xAvgCharWidth" => self::int16, + "usWeightClass" => self::uint16, + "usWidthClass" => self::uint16, + "fsType" => self::int16, + "ySubscriptXSize" => self::int16, + "ySubscriptYSize" => self::int16, + "ySubscriptXOffset" => self::int16, + "ySubscriptYOffset" => self::int16, + "ySuperscriptXSize" => self::int16, + "ySuperscriptYSize" => self::int16, + "ySuperscriptXOffset" => self::int16, + "ySuperscriptYOffset" => self::int16, + "yStrikeoutSize" => self::int16, + "yStrikeoutPosition" => self::int16, + "sFamilyClass" => self::int16, + "panose" => array(self::uint8, 10), + "ulCharRange" => array(self::uint32, 4), + "achVendID" => array(self::char, 4), + "fsSelection" => self::uint16, + "fsFirstCharIndex" => self::uint16, + "fsLastCharIndex" => self::uint16, + "typoAscender" => self::int16, + "typoDescender" => self::int16, + "typoLineGap" => self::int16, + "winAscent" => self::int16, + "winDescent" => self::int16, + ); +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php new file mode 100644 index 0000000..ec5806b --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/Table/Type/post.php @@ -0,0 +1,141 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\Table\Type; +use FontLib\Table\Table; +use FontLib\TrueType\File; + +/** + * `post` font table. + * + * @package php-font-lib + */ +class post extends Table { + protected $def = array( + "format" => self::Fixed, + "italicAngle" => self::Fixed, + "underlinePosition" => self::FWord, + "underlineThickness" => self::FWord, + "isFixedPitch" => self::uint32, + "minMemType42" => self::uint32, + "maxMemType42" => self::uint32, + "minMemType1" => self::uint32, + "maxMemType1" => self::uint32, + ); + + protected function _parse() { + $font = $this->getFont(); + $data = $font->unpack($this->def); + + $names = array(); + + switch ($data["format"]) { + case 1: + $names = File::$macCharNames; + break; + + case 2: + $data["numberOfGlyphs"] = $font->readUInt16(); + + $glyphNameIndex = $font->readUInt16Many($data["numberOfGlyphs"]); + + $data["glyphNameIndex"] = $glyphNameIndex; + + $namesPascal = array(); + for ($i = 0; $i < $data["numberOfGlyphs"]; $i++) { + $len = $font->readUInt8(); + $namesPascal[] = $font->read($len); + } + + foreach ($glyphNameIndex as $g => $index) { + if ($index < 258) { + $names[$g] = File::$macCharNames[$index]; + } + else { + $names[$g] = $namesPascal[$index - 258]; + } + } + + break; + + case 2.5: + // TODO + break; + + case 3: + // nothing + break; + + case 4: + // TODO + break; + } + + $data["names"] = $names; + + $this->data = $data; + } + + function _encode() { + $font = $this->getFont(); + $data = $this->data; + $data["format"] = 3; + + $length = $font->pack($this->def, $data); + + return $length; + /* + $subset = $font->getSubset(); + + switch($data["format"]) { + case 1: + // nothing to do + break; + + case 2: + $old_names = $data["names"]; + + $glyphNameIndex = range(0, count($subset)); + + $names = array(); + foreach($subset as $gid) { + $names[] = $data["names"][$data["glyphNameIndex"][$gid]]; + } + + $numberOfGlyphs = count($names); + $length += $font->writeUInt16($numberOfGlyphs); + + foreach($glyphNameIndex as $gni) { + $length += $font->writeUInt16($gni); + } + + //$names = array_slice($names, 257); + foreach($names as $name) { + $len = strlen($name); + $length += $font->writeUInt8($len); + $length += $font->write($name, $len); + } + + break; + + case 2.5: + // TODO + break; + + case 3: + // nothing + break; + + case 4: + // TODO + break; + } + + return $length;*/ + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php new file mode 100644 index 0000000..460ef4d --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Collection.php @@ -0,0 +1,100 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use Countable; +use FontLib\BinaryStream; +use Iterator; +use OutOfBoundsException; + +/** + * TrueType collection font file. + * + * @package php-font-lib + */ +class Collection extends BinaryStream implements Iterator, Countable { + /** + * Current iterator position. + * + * @var integer + */ + private $position = 0; + + protected $collectionOffsets = array(); + protected $collection = array(); + protected $version; + protected $numFonts; + + function parse() { + if (isset($this->numFonts)) { + return; + } + + $this->read(4); // tag name + + $this->version = $this->readFixed(); + $this->numFonts = $this->readUInt32(); + + for ($i = 0; $i < $this->numFonts; $i++) { + $this->collectionOffsets[] = $this->readUInt32(); + } + } + + /** + * @param int $fontId + * + * @throws OutOfBoundsException + * @return File + */ + function getFont($fontId) { + $this->parse(); + + if (!isset($this->collectionOffsets[$fontId])) { + throw new OutOfBoundsException(); + } + + if (isset($this->collection[$fontId])) { + return $this->collection[$fontId]; + } + + $font = new File(); + $font->f = $this->f; + $font->setTableOffset($this->collectionOffsets[$fontId]); + + return $this->collection[$fontId] = $font; + } + + function current() { + return $this->getFont($this->position); + } + + function key() { + return $this->position; + } + + function next() { + return ++$this->position; + } + + function rewind() { + $this->position = 0; + } + + function valid() { + $this->parse(); + + return isset($this->collectionOffsets[$this->position]); + } + + function count() { + $this->parse(); + + return $this->numFonts; + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php new file mode 100644 index 0000000..b61da0f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/File.php @@ -0,0 +1,471 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use FontLib\AdobeFontMetrics; +use FontLib\Font; +use FontLib\BinaryStream; +use FontLib\Table\Table; +use FontLib\Table\DirectoryEntry; +use FontLib\Table\Type\glyf; +use FontLib\Table\Type\name; +use FontLib\Table\Type\nameRecord; + +/** + * TrueType font file. + * + * @package php-font-lib + */ +class File extends BinaryStream { + /** + * @var Header + */ + public $header = array(); + + private $tableOffset = 0; // Used for TTC + + private static $raw = false; + + protected $directory = array(); + protected $data = array(); + + protected $glyph_subset = array(); + + public $glyph_all = array(); + + static $macCharNames = array( + ".notdef", ".null", "CR", + "space", "exclam", "quotedbl", "numbersign", + "dollar", "percent", "ampersand", "quotesingle", + "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", + "zero", "one", "two", "three", + "four", "five", "six", "seven", + "eight", "nine", "colon", "semicolon", + "less", "equal", "greater", "question", + "at", "A", "B", "C", "D", "E", "F", "G", + "H", "I", "J", "K", "L", "M", "N", "O", + "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", + "backslash", "bracketright", "asciicircum", "underscore", + "grave", "a", "b", "c", "d", "e", "f", "g", + "h", "i", "j", "k", "l", "m", "n", "o", + "p", "q", "r", "s", "t", "u", "v", "w", + "x", "y", "z", "braceleft", + "bar", "braceright", "asciitilde", "Adieresis", + "Aring", "Ccedilla", "Eacute", "Ntilde", + "Odieresis", "Udieresis", "aacute", "agrave", + "acircumflex", "adieresis", "atilde", "aring", + "ccedilla", "eacute", "egrave", "ecircumflex", + "edieresis", "iacute", "igrave", "icircumflex", + "idieresis", "ntilde", "oacute", "ograve", + "ocircumflex", "odieresis", "otilde", "uacute", + "ugrave", "ucircumflex", "udieresis", "dagger", + "degree", "cent", "sterling", "section", + "bullet", "paragraph", "germandbls", "registered", + "copyright", "trademark", "acute", "dieresis", + "notequal", "AE", "Oslash", "infinity", + "plusminus", "lessequal", "greaterequal", "yen", + "mu", "partialdiff", "summation", "product", + "pi", "integral", "ordfeminine", "ordmasculine", + "Omega", "ae", "oslash", "questiondown", + "exclamdown", "logicalnot", "radical", "florin", + "approxequal", "increment", "guillemotleft", "guillemotright", + "ellipsis", "nbspace", "Agrave", "Atilde", + "Otilde", "OE", "oe", "endash", + "emdash", "quotedblleft", "quotedblright", "quoteleft", + "quoteright", "divide", "lozenge", "ydieresis", + "Ydieresis", "fraction", "currency", "guilsinglleft", + "guilsinglright", "fi", "fl", "daggerdbl", + "periodcentered", "quotesinglbase", "quotedblbase", "perthousand", + "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", + "Egrave", "Iacute", "Icircumflex", "Idieresis", + "Igrave", "Oacute", "Ocircumflex", "applelogo", + "Ograve", "Uacute", "Ucircumflex", "Ugrave", + "dotlessi", "circumflex", "tilde", "macron", + "breve", "dotaccent", "ring", "cedilla", + "hungarumlaut", "ogonek", "caron", "Lslash", + "lslash", "Scaron", "scaron", "Zcaron", + "zcaron", "brokenbar", "Eth", "eth", + "Yacute", "yacute", "Thorn", "thorn", + "minus", "multiply", "onesuperior", "twosuperior", + "threesuperior", "onehalf", "onequarter", "threequarters", + "franc", "Gbreve", "gbreve", "Idot", + "Scedilla", "scedilla", "Cacute", "cacute", + "Ccaron", "ccaron", "dmacron" + ); + + function getTable() { + $this->parseTableEntries(); + + return $this->directory; + } + + function setTableOffset($offset) { + $this->tableOffset = $offset; + } + + function parse() { + $this->parseTableEntries(); + + $this->data = array(); + + foreach ($this->directory as $tag => $table) { + if (empty($this->data[$tag])) { + $this->readTable($tag); + } + } + } + + function utf8toUnicode($str) { + $len = strlen($str); + $out = array(); + + for ($i = 0; $i < $len; $i++) { + $uni = -1; + $h = ord($str[$i]); + + if ($h <= 0x7F) { + $uni = $h; + } + elseif ($h >= 0xC2) { + if (($h <= 0xDF) && ($i < $len - 1)) { + $uni = ($h & 0x1F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xEF) && ($i < $len - 2)) { + $uni = ($h & 0x0F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + elseif (($h <= 0xF4) && ($i < $len - 3)) { + $uni = ($h & 0x0F) << 18 | (ord($str[++$i]) & 0x3F) << 12 | (ord($str[++$i]) & 0x3F) << 6 | (ord($str[++$i]) & 0x3F); + } + } + + if ($uni >= 0) { + $out[] = $uni; + } + } + + return $out; + } + + function getUnicodeCharMap() { + $subtable = null; + foreach ($this->getData("cmap", "subtables") as $_subtable) { + if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { + $subtable = $_subtable; + break; + } + } + + if ($subtable) { + return $subtable["glyphIndexArray"]; + } + + return null; + } + + function setSubset($subset) { + if (!is_array($subset)) { + $subset = $this->utf8toUnicode($subset); + } + + $subset = array_unique($subset); + + $glyphIndexArray = $this->getUnicodeCharMap(); + + if (!$glyphIndexArray) { + return; + } + + $gids = array( + 0, // .notdef + 1, // .null + ); + + foreach ($subset as $code) { + if (!isset($glyphIndexArray[$code])) { + continue; + } + + $gid = $glyphIndexArray[$code]; + $gids[$gid] = $gid; + } + + /** @var glyf $glyf */ + $glyf = $this->getTableObject("glyf"); + $gids = $glyf->getGlyphIDs($gids); + + sort($gids); + + $this->glyph_subset = $gids; + $this->glyph_all = array_values($glyphIndexArray); // FIXME + } + + function getSubset() { + if (empty($this->glyph_subset)) { + return $this->glyph_all; + } + + return $this->glyph_subset; + } + + function encode($tags = array()) { + if (!self::$raw) { + $tags = array_merge(array("head", "hhea", "cmap", "hmtx", "maxp", "glyf", "loca", "name", "post"), $tags); + } + else { + $tags = array_keys($this->directory); + } + + $num_tables = count($tags); + $n = 16; // @todo + + Font::d("Tables : " . implode(", ", $tags)); + + /** @var DirectoryEntry[] $entries */ + $entries = array(); + foreach ($tags as $tag) { + if (!isset($this->directory[$tag])) { + Font::d(" >> '$tag' table doesn't exist"); + continue; + } + + $entries[$tag] = $this->directory[$tag]; + } + + $this->header->data["numTables"] = $num_tables; + $this->header->encode(); + + $directory_offset = $this->pos(); + $offset = $directory_offset + $num_tables * $n; + $this->seek($offset); + + $i = 0; + foreach ($entries as $entry) { + $entry->encode($directory_offset + $i * $n); + $i++; + } + } + + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->seek($this->tableOffset); + + $this->header = new Header($this); + $this->header->parse(); + } + + function getFontType(){ + $class_parts = explode("\\", get_class($this)); + return $class_parts[1]; + } + + function parseTableEntries() { + $this->parseHeader(); + + if (!empty($this->directory)) { + return; + } + + if (empty($this->header->data["numTables"])) { + return; + } + + + $type = $this->getFontType(); + $class = "FontLib\\$type\\TableDirectoryEntry"; + + for ($i = 0; $i < $this->header->data["numTables"]; $i++) { + /** @var TableDirectoryEntry $entry */ + $entry = new $class($this); + $entry->parse(); + + $this->directory[$entry->tag] = $entry; + } + } + + function normalizeFUnit($value, $base = 1000) { + return round($value * ($base / $this->getData("head", "unitsPerEm"))); + } + + protected function readTable($tag) { + $this->parseTableEntries(); + + if (!self::$raw) { + $name_canon = preg_replace("/[^a-z0-9]/", "", strtolower($tag)); + + $class = "FontLib\\Table\\Type\\$name_canon"; + + if (!isset($this->directory[$tag]) || !@class_exists($class)) { + return; + } + } + else { + $class = "FontLib\\Table\\Table"; + } + + /** @var Table $table */ + $table = new $class($this->directory[$tag]); + $table->parse(); + + $this->data[$tag] = $table; + } + + /** + * @param $name + * + * @return Table + */ + public function getTableObject($name) { + return $this->data[$name]; + } + + public function setTableObject($name, Table $data) { + $this->data[$name] = $data; + } + + public function getData($name, $key = null) { + $this->parseTableEntries(); + + if (empty($this->data[$name])) { + $this->readTable($name); + } + + if (!isset($this->data[$name])) { + return null; + } + + if (!$key) { + return $this->data[$name]->data; + } + else { + return $this->data[$name]->data[$key]; + } + } + + function addDirectoryEntry(DirectoryEntry $entry) { + $this->directory[$entry->tag] = $entry; + } + + function saveAdobeFontMetrics($file, $encoding = null) { + $afm = new AdobeFontMetrics($this); + $afm->write($file, $encoding); + } + + /** + * Get a specific name table string value from its ID + * + * @param int $nameID The name ID + * + * @return string|null + */ + function getNameTableString($nameID) { + /** @var nameRecord[] $records */ + $records = $this->getData("name", "records"); + + if (!isset($records[$nameID])) { + return null; + } + + return $records[$nameID]->string; + } + + /** + * Get font copyright + * + * @return string|null + */ + function getFontCopyright() { + return $this->getNameTableString(name::NAME_COPYRIGHT); + } + + /** + * Get font name + * + * @return string|null + */ + function getFontName() { + return $this->getNameTableString(name::NAME_NAME); + } + + /** + * Get font subfamily + * + * @return string|null + */ + function getFontSubfamily() { + return $this->getNameTableString(name::NAME_SUBFAMILY); + } + + /** + * Get font subfamily ID + * + * @return string|null + */ + function getFontSubfamilyID() { + return $this->getNameTableString(name::NAME_SUBFAMILY_ID); + } + + /** + * Get font full name + * + * @return string|null + */ + function getFontFullName() { + return $this->getNameTableString(name::NAME_FULL_NAME); + } + + /** + * Get font version + * + * @return string|null + */ + function getFontVersion() { + return $this->getNameTableString(name::NAME_VERSION); + } + + /** + * Get font weight + * + * @return string|null + */ + function getFontWeight() { + return $this->getTableObject("OS/2")->data["usWeightClass"]; + } + + /** + * Get font Postscript name + * + * @return string|null + */ + function getFontPostscriptName() { + return $this->getNameTableString(name::NAME_POSTSCRIPT_NAME); + } + + function reduce() { + $names_to_keep = array( + name::NAME_COPYRIGHT, + name::NAME_NAME, + name::NAME_SUBFAMILY, + name::NAME_SUBFAMILY_ID, + name::NAME_FULL_NAME, + name::NAME_VERSION, + name::NAME_POSTSCRIPT_NAME, + ); + + foreach ($this->data["name"]->data["records"] as $id => $rec) { + if (!in_array($id, $names_to_keep)) { + unset($this->data["name"]->data["records"][$id]); + } + } + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php new file mode 100644 index 0000000..7ff79cc --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/Header.php @@ -0,0 +1,31 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +/** + * TrueType font file header. + * + * @package php-font-lib + */ +class Header extends \FontLib\Header { + protected $def = array( + "format" => self::uint32, + "numTables" => self::uint16, + "searchRange" => self::uint16, + "entrySelector" => self::uint16, + "rangeShift" => self::uint16, + ); + + public function parse() { + parent::parse(); + + $format = $this->data["format"]; + $this->data["formatText"] = $this->convertUInt32ToStr($format); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php new file mode 100644 index 0000000..fc4fe55 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/TrueType/TableDirectoryEntry.php @@ -0,0 +1,33 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\TrueType; + +use FontLib\Table\DirectoryEntry; + +/** + * TrueType table directory entry. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends DirectoryEntry { + function __construct(File $font) { + parent::__construct($font); + } + + function parse() { + parent::parse(); + + $font = $this->font; + $this->checksum = $font->readUInt32(); + $this->offset = $font->readUInt32(); + $this->length = $font->readUInt32(); + $this->entryLength += 12; + } +} + diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php new file mode 100644 index 0000000..9e54b3f --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/File.php @@ -0,0 +1,81 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +use FontLib\Table\DirectoryEntry; + +/** + * WOFF font file. + * + * @package php-font-lib + * + * @property TableDirectoryEntry[] $directory + */ +class File extends \FontLib\TrueType\File { + function parseHeader() { + if (!empty($this->header)) { + return; + } + + $this->header = new Header($this); + $this->header->parse(); + } + + public function load($file) { + parent::load($file); + + $this->parseTableEntries(); + $dataOffset = $this->pos() + count($this->directory) * 20; + + $fw = $this->getTempFile(false); + $fr = $this->f; + + $this->f = $fw; + $offset = $this->header->encode(); + + foreach ($this->directory as $entry) { + // Read ... + $this->f = $fr; + $this->seek($entry->offset); + $data = $this->read($entry->length); + + if ($entry->length < $entry->origLength) { + $data = gzuncompress($data); + } + + // Prepare data ... + $length = strlen($data); + $entry->length = $entry->origLength = $length; + $entry->offset = $dataOffset; + + // Write ... + $this->f = $fw; + + // Woff Entry + $this->seek($offset); + $offset += $this->write($entry->tag, 4); // tag + $offset += $this->writeUInt32($dataOffset); // offset + $offset += $this->writeUInt32($length); // length + $offset += $this->writeUInt32($length); // origLength + $offset += $this->writeUInt32(DirectoryEntry::computeChecksum($data)); // checksum + + // Data + $this->seek($dataOffset); + $dataOffset += $this->write($data, $length); + } + + $this->f = $fw; + $this->seek(0); + + // Need to re-parse this, don't know why + $this->header = null; + $this->directory = array(); + $this->parseTableEntries(); + } +} diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php new file mode 100644 index 0000000..65a6f14 --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/Header.php @@ -0,0 +1,32 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +/** + * WOFF font file header. + * + * @package php-font-lib + */ +class Header extends \FontLib\TrueType\Header { + protected $def = array( + "format" => self::uint32, + "flavor" => self::uint32, + "length" => self::uint32, + "numTables" => self::uint16, + self::uint16, + "totalSfntSize" => self::uint32, + "majorVersion" => self::uint16, + "minorVersion" => self::uint16, + "metaOffset" => self::uint32, + "metaLength" => self::uint32, + "metaOrigLength" => self::uint32, + "privOffset" => self::uint32, + "privLength" => self::uint32, + ); +} \ No newline at end of file diff --git a/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php b/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php new file mode 100644 index 0000000..eb67c9c --- /dev/null +++ b/vendor/phenx/php-font-lib/src/FontLib/WOFF/TableDirectoryEntry.php @@ -0,0 +1,34 @@ + + * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License + */ + +namespace FontLib\WOFF; + +use FontLib\Table\DirectoryEntry; + +/** + * WOFF font file table directory entry. + * + * @package php-font-lib + */ +class TableDirectoryEntry extends DirectoryEntry { + public $origLength; + + function __construct(File $font) { + parent::__construct($font); + } + + function parse() { + parent::parse(); + + $font = $this->font; + $this->offset = $font->readUInt32(); + $this->length = $font->readUInt32(); + $this->origLength = $font->readUInt32(); + $this->checksum = $font->readUInt32(); + } +} diff --git a/vendor/phenx/php-font-lib/tests/FontLib/FontTest.php b/vendor/phenx/php-font-lib/tests/FontLib/FontTest.php new file mode 100644 index 0000000..b998a49 --- /dev/null +++ b/vendor/phenx/php-font-lib/tests/FontLib/FontTest.php @@ -0,0 +1,49 @@ +assertInstanceOf('FontLib\TrueType\File', $trueTypeFont); + } + + public function test12CmapFormat() + { + $trueTypeFont = Font::load('sample-fonts/NotoSansShavian-Regular.ttf'); + + $trueTypeFont->parse(); + + $cmapTable = $trueTypeFont->getData("cmap", "subtables"); + + $cmapFormat4Table = $cmapTable[0]; + + $this->assertEquals(4, $cmapFormat4Table['format']); + $this->assertEquals(6, $cmapFormat4Table['segCount']); + $this->assertEquals($cmapFormat4Table['segCount'], count($cmapFormat4Table['startCode'])); + $this->assertEquals($cmapFormat4Table['segCount'], count($cmapFormat4Table['endCode'])); + + $cmapFormat12Table = $cmapTable[1]; + + $this->assertEquals(12, $cmapFormat12Table['format']); + $this->assertEquals(6, $cmapFormat12Table['ngroups']); + $this->assertEquals(6, count($cmapFormat12Table['startCode'])); + $this->assertEquals(6, count($cmapFormat12Table['endCode'])); + $this->assertEquals(53, count($cmapFormat12Table['glyphIndexArray'])); + } + +} diff --git a/vendor/phenx/php-svg-lib/.gitattributes b/vendor/phenx/php-svg-lib/.gitattributes new file mode 100644 index 0000000..86d3b92 --- /dev/null +++ b/vendor/phenx/php-svg-lib/.gitattributes @@ -0,0 +1,9 @@ +*.json text +*.xml text +*.php text +*.md text +*.css text +*.js text +*.html text +*.htm text +*.svg text diff --git a/vendor/phenx/php-svg-lib/.gitignore b/vendor/phenx/php-svg-lib/.gitignore new file mode 100644 index 0000000..7181efd --- /dev/null +++ b/vendor/phenx/php-svg-lib/.gitignore @@ -0,0 +1,3 @@ +excluded +gui +.idea \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/.travis.yml b/vendor/phenx/php-svg-lib/.travis.yml new file mode 100644 index 0000000..fe318f9 --- /dev/null +++ b/vendor/phenx/php-svg-lib/.travis.yml @@ -0,0 +1,20 @@ +language: php + +php: + - 5.6 + - 7.0 + - 7.1 + - 7.2 + - nightly + +before_script: + - composer self-update + - composer install --prefer-source --no-interaction --dev + +script: phpunit + +matrix: + allow_failures: + - php: 5.6 + - php: nightly + fast_finish: true diff --git a/vendor/phenx/php-svg-lib/COPYING b/vendor/phenx/php-svg-lib/COPYING new file mode 100644 index 0000000..0a04128 --- /dev/null +++ b/vendor/phenx/php-svg-lib/COPYING @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/vendor/phenx/php-svg-lib/COPYING.GPL b/vendor/phenx/php-svg-lib/COPYING.GPL new file mode 100644 index 0000000..f288702 --- /dev/null +++ b/vendor/phenx/php-svg-lib/COPYING.GPL @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/vendor/phenx/php-svg-lib/README.md b/vendor/phenx/php-svg-lib/README.md new file mode 100644 index 0000000..f11cde9 --- /dev/null +++ b/vendor/phenx/php-svg-lib/README.md @@ -0,0 +1,14 @@ +# SVG file parsing / rendering library + +[![Build Status](https://travis-ci.org/PhenX/php-svg-lib.svg?branch=master)](https://travis-ci.org/PhenX/php-svg-lib) +[![Coverage Status](https://coveralls.io/repos/PhenX/php-svg-lib/badge.svg)](https://coveralls.io/r/PhenX/php-svg-lib) + + +[![Latest Stable Version](https://poser.pugx.org/phenx/php-svg-lib/v/stable)](https://packagist.org/packages/phenx/php-svg-lib) +[![Total Downloads](https://poser.pugx.org/phenx/php-svg-lib/downloads)](https://packagist.org/packages/phenx/php-svg-lib) +[![Latest Unstable Version](https://poser.pugx.org/phenx/php-svg-lib/v/unstable)](https://packagist.org/packages/phenx/php-svg-lib) +[![License](https://poser.pugx.org/phenx/php-svg-lib/license)](https://packagist.org/packages/phenx/php-svg-lib) + +The main purpose of this lib is to rasterize SVG to a surface which can be an image or a PDF for example, through a `\Svg\Surface` PHP interface. + +This project was initialized by the need to render SVG documents inside PDF files for the [DomPdf](http://dompdf.github.io) project. \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/composer.json b/vendor/phenx/php-svg-lib/composer.json new file mode 100644 index 0000000..3a57553 --- /dev/null +++ b/vendor/phenx/php-svg-lib/composer.json @@ -0,0 +1,29 @@ +{ + "name": "phenx/php-svg-lib", + "type": "library", + "description": "A library to read, parse and export to PDF SVG files.", + "homepage": "https://github.com/PhenX/php-svg-lib", + "license": "LGPL-3.0", + "authors": [ + { + "name": "Fabien Ménager", + "email": "fabien.menager@gmail.com" + } + ], + "autoload": { + "psr-4": { + "Svg\\": "src/Svg" + } + }, + "autoload-dev": { + "psr-4": { + "Svg\\Tests\\": "tests/Svg" + } + }, + "require": { + "sabberworm/php-css-parser": "^8.3" + }, + "require-dev": { + "phpunit/phpunit": "^5.5|^6.5" + } +} diff --git a/vendor/phenx/php-svg-lib/phpunit.xml b/vendor/phenx/php-svg-lib/phpunit.xml new file mode 100644 index 0000000..9559d96 --- /dev/null +++ b/vendor/phenx/php-svg-lib/phpunit.xml @@ -0,0 +1,19 @@ + + + + + + ./tests/Svg/ + + + \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php b/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php new file mode 100644 index 0000000..c0535c7 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/DefaultStyle.php @@ -0,0 +1,29 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +class DefaultStyle extends Style +{ + public $color = ''; + public $opacity = 1.0; + public $display = 'inline'; + + public $fill = 'black'; + public $fillOpacity = 1.0; + public $fillRule = 'nonzero'; + + public $stroke = 'none'; + public $strokeOpacity = 1.0; + public $strokeLinecap = 'butt'; + public $strokeLinejoin = 'miter'; + public $strokeMiterlimit = 4; + public $strokeWidth = 1.0; + public $strokeDasharray = 0; + public $strokeDashoffset = 0; +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Document.php b/vendor/phenx/php-svg-lib/src/Svg/Document.php new file mode 100644 index 0000000..4ecdc76 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Document.php @@ -0,0 +1,404 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +use Svg\Surface\SurfaceInterface; +use Svg\Tag\AbstractTag; +use Svg\Tag\Anchor; +use Svg\Tag\Circle; +use Svg\Tag\Ellipse; +use Svg\Tag\Group; +use Svg\Tag\ClipPath; +use Svg\Tag\Image; +use Svg\Tag\Line; +use Svg\Tag\LinearGradient; +use Svg\Tag\Path; +use Svg\Tag\Polygon; +use Svg\Tag\Polyline; +use Svg\Tag\Rect; +use Svg\Tag\Stop; +use Svg\Tag\Text; +use Svg\Tag\StyleTag; +use Svg\Tag\UseTag; + +class Document extends AbstractTag +{ + protected $filename; + public $inDefs = false; + + protected $x; + protected $y; + protected $width; + protected $height; + + protected $subPathInit; + protected $pathBBox; + protected $viewBox; + + /** @var resource */ + protected $parser; + + /** @var SurfaceInterface */ + protected $surface; + + /** @var AbstractTag[] */ + protected $stack = array(); + + /** @var AbstractTag[] */ + protected $defs = array(); + + /** @var \Sabberworm\CSS\CSSList\Document[] */ + protected $styleSheets = array(); + + public function loadFile($filename) + { + $this->filename = $filename; + } + + protected function initParser() { + $parser = xml_parser_create("utf-8"); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); + xml_set_element_handler( + $parser, + array($this, "_tagStart"), + array($this, "_tagEnd") + ); + xml_set_character_data_handler( + $parser, + array($this, "_charData") + ); + + return $this->parser = $parser; + } + + public function __construct() { + + } + + /** + * @return SurfaceInterface + */ + public function getSurface() + { + return $this->surface; + } + + public function getStack() + { + return $this->stack; + } + + public function getWidth() + { + return $this->width; + } + + public function getHeight() + { + return $this->height; + } + + public function getDimensions() { + $rootAttributes = null; + + $parser = xml_parser_create("utf-8"); + xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, false); + xml_set_element_handler( + $parser, + function ($parser, $name, $attributes) use (&$rootAttributes) { + if ($name === "svg" && $rootAttributes === null) { + $attributes = array_change_key_case($attributes, CASE_LOWER); + + $rootAttributes = $attributes; + } + }, + function ($parser, $name) {} + ); + + $fp = fopen($this->filename, "r"); + while ($line = fread($fp, 8192)) { + xml_parse($parser, $line, false); + + if ($rootAttributes !== null) { + break; + } + } + + xml_parser_free($parser); + + return $this->handleSizeAttributes($rootAttributes); + } + + public function handleSizeAttributes($attributes){ + if ($this->width === null) { + if (isset($attributes["width"])) { + $width = Style::convertSize($attributes["width"], 400); + $this->width = $width; + } + + if (isset($attributes["height"])) { + $height = Style::convertSize($attributes["height"], 300); + $this->height = $height; + } + + if (isset($attributes['viewbox'])) { + $viewBox = preg_split('/[\s,]+/is', trim($attributes['viewbox'])); + if (count($viewBox) == 4) { + $this->x = $viewBox[0]; + $this->y = $viewBox[1]; + + if (!$this->width) { + $this->width = $viewBox[2]; + } + if (!$this->height) { + $this->height = $viewBox[3]; + } + } + } + } + + return array( + 0 => $this->width, + 1 => $this->height, + + "width" => $this->width, + "height" => $this->height, + ); + } + + public function getDocument(){ + return $this; + } + + /** + * Append a style sheet + * + * @param \Sabberworm\CSS\CSSList\Document $stylesheet + */ + public function appendStyleSheet($stylesheet) { + $this->styleSheets[] = $stylesheet; + } + + /** + * Get the document style sheets + * + * @return \Sabberworm\CSS\CSSList\Document[] + */ + public function getStyleSheets() { + return $this->styleSheets; + } + + protected function before($attributes) + { + $surface = $this->getSurface(); + + $style = new DefaultStyle(); + $style->inherit($this); + $style->fromAttributes($attributes); + + $this->setStyle($style); + + $surface->setStyle($style); + } + + public function render(SurfaceInterface $surface) + { + $this->inDefs = false; + $this->surface = $surface; + + $parser = $this->initParser(); + + if ($this->x || $this->y) { + $surface->translate(-$this->x, -$this->y); + } + + $fp = fopen($this->filename, "r"); + while ($line = fread($fp, 8192)) { + xml_parse($parser, $line, false); + } + + xml_parse($parser, "", true); + + xml_parser_free($parser); + } + + protected function svgOffset($attributes) + { + $this->attributes = $attributes; + + $this->handleSizeAttributes($attributes); + } + + public function getDef($id) { + $id = ltrim($id, "#"); + + return isset($this->defs[$id]) ? $this->defs[$id] : null; + } + + private function _tagStart($parser, $name, $attributes) + { + $this->x = 0; + $this->y = 0; + + $tag = null; + + $attributes = array_change_key_case($attributes, CASE_LOWER); + + switch (strtolower($name)) { + case 'defs': + $this->inDefs = true; + return; + + case 'svg': + if (count($this->attributes)) { + $tag = new Group($this, $name); + } + else { + $tag = $this; + $this->svgOffset($attributes); + } + break; + + case 'path': + $tag = new Path($this, $name); + break; + + case 'rect': + $tag = new Rect($this, $name); + break; + + case 'circle': + $tag = new Circle($this, $name); + break; + + case 'ellipse': + $tag = new Ellipse($this, $name); + break; + + case 'image': + $tag = new Image($this, $name); + break; + + case 'line': + $tag = new Line($this, $name); + break; + + case 'polyline': + $tag = new Polyline($this, $name); + break; + + case 'polygon': + $tag = new Polygon($this, $name); + break; + + case 'lineargradient': + $tag = new LinearGradient($this, $name); + break; + + case 'radialgradient': + $tag = new LinearGradient($this, $name); + break; + + case 'stop': + $tag = new Stop($this, $name); + break; + + case 'style': + $tag = new StyleTag($this, $name); + break; + + case 'a': + $tag = new Anchor($this, $name); + break; + + case 'g': + case 'symbol': + $tag = new Group($this, $name); + break; + + case 'clippath': + $tag = new ClipPath($this, $name); + break; + + case 'use': + $tag = new UseTag($this, $name); + break; + + case 'text': + $tag = new Text($this, $name); + break; + + case 'desc': + return; + } + + if ($tag) { + if (isset($attributes["id"])) { + $this->defs[$attributes["id"]] = $tag; + } + else { + /** @var AbstractTag $top */ + $top = end($this->stack); + if ($top && $top != $tag) { + $top->children[] = $tag; + } + } + + $this->stack[] = $tag; + + $tag->handle($attributes); + } + } + + function _charData($parser, $data) + { + $stack_top = end($this->stack); + + if ($stack_top instanceof Text || $stack_top instanceof StyleTag) { + $stack_top->appendText($data); + } + } + + function _tagEnd($parser, $name) + { + /** @var AbstractTag $tag */ + $tag = null; + switch (strtolower($name)) { + case 'defs': + $this->inDefs = false; + return; + + case 'svg': + case 'path': + case 'rect': + case 'circle': + case 'ellipse': + case 'image': + case 'line': + case 'polyline': + case 'polygon': + case 'radialgradient': + case 'lineargradient': + case 'stop': + case 'style': + case 'text': + case 'g': + case 'symbol': + case 'clippath': + case 'use': + case 'a': + $tag = array_pop($this->stack); + break; + } + + if (!$this->inDefs && $tag) { + $tag->handleEnd(); + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php b/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php new file mode 100644 index 0000000..14a36bd --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Gradient/Stop.php @@ -0,0 +1,16 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Gradient; + +class Stop +{ + public $offset; + public $color; + public $opacity = 1.0; +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Style.php b/vendor/phenx/php-svg-lib/src/Svg/Style.php new file mode 100644 index 0000000..a007872 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Style.php @@ -0,0 +1,550 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg; + +use Svg\Tag\AbstractTag; + +class Style +{ + const TYPE_COLOR = 1; + const TYPE_LENGTH = 2; + const TYPE_NAME = 3; + const TYPE_ANGLE = 4; + const TYPE_NUMBER = 5; + + public $color; + public $opacity; + public $display; + + public $fill; + public $fillOpacity; + public $fillRule; + + public $stroke; + public $strokeOpacity; + public $strokeLinecap; + public $strokeLinejoin; + public $strokeMiterlimit; + public $strokeWidth; + public $strokeDasharray; + public $strokeDashoffset; + + public $fontFamily = 'serif'; + public $fontSize = 12; + public $fontWeight = 'normal'; + public $fontStyle = 'normal'; + public $textAnchor = 'start'; + + protected function getStyleMap() + { + return array( + 'color' => array('color', self::TYPE_COLOR), + 'opacity' => array('opacity', self::TYPE_NUMBER), + 'display' => array('display', self::TYPE_NAME), + + 'fill' => array('fill', self::TYPE_COLOR), + 'fill-opacity' => array('fillOpacity', self::TYPE_NUMBER), + 'fill-rule' => array('fillRule', self::TYPE_NAME), + + 'stroke' => array('stroke', self::TYPE_COLOR), + 'stroke-dasharray' => array('strokeDasharray', self::TYPE_NAME), + 'stroke-dashoffset' => array('strokeDashoffset', self::TYPE_NUMBER), + 'stroke-linecap' => array('strokeLinecap', self::TYPE_NAME), + 'stroke-linejoin' => array('strokeLinejoin', self::TYPE_NAME), + 'stroke-miterlimit' => array('strokeMiterlimit', self::TYPE_NUMBER), + 'stroke-opacity' => array('strokeOpacity', self::TYPE_NUMBER), + 'stroke-width' => array('strokeWidth', self::TYPE_NUMBER), + + 'font-family' => array('fontFamily', self::TYPE_NAME), + 'font-size' => array('fontSize', self::TYPE_NUMBER), + 'font-weight' => array('fontWeight', self::TYPE_NAME), + 'font-style' => array('fontStyle', self::TYPE_NAME), + 'text-anchor' => array('textAnchor', self::TYPE_NAME), + ); + } + + /** + * @param $attributes + * + * @return Style + */ + public function fromAttributes($attributes) + { + $this->fillStyles($attributes); + + if (isset($attributes["style"])) { + $styles = self::parseCssStyle($attributes["style"]); + $this->fillStyles($styles); + } + } + + public function inherit(AbstractTag $tag) { + $group = $tag->getParentGroup(); + if ($group) { + $parent_style = $group->getStyle(); + + foreach ($parent_style as $_key => $_value) { + if ($_value !== null) { + $this->$_key = $_value; + } + } + } + } + + public function fromStyleSheets(AbstractTag $tag, $attributes) { + $class = isset($attributes["class"]) ? preg_split('/\s+/', trim($attributes["class"])) : null; + + $stylesheets = $tag->getDocument()->getStyleSheets(); + + $styles = array(); + + foreach ($stylesheets as $_sc) { + + /** @var \Sabberworm\CSS\RuleSet\DeclarationBlock $_decl */ + foreach ($_sc->getAllDeclarationBlocks() as $_decl) { + + /** @var \Sabberworm\CSS\Property\Selector $_selector */ + foreach ($_decl->getSelectors() as $_selector) { + $_selector = $_selector->getSelector(); + + // Match class name + if ($class !== null) { + foreach ($class as $_class) { + if ($_selector === ".$_class") { + /** @var \Sabberworm\CSS\Rule\Rule $_rule */ + foreach ($_decl->getRules() as $_rule) { + $styles[$_rule->getRule()] = $_rule->getValue() . ""; + } + + break 2; + } + } + } + + // Match tag name + if ($_selector === $tag->tagName) { + /** @var \Sabberworm\CSS\Rule\Rule $_rule */ + foreach ($_decl->getRules() as $_rule) { + $styles[$_rule->getRule()] = $_rule->getValue() . ""; + } + + break; + } + } + } + } + + $this->fillStyles($styles); + } + + protected function fillStyles($styles) + { + foreach ($this->getStyleMap() as $from => $spec) { + if (isset($styles[$from])) { + list($to, $type) = $spec; + $value = null; + switch ($type) { + case self::TYPE_COLOR: + $value = self::parseColor($styles[$from]); + break; + + case self::TYPE_NUMBER: + $value = ($styles[$from] === null) ? null : (float)$styles[$from]; + break; + + default: + $value = $styles[$from]; + } + + if ($value !== null) { + $this->$to = $value; + } + } + } + } + + static function parseColor($color) + { + $color = strtolower(trim($color)); + + $parts = preg_split('/[^,]\s+/', $color, 2); + + if (count($parts) == 2) { + $color = $parts[1]; + } + else { + $color = $parts[0]; + } + + if ($color === "none") { + return "none"; + } + + // SVG color name + if (isset(self::$colorNames[$color])) { + return self::parseHexColor(self::$colorNames[$color]); + } + + // Hex color + if ($color[0] === "#") { + return self::parseHexColor($color); + } + + // RGB color + if (strpos($color, "rgb") !== false) { + return self::getTriplet($color); + } + + // RGB color + if (strpos($color, "hsl") !== false) { + $triplet = self::getTriplet($color, true); + + if ($triplet == null) { + return null; + } + + list($h, $s, $l) = $triplet; + + $r = $l; + $g = $l; + $b = $l; + $v = ($l <= 0.5) ? ($l * (1.0 + $s)) : ($l + $s - $l * $s); + if ($v > 0) { + $m = $l + $l - $v; + $sv = ($v - $m) / $v; + $h *= 6.0; + $sextant = floor($h); + $fract = $h - $sextant; + $vsf = $v * $sv * $fract; + $mid1 = $m + $vsf; + $mid2 = $v - $vsf; + + switch ($sextant) { + case 0: + $r = $v; + $g = $mid1; + $b = $m; + break; + case 1: + $r = $mid2; + $g = $v; + $b = $m; + break; + case 2: + $r = $m; + $g = $v; + $b = $mid1; + break; + case 3: + $r = $m; + $g = $mid2; + $b = $v; + break; + case 4: + $r = $mid1; + $g = $m; + $b = $v; + break; + case 5: + $r = $v; + $g = $m; + $b = $mid2; + break; + } + } + + return array( + $r * 255.0, + $g * 255.0, + $b * 255.0, + ); + } + + // Gradient + if (strpos($color, "url(#") !== false) { + $i = strpos($color, "("); + $j = strpos($color, ")"); + + // Bad url format + if ($i === false || $j === false) { + return null; + } + + return trim(substr($color, $i + 1, $j - $i - 1)); + } + + return null; + } + + static function getTriplet($color, $percent = false) { + $i = strpos($color, "("); + $j = strpos($color, ")"); + + // Bad color value + if ($i === false || $j === false) { + return null; + } + + $triplet = preg_split("/\\s*,\\s*/", trim(substr($color, $i + 1, $j - $i - 1))); + + if (count($triplet) != 3) { + return null; + } + + foreach (array_keys($triplet) as $c) { + $triplet[$c] = trim($triplet[$c]); + + if ($percent) { + if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") { + $triplet[$c] = floatval($triplet[$c]) / 100; + } + else { + $triplet[$c] = $triplet[$c] / 255; + } + } + else { + if ($triplet[$c][strlen($triplet[$c]) - 1] === "%") { + $triplet[$c] = round(floatval($triplet[$c]) * 2.55); + } + } + } + + return $triplet; + } + + static function parseHexColor($hex) + { + $c = array(0, 0, 0); + + // #FFFFFF + if (isset($hex[6])) { + $c[0] = hexdec(substr($hex, 1, 2)); + $c[1] = hexdec(substr($hex, 3, 2)); + $c[2] = hexdec(substr($hex, 5, 2)); + } else { + $c[0] = hexdec($hex[1] . $hex[1]); + $c[1] = hexdec($hex[2] . $hex[2]); + $c[2] = hexdec($hex[3] . $hex[3]); + } + + return $c; + } + + /** + * Simple CSS parser + * + * @param $style + * + * @return array + */ + static function parseCssStyle($style) + { + $matches = array(); + preg_match_all("/([a-z-]+)\\s*:\\s*([^;$]+)/si", $style, $matches, PREG_SET_ORDER); + + $styles = array(); + foreach ($matches as $match) { + $styles[$match[1]] = $match[2]; + } + + return $styles; + } + + /** + * Convert a size to a float + * + * @param string $size SVG size + * @param float $dpi DPI + * @param float $referenceSize Reference size + * + * @return float|null + */ + static function convertSize($size, $referenceSize = 11.0, $dpi = 96.0) { + $size = trim(strtolower($size)); + + if (is_numeric($size)) { + return $size; + } + + if ($pos = strpos($size, "px")) { + return floatval(substr($size, 0, $pos)); + } + + if ($pos = strpos($size, "pt")) { + return floatval(substr($size, 0, $pos)); + } + + if ($pos = strpos($size, "cm")) { + return floatval(substr($size, 0, $pos)) * $dpi; + } + + if ($pos = strpos($size, "%")) { + return $referenceSize * substr($size, 0, $pos) / 100; + } + + if ($pos = strpos($size, "em")) { + return $referenceSize * substr($size, 0, $pos); + } + + // TODO cm, mm, pc, in, etc + + return null; + } + + static $colorNames = array( + 'antiquewhite' => '#FAEBD7', + 'aqua' => '#00FFFF', + 'aquamarine' => '#7FFFD4', + 'beige' => '#F5F5DC', + 'black' => '#000000', + 'blue' => '#0000FF', + 'brown' => '#A52A2A', + 'cadetblue' => '#5F9EA0', + 'chocolate' => '#D2691E', + 'cornflowerblue' => '#6495ED', + 'crimson' => '#DC143C', + 'darkblue' => '#00008B', + 'darkgoldenrod' => '#B8860B', + 'darkgreen' => '#006400', + 'darkmagenta' => '#8B008B', + 'darkorange' => '#FF8C00', + 'darkred' => '#8B0000', + 'darkseagreen' => '#8FBC8F', + 'darkslategray' => '#2F4F4F', + 'darkviolet' => '#9400D3', + 'deepskyblue' => '#00BFFF', + 'dodgerblue' => '#1E90FF', + 'firebrick' => '#B22222', + 'forestgreen' => '#228B22', + 'fuchsia' => '#FF00FF', + 'gainsboro' => '#DCDCDC', + 'gold' => '#FFD700', + 'gray' => '#808080', + 'green' => '#008000', + 'greenyellow' => '#ADFF2F', + 'hotpink' => '#FF69B4', + 'indigo' => '#4B0082', + 'khaki' => '#F0E68C', + 'lavenderblush' => '#FFF0F5', + 'lemonchiffon' => '#FFFACD', + 'lightcoral' => '#F08080', + 'lightgoldenrodyellow' => '#FAFAD2', + 'lightgreen' => '#90EE90', + 'lightsalmon' => '#FFA07A', + 'lightskyblue' => '#87CEFA', + 'lightslategray' => '#778899', + 'lightyellow' => '#FFFFE0', + 'lime' => '#00FF00', + 'limegreen' => '#32CD32', + 'magenta' => '#FF00FF', + 'maroon' => '#800000', + 'mediumaquamarine' => '#66CDAA', + 'mediumorchid' => '#BA55D3', + 'mediumseagreen' => '#3CB371', + 'mediumspringgreen' => '#00FA9A', + 'mediumvioletred' => '#C71585', + 'midnightblue' => '#191970', + 'mintcream' => '#F5FFFA', + 'moccasin' => '#FFE4B5', + 'navy' => '#000080', + 'olive' => '#808000', + 'orange' => '#FFA500', + 'orchid' => '#DA70D6', + 'palegreen' => '#98FB98', + 'palevioletred' => '#D87093', + 'peachpuff' => '#FFDAB9', + 'pink' => '#FFC0CB', + 'powderblue' => '#B0E0E6', + 'purple' => '#800080', + 'red' => '#FF0000', + 'royalblue' => '#4169E1', + 'salmon' => '#FA8072', + 'seagreen' => '#2E8B57', + 'sienna' => '#A0522D', + 'silver' => '#C0C0C0', + 'skyblue' => '#87CEEB', + 'slategray' => '#708090', + 'springgreen' => '#00FF7F', + 'steelblue' => '#4682B4', + 'tan' => '#D2B48C', + 'teal' => '#008080', + 'thistle' => '#D8BFD8', + 'turquoise' => '#40E0D0', + 'violetred' => '#D02090', + 'white' => '#FFFFFF', + 'yellow' => '#FFFF00', + 'aliceblue' => '#f0f8ff', + 'azure' => '#f0ffff', + 'bisque' => '#ffe4c4', + 'blanchedalmond' => '#ffebcd', + 'blueviolet' => '#8a2be2', + 'burlywood' => '#deb887', + 'chartreuse' => '#7fff00', + 'coral' => '#ff7f50', + 'cornsilk' => '#fff8dc', + 'cyan' => '#00ffff', + 'darkcyan' => '#008b8b', + 'darkgray' => '#a9a9a9', + 'darkgrey' => '#a9a9a9', + 'darkkhaki' => '#bdb76b', + 'darkolivegreen' => '#556b2f', + 'darkorchid' => '#9932cc', + 'darksalmon' => '#e9967a', + 'darkslateblue' => '#483d8b', + 'darkslategrey' => '#2f4f4f', + 'darkturquoise' => '#00ced1', + 'deeppink' => '#ff1493', + 'dimgray' => '#696969', + 'dimgrey' => '#696969', + 'floralwhite' => '#fffaf0', + 'ghostwhite' => '#f8f8ff', + 'goldenrod' => '#daa520', + 'grey' => '#808080', + 'honeydew' => '#f0fff0', + 'indianred' => '#cd5c5c', + 'ivory' => '#fffff0', + 'lavender' => '#e6e6fa', + 'lawngreen' => '#7cfc00', + 'lightblue' => '#add8e6', + 'lightcyan' => '#e0ffff', + 'lightgray' => '#d3d3d3', + 'lightgrey' => '#d3d3d3', + 'lightpink' => '#ffb6c1', + 'lightseagreen' => '#20b2aa', + 'lightslategrey' => '#778899', + 'lightsteelblue' => '#b0c4de', + 'linen' => '#faf0e6', + 'mediumblue' => '#0000cd', + 'mediumpurple' => '#9370db', + 'mediumslateblue' => '#7b68ee', + 'mediumturquoise' => '#48d1cc', + 'mistyrose' => '#ffe4e1', + 'navajowhite' => '#ffdead', + 'oldlace' => '#fdf5e6', + 'olivedrab' => '#6b8e23', + 'orangered' => '#ff4500', + 'palegoldenrod' => '#eee8aa', + 'paleturquoise' => '#afeeee', + 'papayawhip' => '#ffefd5', + 'peru' => '#cd853f', + 'plum' => '#dda0dd', + 'rosybrown' => '#bc8f8f', + 'saddlebrown' => '#8b4513', + 'sandybrown' => '#f4a460', + 'seashell' => '#fff5ee', + 'slateblue' => '#6a5acd', + 'slategrey' => '#708090', + 'snow' => '#fffafa', + 'tomato' => '#ff6347', + 'violet' => '#ee82ee', + 'wheat' => '#f5deb3', + 'whitesmoke' => '#f5f5f5', + 'yellowgreen' => '#9acd32', + ); +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php new file mode 100644 index 0000000..2dce8f3 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/CPdf.php @@ -0,0 +1,4768 @@ + + * @author Orion Richardson + * @author Helmut Tischer + * @author Ryan H. Masten + * @author Brian Sweeney + * @author Fabien Ménager + * @license Public Domain http://creativecommons.org/licenses/publicdomain/ + * @package Cpdf + */ + +namespace Svg\Surface; + +class CPdf +{ + + /** + * @var integer The current number of pdf objects in the document + */ + public $numObj = 0; + + /** + * @var array This array contains all of the pdf objects, ready for final assembly + */ + public $objects = array(); + + /** + * @var integer The objectId (number within the objects array) of the document catalog + */ + public $catalogId; + + /** + * @var array Array carrying information about the fonts that the system currently knows about + * Used to ensure that a font is not loaded twice, among other things + */ + public $fonts = array(); + + /** + * @var string The default font metrics file to use if no other font has been loaded. + * The path to the directory containing the font metrics should be included + */ + public $defaultFont = './fonts/Helvetica.afm'; + + /** + * @string A record of the current font + */ + public $currentFont = ''; + + /** + * @var string The current base font + */ + public $currentBaseFont = ''; + + /** + * @var integer The number of the current font within the font array + */ + public $currentFontNum = 0; + + /** + * @var integer + */ + public $currentNode; + + /** + * @var integer Object number of the current page + */ + public $currentPage; + + /** + * @var integer Object number of the currently active contents block + */ + public $currentContents; + + /** + * @var integer Number of fonts within the system + */ + public $numFonts = 0; + + /** + * @var integer Number of graphic state resources used + */ + private $numStates = 0; + + /** + * @var array Current color for fill operations, defaults to inactive value, + * all three components should be between 0 and 1 inclusive when active + */ + public $currentColor = null; + + /** + * @var string Fill rule (nonzero or evenodd) + */ + public $fillRule = "nonzero"; + + /** + * @var array Current color for stroke operations (lines etc.) + */ + public $currentStrokeColor = null; + + /** + * @var string Current style that lines are drawn in + */ + public $currentLineStyle = ''; + + /** + * @var array Current line transparency (partial graphics state) + */ + public $currentLineTransparency = array("mode" => "Normal", "opacity" => 1.0); + + /** + * array Current fill transparency (partial graphics state) + */ + public $currentFillTransparency = array("mode" => "Normal", "opacity" => 1.0); + + /** + * @var array An array which is used to save the state of the document, mainly the colors and styles + * it is used to temporarily change to another state, the change back to what it was before + */ + public $stateStack = array(); + + /** + * @var integer Number of elements within the state stack + */ + public $nStateStack = 0; + + /** + * @var integer Number of page objects within the document + */ + public $numPages = 0; + + /** + * @var array Object Id storage stack + */ + public $stack = array(); + + /** + * @var integer Number of elements within the object Id storage stack + */ + public $nStack = 0; + + /** + * an array which contains information about the objects which are not firmly attached to pages + * these have been added with the addObject function + */ + public $looseObjects = array(); + + /** + * array contains infomation about how the loose objects are to be added to the document + */ + public $addLooseObjects = array(); + + /** + * @var integer The objectId of the information object for the document + * this contains authorship, title etc. + */ + public $infoObject = 0; + + /** + * @var integer Number of images being tracked within the document + */ + public $numImages = 0; + + /** + * @var array An array containing options about the document + * it defaults to turning on the compression of the objects + */ + public $options = array('compression' => true); + + /** + * @var integer The objectId of the first page of the document + */ + public $firstPageId; + + /** + * @var float Used to track the last used value of the inter-word spacing, this is so that it is known + * when the spacing is changed. + */ + public $wordSpaceAdjust = 0; + + /** + * @var float Used to track the last used value of the inter-letter spacing, this is so that it is known + * when the spacing is changed. + */ + public $charSpaceAdjust = 0; + + /** + * @var integer The object Id of the procset object + */ + public $procsetObjectId; + + /** + * @var array Store the information about the relationship between font families + * this used so that the code knows which font is the bold version of another font, etc. + * the value of this array is initialised in the constuctor function. + */ + public $fontFamilies = array(); + + /** + * @var string Folder for php serialized formats of font metrics files. + * If empty string, use same folder as original metrics files. + * This can be passed in from class creator. + * If this folder does not exist or is not writable, Cpdf will be **much** slower. + * Because of potential trouble with php safe mode, folder cannot be created at runtime. + */ + public $fontcache = ''; + + /** + * @var integer The version of the font metrics cache file. + * This value must be manually incremented whenever the internal font data structure is modified. + */ + public $fontcacheVersion = 6; + + /** + * @var string Temporary folder. + * If empty string, will attempty system tmp folder. + * This can be passed in from class creator. + * Only used for conversion of gd images to jpeg images. + */ + public $tmp = ''; + + /** + * @var string Track if the current font is bolded or italicised + */ + public $currentTextState = ''; + + /** + * @var string Messages are stored here during processing, these can be selected afterwards to give some useful debug information + */ + public $messages = ''; + + /** + * @var string The ancryption array for the document encryption is stored here + */ + public $arc4 = ''; + + /** + * @var integer The object Id of the encryption information + */ + public $arc4_objnum = 0; + + /** + * @var string The file identifier, used to uniquely identify a pdf document + */ + public $fileIdentifier = ''; + + /** + * @var boolean A flag to say if a document is to be encrypted or not + */ + public $encrypted = false; + + /** + * @var string The encryption key for the encryption of all the document content (structure is not encrypted) + */ + public $encryptionKey = ''; + + /** + * @var array Array which forms a stack to keep track of nested callback functions + */ + public $callback = array(); + + /** + * @var integer The number of callback functions in the callback array + */ + public $nCallback = 0; + + /** + * @var array Store label->id pairs for named destinations, these will be used to replace internal links + * done this way so that destinations can be defined after the location that links to them + */ + public $destinations = array(); + + /** + * @var array Store the stack for the transaction commands, each item in here is a record of the values of all the + * publiciables within the class, so that the user can rollback at will (from each 'start' command) + * note that this includes the objects array, so these can be large. + */ + public $checkpoint = ''; + + /** + * @var array Table of Image origin filenames and image labels which were already added with o_image(). + * Allows to merge identical images + */ + public $imagelist = array(); + + /** + * @var boolean Whether the text passed in should be treated as Unicode or just local character set. + */ + public $isUnicode = false; + + /** + * @var string the JavaScript code of the document + */ + public $javascript = ''; + + /** + * @var boolean whether the compression is possible + */ + protected $compressionReady = false; + + /** + * @var array Current page size + */ + protected $currentPageSize = array("width" => 0, "height" => 0); + + /** + * @var array All the chars that will be required in the font subsets + */ + protected $stringSubsets = array(); + + /** + * @var string The target internal encoding + */ + static protected $targetEncoding = 'iso-8859-1'; + + /** + * @var array The list of the core fonts + */ + static protected $coreFonts = array( + 'courier', + 'courier-bold', + 'courier-oblique', + 'courier-boldoblique', + 'helvetica', + 'helvetica-bold', + 'helvetica-oblique', + 'helvetica-boldoblique', + 'times-roman', + 'times-bold', + 'times-italic', + 'times-bolditalic', + 'symbol', + 'zapfdingbats' + ); + + /** + * Class constructor + * This will start a new document + * + * @param array $pageSize Array of 4 numbers, defining the bottom left and upper right corner of the page. first two are normally zero. + * @param boolean $isUnicode Whether text will be treated as Unicode or not. + * @param string $fontcache The font cache folder + * @param string $tmp The temporary folder + */ + function __construct($pageSize = array(0, 0, 612, 792), $isUnicode = false, $fontcache = '', $tmp = '') + { + $this->isUnicode = $isUnicode; + $this->fontcache = $fontcache; + $this->tmp = $tmp; + $this->newDocument($pageSize); + + $this->compressionReady = function_exists('gzcompress'); + + if (in_array('Windows-1252', mb_list_encodings())) { + self::$targetEncoding = 'Windows-1252'; + } + + // also initialize the font families that are known about already + $this->setFontFamily('init'); + // $this->fileIdentifier = md5('xxxxxxxx'.time()); + } + + /** + * Document object methods (internal use only) + * + * There is about one object method for each type of object in the pdf document + * Each function has the same call list ($id,$action,$options). + * $id = the object ID of the object, or what it is to be if it is being created + * $action = a string specifying the action to be performed, though ALL must support: + * 'new' - create the object with the id $id + * 'out' - produce the output for the pdf object + * $options = optional, a string or array containing the various parameters for the object + * + * These, in conjunction with the output function are the ONLY way for output to be produced + * within the pdf 'file'. + */ + + /** + * Destination object, used to specify the location for the user to jump to, presently on opening + */ + protected function o_destination($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'destination', 'info' => array()); + $tmp = ''; + switch ($options['type']) { + case 'XYZ': + case 'FitR': + $tmp = ' ' . $options['p3'] . $tmp; + case 'FitH': + case 'FitV': + case 'FitBH': + case 'FitBV': + $tmp = ' ' . $options['p1'] . ' ' . $options['p2'] . $tmp; + case 'Fit': + case 'FitB': + $tmp = $options['type'] . $tmp; + $this->objects[$id]['info']['string'] = $tmp; + $this->objects[$id]['info']['page'] = $options['page']; + } + break; + + case 'out': + $tmp = $o['info']; + $res = "\n$id 0 obj\n" . '[' . $tmp['page'] . ' 0 R /' . $tmp['string'] . "]\nendobj"; + + return $res; + } + } + + /** + * set the viewer preferences + */ + protected function o_viewerPreferences($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'viewerPreferences', 'info' => array()); + break; + + case 'add': + foreach ($options as $k => $v) { + switch ($k) { + case 'HideToolbar': + case 'HideMenubar': + case 'HideWindowUI': + case 'FitWindow': + case 'CenterWindow': + case 'NonFullScreenPageMode': + case 'Direction': + $o['info'][$k] = $v; + break; + } + } + break; + + case 'out': + $res = "\n$id 0 obj\n<< "; + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\n"; + + return $res; + } + } + + /** + * define the document catalog, the overall controller for the document + */ + protected function o_catalog($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'catalog', 'info' => array()); + $this->catalogId = $id; + break; + + case 'outlines': + case 'pages': + case 'openHere': + case 'javascript': + $o['info'][$action] = $options; + break; + + case 'viewerPreferences': + if (!isset($o['info']['viewerPreferences'])) { + $this->numObj++; + $this->o_viewerPreferences($this->numObj, 'new'); + $o['info']['viewerPreferences'] = $this->numObj; + } + + $vp = $o['info']['viewerPreferences']; + $this->o_viewerPreferences($vp, 'add', $options); + + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Catalog"; + + foreach ($o['info'] as $k => $v) { + switch ($k) { + case 'outlines': + $res .= "\n/Outlines $v 0 R"; + break; + + case 'pages': + $res .= "\n/Pages $v 0 R"; + break; + + case 'viewerPreferences': + $res .= "\n/ViewerPreferences $v 0 R"; + break; + + case 'openHere': + $res .= "\n/OpenAction $v 0 R"; + break; + + case 'javascript': + $res .= "\n/Names <>"; + break; + } + } + + $res .= " >>\nendobj"; + + return $res; + } + } + + /** + * object which is a parent to the pages in the document + */ + protected function o_pages($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'pages', 'info' => array()); + $this->o_catalog($this->catalogId, 'pages', $id); + break; + + case 'page': + if (!is_array($options)) { + // then it will just be the id of the new page + $o['info']['pages'][] = $options; + } else { + // then it should be an array having 'id','rid','pos', where rid=the page to which this one will be placed relative + // and pos is either 'before' or 'after', saying where this page will fit. + if (isset($options['id']) && isset($options['rid']) && isset($options['pos'])) { + $i = array_search($options['rid'], $o['info']['pages']); + if (isset($o['info']['pages'][$i]) && $o['info']['pages'][$i] == $options['rid']) { + + // then there is a match + // make a space + switch ($options['pos']) { + case 'before': + $k = $i; + break; + + case 'after': + $k = $i + 1; + break; + + default: + $k = -1; + break; + } + + if ($k >= 0) { + for ($j = count($o['info']['pages']) - 1; $j >= $k; $j--) { + $o['info']['pages'][$j + 1] = $o['info']['pages'][$j]; + } + + $o['info']['pages'][$k] = $options['id']; + } + } + } + } + break; + + case 'procset': + $o['info']['procset'] = $options; + break; + + case 'mediaBox': + $o['info']['mediaBox'] = $options; + // which should be an array of 4 numbers + $this->currentPageSize = array('width' => $options[2], 'height' => $options[3]); + break; + + case 'font': + $o['info']['fonts'][] = array('objNum' => $options['objNum'], 'fontNum' => $options['fontNum']); + break; + + case 'extGState': + $o['info']['extGStates'][] = array('objNum' => $options['objNum'], 'stateNum' => $options['stateNum']); + break; + + case 'xObject': + $o['info']['xObjects'][] = array('objNum' => $options['objNum'], 'label' => $options['label']); + break; + + case 'out': + if (count($o['info']['pages'])) { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Kids ["; + foreach ($o['info']['pages'] as $v) { + $res .= "$v 0 R\n"; + } + + $res .= "]\n/Count " . count($this->objects[$id]['info']['pages']); + + if ((isset($o['info']['fonts']) && count($o['info']['fonts'])) || + isset($o['info']['procset']) || + (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) + ) { + $res .= "\n/Resources <<"; + + if (isset($o['info']['procset'])) { + $res .= "\n/ProcSet " . $o['info']['procset'] . " 0 R"; + } + + if (isset($o['info']['fonts']) && count($o['info']['fonts'])) { + $res .= "\n/Font << "; + foreach ($o['info']['fonts'] as $finfo) { + $res .= "\n/F" . $finfo['fontNum'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['xObjects']) && count($o['info']['xObjects'])) { + $res .= "\n/XObject << "; + foreach ($o['info']['xObjects'] as $finfo) { + $res .= "\n/" . $finfo['label'] . " " . $finfo['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + if (isset($o['info']['extGStates']) && count($o['info']['extGStates'])) { + $res .= "\n/ExtGState << "; + foreach ($o['info']['extGStates'] as $gstate) { + $res .= "\n/GS" . $gstate['stateNum'] . " " . $gstate['objNum'] . " 0 R"; + } + $res .= "\n>>"; + } + + $res .= "\n>>"; + if (isset($o['info']['mediaBox'])) { + $tmp = $o['info']['mediaBox']; + $res .= "\n/MediaBox [" . sprintf( + '%.3F %.3F %.3F %.3F', + $tmp[0], + $tmp[1], + $tmp[2], + $tmp[3] + ) . ']'; + } + } + + $res .= "\n >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Pages\n/Count 0\n>>\nendobj"; + } + + return $res; + } + } + + /** + * define the outlines in the doc, empty for now + */ + protected function o_outlines($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'outlines', 'info' => array('outlines' => array())); + $this->o_catalog($this->catalogId, 'outlines', $id); + break; + + case 'outline': + $o['info']['outlines'][] = $options; + break; + + case 'out': + if (count($o['info']['outlines'])) { + $res = "\n$id 0 obj\n<< /Type /Outlines /Kids ["; + foreach ($o['info']['outlines'] as $v) { + $res .= "$v 0 R "; + } + + $res .= "] /Count " . count($o['info']['outlines']) . " >>\nendobj"; + } else { + $res = "\n$id 0 obj\n<< /Type /Outlines /Count 0 >>\nendobj"; + } + + return $res; + } + } + + /** + * an object to hold the font description + */ + protected function o_font($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array( + 't' => 'font', + 'info' => array( + 'name' => $options['name'], + 'fontFileName' => $options['fontFileName'], + 'SubType' => 'Type1' + ) + ); + $fontNum = $this->numFonts; + $this->objects[$id]['info']['fontNum'] = $fontNum; + + // deal with the encoding and the differences + if (isset($options['differences'])) { + // then we'll need an encoding dictionary + $this->numObj++; + $this->o_fontEncoding($this->numObj, 'new', $options); + $this->objects[$id]['info']['encodingDictionary'] = $this->numObj; + } else { + if (isset($options['encoding'])) { + // we can specify encoding here + switch ($options['encoding']) { + case 'WinAnsiEncoding': + case 'MacRomanEncoding': + case 'MacExpertEncoding': + $this->objects[$id]['info']['encoding'] = $options['encoding']; + break; + + case 'none': + break; + + default: + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + break; + } + } else { + $this->objects[$id]['info']['encoding'] = 'WinAnsiEncoding'; + } + } + + if ($this->fonts[$options['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more informaiton. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $toUnicodeId = ++$this->numObj; + $this->o_contents($toUnicodeId, 'new', 'raw'); + $this->objects[$id]['info']['toUnicode'] = $toUnicodeId; + + $stream = <<> def +/CMapName /Adobe-Identity-UCS def +/CMapType 2 def +1 begincodespacerange +<0000> +endcodespacerange +1 beginbfrange +<0000> <0000> +endbfrange +endcmap +CMapName currentdict /CMap defineresource pop +end +end +EOT; + + $res = "<>\n"; + $res .= "stream\n" . $stream . "endstream"; + + $this->objects[$toUnicodeId]['c'] = $res; + + $cidFontId = ++$this->numObj; + $this->o_fontDescendentCID($cidFontId, 'new', $options); + $this->objects[$id]['info']['cidFont'] = $cidFontId; + } + + // also tell the pages node about the new font + $this->o_pages($this->currentNode, 'font', array('fontNum' => $fontNum, 'objNum' => $id)); + break; + + case 'add': + foreach ($options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + case 'FirstChar': + case 'LastChar': + case 'Widths': + case 'FontDescriptor': + case 'SubType': + $this->addMessage('o_font ' . $k . " : " . $v); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to descendent font + if (isset($o['info']['cidFont'])) { + $this->o_fontDescendentCID($o['info']['cidFont'], 'add', $options); + } + break; + + case 'out': + if ($this->fonts[$this->objects[$id]['info']['fontFileName']]['isUnicode']) { + // For Unicode fonts, we need to incorporate font data into + // sub-sections that are linked from the primary font section. + // Look at o_fontGIDtoCID and o_fontDescendentCID functions + // for more informaiton. + // + // All of this code is adapted from the excellent changes made to + // transform FPDF to TCPDF (http://tcpdf.sourceforge.net/) + + $res = "\n$id 0 obj\n<objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'fontDescriptor', 'info' => $options); + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /FontDescriptor\n"; + foreach ($o['info'] as $label => $value) { + switch ($label) { + case 'Ascent': + case 'CapHeight': + case 'Descent': + case 'Flags': + case 'ItalicAngle': + case 'StemV': + case 'AvgWidth': + case 'Leading': + case 'MaxWidth': + case 'MissingWidth': + case 'StemH': + case 'XHeight': + case 'CharSet': + if (mb_strlen($value, '8bit')) { + $res .= "/$label $value\n"; + } + + break; + case 'FontFile': + case 'FontFile2': + case 'FontFile3': + $res .= "/$label $value 0 R\n"; + break; + + case 'FontBBox': + $res .= "/$label [$value[0] $value[1] $value[2] $value[3]]\n"; + break; + + case 'FontName': + $res .= "/$label /$value\n"; + break; + } + } + + $res .= ">>\nendobj"; + + return $res; + } + } + + /** + * the font encoding + */ + protected function o_fontEncoding($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // the options array should contain 'differences' and maybe 'encoding' + $this->objects[$id] = array('t' => 'fontEncoding', 'info' => $options); + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Encoding\n"; + if (!isset($o['info']['encoding'])) { + $o['info']['encoding'] = 'WinAnsiEncoding'; + } + + if ($o['info']['encoding'] !== 'none') { + $res .= "/BaseEncoding /" . $o['info']['encoding'] . "\n"; + } + + $res .= "/Differences \n["; + + $onum = -100; + + foreach ($o['info']['differences'] as $num => $label) { + if ($num != $onum + 1) { + // we cannot make use of consecutive numbering + $res .= "\n$num /$label"; + } else { + $res .= " /$label"; + } + + $onum = $num; + } + + $res .= "\n]\n>>\nendobj"; + + return $res; + } + } + + /** + * a descendent cid font, needed for unicode fonts + */ + protected function o_fontDescendentCID($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'fontDescendentCID', 'info' => $options); + + // we need a CID system info section + $cidSystemInfoId = ++$this->numObj; + $this->o_contents($cidSystemInfoId, 'new', 'raw'); + $this->objects[$id]['info']['cidSystemInfo'] = $cidSystemInfoId; + $res = "<objects[$cidSystemInfoId]['c'] = $res; + + // and a CID to GID map + $cidToGidMapId = ++$this->numObj; + $this->o_fontGIDtoCIDMap($cidToGidMapId, 'new', $options); + $this->objects[$id]['info']['cidToGidMap'] = $cidToGidMapId; + break; + + case 'add': + foreach ($options as $k => $v) { + switch ($k) { + case 'BaseFont': + $o['info']['name'] = $v; + break; + + case 'FirstChar': + case 'LastChar': + case 'MissingWidth': + case 'FontDescriptor': + case 'SubType': + $this->addMessage("o_fontDescendentCID $k : $v"); + $o['info'][$k] = $v; + break; + } + } + + // pass values down to cid to gid map + $this->o_fontGIDtoCIDMap($o['info']['cidToGidMap'], 'add', $options); + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $res .= "<fonts[$o['info']['fontFileName']]['CIDWidths'])) { + $cid_widths = &$this->fonts[$o['info']['fontFileName']]['CIDWidths']; + $w = ''; + foreach ($cid_widths as $cid => $width) { + $w .= "$cid [$width] "; + } + $res .= "/W [$w]\n"; + } + + $res .= "/CIDToGIDMap " . $o['info']['cidToGidMap'] . " 0 R\n"; + $res .= ">>\n"; + $res .= "endobj"; + + return $res; + } + } + + /** + * a font glyph to character map, needed for unicode fonts + */ + protected function o_fontGIDtoCIDMap($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'fontGIDtoCIDMap', 'info' => $options); + break; + + case 'out': + $res = "\n$id 0 obj\n"; + $fontFileName = $o['info']['fontFileName']; + $tmp = $this->fonts[$fontFileName]['CIDtoGID'] = base64_decode($this->fonts[$fontFileName]['CIDtoGID']); + + $compressed = isset($this->fonts[$fontFileName]['CIDtoGID_Compressed']) && + $this->fonts[$fontFileName]['CIDtoGID_Compressed']; + + if (!$compressed && isset($o['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + + if (!$compressed && $this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $compressed = true; + $tmp = gzcompress($tmp, 6); + } + if ($compressed) { + $res .= "\n/Filter /FlateDecode"; + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + } + + /** + * the document procset, solves some problems with printing to old PS printers + */ + protected function o_procset($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'procset', 'info' => array('PDF' => 1, 'Text' => 1)); + $this->o_pages($this->currentNode, 'procset', $id); + $this->procsetObjectId = $id; + break; + + case 'add': + // this is to add new items to the procset list, despite the fact that this is considered + // obselete, the items are required for printing to some postscript printers + switch ($options) { + case 'ImageB': + case 'ImageC': + case 'ImageI': + $o['info'][$options] = 1; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n["; + foreach ($o['info'] as $label => $val) { + $res .= "/$label "; + } + $res .= "]\nendobj"; + + return $res; + } + } + + /** + * define the document information + */ + protected function o_info($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->infoObject = $id; + $date = 'D:' . @date('Ymd'); + $this->objects[$id] = array( + 't' => 'info', + 'info' => array( + 'Creator' => 'R and OS php pdf writer, http://www.ros.co.nz', + 'CreationDate' => $date + ) + ); + break; + case 'Title': + case 'Author': + case 'Subject': + case 'Keywords': + case 'Creator': + case 'Producer': + case 'CreationDate': + case 'ModDate': + case 'Trapped': + $o['info'][$action] = $options; + break; + + case 'out': + if ($this->encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<<\n"; + foreach ($o['info'] as $k => $v) { + $res .= "/$k ("; + + if ($this->encrypted) { + $v = $this->ARC4($v); + } // dates must be outputted as-is, without Unicode transformations + elseif (!in_array($k, array('CreationDate', 'ModDate'))) { + $v = $this->filterText($v); + } + + $res .= $v; + $res .= ")\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + } + + /** + * an action object, used to link to URLS initially + */ + protected function o_action($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + if (is_array($options)) { + $this->objects[$id] = array('t' => 'action', 'info' => $options, 'type' => $options['type']); + } else { + // then assume a URI action + $this->objects[$id] = array('t' => 'action', 'info' => $options, 'type' => 'URI'); + } + break; + + case 'out': + if ($this->encrypted) { + $this->encryptInit($id); + } + + $res = "\n$id 0 obj\n<< /Type /Action"; + switch ($o['type']) { + case 'ilink': + if (!isset($this->destinations[(string)$o['info']['label']])) { + break; + } + + // there will be an 'label' setting, this is the name of the destination + $res .= "\n/S /GoTo\n/D " . $this->destinations[(string)$o['info']['label']] . " 0 R"; + break; + + case 'URI': + $res .= "\n/S /URI\n/URI ("; + if ($this->encrypted) { + $res .= $this->filterText($this->ARC4($o['info']), true, false); + } else { + $res .= $this->filterText($o['info'], true, false); + } + + $res .= ")"; + break; + } + + $res .= "\n>>\nendobj"; + + return $res; + } + } + + /** + * an annotation object, this will add an annotation to the current page. + * initially will support just link annotations + */ + protected function o_annotation($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // add the annotation to the current page + $pageId = $this->currentPage; + $this->o_page($pageId, 'annot', $id); + + // and add the action object which is going to be required + switch ($options['type']) { + case 'link': + $this->objects[$id] = array('t' => 'annotation', 'info' => $options); + $this->numObj++; + $this->o_action($this->numObj, 'new', $options['url']); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + + case 'ilink': + // this is to a named internal link + $label = $options['label']; + $this->objects[$id] = array('t' => 'annotation', 'info' => $options); + $this->numObj++; + $this->o_action($this->numObj, 'new', array('type' => 'ilink', 'label' => $label)); + $this->objects[$id]['info']['actionId'] = $this->numObj; + break; + } + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Annot"; + switch ($o['info']['type']) { + case 'link': + case 'ilink': + $res .= "\n/Subtype /Link"; + break; + } + $res .= "\n/A " . $o['info']['actionId'] . " 0 R"; + $res .= "\n/Border [0 0 0]"; + $res .= "\n/H /I"; + $res .= "\n/Rect [ "; + + foreach ($o['info']['rect'] as $v) { + $res .= sprintf("%.4F ", $v); + } + + $res .= "]"; + $res .= "\n>>\nendobj"; + + return $res; + } + } + + /** + * a page object, it also creates a contents object to hold its contents + */ + protected function o_page($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->numPages++; + $this->objects[$id] = array( + 't' => 'page', + 'info' => array( + 'parent' => $this->currentNode, + 'pageNum' => $this->numPages + ) + ); + + if (is_array($options)) { + // then this must be a page insertion, array should contain 'rid','pos'=[before|after] + $options['id'] = $id; + $this->o_pages($this->currentNode, 'page', $options); + } else { + $this->o_pages($this->currentNode, 'page', $id); + } + + $this->currentPage = $id; + //make a contents object to go with this page + $this->numObj++; + $this->o_contents($this->numObj, 'new', $id); + $this->currentContents = $this->numObj; + $this->objects[$id]['info']['contents'] = array(); + $this->objects[$id]['info']['contents'][] = $this->numObj; + + $match = ($this->numPages % 2 ? 'odd' : 'even'); + foreach ($this->addLooseObjects as $oId => $target) { + if ($target === 'all' || $match === $target) { + $this->objects[$id]['info']['contents'][] = $oId; + } + } + break; + + case 'content': + $o['info']['contents'][] = $options; + break; + + case 'annot': + // add an annotation to this page + if (!isset($o['info']['annot'])) { + $o['info']['annot'] = array(); + } + + // $options should contain the id of the annotation dictionary + $o['info']['annot'][] = $options; + break; + + case 'out': + $res = "\n$id 0 obj\n<< /Type /Page"; + $res .= "\n/Parent " . $o['info']['parent'] . " 0 R"; + + if (isset($o['info']['annot'])) { + $res .= "\n/Annots ["; + foreach ($o['info']['annot'] as $aId) { + $res .= " $aId 0 R"; + } + $res .= " ]"; + } + + $count = count($o['info']['contents']); + if ($count == 1) { + $res .= "\n/Contents " . $o['info']['contents'][0] . " 0 R"; + } else { + if ($count > 1) { + $res .= "\n/Contents [\n"; + + // reverse the page contents so added objects are below normal content + //foreach (array_reverse($o['info']['contents']) as $cId) { + // Back to normal now that I've got transparency working --Benj + foreach ($o['info']['contents'] as $cId) { + $res .= "$cId 0 R\n"; + } + $res .= "]"; + } + } + + $res .= "\n>>\nendobj"; + + return $res; + } + } + + /** + * the contents objects hold all of the content which appears on pages + */ + protected function o_contents($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array('t' => 'contents', 'c' => '', 'info' => array()); + if (mb_strlen($options, '8bit') && intval($options)) { + // then this contents is the primary for a page + $this->objects[$id]['onPage'] = $options; + } else { + if ($options === 'raw') { + // then this page contains some other type of system object + $this->objects[$id]['raw'] = 1; + } + } + break; + + case 'add': + // add more options to the decleration + foreach ($options as $k => $v) { + $o['info'][$k] = $v; + } + + case 'out': + $tmp = $o['c']; + $res = "\n$id 0 obj\n"; + + if (isset($this->objects[$id]['raw'])) { + $res .= $tmp; + } else { + $res .= "<<"; + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on this content stream + $res .= " /Filter /FlateDecode"; + $tmp = gzcompress($tmp, 6); + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . " >>\nstream\n$tmp\nendstream"; + } + + $res .= "\nendobj"; + + return $res; + } + } + + protected function o_embedjs($id, $action) + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array( + 't' => 'embedjs', + 'info' => array( + 'Names' => '[(EmbeddedJS) ' . ($id + 1) . ' 0 R]' + ) + ); + break; + + case 'out': + $res = "\n$id 0 obj\n<< "; + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + } + + protected function o_javascript($id, $action, $code = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + $this->objects[$id] = array( + 't' => 'javascript', + 'info' => array( + 'S' => '/JavaScript', + 'JS' => '(' . $this->filterText($code) . ')', + ) + ); + break; + + case 'out': + $res = "\n$id 0 obj\n<< "; + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + $res .= "\n>>\nendobj"; + + return $res; + } + } + + /** + * an image object, will be an XObject in the document, includes description and data + */ + protected function o_image($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = array('t' => 'image', 'data' => &$options['data'], 'info' => array()); + + $info =& $this->objects[$id]['info']; + + $info['Type'] = '/XObject'; + $info['Subtype'] = '/Image'; + $info['Width'] = $options['iw']; + $info['Height'] = $options['ih']; + + if (isset($options['masked']) && $options['masked']) { + $info['SMask'] = ($this->numObj - 1) . ' 0 R'; + } + + if (!isset($options['type']) || $options['type'] === 'jpg') { + if (!isset($options['channels'])) { + $options['channels'] = 3; + } + + switch ($options['channels']) { + case 1: + $info['ColorSpace'] = '/DeviceGray'; + break; + case 4: + $info['ColorSpace'] = '/DeviceCMYK'; + break; + default: + $info['ColorSpace'] = '/DeviceRGB'; + break; + } + + if ($info['ColorSpace'] === '/DeviceCMYK') { + $info['Decode'] = '[1 0 1 0 1 0 1 0]'; + } + + $info['Filter'] = '/DCTDecode'; + $info['BitsPerComponent'] = 8; + } else { + if ($options['type'] === 'png') { + $info['Filter'] = '/FlateDecode'; + $info['DecodeParms'] = '<< /Predictor 15 /Colors ' . $options['ncolor'] . ' /Columns ' . $options['iw'] . ' /BitsPerComponent ' . $options['bitsPerComponent'] . '>>'; + + if ($options['isMask']) { + $info['ColorSpace'] = '/DeviceGray'; + } else { + if (mb_strlen($options['pdata'], '8bit')) { + $tmp = ' [ /Indexed /DeviceRGB ' . (mb_strlen($options['pdata'], '8bit') / 3 - 1) . ' '; + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->objects[$this->numObj]['c'] = $options['pdata']; + $tmp .= $this->numObj . ' 0 R'; + $tmp .= ' ]'; + $info['ColorSpace'] = $tmp; + + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . + $transparency['g'] . ' ' . $transparency['g'] . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + } else { + if (isset($options['transparency'])) { + $transparency = $options['transparency']; + + switch ($transparency['type']) { + case 'indexed': + $tmp = ' [ ' . $transparency['data'] . ' ' . $transparency['data'] . '] '; + $info['Mask'] = $tmp; + break; + + case 'color-key': + $tmp = ' [ ' . + $transparency['r'] . ' ' . $transparency['r'] . ' ' . + $transparency['g'] . ' ' . $transparency['g'] . ' ' . + $transparency['b'] . ' ' . $transparency['b'] . + ' ] '; + $info['Mask'] = $tmp; + break; + } + } + $info['ColorSpace'] = '/' . $options['color']; + } + } + + $info['BitsPerComponent'] = $options['bitsPerComponent']; + } + } + + // assign it a place in the named resource dictionary as an external object, according to + // the label passed in with it. + $this->o_pages($this->currentNode, 'xObject', array('label' => $options['label'], 'objNum' => $id)); + + // also make sure that we have the right procset object for it. + $this->o_procset($this->procsetObjectId, 'add', 'ImageC'); + break; + + case 'out': + $tmp = &$o['data']; + $res = "\n$id 0 obj\n<<"; + + foreach ($o['info'] as $k => $v) { + $res .= "\n/$k $v"; + } + + if ($this->encrypted) { + $this->encryptInit($id); + $tmp = $this->ARC4($tmp); + } + + $res .= "\n/Length " . mb_strlen($tmp, '8bit') . ">>\nstream\n$tmp\nendstream\nendobj"; + + return $res; + } + } + + /** + * graphics state object + */ + protected function o_extGState($id, $action, $options = "") + { + static $valid_params = array( + "LW", + "LC", + "LC", + "LJ", + "ML", + "D", + "RI", + "OP", + "op", + "OPM", + "Font", + "BG", + "BG2", + "UCR", + "TR", + "TR2", + "HT", + "FL", + "SM", + "SA", + "BM", + "SMask", + "CA", + "ca", + "AIS", + "TK" + ); + + if ($action !== "new") { + $o = &$this->objects[$id]; + } + + switch ($action) { + case "new": + $this->objects[$id] = array('t' => 'extGState', 'info' => $options); + + // Tell the pages about the new resource + $this->numStates++; + $this->o_pages($this->currentNode, 'extGState', array("objNum" => $id, "stateNum" => $this->numStates)); + break; + + case "out": + $res = "\n$id 0 obj\n<< /Type /ExtGState\n"; + + foreach ($o["info"] as $k => $v) { + if (!in_array($k, $valid_params)) { + continue; + } + $res .= "/$k $v\n"; + } + + $res .= ">>\nendobj"; + + return $res; + } + } + + /** + * encryption object. + */ + protected function o_encryption($id, $action, $options = '') + { + if ($action !== 'new') { + $o = &$this->objects[$id]; + } + + switch ($action) { + case 'new': + // make the new object + $this->objects[$id] = array('t' => 'encryption', 'info' => $options); + $this->arc4_objnum = $id; + + // figure out the additional paramaters required + $pad = chr(0x28) . chr(0xBF) . chr(0x4E) . chr(0x5E) . chr(0x4E) . chr(0x75) . chr(0x8A) . chr(0x41) + . chr(0x64) . chr(0x00) . chr(0x4E) . chr(0x56) . chr(0xFF) . chr(0xFA) . chr(0x01) . chr(0x08) + . chr(0x2E) . chr(0x2E) . chr(0x00) . chr(0xB6) . chr(0xD0) . chr(0x68) . chr(0x3E) . chr(0x80) + . chr(0x2F) . chr(0x0C) . chr(0xA9) . chr(0xFE) . chr(0x64) . chr(0x53) . chr(0x69) . chr(0x7A); + + $len = mb_strlen($options['owner'], '8bit'); + + if ($len > 32) { + $owner = substr($options['owner'], 0, 32); + } else { + if ($len < 32) { + $owner = $options['owner'] . substr($pad, 0, 32 - $len); + } else { + $owner = $options['owner']; + } + } + + $len = mb_strlen($options['user'], '8bit'); + if ($len > 32) { + $user = substr($options['user'], 0, 32); + } else { + if ($len < 32) { + $user = $options['user'] . substr($pad, 0, 32 - $len); + } else { + $user = $options['user']; + } + } + + $tmp = $this->md5_16($owner); + $okey = substr($tmp, 0, 5); + $this->ARC4_init($okey); + $ovalue = $this->ARC4($user); + $this->objects[$id]['info']['O'] = $ovalue; + + // now make the u value, phew. + $tmp = $this->md5_16( + $user . $ovalue . chr($options['p']) . chr(255) . chr(255) . chr(255) . $this->fileIdentifier + ); + + $ukey = substr($tmp, 0, 5); + $this->ARC4_init($ukey); + $this->encryptionKey = $ukey; + $this->encrypted = true; + $uvalue = $this->ARC4($pad); + $this->objects[$id]['info']['U'] = $uvalue; + $this->encryptionKey = $ukey; + // initialize the arc4 array + break; + + case 'out': + $res = "\n$id 0 obj\n<<"; + $res .= "\n/Filter /Standard"; + $res .= "\n/V 1"; + $res .= "\n/R 2"; + $res .= "\n/O (" . $this->filterText($o['info']['O'], true, false) . ')'; + $res .= "\n/U (" . $this->filterText($o['info']['U'], true, false) . ')'; + // and the p-value needs to be converted to account for the twos-complement approach + $o['info']['p'] = (($o['info']['p'] ^ 255) + 1) * -1; + $res .= "\n/P " . ($o['info']['p']); + $res .= "\n>>\nendobj"; + + return $res; + } + } + + /** + * ARC4 functions + * A series of function to implement ARC4 encoding in PHP + */ + + /** + * calculate the 16 byte version of the 128 bit md5 digest of the string + */ + function md5_16($string) + { + $tmp = md5($string); + $out = ''; + for ($i = 0; $i <= 30; $i = $i + 2) { + $out .= chr(hexdec(substr($tmp, $i, 2))); + } + + return $out; + } + + /** + * initialize the encryption for processing a particular object + */ + function encryptInit($id) + { + $tmp = $this->encryptionKey; + $hex = dechex($id); + if (mb_strlen($hex, '8bit') < 6) { + $hex = substr('000000', 0, 6 - mb_strlen($hex, '8bit')) . $hex; + } + $tmp .= chr(hexdec(substr($hex, 4, 2))) . chr(hexdec(substr($hex, 2, 2))) . chr( + hexdec(substr($hex, 0, 2)) + ) . chr(0) . chr(0); + $key = $this->md5_16($tmp); + $this->ARC4_init(substr($key, 0, 10)); + } + + /** + * initialize the ARC4 encryption + */ + function ARC4_init($key = '') + { + $this->arc4 = ''; + + // setup the control array + if (mb_strlen($key, '8bit') == 0) { + return; + } + + $k = ''; + while (mb_strlen($k, '8bit') < 256) { + $k .= $key; + } + + $k = substr($k, 0, 256); + for ($i = 0; $i < 256; $i++) { + $this->arc4 .= chr($i); + } + + $j = 0; + + for ($i = 0; $i < 256; $i++) { + $t = $this->arc4[$i]; + $j = ($j + ord($t) + ord($k[$i])) % 256; + $this->arc4[$i] = $this->arc4[$j]; + $this->arc4[$j] = $t; + } + } + + /** + * ARC4 encrypt a text string + */ + function ARC4($text) + { + $len = mb_strlen($text, '8bit'); + $a = 0; + $b = 0; + $c = $this->arc4; + $out = ''; + for ($i = 0; $i < $len; $i++) { + $a = ($a + 1) % 256; + $t = $c[$a]; + $b = ($b + ord($t)) % 256; + $c[$a] = $c[$b]; + $c[$b] = $t; + $k = ord($c[(ord($c[$a]) + ord($c[$b])) % 256]); + $out .= chr(ord($text[$i]) ^ $k); + } + + return $out; + } + + /** + * functions which can be called to adjust or add to the document + */ + + /** + * add a link in the document to an external URL + */ + function addLink($url, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = array('type' => 'link', 'url' => $url, 'rect' => array($x0, $y0, $x1, $y1)); + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * add a link in the document to an internal destination (ie. within the document) + */ + function addInternalLink($label, $x0, $y0, $x1, $y1) + { + $this->numObj++; + $info = array('type' => 'ilink', 'label' => $label, 'rect' => array($x0, $y0, $x1, $y1)); + $this->o_annotation($this->numObj, 'new', $info); + } + + /** + * set the encryption of the document + * can be used to turn it on and/or set the passwords which it will have. + * also the functions that the user will have are set here, such as print, modify, add + */ + function setEncryption($userPass = '', $ownerPass = '', $pc = array()) + { + $p = bindec("11000000"); + + $options = array('print' => 4, 'modify' => 8, 'copy' => 16, 'add' => 32); + + foreach ($pc as $k => $v) { + if ($v && isset($options[$k])) { + $p += $options[$k]; + } else { + if (isset($options[$v])) { + $p += $options[$v]; + } + } + } + + // implement encryption on the document + if ($this->arc4_objnum == 0) { + // then the block does not exist already, add it. + $this->numObj++; + if (mb_strlen($ownerPass) == 0) { + $ownerPass = $userPass; + } + + $this->o_encryption($this->numObj, 'new', array('user' => $userPass, 'owner' => $ownerPass, 'p' => $p)); + } + } + + /** + * should be used for internal checks, not implemented as yet + */ + function checkAllHere() + { + } + + /** + * return the pdf stream as a string returned from the function + */ + function output($debug = false) + { + if ($debug) { + // turn compression off + $this->options['compression'] = false; + } + + if ($this->javascript) { + $this->numObj++; + + $js_id = $this->numObj; + $this->o_embedjs($js_id, 'new'); + $this->o_javascript(++$this->numObj, 'new', $this->javascript); + + $id = $this->catalogId; + + $this->o_catalog($id, 'javascript', $js_id); + } + + if ($this->arc4_objnum) { + $this->ARC4_init($this->encryptionKey); + } + + $this->checkAllHere(); + + $xref = array(); + $content = '%PDF-1.3'; + $pos = mb_strlen($content, '8bit'); + + foreach ($this->objects as $k => $v) { + $tmp = 'o_' . $v['t']; + $cont = $this->$tmp($k, 'out'); + $content .= $cont; + $xref[] = $pos; + $pos += mb_strlen($cont, '8bit'); + } + + $content .= "\nxref\n0 " . (count($xref) + 1) . "\n0000000000 65535 f \n"; + + foreach ($xref as $p) { + $content .= str_pad($p, 10, "0", STR_PAD_LEFT) . " 00000 n \n"; + } + + $content .= "trailer\n<<\n/Size " . (count($xref) + 1) . "\n/Root 1 0 R\n/Info $this->infoObject 0 R\n"; + + // if encryption has been applied to this document then add the marker for this dictionary + if ($this->arc4_objnum > 0) { + $content .= "/Encrypt $this->arc4_objnum 0 R\n"; + } + + if (mb_strlen($this->fileIdentifier, '8bit')) { + $content .= "/ID[<$this->fileIdentifier><$this->fileIdentifier>]\n"; + } + + // account for \n added at start of xref table + $pos++; + + $content .= ">>\nstartxref\n$pos\n%%EOF\n"; + + return $content; + } + + /** + * intialize a new document + * if this is called on an existing document results may be unpredictable, but the existing document would be lost at minimum + * this function is called automatically by the constructor function + */ + private function newDocument($pageSize = array(0, 0, 612, 792)) + { + $this->numObj = 0; + $this->objects = array(); + + $this->numObj++; + $this->o_catalog($this->numObj, 'new'); + + $this->numObj++; + $this->o_outlines($this->numObj, 'new'); + + $this->numObj++; + $this->o_pages($this->numObj, 'new'); + + $this->o_pages($this->numObj, 'mediaBox', $pageSize); + $this->currentNode = 3; + + $this->numObj++; + $this->o_procset($this->numObj, 'new'); + + $this->numObj++; + $this->o_info($this->numObj, 'new'); + + $this->numObj++; + $this->o_page($this->numObj, 'new'); + + // need to store the first page id as there is no way to get it to the user during + // startup + $this->firstPageId = $this->currentContents; + } + + /** + * open the font file and return a php structure containing it. + * first check if this one has been done before and saved in a form more suited to php + * note that if a php serialized version does not exist it will try and make one, but will + * require write access to the directory to do it... it is MUCH faster to have these serialized + * files. + */ + private function openFont($font) + { + // assume that $font contains the path and file but not the extension + $pos = strrpos($font, '/'); + + if ($pos === false) { + $dir = './'; + $name = $font; + } else { + $dir = substr($font, 0, $pos + 1); + $name = substr($font, $pos + 1); + } + + $fontcache = $this->fontcache; + if ($fontcache == '') { + $fontcache = $dir; + } + + //$name filename without folder and extension of font metrics + //$dir folder of font metrics + //$fontcache folder of runtime created php serialized version of font metrics. + // If this is not given, the same folder as the font metrics will be used. + // Storing and reusing serialized versions improves speed much + + $this->addMessage("openFont: $font - $name"); + + if (!$this->isUnicode || in_array(mb_strtolower(basename($name)), self::$coreFonts)) { + $metrics_name = "$name.afm"; + } else { + $metrics_name = "$name.ufm"; + } + + $cache_name = "$metrics_name.php"; + $this->addMessage("metrics: $metrics_name, cache: $cache_name"); + + if (file_exists($fontcache . $cache_name)) { + $this->addMessage("openFont: php file exists $fontcache$cache_name"); + $this->fonts[$font] = require($fontcache . $cache_name); + + if (!isset($this->fonts[$font]['_version_']) || $this->fonts[$font]['_version_'] != $this->fontcacheVersion) { + // if the font file is old, then clear it out and prepare for re-creation + $this->addMessage('openFont: clear out, make way for new version.'); + $this->fonts[$font] = null; + unset($this->fonts[$font]); + } + } else { + $old_cache_name = "php_$metrics_name"; + if (file_exists($fontcache . $old_cache_name)) { + $this->addMessage( + "openFont: php file doesn't exist $fontcache$cache_name, creating it from the old format" + ); + $old_cache = file_get_contents($fontcache . $old_cache_name); + file_put_contents($fontcache . $cache_name, 'openFont($font); + } + } + + if (!isset($this->fonts[$font]) && file_exists($dir . $metrics_name)) { + // then rebuild the php_.afm file from the .afm file + $this->addMessage("openFont: build php file from $dir$metrics_name"); + $data = array(); + + // 20 => 'space' + $data['codeToName'] = array(); + + // Since we're not going to enable Unicode for the core fonts we need to use a font-based + // setting for Unicode support rather than a global setting. + $data['isUnicode'] = (strtolower(substr($metrics_name, -3)) !== 'afm'); + + $cidtogid = ''; + if ($data['isUnicode']) { + $cidtogid = str_pad('', 256 * 256 * 2, "\x00"); + } + + $file = file($dir . $metrics_name); + + foreach ($file as $rowA) { + $row = trim($rowA); + $pos = strpos($row, ' '); + + if ($pos) { + // then there must be some keyword + $key = substr($row, 0, $pos); + switch ($key) { + case 'FontName': + case 'FullName': + case 'FamilyName': + case 'PostScriptName': + case 'Weight': + case 'ItalicAngle': + case 'IsFixedPitch': + case 'CharacterSet': + case 'UnderlinePosition': + case 'UnderlineThickness': + case 'Version': + case 'EncodingScheme': + case 'CapHeight': + case 'XHeight': + case 'Ascender': + case 'Descender': + case 'StdHW': + case 'StdVW': + case 'StartCharMetrics': + case 'FontHeightOffset': // OAR - Added so we can offset the height calculation of a Windows font. Otherwise it's too big. + $data[$key] = trim(substr($row, $pos)); + break; + + case 'FontBBox': + $data[$key] = explode(' ', trim(substr($row, $pos))); + break; + + //C 39 ; WX 222 ; N quoteright ; B 53 463 157 718 ; + case 'C': // Found in AFM files + $bits = explode(';', trim($row)); + $dtmp = array(); + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') == 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = array(); + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['C']; + $n = $dtmp['N']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + if ($c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } else { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c == -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + // U 827 ; WX 0 ; N squaresubnosp ; G 675 ; + case 'U': // Found in UFM files + if (!$data['isUnicode']) { + break; + } + + $bits = explode(';', trim($row)); + $dtmp = array(); + + foreach ($bits as $bit) { + $bits2 = explode(' ', trim($bit)); + if (mb_strlen($bits2[0], '8bit') === 0) { + continue; + } + + if (count($bits2) > 2) { + $dtmp[$bits2[0]] = array(); + for ($i = 1; $i < count($bits2); $i++) { + $dtmp[$bits2[0]][] = $bits2[$i]; + } + } else { + if (count($bits2) == 2) { + $dtmp[$bits2[0]] = $bits2[1]; + } + } + } + + $c = (int)$dtmp['U']; + $n = $dtmp['N']; + $glyph = $dtmp['G']; + $width = floatval($dtmp['WX']); + + if ($c >= 0) { + // Set values in CID to GID map + if ($c >= 0 && $c < 0xFFFF && $glyph) { + $cidtogid[$c * 2] = chr($glyph >> 8); + $cidtogid[$c * 2 + 1] = chr($glyph & 0xFF); + } + + if ($c != hexdec($n)) { + $data['codeToName'][$c] = $n; + } + $data['C'][$c] = $width; + } else { + $data['C'][$n] = $width; + } + + if (!isset($data['MissingWidth']) && $c == -1 && $n === '.notdef') { + $data['MissingWidth'] = $width; + } + + break; + + case 'KPX': + break; // don't include them as they are not used yet + //KPX Adieresis yacute -40 + $bits = explode(' ', trim($row)); + $data['KPX'][$bits[1]][$bits[2]] = $bits[3]; + break; + } + } + } + + if ($this->compressionReady && $this->options['compression']) { + // then implement ZLIB based compression on CIDtoGID string + $data['CIDtoGID_Compressed'] = true; + $cidtogid = gzcompress($cidtogid, 6); + } + $data['CIDtoGID'] = base64_encode($cidtogid); + $data['_version_'] = $this->fontcacheVersion; + $this->fonts[$font] = $data; + + //Because of potential trouble with php safe mode, expect that the folder already exists. + //If not existing, this will hit performance because of missing cached results. + if (is_dir(substr($fontcache, 0, -1)) && is_writable(substr($fontcache, 0, -1))) { + file_put_contents($fontcache . $cache_name, 'fonts[$font])) { + $this->addMessage("openFont: no font file found for $font. Do you need to run load_font.php?"); + } + + //pre_r($this->messages); + } + + /** + * if the font is not loaded then load it and make the required object + * else just make it the current font + * the encoding array can contain 'encoding'=> 'none','WinAnsiEncoding','MacRomanEncoding' or 'MacExpertEncoding' + * note that encoding='none' will need to be used for symbolic fonts + * and 'differences' => an array of mappings between numbers 0->255 and character names. + * + */ + function selectFont($fontName, $encoding = '', $set = true) + { + $ext = substr($fontName, -4); + if ($ext === '.afm' || $ext === '.ufm') { + $fontName = substr($fontName, 0, mb_strlen($fontName) - 4); + } + + if (!isset($this->fonts[$fontName])) { + $this->addMessage("selectFont: selecting - $fontName - $encoding, $set"); + + // load the file + $this->openFont($fontName); + + if (isset($this->fonts[$fontName])) { + $this->numObj++; + $this->numFonts++; + + $font = &$this->fonts[$fontName]; + + //$this->numFonts = md5($fontName); + $pos = strrpos($fontName, '/'); + // $dir = substr($fontName,0,$pos+1); + $name = substr($fontName, $pos + 1); + $options = array('name' => $name, 'fontFileName' => $fontName); + + if (is_array($encoding)) { + // then encoding and differences might be set + if (isset($encoding['encoding'])) { + $options['encoding'] = $encoding['encoding']; + } + + if (isset($encoding['differences'])) { + $options['differences'] = $encoding['differences']; + } + } else { + if (mb_strlen($encoding, '8bit')) { + // then perhaps only the encoding has been set + $options['encoding'] = $encoding; + } + } + + $fontObj = $this->numObj; + $this->o_font($this->numObj, 'new', $options); + $font['fontNum'] = $this->numFonts; + + // if this is a '.afm' font, and there is a '.pfa' file to go with it ( as there + // should be for all non-basic fonts), then load it into an object and put the + // references into the font object + $basefile = $fontName; + + $fbtype = ''; + if (file_exists("$basefile.pfb")) { + $fbtype = 'pfb'; + } else { + if (file_exists("$basefile.ttf")) { + $fbtype = 'ttf'; + } + } + + $fbfile = "$basefile.$fbtype"; + + // $pfbfile = substr($fontName,0,strlen($fontName)-4).'.pfb'; + // $ttffile = substr($fontName,0,strlen($fontName)-4).'.ttf'; + $this->addMessage('selectFont: checking for - ' . $fbfile); + + // OAR - I don't understand this old check + // if (substr($fontName, -4) === '.afm' && strlen($fbtype)) { + if ($fbtype) { + $adobeFontName = isset($font['PostScriptName']) ? $font['PostScriptName'] : $font['FontName']; + // $fontObj = $this->numObj; + $this->addMessage("selectFont: adding font file - $fbfile - $adobeFontName"); + + // find the array of font widths, and put that into an object. + $firstChar = -1; + $lastChar = 0; + $widths = array(); + $cid_widths = array(); + + foreach ($font['C'] as $num => $d) { + if (intval($num) > 0 || $num == '0') { + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + if ($lastChar > 0 && $num > $lastChar + 1) { + for ($i = $lastChar + 1; $i < $num; $i++) { + $widths[] = 0; + } + } + } + + $widths[] = $d; + + if ($font['isUnicode']) { + $cid_widths[$num] = $d; + } + + if ($firstChar == -1) { + $firstChar = $num; + } + + $lastChar = $num; + } + } + + // also need to adjust the widths for the differences array + if (isset($options['differences'])) { + foreach ($options['differences'] as $charNum => $charName) { + if ($charNum > $lastChar) { + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + for ($i = $lastChar + 1; $i <= $charNum; $i++) { + $widths[] = 0; + } + } + + $lastChar = $charNum; + } + + if (isset($font['C'][$charName])) { + $widths[$charNum - $firstChar] = $font['C'][$charName]; + if ($font['isUnicode']) { + $cid_widths[$charName] = $font['C'][$charName]; + } + } + } + } + + if ($font['isUnicode']) { + $font['CIDWidths'] = $cid_widths; + } + + $this->addMessage('selectFont: FirstChar = ' . $firstChar); + $this->addMessage('selectFont: LastChar = ' . $lastChar); + + $widthid = -1; + + if (!$font['isUnicode']) { + // With Unicode, widths array isn't used + + $this->numObj++; + $this->o_contents($this->numObj, 'new', 'raw'); + $this->objects[$this->numObj]['c'] .= '[' . implode(' ', $widths) . ']'; + $widthid = $this->numObj; + } + + $missing_width = 500; + $stemV = 70; + + if (isset($font['MissingWidth'])) { + $missing_width = $font['MissingWidth']; + } + if (isset($font['StdVW'])) { + $stemV = $font['StdVW']; + } else { + if (isset($font['Weight']) && preg_match('!(bold|black)!i', $font['Weight'])) { + $stemV = 120; + } + } + + // load the pfb file, and put that into an object too. + // note that pdf supports only binary format type 1 font files, though there is a + // simple utility to convert them from pfa to pfb. + // FIXME: should we move font subset creation to CPDF::output? See notes in issue #750. + if (!$this->isUnicode || $fbtype !== 'ttf' || empty($this->stringSubsets)) { + $data = file_get_contents($fbfile); + } else { + $this->stringSubsets[$fontName][] = 32; // Force space if not in yet + + $subset = $this->stringSubsets[$fontName]; + sort($subset); + + // Load font + $font_obj = Font::load($fbfile); + $font_obj->parse(); + + // Define subset + $font_obj->setSubset($subset); + $font_obj->reduce(); + + // Write new font + $tmp_name = "$fbfile.tmp." . uniqid(); + $font_obj->open($tmp_name, Font_Binary_Stream::modeWrite); + $font_obj->encode(array("OS/2")); + $font_obj->close(); + + // Parse the new font to get cid2gid and widths + $font_obj = Font::load($tmp_name); + + // Find Unicode char map table + $subtable = null; + foreach ($font_obj->getData("cmap", "subtables") as $_subtable) { + if ($_subtable["platformID"] == 0 || $_subtable["platformID"] == 3 && $_subtable["platformSpecificID"] == 1) { + $subtable = $_subtable; + break; + } + } + + if ($subtable) { + $glyphIndexArray = $subtable["glyphIndexArray"]; + $hmtx = $font_obj->getData("hmtx"); + + unset($glyphIndexArray[0xFFFF]); + + $cidtogid = str_pad('', max(array_keys($glyphIndexArray)) * 2 + 1, "\x00"); + $font['CIDWidths'] = array(); + foreach ($glyphIndexArray as $cid => $gid) { + if ($cid >= 0 && $cid < 0xFFFF && $gid) { + $cidtogid[$cid * 2] = chr($gid >> 8); + $cidtogid[$cid * 2 + 1] = chr($gid & 0xFF); + } + + $width = $font_obj->normalizeFUnit(isset($hmtx[$gid]) ? $hmtx[$gid][0] : $hmtx[0][0]); + $font['CIDWidths'][$cid] = $width; + } + + $font['CIDtoGID'] = base64_encode(gzcompress($cidtogid)); + $font['CIDtoGID_Compressed'] = true; + + $data = file_get_contents($tmp_name); + } else { + $data = file_get_contents($fbfile); + } + + $font_obj->close(); + unlink($tmp_name); + } + + // create the font descriptor + $this->numObj++; + $fontDescriptorId = $this->numObj; + + $this->numObj++; + $pfbid = $this->numObj; + + // determine flags (more than a little flakey, hopefully will not matter much) + $flags = 0; + + if ($font['ItalicAngle'] != 0) { + $flags += pow(2, 6); + } + + if ($font['IsFixedPitch'] === 'true') { + $flags += 1; + } + + $flags += pow(2, 5); // assume non-sybolic + $list = array( + 'Ascent' => 'Ascender', + 'CapHeight' => 'CapHeight', + 'MissingWidth' => 'MissingWidth', + 'Descent' => 'Descender', + 'FontBBox' => 'FontBBox', + 'ItalicAngle' => 'ItalicAngle' + ); + $fdopt = array( + 'Flags' => $flags, + 'FontName' => $adobeFontName, + 'StemV' => $stemV + ); + + foreach ($list as $k => $v) { + if (isset($font[$v])) { + $fdopt[$k] = $font[$v]; + } + } + + if ($fbtype === 'pfb') { + $fdopt['FontFile'] = $pfbid; + } else { + if ($fbtype === 'ttf') { + $fdopt['FontFile2'] = $pfbid; + } + } + + $this->o_fontDescriptor($fontDescriptorId, 'new', $fdopt); + + // embed the font program + $this->o_contents($this->numObj, 'new'); + $this->objects[$pfbid]['c'] .= $data; + + // determine the cruicial lengths within this file + if ($fbtype === 'pfb') { + $l1 = strpos($data, 'eexec') + 6; + $l2 = strpos($data, '00000000') - $l1; + $l3 = mb_strlen($data, '8bit') - $l2 - $l1; + $this->o_contents( + $this->numObj, + 'add', + array('Length1' => $l1, 'Length2' => $l2, 'Length3' => $l3) + ); + } else { + if ($fbtype == 'ttf') { + $l1 = mb_strlen($data, '8bit'); + $this->o_contents($this->numObj, 'add', array('Length1' => $l1)); + } + } + + // tell the font object about all this new stuff + $tmp = array( + 'BaseFont' => $adobeFontName, + 'MissingWidth' => $missing_width, + 'Widths' => $widthid, + 'FirstChar' => $firstChar, + 'LastChar' => $lastChar, + 'FontDescriptor' => $fontDescriptorId + ); + + if ($fbtype === 'ttf') { + $tmp['SubType'] = 'TrueType'; + } + + $this->addMessage("adding extra info to font.($fontObj)"); + + foreach ($tmp as $fk => $fv) { + $this->addMessage("$fk : $fv"); + } + + $this->o_font($fontObj, 'add', $tmp); + } else { + $this->addMessage( + 'selectFont: pfb or ttf file not found, ok if this is one of the 14 standard fonts' + ); + } + + // also set the differences here, note that this means that these will take effect only the + //first time that a font is selected, else they are ignored + if (isset($options['differences'])) { + $font['differences'] = $options['differences']; + } + } + } + + if ($set && isset($this->fonts[$fontName])) { + // so if for some reason the font was not set in the last one then it will not be selected + $this->currentBaseFont = $fontName; + + // the next lines mean that if a new font is selected, then the current text state will be + // applied to it as well. + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + + //$this->setCurrentFont(); + } + + return $this->currentFontNum; + //return $this->numObj; + } + + /** + * sets up the current font, based on the font families, and the current text state + * note that this system is quite flexible, a bold-italic font can be completely different to a + * italic-bold font, and even bold-bold will have to be defined within the family to have meaning + * This function is to be called whenever the currentTextState is changed, it will update + * the currentFont setting to whatever the appropriatte family one is. + * If the user calls selectFont themselves then that will reset the currentBaseFont, and the currentFont + * This function will change the currentFont to whatever it should be, but will not change the + * currentBaseFont. + */ + private function setCurrentFont() + { + // if (strlen($this->currentBaseFont) == 0){ + // // then assume an initial font + // $this->selectFont($this->defaultFont); + // } + // $cf = substr($this->currentBaseFont,strrpos($this->currentBaseFont,'/')+1); + // if (strlen($this->currentTextState) + // && isset($this->fontFamilies[$cf]) + // && isset($this->fontFamilies[$cf][$this->currentTextState])){ + // // then we are in some state or another + // // and this font has a family, and the current setting exists within it + // // select the font, then return it + // $nf = substr($this->currentBaseFont,0,strrpos($this->currentBaseFont,'/')+1).$this->fontFamilies[$cf][$this->currentTextState]; + // $this->selectFont($nf,'',0); + // $this->currentFont = $nf; + // $this->currentFontNum = $this->fonts[$nf]['fontNum']; + // } else { + // // the this font must not have the right family member for the current state + // // simply assume the base font + $this->currentFont = $this->currentBaseFont; + $this->currentFontNum = $this->fonts[$this->currentFont]['fontNum']; + // } + } + + /** + * function for the user to find out what the ID is of the first page that was created during + * startup - useful if they wish to add something to it later. + */ + function getFirstPageId() + { + return $this->firstPageId; + } + + /** + * add content to the currently active object + */ + private function addContent($content) + { + $this->objects[$this->currentContents]['c'] .= $content; + } + + /** + * sets the color for fill operations + */ + function setColor($color, $force = false) + { + $new_color = array($color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null); + + if (!$force && $this->currentColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + //$this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F k", $this->currentColor)); + } else { + if (isset($new_color[2])) { + //$this->currentColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F rg", $new_color)); + } + } + } + + /** + * sets the color for fill operations + */ + function setFillRule($fillRule) + { + if (!in_array($fillRule, array("nonzero", "evenodd"))) { + return; + } + + $this->fillRule = $fillRule; + } + + /** + * sets the color for stroke operations + */ + function setStrokeColor($color, $force = false) + { + $new_color = array($color[0], $color[1], $color[2], isset($color[3]) ? $color[3] : null); + + if (!$force && $this->currentStrokeColor == $new_color) { + return; + } + + if (isset($new_color[3])) { + //$this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F %.3F K", $this->currentStrokeColor)); + } else { + if (isset($new_color[2])) { + //$this->currentStrokeColor = $new_color; + $this->addContent(vsprintf("\n%.3F %.3F %.3F RG", $new_color)); + } + } + } + + /** + * Set the graphics state for compositions + */ + function setGraphicsState($parameters) + { + // Create a new graphics state object + // FIXME: should actually keep track of states that have already been created... + $this->numObj++; + $this->o_extGState($this->numObj, 'new', $parameters); + $this->addContent("\n/GS$this->numStates gs"); + } + + /** + * Set current blend mode & opacity for lines. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setLineTransparency($mode, $opacity) + { + static $blend_modes = array( + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ); + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + // Only create a new graphics state if required + if ($mode === $this->currentLineTransparency["mode"] && + $opacity == $this->currentLineTransparency["opacity"] + ) { + return; + } + + $this->currentLineTransparency["mode"] = $mode; + $this->currentLineTransparency["opacity"] = $opacity; + + $options = array( + "BM" => "/$mode", + "CA" => (float)$opacity + ); + + $this->setGraphicsState($options); + } + + /** + * Set current blend mode & opacity for filled objects. + * + * Valid blend modes are: + * + * Normal, Multiply, Screen, Overlay, Darken, Lighten, + * ColorDogde, ColorBurn, HardLight, SoftLight, Difference, + * Exclusion + * + * @param string $mode the blend mode to use + * @param float $opacity 0.0 fully transparent, 1.0 fully opaque + */ + function setFillTransparency($mode, $opacity) + { + static $blend_modes = array( + "Normal", + "Multiply", + "Screen", + "Overlay", + "Darken", + "Lighten", + "ColorDogde", + "ColorBurn", + "HardLight", + "SoftLight", + "Difference", + "Exclusion" + ); + + if (!in_array($mode, $blend_modes)) { + $mode = "Normal"; + } + + if ($mode === $this->currentFillTransparency["mode"] && + $opacity == $this->currentFillTransparency["opacity"] + ) { + return; + } + + $this->currentFillTransparency["mode"] = $mode; + $this->currentFillTransparency["opacity"] = $opacity; + + $options = array( + "BM" => "/$mode", + "ca" => (float)$opacity, + ); + + $this->setGraphicsState($options); + } + + function lineTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F l", $x, $y)); + } + + function moveTo($x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F m", $x, $y)); + } + + /** + * draw a bezier curve based on 4 control points + */ + function curveTo($x1, $y1, $x2, $y2, $x3, $y3) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F %.3F %.3F c", $x1, $y1, $x2, $y2, $x3, $y3)); + } + + /** + * draw a bezier curve based on 4 control points + */ + function quadTo($cpx, $cpy, $x, $y) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F v", $cpx, $cpy, $x, $y)); + } + + function closePath() + { + $this->addContent(' h'); + } + + function endPath() + { + $this->addContent(' n'); + } + + /** + * draw an ellipse + * note that the part and filled ellipse are just special cases of this function + * + * draws an ellipse in the current line style + * centered at $x0,$y0, radii $r1,$r2 + * if $r2 is not set, then a circle is drawn + * from $astart to $afinish, measured in degrees, running anti-clockwise from the right hand side of the ellipse. + * nSeg is not allowed to be less than 2, as this will simply draw a line (and will even draw a + * pretty crappy shape at 2, as we are approximating with bezier curves. + */ + function ellipse( + $x0, + $y0, + $r1, + $r2 = 0, + $angle = 0, + $nSeg = 8, + $astart = 0, + $afinish = 360, + $close = true, + $fill = false, + $stroke = true, + $incomplete = false + ) { + if ($r1 == 0) { + return; + } + + if ($r2 == 0) { + $r2 = $r1; + } + + if ($nSeg < 2) { + $nSeg = 2; + } + + $astart = deg2rad((float)$astart); + $afinish = deg2rad((float)$afinish); + $totalAngle = $afinish - $astart; + + $dt = $totalAngle / $nSeg; + $dtm = $dt / 3; + + if ($angle != 0) { + $a = -1 * deg2rad((float)$angle); + + $this->addContent( + sprintf("\n q %.3F %.3F %.3F %.3F %.3F %.3F cm", cos($a), -sin($a), sin($a), cos($a), $x0, $y0) + ); + + $x0 = 0; + $y0 = 0; + } + + $t1 = $astart; + $a0 = $x0 + $r1 * cos($t1); + $b0 = $y0 + $r2 * sin($t1); + $c0 = -$r1 * sin($t1); + $d0 = $r2 * cos($t1); + + if (!$incomplete) { + $this->addContent(sprintf("\n%.3F %.3F m ", $a0, $b0)); + } + + for ($i = 1; $i <= $nSeg; $i++) { + // draw this bit of the total curve + $t1 = $i * $dt + $astart; + $a1 = $x0 + $r1 * cos($t1); + $b1 = $y0 + $r2 * sin($t1); + $c1 = -$r1 * sin($t1); + $d1 = $r2 * cos($t1); + + $this->addContent( + sprintf( + "\n%.3F %.3F %.3F %.3F %.3F %.3F c", + ($a0 + $c0 * $dtm), + ($b0 + $d0 * $dtm), + ($a1 - $c1 * $dtm), + ($b1 - $d1 * $dtm), + $a1, + $b1 + ) + ); + + $a0 = $a1; + $b0 = $b1; + $c0 = $c1; + $d0 = $d1; + } + + if (!$incomplete) { + if ($fill) { + $this->addContent(' f'); + } + + if ($stroke) { + if ($close) { + $this->addContent(' s'); // small 's' signifies closing the path as well + } else { + $this->addContent(' S'); + } + } + } + + if ($angle != 0) { + $this->addContent(' Q'); + } + } + + /** + * this sets the line drawing style. + * width, is the thickness of the line in user units + * cap is the type of cap to put on the line, values can be 'butt','round','square' + * where the diffference between 'square' and 'butt' is that 'square' projects a flat end past the + * end of the line. + * join can be 'miter', 'round', 'bevel' + * dash is an array which sets the dash pattern, is a series of length values, which are the lengths of the + * on and off dashes. + * (2) represents 2 on, 2 off, 2 on , 2 off ... + * (2,1) is 2 on, 1 off, 2 on, 1 off.. etc + * phase is a modifier on the dash pattern which is used to shift the point at which the pattern starts. + */ + function setLineStyle($width = 1, $cap = '', $join = '', $dash = '', $phase = 0) + { + // this is quite inefficient in that it sets all the parameters whenever 1 is changed, but will fix another day + $string = ''; + + if ($width > 0) { + $string .= sprintf("%.3F w", $width); + } + + $ca = array('butt' => 0, 'round' => 1, 'square' => 2); + + if (isset($ca[$cap])) { + $string .= " $ca[$cap] J"; + } + + $ja = array('miter' => 0, 'round' => 1, 'bevel' => 2); + + if (isset($ja[$join])) { + $string .= " $ja[$join] j"; + } + + if (is_array($dash)) { + $string .= ' [ ' . implode(' ', $dash) . " ] $phase d"; + } + + $this->currentLineStyle = $string; + $this->addContent("\n$string"); + } + + function rect($x1, $y1, $width, $height) + { + $this->addContent(sprintf("\n%.3F %.3F %.3F %.3F re", $x1, $y1, $width, $height)); + } + + function stroke() + { + $this->addContent("\nS"); + } + + function fill() + { + $this->addContent("\nf".($this->fillRule === "evenodd" ? "*" : "")); + } + + function fillStroke() + { + $this->addContent("\nb".($this->fillRule === "evenodd" ? "*" : "")); + } + + /** + * save the current graphic state + */ + function save() + { + $this->addContent("\nq"); + } + + /** + * restore the last graphic state + */ + function restore() + { + $this->addContent("\nQ"); + } + + /** + * scale + * + * @param float $s_x scaling factor for width as percent + * @param float $s_y scaling factor for height as percent + * @param float $x Origin abscisse + * @param float $y Origin ordinate + */ + function scale($s_x, $s_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tm = array( + $s_x, 0, + 0, $s_y, + $x * (1 - $s_x), $y * (1 - $s_y) + ); + + $this->transform($tm); + } + + /** + * translate + * + * @param float $t_x movement to the right + * @param float $t_y movement to the bottom + */ + function translate($t_x, $t_y) + { + $tm = array( + 1, 0, + 0, 1, + $t_x, -$t_y + ); + + $this->transform($tm); + } + + /** + * rotate + * + * @param float $angle angle in degrees for counter-clockwise rotation + * @param float $x Origin abscisse + * @param float $y Origin ordinate + */ + function rotate($angle, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $a = deg2rad($angle); + $cos_a = cos($a); + $sin_a = sin($a); + + $tm = array( + $cos_a, -$sin_a, + $sin_a, $cos_a, + $x - $sin_a * $y - $cos_a * $x, $y - $cos_a * $y + $sin_a * $x, + ); + + $this->transform($tm); + } + + /** + * skew + * + * @param float $angle_x + * @param float $angle_y + * @param float $x Origin abscisse + * @param float $y Origin ordinate + */ + function skew($angle_x, $angle_y, $x, $y) + { + $y = $this->currentPageSize["height"] - $y; + + $tan_x = tan(deg2rad($angle_x)); + $tan_y = tan(deg2rad($angle_y)); + + $tm = array( + 1, -$tan_y, + -$tan_x, 1, + $tan_x * $y, $tan_y * $x, + ); + + $this->transform($tm); + } + + /** + * apply graphic transformations + * + * @param array $tm transformation matrix + */ + function transform($tm) + { + $this->addContent(vsprintf("\n %.3F %.3F %.3F %.3F %.3F %.3F cm", $tm)); + } + + /** + * add a new page to the document + * this also makes the new page the current active object + */ + function newPage($insert = 0, $id = 0, $pos = 'after') + { + // if there is a state saved, then go up the stack closing them + // then on the new page, re-open them with the right setings + + if ($this->nStateStack) { + for ($i = $this->nStateStack; $i >= 1; $i--) { + $this->restoreState($i); + } + } + + $this->numObj++; + + if ($insert) { + // the id from the ezPdf class is the id of the contents of the page, not the page object itself + // query that object to find the parent + $rid = $this->objects[$id]['onPage']; + $opt = array('rid' => $rid, 'pos' => $pos); + $this->o_page($this->numObj, 'new', $opt); + } else { + $this->o_page($this->numObj, 'new'); + } + + // if there is a stack saved, then put that onto the page + if ($this->nStateStack) { + for ($i = 1; $i <= $this->nStateStack; $i++) { + $this->saveState($i); + } + } + + // and if there has been a stroke or fill color set, then transfer them + if (isset($this->currentColor)) { + $this->setColor($this->currentColor, true); + } + + if (isset($this->currentStrokeColor)) { + $this->setStrokeColor($this->currentStrokeColor, true); + } + + // if there is a line style set, then put this in too + if (mb_strlen($this->currentLineStyle, '8bit')) { + $this->addContent("\n$this->currentLineStyle"); + } + + // the call to the o_page object set currentContents to the present page, so this can be returned as the page id + return $this->currentContents; + } + + /** + * output the pdf code, streaming it to the browser + * the relevant headers are set so that hopefully the browser will recognise it + */ + function stream($options = '') + { + // setting the options allows the adjustment of the headers + // values at the moment are: + // 'Content-Disposition' => 'filename' - sets the filename, though not too sure how well this will + // work as in my trial the browser seems to use the filename of the php file with .pdf on the end + // 'Accept-Ranges' => 1 or 0 - if this is not set to 1, then this header is not included, off by default + // this header seems to have caused some problems despite tha fact that it is supposed to solve + // them, so I am leaving it off by default. + // 'compress' = > 1 or 0 - apply content stream compression, this is on (1) by default + // 'Attachment' => 1 or 0 - if 1, force the browser to open a download dialog + if (!is_array($options)) { + $options = array(); + } + + if (headers_sent()) { + die("Unable to stream pdf: headers already sent"); + } + + $debug = empty($options['compression']); + $tmp = ltrim($this->output($debug)); + + header("Cache-Control: private"); + header("Content-type: application/pdf"); + + //FIXME: I don't know that this is sufficient for determining content length (i.e. what about transport compression?) + header("Content-Length: " . mb_strlen($tmp, '8bit')); + $fileName = (isset($options['Content-Disposition']) ? $options['Content-Disposition'] : 'file.pdf'); + + if (!isset($options["Attachment"])) { + $options["Attachment"] = true; + } + + $attachment = $options["Attachment"] ? "attachment" : "inline"; + + // detect the character encoding of the incoming file + $encoding = mb_detect_encoding($fileName); + $fallbackfilename = mb_convert_encoding($fileName, "ISO-8859-1", $encoding); + $encodedfallbackfilename = rawurlencode($fallbackfilename); + $encodedfilename = rawurlencode($fileName); + + header( + "Content-Disposition: $attachment; filename=" . $encodedfallbackfilename . "; filename*=UTF-8''$encodedfilename" + ); + + if (isset($options['Accept-Ranges']) && $options['Accept-Ranges'] == 1) { + //FIXME: Is this the correct value ... spec says 1#range-unit + header("Accept-Ranges: " . mb_strlen($tmp, '8bit')); + } + + echo $tmp; + flush(); + } + + /** + * return the height in units of the current font in the given size + */ + function getFontHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['Ascender']) && isset($font['Descender'])) { + $h = $font['Ascender'] - $font['Descender']; + } else { + $h = $font['FontBBox'][3] - $font['FontBBox'][1]; + } + + // have to adjust by a font offset for Windows fonts. unfortunately it looks like + // the bounding box calculations are wrong and I don't know why. + if (isset($font['FontHeightOffset'])) { + // For CourierNew from Windows this needs to be -646 to match the + // Adobe native Courier font. + // + // For FreeMono from GNU this needs to be -337 to match the + // Courier font. + // + // Both have been added manually to the .afm and .ufm files. + $h += (int)$font['FontHeightOffset']; + } + + return $size * $h / 1000; + } + + function getFontXHeight($size) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $font = $this->fonts[$this->currentFont]; + + // for the current font, and the given size, what is the height of the font in user units + if (isset($font['XHeight'])) { + $xh = $font['Ascender'] - $font['Descender']; + } else { + $xh = $this->getFontHeight($size) / 2; + } + + return $size * $xh / 1000; + } + + /** + * return the font descender, this will normally return a negative number + * if you add this number to the baseline, you get the level of the bottom of the font + * it is in the pdf user units + */ + function getFontDescender($size) + { + // note that this will most likely return a negative value + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + //$h = $this->fonts[$this->currentFont]['FontBBox'][1]; + $h = $this->fonts[$this->currentFont]['Descender']; + + return $size * $h / 1000; + } + + /** + * filter the text, this is applied to all text just before being inserted into the pdf document + * it escapes the various things that need to be escaped, and so on + * + * @access private + */ + function filterText($text, $bom = true, $convert_encoding = true) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + if ($convert_encoding) { + $cf = $this->currentFont; + if (isset($this->fonts[$cf]) && $this->fonts[$cf]['isUnicode']) { + //$text = html_entity_decode($text, ENT_QUOTES, 'UTF-8'); + $text = $this->utf8toUtf16BE($text, $bom); + } else { + //$text = html_entity_decode($text, ENT_QUOTES); + $text = mb_convert_encoding($text, self::$targetEncoding, 'UTF-8'); + } + } + + // the chr(13) substitution fixes a bug seen in TCPDF (bug #1421290) + return strtr($text, array(')' => '\\)', '(' => '\\(', '\\' => '\\\\', chr(13) => '\r')); + } + + /** + * given a start position and information about how text is to be laid out, calculate where + * on the page the text will end + */ + private function getTextPosition($x, $y, $angle, $size, $wa, $text) + { + // given this information return an array containing x and y for the end position as elements 0 and 1 + $w = $this->getTextWidth($size, $text); + + // need to adjust for the number of spaces in this text + $words = explode(' ', $text); + $nspaces = count($words) - 1; + $w += $wa * $nspaces; + $a = deg2rad((float)$angle); + + return array(cos($a) * $w + $x, -sin($a) * $w + $y); + } + + /** + * Callback method used by smallCaps + * + * @param array $matches + * + * @return string + */ + function toUpper($matches) + { + return mb_strtoupper($matches[0]); + } + + function concatMatches($matches) + { + $str = ""; + foreach ($matches as $match) { + $str .= $match[0]; + } + + return $str; + } + + /** + * add text to the document, at a specified location, size and angle on the page + */ + function registerText($font, $text) + { + if (!$this->isUnicode || in_array(mb_strtolower(basename($font)), self::$coreFonts)) { + return; + } + + if (!isset($this->stringSubsets[$font])) { + $this->stringSubsets[$font] = array(); + } + + $this->stringSubsets[$font] = array_unique( + array_merge($this->stringSubsets[$font], $this->utf8toCodePointsArray($text)) + ); + } + + /** + * add text to the document, at a specified location, size and angle on the page + */ + function addText($x, $y, $size, $text, $angle = 0, $wordSpaceAdjust = 0, $charSpaceAdjust = 0, $smallCaps = false) + { + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(array("\r", "\n"), "", $text); + + if ($smallCaps) { + preg_match_all("/(\P{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + $lower = $this->concatMatches($matches); + d($lower); + + preg_match_all("/(\p{Ll}+)/u", $text, $matches, PREG_SET_ORDER); + $other = $this->concatMatches($matches); + d($other); + + //$text = preg_replace_callback("/\p{Ll}/u", array($this, "toUpper"), $text); + } + + // if there are any open callbacks, then they should be called, to show the start of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $info = array( + 'x' => $x, + 'y' => $y, + 'angle' => $angle, + 'status' => 'sol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ); + + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + + if ($angle == 0) { + $this->addContent(sprintf("\nBT %.3F %.3F Td", $x, $y)); + } else { + $a = deg2rad((float)$angle); + $this->addContent( + sprintf("\nBT %.3F %.3F %.3F %.3F %.3F %.3F Tm", cos($a), -sin($a), sin($a), cos($a), $x, $y) + ); + } + + if ($wordSpaceAdjust != 0 || $wordSpaceAdjust != $this->wordSpaceAdjust) { + $this->wordSpaceAdjust = $wordSpaceAdjust; + $this->addContent(sprintf(" %.3F Tw", $wordSpaceAdjust)); + } + + if ($charSpaceAdjust != 0 || $charSpaceAdjust != $this->charSpaceAdjust) { + $this->charSpaceAdjust = $charSpaceAdjust; + $this->addContent(sprintf(" %.3F Tc", $charSpaceAdjust)); + } + + $len = mb_strlen($text); + $start = 0; + + if ($start < $len) { + $part = $text; // OAR - Don't need this anymore, given that $start always equals zero. substr($text, $start); + $place_text = $this->filterText($part, false); + // modify unicode text so that extra word spacing is manually implemented (bug #) + $cf = $this->currentFont; + if ($this->fonts[$cf]['isUnicode'] && $wordSpaceAdjust != 0) { + $space_scale = 1000 / $size; + //$place_text = str_replace(' ', ') ( ) '.($this->getTextWidth($size, chr(32), $wordSpaceAdjust)*-75).' (', $place_text); + $place_text = str_replace(' ', ' ) ' . (-round($space_scale * $wordSpaceAdjust)) . ' (', $place_text); + } + $this->addContent(" /F$this->currentFontNum " . sprintf('%.1F Tf ', $size)); + $this->addContent(" [($place_text)] TJ"); + } + + $this->addContent(' ET'); + + // if there are any open callbacks, then they should be called, to show the end of the line + if ($this->nCallback > 0) { + for ($i = $this->nCallback; $i > 0; $i--) { + // call each function + $tmp = $this->getTextPosition($x, $y, $angle, $size, $wordSpaceAdjust, $text); + $info = array( + 'x' => $tmp[0], + 'y' => $tmp[1], + 'angle' => $angle, + 'status' => 'eol', + 'p' => $this->callback[$i]['p'], + 'nCallback' => $this->callback[$i]['nCallback'], + 'height' => $this->callback[$i]['height'], + 'descender' => $this->callback[$i]['descender'] + ); + $func = $this->callback[$i]['f']; + $this->$func($info); + } + } + } + + /** + * calculate how wide a given text string will be on a page, at a given size. + * this can be called externally, but is also used by the other class functions + */ + function getTextWidth($size, $text, $word_spacing = 0, $char_spacing = 0) + { + static $ord_cache = array(); + + // this function should not change any of the settings, though it will need to + // track any directives which change during calculation, so copy them at the start + // and put them back at the end. + $store_currentTextState = $this->currentTextState; + + if (!$this->numFonts) { + $this->selectFont($this->defaultFont); + } + + $text = str_replace(array("\r", "\n"), "", $text); + + // converts a number or a float to a string so it can get the width + $text = "$text"; + + // hmm, this is where it all starts to get tricky - use the font information to + // calculate the width of each character, add them up and convert to user units + $w = 0; + $cf = $this->currentFont; + $current_font = $this->fonts[$cf]; + $space_scale = 1000 / ($size > 0 ? $size : 1); + $n_spaces = 0; + + if ($current_font['isUnicode']) { + // for Unicode, use the code points array to calculate width rather + // than just the string itself + $unicode = $this->utf8toCodePointsArray($text); + + foreach ($unicode as $char) { + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + $n_spaces++; + } + } + } + + // add additionnal char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * (count($unicode) + $n_spaces); + } + + } else { + // If CPDF is in Unicode mode but the current font does not support Unicode we need to convert the character set to Windows-1252 + if ($this->isUnicode) { + $text = mb_convert_encoding($text, 'Windows-1252', 'UTF-8'); + } + + $len = mb_strlen($text, 'Windows-1252'); + + for ($i = 0; $i < $len; $i++) { + $c = $text[$i]; + $char = isset($ord_cache[$c]) ? $ord_cache[$c] : ($ord_cache[$c] = ord($c)); + + // check if we have to replace character + if (isset($current_font['differences'][$char])) { + $char = $current_font['differences'][$char]; + } + + if (isset($current_font['C'][$char])) { + $char_width = $current_font['C'][$char]; + + // add the character width + $w += $char_width; + + // add additional padding for space + if (isset($current_font['codeToName'][$char]) && $current_font['codeToName'][$char] === 'space') { // Space + $w += $word_spacing * $space_scale; + $n_spaces++; + } + } + } + + // add additionnal char spacing + if ($char_spacing != 0) { + $w += $char_spacing * $space_scale * ($len + $n_spaces); + } + } + + $this->currentTextState = $store_currentTextState; + $this->setCurrentFont(); + + return $w * $size / 1000; + } + + /** + * this will be called at a new page to return the state to what it was on the + * end of the previous page, before the stack was closed down + * This is to get around not being able to have open 'q' across pages + * + */ + function saveState($pageEnd = 0) + { + if ($pageEnd) { + // this will be called at a new page to return the state to what it was on the + // end of the previous page, before the stack was closed down + // This is to get around not being able to have open 'q' across pages + $opt = $this->stateStack[$pageEnd]; + // ok to use this as stack starts numbering at 1 + $this->setColor($opt['col'], true); + $this->setStrokeColor($opt['str'], true); + $this->addContent("\n" . $opt['lin']); + // $this->currentLineStyle = $opt['lin']; + } else { + $this->nStateStack++; + $this->stateStack[$this->nStateStack] = array( + 'col' => $this->currentColor, + 'str' => $this->currentStrokeColor, + 'lin' => $this->currentLineStyle + ); + } + + $this->save(); + } + + /** + * restore a previously saved state + */ + function restoreState($pageEnd = 0) + { + if (!$pageEnd) { + $n = $this->nStateStack; + $this->currentColor = $this->stateStack[$n]['col']; + $this->currentStrokeColor = $this->stateStack[$n]['str']; + $this->addContent("\n" . $this->stateStack[$n]['lin']); + $this->currentLineStyle = $this->stateStack[$n]['lin']; + $this->stateStack[$n] = null; + unset($this->stateStack[$n]); + $this->nStateStack--; + } + + $this->restore(); + } + + /** + * make a loose object, the output will go into this object, until it is closed, then will revert to + * the current one. + * this object will not appear until it is included within a page. + * the function will return the object number + */ + function openObject() + { + $this->nStack++; + $this->stack[$this->nStack] = array('c' => $this->currentContents, 'p' => $this->currentPage); + // add a new object of the content type, to hold the data flow + $this->numObj++; + $this->o_contents($this->numObj, 'new'); + $this->currentContents = $this->numObj; + $this->looseObjects[$this->numObj] = 1; + + return $this->numObj; + } + + /** + * open an existing object for editing + */ + function reopenObject($id) + { + $this->nStack++; + $this->stack[$this->nStack] = array('c' => $this->currentContents, 'p' => $this->currentPage); + $this->currentContents = $id; + + // also if this object is the primary contents for a page, then set the current page to its parent + if (isset($this->objects[$id]['onPage'])) { + $this->currentPage = $this->objects[$id]['onPage']; + } + } + + /** + * close an object + */ + function closeObject() + { + // close the object, as long as there was one open in the first place, which will be indicated by + // an objectId on the stack. + if ($this->nStack > 0) { + $this->currentContents = $this->stack[$this->nStack]['c']; + $this->currentPage = $this->stack[$this->nStack]['p']; + $this->nStack--; + // easier to probably not worry about removing the old entries, they will be overwritten + // if there are new ones. + } + } + + /** + * stop an object from appearing on pages from this point on + */ + function stopObject($id) + { + // if an object has been appearing on pages up to now, then stop it, this page will + // be the last one that could contian it. + if (isset($this->addLooseObjects[$id])) { + $this->addLooseObjects[$id] = ''; + } + } + + /** + * after an object has been created, it wil only show if it has been added, using this function. + */ + function addObject($id, $options = 'add') + { + // add the specified object to the page + if (isset($this->looseObjects[$id]) && $this->currentContents != $id) { + // then it is a valid object, and it is not being added to itself + switch ($options) { + case 'all': + // then this object is to be added to this page (done in the next block) and + // all future new pages. + $this->addLooseObjects[$id] = 'all'; + + case 'add': + if (isset($this->objects[$this->currentContents]['onPage'])) { + // then the destination contents is the primary for the page + // (though this object is actually added to that page) + $this->o_page($this->objects[$this->currentContents]['onPage'], 'content', $id); + } + break; + + case 'even': + $this->addLooseObjects[$id] = 'even'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 0) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'odd': + $this->addLooseObjects[$id] = 'odd'; + $pageObjectId = $this->objects[$this->currentContents]['onPage']; + if ($this->objects[$pageObjectId]['info']['pageNum'] % 2 == 1) { + $this->addObject($id); + // hacky huh :) + } + break; + + case 'next': + $this->addLooseObjects[$id] = 'all'; + break; + + case 'nexteven': + $this->addLooseObjects[$id] = 'even'; + break; + + case 'nextodd': + $this->addLooseObjects[$id] = 'odd'; + break; + } + } + } + + /** + * return a storable representation of a specific object + */ + function serializeObject($id) + { + if (array_key_exists($id, $this->objects)) { + return serialize($this->objects[$id]); + } + } + + /** + * restore an object from its stored representation. returns its new object id. + */ + function restoreSerializedObject($obj) + { + $obj_id = $this->openObject(); + $this->objects[$obj_id] = unserialize($obj); + $this->closeObject(); + + return $obj_id; + } + + /** + * add content to the documents info object + */ + function addInfo($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + // modify this so that arrays can be passed as well. + // if $label is an array then assume that it is key => value pairs + // else assume that they are both scalar, anything else will probably error + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_info($this->infoObject, $l, $v); + } + } else { + $this->o_info($this->infoObject, $label, $value); + } + } + + /** + * set the viewer preferences of the document, it is up to the browser to obey these. + */ + function setPreferences($label, $value = 0) + { + // this will only work if the label is one of the valid ones. + if (is_array($label)) { + foreach ($label as $l => $v) { + $this->o_catalog($this->catalogId, 'viewerPreferences', array($l => $v)); + } + } else { + $this->o_catalog($this->catalogId, 'viewerPreferences', array($label => $value)); + } + } + + /** + * extract an integer from a position in a byte stream + */ + private function getBytes(&$data, $pos, $num) + { + // return the integer represented by $num bytes from $pos within $data + $ret = 0; + for ($i = 0; $i < $num; $i++) { + $ret *= 256; + $ret += ord($data[$pos + $i]); + } + + return $ret; + } + + /** + * Check if image already added to pdf image directory. + * If yes, need not to create again (pass empty data) + */ + function image_iscached($imgname) + { + return isset($this->imagelist[$imgname]); + } + + /** + * add a PNG image into the document, from a GD object + * this should work with remote files + * + * @param string $file The PNG file + * @param float $x X position + * @param float $y Y position + * @param float $w Width + * @param float $h Height + * @param resource $img A GD resource + * @param bool $is_mask true if the image is a mask + * @param bool $mask true if the image is masked + */ + function addImagePng($file, $x, $y, $w = 0.0, $h = 0.0, &$img, $is_mask = false, $mask = null) + { + if (!function_exists("imagepng")) { + throw new Exception("The PHP GD extension is required, but is not installed."); + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $data = null; + } else { + // Example for transparency handling on new image. Retain for current image + // $tIndex = imagecolortransparent($img); + // if ($tIndex > 0) { + // $tColor = imagecolorsforindex($img, $tIndex); + // $new_tIndex = imagecolorallocate($new_img, $tColor['red'], $tColor['green'], $tColor['blue']); + // imagefill($new_img, 0, 0, $new_tIndex); + // imagecolortransparent($new_img, $new_tIndex); + // } + // blending mode (literal/blending) on drawing into current image. not relevant when not saved or not drawn + //imagealphablending($img, true); + + //default, but explicitely set to ensure pdf compatibility + imagesavealpha($img, false/*!$is_mask && !$mask*/); + + $error = 0; + + ob_start(); + @imagepng($img); + $data = ob_get_clean(); + + if ($data == '') { + $error = 1; + $errormsg = 'trouble writing file from GD'; + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + } //End isset($this->imagelist[$file]) (png Duplicate removal) + + $this->addPngFromBuf($file, $x, $y, $w, $h, $data, $is_mask, $mask); + } + + protected function addImagePngAlpha($file, $x, $y, $w, $h, $byte) + { + // generate images + $img = imagecreatefrompng($file); + + if ($img === false) { + return; + } + + // FIXME The pixel transformation doesn't work well with 8bit PNGs + $eight_bit = ($byte & 4) !== 4; + + $wpx = imagesx($img); + $hpx = imagesy($img); + + imagesavealpha($img, false); + + // create temp alpha file + $tempfile_alpha = tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_alpha); + $tempfile_alpha = "$tempfile_alpha.png"; + + // create temp plain file + $tempfile_plain = tempnam($this->tmp, "cpdf_img_"); + @unlink($tempfile_plain); + $tempfile_plain = "$tempfile_plain.png"; + + $imgalpha = imagecreate($wpx, $hpx); + imagesavealpha($imgalpha, false); + + // generate gray scale palette (0 -> 255) + for ($c = 0; $c < 256; ++$c) { + imagecolorallocate($imgalpha, $c, $c, $c); + } + + // Use PECL gmagick + Graphics Magic to process transparent PNG images + if (extension_loaded("gmagick")) { + $gmagick = new Gmagick($file); + $gmagick->setimageformat('png'); + + // Get opacity channel (negative of alpha channel) + $alpha_channel_neg = clone $gmagick; + $alpha_channel_neg->separateimagechannel(Gmagick::CHANNEL_OPACITY); + + // Negate opacity channel + $alpha_channel = new Gmagick(); + $alpha_channel->newimage($wpx, $hpx, "#FFFFFF", "png"); + $alpha_channel->compositeimage($alpha_channel_neg, Gmagick::COMPOSITE_DIFFERENCE, 0, 0); + $alpha_channel->separateimagechannel(Gmagick::CHANNEL_RED); + $alpha_channel->writeimage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + + // Make opaque image + $color_channels = new Gmagick(); + $color_channels->newimage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeimage($gmagick, Gmagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeimage($gmagick, Gmagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeimage($gmagick, Gmagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeimage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } // Use PECL imagick + ImageMagic to process transparent PNG images + elseif (extension_loaded("imagick")) { + // Native cloning was added to pecl-imagick in svn commit 263814 + // the first version containing it was 3.0.1RC1 + static $imagickClonable = null; + if ($imagickClonable === null) { + $imagickClonable = version_compare(phpversion('imagick'), '3.0.1rc1') > 0; + } + + $imagick = new Imagick($file); + $imagick->setFormat('png'); + + // Get opacity channel (negative of alpha channel) + $alpha_channel = $imagickClonable ? clone $imagick : $imagick->clone(); + $alpha_channel->separateImageChannel(Imagick::CHANNEL_ALPHA); + $alpha_channel->negateImage(true); + $alpha_channel->writeImage($tempfile_alpha); + + // Cast to 8bit+palette + $imgalpha_ = imagecreatefrompng($tempfile_alpha); + imagecopy($imgalpha, $imgalpha_, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($imgalpha_); + imagepng($imgalpha, $tempfile_alpha); + + // Make opaque image + $color_channels = new Imagick(); + $color_channels->newImage($wpx, $hpx, "#FFFFFF", "png"); + $color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYRED, 0, 0); + $color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYGREEN, 0, 0); + $color_channels->compositeImage($imagick, Imagick::COMPOSITE_COPYBLUE, 0, 0); + $color_channels->writeImage($tempfile_plain); + + $imgplain = imagecreatefrompng($tempfile_plain); + } else { + // allocated colors cache + $allocated_colors = array(); + + // extract alpha channel + for ($xpx = 0; $xpx < $wpx; ++$xpx) { + for ($ypx = 0; $ypx < $hpx; ++$ypx) { + $color = imagecolorat($img, $xpx, $ypx); + $col = imagecolorsforindex($img, $color); + $alpha = $col['alpha']; + + if ($eight_bit) { + // with gamma correction + $gammacorr = 2.2; + $pixel = pow((((127 - $alpha) * 255 / 127) / 255), $gammacorr) * 255; + } else { + // without gamma correction + $pixel = (127 - $alpha) * 2; + + $key = $col['red'] . $col['green'] . $col['blue']; + + if (!isset($allocated_colors[$key])) { + $pixel_img = imagecolorallocate($img, $col['red'], $col['green'], $col['blue']); + $allocated_colors[$key] = $pixel_img; + } else { + $pixel_img = $allocated_colors[$key]; + } + + imagesetpixel($img, $xpx, $ypx, $pixel_img); + } + + imagesetpixel($imgalpha, $xpx, $ypx, $pixel); + } + } + + // extract image without alpha channel + $imgplain = imagecreatetruecolor($wpx, $hpx); + imagecopy($imgplain, $img, 0, 0, 0, 0, $wpx, $hpx); + imagedestroy($img); + + imagepng($imgalpha, $tempfile_alpha); + imagepng($imgplain, $tempfile_plain); + } + + // embed mask image + $this->addImagePng($tempfile_alpha, $x, $y, $w, $h, $imgalpha, true); + imagedestroy($imgalpha); + + // embed image, masked with previously embedded mask + $this->addImagePng($tempfile_plain, $x, $y, $w, $h, $imgplain, false, true); + imagedestroy($imgplain); + + // remove temp files + unlink($tempfile_alpha); + unlink($tempfile_plain); + } + + /** + * add a PNG image into the document, from a file + * this should work with remote files + */ + function addPngFromFile($file, $x, $y, $w = 0, $h = 0) + { + if (!function_exists("imagecreatefrompng")) { + throw new Exception("The PHP GD extension is required, but is not installed."); + } + + //if already cached, need not to read again + if (isset($this->imagelist[$file])) { + $img = null; + } else { + $info = file_get_contents($file, false, null, 24, 5); + $meta = unpack("CbitDepth/CcolorType/CcompressionMethod/CfilterMethod/CinterlaceMethod", $info); + $bit_depth = $meta["bitDepth"]; + $color_type = $meta["colorType"]; + + // http://www.w3.org/TR/PNG/#11IHDR + // 3 => indexed + // 4 => greyscale with alpha + // 6 => fullcolor with alpha + $is_alpha = in_array($color_type, array(4, 6)) || ($color_type == 3 && $bit_depth != 4); + + if ($is_alpha) { // exclude grayscale alpha + return $this->addImagePngAlpha($file, $x, $y, $w, $h, $color_type); + } + + //png files typically contain an alpha channel. + //pdf file format or class.pdf does not support alpha blending. + //on alpha blended images, more transparent areas have a color near black. + //This appears in the result on not storing the alpha channel. + //Correct would be the box background image or its parent when transparent. + //But this would make the image dependent on the background. + //Therefore create an image with white background and copy in + //A more natural background than black is white. + //Therefore create an empty image with white background and merge the + //image in with alpha blending. + $imgtmp = @imagecreatefrompng($file); + if (!$imgtmp) { + return; + } + $sx = imagesx($imgtmp); + $sy = imagesy($imgtmp); + $img = imagecreatetruecolor($sx, $sy); + imagealphablending($img, true); + + // @todo is it still needed ?? + $ti = imagecolortransparent($imgtmp); + if ($ti >= 0) { + $tc = imagecolorsforindex($imgtmp, $ti); + $ti = imagecolorallocate($img, $tc['red'], $tc['green'], $tc['blue']); + imagefill($img, 0, 0, $ti); + imagecolortransparent($img, $ti); + } else { + imagefill($img, 1, 1, imagecolorallocate($img, 255, 255, 255)); + } + + imagecopy($img, $imgtmp, 0, 0, 0, 0, $sx, $sy); + imagedestroy($imgtmp); + } + $this->addImagePng($file, $x, $y, $w, $h, $img); + + if ($img) { + imagedestroy($img); + } + } + + /** + * add a PNG image into the document, from a memory buffer of the file + */ + function addPngFromBuf($file, $x, $y, $w = 0.0, $h = 0.0, &$data, $is_mask = false, $mask = null) + { + if (isset($this->imagelist[$file])) { + $data = null; + $info['width'] = $this->imagelist[$file]['w']; + $info['height'] = $this->imagelist[$file]['h']; + $label = $this->imagelist[$file]['label']; + } else { + if ($data == null) { + $this->addMessage('addPngFromBuf error - data not present!'); + + return; + } + + $error = 0; + + if (!$error) { + $header = chr(137) . chr(80) . chr(78) . chr(71) . chr(13) . chr(10) . chr(26) . chr(10); + + if (mb_substr($data, 0, 8, '8bit') != $header) { + $error = 1; + + $errormsg = 'this file does not have a valid header'; + } + } + + if (!$error) { + // set pointer + $p = 8; + $len = mb_strlen($data, '8bit'); + + // cycle through the file, identifying chunks + $haveHeader = 0; + $info = array(); + $idata = ''; + $pdata = ''; + + while ($p < $len) { + $chunkLen = $this->getBytes($data, $p, 4); + $chunkType = mb_substr($data, $p + 4, 4, '8bit'); + + switch ($chunkType) { + case 'IHDR': + // this is where all the file information comes from + $info['width'] = $this->getBytes($data, $p + 8, 4); + $info['height'] = $this->getBytes($data, $p + 12, 4); + $info['bitDepth'] = ord($data[$p + 16]); + $info['colorType'] = ord($data[$p + 17]); + $info['compressionMethod'] = ord($data[$p + 18]); + $info['filterMethod'] = ord($data[$p + 19]); + $info['interlaceMethod'] = ord($data[$p + 20]); + + //print_r($info); + $haveHeader = 1; + if ($info['compressionMethod'] != 0) { + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile unsupported compression method ' . $file . ']'; + } + + $errormsg = 'unsupported compression method'; + } + + if ($info['filterMethod'] != 0) { + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile unsupported filter method ' . $file . ']'; + } + + $errormsg = 'unsupported filter method'; + } + break; + + case 'PLTE': + $pdata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'IDAT': + $idata .= mb_substr($data, $p + 8, $chunkLen, '8bit'); + break; + + case 'tRNS': + //this chunk can only occur once and it must occur after the PLTE chunk and before IDAT chunk + //print "tRNS found, color type = ".$info['colorType']."\n"; + $transparency = array(); + + switch ($info['colorType']) { + // indexed color, rbg + case 3: + /* corresponding to entries in the plte chunk + Alpha for palette index 0: 1 byte + Alpha for palette index 1: 1 byte + ...etc... + */ + // there will be one entry for each palette entry. up until the last non-opaque entry. + // set up an array, stretching over all palette entries which will be o (opaque) or 1 (transparent) + $transparency['type'] = 'indexed'; + $trans = 0; + + for ($i = $chunkLen; $i >= 0; $i--) { + if (ord($data[$p + 8 + $i]) == 0) { + $trans = $i; + } + } + + $transparency['data'] = $trans; + break; + + // grayscale + case 0: + /* corresponding to entries in the plte chunk + Gray: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + // $transparency['grayscale'] = $this->PRVT_getBytes($data,$p+8,2); // g = grayscale + $transparency['type'] = 'indexed'; + $transparency['data'] = ord($data[$p + 8 + 1]); + break; + + // truecolor + case 2: + /* corresponding to entries in the plte chunk + Red: 2 bytes, range 0 .. (2^bitdepth)-1 + Green: 2 bytes, range 0 .. (2^bitdepth)-1 + Blue: 2 bytes, range 0 .. (2^bitdepth)-1 + */ + $transparency['r'] = $this->getBytes($data, $p + 8, 2); + // r from truecolor + $transparency['g'] = $this->getBytes($data, $p + 10, 2); + // g from truecolor + $transparency['b'] = $this->getBytes($data, $p + 12, 2); + // b from truecolor + + $transparency['type'] = 'color-key'; + break; + + //unsupported transparency type + default: + if (DEBUGPNG) { + print '[addPngFromFile unsupported transparency type ' . $file . ']'; + } + break; + } + + // KS End new code + break; + + default: + break; + } + + $p += $chunkLen + 12; + } + + if (!$haveHeader) { + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile information header is missing ' . $file . ']'; + } + + $errormsg = 'information header is missing'; + } + + if (isset($info['interlaceMethod']) && $info['interlaceMethod']) { + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile no support for interlaced images in pdf ' . $file . ']'; + } + + $errormsg = 'There appears to be no support for interlaced images in pdf.'; + } + } + + if (!$error && $info['bitDepth'] > 8) { + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile bit depth of 8 or less is supported ' . $file . ']'; + } + + $errormsg = 'only bit depth of 8 or less is supported'; + } + + if (!$error) { + switch ($info['colorType']) { + case 3: + $color = 'DeviceRGB'; + $ncolor = 1; + break; + + case 2: + $color = 'DeviceRGB'; + $ncolor = 3; + break; + + case 0: + $color = 'DeviceGray'; + $ncolor = 1; + break; + + default: + $error = 1; + + //debugpng + if (DEBUGPNG) { + print '[addPngFromFile alpha channel not supported: ' . $info['colorType'] . ' ' . $file . ']'; + } + + $errormsg = 'transparancey alpha channel not supported, transparency only supported for palette images.'; + } + } + + if ($error) { + $this->addMessage('PNG error - (' . $file . ') ' . $errormsg); + + return; + } + + //print_r($info); + // so this image is ok... add it in. + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + // $this->o_image($this->numObj,'new',array('label' => $label,'data' => $idata,'iw' => $w,'ih' => $h,'type' => 'png','ic' => $info['width'])); + $options = array( + 'label' => $label, + 'data' => $idata, + 'bitsPerComponent' => $info['bitDepth'], + 'pdata' => $pdata, + 'iw' => $info['width'], + 'ih' => $info['height'], + 'type' => 'png', + 'color' => $color, + 'ncolor' => $ncolor, + 'masked' => $mask, + 'isMask' => $is_mask + ); + + if (isset($transparency)) { + $options['transparency'] = $transparency; + } + + $this->o_image($this->numObj, 'new', $options); + $this->imagelist[$file] = array('label' => $label, 'w' => $info['width'], 'h' => $info['height']); + } + + if ($is_mask) { + return; + } + + if ($w <= 0 && $h <= 0) { + $w = $info['width']; + $h = $info['height']; + } + + if ($w <= 0) { + $w = $h / $info['height'] * $info['width']; + } + + if ($h <= 0) { + $h = $w * $info['height'] / $info['width']; + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ", $w, $h, $x, $y, $label)); + } + + /** + * add a JPEG image into the document, from a file + */ + function addJpegFromFile($img, $x, $y, $w = 0, $h = 0) + { + // attempt to add a jpeg image straight from a file, using no GD commands + // note that this function is unable to operate on a remote file. + + if (!file_exists($img)) { + return; + } + + if ($this->image_iscached($img)) { + $data = null; + $imageWidth = $this->imagelist[$img]['w']; + $imageHeight = $this->imagelist[$img]['h']; + $channels = $this->imagelist[$img]['c']; + } else { + $tmp = getimagesize($img); + $imageWidth = $tmp[0]; + $imageHeight = $tmp[1]; + + if (isset($tmp['channels'])) { + $channels = $tmp['channels']; + } else { + $channels = 3; + } + + $data = file_get_contents($img); + } + + if ($w <= 0 && $h <= 0) { + $w = $imageWidth; + } + + if ($w == 0) { + $w = $h / $imageHeight * $imageWidth; + } + + if ($h == 0) { + $h = $w * $imageHeight / $imageWidth; + } + + $this->addJpegImage_common($data, $x, $y, $w, $h, $imageWidth, $imageHeight, $channels, $img); + } + + /** + * common code used by the two JPEG adding functions + */ + private function addJpegImage_common( + &$data, + $x, + $y, + $w = 0, + $h = 0, + $imageWidth, + $imageHeight, + $channels = 3, + $imgname + ) { + if ($this->image_iscached($imgname)) { + $label = $this->imagelist[$imgname]['label']; + //debugpng + //if (DEBUGPNG) print '[addJpegImage_common Duplicate '.$imgname.']'; + + } else { + if ($data == null) { + $this->addMessage('addJpegImage_common error - (' . $imgname . ') data not present!'); + + return; + } + + // note that this function is not to be called externally + // it is just the common code between the GD and the file options + $this->numImages++; + $im = $this->numImages; + $label = "I$im"; + $this->numObj++; + + $this->o_image( + $this->numObj, + 'new', + array( + 'label' => $label, + 'data' => &$data, + 'iw' => $imageWidth, + 'ih' => $imageHeight, + 'channels' => $channels + ) + ); + + $this->imagelist[$imgname] = array( + 'label' => $label, + 'w' => $imageWidth, + 'h' => $imageHeight, + 'c' => $channels + ); + } + + $this->addContent(sprintf("\nq\n%.3F 0 0 %.3F %.3F %.3F cm /%s Do\nQ ", $w, $h, $x, $y, $label)); + } + + /** + * specify where the document should open when it first starts + */ + function openHere($style, $a = 0, $b = 0, $c = 0) + { + // this function will open the document at a specified page, in a specified style + // the values for style, and the required paramters are: + // 'XYZ' left, top, zoom + // 'Fit' + // 'FitH' top + // 'FitV' left + // 'FitR' left,bottom,right + // 'FitB' + // 'FitBH' top + // 'FitBV' left + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + array('page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c) + ); + $id = $this->catalogId; + $this->o_catalog($id, 'openHere', $this->numObj); + } + + /** + * Add JavaScript code to the PDF document + * + * @param string $code + * + * @return void + */ + function addJavascript($code) + { + $this->javascript .= $code; + } + + /** + * create a labelled destination within the document + */ + function addDestination($label, $style, $a = 0, $b = 0, $c = 0) + { + // associates the given label with the destination, it is done this way so that a destination can be specified after + // it has been linked to + // styles are the same as the 'openHere' function + $this->numObj++; + $this->o_destination( + $this->numObj, + 'new', + array('page' => $this->currentPage, 'type' => $style, 'p1' => $a, 'p2' => $b, 'p3' => $c) + ); + $id = $this->numObj; + + // store the label->idf relationship, note that this means that labels can be used only once + $this->destinations["$label"] = $id; + } + + /** + * define font families, this is used to initialize the font families for the default fonts + * and for the user to add new ones for their fonts. The default bahavious can be overridden should + * that be desired. + */ + function setFontFamily($family, $options = '') + { + if (!is_array($options)) { + if ($family === 'init') { + // set the known family groups + // these font families will be used to enable bold and italic markers to be included + // within text streams. html forms will be used... + $this->fontFamilies['Helvetica.afm'] = + array( + 'b' => 'Helvetica-Bold.afm', + 'i' => 'Helvetica-Oblique.afm', + 'bi' => 'Helvetica-BoldOblique.afm', + 'ib' => 'Helvetica-BoldOblique.afm' + ); + + $this->fontFamilies['Courier.afm'] = + array( + 'b' => 'Courier-Bold.afm', + 'i' => 'Courier-Oblique.afm', + 'bi' => 'Courier-BoldOblique.afm', + 'ib' => 'Courier-BoldOblique.afm' + ); + + $this->fontFamilies['Times-Roman.afm'] = + array( + 'b' => 'Times-Bold.afm', + 'i' => 'Times-Italic.afm', + 'bi' => 'Times-BoldItalic.afm', + 'ib' => 'Times-BoldItalic.afm' + ); + } + } else { + + // the user is trying to set a font family + // note that this can also be used to set the base ones to something else + if (mb_strlen($family)) { + $this->fontFamilies[$family] = $options; + } + } + } + + /** + * used to add messages for use in debugging + */ + function addMessage($message) + { + $this->messages .= $message . "\n"; + } + + /** + * a few functions which should allow the document to be treated transactionally. + */ + function transaction($action) + { + switch ($action) { + case 'start': + // store all the data away into the checkpoint variable + $data = get_object_vars($this); + $this->checkpoint = $data; + unset($data); + break; + + case 'commit': + if (is_array($this->checkpoint) && isset($this->checkpoint['checkpoint'])) { + $tmp = $this->checkpoint['checkpoint']; + $this->checkpoint = $tmp; + unset($tmp); + } else { + $this->checkpoint = ''; + } + break; + + case 'rewind': + // do not destroy the current checkpoint, but move us back to the state then, so that we can try again + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + + foreach ($tmp as $k => $v) { + if ($k !== 'checkpoint') { + $this->$k = $v; + } + } + unset($tmp); + } + break; + + case 'abort': + if (is_array($this->checkpoint)) { + // can only abort if were inside a checkpoint + $tmp = $this->checkpoint; + foreach ($tmp as $k => $v) { + $this->$k = $v; + } + unset($tmp); + } + break; + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php new file mode 100644 index 0000000..fc85797 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceCpdf.php @@ -0,0 +1,486 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Document; +use Svg\Style; + +class SurfaceCpdf implements SurfaceInterface +{ + const DEBUG = false; + + /** @var \CPdf\CPdf */ + private $canvas; + + private $width; + private $height; + + /** @var Style */ + private $style; + + public function __construct(Document $doc, $canvas = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $dimensions = $doc->getDimensions(); + $w = $dimensions["width"]; + $h = $dimensions["height"]; + + if (!$canvas) { + $canvas = new \CPdf\CPdf(array(0, 0, $w, $h)); + $refl = new \ReflectionClass($canvas); + $canvas->fontcache = realpath(dirname($refl->getFileName()) . "/../../fonts/")."/"; + } + + // Flip PDF coordinate system so that the origin is in + // the top left rather than the bottom left + $canvas->transform(array( + 1, 0, + 0, -1, + 0, $h + )); + + $this->width = $w; + $this->height = $h; + + $this->canvas = $canvas; + } + + function out() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->canvas->output(); + } + + public function save() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->save(); + } + + public function restore() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->restore(); + } + + public function scale($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->transform($x, 0, 0, $y, 0, 0); + } + + public function rotate($angle) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $a = deg2rad($angle); + $cos_a = cos($a); + $sin_a = sin($a); + + $this->transform( + $cos_a, $sin_a, + -$sin_a, $cos_a, + 0, 0 + ); + } + + public function translate($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->transform( + 1, 0, + 0, 1, + $x, $y + ); + } + + public function transform($a, $b, $c, $d, $e, $f) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->canvas->transform(array($a, $b, $c, $d, $e, $f)); + } + + public function beginPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement beginPath() method. + } + + public function closePath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->closePath(); + } + + public function fillStroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fillStroke(); + } + + public function clip() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->clip(); + } + + public function fillText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->addText($x, $y, $this->style->fontSize, $text); + } + + public function strokeText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->addText($x, $y, $this->style->fontSize, $text); + } + + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + if (strpos($image, "data:") === 0) { + $parts = explode(',', $image, 2); + + $data = $parts[1]; + $base64 = false; + + $token = strtok($parts[0], ';'); + while ($token !== false) { + if ($token == 'base64') { + $base64 = true; + } + + $token = strtok(';'); + } + + if ($base64) { + $data = base64_decode($data); + } + } + else { + $data = file_get_contents($image); + } + + $image = tempnam("", "svg"); + file_put_contents($image, $data); + + $img = $this->image($image, $sx, $sy, $sw, $sh, "normal"); + + + unlink($image); + } + + public static function getimagesize($filename) + { + static $cache = array(); + + if (isset($cache[$filename])) { + return $cache[$filename]; + } + + list($width, $height, $type) = getimagesize($filename); + + if ($width == null || $height == null) { + $data = file_get_contents($filename, null, null, 0, 26); + + if (substr($data, 0, 2) === "BM") { + $meta = unpack('vtype/Vfilesize/Vreserved/Voffset/Vheadersize/Vwidth/Vheight', $data); + $width = (int)$meta['width']; + $height = (int)$meta['height']; + $type = IMAGETYPE_BMP; + } + } + + return $cache[$filename] = array($width, $height, $type); + } + + function image($img, $x, $y, $w, $h, $resolution = "normal") + { + list($width, $height, $type) = $this->getimagesize($img); + + switch ($type) { + case IMAGETYPE_JPEG: + $this->canvas->addJpegFromFile($img, $x, $y - $h, $w, $h); + break; + + case IMAGETYPE_GIF: + case IMAGETYPE_BMP: + // @todo use cache for BMP and GIF + $img = $this->_convert_gif_bmp_to_png($img, $type); + + case IMAGETYPE_PNG: + $this->canvas->addPngFromFile($img, $x, $y - $h, $w, $h); + break; + + default: + } + } + + public function lineTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->lineTo($x, $y); + } + + public function moveTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->moveTo($x, $y); + } + + public function quadraticCurveTo($cpx, $cpy, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + // FIXME not accurate + $this->canvas->quadTo($cpx, $cpy, $x, $y); + } + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->curveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + } + + public function arcTo($x1, $y1, $x2, $y2, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + } + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, $startAngle, $endAngle, false, false, false, true); + } + + public function circle($x, $y, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radius, $radius, 0, 8, 0, 360, true, false, false, false); + } + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radiusX, $radiusY, 0, 8, 0, 360, false, false, false, false); + } + + public function fillRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->fill(); + } + + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $canvas = $this->canvas; + + if ($rx <= 0.000001/* && $ry <= 0.000001*/) { + $canvas->rect($x, $y, $w, $h); + + return; + } + + $rx = min($rx, $w / 2); + $rx = min($rx, $h / 2); + + /* Define a path for a rectangle with corners rounded by a given radius. + * Start from the lower left corner and proceed counterclockwise. + */ + $this->moveTo($x + $rx, $y); + + /* Start of the arc segment in the lower right corner */ + $this->lineTo($x + $w - $rx, $y); + + /* Arc segment in the lower right corner */ + $this->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); + + /* Start of the arc segment in the upper right corner */ + $this->lineTo($x + $w, $y + $h - $rx ); + + /* Arc segment in the upper right corner */ + $this->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); + + /* Start of the arc segment in the upper left corner */ + $this->lineTo($x + $rx, $y + $h); + + /* Arc segment in the upper left corner */ + $this->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); + + /* Start of the arc segment in the lower left corner */ + $this->lineTo($x , $y + $rx); + + /* Arc segment in the lower left corner */ + $this->arc($x + $rx, $y + $rx, $rx, 180, 270); + } + + public function fill() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill(); + } + + public function strokeRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->stroke(); + } + + public function stroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->stroke(); + } + + public function endPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->endPath(); + } + + public function measureText($text) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $style = $this->getStyle(); + $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + + return $this->canvas->getTextWidth($this->getStyle()->fontSize, $text); + } + + public function getStyle() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->style; + } + + public function setStyle(Style $style) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->style = $style; + $canvas = $this->canvas; + + if (is_array($style->stroke) && $stroke = $style->stroke) { + $canvas->setStrokeColor(array((float)$stroke[0]/255, (float)$stroke[1]/255, (float)$stroke[2]/255), true); + } + + if (is_array($style->fill) && $fill = $style->fill) { + $canvas->setColor(array((float)$fill[0]/255, (float)$fill[1]/255, (float)$fill[2]/255), true); + } + + if ($fillRule = strtolower($style->fillRule)) { + $canvas->setFillRule($fillRule); + } + + $opacity = $style->opacity; + if ($opacity !== null && $opacity < 1.0) { + $canvas->setLineTransparency("Normal", $opacity); + $canvas->currentLineTransparency = null; + + $canvas->setFillTransparency("Normal", $opacity); + $canvas->currentFillTransparency = null; + } + else { + $fillOpacity = $style->fillOpacity; + if ($fillOpacity !== null && $fillOpacity < 1.0) { + $canvas->setFillTransparency("Normal", $fillOpacity); + $canvas->currentFillTransparency = null; + } + + $strokeOpacity = $style->strokeOpacity; + if ($strokeOpacity !== null && $strokeOpacity < 1.0) { + $canvas->setLineTransparency("Normal", $strokeOpacity); + $canvas->currentLineTransparency = null; + } + } + + $dashArray = null; + if ($style->strokeDasharray) { + $dashArray = preg_split('/\s*,\s*/', $style->strokeDasharray); + } + + $canvas->setLineStyle( + $style->strokeWidth, + $style->strokeLinecap, + $style->strokeLinejoin, + $dashArray + ); + + $this->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + } + + public function setFont($family, $style, $weight) + { + $map = array( + "serif" => "Times", + "sans-serif" => "Helvetica", + "fantasy" => "Symbol", + "cursive" => "Times", + "monospace" => "Courier", + + "arial" => "Helvetica", + "verdana" => "Helvetica", + ); + + $styleMap = array( + 'Helvetica' => array( + 'b' => 'Helvetica-Bold', + 'i' => 'Helvetica-Oblique', + 'bi' => 'Helvetica-BoldOblique', + ), + 'Courier' => array( + 'b' => 'Courier-Bold', + 'i' => 'Courier-Oblique', + 'bi' => 'Courier-BoldOblique', + ), + 'Times' => array( + '' => 'Times-Roman', + 'b' => 'Times-Bold', + 'i' => 'Times-Italic', + 'bi' => 'Times-BoldItalic', + ), + ); + + $family = strtolower($family); + $style = strtolower($style); + $weight = strtolower($weight); + + if (isset($map[$family])) { + $family = $map[$family]; + } + + if (isset($styleMap[$family])) { + $key = ""; + + if ($weight === "bold" || $weight === "bolder" || (is_numeric($weight) && $weight >= 600)) { + $key .= "b"; + } + + if ($style === "italic" || $style === "oblique") { + $key .= "i"; + } + + if (isset($styleMap[$family][$key])) { + $family = $styleMap[$family][$key]; + } + } + + $this->canvas->selectFont("$family.afm"); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php new file mode 100644 index 0000000..5d41906 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceGmagick.php @@ -0,0 +1,308 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Style; + +class SurfaceGmagick implements SurfaceInterface +{ + const DEBUG = false; + + /** @var \GmagickDraw */ + private $canvas; + + private $width; + private $height; + + /** @var Style */ + private $style; + + public function __construct($w, $h) + { + if (self::DEBUG) { + echo __FUNCTION__ . "\n"; + } + $this->width = $w; + $this->height = $h; + + $canvas = new \GmagickDraw(); + + $this->canvas = $canvas; + } + + function out() + { + if (self::DEBUG) { + echo __FUNCTION__ . "\n"; + } + + $image = new \Gmagick(); + $image->newimage($this->width, $this->height); + $image->drawimage($this->canvas); + + $tmp = tempnam("", "gm"); + + $image->write($tmp); + + return file_get_contents($tmp); + } + + public function save() + { + if (self::DEBUG) { + echo __FUNCTION__ . "\n"; + } + $this->canvas->save(); + } + + public function restore() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->restore(); + } + + public function scale($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->scale($x, $y); + } + + public function rotate($angle) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->rotate($angle); + } + + public function translate($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->translate($x, $y); + } + + public function transform($a, $b, $c, $d, $e, $f) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->concat($a, $b, $c, $d, $e, $f); + } + + public function beginPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement beginPath() method. + } + + public function closePath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->closepath(); + } + + public function fillStroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill_stroke(); + } + + public function clip() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->clip(); + } + + public function fillText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->set_text_pos($x, $y); + $this->canvas->show($text); + } + + public function strokeText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement drawImage() method. + } + + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + if (strpos($image, "data:") === 0) { + $data = substr($image, strpos($image, ";") + 1); + if (strpos($data, "base64") === 0) { + $data = base64_decode(substr($data, 7)); + } + + $image = tempnam("", "svg"); + file_put_contents($image, $data); + } + + $img = $this->canvas->load_image("auto", $image, ""); + + $sy = $sy - $sh; + $this->canvas->fit_image($img, $sx, $sy, 'boxsize={' . "$sw $sh" . '} fitmethod=entire'); + } + + public function lineTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->lineto($x, $y); + } + + public function moveTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->moveto($x, $y); + } + + public function quadraticCurveTo($cpx, $cpy, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement quadraticCurveTo() method. + } + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->curveto($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + } + + public function arcTo($x1, $y1, $x2, $y2, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + } + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->arc($x, $y, $radius, $startAngle, $endAngle); + } + + public function circle($x, $y, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->circle($x, $y, $radius); + } + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radiusX, $radiusY); + } + + public function fillRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->fill(); + } + + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->rect($x, $y, $w, $h); + } + + public function fill() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill(); + } + + public function strokeRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->stroke(); + } + + public function stroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->stroke(); + } + + public function endPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + //$this->canvas->endPath(); + } + + public function measureText($text) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $style = $this->getStyle(); + $font = $this->getFont($style->fontFamily, $style->fontStyle); + + return $this->canvas->stringwidth($text, $font, $this->getStyle()->fontSize); + } + + public function getStyle() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + return $this->style; + } + + public function setStyle(Style $style) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->style = $style; + $canvas = $this->canvas; + + if (is_array($style->stroke) && $stroke = $style->stroke) { + $canvas->setcolor("stroke", "rgb", $stroke[0] / 255, $stroke[1] / 255, $stroke[2] / 255, null); + } + + if (is_array($style->fill) && $fill = $style->fill) { + // $canvas->setcolor("fill", "rgb", $fill[0] / 255, $fill[1] / 255, $fill[2] / 255, null); + } + + $opts = array(); + if ($style->strokeWidth > 0.000001) { + $opts[] = "linewidth=$style->strokeWidth"; + } + + if (in_array($style->strokeLinecap, array("butt", "round", "projecting"))) { + $opts[] = "linecap=$style->strokeLinecap"; + } + + if (in_array($style->strokeLinejoin, array("miter", "round", "bevel"))) { + $opts[] = "linejoin=$style->strokeLinejoin"; + } + + $canvas->set_graphics_option(implode(" ", $opts)); + + $font = $this->getFont($style->fontFamily, $style->fontStyle); + $canvas->setfont($font, $style->fontSize); + } + + private function getFont($family, $style) + { + $map = array( + "serif" => "Times", + "sans-serif" => "Helvetica", + "fantasy" => "Symbol", + "cursive" => "serif", + "monospance" => "Courier", + ); + + $family = strtolower($family); + if (isset($map[$family])) { + $family = $map[$family]; + } + + return $this->canvas->load_font($family, "unicode", "fontstyle=$style"); + } + + public function setFont($family, $style, $weight) + { + // TODO: Implement setFont() method. + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php new file mode 100644 index 0000000..fb007ed --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfaceInterface.php @@ -0,0 +1,90 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Style; + +/** + * Interface Surface, like CanvasRenderingContext2D + * + * @package Svg + */ +interface SurfaceInterface +{ + public function save(); + + public function restore(); + + // transformations (default transform is the identity matrix) + public function scale($x, $y); + + public function rotate($angle); + + public function translate($x, $y); + + public function transform($a, $b, $c, $d, $e, $f); + + // path ends + public function beginPath(); + + public function closePath(); + + public function fill(); + + public function stroke(); + + public function endPath(); + + public function fillStroke(); + + public function clip(); + + // text (see also the CanvasDrawingStyles interface) + public function fillText($text, $x, $y, $maxWidth = null); + + public function strokeText($text, $x, $y, $maxWidth = null); + + public function measureText($text); + + // drawing images + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null); + + // paths + public function lineTo($x, $y); + + public function moveTo($x, $y); + + public function quadraticCurveTo($cpx, $cpy, $x, $y); + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + + public function arcTo($x1, $y1, $x2, $y2, $radius); + + public function circle($x, $y, $radius); + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false); + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise); + + // Rectangle + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0); + + public function fillRect($x, $y, $w, $h); + + public function strokeRect($x, $y, $w, $h); + + public function setStyle(Style $style); + + /** + * @return Style + */ + public function getStyle(); + + public function setFont($family, $style, $weight); +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php new file mode 100644 index 0000000..a4d1734 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Surface/SurfacePDFLib.php @@ -0,0 +1,422 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Surface; + +use Svg\Style; +use Svg\Document; + +class SurfacePDFLib implements SurfaceInterface +{ + const DEBUG = false; + + private $canvas; + + private $width; + private $height; + + /** @var Style */ + private $style; + + public function __construct(Document $doc, $canvas = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $dimensions = $doc->getDimensions(); + $w = $dimensions["width"]; + $h = $dimensions["height"]; + + if (!$canvas) { + $canvas = new \PDFlib(); + + /* all strings are expected as utf8 */ + $canvas->set_option("stringformat=utf8"); + $canvas->set_option("errorpolicy=return"); + + /* open new PDF file; insert a file name to create the PDF on disk */ + if ($canvas->begin_document("", "") == 0) { + die("Error: " . $canvas->get_errmsg()); + } + $canvas->set_info("Creator", "PDFlib starter sample"); + $canvas->set_info("Title", "starter_graphics"); + + $canvas->begin_page_ext($w, $h, ""); + } + + // Flip PDF coordinate system so that the origin is in + // the top left rather than the bottom left + $canvas->setmatrix( + 1, 0, + 0, -1, + 0, $h + ); + + $this->width = $w; + $this->height = $h; + + $this->canvas = $canvas; + } + + function out() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->canvas->end_page_ext(""); + $this->canvas->end_document(""); + + return $this->canvas->get_buffer(); + } + + public function save() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->save(); + } + + public function restore() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->restore(); + } + + public function scale($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->scale($x, $y); + } + + public function rotate($angle) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->rotate($angle); + } + + public function translate($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->translate($x, $y); + } + + public function transform($a, $b, $c, $d, $e, $f) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->concat($a, $b, $c, $d, $e, $f); + } + + public function beginPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement beginPath() method. + } + + public function closePath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->closepath(); + } + + public function fillStroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill_stroke(); + } + + public function clip() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->clip(); + } + + public function fillText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->set_text_pos($x, $y); + $this->canvas->show($text); + } + + public function strokeText($text, $x, $y, $maxWidth = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + // TODO: Implement drawImage() method. + } + + public function drawImage($image, $sx, $sy, $sw = null, $sh = null, $dx = null, $dy = null, $dw = null, $dh = null) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + if (strpos($image, "data:") === 0) { + $data = substr($image, strpos($image, ";") + 1); + if (strpos($data, "base64") === 0) { + $data = base64_decode(substr($data, 7)); + } + } + else { + $data = file_get_contents($image); + } + + $image = tempnam("", "svg"); + file_put_contents($image, $data); + + $img = $this->canvas->load_image("auto", $image, ""); + + $sy = $sy - $sh; + $this->canvas->fit_image($img, $sx, $sy, 'boxsize={' . "$sw $sh" . '} fitmethod=entire'); + + unlink($image); + } + + public function lineTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->lineto($x, $y); + } + + public function moveTo($x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->moveto($x, $y); + } + + public function quadraticCurveTo($cpx, $cpy, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + // FIXME not accurate + $this->canvas->curveTo($cpx, $cpy, $cpx, $cpy, $x, $y); + } + + public function bezierCurveTo($cp1x, $cp1y, $cp2x, $cp2y, $x, $y) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->curveto($cp1x, $cp1y, $cp2x, $cp2y, $x, $y); + } + + public function arcTo($x1, $y1, $x2, $y2, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + } + + public function arc($x, $y, $radius, $startAngle, $endAngle, $anticlockwise = false) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->arc($x, $y, $radius, $startAngle, $endAngle); + } + + public function circle($x, $y, $radius) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->circle($x, $y, $radius); + } + + public function ellipse($x, $y, $radiusX, $radiusY, $rotation, $startAngle, $endAngle, $anticlockwise) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->ellipse($x, $y, $radiusX, $radiusY); + } + + public function fillRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->fill(); + } + + public function rect($x, $y, $w, $h, $rx = 0, $ry = 0) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $canvas = $this->canvas; + + if ($rx <= 0.000001/* && $ry <= 0.000001*/) { + $canvas->rect($x, $y, $w, $h); + + return; + } + + /* Define a path for a rectangle with corners rounded by a given radius. + * Start from the lower left corner and proceed counterclockwise. + */ + $canvas->moveto($x + $rx, $y); + + /* Start of the arc segment in the lower right corner */ + $canvas->lineto($x + $w - $rx, $y); + + /* Arc segment in the lower right corner */ + $canvas->arc($x + $w - $rx, $y + $rx, $rx, 270, 360); + + /* Start of the arc segment in the upper right corner */ + $canvas->lineto($x + $w, $y + $h - $rx ); + + /* Arc segment in the upper right corner */ + $canvas->arc($x + $w - $rx, $y + $h - $rx, $rx, 0, 90); + + /* Start of the arc segment in the upper left corner */ + $canvas->lineto($x + $rx, $y + $h); + + /* Arc segment in the upper left corner */ + $canvas->arc($x + $rx, $y + $h - $rx, $rx, 90, 180); + + /* Start of the arc segment in the lower left corner */ + $canvas->lineto($x , $y + $rx); + + /* Arc segment in the lower left corner */ + $canvas->arc($x + $rx, $y + $rx, $rx, 180, 270); + } + + public function fill() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->fill(); + } + + public function strokeRect($x, $y, $w, $h) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->rect($x, $y, $w, $h); + $this->stroke(); + } + + public function stroke() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->stroke(); + } + + public function endPath() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $this->canvas->endPath(); + } + + public function measureText($text) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + $style = $this->getStyle(); + $font = $this->getFont($style->fontFamily, $style->fontStyle); + + return $this->canvas->stringwidth($text, $font, $this->getStyle()->fontSize); + } + + public function getStyle() + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + return $this->style; + } + + public function setStyle(Style $style) + { + if (self::DEBUG) echo __FUNCTION__ . "\n"; + + $this->style = $style; + $canvas = $this->canvas; + + if ($stroke = $style->stroke && is_array($style->stroke)) { + $canvas->setcolor( + "stroke", + "rgb", + $stroke[0] / 255, + $stroke[1] / 255, + $stroke[2] / 255, + null + ); + } + + if ($fill = $style->fill && is_array($style->fill)) { + $canvas->setcolor( + "fill", + "rgb", + $fill[0] / 255, + $fill[1] / 255, + $fill[2] / 255, + null + ); + } + + if ($fillRule = strtolower($style->fillRule)) { + $map = array( + "nonzero" => "winding", + "evenodd" => "evenodd", + ); + + if (isset($map[$fillRule])) { + $fillRule = $map[$fillRule]; + + $canvas->set_parameter("fillrule", $fillRule); + } + } + + $opts = array(); + if ($style->strokeWidth > 0.000001) { + $opts[] = "linewidth=$style->strokeWidth"; + } + + if (in_array($style->strokeLinecap, array("butt", "round", "projecting"))) { + $opts[] = "linecap=$style->strokeLinecap"; + } + + if (in_array($style->strokeLinejoin, array("miter", "round", "bevel"))) { + $opts[] = "linejoin=$style->strokeLinejoin"; + } + + $canvas->set_graphics_option(implode(" ", $opts)); + + $opts = array(); + $opacity = $style->opacity; + if ($opacity !== null && $opacity < 1.0) { + $opts[] = "opacityfill=$opacity"; + $opts[] = "opacitystroke=$opacity"; + } + else { + $fillOpacity = $style->fillOpacity; + if ($fillOpacity !== null && $fillOpacity < 1.0) { + $opts[] = "opacityfill=$fillOpacity"; + } + + $strokeOpacity = $style->strokeOpacity; + if ($strokeOpacity !== null && $strokeOpacity < 1.0) { + $opts[] = "opacitystroke=$strokeOpacity"; + } + } + + if (count($opts)) { + $gs = $canvas->create_gstate(implode(" ", $opts)); + $canvas->set_gstate($gs); + } + + $font = $this->getFont($style->fontFamily, $style->fontStyle); + if ($font) { + $canvas->setfont($font, $style->fontSize); + } + } + + private function getFont($family, $style) + { + $map = array( + "serif" => "Times", + "sans-serif" => "Helvetica", + "fantasy" => "Symbol", + "cursive" => "Times", + "monospace" => "Courier", + + "arial" => "Helvetica", + "verdana" => "Helvetica", + ); + + $family = strtolower($family); + if (isset($map[$family])) { + $family = $map[$family]; + } + + return $this->canvas->load_font($family, "unicode", "fontstyle=$style"); + } + + public function setFont($family, $style, $weight) + { + // TODO: Implement setFont() method. + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php new file mode 100644 index 0000000..7044cdd --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/AbstractTag.php @@ -0,0 +1,190 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Document; +use Svg\Style; + +abstract class AbstractTag +{ + /** @var Document */ + protected $document; + + public $tagName; + + /** @var Style */ + protected $style; + + protected $attributes = array(); + + protected $hasShape = true; + + /** @var self[] */ + protected $children = array(); + + public function __construct(Document $document, $tagName) + { + $this->document = $document; + $this->tagName = $tagName; + } + + public function getDocument(){ + return $this->document; + } + + /** + * @return Group|null + */ + public function getParentGroup() { + $stack = $this->getDocument()->getStack(); + for ($i = count($stack)-2; $i >= 0; $i--) { + $tag = $stack[$i]; + + if ($tag instanceof Group || $tag instanceof Document) { + return $tag; + } + } + + return null; + } + + public function handle($attributes) + { + $this->attributes = $attributes; + + if (!$this->getDocument()->inDefs) { + $this->before($attributes); + $this->start($attributes); + } + } + + public function handleEnd() + { + if (!$this->getDocument()->inDefs) { + $this->end(); + $this->after(); + } + } + + protected function before($attributes) + { + } + + protected function start($attributes) + { + } + + protected function end() + { + } + + protected function after() + { + } + + public function getAttributes() + { + return $this->attributes; + } + + protected function setStyle(Style $style) + { + $this->style = $style; + + if ($style->display === "none") { + $this->hasShape = false; + } + } + + /** + * @return Style + */ + public function getStyle() + { + return $this->style; + } + + /** + * Make a style object from the tag and its attributes + * + * @param array $attributes + * + * @return Style + */ + protected function makeStyle($attributes) { + $style = new Style(); + $style->inherit($this); + $style->fromStyleSheets($this, $attributes); + $style->fromAttributes($attributes); + + return $style; + } + + protected function applyTransform($attributes) + { + + if (isset($attributes["transform"])) { + $surface = $this->document->getSurface(); + + $transform = $attributes["transform"]; + + $match = array(); + preg_match_all( + '/(matrix|translate|scale|rotate|skewX|skewY)\((.*?)\)/is', + $transform, + $match, + PREG_SET_ORDER + ); + + $transformations = array(); + if (count($match[0])) { + foreach ($match as $_match) { + $arguments = preg_split('/[ ,]+/', $_match[2]); + array_unshift($arguments, $_match[1]); + $transformations[] = $arguments; + } + } + + foreach ($transformations as $t) { + switch ($t[0]) { + case "matrix": + $surface->transform($t[1], $t[2], $t[3], $t[4], $t[5], $t[6]); + break; + + case "translate": + $surface->translate($t[1], isset($t[2]) ? $t[2] : 0); + break; + + case "scale": + $surface->scale($t[1], isset($t[2]) ? $t[2] : $t[1]); + break; + + case "rotate": + if (isset($t[2])) { + $t[3] = isset($t[3]) ? $t[3] : 0; + $surface->translate($t[2], $t[3]); + $surface->rotate($t[1]); + $surface->translate(-$t[2], -$t[3]); + } else { + $surface->rotate($t[1]); + } + break; + + case "skewX": + $surface->skewX($t[1]); + break; + + case "skewY": + $surface->skewY($t[1]); + break; + } + } + } + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php new file mode 100644 index 0000000..9a4b3fe --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Anchor.php @@ -0,0 +1,14 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Anchor extends Group +{ + +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php new file mode 100644 index 0000000..2e516b4 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Circle.php @@ -0,0 +1,31 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Circle extends Shape +{ + protected $cx = 0; + protected $cy = 0; + protected $r; + + public function start($attributes) + { + if (isset($attributes['cx'])) { + $this->cx = $attributes['cx']; + } + if (isset($attributes['cy'])) { + $this->cy = $attributes['cy']; + } + if (isset($attributes['r'])) { + $this->r = $attributes['r']; + } + + $this->document->getSurface()->circle($this->cx, $this->cy, $this->r); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php new file mode 100644 index 0000000..54ee084 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/ClipPath.php @@ -0,0 +1,33 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class ClipPath extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php new file mode 100644 index 0000000..483e51e --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Ellipse.php @@ -0,0 +1,37 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Ellipse extends Shape +{ + protected $cx = 0; + protected $cy = 0; + protected $rx = 0; + protected $ry = 0; + + public function start($attributes) + { + parent::start($attributes); + + if (isset($attributes['cx'])) { + $this->cx = $attributes['cx']; + } + if (isset($attributes['cy'])) { + $this->cy = $attributes['cy']; + } + if (isset($attributes['rx'])) { + $this->rx = $attributes['rx']; + } + if (isset($attributes['ry'])) { + $this->ry = $attributes['ry']; + } + + $this->document->getSurface()->ellipse($this->cx, $this->cy, $this->rx, $this->ry, 0, 0, 360, false); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php new file mode 100644 index 0000000..542bfbd --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Group.php @@ -0,0 +1,33 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Group extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php new file mode 100644 index 0000000..f356b28 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Image.php @@ -0,0 +1,62 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Image extends AbstractTag +{ + protected $x = 0; + protected $y = 0; + protected $width = 0; + protected $height = 0; + protected $href = null; + + protected function before($attributes) + { + parent::before($attributes); + + $surface = $this->document->getSurface(); + $surface->save(); + + $this->applyTransform($attributes); + } + + public function start($attributes) + { + $document = $this->document; + $height = $this->document->getHeight(); + $this->y = $height; + + if (isset($attributes['x'])) { + $this->x = $attributes['x']; + } + if (isset($attributes['y'])) { + $this->y = $height - $attributes['y']; + } + + if (isset($attributes['width'])) { + $this->width = $attributes['width']; + } + if (isset($attributes['height'])) { + $this->height = $attributes['height']; + } + + if (isset($attributes['xlink:href'])) { + $this->href = $attributes['xlink:href']; + } + + $document->getSurface()->transform(1, 0, 0, -1, 0, $height); + + $document->getSurface()->drawImage($this->href, $this->x, $this->y, $this->width, $this->height); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php new file mode 100644 index 0000000..42504bc --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Line.php @@ -0,0 +1,38 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Line extends Shape +{ + protected $x1 = 0; + protected $y1 = 0; + + protected $x2 = 0; + protected $y2 = 0; + + public function start($attributes) + { + if (isset($attributes['x1'])) { + $this->x1 = $attributes['x1']; + } + if (isset($attributes['y1'])) { + $this->y1 = $attributes['y1']; + } + if (isset($attributes['x2'])) { + $this->x2 = $attributes['x2']; + } + if (isset($attributes['y2'])) { + $this->y2 = $attributes['y2']; + } + + $surface = $this->document->getSurface(); + $surface->moveTo($this->x1, $this->y1); + $surface->lineTo($this->x2, $this->y2); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php new file mode 100644 index 0000000..605ec23 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/LinearGradient.php @@ -0,0 +1,83 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + + +use Svg\Gradient; +use Svg\Style; + +class LinearGradient extends AbstractTag +{ + protected $x1; + protected $y1; + protected $x2; + protected $y2; + + /** @var Gradient\Stop[] */ + protected $stops = array(); + + public function start($attributes) + { + parent::start($attributes); + + if (isset($attributes['x1'])) { + $this->x1 = $attributes['x1']; + } + if (isset($attributes['y1'])) { + $this->y1 = $attributes['y1']; + } + if (isset($attributes['x2'])) { + $this->x2 = $attributes['x2']; + } + if (isset($attributes['y2'])) { + $this->y2 = $attributes['y2']; + } + } + + public function getStops() { + if (empty($this->stops)) { + foreach ($this->children as $_child) { + if ($_child->tagName != "stop") { + continue; + } + + $_stop = new Gradient\Stop(); + $_attributes = $_child->attributes; + + // Style + if (isset($_attributes["style"])) { + $_style = Style::parseCssStyle($_attributes["style"]); + + if (isset($_style["stop-color"])) { + $_stop->color = Style::parseColor($_style["stop-color"]); + } + + if (isset($_style["stop-opacity"])) { + $_stop->opacity = max(0, min(1.0, $_style["stop-opacity"])); + } + } + + // Attributes + if (isset($_attributes["offset"])) { + $_stop->offset = $_attributes["offset"]; + } + if (isset($_attributes["stop-color"])) { + $_stop->color = Style::parseColor($_attributes["stop-color"]); + } + if (isset($_attributes["stop-opacity"])) { + $_stop->opacity = max(0, min(1.0, $_attributes["stop-opacity"])); + } + + $this->stops[] = $_stop; + } + } + + return $this->stops; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php new file mode 100644 index 0000000..c43d638 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Path.php @@ -0,0 +1,528 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Surface\SurfaceInterface; + +class Path extends Shape +{ + static $commandLengths = array( + 'm' => 2, + 'l' => 2, + 'h' => 1, + 'v' => 1, + 'c' => 6, + 's' => 4, + 'q' => 4, + 't' => 2, + 'a' => 7, + ); + + static $repeatedCommands = array( + 'm' => 'l', + 'M' => 'L', + ); + + public function start($attributes) + { + if (!isset($attributes['d'])) { + $this->hasShape = false; + + return; + } + + $commands = array(); + preg_match_all('/([MZLHVCSQTAmzlhvcsqta])([eE ,\-.\d]+)*/', $attributes['d'], $commands, PREG_SET_ORDER); + + $path = array(); + foreach ($commands as $c) { + if (count($c) == 3) { + $arguments = array(); + preg_match_all('/([-+]?((\d+\.\d+)|((\d+)|(\.\d+)))(?:e[-+]?\d+)?)/i', $c[2], $arguments, PREG_PATTERN_ORDER); + $item = $arguments[0]; + $commandLower = strtolower($c[1]); + + if ( + isset(self::$commandLengths[$commandLower]) && + ($commandLength = self::$commandLengths[$commandLower]) && + count($item) > $commandLength + ) { + $repeatedCommand = isset(self::$repeatedCommands[$c[1]]) ? self::$repeatedCommands[$c[1]] : $c[1]; + $command = $c[1]; + + for ($k = 0, $klen = count($item); $k < $klen; $k += $commandLength) { + $_item = array_slice($item, $k, $k + $commandLength); + array_unshift($_item, $command); + $path[] = $_item; + + $command = $repeatedCommand; + } + } else { + array_unshift($item, $c[1]); + $path[] = $item; + } + + } else { + $item = array($c[1]); + + $path[] = $item; + } + } + + $surface = $this->document->getSurface(); + + // From https://github.com/kangax/fabric.js/blob/master/src/shapes/path.class.js + $current = null; // current instruction + $previous = null; + $subpathStartX = 0; + $subpathStartY = 0; + $x = 0; // current x + $y = 0; // current y + $controlX = 0; // current control point x + $controlY = 0; // current control point y + $tempX = null; + $tempY = null; + $tempControlX = null; + $tempControlY = null; + $l = 0; //-((this.width / 2) + $this.pathOffset.x), + $t = 0; //-((this.height / 2) + $this.pathOffset.y), + $methodName = null; + + foreach ($path as $current) { + switch ($current[0]) { // first letter + case 'l': // lineto, relative + $x += $current[1]; + $y += $current[2]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'L': // lineto, absolute + $x = $current[1]; + $y = $current[2]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'h': // horizontal lineto, relative + $x += $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'H': // horizontal lineto, absolute + $x = $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'v': // vertical lineto, relative + $y += $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'V': // verical lineto, absolute + $y = $current[1]; + $surface->lineTo($x + $l, $y + $t); + break; + + case 'm': // moveTo, relative + $x += $current[1]; + $y += $current[2]; + $subpathStartX = $x; + $subpathStartY = $y; + $surface->moveTo($x + $l, $y + $t); + break; + + case 'M': // moveTo, absolute + $x = $current[1]; + $y = $current[2]; + $subpathStartX = $x; + $subpathStartY = $y; + $surface->moveTo($x + $l, $y + $t); + break; + + case 'c': // bezierCurveTo, relative + $tempX = $x + $current[5]; + $tempY = $y + $current[6]; + $controlX = $x + $current[3]; + $controlY = $y + $current[4]; + $surface->bezierCurveTo( + $x + $current[1] + $l, // x1 + $y + $current[2] + $t, // y1 + $controlX + $l, // x2 + $controlY + $t, // y2 + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'C': // bezierCurveTo, absolute + $x = $current[5]; + $y = $current[6]; + $controlX = $current[3]; + $controlY = $current[4]; + $surface->bezierCurveTo( + $current[1] + $l, + $current[2] + $t, + $controlX + $l, + $controlY + $t, + $x + $l, + $y + $t + ); + break; + + case 's': // shorthand cubic bezierCurveTo, relative + + // transform to absolute x,y + $tempX = $x + $current[3]; + $tempY = $y + $current[4]; + + if (!preg_match('/[CcSs]/', $previous[0])) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + $controlX = $x; + $controlY = $y; + } else { + // calculate reflection of previous control points + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } + + $surface->bezierCurveTo( + $controlX + $l, + $controlY + $t, + $x + $current[1] + $l, + $y + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + $controlX = $x + $current[1]; + $controlY = $y + $current[2]; + + $x = $tempX; + $y = $tempY; + break; + + case 'S': // shorthand cubic bezierCurveTo, absolute + $tempX = $current[3]; + $tempY = $current[4]; + + if (!preg_match('/[CcSs]/', $previous[0])) { + // If there is no previous command or if the previous command was not a C, c, S, or s, + // the control point is coincident with the current point + $controlX = $x; + $controlY = $y; + } else { + // calculate reflection of previous control points + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } + + $surface->bezierCurveTo( + $controlX + $l, + $controlY + $t, + $current[1] + $l, + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + + // set control point to 2nd one of this command + // "... the first control point is assumed to be + // the reflection of the second control point on + // the previous command relative to the current point." + $controlX = $current[1]; + $controlY = $current[2]; + + break; + + case 'q': // quadraticCurveTo, relative + // transform to absolute x,y + $tempX = $x + $current[3]; + $tempY = $y + $current[4]; + + $controlX = $x + $current[1]; + $controlY = $y + $current[2]; + + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'Q': // quadraticCurveTo, absolute + $tempX = $current[3]; + $tempY = $current[4]; + + $surface->quadraticCurveTo( + $current[1] + $l, + $current[2] + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + $controlX = $current[1]; + $controlY = $current[2]; + break; + + case 't': // shorthand quadraticCurveTo, relative + + // transform to absolute x,y + $tempX = $x + $current[1]; + $tempY = $y + $current[2]; + + if (preg_match("/[QqTt]/", $previous[0])) { + // If there is no previous command or if the previous command was not a Q, q, T or t, + // assume the control point is coincident with the current point + $controlX = $x; + $controlY = $y; + } else { + if ($previous[0] === 't') { + // calculate reflection of previous control points for t + $controlX = 2 * $x - $tempControlX; + $controlY = 2 * $y - $tempControlY; + } else { + if ($previous[0] === 'q') { + // calculate reflection of previous control points for q + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + } + } + } + + $tempControlX = $controlX; + $tempControlY = $controlY; + + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + $controlX = $x + $current[1]; + $controlY = $y + $current[2]; + break; + + case 'T': + $tempX = $current[1]; + $tempY = $current[2]; + + // calculate reflection of previous control points + $controlX = 2 * $x - $controlX; + $controlY = 2 * $y - $controlY; + $surface->quadraticCurveTo( + $controlX + $l, + $controlY + $t, + $tempX + $l, + $tempY + $t + ); + $x = $tempX; + $y = $tempY; + break; + + case 'a': + // TODO: optimize this + $this->drawArc( + $surface, + $x + $l, + $y + $t, + array( + $current[1], + $current[2], + $current[3], + $current[4], + $current[5], + $current[6] + $x + $l, + $current[7] + $y + $t + ) + ); + $x += $current[6]; + $y += $current[7]; + break; + + case 'A': + // TODO: optimize this + $this->drawArc( + $surface, + $x + $l, + $y + $t, + array( + $current[1], + $current[2], + $current[3], + $current[4], + $current[5], + $current[6] + $l, + $current[7] + $t + ) + ); + $x = $current[6]; + $y = $current[7]; + break; + + case 'z': + case 'Z': + $x = $subpathStartX; + $y = $subpathStartY; + $surface->closePath(); + break; + } + $previous = $current; + } + } + + function drawArc(SurfaceInterface $surface, $fx, $fy, $coords) + { + $rx = $coords[0]; + $ry = $coords[1]; + $rot = $coords[2]; + $large = $coords[3]; + $sweep = $coords[4]; + $tx = $coords[5]; + $ty = $coords[6]; + $segs = array( + array(), + array(), + array(), + array(), + ); + + $segsNorm = $this->arcToSegments($tx - $fx, $ty - $fy, $rx, $ry, $large, $sweep, $rot); + + for ($i = 0, $len = count($segsNorm); $i < $len; $i++) { + $segs[$i][0] = $segsNorm[$i][0] + $fx; + $segs[$i][1] = $segsNorm[$i][1] + $fy; + $segs[$i][2] = $segsNorm[$i][2] + $fx; + $segs[$i][3] = $segsNorm[$i][3] + $fy; + $segs[$i][4] = $segsNorm[$i][4] + $fx; + $segs[$i][5] = $segsNorm[$i][5] + $fy; + + call_user_func_array(array($surface, "bezierCurveTo"), $segs[$i]); + } + } + + function arcToSegments($toX, $toY, $rx, $ry, $large, $sweep, $rotateX) + { + $th = $rotateX * M_PI / 180; + $sinTh = sin($th); + $cosTh = cos($th); + $fromX = 0; + $fromY = 0; + + $rx = abs($rx); + $ry = abs($ry); + + $px = -$cosTh * $toX * 0.5 - $sinTh * $toY * 0.5; + $py = -$cosTh * $toY * 0.5 + $sinTh * $toX * 0.5; + $rx2 = $rx * $rx; + $ry2 = $ry * $ry; + $py2 = $py * $py; + $px2 = $px * $px; + $pl = $rx2 * $ry2 - $rx2 * $py2 - $ry2 * $px2; + $root = 0; + + if ($pl < 0) { + $s = sqrt(1 - $pl / ($rx2 * $ry2)); + $rx *= $s; + $ry *= $s; + } else { + $root = ($large == $sweep ? -1.0 : 1.0) * sqrt($pl / ($rx2 * $py2 + $ry2 * $px2)); + } + + $cx = $root * $rx * $py / $ry; + $cy = -$root * $ry * $px / $rx; + $cx1 = $cosTh * $cx - $sinTh * $cy + $toX * 0.5; + $cy1 = $sinTh * $cx + $cosTh * $cy + $toY * 0.5; + $mTheta = $this->calcVectorAngle(1, 0, ($px - $cx) / $rx, ($py - $cy) / $ry); + $dtheta = $this->calcVectorAngle(($px - $cx) / $rx, ($py - $cy) / $ry, (-$px - $cx) / $rx, (-$py - $cy) / $ry); + + if ($sweep == 0 && $dtheta > 0) { + $dtheta -= 2 * M_PI; + } else { + if ($sweep == 1 && $dtheta < 0) { + $dtheta += 2 * M_PI; + } + } + + // $Convert $into $cubic $bezier $segments <= 90deg + $segments = ceil(abs($dtheta / M_PI * 2)); + $result = array(); + $mDelta = $dtheta / $segments; + $mT = 8 / 3 * sin($mDelta / 4) * sin($mDelta / 4) / sin($mDelta / 2); + $th3 = $mTheta + $mDelta; + + for ($i = 0; $i < $segments; $i++) { + $result[$i] = $this->segmentToBezier( + $mTheta, + $th3, + $cosTh, + $sinTh, + $rx, + $ry, + $cx1, + $cy1, + $mT, + $fromX, + $fromY + ); + $fromX = $result[$i][4]; + $fromY = $result[$i][5]; + $mTheta = $th3; + $th3 += $mDelta; + } + + return $result; + } + + function segmentToBezier($th2, $th3, $cosTh, $sinTh, $rx, $ry, $cx1, $cy1, $mT, $fromX, $fromY) + { + $costh2 = cos($th2); + $sinth2 = sin($th2); + $costh3 = cos($th3); + $sinth3 = sin($th3); + $toX = $cosTh * $rx * $costh3 - $sinTh * $ry * $sinth3 + $cx1; + $toY = $sinTh * $rx * $costh3 + $cosTh * $ry * $sinth3 + $cy1; + $cp1X = $fromX + $mT * (-$cosTh * $rx * $sinth2 - $sinTh * $ry * $costh2); + $cp1Y = $fromY + $mT * (-$sinTh * $rx * $sinth2 + $cosTh * $ry * $costh2); + $cp2X = $toX + $mT * ($cosTh * $rx * $sinth3 + $sinTh * $ry * $costh3); + $cp2Y = $toY + $mT * ($sinTh * $rx * $sinth3 - $cosTh * $ry * $costh3); + + return array( + $cp1X, + $cp1Y, + $cp2X, + $cp2Y, + $toX, + $toY + ); + } + + function calcVectorAngle($ux, $uy, $vx, $vy) + { + $ta = atan2($uy, $ux); + $tb = atan2($vy, $vx); + if ($tb >= $ta) { + return $tb - $ta; + } else { + return 2 * M_PI - ($ta - $tb); + } + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php new file mode 100644 index 0000000..3100c5e --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polygon.php @@ -0,0 +1,33 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Polygon extends Shape +{ + public function start($attributes) + { + $tmp = array(); + preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp); + + $points = $tmp[0]; + $count = count($points); + + $surface = $this->document->getSurface(); + list($x, $y) = $points; + $surface->moveTo($x, $y); + + for ($i = 2; $i < $count; $i += 2) { + $x = $points[$i]; + $y = $points[$i + 1]; + $surface->lineTo($x, $y); + } + + $surface->closePath(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php new file mode 100644 index 0000000..c2837f5 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Polyline.php @@ -0,0 +1,31 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Polyline extends Shape +{ + public function start($attributes) + { + $tmp = array(); + preg_match_all('/([\-]*[0-9\.]+)/', $attributes['points'], $tmp); + + $points = $tmp[0]; + $count = count($points); + + $surface = $this->document->getSurface(); + list($x, $y) = $points; + $surface->moveTo($x, $y); + + for ($i = 2; $i < $count; $i += 2) { + $x = $points[$i]; + $y = $points[$i + 1]; + $surface->lineTo($x, $y); + } + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php new file mode 100644 index 0000000..93987b3 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/RadialGradient.php @@ -0,0 +1,17 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class RadialGradient extends AbstractTag +{ + public function start($attributes) + { + + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php new file mode 100644 index 0000000..1e925a8 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Rect.php @@ -0,0 +1,55 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Rect extends Shape +{ + protected $x = 0; + protected $y = 0; + protected $width = 0; + protected $height = 0; + protected $rx = 0; + protected $ry = 0; + + public function start($attributes) + { + if (isset($attributes['x'])) { + $this->x = $attributes['x']; + } + if (isset($attributes['y'])) { + $this->y = $attributes['y']; + } + + if (isset($attributes['width'])) { + if ('%' === substr($attributes['width'], -1)) { + $factor = substr($attributes['width'], 0, -1) / 100; + $this->width = $this->document->getWidth() * $factor; + } else { + $this->width = $attributes['width']; + } + } + if (isset($attributes['height'])) { + if ('%' === substr($attributes['height'], -1)) { + $factor = substr($attributes['height'], 0, -1) / 100; + $this->height = $this->document->getHeight() * $factor; + } else { + $this->height = $attributes['height']; + } + } + + if (isset($attributes['rx'])) { + $this->rx = $attributes['rx']; + } + if (isset($attributes['ry'])) { + $this->ry = $attributes['ry']; + } + + $this->document->getSurface()->rect($this->x, $this->y, $this->width, $this->height, $this->rx, $this->ry); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php new file mode 100644 index 0000000..0a2bfae --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Shape.php @@ -0,0 +1,63 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Svg\Style; + +class Shape extends AbstractTag +{ + protected function before($attributes) + { + $surface = $this->document->getSurface(); + + $surface->save(); + + $style = $this->makeStyle($attributes); + + $this->setStyle($style); + $surface->setStyle($style); + + $this->applyTransform($attributes); + } + + protected function after() + { + $surface = $this->document->getSurface(); + + if ($this->hasShape) { + $style = $surface->getStyle(); + + $fill = $style->fill && is_array($style->fill); + $stroke = $style->stroke && is_array($style->stroke); + + if ($fill) { + if ($stroke) { + $surface->fillStroke(); + } else { +// if (is_string($style->fill)) { +// /** @var LinearGradient|RadialGradient $gradient */ +// $gradient = $this->getDocument()->getDef($style->fill); +// +// var_dump($gradient->getStops()); +// } + + $surface->fill(); + } + } + elseif ($stroke) { + $surface->stroke(); + } + else { + $surface->endPath(); + } + } + + $surface->restore(); + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php new file mode 100644 index 0000000..666a2ac --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Stop.php @@ -0,0 +1,17 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Stop extends AbstractTag +{ + public function start($attributes) + { + + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php new file mode 100644 index 0000000..cda5493 --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/StyleTag.php @@ -0,0 +1,27 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +use Sabberworm\CSS; + +class StyleTag extends AbstractTag +{ + protected $text = ""; + + public function end() + { + $parser = new CSS\Parser($this->text); + $this->document->appendStyleSheet($parser->parse()); + } + + public function appendText($text) + { + $this->text .= $text; + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php new file mode 100644 index 0000000..83b5afe --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/Text.php @@ -0,0 +1,70 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class Text extends Shape +{ + protected $x = 0; + protected $y = 0; + protected $text = ""; + + public function start($attributes) + { + $document = $this->document; + $height = $this->document->getHeight(); + $this->y = $height; + + if (isset($attributes['x'])) { + $this->x = $attributes['x']; + } + if (isset($attributes['y'])) { + $this->y = $height - $attributes['y']; + } + + $document->getSurface()->transform(1, 0, 0, -1, 0, $height); + } + + public function end() + { + $surface = $this->document->getSurface(); + $x = $this->x; + $y = $this->y; + $style = $surface->getStyle(); + $surface->setFont($style->fontFamily, $style->fontStyle, $style->fontWeight); + + switch ($style->textAnchor) { + case "middle": + $width = $surface->measureText($this->text); + $x -= $width / 2; + break; + + case "end": + $width = $surface->measureText($this->text); + $x -= $width; + break; + } + + $surface->fillText($this->getText(), $x, $y); + } + + protected function after() + { + $this->document->getSurface()->restore(); + } + + public function appendText($text) + { + $this->text .= $text; + } + + public function getText() + { + return trim($this->text); + } +} diff --git a/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php b/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php new file mode 100644 index 0000000..b88a6cc --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/Svg/Tag/UseTag.php @@ -0,0 +1,96 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +namespace Svg\Tag; + +class UseTag extends AbstractTag +{ + protected $x = 0; + protected $y = 0; + protected $width; + protected $height; + + /** @var AbstractTag */ + protected $reference; + + protected function before($attributes) + { + if (isset($attributes['x'])) { + $this->x = $attributes['x']; + } + if (isset($attributes['y'])) { + $this->y = $attributes['y']; + } + + if (isset($attributes['width'])) { + $this->width = $attributes['width']; + } + if (isset($attributes['height'])) { + $this->height = $attributes['height']; + } + + parent::before($attributes); + + $document = $this->getDocument(); + + $link = $attributes["xlink:href"]; + $this->reference = $document->getDef($link); + + if ($this->reference) { + $this->reference->before($attributes); + } + + $surface = $document->getSurface(); + $surface->save(); + + $surface->translate($this->x, $this->y); + } + + protected function after() { + parent::after(); + + if ($this->reference) { + $this->reference->after(); + } + + $this->getDocument()->getSurface()->restore(); + } + + public function handle($attributes) + { + parent::handle($attributes); + + if (!$this->reference) { + return; + } + + $attributes = array_merge($this->reference->attributes, $attributes); + + $this->reference->handle($attributes); + + foreach ($this->reference->children as $_child) { + $_attributes = array_merge($_child->attributes, $attributes); + $_child->handle($_attributes); + } + } + + public function handleEnd() + { + parent::handleEnd(); + + if (!$this->reference) { + return; + } + + $this->reference->handleEnd(); + + foreach ($this->reference->children as $_child) { + $_child->handleEnd(); + } + } +} \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/src/autoload.php b/vendor/phenx/php-svg-lib/src/autoload.php new file mode 100644 index 0000000..b0e2b9c --- /dev/null +++ b/vendor/phenx/php-svg-lib/src/autoload.php @@ -0,0 +1,17 @@ + + * @license GNU LGPLv3+ http://www.gnu.org/copyleft/lesser.html + */ + +spl_autoload_register(function($class) { + if (0 === strpos($class, "Svg")) { + $file = str_replace('\\', DIRECTORY_SEPARATOR, $class); + $file = realpath(__DIR__ . DIRECTORY_SEPARATOR . $file . '.php'); + if (file_exists($file)) { + include_once $file; + } + } +}); \ No newline at end of file diff --git a/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php b/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php new file mode 100644 index 0000000..f434a07 --- /dev/null +++ b/vendor/phenx/php-svg-lib/tests/Svg/StyleTest.php @@ -0,0 +1,59 @@ +assertEquals("none", Style::parseColor("none")); + $this->assertEquals(array(255, 0, 0), Style::parseColor("RED")); + $this->assertEquals(array(0, 0, 255), Style::parseColor("blue")); + $this->assertEquals(null, Style::parseColor("foo")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("black")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("white")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("#000000")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("#ffffff")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("rgb(0,0,0)")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("rgb(255,255,255)")); + $this->assertEquals(array(0, 0, 0), Style::parseColor("rgb(0, 0, 0)")); + $this->assertEquals(array(255, 255, 255), Style::parseColor("rgb(255, 255, 255)")); + } + + public function test_fromAttributes() + { + $style = new Style(); + + $attributes = array( + "color" => "blue", + "fill" => "#fff", + "stroke" => "none", + ); + + $style->fromAttributes($attributes); + + $this->assertEquals(array(0, 0, 255), $style->color); + $this->assertEquals(array(255, 255, 255), $style->fill); + $this->assertEquals("none", $style->stroke); + } + + public function test_convertSize() + { + $this->assertEquals(1, Style::convertSize(1)); + $this->assertEquals(10, Style::convertSize("10px")); // FIXME + $this->assertEquals(10, Style::convertSize("10pt")); + $this->assertEquals(8, Style::convertSize("80%", 10, 72)); + } + +} + diff --git a/vendor/phpdocumentor/reflection-common/.github/dependabot.yml b/vendor/phpdocumentor/reflection-common/.github/dependabot.yml new file mode 100644 index 0000000..c630ffa --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: composer + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 diff --git a/vendor/phpdocumentor/reflection-common/.github/workflows/push.yml b/vendor/phpdocumentor/reflection-common/.github/workflows/push.yml new file mode 100644 index 0000000..484410e --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/.github/workflows/push.yml @@ -0,0 +1,223 @@ +on: + push: + branches: + - 2.x + pull_request: +name: Qa workflow +jobs: + setup: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - name: Restore/cache vendor folder + uses: actions/cache@v1 + with: + path: vendor + key: all-build-${{ hashFiles('**/composer.lock') }} + restore-keys: | + all-build-${{ hashFiles('**/composer.lock') }} + all-build- + + - name: Restore/cache tools folder + uses: actions/cache@v1 + with: + path: tools + key: all-tools-${{ github.sha }} + restore-keys: | + all-tools-${{ github.sha }}- + all-tools- + + - name: composer + uses: docker://composer + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: install --no-interaction --prefer-dist --optimize-autoloader + + - name: Install phive + run: make install-phive + + - name: Install PHAR dependencies + run: tools/phive.phar --no-progress install --copy --trust-gpg-keys 4AA394086372C20A,8A03EA3B385DBAA1 --force-accept-unsigned + + phpunit-with-coverage: + runs-on: ubuntu-latest + name: Unit tests + needs: setup + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 + coverage: pcov + + - name: Restore/cache tools folder + uses: actions/cache@v1 + with: + path: tools + key: all-tools-${{ github.sha }} + restore-keys: | + all-tools-${{ github.sha }}- + all-tools- + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ubuntu-latest-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ubuntu-latest-composer- + + - name: Install Composer dependencies + run: | + composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Run PHPUnit + run: php tools/phpunit + + phpunit: + runs-on: ${{ matrix.operating-system }} + strategy: + matrix: + operating-system: + - ubuntu-latest + - windows-latest + - macOS-latest + php-versions: ['7.2', '7.3', '7.4', '8.0'] + name: Unit tests for PHP version ${{ matrix.php-versions }} on ${{ matrix.operating-system }} + needs: + - setup + - phpunit-with-coverage + steps: + - uses: actions/checkout@v2 + + - name: Restore/cache tools folder + uses: actions/cache@v1 + with: + path: tools + key: all-tools-${{ github.sha }} + restore-keys: | + all-tools-${{ github.sha }}- + all-tools- + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-versions }} + ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Composer dependencies + run: | + composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Run PHPUnit + continue-on-error: true + run: php tools/phpunit + + codestyle: + runs-on: ubuntu-latest + needs: [setup, phpunit] + steps: + - uses: actions/checkout@v2 + - name: Restore/cache vendor folder + uses: actions/cache@v1 + with: + path: vendor + key: all-build-${{ hashFiles('**/composer.lock') }} + restore-keys: | + all-build-${{ hashFiles('**/composer.lock') }} + all-build- + - name: Code style check + uses: phpDocumentor/coding-standard@latest + with: + args: -s + + phpstan: + runs-on: ubuntu-latest + needs: [setup, phpunit] + steps: + - uses: actions/checkout@v2 + - name: Restore/cache vendor folder + uses: actions/cache@v1 + with: + path: vendor + key: all-build-${{ hashFiles('**/composer.lock') }} + restore-keys: | + all-build-${{ hashFiles('**/composer.lock') }} + all-build- + - name: PHPStan + uses: phpDocumentor/phpstan-ga@latest + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + args: analyse src --configuration phpstan.neon + + psalm: + runs-on: ubuntu-latest + needs: [setup, phpunit] + steps: + - uses: actions/checkout@v2 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + ini-values: memory_limit=2G, display_errors=On, error_reporting=-1 + tools: psalm + coverage: none + + - name: Get composer cache directory + id: composer-cache + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache composer dependencies + uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: Install Composer dependencies + run: | + composer install --no-progress --no-suggest --prefer-dist --optimize-autoloader + + - name: Psalm + run: psalm --output-format=github + + bc_check: + name: BC Check + runs-on: ubuntu-latest + needs: [setup, phpunit] + steps: + - uses: actions/checkout@v2 + - name: fetch tags + run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* + - name: Restore/cache vendor folder + uses: actions/cache@v1 + with: + path: vendor + key: all-build-${{ hashFiles('**/composer.lock') }} + restore-keys: | + all-build-${{ hashFiles('**/composer.lock') }} + all-build- + - name: Roave BC Check + uses: docker://nyholm/roave-bc-check-ga diff --git a/vendor/phpdocumentor/reflection-common/LICENSE b/vendor/phpdocumentor/reflection-common/LICENSE new file mode 100644 index 0000000..ed6926c --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 phpDocumentor + +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/phpdocumentor/reflection-common/README.md b/vendor/phpdocumentor/reflection-common/README.md new file mode 100644 index 0000000..70f830d --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/README.md @@ -0,0 +1,11 @@ +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +![Qa workflow](https://github.com/phpDocumentor/ReflectionCommon/workflows/Qa%20workflow/badge.svg) +[![Coveralls Coverage](https://img.shields.io/coveralls/github/phpDocumentor/ReflectionCommon.svg)](https://coveralls.io/github/phpDocumentor/ReflectionCommon?branch=master) +[![Scrutinizer Code Coverage](https://img.shields.io/scrutinizer/coverage/g/phpDocumentor/ReflectionCommon.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionCommon/?branch=master) +[![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/phpDocumentor/ReflectionCommon.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionCommon/?branch=master) +[![Stable Version](https://img.shields.io/packagist/v/phpDocumentor/Reflection-Common.svg)](https://packagist.org/packages/phpDocumentor/Reflection-Common) +[![Unstable Version](https://img.shields.io/packagist/vpre/phpDocumentor/Reflection-Common.svg)](https://packagist.org/packages/phpDocumentor/Reflection-Common) + + +ReflectionCommon +================ diff --git a/vendor/phpdocumentor/reflection-common/composer.json b/vendor/phpdocumentor/reflection-common/composer.json new file mode 100644 index 0000000..4d128b4 --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/composer.json @@ -0,0 +1,28 @@ +{ + "name": "phpdocumentor/reflection-common", + "keywords": ["phpdoc", "phpDocumentor", "reflection", "static analysis", "FQSEN"], + "homepage": "http://www.phpdoc.org", + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "license": "MIT", + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "require": { + "php": "^7.2 || ^8.0" + }, + "autoload" : { + "psr-4" : { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "require-dev": { + }, + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + } +} diff --git a/vendor/phpdocumentor/reflection-common/src/Element.php b/vendor/phpdocumentor/reflection-common/src/Element.php new file mode 100644 index 0000000..8923e4f --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/src/Element.php @@ -0,0 +1,30 @@ +fqsen = $fqsen; + + if (isset($matches[2])) { + $this->name = $matches[2]; + } else { + $matches = explode('\\', $fqsen); + $name = end($matches); + assert(is_string($name)); + $this->name = trim($name, '()'); + } + } + + /** + * converts this class to string. + */ + public function __toString() : string + { + return $this->fqsen; + } + + /** + * Returns the name of the element without path. + */ + public function getName() : string + { + return $this->name; + } +} diff --git a/vendor/phpdocumentor/reflection-common/src/Location.php b/vendor/phpdocumentor/reflection-common/src/Location.php new file mode 100644 index 0000000..177deed --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/src/Location.php @@ -0,0 +1,53 @@ +lineNumber = $lineNumber; + $this->columnNumber = $columnNumber; + } + + /** + * Returns the line number that is covered by this location. + */ + public function getLineNumber() : int + { + return $this->lineNumber; + } + + /** + * Returns the column number (character position on a line) for this location object. + */ + public function getColumnNumber() : int + { + return $this->columnNumber; + } +} diff --git a/vendor/phpdocumentor/reflection-common/src/Project.php b/vendor/phpdocumentor/reflection-common/src/Project.php new file mode 100644 index 0000000..57839fd --- /dev/null +++ b/vendor/phpdocumentor/reflection-common/src/Project.php @@ -0,0 +1,25 @@ +create($docComment); +``` + +The `create` method will yield an object of type `\phpDocumentor\Reflection\DocBlock` +whose methods can be queried: + +```php +// Contains the summary for this DocBlock +$summary = $docblock->getSummary(); + +// Contains \phpDocumentor\Reflection\DocBlock\Description object +$description = $docblock->getDescription(); + +// You can either cast it to string +$description = (string) $docblock->getDescription(); + +// Or use the render method to get a string representation of the Description. +$description = $docblock->getDescription()->render(); +``` + +> For more examples it would be best to review the scripts in the [`/examples` folder](/examples). diff --git a/vendor/phpdocumentor/reflection-docblock/composer.json b/vendor/phpdocumentor/reflection-docblock/composer.json new file mode 100644 index 0000000..7038f48 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/composer.json @@ -0,0 +1,41 @@ +{ + "name": "phpdocumentor/reflection-docblock", + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1", + "phpdocumentor/reflection-common": "^2.2", + "ext-filter": "*" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "phpDocumentor\\Reflection\\": "tests/unit" + } + }, + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php new file mode 100644 index 0000000..f3403d6 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php @@ -0,0 +1,204 @@ +summary = $summary; + $this->description = $description ?: new DocBlock\Description(''); + foreach ($tags as $tag) { + $this->addTag($tag); + } + + $this->context = $context; + $this->location = $location; + + $this->isTemplateEnd = $isTemplateEnd; + $this->isTemplateStart = $isTemplateStart; + } + + public function getSummary() : string + { + return $this->summary; + } + + public function getDescription() : DocBlock\Description + { + return $this->description; + } + + /** + * Returns the current context. + */ + public function getContext() : ?Types\Context + { + return $this->context; + } + + /** + * Returns the current location. + */ + public function getLocation() : ?Location + { + return $this->location; + } + + /** + * Returns whether this DocBlock is the start of a Template section. + * + * A Docblock may serve as template for a series of subsequent DocBlocks. This is indicated by a special marker + * (`#@+`) that is appended directly after the opening `/**` of a DocBlock. + * + * An example of such an opening is: + * + * ``` + * /**#@+ + * * My DocBlock + * * / + * ``` + * + * The description and tags (not the summary!) are copied onto all subsequent DocBlocks and also applied to all + * elements that follow until another DocBlock is found that contains the closing marker (`#@-`). + * + * @see self::isTemplateEnd() for the check whether a closing marker was provided. + */ + public function isTemplateStart() : bool + { + return $this->isTemplateStart; + } + + /** + * Returns whether this DocBlock is the end of a Template section. + * + * @see self::isTemplateStart() for a more complete description of the Docblock Template functionality. + */ + public function isTemplateEnd() : bool + { + return $this->isTemplateEnd; + } + + /** + * Returns the tags for this DocBlock. + * + * @return Tag[] + */ + public function getTags() : array + { + return $this->tags; + } + + /** + * Returns an array of tags matching the given name. If no tags are found + * an empty array is returned. + * + * @param string $name String to search by. + * + * @return Tag[] + */ + public function getTagsByName(string $name) : array + { + $result = []; + + foreach ($this->getTags() as $tag) { + if ($tag->getName() !== $name) { + continue; + } + + $result[] = $tag; + } + + return $result; + } + + /** + * Checks if a tag of a certain type is present in this DocBlock. + * + * @param string $name Tag name to check for. + */ + public function hasTag(string $name) : bool + { + foreach ($this->getTags() as $tag) { + if ($tag->getName() === $name) { + return true; + } + } + + return false; + } + + /** + * Remove a tag from this DocBlock. + * + * @param Tag $tagToRemove The tag to remove. + */ + public function removeTag(Tag $tagToRemove) : void + { + foreach ($this->tags as $key => $tag) { + if ($tag === $tagToRemove) { + unset($this->tags[$key]); + break; + } + } + } + + /** + * Adds a tag to this DocBlock. + * + * @param Tag $tag The tag to add. + */ + private function addTag(Tag $tag) : void + { + $this->tags[] = $tag; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php new file mode 100644 index 0000000..7b11b80 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php @@ -0,0 +1,114 @@ +create('This is a {@see Description}', $context); + * + * The description factory will interpret the given body and create a body template and list of tags from them, and pass + * that onto the constructor if this class. + * + * > The $context variable is a class of type {@see \phpDocumentor\Reflection\Types\Context} and contains the namespace + * > and the namespace aliases that apply to this DocBlock. These are used by the Factory to resolve and expand partial + * > type names and FQSENs. + * + * If you do not want to use the DescriptionFactory you can pass a body template and tag listing like this: + * + * $description = new Description( + * 'This is a %1$s', + * [ new See(new Fqsen('\phpDocumentor\Reflection\DocBlock\Description')) ] + * ); + * + * It is generally recommended to use the Factory as that will also apply escaping rules, while the Description object + * is mainly responsible for rendering. + * + * @see DescriptionFactory to create a new Description. + * @see Description\Formatter for the formatting of the body and tags. + */ +class Description +{ + /** @var string */ + private $bodyTemplate; + + /** @var Tag[] */ + private $tags; + + /** + * Initializes a Description with its body (template) and a listing of the tags used in the body template. + * + * @param Tag[] $tags + */ + public function __construct(string $bodyTemplate, array $tags = []) + { + $this->bodyTemplate = $bodyTemplate; + $this->tags = $tags; + } + + /** + * Returns the body template. + */ + public function getBodyTemplate() : string + { + return $this->bodyTemplate; + } + + /** + * Returns the tags for this DocBlock. + * + * @return Tag[] + */ + public function getTags() : array + { + return $this->tags; + } + + /** + * Renders this description as a string where the provided formatter will format the tags in the expected string + * format. + */ + public function render(?Formatter $formatter = null) : string + { + if ($formatter === null) { + $formatter = new PassthroughFormatter(); + } + + $tags = []; + foreach ($this->tags as $tag) { + $tags[] = '{' . $formatter->format($tag) . '}'; + } + + return vsprintf($this->bodyTemplate, $tags); + } + + /** + * Returns a plain string representation of this description. + */ + public function __toString() : string + { + return $this->render(); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php new file mode 100644 index 0000000..c27d2a0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php @@ -0,0 +1,177 @@ +tagFactory = $tagFactory; + } + + /** + * Returns the parsed text of this description. + */ + public function create(string $contents, ?TypeContext $context = null) : Description + { + $tokens = $this->lex($contents); + $count = count($tokens); + $tagCount = 0; + $tags = []; + + for ($i = 1; $i < $count; $i += 2) { + $tags[] = $this->tagFactory->create($tokens[$i], $context); + $tokens[$i] = '%' . ++$tagCount . '$s'; + } + + //In order to allow "literal" inline tags, the otherwise invalid + //sequence "{@}" is changed to "@", and "{}" is changed to "}". + //"%" is escaped to "%%" because of vsprintf. + //See unit tests for examples. + for ($i = 0; $i < $count; $i += 2) { + $tokens[$i] = str_replace(['{@}', '{}', '%'], ['@', '}', '%%'], $tokens[$i]); + } + + return new Description(implode('', $tokens), $tags); + } + + /** + * Strips the contents from superfluous whitespace and splits the description into a series of tokens. + * + * @return string[] A series of tokens of which the description text is composed. + */ + private function lex(string $contents) : array + { + $contents = $this->removeSuperfluousStartingWhitespace($contents); + + // performance optimalization; if there is no inline tag, don't bother splitting it up. + if (strpos($contents, '{@') === false) { + return [$contents]; + } + + return Utils::pregSplit( + '/\{ + # "{@}" is not a valid inline tag. This ensures that we do not treat it as one, but treat it literally. + (?!@\}) + # We want to capture the whole tag line, but without the inline tag delimiters. + (\@ + # Match everything up to the next delimiter. + [^{}]* + # Nested inline tag content should not be captured, or it will appear in the result separately. + (?: + # Match nested inline tags. + (?: + # Because we did not catch the tag delimiters earlier, we must be explicit with them here. + # Notice that this also matches "{}", as a way to later introduce it as an escape sequence. + \{(?1)?\} + | + # Make sure we match hanging "{". + \{ + ) + # Match content after the nested inline tag. + [^{}]* + )* # If there are more inline tags, match them as well. We use "*" since there may not be any + # nested inline tags. + ) + \}/Sux', + $contents, + 0, + PREG_SPLIT_DELIM_CAPTURE + ); + } + + /** + * Removes the superfluous from a multi-line description. + * + * When a description has more than one line then it can happen that the second and subsequent lines have an + * additional indentation. This is commonly in use with tags like this: + * + * {@}since 1.1.0 This is an example + * description where we have an + * indentation in the second and + * subsequent lines. + * + * If we do not normalize the indentation then we have superfluous whitespace on the second and subsequent + * lines and this may cause rendering issues when, for example, using a Markdown converter. + */ + private function removeSuperfluousStartingWhitespace(string $contents) : string + { + $lines = explode("\n", $contents); + + // if there is only one line then we don't have lines with superfluous whitespace and + // can use the contents as-is + if (count($lines) <= 1) { + return $contents; + } + + // determine how many whitespace characters need to be stripped + $startingSpaceCount = 9999999; + for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) { + // lines with a no length do not count as they are not indented at all + if (trim($lines[$i]) === '') { + continue; + } + + // determine the number of prefixing spaces by checking the difference in line length before and after + // an ltrim + $startingSpaceCount = min($startingSpaceCount, strlen($lines[$i]) - strlen(ltrim($lines[$i]))); + } + + // strip the number of spaces from each line + if ($startingSpaceCount > 0) { + for ($i = 1, $iMax = count($lines); $i < $iMax; ++$i) { + $lines[$i] = substr($lines[$i], $startingSpaceCount); + } + } + + return implode("\n", $lines); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php new file mode 100644 index 0000000..7249efb --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php @@ -0,0 +1,157 @@ +getFilePath(); + + $file = $this->getExampleFileContents($filename); + if (!$file) { + return sprintf('** File not found : %s **', $filename); + } + + return implode('', array_slice($file, $example->getStartingLine() - 1, $example->getLineCount())); + } + + /** + * Registers the project's root directory where an 'examples' folder can be expected. + */ + public function setSourceDirectory(string $directory = '') : void + { + $this->sourceDirectory = $directory; + } + + /** + * Returns the project's root directory where an 'examples' folder can be expected. + */ + public function getSourceDirectory() : string + { + return $this->sourceDirectory; + } + + /** + * Registers a series of directories that may contain examples. + * + * @param string[] $directories + */ + public function setExampleDirectories(array $directories) : void + { + $this->exampleDirectories = $directories; + } + + /** + * Returns a series of directories that may contain examples. + * + * @return string[] + */ + public function getExampleDirectories() : array + { + return $this->exampleDirectories; + } + + /** + * Attempts to find the requested example file and returns its contents or null if no file was found. + * + * This method will try several methods in search of the given example file, the first one it encounters is + * returned: + * + * 1. Iterates through all examples folders for the given filename + * 2. Checks the source folder for the given filename + * 3. Checks the 'examples' folder in the current working directory for examples + * 4. Checks the path relative to the current working directory for the given filename + * + * @return string[] all lines of the example file + */ + private function getExampleFileContents(string $filename) : ?array + { + $normalizedPath = null; + + foreach ($this->exampleDirectories as $directory) { + $exampleFileFromConfig = $this->constructExamplePath($directory, $filename); + if (is_readable($exampleFileFromConfig)) { + $normalizedPath = $exampleFileFromConfig; + break; + } + } + + if (!$normalizedPath) { + if (is_readable($this->getExamplePathFromSource($filename))) { + $normalizedPath = $this->getExamplePathFromSource($filename); + } elseif (is_readable($this->getExamplePathFromExampleDirectory($filename))) { + $normalizedPath = $this->getExamplePathFromExampleDirectory($filename); + } elseif (is_readable($filename)) { + $normalizedPath = $filename; + } + } + + $lines = $normalizedPath && is_readable($normalizedPath) ? file($normalizedPath) : false; + + return $lines !== false ? $lines : null; + } + + /** + * Get example filepath based on the example directory inside your project. + */ + private function getExamplePathFromExampleDirectory(string $file) : string + { + return getcwd() . DIRECTORY_SEPARATOR . 'examples' . DIRECTORY_SEPARATOR . $file; + } + + /** + * Returns a path to the example file in the given directory.. + */ + private function constructExamplePath(string $directory, string $file) : string + { + return rtrim($directory, '\\/') . DIRECTORY_SEPARATOR . $file; + } + + /** + * Get example filepath based on sourcecode. + */ + private function getExamplePathFromSource(string $file) : string + { + return sprintf( + '%s%s%s', + trim($this->getSourceDirectory(), '\\/'), + DIRECTORY_SEPARATOR, + trim($file, '"') + ); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php new file mode 100644 index 0000000..531970b --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php @@ -0,0 +1,151 @@ +indent = $indent; + $this->indentString = $indentString; + $this->isFirstLineIndented = $indentFirstLine; + $this->lineLength = $lineLength; + $this->tagFormatter = $tagFormatter ?: new PassthroughFormatter(); + } + + /** + * Generate a DocBlock comment. + * + * @param DocBlock $docblock The DocBlock to serialize. + * + * @return string The serialized doc block. + */ + public function getDocComment(DocBlock $docblock) : string + { + $indent = str_repeat($this->indentString, $this->indent); + $firstIndent = $this->isFirstLineIndented ? $indent : ''; + // 3 === strlen(' * ') + $wrapLength = $this->lineLength ? $this->lineLength - strlen($indent) - 3 : null; + + $text = $this->removeTrailingSpaces( + $indent, + $this->addAsterisksForEachLine( + $indent, + $this->getSummaryAndDescriptionTextBlock($docblock, $wrapLength) + ) + ); + + $comment = $firstIndent . "/**\n"; + if ($text) { + $comment .= $indent . ' * ' . $text . "\n"; + $comment .= $indent . " *\n"; + } + + $comment = $this->addTagBlock($docblock, $wrapLength, $indent, $comment); + + return $comment . $indent . ' */'; + } + + private function removeTrailingSpaces(string $indent, string $text) : string + { + return str_replace( + sprintf("\n%s * \n", $indent), + sprintf("\n%s *\n", $indent), + $text + ); + } + + private function addAsterisksForEachLine(string $indent, string $text) : string + { + return str_replace( + "\n", + sprintf("\n%s * ", $indent), + $text + ); + } + + private function getSummaryAndDescriptionTextBlock(DocBlock $docblock, ?int $wrapLength) : string + { + $text = $docblock->getSummary() . ((string) $docblock->getDescription() ? "\n\n" . $docblock->getDescription() + : ''); + if ($wrapLength !== null) { + $text = wordwrap($text, $wrapLength); + + return $text; + } + + return $text; + } + + private function addTagBlock(DocBlock $docblock, ?int $wrapLength, string $indent, string $comment) : string + { + foreach ($docblock->getTags() as $tag) { + $tagText = $this->tagFormatter->format($tag); + if ($wrapLength !== null) { + $tagText = wordwrap($tagText, $wrapLength); + } + + $tagText = str_replace( + "\n", + sprintf("\n%s * ", $indent), + $tagText + ); + + $comment .= sprintf("%s * %s\n", $indent, $tagText); + } + + return $comment; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php new file mode 100644 index 0000000..e64b587 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php @@ -0,0 +1,347 @@ + Important: each parameter in addition to the body variable for the `create` method must default to null, otherwise + * > it violates the constraint with the interface; it is recommended to use the {@see Assert::notNull()} method to + * > verify that a dependency is actually passed. + * + * This Factory also features a Service Locator component that is used to pass the right dependencies to the + * `create` method of a tag; each dependency should be registered as a service or as a parameter. + * + * When you want to use a Tag of your own with custom handling you need to call the `registerTagHandler` method, pass + * the name of the tag and a Fully Qualified Class Name pointing to a class that implements the Tag interface. + */ +final class StandardTagFactory implements TagFactory +{ + /** PCRE regular expression matching a tag name. */ + public const REGEX_TAGNAME = '[\w\-\_\\\\:]+'; + + /** + * @var array> An array with a tag as a key, and an + * FQCN to a class that handles it as an array value. + */ + private $tagHandlerMappings = [ + 'author' => Author::class, + 'covers' => Covers::class, + 'deprecated' => Deprecated::class, + // 'example' => '\phpDocumentor\Reflection\DocBlock\Tags\Example', + 'link' => LinkTag::class, + 'method' => Method::class, + 'param' => Param::class, + 'property-read' => PropertyRead::class, + 'property' => Property::class, + 'property-write' => PropertyWrite::class, + 'return' => Return_::class, + 'see' => SeeTag::class, + 'since' => Since::class, + 'source' => Source::class, + 'throw' => Throws::class, + 'throws' => Throws::class, + 'uses' => Uses::class, + 'var' => Var_::class, + 'version' => Version::class, + ]; + + /** + * @var array> An array with a anotation s a key, and an + * FQCN to a class that handles it as an array value. + */ + private $annotationMappings = []; + + /** + * @var ReflectionParameter[][] a lazy-loading cache containing parameters + * for each tagHandler that has been used. + */ + private $tagHandlerParameterCache = []; + + /** @var FqsenResolver */ + private $fqsenResolver; + + /** + * @var mixed[] an array representing a simple Service Locator where we can store parameters and + * services that can be inserted into the Factory Methods of Tag Handlers. + */ + private $serviceLocator = []; + + /** + * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers. + * + * If no tag handlers are provided than the default list in the {@see self::$tagHandlerMappings} property + * is used. + * + * @see self::registerTagHandler() to add a new tag handler to the existing default list. + * + * @param array> $tagHandlers + */ + public function __construct(FqsenResolver $fqsenResolver, ?array $tagHandlers = null) + { + $this->fqsenResolver = $fqsenResolver; + if ($tagHandlers !== null) { + $this->tagHandlerMappings = $tagHandlers; + } + + $this->addService($fqsenResolver, FqsenResolver::class); + } + + public function create(string $tagLine, ?TypeContext $context = null) : Tag + { + if (!$context) { + $context = new TypeContext(''); + } + + [$tagName, $tagBody] = $this->extractTagParts($tagLine); + + return $this->createTag(trim($tagBody), $tagName, $context); + } + + /** + * @param mixed $value + */ + public function addParameter(string $name, $value) : void + { + $this->serviceLocator[$name] = $value; + } + + public function addService(object $service, ?string $alias = null) : void + { + $this->serviceLocator[$alias ?: get_class($service)] = $service; + } + + public function registerTagHandler(string $tagName, string $handler) : void + { + Assert::stringNotEmpty($tagName); + Assert::classExists($handler); + Assert::implementsInterface($handler, Tag::class); + + if (strpos($tagName, '\\') && $tagName[0] !== '\\') { + throw new InvalidArgumentException( + 'A namespaced tag must have a leading backslash as it must be fully qualified' + ); + } + + $this->tagHandlerMappings[$tagName] = $handler; + } + + /** + * Extracts all components for a tag. + * + * @return string[] + */ + private function extractTagParts(string $tagLine) : array + { + $matches = []; + if (!preg_match('/^@(' . self::REGEX_TAGNAME . ')((?:[\s\(\{])\s*([^\s].*)|$)/us', $tagLine, $matches)) { + throw new InvalidArgumentException( + 'The tag "' . $tagLine . '" does not seem to be wellformed, please check it for errors' + ); + } + + if (count($matches) < 3) { + $matches[] = ''; + } + + return array_slice($matches, 1); + } + + /** + * Creates a new tag object with the given name and body or returns null if the tag name was recognized but the + * body was invalid. + */ + private function createTag(string $body, string $name, TypeContext $context) : Tag + { + $handlerClassName = $this->findHandlerClassName($name, $context); + $arguments = $this->getArgumentsForParametersFromWiring( + $this->fetchParametersForHandlerFactoryMethod($handlerClassName), + $this->getServiceLocatorWithDynamicParameters($context, $name, $body) + ); + + try { + $callable = [$handlerClassName, 'create']; + Assert::isCallable($callable); + /** @phpstan-var callable(string): ?Tag $callable */ + $tag = call_user_func_array($callable, $arguments); + + return $tag ?? InvalidTag::create($body, $name); + } catch (InvalidArgumentException $e) { + return InvalidTag::create($body, $name)->withError($e); + } + } + + /** + * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`). + * + * @return class-string + */ + private function findHandlerClassName(string $tagName, TypeContext $context) : string + { + $handlerClassName = Generic::class; + if (isset($this->tagHandlerMappings[$tagName])) { + $handlerClassName = $this->tagHandlerMappings[$tagName]; + } elseif ($this->isAnnotation($tagName)) { + // TODO: Annotation support is planned for a later stage and as such is disabled for now + $tagName = (string) $this->fqsenResolver->resolve($tagName, $context); + if (isset($this->annotationMappings[$tagName])) { + $handlerClassName = $this->annotationMappings[$tagName]; + } + } + + return $handlerClassName; + } + + /** + * Retrieves the arguments that need to be passed to the Factory Method with the given Parameters. + * + * @param ReflectionParameter[] $parameters + * @param mixed[] $locator + * + * @return mixed[] A series of values that can be passed to the Factory Method of the tag whose parameters + * is provided with this method. + */ + private function getArgumentsForParametersFromWiring(array $parameters, array $locator) : array + { + $arguments = []; + foreach ($parameters as $parameter) { + $type = $parameter->getType(); + $typeHint = null; + if ($type instanceof ReflectionNamedType) { + $typeHint = $type->getName(); + if ($typeHint === 'self') { + $declaringClass = $parameter->getDeclaringClass(); + if ($declaringClass !== null) { + $typeHint = $declaringClass->getName(); + } + } + } + + if (isset($locator[$typeHint])) { + $arguments[] = $locator[$typeHint]; + continue; + } + + $parameterName = $parameter->getName(); + if (isset($locator[$parameterName])) { + $arguments[] = $locator[$parameterName]; + continue; + } + + $arguments[] = null; + } + + return $arguments; + } + + /** + * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given + * tag handler class name. + * + * @param class-string $handlerClassName + * + * @return ReflectionParameter[] + */ + private function fetchParametersForHandlerFactoryMethod(string $handlerClassName) : array + { + if (!isset($this->tagHandlerParameterCache[$handlerClassName])) { + $methodReflection = new ReflectionMethod($handlerClassName, 'create'); + $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters(); + } + + return $this->tagHandlerParameterCache[$handlerClassName]; + } + + /** + * Returns a copy of this class' Service Locator with added dynamic parameters, + * such as the tag's name, body and Context. + * + * @param TypeContext $context The Context (namespace and aliasses) that may be + * passed and is used to resolve FQSENs. + * @param string $tagName The name of the tag that may be + * passed onto the factory method of the Tag class. + * @param string $tagBody The body of the tag that may be + * passed onto the factory method of the Tag class. + * + * @return mixed[] + */ + private function getServiceLocatorWithDynamicParameters( + TypeContext $context, + string $tagName, + string $tagBody + ) : array { + return array_merge( + $this->serviceLocator, + [ + 'name' => $tagName, + 'body' => $tagBody, + TypeContext::class => $context, + ] + ); + } + + /** + * Returns whether the given tag belongs to an annotation. + * + * @todo this method should be populated once we implement Annotation notation support. + */ + private function isAnnotation(string $tagContent) : bool + { + // 1. Contains a namespace separator + // 2. Contains parenthesis + // 3. Is present in a list of known annotations (make the algorithm smart by first checking is the last part + // of the annotation class name matches the found tag name + + return false; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php new file mode 100644 index 0000000..f55de91 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php @@ -0,0 +1,32 @@ + $handler FQCN of handler. + * + * @throws InvalidArgumentException If the tag name is not a string. + * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but + * does not start with a backslash. + * @throws InvalidArgumentException If the handler is not a string. + * @throws InvalidArgumentException If the handler is not an existing class. + * @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface. + */ + public function registerTagHandler(string $tagName, string $handler) : void; +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php new file mode 100644 index 0000000..d120757 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php @@ -0,0 +1,100 @@ +authorName = $authorName; + $this->authorEmail = $authorEmail; + } + + /** + * Gets the author's name. + * + * @return string The author's name. + */ + public function getAuthorName() : string + { + return $this->authorName; + } + + /** + * Returns the author's email. + * + * @return string The author's email. + */ + public function getEmail() : string + { + return $this->authorEmail; + } + + /** + * Returns this tag in string form. + */ + public function __toString() : string + { + if ($this->authorEmail) { + $authorEmail = '<' . $this->authorEmail . '>'; + } else { + $authorEmail = ''; + } + + $authorName = (string) $this->authorName; + + return $authorName . ($authorEmail !== '' ? ($authorName !== '' ? ' ' : '') . $authorEmail : ''); + } + + /** + * Attempts to create a new Author object based on †he tag body. + */ + public static function create(string $body) : ?self + { + $splitTagContent = preg_match('/^([^\<]*)(?:\<([^\>]*)\>)?$/u', $body, $matches); + if (!$splitTagContent) { + return null; + } + + $authorName = trim($matches[1]); + $email = isset($matches[2]) ? trim($matches[2]) : ''; + + return new static($authorName, $email); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php new file mode 100644 index 0000000..fbcd402 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php @@ -0,0 +1,53 @@ +name; + } + + public function getDescription() : ?Description + { + return $this->description; + } + + public function render(?Formatter $formatter = null) : string + { + if ($formatter === null) { + $formatter = new Formatter\PassthroughFormatter(); + } + + return $formatter->format($this); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php new file mode 100644 index 0000000..9e52e5e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php @@ -0,0 +1,100 @@ +refers = $refers; + $this->description = $description; + } + + public static function create( + string $body, + ?DescriptionFactory $descriptionFactory = null, + ?FqsenResolver $resolver = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($descriptionFactory); + Assert::notNull($resolver); + + $parts = Utils::pregSplit('/\s+/Su', $body, 2); + + return new static( + self::resolveFqsen($parts[0], $resolver, $context), + $descriptionFactory->create($parts[1] ?? '', $context) + ); + } + + private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen + { + Assert::notNull($fqsenResolver); + $fqsenParts = explode('::', $parts); + $resolved = $fqsenResolver->resolve($fqsenParts[0], $context); + + if (!array_key_exists(1, $fqsenParts)) { + return $resolved; + } + + return new Fqsen($resolved . '::' . $fqsenParts[1]); + } + + /** + * Returns the structural element this tag refers to. + */ + public function getReference() : Fqsen + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $refers = (string) $this->refers; + + return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php new file mode 100644 index 0000000..68e8f03 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php @@ -0,0 +1,108 @@ +version = $version; + $this->description = $description; + } + + /** + * @return static + */ + public static function create( + ?string $body, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return new static( + null, + $descriptionFactory !== null ? $descriptionFactory->create($body, $context) : null + ); + } + + Assert::notNull($descriptionFactory); + + return new static( + $matches[1], + $descriptionFactory->create($matches[2] ?? '', $context) + ); + } + + /** + * Gets the version section of the tag. + */ + public function getVersion() : ?string + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $version = (string) $this->version; + + return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php new file mode 100644 index 0000000..3face1e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php @@ -0,0 +1,199 @@ +filePath = $filePath; + $this->startingLine = $startingLine; + $this->lineCount = $lineCount; + if ($content !== null) { + $this->content = trim($content); + } + + $this->isURI = $isURI; + } + + public function getContent() : string + { + if ($this->content === null || $this->content === '') { + $filePath = $this->filePath; + if ($this->isURI) { + $filePath = $this->isUriRelative($this->filePath) + ? str_replace('%2F', '/', rawurlencode($this->filePath)) + : $this->filePath; + } + + return trim($filePath); + } + + return $this->content; + } + + public function getDescription() : ?string + { + return $this->content; + } + + public static function create(string $body) : ?Tag + { + // File component: File path in quotes or File URI / Source information + if (!preg_match('/^\s*(?:(\"[^\"]+\")|(\S+))(?:\s+(.*))?$/sux', $body, $matches)) { + return null; + } + + $filePath = null; + $fileUri = null; + if ($matches[1] !== '') { + $filePath = $matches[1]; + } else { + $fileUri = $matches[2]; + } + + $startingLine = 1; + $lineCount = 0; + $description = null; + + if (array_key_exists(3, $matches)) { + $description = $matches[3]; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)(?:\s+((?1))\s*)?(.*)$/sux', $matches[3], $contentMatches)) { + $startingLine = (int) $contentMatches[1]; + if (isset($contentMatches[2])) { + $lineCount = (int) $contentMatches[2]; + } + + if (array_key_exists(3, $contentMatches)) { + $description = $contentMatches[3]; + } + } + } + + return new static( + $filePath ?? ($fileUri ?? ''), + $fileUri !== null, + $startingLine, + $lineCount, + $description + ); + } + + /** + * Returns the file path. + * + * @return string Path to a file to use as an example. + * May also be an absolute URI. + */ + public function getFilePath() : string + { + return trim($this->filePath, '"'); + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + $filePath = (string) $this->filePath; + $isDefaultLine = $this->startingLine === 1 && $this->lineCount === 0; + $startingLine = !$isDefaultLine ? (string) $this->startingLine : ''; + $lineCount = !$isDefaultLine ? (string) $this->lineCount : ''; + $content = (string) $this->content; + + return $filePath + . ($startingLine !== '' + ? ($filePath !== '' ? ' ' : '') . $startingLine + : '') + . ($lineCount !== '' + ? ($filePath !== '' || $startingLine !== '' ? ' ' : '') . $lineCount + : '') + . ($content !== '' + ? ($filePath !== '' || $startingLine !== '' || $lineCount !== '' ? ' ' : '') . $content + : ''); + } + + /** + * Returns true if the provided URI is relative or contains a complete scheme (and thus is absolute). + */ + private function isUriRelative(string $uri) : bool + { + return strpos($uri, ':') === false; + } + + public function getStartingLine() : int + { + return $this->startingLine; + } + + public function getLineCount() : int + { + return $this->lineCount; + } + + public function getName() : string + { + return 'example'; + } + + public function render(?Formatter $formatter = null) : string + { + if ($formatter === null) { + $formatter = new Formatter\PassthroughFormatter(); + } + + return $formatter->format($this); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php new file mode 100644 index 0000000..f6f0bb5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php @@ -0,0 +1,25 @@ +maxLen = max($this->maxLen, strlen($tag->getName())); + } + } + + /** + * Formats the given tag to return a simple plain text version. + */ + public function format(Tag $tag) : string + { + return '@' . $tag->getName() . + str_repeat( + ' ', + $this->maxLen - strlen($tag->getName()) + 1 + ) . + $tag; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php new file mode 100644 index 0000000..f26d22f --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php @@ -0,0 +1,29 @@ +getName() . ' ' . $tag); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php new file mode 100644 index 0000000..a7b423f --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php @@ -0,0 +1,88 @@ +validateTagName($name); + + $this->name = $name; + $this->description = $description; + } + + /** + * Creates a new tag that represents any unknown tag type. + * + * @return static + */ + public static function create( + string $body, + string $name = '', + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($name); + Assert::notNull($descriptionFactory); + + $description = $body !== '' ? $descriptionFactory->create($body, $context) : null; + + return new static($name, $description); + } + + /** + * Returns the tag as a serialized string + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + return $description; + } + + /** + * Validates if the tag name matches the expected format, otherwise throws an exception. + */ + private function validateTagName(string $name) : void + { + if (!preg_match('/^' . StandardTagFactory::REGEX_TAGNAME . '$/u', $name)) { + throw new InvalidArgumentException( + 'The tag name "' . $name . '" is not wellformed. Tags may only consist of letters, underscores, ' + . 'hyphens and backslashes.' + ); + } + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php new file mode 100644 index 0000000..e3deb5a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php @@ -0,0 +1,144 @@ +name = $name; + $this->body = $body; + } + + public function getException() : ?Throwable + { + return $this->throwable; + } + + public function getName() : string + { + return $this->name; + } + + public static function create(string $body, string $name = '') : self + { + return new self($name, $body); + } + + public function withError(Throwable $exception) : self + { + $this->flattenExceptionBacktrace($exception); + $tag = new self($this->name, $this->body); + $tag->throwable = $exception; + + return $tag; + } + + /** + * Removes all complex types from backtrace + * + * Not all objects are serializable. So we need to remove them from the + * stored exception to be sure that we do not break existing library usage. + */ + private function flattenExceptionBacktrace(Throwable $exception) : void + { + $traceProperty = (new ReflectionClass(Exception::class))->getProperty('trace'); + $traceProperty->setAccessible(true); + + do { + $trace = $exception->getTrace(); + if (isset($trace[0]['args'])) { + $trace = array_map( + function (array $call) : array { + $call['args'] = array_map([$this, 'flattenArguments'], $call['args']); + + return $call; + }, + $trace + ); + } + + $traceProperty->setValue($exception, $trace); + $exception = $exception->getPrevious(); + } while ($exception !== null); + + $traceProperty->setAccessible(false); + } + + /** + * @param mixed $value + * + * @return mixed + * + * @throws ReflectionException + */ + private function flattenArguments($value) + { + if ($value instanceof Closure) { + $closureReflection = new ReflectionFunction($value); + $value = sprintf( + '(Closure at %s:%s)', + $closureReflection->getFileName(), + $closureReflection->getStartLine() + ); + } elseif (is_object($value)) { + $value = sprintf('object(%s)', get_class($value)); + } elseif (is_resource($value)) { + $value = sprintf('resource(%s)', get_resource_type($value)); + } elseif (is_array($value)) { + $value = array_map([$this, 'flattenArguments'], $value); + } + + return $value; + } + + public function render(?Formatter $formatter = null) : string + { + if ($formatter === null) { + $formatter = new Formatter\PassthroughFormatter(); + } + + return $formatter->format($this); + } + + public function __toString() : string + { + return $this->body; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php new file mode 100644 index 0000000..226bbe0 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php @@ -0,0 +1,78 @@ +link = $link; + $this->description = $description; + } + + public static function create( + string $body, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::notNull($descriptionFactory); + + $parts = Utils::pregSplit('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + return new static($parts[0], $description); + } + + /** + * Gets the link + */ + public function getLink() : string + { + return $this->link; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $link = (string) $this->link; + + return $link . ($description !== '' ? ($link !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php new file mode 100644 index 0000000..08c0407 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php @@ -0,0 +1,279 @@ + + * @var array> + */ + private $arguments; + + /** @var bool */ + private $isStatic; + + /** @var Type */ + private $returnType; + + /** + * @param array> $arguments + * + * @phpstan-param array $arguments + */ + public function __construct( + string $methodName, + array $arguments = [], + ?Type $returnType = null, + bool $static = false, + ?Description $description = null + ) { + Assert::stringNotEmpty($methodName); + + if ($returnType === null) { + $returnType = new Void_(); + } + + $this->methodName = $methodName; + $this->arguments = $this->filterArguments($arguments); + $this->returnType = $returnType; + $this->isStatic = $static; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : ?self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + // 1. none or more whitespace + // 2. optionally the keyword "static" followed by whitespace + // 3. optionally a word with underscores followed by whitespace : as + // type for the return value + // 4. then optionally a word with underscores followed by () and + // whitespace : as method name as used by phpDocumentor + // 5. then a word with underscores, followed by ( and any character + // until a ) and whitespace : as method name with signature + // 6. any remaining text : as description + if (!preg_match( + '/^ + # Static keyword + # Declares a static method ONLY if type is also present + (?: + (static) + \s+ + )? + # Return type + (?: + ( + (?:[\w\|_\\\\]*\$this[\w\|_\\\\]*) + | + (?: + (?:[\w\|_\\\\]+) + # array notation + (?:\[\])* + )*+ + ) + \s+ + )? + # Method name + ([\w_]+) + # Arguments + (?: + \(([^\)]*)\) + )? + \s* + # Description + (.*) + $/sux', + $body, + $matches + )) { + return null; + } + + [, $static, $returnType, $methodName, $argumentLines, $description] = $matches; + + $static = $static === 'static'; + + if ($returnType === '') { + $returnType = 'void'; + } + + $returnType = $typeResolver->resolve($returnType, $context); + $description = $descriptionFactory->create($description, $context); + + /** @phpstan-var array $arguments */ + $arguments = []; + if ($argumentLines !== '') { + $argumentsExploded = explode(',', $argumentLines); + foreach ($argumentsExploded as $argument) { + $argument = explode(' ', self::stripRestArg(trim($argument)), 2); + if (strpos($argument[0], '$') === 0) { + $argumentName = substr($argument[0], 1); + $argumentType = new Mixed_(); + } else { + $argumentType = $typeResolver->resolve($argument[0], $context); + $argumentName = ''; + if (isset($argument[1])) { + $argument[1] = self::stripRestArg($argument[1]); + $argumentName = substr($argument[1], 1); + } + } + + $arguments[] = ['name' => $argumentName, 'type' => $argumentType]; + } + } + + return new static($methodName, $arguments, $returnType, $static, $description); + } + + /** + * Retrieves the method name. + */ + public function getMethodName() : string + { + return $this->methodName; + } + + /** + * @return array> + * + * @phpstan-return array + */ + public function getArguments() : array + { + return $this->arguments; + } + + /** + * Checks whether the method tag describes a static method or not. + * + * @return bool TRUE if the method declaration is for a static method, FALSE otherwise. + */ + public function isStatic() : bool + { + return $this->isStatic; + } + + public function getReturnType() : Type + { + return $this->returnType; + } + + public function __toString() : string + { + $arguments = []; + foreach ($this->arguments as $argument) { + $arguments[] = $argument['type'] . ' $' . $argument['name']; + } + + $argumentStr = '(' . implode(', ', $arguments) . ')'; + + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $static = $this->isStatic ? 'static' : ''; + + $returnType = (string) $this->returnType; + + $methodName = (string) $this->methodName; + + return $static + . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '') + . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $methodName : '') + . $argumentStr + . ($description !== '' ? ' ' . $description : ''); + } + + /** + * @param mixed[][]|string[] $arguments + * + * @return mixed[][] + * + * @phpstan-param array $arguments + * @phpstan-return array + */ + private function filterArguments(array $arguments = []) : array + { + $result = []; + foreach ($arguments as $argument) { + if (is_string($argument)) { + $argument = ['name' => $argument]; + } + + if (!isset($argument['type'])) { + $argument['type'] = new Mixed_(); + } + + $keys = array_keys($argument); + sort($keys); + if ($keys !== ['name', 'type']) { + throw new InvalidArgumentException( + 'Arguments can only have the "name" and "type" fields, found: ' . var_export($keys, true) + ); + } + + $result[] = $argument; + } + + return $result; + } + + private static function stripRestArg(string $argument) : string + { + if (strpos($argument, '...') === 0) { + $argument = trim(substr($argument, 3)); + } + + return $argument; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php new file mode 100644 index 0000000..83419e9 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php @@ -0,0 +1,172 @@ +name = 'param'; + $this->variableName = $variableName; + $this->type = $type; + $this->isVariadic = $isVariadic; + $this->description = $description; + $this->isReference = $isReference; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$firstPart, $body] = self::extractTypeFromBody($body); + + $type = null; + $parts = Utils::pregSplit('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $variableName = ''; + $isVariadic = false; + $isReference = false; + + // if the first item that is encountered is not a variable; it is a type + if ($firstPart && !self::strStartsWithVariable($firstPart)) { + $type = $typeResolver->resolve($firstPart, $context); + } else { + // first part is not a type; we should prepend it to the parts array for further processing + array_unshift($parts, $firstPart); + } + + // if the next item starts with a $ or ...$ or &$ or &...$ it must be the variable name + if (isset($parts[0]) && self::strStartsWithVariable($parts[0])) { + $variableName = array_shift($parts); + if ($type) { + array_shift($parts); + } + + Assert::notNull($variableName); + + if (strpos($variableName, '$') === 0) { + $variableName = substr($variableName, 1); + } elseif (strpos($variableName, '&$') === 0) { + $isReference = true; + $variableName = substr($variableName, 2); + } elseif (strpos($variableName, '...$') === 0) { + $isVariadic = true; + $variableName = substr($variableName, 4); + } elseif (strpos($variableName, '&...$') === 0) { + $isVariadic = true; + $isReference = true; + $variableName = substr($variableName, 5); + } + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $isVariadic, $description, $isReference); + } + + /** + * Returns the variable's name. + */ + public function getVariableName() : ?string + { + return $this->variableName; + } + + /** + * Returns whether this tag is variadic. + */ + public function isVariadic() : bool + { + return $this->isVariadic; + } + + /** + * Returns whether this tag is passed by reference. + */ + public function isReference() : bool + { + return $this->isReference; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $variableName = ''; + if ($this->variableName) { + $variableName .= ($this->isReference ? '&' : '') . ($this->isVariadic ? '...' : ''); + $variableName .= '$' . $this->variableName; + } + + $type = (string) $this->type; + + return $type + . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') + . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); + } + + private static function strStartsWithVariable(string $str) : bool + { + return strpos($str, '$') === 0 + || + strpos($str, '...$') === 0 + || + strpos($str, '&$') === 0 + || + strpos($str, '&...$') === 0; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php new file mode 100644 index 0000000..0389757 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php @@ -0,0 +1,119 @@ +name = 'property'; + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$firstPart, $body] = self::extractTypeFromBody($body); + $type = null; + $parts = Utils::pregSplit('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if ($firstPart && $firstPart[0] !== '$') { + $type = $typeResolver->resolve($firstPart, $context); + } else { + // first part is not a type; we should prepend it to the parts array for further processing + array_unshift($parts, $firstPart); + } + + // if the next item starts with a $ it must be the variable name + if (isset($parts[0]) && strpos($parts[0], '$') === 0) { + $variableName = array_shift($parts); + if ($type) { + array_shift($parts); + } + + Assert::notNull($variableName); + + $variableName = substr($variableName, 1); + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + */ + public function getVariableName() : ?string + { + return $this->variableName; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + if ($this->variableName) { + $variableName = '$' . $this->variableName; + } else { + $variableName = ''; + } + + $type = (string) $this->type; + + return $type + . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') + . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php new file mode 100644 index 0000000..7ff55d5 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php @@ -0,0 +1,119 @@ +name = 'property-read'; + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$firstPart, $body] = self::extractTypeFromBody($body); + $type = null; + $parts = Utils::pregSplit('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if ($firstPart && $firstPart[0] !== '$') { + $type = $typeResolver->resolve($firstPart, $context); + } else { + // first part is not a type; we should prepend it to the parts array for further processing + array_unshift($parts, $firstPart); + } + + // if the next item starts with a $ it must be the variable name + if (isset($parts[0]) && strpos($parts[0], '$') === 0) { + $variableName = array_shift($parts); + if ($type) { + array_shift($parts); + } + + Assert::notNull($variableName); + + $variableName = substr($variableName, 1); + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + */ + public function getVariableName() : ?string + { + return $this->variableName; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + if ($this->variableName) { + $variableName = '$' . $this->variableName; + } else { + $variableName = ''; + } + + $type = (string) $this->type; + + return $type + . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') + . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php new file mode 100644 index 0000000..cc1e4b6 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php @@ -0,0 +1,119 @@ +name = 'property-write'; + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$firstPart, $body] = self::extractTypeFromBody($body); + $type = null; + $parts = Utils::pregSplit('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if ($firstPart && $firstPart[0] !== '$') { + $type = $typeResolver->resolve($firstPart, $context); + } else { + // first part is not a type; we should prepend it to the parts array for further processing + array_unshift($parts, $firstPart); + } + + // if the next item starts with a $ it must be the variable name + if (isset($parts[0]) && strpos($parts[0], '$') === 0) { + $variableName = array_shift($parts); + if ($type) { + array_shift($parts); + } + + Assert::notNull($variableName); + + $variableName = substr($variableName, 1); + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + */ + public function getVariableName() : ?string + { + return $this->variableName; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + if ($this->variableName) { + $variableName = '$' . $this->variableName; + } else { + $variableName = ''; + } + + $type = (string) $this->type; + + return $type + . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') + . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php new file mode 100644 index 0000000..cede74c --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php @@ -0,0 +1,38 @@ +fqsen = $fqsen; + } + + /** + * @return string string representation of the referenced fqsen + */ + public function __toString() : string + { + return (string) $this->fqsen; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php new file mode 100644 index 0000000..5eedcbc --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php @@ -0,0 +1,22 @@ +uri = $uri; + } + + public function __toString() : string + { + return $this->uri; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php new file mode 100644 index 0000000..546a0ea --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php @@ -0,0 +1,64 @@ +name = 'return'; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$type, $description] = self::extractTypeFromBody($body); + + $type = $typeResolver->resolve($type, $context); + $description = $descriptionFactory->create($description, $context); + + return new static($type, $description); + } + + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $type = $this->type ? '' . $this->type : 'mixed'; + + return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php new file mode 100644 index 0000000..73311df --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php @@ -0,0 +1,105 @@ +refers = $refers; + $this->description = $description; + } + + public static function create( + string $body, + ?FqsenResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::notNull($descriptionFactory); + + $parts = Utils::pregSplit('/\s+/Su', $body, 2); + $description = isset($parts[1]) ? $descriptionFactory->create($parts[1], $context) : null; + + // https://tools.ietf.org/html/rfc2396#section-3 + if (preg_match('/\w:\/\/\w/i', $parts[0])) { + return new static(new Url($parts[0]), $description); + } + + return new static(new FqsenRef(self::resolveFqsen($parts[0], $typeResolver, $context)), $description); + } + + private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen + { + Assert::notNull($fqsenResolver); + $fqsenParts = explode('::', $parts); + $resolved = $fqsenResolver->resolve($fqsenParts[0], $context); + + if (!array_key_exists(1, $fqsenParts)) { + return $resolved; + } + + return new Fqsen($resolved . '::' . $fqsenParts[1]); + } + + /** + * Returns the ref of this tag. + */ + public function getReference() : Reference + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $refers = (string) $this->refers; + + return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php new file mode 100644 index 0000000..32de527 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php @@ -0,0 +1,102 @@ +version = $version; + $this->description = $description; + } + + public static function create( + ?string $body, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : ?self { + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + Assert::notNull($descriptionFactory); + + return new static( + $matches[1], + $descriptionFactory->create($matches[2] ?? '', $context) + ); + } + + /** + * Gets the version section of the tag. + */ + public function getVersion() : ?string + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $version = (string) $this->version; + + return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php new file mode 100644 index 0000000..f0c3101 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php @@ -0,0 +1,117 @@ +startingLine = (int) $startingLine; + $this->lineCount = $lineCount !== null ? (int) $lineCount : null; + $this->description = $description; + } + + public static function create( + string $body, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($descriptionFactory); + + $startingLine = 1; + $lineCount = null; + $description = null; + + // Starting line / Number of lines / Description + if (preg_match('/^([1-9]\d*)\s*(?:((?1))\s+)?(.*)$/sux', $body, $matches)) { + $startingLine = (int) $matches[1]; + if (isset($matches[2]) && $matches[2] !== '') { + $lineCount = (int) $matches[2]; + } + + $description = $matches[3]; + } + + return new static($startingLine, $lineCount, $descriptionFactory->create($description??'', $context)); + } + + /** + * Gets the starting line. + * + * @return int The starting line, relative to the structural element's + * location. + */ + public function getStartingLine() : int + { + return $this->startingLine; + } + + /** + * Returns the number of lines. + * + * @return int|null The number of lines, relative to the starting line. NULL + * means "to the end". + */ + public function getLineCount() : ?int + { + return $this->lineCount; + } + + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $startingLine = (string) $this->startingLine; + + $lineCount = $this->lineCount !== null ? '' . $this->lineCount : ''; + + return $startingLine + . ($lineCount !== '' + ? ($startingLine || $startingLine === '0' ? ' ' : '') . $lineCount + : '') + . ($description !== '' + ? ($startingLine || $startingLine === '0' || $lineCount !== '' ? ' ' : '') . $description + : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php new file mode 100644 index 0000000..0083d34 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php @@ -0,0 +1,65 @@ +type; + } + + /** + * @return string[] + */ + protected static function extractTypeFromBody(string $body) : array + { + $type = ''; + $nestingLevel = 0; + for ($i = 0, $iMax = strlen($body); $i < $iMax; $i++) { + $character = $body[$i]; + + if ($nestingLevel === 0 && trim($character) === '') { + break; + } + + $type .= $character; + if (in_array($character, ['<', '(', '[', '{'])) { + $nestingLevel++; + continue; + } + + if (in_array($character, ['>', ')', ']', '}'])) { + $nestingLevel--; + continue; + } + } + + $description = trim(substr($body, strlen($type))); + + return [$type, $description]; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php new file mode 100644 index 0000000..d4dc947 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php @@ -0,0 +1,64 @@ +name = 'throws'; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$type, $description] = self::extractTypeFromBody($body); + + $type = $typeResolver->resolve($type, $context); + $description = $descriptionFactory->create($description, $context); + + return new static($type, $description); + } + + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $type = (string) $this->type; + + return $type . ($description !== '' ? ($type !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php new file mode 100644 index 0000000..4d52afc --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php @@ -0,0 +1,99 @@ +refers = $refers; + $this->description = $description; + } + + public static function create( + string $body, + ?FqsenResolver $resolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::notNull($resolver); + Assert::notNull($descriptionFactory); + + $parts = Utils::pregSplit('/\s+/Su', $body, 2); + + return new static( + self::resolveFqsen($parts[0], $resolver, $context), + $descriptionFactory->create($parts[1] ?? '', $context) + ); + } + + private static function resolveFqsen(string $parts, ?FqsenResolver $fqsenResolver, ?TypeContext $context) : Fqsen + { + Assert::notNull($fqsenResolver); + $fqsenParts = explode('::', $parts); + $resolved = $fqsenResolver->resolve($fqsenParts[0], $context); + + if (!array_key_exists(1, $fqsenParts)) { + return $resolved; + } + + return new Fqsen($resolved . '::' . $fqsenParts[1]); + } + + /** + * Returns the structural element this tag refers to. + */ + public function getReference() : Fqsen + { + return $this->refers; + } + + /** + * Returns a string representation of this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $refers = (string) $this->refers; + + return $refers . ($description !== '' ? ($refers !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php new file mode 100644 index 0000000..762c262 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php @@ -0,0 +1,120 @@ +name = 'var'; + $this->variableName = $variableName; + $this->type = $type; + $this->description = $description; + } + + public static function create( + string $body, + ?TypeResolver $typeResolver = null, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : self { + Assert::stringNotEmpty($body); + Assert::notNull($typeResolver); + Assert::notNull($descriptionFactory); + + [$firstPart, $body] = self::extractTypeFromBody($body); + + $parts = Utils::pregSplit('/(\s+)/Su', $body, 2, PREG_SPLIT_DELIM_CAPTURE); + $type = null; + $variableName = ''; + + // if the first item that is encountered is not a variable; it is a type + if ($firstPart && $firstPart[0] !== '$') { + $type = $typeResolver->resolve($firstPart, $context); + } else { + // first part is not a type; we should prepend it to the parts array for further processing + array_unshift($parts, $firstPart); + } + + // if the next item starts with a $ it must be the variable name + if (isset($parts[0]) && strpos($parts[0], '$') === 0) { + $variableName = array_shift($parts); + if ($type) { + array_shift($parts); + } + + Assert::notNull($variableName); + + $variableName = substr($variableName, 1); + } + + $description = $descriptionFactory->create(implode('', $parts), $context); + + return new static($variableName, $type, $description); + } + + /** + * Returns the variable's name. + */ + public function getVariableName() : ?string + { + return $this->variableName; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + if ($this->variableName) { + $variableName = '$' . $this->variableName; + } else { + $variableName = ''; + } + + $type = (string) $this->type; + + return $type + . ($variableName !== '' ? ($type !== '' ? ' ' : '') . $variableName : '') + . ($description !== '' ? ($type !== '' || $variableName !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php new file mode 100644 index 0000000..460c86d --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php @@ -0,0 +1,105 @@ +version = $version; + $this->description = $description; + } + + public static function create( + ?string $body, + ?DescriptionFactory $descriptionFactory = null, + ?TypeContext $context = null + ) : ?self { + if (empty($body)) { + return new static(); + } + + $matches = []; + if (!preg_match('/^(' . self::REGEX_VECTOR . ')\s*(.+)?$/sux', $body, $matches)) { + return null; + } + + $description = null; + if ($descriptionFactory !== null) { + $description = $descriptionFactory->create($matches[2] ?? '', $context); + } + + return new static( + $matches[1], + $description + ); + } + + /** + * Gets the version section of the tag. + */ + public function getVersion() : ?string + { + return $this->version; + } + + /** + * Returns a string representation for this tag. + */ + public function __toString() : string + { + if ($this->description) { + $description = $this->description->render(); + } else { + $description = ''; + } + + $version = (string) $this->version; + + return $version . ($description !== '' ? ($version !== '' ? ' ' : '') . $description : ''); + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php new file mode 100644 index 0000000..cf04e5a --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php @@ -0,0 +1,286 @@ +descriptionFactory = $descriptionFactory; + $this->tagFactory = $tagFactory; + } + + /** + * Factory method for easy instantiation. + * + * @param array> $additionalTags + */ + public static function createInstance(array $additionalTags = []) : self + { + $fqsenResolver = new FqsenResolver(); + $tagFactory = new StandardTagFactory($fqsenResolver); + $descriptionFactory = new DescriptionFactory($tagFactory); + + $tagFactory->addService($descriptionFactory); + $tagFactory->addService(new TypeResolver($fqsenResolver)); + + $docBlockFactory = new self($descriptionFactory, $tagFactory); + foreach ($additionalTags as $tagName => $tagHandler) { + $docBlockFactory->registerTagHandler($tagName, $tagHandler); + } + + return $docBlockFactory; + } + + /** + * @param object|string $docblock A string containing the DocBlock to parse or an object supporting the + * getDocComment method (such as a ReflectionClass object). + */ + public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock + { + if (is_object($docblock)) { + if (!method_exists($docblock, 'getDocComment')) { + $exceptionMessage = 'Invalid object passed; the given object must support the getDocComment method'; + + throw new InvalidArgumentException($exceptionMessage); + } + + $docblock = $docblock->getDocComment(); + Assert::string($docblock); + } + + Assert::stringNotEmpty($docblock); + + if ($context === null) { + $context = new Types\Context(''); + } + + $parts = $this->splitDocBlock($this->stripDocComment($docblock)); + + [$templateMarker, $summary, $description, $tags] = $parts; + + return new DocBlock( + $summary, + $description ? $this->descriptionFactory->create($description, $context) : null, + $this->parseTagBlock($tags, $context), + $context, + $location, + $templateMarker === '#@+', + $templateMarker === '#@-' + ); + } + + /** + * @param class-string $handler + */ + public function registerTagHandler(string $tagName, string $handler) : void + { + $this->tagFactory->registerTagHandler($tagName, $handler); + } + + /** + * Strips the asterisks from the DocBlock comment. + * + * @param string $comment String containing the comment text. + */ + private function stripDocComment(string $comment) : string + { + $comment = preg_replace('#[ \t]*(?:\/\*\*|\*\/|\*)?[ \t]?(.*)?#u', '$1', $comment); + Assert::string($comment); + $comment = trim($comment); + + // reg ex above is not able to remove */ from a single line docblock + if (substr($comment, -2) === '*/') { + $comment = trim(substr($comment, 0, -2)); + } + + return str_replace(["\r\n", "\r"], "\n", $comment); + } + + // phpcs:disable + /** + * Splits the DocBlock into a template marker, summary, description and block of tags. + * + * @param string $comment Comment to split into the sub-parts. + * + * @return string[] containing the template marker (if any), summary, description and a string containing the tags. + * + * @author Mike van Riel for extending the regex with template marker support. + * + * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split. + */ + private function splitDocBlock(string $comment) : array + { + // phpcs:enable + // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This + // method does not split tags so we return this verbatim as the fourth result (tags). This saves us the + // performance impact of running a regular expression + if (strpos($comment, '@') === 0) { + return ['', '', '', $comment]; + } + + // clears all extra horizontal whitespace from the line endings to prevent parsing issues + $comment = preg_replace('/\h*$/Sum', '', $comment); + Assert::string($comment); + /* + * Splits the docblock into a template marker, summary, description and tags section. + * + * - The template marker is empty, #@+ or #@- if the DocBlock starts with either of those (a newline may + * occur after it and will be stripped). + * - The short description is started from the first character until a dot is encountered followed by a + * newline OR two consecutive newlines (horizontal whitespace is taken into account to consider spacing + * errors). This is optional. + * - The long description, any character until a new line is encountered followed by an @ and word + * characters (a tag). This is optional. + * - Tags; the remaining characters + * + * Big thanks to RichardJ for contributing this Regular Expression + */ + preg_match( + '/ + \A + # 1. Extract the template marker + (?:(\#\@\+|\#\@\-)\n?)? + + # 2. Extract the summary + (?: + (?! @\pL ) # The summary may not start with an @ + ( + [^\n.]+ + (?: + (?! \. \n | \n{2} ) # End summary upon a dot followed by newline or two newlines + [\n.]* (?! [ \t]* @\pL ) # End summary when an @ is found as first character on a new line + [^\n.]+ # Include anything else + )* + \.? + )? + ) + + # 3. Extract the description + (?: + \s* # Some form of whitespace _must_ precede a description because a summary must be there + (?! @\pL ) # The description may not start with an @ + ( + [^\n]+ + (?: \n+ + (?! [ \t]* @\pL ) # End description when an @ is found as first character on a new line + [^\n]+ # Include anything else + )* + ) + )? + + # 4. Extract the tags (anything that follows) + (\s+ [\s\S]*)? # everything that follows + /ux', + $comment, + $matches + ); + array_shift($matches); + + while (count($matches) < 4) { + $matches[] = ''; + } + + return $matches; + } + + /** + * Creates the tag objects. + * + * @param string $tags Tag block to parse. + * @param Types\Context $context Context of the parsed Tag + * + * @return DocBlock\Tag[] + */ + private function parseTagBlock(string $tags, Types\Context $context) : array + { + $tags = $this->filterTagBlock($tags); + if ($tags === null) { + return []; + } + + $result = []; + $lines = $this->splitTagBlockIntoTagLines($tags); + foreach ($lines as $key => $tagLine) { + $result[$key] = $this->tagFactory->create(trim($tagLine), $context); + } + + return $result; + } + + /** + * @return string[] + */ + private function splitTagBlockIntoTagLines(string $tags) : array + { + $result = []; + foreach (explode("\n", $tags) as $tagLine) { + if ($tagLine !== '' && strpos($tagLine, '@') === 0) { + $result[] = $tagLine; + } else { + $result[count($result) - 1] .= "\n" . $tagLine; + } + } + + return $result; + } + + private function filterTagBlock(string $tags) : ?string + { + $tags = trim($tags); + if (!$tags) { + return null; + } + + if ($tags[0] !== '@') { + // @codeCoverageIgnoreStart + // Can't simulate this; this only happens if there is an error with the parsing of the DocBlock that + // we didn't foresee. + + throw new LogicException('A tag block started with text instead of an at-sign(@): ' . $tags); + + // @codeCoverageIgnoreEnd + } + + return $tags; + } +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php new file mode 100644 index 0000000..ef039a4 --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php @@ -0,0 +1,23 @@ +> $additionalTags + */ + public static function createInstance(array $additionalTags = []) : DocBlockFactory; + + /** + * @param string|object $docblock + */ + public function create($docblock, ?Types\Context $context = null, ?Location $location = null) : DocBlock; +} diff --git a/vendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php b/vendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php new file mode 100644 index 0000000..77aa40e --- /dev/null +++ b/vendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php @@ -0,0 +1,38 @@ + please note that if you want to pass partial class names that additional steps are necessary, see the + > chapter `Resolving partial classes and FQSENs` for more information. + +Where the FqsenResolver can resolve: + +- Constant expressions (i.e. `@see \MyNamespace\MY_CONSTANT`) +- Function expressions (i.e. `@see \MyNamespace\myFunction()`) +- Class expressions (i.e. `@see \MyNamespace\MyClass`) +- Interface expressions (i.e. `@see \MyNamespace\MyInterface`) +- Trait expressions (i.e. `@see \MyNamespace\MyTrait`) +- Class constant expressions (i.e. `@see \MyNamespace\MyClass::MY_CONSTANT`) +- Property expressions (i.e. `@see \MyNamespace\MyClass::$myProperty`) +- Method expressions (i.e. `@see \MyNamespace\MyClass::myMethod()`) + +## Resolving a type + +In order to resolve a type you will have to instantiate the class `\phpDocumentor\Reflection\TypeResolver` and call its `resolve` method like this: + +```php +$typeResolver = new \phpDocumentor\Reflection\TypeResolver(); +$type = $typeResolver->resolve('string|integer'); +``` + +In this example you will receive a Value Object of class `\phpDocumentor\Reflection\Types\Compound` that has two +elements, one of type `\phpDocumentor\Reflection\Types\String_` and one of type +`\phpDocumentor\Reflection\Types\Integer`. + +The real power of this resolver is in its capability to expand partial class names into fully qualified class names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply. + +### Resolving nullable types + +Php 7.1 introduced nullable types e.g. `?string`. Type resolver will resolve the original type without the nullable notation `?` +just like it would do without the `?`. After that the type is wrapped in a `\phpDocumentor\Reflection\Types\Nullable` object. +The `Nullable` type has a method to fetch the actual type. + +## Resolving an FQSEN + +A Fully Qualified Structural Element Name is a reference to another element in your code bases and can be resolved using the `\phpDocumentor\Reflection\FqsenResolver` class' `resolve` method, like this: + +```php +$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); +$fqsen = $fqsenResolver->resolve('\phpDocumentor\Reflection\FqsenResolver::resolve()'); +``` + +In this example we resolve a Fully Qualified Structural Element Name (meaning that it includes the full namespace, class name and element name) and receive a Value Object of type `\phpDocumentor\Reflection\Fqsen`. + +The real power of this resolver is in its capability to expand partial element names into Fully Qualified Structural Element Names; but in order to do that we need an additional `\phpDocumentor\Reflection\Types\Context` class that will inform the resolver in which namespace the given expression occurs and which namespace aliases (or imports) apply. + +## Resolving partial Classes and Structural Element Names + +Perhaps the best feature of this library is that it knows how to resolve partial class names into fully qualified class names. + +For example, you have this file: + +```php +namespace My\Example; + +use phpDocumentor\Reflection\Types; + +class Classy +{ + /** + * @var Types\Context + * @see Classy::otherFunction() + */ + public function __construct($context) {} + + public function otherFunction(){} +} +``` + +Suppose that you would want to resolve (and expand) the type in the `@var` tag and the element name in the `@see` tag. + +For the resolvers to know how to expand partial names you have to provide a bit of _Context_ for them by instantiating a new class named `\phpDocumentor\Reflection\Types\Context` with the name of the namespace and the aliases that are in play. + +### Creating a Context + +You can do this by manually creating a Context like this: + +```php +$context = new \phpDocumentor\Reflection\Types\Context( + '\My\Example', + [ 'Types' => '\phpDocumentor\Reflection\Types'] +); +``` + +Or by using the `\phpDocumentor\Reflection\Types\ContextFactory` to instantiate a new context based on a Reflector object or by providing the namespace that you'd like to extract and the source code of the file in which the given type expression occurs. + +```php +$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); +$context = $contextFactory->createFromReflector(new ReflectionMethod('\My\Example\Classy', '__construct')); +``` + +or + +```php +$contextFactory = new \phpDocumentor\Reflection\Types\ContextFactory(); +$context = $contextFactory->createForNamespace('\My\Example', file_get_contents('My/Example/Classy.php')); +``` + +### Using the Context + +After you have obtained a Context it is just a matter of passing it along with the `resolve` method of either Resolver class as second argument and the Resolvers will take this into account when resolving partial names. + +To obtain the resolved class name for the `@var` tag in the example above you can do: + +```php +$typeResolver = new \phpDocumentor\Reflection\TypeResolver(); +$type = $typeResolver->resolve('Types\Context', $context); +``` + +When you do this you will receive an object of class `\phpDocumentor\Reflection\Types\Object_` for which you can call the `getFqsen` method to receive a Value Object that represents the complete FQSEN. So that would be `phpDocumentor\Reflection\Types\Context`. + +> Why is the FQSEN wrapped in another object `Object_`? +> +> The resolve method of the TypeResolver only returns object with the interface `Type` and the FQSEN is a common type that does not represent a Type. Also: in some cases a type can represent an "Untyped Object", meaning that it is an object (signified by the `object` keyword) but does not refer to a specific element using an FQSEN. + +Another example is on how to resolve the FQSEN of a method as can be seen with the `@see` tag in the example above. To resolve that you can do the following: + +```php +$fqsenResolver = new \phpDocumentor\Reflection\FqsenResolver(); +$type = $fqsenResolver->resolve('Classy::otherFunction()', $context); +``` + +Because Classy is a Class in the current namespace its FQSEN will have the `My\Example` namespace and by calling the `resolve` method of the FQSEN Resolver you will receive an `Fqsen` object that refers to `\My\Example\Classy::otherFunction()`. diff --git a/vendor/phpdocumentor/type-resolver/composer.json b/vendor/phpdocumentor/type-resolver/composer.json new file mode 100644 index 0000000..242ecbe --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/composer.json @@ -0,0 +1,34 @@ +{ + "name": "phpdocumentor/type-resolver", + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "phpDocumentor\\Reflection\\": ["tests/unit", "tests/benchmark"] + } + }, + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + } +} diff --git a/vendor/phpdocumentor/type-resolver/composer.lock b/vendor/phpdocumentor/type-resolver/composer.lock new file mode 100644 index 0000000..8fa8b87 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/composer.lock @@ -0,0 +1,71 @@ +{ + "_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": "ee8aea1f755e1772266bc7e041d8ee5b", + "packages": [ + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": "^7.2 || ^8.0" + }, + "platform-dev": { + "ext-tokenizer": "*" + } +} diff --git a/vendor/phpdocumentor/type-resolver/phpbench.json b/vendor/phpdocumentor/type-resolver/phpbench.json new file mode 100644 index 0000000..ced1eba --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/phpbench.json @@ -0,0 +1,10 @@ +{ + "bootstrap": "vendor/autoload.php", + "path": "tests/benchmark", + "extensions": [ + "Jaapio\\Blackfire\\Extension" + ], + "blackfire" : { + "env": "c12030d0-c177-47e2-b466-4994c40dc993" + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php new file mode 100644 index 0000000..6447a01 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php @@ -0,0 +1,79 @@ +isFqsen($fqsen)) { + return new Fqsen($fqsen); + } + + return $this->resolvePartialStructuralElementName($fqsen, $context); + } + + /** + * Tests whether the given type is a Fully Qualified Structural Element Name. + */ + private function isFqsen(string $type) : bool + { + return strpos($type, self::OPERATOR_NAMESPACE) === 0; + } + + /** + * Resolves a partial Structural Element Name (i.e. `Reflection\DocBlock`) to its FQSEN representation + * (i.e. `\phpDocumentor\Reflection\DocBlock`) based on the Namespace and aliases mentioned in the Context. + * + * @throws InvalidArgumentException When type is not a valid FQSEN. + */ + private function resolvePartialStructuralElementName(string $type, Context $context) : Fqsen + { + $typeParts = explode(self::OPERATOR_NAMESPACE, $type, 2); + + $namespaceAliases = $context->getNamespaceAliases(); + + // if the first segment is not an alias; prepend namespace name and return + if (!isset($namespaceAliases[$typeParts[0]])) { + $namespace = $context->getNamespace(); + if ($namespace !== '') { + $namespace .= self::OPERATOR_NAMESPACE; + } + + return new Fqsen(self::OPERATOR_NAMESPACE . $namespace . $type); + } + + $typeParts[0] = $namespaceAliases[$typeParts[0]]; + + return new Fqsen(self::OPERATOR_NAMESPACE . implode(self::OPERATOR_NAMESPACE, $typeParts)); + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/PseudoType.php b/vendor/phpdocumentor/type-resolver/src/PseudoType.php new file mode 100644 index 0000000..f94cff5 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/PseudoType.php @@ -0,0 +1,19 @@ + List of recognized keywords and unto which Value Object they map + * @psalm-var array> + */ + private $keywords = [ + 'string' => Types\String_::class, + 'class-string' => Types\ClassString::class, + 'int' => Types\Integer::class, + 'integer' => Types\Integer::class, + 'bool' => Types\Boolean::class, + 'boolean' => Types\Boolean::class, + 'real' => Types\Float_::class, + 'float' => Types\Float_::class, + 'double' => Types\Float_::class, + 'object' => Object_::class, + 'mixed' => Types\Mixed_::class, + 'array' => Array_::class, + 'resource' => Types\Resource_::class, + 'void' => Types\Void_::class, + 'null' => Types\Null_::class, + 'scalar' => Types\Scalar::class, + 'callback' => Types\Callable_::class, + 'callable' => Types\Callable_::class, + 'false' => PseudoTypes\False_::class, + 'true' => PseudoTypes\True_::class, + 'self' => Types\Self_::class, + '$this' => Types\This::class, + 'static' => Types\Static_::class, + 'parent' => Types\Parent_::class, + 'iterable' => Iterable_::class, + ]; + + /** + * @var FqsenResolver + * @psalm-readonly + */ + private $fqsenResolver; + + /** + * Initializes this TypeResolver with the means to create and resolve Fqsen objects. + */ + public function __construct(?FqsenResolver $fqsenResolver = null) + { + $this->fqsenResolver = $fqsenResolver ?: new FqsenResolver(); + } + + /** + * Analyzes the given type and returns the FQCN variant. + * + * When a type is provided this method checks whether it is not a keyword or + * Fully Qualified Class Name. If so it will use the given namespace and + * aliases to expand the type to a FQCN representation. + * + * This method only works as expected if the namespace and aliases are set; + * no dynamic reflection is being performed here. + * + * @uses Context::getNamespaceAliases() to check whether the first part of the relative type name should not be + * replaced with another namespace. + * @uses Context::getNamespace() to determine with what to prefix the type name. + * + * @param string $type The relative or absolute type. + */ + public function resolve(string $type, ?Context $context = null) : Type + { + $type = trim($type); + if (!$type) { + throw new InvalidArgumentException('Attempted to resolve "' . $type . '" but it appears to be empty'); + } + + if ($context === null) { + $context = new Context(''); + } + + // split the type string into tokens `|`, `?`, `<`, `>`, `,`, `(`, `)`, `[]`, '<', '>' and type names + $tokens = preg_split( + '/(\\||\\?|<|>|&|, ?|\\(|\\)|\\[\\]+)/', + $type, + -1, + PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE + ); + + if ($tokens === false) { + throw new InvalidArgumentException('Unable to split the type string "' . $type . '" into tokens'); + } + + /** @var ArrayIterator $tokenIterator */ + $tokenIterator = new ArrayIterator($tokens); + + return $this->parseTypes($tokenIterator, $context, self::PARSER_IN_COMPOUND); + } + + /** + * Analyse each tokens and creates types + * + * @param ArrayIterator $tokens the iterator on tokens + * @param int $parserContext on of self::PARSER_* constants, indicating + * the context where we are in the parsing + */ + private function parseTypes(ArrayIterator $tokens, Context $context, int $parserContext) : Type + { + $types = []; + $token = ''; + $compoundToken = '|'; + while ($tokens->valid()) { + $token = $tokens->current(); + if ($token === null) { + throw new RuntimeException( + 'Unexpected nullable character' + ); + } + + if ($token === '|' || $token === '&') { + if (count($types) === 0) { + throw new RuntimeException( + 'A type is missing before a type separator' + ); + } + + if (!in_array($parserContext, [ + self::PARSER_IN_COMPOUND, + self::PARSER_IN_ARRAY_EXPRESSION, + self::PARSER_IN_COLLECTION_EXPRESSION, + ], true) + ) { + throw new RuntimeException( + 'Unexpected type separator' + ); + } + + $compoundToken = $token; + $tokens->next(); + } elseif ($token === '?') { + if (!in_array($parserContext, [ + self::PARSER_IN_COMPOUND, + self::PARSER_IN_ARRAY_EXPRESSION, + self::PARSER_IN_COLLECTION_EXPRESSION, + ], true) + ) { + throw new RuntimeException( + 'Unexpected nullable character' + ); + } + + $tokens->next(); + $type = $this->parseTypes($tokens, $context, self::PARSER_IN_NULLABLE); + $types[] = new Nullable($type); + } elseif ($token === '(') { + $tokens->next(); + $type = $this->parseTypes($tokens, $context, self::PARSER_IN_ARRAY_EXPRESSION); + + $token = $tokens->current(); + if ($token === null) { // Someone did not properly close their array expression .. + break; + } + + $tokens->next(); + + $resolvedType = new Expression($type); + + $types[] = $resolvedType; + } elseif ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION && $token[0] === ')') { + break; + } elseif ($token === '<') { + if (count($types) === 0) { + throw new RuntimeException( + 'Unexpected collection operator "<", class name is missing' + ); + } + + $classType = array_pop($types); + if ($classType !== null) { + if ((string) $classType === 'class-string') { + $types[] = $this->resolveClassString($tokens, $context); + } else { + $types[] = $this->resolveCollection($tokens, $classType, $context); + } + } + + $tokens->next(); + } elseif ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION + && ($token === '>' || trim($token) === ',') + ) { + break; + } elseif ($token === self::OPERATOR_ARRAY) { + end($types); + $last = key($types); + $lastItem = $types[$last]; + if ($lastItem instanceof Expression) { + $lastItem = $lastItem->getValueType(); + } + + $types[$last] = new Array_($lastItem); + + $tokens->next(); + } else { + $type = $this->resolveSingleType($token, $context); + $tokens->next(); + if ($parserContext === self::PARSER_IN_NULLABLE) { + return $type; + } + + $types[] = $type; + } + } + + if ($token === '|' || $token === '&') { + throw new RuntimeException( + 'A type is missing after a type separator' + ); + } + + if (count($types) === 0) { + if ($parserContext === self::PARSER_IN_NULLABLE) { + throw new RuntimeException( + 'A type is missing after a nullable character' + ); + } + + if ($parserContext === self::PARSER_IN_ARRAY_EXPRESSION) { + throw new RuntimeException( + 'A type is missing in an array expression' + ); + } + + if ($parserContext === self::PARSER_IN_COLLECTION_EXPRESSION) { + throw new RuntimeException( + 'A type is missing in a collection expression' + ); + } + } elseif (count($types) === 1) { + return $types[0]; + } + + if ($compoundToken === '|') { + return new Compound(array_values($types)); + } + + return new Intersection(array_values($types)); + } + + /** + * resolve the given type into a type object + * + * @param string $type the type string, representing a single type + * + * @return Type|Array_|Object_ + * + * @psalm-mutation-free + */ + private function resolveSingleType(string $type, Context $context) : object + { + switch (true) { + case $this->isKeyword($type): + return $this->resolveKeyword($type); + case $this->isFqsen($type): + return $this->resolveTypedObject($type); + case $this->isPartialStructuralElementName($type): + return $this->resolveTypedObject($type, $context); + + // @codeCoverageIgnoreStart + default: + // I haven't got the foggiest how the logic would come here but added this as a defense. + throw new RuntimeException( + 'Unable to resolve type "' . $type . '", there is no known method to resolve it' + ); + } + + // @codeCoverageIgnoreEnd + } + + /** + * Adds a keyword to the list of Keywords and associates it with a specific Value Object. + * + * @psalm-param class-string $typeClassName + */ + public function addKeyword(string $keyword, string $typeClassName) : void + { + if (!class_exists($typeClassName)) { + throw new InvalidArgumentException( + 'The Value Object that needs to be created with a keyword "' . $keyword . '" must be an existing class' + . ' but we could not find the class ' . $typeClassName + ); + } + + if (!in_array(Type::class, class_implements($typeClassName), true)) { + throw new InvalidArgumentException( + 'The class "' . $typeClassName . '" must implement the interface "phpDocumentor\Reflection\Type"' + ); + } + + $this->keywords[$keyword] = $typeClassName; + } + + /** + * Detects whether the given type represents a PHPDoc keyword. + * + * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. + * + * @psalm-mutation-free + */ + private function isKeyword(string $type) : bool + { + return array_key_exists(strtolower($type), $this->keywords); + } + + /** + * Detects whether the given type represents a relative structural element name. + * + * @param string $type A relative or absolute type as defined in the phpDocumentor documentation. + * + * @psalm-mutation-free + */ + private function isPartialStructuralElementName(string $type) : bool + { + return ($type[0] !== self::OPERATOR_NAMESPACE) && !$this->isKeyword($type); + } + + /** + * Tests whether the given type is a Fully Qualified Structural Element Name. + * + * @psalm-mutation-free + */ + private function isFqsen(string $type) : bool + { + return strpos($type, self::OPERATOR_NAMESPACE) === 0; + } + + /** + * Resolves the given keyword (such as `string`) into a Type object representing that keyword. + * + * @psalm-mutation-free + */ + private function resolveKeyword(string $type) : Type + { + $className = $this->keywords[strtolower($type)]; + + return new $className(); + } + + /** + * Resolves the given FQSEN string into an FQSEN object. + * + * @psalm-mutation-free + */ + private function resolveTypedObject(string $type, ?Context $context = null) : Object_ + { + return new Object_($this->fqsenResolver->resolve($type, $context)); + } + + /** + * Resolves class string + * + * @param ArrayIterator $tokens + */ + private function resolveClassString(ArrayIterator $tokens, Context $context) : Type + { + $tokens->next(); + + $classType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION); + + if (!$classType instanceof Object_ || $classType->getFqsen() === null) { + throw new RuntimeException( + $classType . ' is not a class string' + ); + } + + $token = $tokens->current(); + if ($token !== '>') { + if (empty($token)) { + throw new RuntimeException( + 'class-string: ">" is missing' + ); + } + + throw new RuntimeException( + 'Unexpected character "' . $token . '", ">" is missing' + ); + } + + return new ClassString($classType->getFqsen()); + } + + /** + * Resolves the collection values and keys + * + * @param ArrayIterator $tokens + * + * @return Array_|Iterable_|Collection + */ + private function resolveCollection(ArrayIterator $tokens, Type $classType, Context $context) : Type + { + $isArray = ((string) $classType === 'array'); + $isIterable = ((string) $classType === 'iterable'); + + // allow only "array", "iterable" or class name before "<" + if (!$isArray && !$isIterable + && (!$classType instanceof Object_ || $classType->getFqsen() === null)) { + throw new RuntimeException( + $classType . ' is not a collection' + ); + } + + $tokens->next(); + + $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION); + $keyType = null; + + $token = $tokens->current(); + if ($token !== null && trim($token) === ',') { + // if we have a comma, then we just parsed the key type, not the value type + $keyType = $valueType; + if ($isArray) { + // check the key type for an "array" collection. We allow only + // strings or integers. + if (!$keyType instanceof String_ && + !$keyType instanceof Integer && + !$keyType instanceof Compound + ) { + throw new RuntimeException( + 'An array can have only integers or strings as keys' + ); + } + + if ($keyType instanceof Compound) { + foreach ($keyType->getIterator() as $item) { + if (!$item instanceof String_ && + !$item instanceof Integer + ) { + throw new RuntimeException( + 'An array can have only integers or strings as keys' + ); + } + } + } + } + + $tokens->next(); + // now let's parse the value type + $valueType = $this->parseTypes($tokens, $context, self::PARSER_IN_COLLECTION_EXPRESSION); + } + + $token = $tokens->current(); + if ($token !== '>') { + if (empty($token)) { + throw new RuntimeException( + 'Collection: ">" is missing' + ); + } + + throw new RuntimeException( + 'Unexpected character "' . $token . '", ">" is missing' + ); + } + + if ($isArray) { + return new Array_($valueType, $keyType); + } + + if ($isIterable) { + return new Iterable_($valueType, $keyType); + } + + if ($classType instanceof Object_) { + return $this->makeCollectionFromObject($classType, $valueType, $keyType); + } + + throw new RuntimeException('Invalid $classType provided'); + } + + /** + * @psalm-pure + */ + private function makeCollectionFromObject(Object_ $object, Type $valueType, ?Type $keyType = null) : Collection + { + return new Collection($object->getFqsen(), $valueType, $keyType); + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php b/vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php new file mode 100644 index 0000000..bbea4f1 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php @@ -0,0 +1,83 @@ +valueType = $valueType; + $this->defaultKeyType = new Compound([new String_(), new Integer()]); + $this->keyType = $keyType; + } + + /** + * Returns the type for the keys of this array. + */ + public function getKeyType() : Type + { + return $this->keyType ?? $this->defaultKeyType; + } + + /** + * Returns the value for the keys of this array. + */ + public function getValueType() : Type + { + return $this->valueType; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + if ($this->keyType) { + return 'array<' . $this->keyType . ',' . $this->valueType . '>'; + } + + if ($this->valueType instanceof Mixed_) { + return 'array'; + } + + if ($this->valueType instanceof Compound) { + return '(' . $this->valueType . ')[]'; + } + + return $this->valueType . '[]'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php b/vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php new file mode 100644 index 0000000..9522295 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php @@ -0,0 +1,124 @@ + + */ +abstract class AggregatedType implements Type, IteratorAggregate +{ + /** + * @psalm-allow-private-mutation + * @var array + */ + private $types = []; + + /** @var string */ + private $token; + + /** + * @param array $types + */ + public function __construct(array $types, string $token) + { + foreach ($types as $type) { + $this->add($type); + } + + $this->token = $token; + } + + /** + * Returns the type at the given index. + */ + public function get(int $index) : ?Type + { + if (!$this->has($index)) { + return null; + } + + return $this->types[$index]; + } + + /** + * Tests if this compound type has a type with the given index. + */ + public function has(int $index) : bool + { + return array_key_exists($index, $this->types); + } + + /** + * Tests if this compound type contains the given type. + */ + public function contains(Type $type) : bool + { + foreach ($this->types as $typePart) { + // if the type is duplicate; do not add it + if ((string) $typePart === (string) $type) { + return true; + } + } + + return false; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + return implode($this->token, $this->types); + } + + /** + * @return ArrayIterator + */ + public function getIterator() : ArrayIterator + { + return new ArrayIterator($this->types); + } + + /** + * @psalm-suppress ImpureMethodCall + */ + private function add(Type $type) : void + { + if ($type instanceof self) { + foreach ($type->getIterator() as $subType) { + $this->add($subType); + } + + return; + } + + // if the type is duplicate; do not add it + if ($this->contains($type)) { + return; + } + + $this->types[] = $type; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Array_.php b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php new file mode 100644 index 0000000..7f880e2 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Array_.php @@ -0,0 +1,29 @@ +fqsen = $fqsen; + } + + /** + * Returns the FQSEN associated with this object. + */ + public function getFqsen() : ?Fqsen + { + return $this->fqsen; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + if ($this->fqsen === null) { + return 'class-string'; + } + + return 'class-string<' . (string) $this->fqsen . '>'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Collection.php b/vendor/phpdocumentor/type-resolver/src/Types/Collection.php new file mode 100644 index 0000000..84b4463 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Collection.php @@ -0,0 +1,68 @@ +` + * 2. `ACollectionObject` + * + * - ACollectionObject can be 'array' or an object that can act as an array + * - aValueType and aKeyType can be any type expression + * + * @psalm-immutable + */ +final class Collection extends AbstractList +{ + /** @var Fqsen|null */ + private $fqsen; + + /** + * Initializes this representation of an array with the given Type or Fqsen. + */ + public function __construct(?Fqsen $fqsen, Type $valueType, ?Type $keyType = null) + { + parent::__construct($valueType, $keyType); + + $this->fqsen = $fqsen; + } + + /** + * Returns the FQSEN associated with this object. + */ + public function getFqsen() : ?Fqsen + { + return $this->fqsen; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + $objectType = (string) ($this->fqsen ?? 'object'); + + if ($this->keyType === null) { + return $objectType . '<' . $this->valueType . '>'; + } + + return $objectType . '<' . $this->keyType . ',' . $this->valueType . '>'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Compound.php b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php new file mode 100644 index 0000000..ad426cc --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Compound.php @@ -0,0 +1,38 @@ + $types + */ + public function __construct(array $types) + { + parent::__construct($types, '|'); + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Context.php b/vendor/phpdocumentor/type-resolver/src/Types/Context.php new file mode 100644 index 0000000..c134d7c --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Context.php @@ -0,0 +1,97 @@ + Fully Qualified Namespace. + * @psalm-var array + */ + private $namespaceAliases; + + /** + * Initializes the new context and normalizes all passed namespaces to be in Qualified Namespace Name (QNN) + * format (without a preceding `\`). + * + * @param string $namespace The namespace where this DocBlock resides in. + * @param string[] $namespaceAliases List of namespace aliases => Fully Qualified Namespace. + * + * @psalm-param array $namespaceAliases + */ + public function __construct(string $namespace, array $namespaceAliases = []) + { + $this->namespace = $namespace !== 'global' && $namespace !== 'default' + ? trim($namespace, '\\') + : ''; + + foreach ($namespaceAliases as $alias => $fqnn) { + if ($fqnn[0] === '\\') { + $fqnn = substr($fqnn, 1); + } + + if ($fqnn[strlen($fqnn) - 1] === '\\') { + $fqnn = substr($fqnn, 0, -1); + } + + $namespaceAliases[$alias] = $fqnn; + } + + $this->namespaceAliases = $namespaceAliases; + } + + /** + * Returns the Qualified Namespace Name (thus without `\` in front) where the associated element is in. + */ + public function getNamespace() : string + { + return $this->namespace; + } + + /** + * Returns a list of Qualified Namespace Names (thus without `\` in front) that are imported, the keys represent + * the alias for the imported Namespace. + * + * @return string[] + * + * @psalm-return array + */ + public function getNamespaceAliases() : array + { + return $this->namespaceAliases; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php new file mode 100644 index 0000000..5d09d56 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php @@ -0,0 +1,423 @@ + $reflector */ + + return $this->createFromReflectionClass($reflector); + } + + if ($reflector instanceof ReflectionParameter) { + return $this->createFromReflectionParameter($reflector); + } + + if ($reflector instanceof ReflectionMethod) { + return $this->createFromReflectionMethod($reflector); + } + + if ($reflector instanceof ReflectionProperty) { + return $this->createFromReflectionProperty($reflector); + } + + if ($reflector instanceof ReflectionClassConstant) { + return $this->createFromReflectionClassConstant($reflector); + } + + throw new UnexpectedValueException('Unhandled \Reflector instance given: ' . get_class($reflector)); + } + + private function createFromReflectionParameter(ReflectionParameter $parameter) : Context + { + $class = $parameter->getDeclaringClass(); + if (!$class) { + throw new InvalidArgumentException('Unable to get class of ' . $parameter->getName()); + } + + //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable + /** @var ReflectionClass $class */ + + return $this->createFromReflectionClass($class); + } + + private function createFromReflectionMethod(ReflectionMethod $method) : Context + { + //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable + /** @var ReflectionClass $class */ + $class = $method->getDeclaringClass(); + + return $this->createFromReflectionClass($class); + } + + private function createFromReflectionProperty(ReflectionProperty $property) : Context + { + //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable + /** @var ReflectionClass $class */ + $class = $property->getDeclaringClass(); + + return $this->createFromReflectionClass($class); + } + + private function createFromReflectionClassConstant(ReflectionClassConstant $constant) : Context + { + //phpcs:ignore SlevomatCodingStandard.Commenting.InlineDocCommentDeclaration.MissingVariable + /** @var ReflectionClass $class */ + $class = $constant->getDeclaringClass(); + + return $this->createFromReflectionClass($class); + } + + /** + * @param ReflectionClass $class + */ + private function createFromReflectionClass(ReflectionClass $class) : Context + { + $fileName = $class->getFileName(); + $namespace = $class->getNamespaceName(); + + if (is_string($fileName) && file_exists($fileName)) { + $contents = file_get_contents($fileName); + if ($contents === false) { + throw new RuntimeException('Unable to read file "' . $fileName . '"'); + } + + return $this->createForNamespace($namespace, $contents); + } + + return new Context($namespace, []); + } + + /** + * Build a Context for a namespace in the provided file contents. + * + * @see Context for more information on Contexts. + * + * @param string $namespace It does not matter if a `\` precedes the namespace name, + * this method first normalizes. + * @param string $fileContents The file's contents to retrieve the aliases from with the given namespace. + */ + public function createForNamespace(string $namespace, string $fileContents) : Context + { + $namespace = trim($namespace, '\\'); + $useStatements = []; + $currentNamespace = ''; + $tokens = new ArrayIterator(token_get_all($fileContents)); + + while ($tokens->valid()) { + $currentToken = $tokens->current(); + switch ($currentToken[0]) { + case T_NAMESPACE: + $currentNamespace = $this->parseNamespace($tokens); + break; + case T_CLASS: + // Fast-forward the iterator through the class so that any + // T_USE tokens found within are skipped - these are not + // valid namespace use statements so should be ignored. + $braceLevel = 0; + $firstBraceFound = false; + while ($tokens->valid() && ($braceLevel > 0 || !$firstBraceFound)) { + $currentToken = $tokens->current(); + if ($currentToken === '{' + || in_array($currentToken[0], [T_CURLY_OPEN, T_DOLLAR_OPEN_CURLY_BRACES], true)) { + if (!$firstBraceFound) { + $firstBraceFound = true; + } + + ++$braceLevel; + } + + if ($currentToken === '}') { + --$braceLevel; + } + + $tokens->next(); + } + + break; + case T_USE: + if ($currentNamespace === $namespace) { + $useStatements += $this->parseUseStatement($tokens); + } + + break; + } + + $tokens->next(); + } + + return new Context($namespace, $useStatements); + } + + /** + * Deduce the name from tokens when we are at the T_NAMESPACE token. + * + * @param ArrayIterator $tokens + */ + private function parseNamespace(ArrayIterator $tokens) : string + { + // skip to the first string or namespace separator + $this->skipToNextStringOrNamespaceSeparator($tokens); + + $name = ''; + $acceptedTokens = [T_STRING, T_NS_SEPARATOR, T_NAME_QUALIFIED]; + while ($tokens->valid() && in_array($tokens->current()[0], $acceptedTokens, true)) { + $name .= $tokens->current()[1]; + $tokens->next(); + } + + return $name; + } + + /** + * Deduce the names of all imports when we are at the T_USE token. + * + * @param ArrayIterator $tokens + * + * @return string[] + * + * @psalm-return array + */ + private function parseUseStatement(ArrayIterator $tokens) : array + { + $uses = []; + + while ($tokens->valid()) { + $this->skipToNextStringOrNamespaceSeparator($tokens); + + $uses += $this->extractUseStatements($tokens); + $currentToken = $tokens->current(); + if ($currentToken[0] === self::T_LITERAL_END_OF_USE) { + return $uses; + } + } + + return $uses; + } + + /** + * Fast-forwards the iterator as longs as we don't encounter a T_STRING or T_NS_SEPARATOR token. + * + * @param ArrayIterator $tokens + */ + private function skipToNextStringOrNamespaceSeparator(ArrayIterator $tokens) : void + { + while ($tokens->valid()) { + $currentToken = $tokens->current(); + if (in_array($currentToken[0], [T_STRING, T_NS_SEPARATOR], true)) { + break; + } + + if ($currentToken[0] === T_NAME_QUALIFIED) { + break; + } + + if (defined('T_NAME_FULLY_QUALIFIED') && $currentToken[0] === T_NAME_FULLY_QUALIFIED) { + break; + } + + $tokens->next(); + } + } + + /** + * Deduce the namespace name and alias of an import when we are at the T_USE token or have not reached the end of + * a USE statement yet. This will return a key/value array of the alias => namespace. + * + * @param ArrayIterator $tokens + * + * @return string[] + * + * @psalm-suppress TypeDoesNotContainType + * + * @psalm-return array + */ + private function extractUseStatements(ArrayIterator $tokens) : array + { + $extractedUseStatements = []; + $groupedNs = ''; + $currentNs = ''; + $currentAlias = ''; + $state = 'start'; + + while ($tokens->valid()) { + $currentToken = $tokens->current(); + $tokenId = is_string($currentToken) ? $currentToken : $currentToken[0]; + $tokenValue = is_string($currentToken) ? null : $currentToken[1]; + switch ($state) { + case 'start': + switch ($tokenId) { + case T_STRING: + case T_NS_SEPARATOR: + $currentNs .= (string) $tokenValue; + $currentAlias = $tokenValue; + break; + case T_NAME_QUALIFIED: + case T_NAME_FULLY_QUALIFIED: + $currentNs .= (string) $tokenValue; + $currentAlias = substr( + (string) $tokenValue, + (int) (strrpos((string) $tokenValue, '\\')) + 1 + ); + break; + case T_CURLY_OPEN: + case '{': + $state = 'grouped'; + $groupedNs = $currentNs; + break; + case T_AS: + $state = 'start-alias'; + break; + case self::T_LITERAL_USE_SEPARATOR: + case self::T_LITERAL_END_OF_USE: + $state = 'end'; + break; + default: + break; + } + + break; + case 'start-alias': + switch ($tokenId) { + case T_STRING: + $currentAlias = $tokenValue; + break; + case self::T_LITERAL_USE_SEPARATOR: + case self::T_LITERAL_END_OF_USE: + $state = 'end'; + break; + default: + break; + } + + break; + case 'grouped': + switch ($tokenId) { + case T_STRING: + case T_NS_SEPARATOR: + $currentNs .= (string) $tokenValue; + $currentAlias = $tokenValue; + break; + case T_AS: + $state = 'grouped-alias'; + break; + case self::T_LITERAL_USE_SEPARATOR: + $state = 'grouped'; + $extractedUseStatements[(string) $currentAlias] = $currentNs; + $currentNs = $groupedNs; + $currentAlias = ''; + break; + case self::T_LITERAL_END_OF_USE: + $state = 'end'; + break; + default: + break; + } + + break; + case 'grouped-alias': + switch ($tokenId) { + case T_STRING: + $currentAlias = $tokenValue; + break; + case self::T_LITERAL_USE_SEPARATOR: + $state = 'grouped'; + $extractedUseStatements[(string) $currentAlias] = $currentNs; + $currentNs = $groupedNs; + $currentAlias = ''; + break; + case self::T_LITERAL_END_OF_USE: + $state = 'end'; + break; + default: + break; + } + } + + if ($state === 'end') { + break; + } + + $tokens->next(); + } + + if ($groupedNs !== $currentNs) { + $extractedUseStatements[(string) $currentAlias] = $currentNs; + } + + return $extractedUseStatements; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Expression.php b/vendor/phpdocumentor/type-resolver/src/Types/Expression.php new file mode 100644 index 0000000..4a8ae1f --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Expression.php @@ -0,0 +1,51 @@ +valueType = $valueType; + } + + /** + * Returns the value for the keys of this array. + */ + public function getValueType() : Type + { + return $this->valueType; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + return '(' . $this->valueType . ')'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Float_.php b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php new file mode 100644 index 0000000..e70ce7d --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Float_.php @@ -0,0 +1,32 @@ + $types + */ + public function __construct(array $types) + { + parent::__construct($types, '&'); + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php new file mode 100644 index 0000000..a03a7cd --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php @@ -0,0 +1,38 @@ +keyType) { + return 'iterable<' . $this->keyType . ',' . $this->valueType . '>'; + } + + if ($this->valueType instanceof Mixed_) { + return 'iterable'; + } + + return 'iterable<' . $this->valueType . '>'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php new file mode 100644 index 0000000..2fedff4 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php @@ -0,0 +1,32 @@ +realType = $realType; + } + + /** + * Provide access to the actual type directly, if needed. + */ + public function getActualType() : Type + { + return $this->realType; + } + + /** + * Returns a rendered output of the Type as it would be used in a DocBlock. + */ + public function __toString() : string + { + return '?' . $this->realType->__toString(); + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Object_.php b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php new file mode 100644 index 0000000..4cfe2a0 --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Object_.php @@ -0,0 +1,68 @@ +fqsen = $fqsen; + } + + /** + * Returns the FQSEN associated with this object. + */ + public function getFqsen() : ?Fqsen + { + return $this->fqsen; + } + + public function __toString() : string + { + if ($this->fqsen) { + return (string) $this->fqsen; + } + + return 'object'; + } +} diff --git a/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php new file mode 100644 index 0000000..08900ab --- /dev/null +++ b/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php @@ -0,0 +1,34 @@ + + Marcello Duarte + +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/phpspec/prophecy/README.md b/vendor/phpspec/prophecy/README.md new file mode 100644 index 0000000..6033594 --- /dev/null +++ b/vendor/phpspec/prophecy/README.md @@ -0,0 +1,404 @@ +# Prophecy + +[![Stable release](https://poser.pugx.org/phpspec/prophecy/version.svg)](https://packagist.org/packages/phpspec/prophecy) +[![Build Status](https://travis-ci.org/phpspec/prophecy.svg?branch=master)](https://travis-ci.org/phpspec/prophecy) + +Prophecy is a highly opinionated yet very powerful and flexible PHP object mocking +framework. Though initially it was created to fulfil phpspec2 needs, it is flexible +enough to be used inside any testing framework out there with minimal effort. + +## A simple example + +```php +prophet->prophesize('App\Security\Hasher'); + $user = new App\Entity\User($hasher->reveal()); + + $hasher->generateHash($user, 'qwerty')->willReturn('hashed_pass'); + + $user->setPassword('qwerty'); + + $this->assertEquals('hashed_pass', $user->getPassword()); + } + + protected function setUp() + { + $this->prophet = new \Prophecy\Prophet; + } + + protected function tearDown() + { + $this->prophet->checkPredictions(); + } +} +``` + +## Installation + +### Prerequisites + +Prophecy requires PHP 7.2.0 or greater. + +### Setup through composer + +First, add Prophecy to the list of dependencies inside your `composer.json`: + +```json +{ + "require-dev": { + "phpspec/prophecy": "~1.0" + } +} +``` + +Then simply install it with composer: + +```bash +$> composer install --prefer-dist +``` + +You can read more about Composer on its [official webpage](http://getcomposer.org). + +## How to use it + +First of all, in Prophecy every word has a logical meaning, even the name of the library +itself (Prophecy). When you start feeling that, you'll become very fluid with this +tool. + +For example, Prophecy has been named that way because it concentrates on describing the future +behavior of objects with very limited knowledge about them. But as with any other prophecy, +those object prophecies can't create themselves - there should be a Prophet: + +```php +$prophet = new Prophecy\Prophet; +``` + +The Prophet creates prophecies by *prophesizing* them: + +```php +$prophecy = $prophet->prophesize(); +``` + +The result of the `prophesize()` method call is a new object of class `ObjectProphecy`. Yes, +that's your specific object prophecy, which describes how your object would behave +in the near future. But first, you need to specify which object you're talking about, +right? + +```php +$prophecy->willExtend('stdClass'); +$prophecy->willImplement('SessionHandlerInterface'); +``` + +There are 2 interesting calls - `willExtend` and `willImplement`. The first one tells +object prophecy that our object should extend specific class, the second one says that +it should implement some interface. Obviously, objects in PHP can implement multiple +interfaces, but extend only one parent class. + +### Dummies + +Ok, now we have our object prophecy. What can we do with it? First of all, we can get +our object *dummy* by revealing its prophecy: + +```php +$dummy = $prophecy->reveal(); +``` + +The `$dummy` variable now holds a special dummy object. Dummy objects are objects that extend +and/or implement preset classes/interfaces by overriding all their public methods. The key +point about dummies is that they do not hold any logic - they just do nothing. Any method +of the dummy will always return `null` and the dummy will never throw any exceptions. +Dummy is your friend if you don't care about the actual behavior of this double and just need +a token object to satisfy a method typehint. + +You need to understand one thing - a dummy is not a prophecy. Your object prophecy is still +assigned to `$prophecy` variable and in order to manipulate with your expectations, you +should work with it. `$dummy` is a dummy - a simple php object that tries to fulfil your +prophecy. + +### Stubs + +Ok, now we know how to create basic prophecies and reveal dummies from them. That's +awesome if we don't care about our _doubles_ (objects that reflect originals) +interactions. If we do, we need to use *stubs* or *mocks*. + +A stub is an object double, which doesn't have any expectations about the object behavior, +but when put in specific environment, behaves in specific way. Ok, I know, it's cryptic, +but bear with me for a minute. Simply put, a stub is a dummy, which depending on the called +method signature does different things (has logic). To create stubs in Prophecy: + +```php +$prophecy->read('123')->willReturn('value'); +``` + +Oh wow. We've just made an arbitrary call on the object prophecy? Yes, we did. And this +call returned us a new object instance of class `MethodProphecy`. Yep, that's a specific +method with arguments prophecy. Method prophecies give you the ability to create method +promises or predictions. We'll talk about method predictions later in the _Mocks_ section. + +#### Promises + +Promises are logical blocks, that represent your fictional methods in prophecy terms +and they are handled by the `MethodProphecy::will(PromiseInterface $promise)` method. +As a matter of fact, the call that we made earlier (`willReturn('value')`) is a simple +shortcut to: + +```php +$prophecy->read('123')->will(new Prophecy\Promise\ReturnPromise(array('value'))); +``` + +This promise will cause any call to our double's `read()` method with exactly one +argument - `'123'` to always return `'value'`. But that's only for this +promise, there's plenty others you can use: + +- `ReturnPromise` or `->willReturn(1)` - returns a value from a method call +- `ReturnArgumentPromise` or `->willReturnArgument($index)` - returns the nth method argument from call +- `ThrowPromise` or `->willThrow($exception)` - causes the method to throw specific exception +- `CallbackPromise` or `->will($callback)` - gives you a quick way to define your own custom logic + +Keep in mind, that you can always add even more promises by implementing +`Prophecy\Promise\PromiseInterface`. + +#### Method prophecies idempotency + +Prophecy enforces same method prophecies and, as a consequence, same promises and +predictions for the same method calls with the same arguments. This means: + +```php +$methodProphecy1 = $prophecy->read('123'); +$methodProphecy2 = $prophecy->read('123'); +$methodProphecy3 = $prophecy->read('321'); + +$methodProphecy1 === $methodProphecy2; +$methodProphecy1 !== $methodProphecy3; +``` + +That's interesting, right? Now you might ask me how would you define more complex +behaviors where some method call changes behavior of others. In PHPUnit or Mockery +you do that by predicting how many times your method will be called. In Prophecy, +you'll use promises for that: + +```php +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName('everzet')->will(function () { + $this->getName()->willReturn('everzet'); +}); + +// For PHP 5.3 +$user->setName('everzet')->will(function ($args, $user) { + $user->getName()->willReturn('everzet'); +}); + +// Or +$user->setName('everzet')->will(function ($args) use ($user) { + $user->getName()->willReturn('everzet'); +}); +``` + +And now it doesn't matter how many times or in which order your methods are called. +What matters is their behaviors and how well you faked it. + +Note: If the method is called several times, you can use the following syntax to return different +values for each call: + +```php +$prophecy->read('123')->willReturn(1, 2, 3); +``` + +This feature is actually not recommended for most cases. Relying on the order of +calls for the same arguments tends to make test fragile, as adding one more call +can break everything. + +#### Arguments wildcarding + +The previous example is awesome (at least I hope it is for you), but that's not +optimal enough. We hardcoded `'everzet'` in our expectation. Isn't there a better +way? In fact there is, but it involves understanding what this `'everzet'` +actually is. + +You see, even if method arguments used during method prophecy creation look +like simple method arguments, in reality they are not. They are argument token +wildcards. As a matter of fact, `->setName('everzet')` looks like a simple call just +because Prophecy automatically transforms it under the hood into: + +```php +$user->setName(new Prophecy\Argument\Token\ExactValueToken('everzet')); +``` + +Those argument tokens are simple PHP classes, that implement +`Prophecy\Argument\Token\TokenInterface` and tell Prophecy how to compare real arguments +with your expectations. And yes, those classnames are damn big. That's why there's a +shortcut class `Prophecy\Argument`, which you can use to create tokens like that: + +```php +use Prophecy\Argument; + +$user->setName(Argument::exact('everzet')); +``` + +`ExactValueToken` is not very useful in our case as it forced us to hardcode the username. +That's why Prophecy comes bundled with a bunch of other tokens: + +- `IdenticalValueToken` or `Argument::is($value)` - checks that the argument is identical to a specific value +- `ExactValueToken` or `Argument::exact($value)` - checks that the argument matches a specific value +- `TypeToken` or `Argument::type($typeOrClass)` - checks that the argument matches a specific type or + classname +- `ObjectStateToken` or `Argument::which($method, $value)` - checks that the argument method returns + a specific value +- `CallbackToken` or `Argument::that(callback)` - checks that the argument matches a custom callback +- `AnyValueToken` or `Argument::any()` - matches any argument +- `AnyValuesToken` or `Argument::cetera()` - matches any arguments to the rest of the signature +- `StringContainsToken` or `Argument::containingString($value)` - checks that the argument contains a specific string value +- `InArrayToken` or `Argument::in($array)` - checks if value is in array +- `NotInArrayToken` or `Argument::notIn($array)` - checks if value is not in array + +And you can add even more by implementing `TokenInterface` with your own custom classes. + +So, let's refactor our initial `{set,get}Name()` logic with argument tokens: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); +``` + +That's it. Now our `{set,get}Name()` prophecy will work with any string argument provided to it. +We've just described how our stub object should behave, even though the original object could have +no behavior whatsoever. + +One last bit about arguments now. You might ask, what happens in case of: + +```php +use Prophecy\Argument; + +$user->getName()->willReturn(null); + +// For PHP 5.4 +$user->setName(Argument::type('string'))->will(function ($args) { + $this->getName()->willReturn($args[0]); +}); + +// For PHP 5.3 +$user->setName(Argument::type('string'))->will(function ($args, $user) { + $user->getName()->willReturn($args[0]); +}); + +// Or +$user->setName(Argument::type('string'))->will(function ($args) use ($user) { + $user->getName()->willReturn($args[0]); +}); + +$user->setName(Argument::any())->will(function () { +}); +``` + +Nothing. Your stub will continue behaving the way it did before. That's because of how +arguments wildcarding works. Every argument token type has a different score level, which +wildcard then uses to calculate the final arguments match score and use the method prophecy +promise that has the highest score. In this case, `Argument::type()` in case of success +scores `5` and `Argument::any()` scores `3`. So the type token wins, as does the first +`setName()` method prophecy and its promise. The simple rule of thumb - more precise token +always wins. + +#### Getting stub objects + +Ok, now we know how to define our prophecy method promises, let's get our stub from +it: + +```php +$stub = $prophecy->reveal(); +``` + +As you might see, the only difference between how we get dummies and stubs is that with +stubs we describe every object conversation instead of just agreeing with `null` returns +(object being *dummy*). As a matter of fact, after you define your first promise +(method call), Prophecy will force you to define all the communications - it throws +the `UnexpectedCallException` for any call you didn't describe with object prophecy before +calling it on a stub. + +### Mocks + +Now we know how to define doubles without behavior (dummies) and doubles with behavior, but +no expectations (stubs). What's left is doubles for which we have some expectations. These +are called mocks and in Prophecy they look almost exactly the same as stubs, except that +they define *predictions* instead of *promises* on method prophecies: + +```php +$entityManager->flush()->shouldBeCalled(); +``` + +#### Predictions + +The `shouldBeCalled()` method here assigns `CallPrediction` to our method prophecy. +Predictions are a delayed behavior check for your prophecies. You see, during the entire lifetime +of your doubles, Prophecy records every single call you're making against it inside your +code. After that, Prophecy can use this collected information to check if it matches defined +predictions. You can assign predictions to method prophecies using the +`MethodProphecy::should(PredictionInterface $prediction)` method. As a matter of fact, +the `shouldBeCalled()` method we used earlier is just a shortcut to: + +```php +$entityManager->flush()->should(new Prophecy\Prediction\CallPrediction()); +``` + +It checks if your method of interest (that matches both the method name and the arguments wildcard) +was called 1 or more times. If the prediction failed then it throws an exception. When does this +check happen? Whenever you call `checkPredictions()` on the main Prophet object: + +```php +$prophet->checkPredictions(); +``` + +In PHPUnit, you would want to put this call into the `tearDown()` method. If no predictions +are defined, it would do nothing. So it won't harm to call it after every test. + +There are plenty more predictions you can play with: + +- `CallPrediction` or `shouldBeCalled()` - checks that the method has been called 1 or more times +- `NoCallsPrediction` or `shouldNotBeCalled()` - checks that the method has not been called +- `CallTimesPrediction` or `shouldBeCalledTimes($count)` - checks that the method has been called + `$count` times +- `CallbackPrediction` or `should($callback)` - checks the method against your own custom callback + +Of course, you can always create your own custom prediction any time by implementing +`PredictionInterface`. + +### Spies + +The last bit of awesomeness in Prophecy is out-of-the-box spies support. As I said in the previous +section, Prophecy records every call made during the double's entire lifetime. This means +you don't need to record predictions in order to check them. You can also do it +manually by using the `MethodProphecy::shouldHave(PredictionInterface $prediction)` method: + +```php +$em = $prophet->prophesize('Doctrine\ORM\EntityManager'); + +$controller->createUser($em->reveal()); + +$em->flush()->shouldHaveBeenCalled(); +``` + +Such manipulation with doubles is called spying. And with Prophecy it just works. diff --git a/vendor/phpspec/prophecy/composer.json b/vendor/phpspec/prophecy/composer.json new file mode 100644 index 0000000..3bde881 --- /dev/null +++ b/vendor/phpspec/prophecy/composer.json @@ -0,0 +1,50 @@ +{ + "name": "phpspec/prophecy", + "description": "Highly opinionated mocking framework for PHP 5.3+", + "keywords": ["Mock", "Stub", "Dummy", "Double", "Fake", "Spy"], + "homepage": "https://github.com/phpspec/prophecy", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + + "require": { + "php": "^7.2 || ~8.0, <8.1", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "doctrine/instantiator": "^1.2", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + }, + + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + + "autoload-dev": { + "psr-4": { + "Fixtures\\Prophecy\\": "fixtures" + } + }, + + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument.php b/vendor/phpspec/prophecy/src/Prophecy/Argument.php new file mode 100644 index 0000000..72c9fab --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument.php @@ -0,0 +1,239 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Argument\Token; + +/** + * Argument tokens shortcuts. + * + * @author Konstantin Kudryashov + */ +class Argument +{ + /** + * Checks that argument is exact value or object. + * + * @param mixed $value + * + * @return Token\ExactValueToken + */ + public static function exact($value) + { + return new Token\ExactValueToken($value); + } + + /** + * Checks that argument is of specific type or instance of specific class. + * + * @param string $type Type name (`integer`, `string`) or full class name + * + * @return Token\TypeToken + */ + public static function type($type) + { + return new Token\TypeToken($type); + } + + /** + * Checks that argument object has specific state. + * + * @param string $methodName + * @param mixed $value + * + * @return Token\ObjectStateToken + */ + public static function which($methodName, $value) + { + return new Token\ObjectStateToken($methodName, $value); + } + + /** + * Checks that argument matches provided callback. + * + * @param callable $callback + * + * @return Token\CallbackToken + */ + public static function that($callback) + { + return new Token\CallbackToken($callback); + } + + /** + * Matches any single value. + * + * @return Token\AnyValueToken + */ + public static function any() + { + return new Token\AnyValueToken; + } + + /** + * Matches all values to the rest of the signature. + * + * @return Token\AnyValuesToken + */ + public static function cetera() + { + return new Token\AnyValuesToken; + } + + /** + * Checks that argument matches all tokens + * + * @param mixed ... a list of tokens + * + * @return Token\LogicalAndToken + */ + public static function allOf() + { + return new Token\LogicalAndToken(func_get_args()); + } + + /** + * Checks that argument array or countable object has exact number of elements. + * + * @param integer $value array elements count + * + * @return Token\ArrayCountToken + */ + public static function size($value) + { + return new Token\ArrayCountToken($value); + } + + /** + * Checks that argument array contains (key, value) pair + * + * @param mixed $key exact value or token + * @param mixed $value exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withEntry($key, $value) + { + return new Token\ArrayEntryToken($key, $value); + } + + /** + * Checks that arguments array entries all match value + * + * @param mixed $value + * + * @return Token\ArrayEveryEntryToken + */ + public static function withEveryEntry($value) + { + return new Token\ArrayEveryEntryToken($value); + } + + /** + * Checks that argument array contains value + * + * @param mixed $value + * + * @return Token\ArrayEntryToken + */ + public static function containing($value) + { + return new Token\ArrayEntryToken(self::any(), $value); + } + + /** + * Checks that argument array has key + * + * @param mixed $key exact value or token + * + * @return Token\ArrayEntryToken + */ + public static function withKey($key) + { + return new Token\ArrayEntryToken($key, self::any()); + } + + /** + * Checks that argument does not match the value|token. + * + * @param mixed $value either exact value or argument token + * + * @return Token\LogicalNotToken + */ + public static function not($value) + { + return new Token\LogicalNotToken($value); + } + + /** + * @param string $value + * + * @return Token\StringContainsToken + */ + public static function containingString($value) + { + return new Token\StringContainsToken($value); + } + + /** + * Checks that argument is identical value. + * + * @param mixed $value + * + * @return Token\IdenticalValueToken + */ + public static function is($value) + { + return new Token\IdenticalValueToken($value); + } + + /** + * Check that argument is same value when rounding to the + * given precision. + * + * @param float $value + * @param float $precision + * + * @return Token\ApproximateValueToken + */ + public static function approximate($value, $precision = 0) + { + return new Token\ApproximateValueToken($value, $precision); + } + + /** + * Checks that argument is in array. + * + * @param array $value + * + * @return Token\InArrayToken + */ + + public function in($value) + { + return new Token\InArrayToken($value); + } + + /** + * Checks that argument is in array. + * + * @param array $value + * + * @return Token\InArrayToken + */ + + public function notIn($value) + { + return new Token\NotInArrayToken($value); + } + +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php new file mode 100644 index 0000000..a088f21 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php @@ -0,0 +1,101 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument; + +/** + * Arguments wildcarding. + * + * @author Konstantin Kudryashov + */ +class ArgumentsWildcard +{ + /** + * @var Token\TokenInterface[] + */ + private $tokens = array(); + private $string; + + /** + * Initializes wildcard. + * + * @param array $arguments Array of argument tokens or values + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof Token\TokenInterface) { + $argument = new Token\ExactValueToken($argument); + } + + $this->tokens[] = $argument; + } + } + + /** + * Calculates wildcard match score for provided arguments. + * + * @param array $arguments + * + * @return false|int False OR integer score (higher - better) + */ + public function scoreArguments(array $arguments) + { + if (0 == count($arguments) && 0 == count($this->tokens)) { + return 1; + } + + $arguments = array_values($arguments); + $totalScore = 0; + foreach ($this->tokens as $i => $token) { + $argument = isset($arguments[$i]) ? $arguments[$i] : null; + if (1 >= $score = $token->scoreArgument($argument)) { + return false; + } + + $totalScore += $score; + + if (true === $token->isLast()) { + return $totalScore; + } + } + + if (count($arguments) > count($this->tokens)) { + return false; + } + + return $totalScore; + } + + /** + * Returns string representation for wildcard. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = implode(', ', array_map(function ($token) { + return (string) $token; + }, $this->tokens)); + } + + return $this->string; + } + + /** + * @return array + */ + public function getTokens() + { + return $this->tokens; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php new file mode 100644 index 0000000..5098811 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any single value token. + * + * @author Konstantin Kudryashov + */ +class AnyValueToken implements TokenInterface +{ + /** + * Always scores 3 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 3; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '*'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php new file mode 100644 index 0000000..f76b17b --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Any values token. + * + * @author Konstantin Kudryashov + */ +class AnyValuesToken implements TokenInterface +{ + /** + * Always scores 2 for any argument. + * + * @param $argument + * + * @return int + */ + public function scoreArgument($argument) + { + return 2; + } + + /** + * Returns true to stop wildcard from processing other tokens. + * + * @return bool + */ + public function isLast() + { + return true; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return '* [, ...]'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php new file mode 100644 index 0000000..901744a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php @@ -0,0 +1,55 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Approximate value token + * + * @author Daniel Leech + */ +class ApproximateValueToken implements TokenInterface +{ + private $value; + private $precision; + + public function __construct($value, $precision = 0) + { + $this->value = $value; + $this->precision = $precision; + } + + /** + * {@inheritdoc} + */ + public function scoreArgument($argument) + { + return round((float)$argument, $this->precision) === round($this->value, $this->precision) ? 10 : false; + } + + /** + * {@inheritdoc} + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('≅%s', round($this->value, $this->precision)); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php new file mode 100644 index 0000000..96b4bef --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array elements count token. + * + * @author Boris Mikhaylov + */ + +class ArrayCountToken implements TokenInterface +{ + private $count; + + /** + * @param integer $value + */ + public function __construct($value) + { + $this->count = $value; + } + + /** + * Scores 6 when argument has preset number of elements. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $this->isCountable($argument) && $this->hasProperCount($argument) ? 6 : false; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('count(%s)', $this->count); + } + + /** + * Returns true if object is either array or instance of \Countable + * + * @param $argument + * @return bool + */ + private function isCountable($argument) + { + return (is_array($argument) || $argument instanceof \Countable); + } + + /** + * Returns true if $argument has expected number of elements + * + * @param array|\Countable $argument + * + * @return bool + */ + private function hasProperCount($argument) + { + return $this->count === count($argument); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php new file mode 100644 index 0000000..0305fc7 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php @@ -0,0 +1,143 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Array entry token. + * + * @author Boris Mikhaylov + */ +class ArrayEntryToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $key; + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $value; + + /** + * @param mixed $key exact value or token + * @param mixed $value exact value or token + */ + public function __construct($key, $value) + { + $this->key = $this->wrapIntoExactValueToken($key); + $this->value = $this->wrapIntoExactValueToken($value); + } + + /** + * Scores half of combined scores from key and value tokens for same entry. Capped at 8. + * If argument implements \ArrayAccess without \Traversable, then key token is restricted to ExactValueToken. + * + * @param array|\ArrayAccess|\Traversable $argument + * + * @throws \Prophecy\Exception\InvalidArgumentException + * @return bool|int + */ + public function scoreArgument($argument) + { + if ($argument instanceof \Traversable) { + $argument = iterator_to_array($argument); + } + + if ($argument instanceof \ArrayAccess) { + $argument = $this->convertArrayAccessToEntry($argument); + } + + if (!is_array($argument) || empty($argument)) { + return false; + } + + $keyScores = array_map(array($this->key,'scoreArgument'), array_keys($argument)); + $valueScores = array_map(array($this->value,'scoreArgument'), $argument); + $scoreEntry = function ($value, $key) { + return $value && $key ? min(8, ($key + $value) / 2) : false; + }; + + return max(array_map($scoreEntry, $valueScores, $keyScores)); + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('[..., %s => %s, ...]', $this->key, $this->value); + } + + /** + * Returns key + * + * @return TokenInterface + */ + public function getKey() + { + return $this->key; + } + + /** + * Returns value + * + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } + + /** + * Wraps non token $value into ExactValueToken + * + * @param $value + * @return TokenInterface + */ + private function wrapIntoExactValueToken($value) + { + return $value instanceof TokenInterface ? $value : new ExactValueToken($value); + } + + /** + * Converts instance of \ArrayAccess to key => value array entry + * + * @param \ArrayAccess $object + * + * @return array|null + * @throws \Prophecy\Exception\InvalidArgumentException + */ + private function convertArrayAccessToEntry(\ArrayAccess $object) + { + if (!$this->key instanceof ExactValueToken) { + throw new InvalidArgumentException(sprintf( + 'You can only use exact value tokens to match key of ArrayAccess object'.PHP_EOL. + 'But you used `%s`.', + $this->key + )); + } + + $key = $this->key->getValue(); + + return $object->offsetExists($key) ? array($key => $object[$key]) : array(); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php new file mode 100644 index 0000000..5d41fa4 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php @@ -0,0 +1,82 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Array every entry token. + * + * @author Adrien Brault + */ +class ArrayEveryEntryToken implements TokenInterface +{ + /** + * @var TokenInterface + */ + private $value; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + if (!$value instanceof TokenInterface) { + $value = new ExactValueToken($value); + } + + $this->value = $value; + } + + /** + * {@inheritdoc} + */ + public function scoreArgument($argument) + { + if (!$argument instanceof \Traversable && !is_array($argument)) { + return false; + } + + $scores = array(); + foreach ($argument as $key => $argumentEntry) { + $scores[] = $this->value->scoreArgument($argumentEntry); + } + + if (empty($scores) || in_array(false, $scores, true)) { + return false; + } + + return array_sum($scores) / count($scores); + } + + /** + * {@inheritdoc} + */ + public function isLast() + { + return false; + } + + /** + * {@inheritdoc} + */ + public function __toString() + { + return sprintf('[%s, ..., %s]', $this->value, $this->value); + } + + /** + * @return TokenInterface + */ + public function getValue() + { + return $this->value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php new file mode 100644 index 0000000..f45ba20 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php @@ -0,0 +1,75 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Callback-verified token. + * + * @author Konstantin Kudryashov + */ +class CallbackToken implements TokenInterface +{ + private $callback; + + /** + * Initializes token. + * + * @param callable $callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackToken, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Scores 7 if callback returns true, false otherwise. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return call_user_func($this->callback, $argument) ? 7 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return 'callback()'; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php new file mode 100644 index 0000000..045a1b9 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php @@ -0,0 +1,118 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Exact value token. + * + * @author Konstantin Kudryashov + */ +class ExactValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct($value, StringUtil $util = null, ComparatorFactory $comparatorFactory = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 10 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && is_object($this->value)) { + $comparator = $this->comparatorFactory->getComparatorFor( + $argument, $this->value + ); + + try { + $comparator->assertEquals($argument, $this->value); + return 10; + } catch (ComparisonFailure $failure) { + return false; + } + } + + // If either one is an object it should be castable to a string + if (is_object($argument) xor is_object($this->value)) { + if (is_object($argument) && !method_exists($argument, '__toString')) { + return false; + } + + if (is_object($this->value) && !method_exists($this->value, '__toString')) { + return false; + } + } elseif (is_numeric($argument) && is_numeric($this->value)) { + // noop + } elseif (gettype($argument) !== gettype($this->value)) { + return false; + } + + return $argument == $this->value ? 10 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('exact(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php new file mode 100644 index 0000000..0b6d23a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php @@ -0,0 +1,74 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Util\StringUtil; + +/** + * Identical value token. + * + * @author Florian Voutzinos + */ +class IdenticalValueToken implements TokenInterface +{ + private $value; + private $string; + private $util; + + /** + * Initializes token. + * + * @param mixed $value + * @param StringUtil $util + */ + public function __construct($value, StringUtil $util = null) + { + $this->value = $value; + $this->util = $util ?: new StringUtil(); + } + + /** + * Scores 11 if argument matches preset value. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return $argument === $this->value ? 11 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + if (null === $this->string) { + $this->string = sprintf('identical(%s)', $this->util->stringify($this->value)); + } + + return $this->string; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/InArrayToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/InArrayToken.php new file mode 100644 index 0000000..f727aea --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/InArrayToken.php @@ -0,0 +1,74 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Check if values is in array + * + * @author Vinícius Alonso + */ +class InArrayToken implements TokenInterface +{ + private $token = array(); + private $strict; + + /** + * @param array $arguments tokens + * @param bool $strict + */ + public function __construct(array $arguments, $strict = true) + { + $this->token = $arguments; + $this->strict = $strict; + } + + /** + * Return scores 8 score if argument is in array. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (count($this->token) === 0) { + return false; + } + + if (\in_array($argument, $this->token, $this->strict)) { + return 8; + } + + return false; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + $arrayAsString = implode(', ', $this->token); + return "[{$arrayAsString}]"; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php new file mode 100644 index 0000000..4ee1b25 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php @@ -0,0 +1,80 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical AND token. + * + * @author Boris Mikhaylov + */ +class LogicalAndToken implements TokenInterface +{ + private $tokens = array(); + + /** + * @param array $arguments exact values or tokens + */ + public function __construct(array $arguments) + { + foreach ($arguments as $argument) { + if (!$argument instanceof TokenInterface) { + $argument = new ExactValueToken($argument); + } + $this->tokens[] = $argument; + } + } + + /** + * Scores maximum score from scores returned by tokens for this argument if all of them score. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (0 === count($this->tokens)) { + return false; + } + + $maxScore = 0; + foreach ($this->tokens as $token) { + $score = $token->scoreArgument($argument); + if (false === $score) { + return false; + } + $maxScore = max($score, $maxScore); + } + + return $maxScore; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('bool(%s)', implode(' AND ', $this->tokens)); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php new file mode 100644 index 0000000..623efa5 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php @@ -0,0 +1,73 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Logical NOT token. + * + * @author Boris Mikhaylov + */ +class LogicalNotToken implements TokenInterface +{ + /** @var \Prophecy\Argument\Token\TokenInterface */ + private $token; + + /** + * @param mixed $value exact value or token + */ + public function __construct($value) + { + $this->token = $value instanceof TokenInterface? $value : new ExactValueToken($value); + } + + /** + * Scores 4 when preset token does not match the argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + return false === $this->token->scoreArgument($argument) ? 4 : false; + } + + /** + * Returns true if preset token is last. + * + * @return bool|int + */ + public function isLast() + { + return $this->token->isLast(); + } + + /** + * Returns originating token. + * + * @return TokenInterface + */ + public function getOriginatingToken() + { + return $this->token; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('not(%s)', $this->token); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/NotInArrayToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/NotInArrayToken.php new file mode 100644 index 0000000..6aed8aa --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/NotInArrayToken.php @@ -0,0 +1,75 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Check if values is not in array + * + * @author Vinícius Alonso + */ +class NotInArrayToken implements TokenInterface +{ + private $token = array(); + private $strict; + + /** + * @param array $arguments tokens + * @param bool $strict + */ + public function __construct(array $arguments, $strict = true) + { + $this->token = $arguments; + $this->strict = $strict; + } + + /** + * Return scores 8 score if argument is in array. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (count($this->token) === 0) { + return false; + } + + if (!\in_array($argument, $this->token, $this->strict)) { + return 8; + } + + return false; + } + + /** + * Returns false. + * + * @return boolean + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + $arrayAsString = implode(', ', $this->token); + return "[{$arrayAsString}]"; + } +} + diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php new file mode 100644 index 0000000..d771077 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php @@ -0,0 +1,104 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Util\StringUtil; + +/** + * Object state-checker token. + * + * @author Konstantin Kudryashov + */ +class ObjectStateToken implements TokenInterface +{ + private $name; + private $value; + private $util; + private $comparatorFactory; + + /** + * Initializes token. + * + * @param string $methodName + * @param mixed $value Expected return value + * @param null|StringUtil $util + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + $methodName, + $value, + StringUtil $util = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->name = $methodName; + $this->value = $value; + $this->util = $util ?: new StringUtil; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Scores 8 if argument is an object, which method returns expected value. + * + * @param mixed $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + if (is_object($argument) && method_exists($argument, $this->name)) { + $actual = call_user_func(array($argument, $this->name)); + + $comparator = $this->comparatorFactory->getComparatorFor( + $this->value, $actual + ); + + try { + $comparator->assertEquals($this->value, $actual); + return 8; + } catch (ComparisonFailure $failure) { + return false; + } + } + + if (is_object($argument) && property_exists($argument, $this->name)) { + return $argument->{$this->name} === $this->value ? 8 : false; + } + + return false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('state(%s(), %s)', + $this->name, + $this->util->stringify($this->value) + ); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php new file mode 100644 index 0000000..bd8d423 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * String contains token. + * + * @author Peter Mitchell + */ +class StringContainsToken implements TokenInterface +{ + private $value; + + /** + * Initializes token. + * + * @param string $value + */ + public function __construct($value) + { + $this->value = $value; + } + + public function scoreArgument($argument) + { + return is_string($argument) && strpos($argument, $this->value) !== false ? 6 : false; + } + + /** + * Returns preset value against which token checks arguments. + * + * @return mixed + */ + public function getValue() + { + return $this->value; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('contains("%s")', $this->value); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php new file mode 100644 index 0000000..625d3ba --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php @@ -0,0 +1,43 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +/** + * Argument token interface. + * + * @author Konstantin Kudryashov + */ +interface TokenInterface +{ + /** + * Calculates token match score for provided argument. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument); + + /** + * Returns true if this token prevents check of other tokens (is last one). + * + * @return bool|int + */ + public function isLast(); + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php new file mode 100644 index 0000000..cb65132 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php @@ -0,0 +1,76 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Argument\Token; + +use Prophecy\Exception\InvalidArgumentException; + +/** + * Value type token. + * + * @author Konstantin Kudryashov + */ +class TypeToken implements TokenInterface +{ + private $type; + + /** + * @param string $type + */ + public function __construct($type) + { + $checker = "is_{$type}"; + if (!function_exists($checker) && !interface_exists($type) && !class_exists($type)) { + throw new InvalidArgumentException(sprintf( + 'Type or class name expected as an argument to TypeToken, but got %s.', $type + )); + } + + $this->type = $type; + } + + /** + * Scores 5 if argument has the same type this token was constructed with. + * + * @param $argument + * + * @return bool|int + */ + public function scoreArgument($argument) + { + $checker = "is_{$this->type}"; + if (function_exists($checker)) { + return call_user_func($checker, $argument) ? 5 : false; + } + + return $argument instanceof $this->type ? 5 : false; + } + + /** + * Returns false. + * + * @return bool + */ + public function isLast() + { + return false; + } + + /** + * Returns string representation for token. + * + * @return string + */ + public function __toString() + { + return sprintf('type(%s)', $this->type); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php new file mode 100644 index 0000000..2652235 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php @@ -0,0 +1,162 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Exception; +use Prophecy\Argument\ArgumentsWildcard; + +/** + * Call object. + * + * @author Konstantin Kudryashov + */ +class Call +{ + private $methodName; + private $arguments; + private $returnValue; + private $exception; + private $file; + private $line; + private $scores; + + /** + * Initializes call. + * + * @param string $methodName + * @param array $arguments + * @param mixed $returnValue + * @param Exception $exception + * @param null|string $file + * @param null|int $line + */ + public function __construct($methodName, array $arguments, $returnValue, + Exception $exception = null, $file, $line) + { + $this->methodName = $methodName; + $this->arguments = $arguments; + $this->returnValue = $returnValue; + $this->exception = $exception; + $this->scores = new \SplObjectStorage(); + + if ($file) { + $this->file = $file; + $this->line = intval($line); + } + } + + /** + * Returns called method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns called method arguments. + * + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * Returns called method return value. + * + * @return null|mixed + */ + public function getReturnValue() + { + return $this->returnValue; + } + + /** + * Returns exception that call thrown. + * + * @return null|Exception + */ + public function getException() + { + return $this->exception; + } + + /** + * Returns callee filename. + * + * @return string + */ + public function getFile() + { + return $this->file; + } + + /** + * Returns callee line number. + * + * @return int + */ + public function getLine() + { + return $this->line; + } + + /** + * Returns short notation for callee place. + * + * @return string + */ + public function getCallPlace() + { + if (null === $this->file) { + return 'unknown'; + } + + return sprintf('%s:%d', $this->file, $this->line); + } + + /** + * Adds the wildcard match score for the provided wildcard. + * + * @param ArgumentsWildcard $wildcard + * @param false|int $score + * + * @return $this + */ + public function addScore(ArgumentsWildcard $wildcard, $score) + { + $this->scores[$wildcard] = $score; + + return $this; + } + + /** + * Returns wildcard match score for the provided wildcard. The score is + * calculated if not already done. + * + * @param ArgumentsWildcard $wildcard + * + * @return false|int False OR integer score (higher - better) + */ + public function getScore(ArgumentsWildcard $wildcard) + { + if (isset($this->scores[$wildcard])) { + return $this->scores[$wildcard]; + } + + return $this->scores[$wildcard] = $wildcard->scoreArguments($this->getArguments()); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php new file mode 100644 index 0000000..00c526d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php @@ -0,0 +1,240 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Call; + +use Prophecy\Exception\Prophecy\MethodProphecyException; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Call\UnexpectedCallException; +use SplObjectStorage; + +/** + * Calls receiver & manager. + * + * @author Konstantin Kudryashov + */ +class CallCenter +{ + private $util; + + /** + * @var Call[] + */ + private $recordedCalls = array(); + + /** + * @var SplObjectStorage + */ + private $unexpectedCalls; + + /** + * Initializes call center. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + $this->unexpectedCalls = new SplObjectStorage(); + } + + /** + * Makes and records specific method call for object prophecy. + * + * @param ObjectProphecy $prophecy + * @param string $methodName + * @param array $arguments + * + * @return mixed Returns null if no promise for prophecy found or promise return value. + * + * @throws \Prophecy\Exception\Call\UnexpectedCallException If no appropriate method prophecy found + */ + public function makeCall(ObjectProphecy $prophecy, $methodName, array $arguments) + { + // For efficiency exclude 'args' from the generated backtrace + // Limit backtrace to last 3 calls as we don't use the rest + $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3); + + $file = $line = null; + if (isset($backtrace[2]) && isset($backtrace[2]['file'])) { + $file = $backtrace[2]['file']; + $line = $backtrace[2]['line']; + } + + // If no method prophecies defined, then it's a dummy, so we'll just return null + if ('__destruct' === strtolower($methodName) || 0 == count($prophecy->getMethodProphecies())) { + $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line); + + return null; + } + + // There are method prophecies, so it's a fake/stub. Searching prophecy for this call + $matches = $this->findMethodProphecies($prophecy, $methodName, $arguments); + + // If fake/stub doesn't have method prophecy for this call - throw exception + if (!count($matches)) { + $this->unexpectedCalls->attach(new Call($methodName, $arguments, null, null, $file, $line), $prophecy); + $this->recordedCalls[] = new Call($methodName, $arguments, null, null, $file, $line); + + return null; + } + + // Sort matches by their score value + @usort($matches, function ($match1, $match2) { return $match2[0] - $match1[0]; }); + + $score = $matches[0][0]; + // If Highest rated method prophecy has a promise - execute it or return null instead + $methodProphecy = $matches[0][1]; + $returnValue = null; + $exception = null; + if ($promise = $methodProphecy->getPromise()) { + try { + $returnValue = $promise->execute($arguments, $prophecy, $methodProphecy); + } catch (\Exception $e) { + $exception = $e; + } + } + + if ($methodProphecy->hasReturnVoid() && $returnValue !== null) { + throw new MethodProphecyException( + "The method \"$methodName\" has a void return type, but the promise returned a value", + $methodProphecy + ); + } + + $this->recordedCalls[] = $call = new Call( + $methodName, $arguments, $returnValue, $exception, $file, $line + ); + $call->addScore($methodProphecy->getArgumentsWildcard(), $score); + + if (null !== $exception) { + throw $exception; + } + + return $returnValue; + } + + /** + * Searches for calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findCalls($methodName, ArgumentsWildcard $wildcard) + { + $methodName = strtolower($methodName); + + return array_values( + array_filter($this->recordedCalls, function (Call $call) use ($methodName, $wildcard) { + return $methodName === strtolower($call->getMethodName()) + && 0 < $call->getScore($wildcard) + ; + }) + ); + } + + /** + * @throws UnexpectedCallException + */ + public function checkUnexpectedCalls() + { + /** @var Call $call */ + foreach ($this->unexpectedCalls as $call) { + $prophecy = $this->unexpectedCalls[$call]; + + // If fake/stub doesn't have method prophecy for this call - throw exception + if (!count($this->findMethodProphecies($prophecy, $call->getMethodName(), $call->getArguments()))) { + throw $this->createUnexpectedCallException($prophecy, $call->getMethodName(), $call->getArguments()); + } + } + } + + private function createUnexpectedCallException(ObjectProphecy $prophecy, $methodName, + array $arguments) + { + $classname = get_class($prophecy->reveal()); + $indentationLength = 8; // looks good + $argstring = implode( + ",\n", + $this->indentArguments( + array_map(array($this->util, 'stringify'), $arguments), + $indentationLength + ) + ); + + $expected = array(); + + foreach (array_merge(...array_values($prophecy->getMethodProphecies())) as $methodProphecy) { + $expected[] = sprintf( + " - %s(\n" . + "%s\n" . + " )", + $methodProphecy->getMethodName(), + implode( + ",\n", + $this->indentArguments( + array_map('strval', $methodProphecy->getArgumentsWildcard()->getTokens()), + $indentationLength + ) + ) + ); + } + + return new UnexpectedCallException( + sprintf( + "Unexpected method call on %s:\n". + " - %s(\n". + "%s\n". + " )\n". + "expected calls were:\n". + "%s", + + $classname, $methodName, $argstring, implode("\n", $expected) + ), + $prophecy, $methodName, $arguments + + ); + } + + private function indentArguments(array $arguments, $indentationLength) + { + return preg_replace_callback( + '/^/m', + function () use ($indentationLength) { + return str_repeat(' ', $indentationLength); + }, + $arguments + ); + } + + /** + * @param ObjectProphecy $prophecy + * @param string $methodName + * @param array $arguments + * + * @return array + */ + private function findMethodProphecies(ObjectProphecy $prophecy, $methodName, array $arguments) + { + $matches = array(); + foreach ($prophecy->getMethodProphecies($methodName) as $methodProphecy) { + if (0 < $score = $methodProphecy->getArgumentsWildcard()->scoreArguments($arguments)) { + $matches[] = array($score, $methodProphecy); + } + } + + return $matches; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php new file mode 100644 index 0000000..fa4f578 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php @@ -0,0 +1,44 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Closure comparator. + * + * @author Konstantin Kudryashov + */ +final class ClosureComparator extends Comparator +{ + public function accepts($expected, $actual) + { + return is_object($expected) && $expected instanceof \Closure + && is_object($actual) && $actual instanceof \Closure; + } + + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) + { + if ($expected !== $actual) { + throw new ComparisonFailure( + $expected, + $actual, + // we don't need a diff + '', + '', + false, + 'all closures are different if not identical' + ); + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php new file mode 100644 index 0000000..2070db1 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php @@ -0,0 +1,47 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use SebastianBergmann\Comparator\Factory as BaseFactory; + +/** + * Prophecy comparator factory. + * + * @author Konstantin Kudryashov + */ +final class Factory extends BaseFactory +{ + /** + * @var Factory + */ + private static $instance; + + public function __construct() + { + parent::__construct(); + + $this->register(new ClosureComparator()); + $this->register(new ProphecyComparator()); + } + + /** + * @return Factory + */ + public static function getInstance() + { + if (self::$instance === null) { + self::$instance = new Factory; + } + + return self::$instance; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php new file mode 100644 index 0000000..298a8e3 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php @@ -0,0 +1,28 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Comparator; + +use Prophecy\Prophecy\ProphecyInterface; +use SebastianBergmann\Comparator\ObjectComparator; + +class ProphecyComparator extends ObjectComparator +{ + public function accepts($expected, $actual) + { + return is_object($expected) && is_object($actual) && $actual instanceof ProphecyInterface; + } + + public function assertEquals($expected, $actual, $delta = 0.0, $canonicalize = false, $ignoreCase = false, array &$processed = array()) + { + parent::assertEquals($expected, $actual->reveal(), $delta, $canonicalize, $ignoreCase, $processed); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php new file mode 100644 index 0000000..2b87521 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php @@ -0,0 +1,66 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class CachedDoubler extends Doubler +{ + private static $classes = array(); + + /** + * {@inheritdoc} + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $classId = $this->generateClassId($class, $interfaces); + if (isset(self::$classes[$classId])) { + return self::$classes[$classId]; + } + + return self::$classes[$classId] = parent::createDoubleClass($class, $interfaces); + } + + /** + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + private function generateClassId(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + if (null !== $class) { + $parts[] = $class->getName(); + } + foreach ($interfaces as $interface) { + $parts[] = $interface->getName(); + } + foreach ($this->getClassPatches() as $patch) { + $parts[] = get_class($patch); + } + sort($parts); + + return md5(implode('', $parts)); + } + + public function resetCache() + { + self::$classes = array(); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php new file mode 100644 index 0000000..d6d1968 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php @@ -0,0 +1,48 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Class patch interface. + * Class patches extend doubles functionality or help + * Prophecy to avoid some internal PHP bugs. + * + * @author Konstantin Kudryashov + */ +interface ClassPatchInterface +{ + /** + * Checks if patch supports specific class node. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node); + + /** + * Applies patch to the specific class node. + * + * @param ClassNode $node + * @return void + */ + public function apply(ClassNode $node); + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php new file mode 100644 index 0000000..9d84309 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php @@ -0,0 +1,76 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Disable constructor. + * Makes all constructor arguments optional. + * + * @author Konstantin Kudryashov + */ +class DisableConstructorPatch implements ClassPatchInterface +{ + /** + * Checks if class has `__construct` method. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Makes all class constructor arguments optional. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if (!$node->isExtendable('__construct')) { + return; + } + + if (!$node->hasMethod('__construct')) { + $node->addMethod(new MethodNode('__construct', '')); + + return; + } + + $constructor = $node->getMethod('__construct'); + foreach ($constructor->getArguments() as $argument) { + $argument->setDefault(null); + } + + $constructor->setCode(<< + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Exception patch for HHVM to remove the stubs from special methods + * + * @author Christophe Coevoet + */ +class HhvmExceptionPatch implements ClassPatchInterface +{ + /** + * Supports exceptions on HHVM. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (!defined('HHVM_VERSION')) { + return false; + } + + return 'Exception' === $node->getParentClass() || is_subclass_of($node->getParentClass(), 'Exception'); + } + + /** + * Removes special exception static methods from the doubled methods. + * + * @param ClassNode $node + * + * @return void + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('setTraceOptions')) { + $node->getMethod('setTraceOptions')->useParentCode(); + } + if ($node->hasMethod('getTraceOptions')) { + $node->getMethod('getTraceOptions')->useParentCode(); + } + } + + /** + * {@inheritdoc} + */ + public function getPriority() + { + return -50; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php new file mode 100644 index 0000000..ab99f74 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * Remove method functionality from the double which will clash with php keywords. + * + * @author Milan Magudia + */ +class KeywordPatch implements ClassPatchInterface +{ + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Remove methods that clash with php keywords + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $methodNames = array_keys($node->getMethods()); + $methodsToRemove = array_intersect($methodNames, $this->getKeywords()); + foreach ($methodsToRemove as $methodName) { + $node->removeMethod($methodName); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 49; + } + + /** + * Returns array of php keywords. + * + * @return array + */ + private function getKeywords() + { + return ['__halt_compiler']; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php new file mode 100644 index 0000000..9ff49cd --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php @@ -0,0 +1,94 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; +use Prophecy\PhpDocumentor\ClassAndInterfaceTagRetriever; +use Prophecy\PhpDocumentor\MethodTagRetrieverInterface; + +/** + * Discover Magical API using "@method" PHPDoc format. + * + * @author Thomas Tourlourat + * @author Kévin Dunglas + * @author Théo FIDRY + */ +class MagicCallPatch implements ClassPatchInterface +{ + private $tagRetriever; + + public function __construct(MethodTagRetrieverInterface $tagRetriever = null) + { + $this->tagRetriever = null === $tagRetriever ? new ClassAndInterfaceTagRetriever() : $tagRetriever; + } + + /** + * Support any class + * + * @param ClassNode $node + * + * @return boolean + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Discover Magical API + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $types = array_filter($node->getInterfaces(), function ($interface) { + return 0 !== strpos($interface, 'Prophecy\\'); + }); + $types[] = $node->getParentClass(); + + foreach ($types as $type) { + $reflectionClass = new \ReflectionClass($type); + + while ($reflectionClass) { + $tagList = $this->tagRetriever->getTagList($reflectionClass); + + foreach ($tagList as $tag) { + $methodName = $tag->getMethodName(); + + if (empty($methodName)) { + continue; + } + + if (!$reflectionClass->hasMethod($methodName)) { + $methodNode = new MethodNode($methodName); + $methodNode->setStatic($tag->isStatic()); + $node->addMethod($methodNode); + } + } + + $reflectionClass = $reflectionClass->getParentClass(); + } + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return integer Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } +} + diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php new file mode 100644 index 0000000..b41ebaa --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php @@ -0,0 +1,113 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ArgumentTypeNode; +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; +use Prophecy\Doubler\Generator\Node\ArgumentNode; +use Prophecy\Doubler\Generator\Node\ReturnTypeNode; + +/** + * Add Prophecy functionality to the double. + * This is a core class patch for Prophecy. + * + * @author Konstantin Kudryashov + */ +class ProphecySubjectPatch implements ClassPatchInterface +{ + /** + * Always returns true. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return true; + } + + /** + * Apply Prophecy functionality to class node. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Prophecy\Prophecy\ProphecySubjectInterface'); + $node->addProperty('objectProphecyClosure', 'private'); + + foreach ($node->getMethods() as $name => $method) { + if ('__construct' === strtolower($name)) { + continue; + } + + if ($method->getReturnTypeNode()->isVoid()) { + $method->setCode( + '$this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());' + ); + } else { + $method->setCode( + 'return $this->getProphecy()->makeProphecyMethodCall(__FUNCTION__, func_get_args());' + ); + } + } + + $prophecySetter = new MethodNode('setProphecy'); + $prophecyArgument = new ArgumentNode('prophecy'); + $prophecyArgument->setTypeNode(new ArgumentTypeNode('Prophecy\Prophecy\ProphecyInterface')); + $prophecySetter->addArgument($prophecyArgument); + $prophecySetter->setCode(<<objectProphecyClosure) { + \$this->objectProphecyClosure = static function () use (\$prophecy) { + return \$prophecy; + }; +} +PHP + ); + + $prophecyGetter = new MethodNode('getProphecy'); + $prophecyGetter->setCode('return \call_user_func($this->objectProphecyClosure);'); + + if ($node->hasMethod('__call')) { + $__call = $node->getMethod('__call'); + } else { + $__call = new MethodNode('__call'); + $__call->addArgument(new ArgumentNode('name')); + $__call->addArgument(new ArgumentNode('arguments')); + + $node->addMethod($__call, true); + } + + $__call->setCode(<<getProphecy(), func_get_arg(0) +); +PHP + ); + + $node->addMethod($prophecySetter, true); + $node->addMethod($prophecyGetter, true); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 0; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php new file mode 100644 index 0000000..9166aee --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php @@ -0,0 +1,57 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +/** + * ReflectionClass::newInstance patch. + * Makes first argument of newInstance optional, since it works but signature is misleading + * + * @author Florian Klein + */ +class ReflectionClassNewInstancePatch implements ClassPatchInterface +{ + /** + * Supports ReflectionClass + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + return 'ReflectionClass' === $node->getParentClass(); + } + + /** + * Updates newInstance's first argument to make it optional + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + foreach ($node->getMethod('newInstance')->getArguments() as $argument) { + $argument->setDefault(null); + } + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher = earlier) + */ + public function getPriority() + { + return 50; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php new file mode 100644 index 0000000..ceee94a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php @@ -0,0 +1,123 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * SplFileInfo patch. + * Makes SplFileInfo and derivative classes usable with Prophecy. + * + * @author Konstantin Kudryashov + */ +class SplFileInfoPatch implements ClassPatchInterface +{ + /** + * Supports everything that extends SplFileInfo. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (null === $node->getParentClass()) { + return false; + } + return 'SplFileInfo' === $node->getParentClass() + || is_subclass_of($node->getParentClass(), 'SplFileInfo') + ; + } + + /** + * Updated constructor code to call parent one with dummy file argument. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + if ($node->hasMethod('__construct')) { + $constructor = $node->getMethod('__construct'); + } else { + $constructor = new MethodNode('__construct'); + $node->addMethod($constructor); + } + + if ($this->nodeIsDirectoryIterator($node)) { + $constructor->setCode('return parent::__construct("' . __DIR__ . '");'); + + return; + } + + if ($this->nodeIsSplFileObject($node)) { + $filePath = str_replace('\\','\\\\',__FILE__); + $constructor->setCode('return parent::__construct("' . $filePath .'");'); + + return; + } + + if ($this->nodeIsSymfonySplFileInfo($node)) { + $filePath = str_replace('\\','\\\\',__FILE__); + $constructor->setCode('return parent::__construct("' . $filePath .'", "", "");'); + + return; + } + + $constructor->useParentCode(); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 50; + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsDirectoryIterator(ClassNode $node) + { + $parent = $node->getParentClass(); + + return 'DirectoryIterator' === $parent + || is_subclass_of($parent, 'DirectoryIterator'); + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsSplFileObject(ClassNode $node) + { + $parent = $node->getParentClass(); + + return 'SplFileObject' === $parent + || is_subclass_of($parent, 'SplFileObject'); + } + + /** + * @param ClassNode $node + * @return boolean + */ + private function nodeIsSymfonySplFileInfo(ClassNode $node) + { + $parent = $node->getParentClass(); + + return 'Symfony\\Component\\Finder\\SplFileInfo' === $parent; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php new file mode 100644 index 0000000..b98e943 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php @@ -0,0 +1,95 @@ +implementsAThrowableInterface($node) && $this->doesNotExtendAThrowableClass($node); + } + + /** + * @param ClassNode $node + * @return bool + */ + private function implementsAThrowableInterface(ClassNode $node) + { + foreach ($node->getInterfaces() as $type) { + if (is_a($type, 'Throwable', true)) { + return true; + } + } + + return false; + } + + /** + * @param ClassNode $node + * @return bool + */ + private function doesNotExtendAThrowableClass(ClassNode $node) + { + return !is_a($node->getParentClass(), 'Throwable', true); + } + + /** + * Applies patch to the specific class node. + * + * @param ClassNode $node + * + * @return void + */ + public function apply(ClassNode $node) + { + $this->checkItCanBeDoubled($node); + $this->setParentClassToException($node); + } + + private function checkItCanBeDoubled(ClassNode $node) + { + $className = $node->getParentClass(); + if ($className !== 'stdClass') { + throw new ClassCreatorException( + sprintf( + 'Cannot double concrete class %s as well as implement Traversable', + $className + ), + $node + ); + } + } + + private function setParentClassToException(ClassNode $node) + { + $node->setParentClass('Exception'); + + $node->removeMethod('getMessage'); + $node->removeMethod('getCode'); + $node->removeMethod('getFile'); + $node->removeMethod('getLine'); + $node->removeMethod('getTrace'); + $node->removeMethod('getPrevious'); + $node->removeMethod('getNext'); + $node->removeMethod('getTraceAsString'); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 100; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php new file mode 100644 index 0000000..eea0202 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php @@ -0,0 +1,83 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\ClassPatch; + +use Prophecy\Doubler\Generator\Node\ClassNode; +use Prophecy\Doubler\Generator\Node\MethodNode; + +/** + * Traversable interface patch. + * Forces classes that implement interfaces, that extend Traversable to also implement Iterator. + * + * @author Konstantin Kudryashov + */ +class TraversablePatch implements ClassPatchInterface +{ + /** + * Supports nodetree, that implement Traversable, but not Iterator or IteratorAggregate. + * + * @param ClassNode $node + * + * @return bool + */ + public function supports(ClassNode $node) + { + if (in_array('Iterator', $node->getInterfaces())) { + return false; + } + if (in_array('IteratorAggregate', $node->getInterfaces())) { + return false; + } + + foreach ($node->getInterfaces() as $interface) { + if ('Traversable' !== $interface && !is_subclass_of($interface, 'Traversable')) { + continue; + } + if ('Iterator' === $interface || is_subclass_of($interface, 'Iterator')) { + continue; + } + if ('IteratorAggregate' === $interface || is_subclass_of($interface, 'IteratorAggregate')) { + continue; + } + + return true; + } + + return false; + } + + /** + * Forces class to implement Iterator interface. + * + * @param ClassNode $node + */ + public function apply(ClassNode $node) + { + $node->addInterface('Iterator'); + + $node->addMethod(new MethodNode('current')); + $node->addMethod(new MethodNode('key')); + $node->addMethod(new MethodNode('next')); + $node->addMethod(new MethodNode('rewind')); + $node->addMethod(new MethodNode('valid')); + } + + /** + * Returns patch priority, which determines when patch will be applied. + * + * @return int Priority number (higher - earlier) + */ + public function getPriority() + { + return 100; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php new file mode 100644 index 0000000..699be3a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +/** + * Core double interface. + * All doubled classes will implement this one. + * + * @author Konstantin Kudryashov + */ +interface DoubleInterface +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php new file mode 100644 index 0000000..a378ae2 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php @@ -0,0 +1,146 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Doubler\ClassPatch\ClassPatchInterface; +use Prophecy\Doubler\Generator\ClassMirror; +use Prophecy\Doubler\Generator\ClassCreator; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Cached class doubler. + * Prevents mirroring/creation of the same structure twice. + * + * @author Konstantin Kudryashov + */ +class Doubler +{ + private $mirror; + private $creator; + private $namer; + + /** + * @var ClassPatchInterface[] + */ + private $patches = array(); + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes doubler. + * + * @param ClassMirror $mirror + * @param ClassCreator $creator + * @param NameGenerator $namer + */ + public function __construct(ClassMirror $mirror = null, ClassCreator $creator = null, + NameGenerator $namer = null) + { + $this->mirror = $mirror ?: new ClassMirror; + $this->creator = $creator ?: new ClassCreator; + $this->namer = $namer ?: new NameGenerator; + } + + /** + * Returns list of registered class patches. + * + * @return ClassPatchInterface[] + */ + public function getClassPatches() + { + return $this->patches; + } + + /** + * Registers new class patch. + * + * @param ClassPatchInterface $patch + */ + public function registerClassPatch(ClassPatchInterface $patch) + { + $this->patches[] = $patch; + + @usort($this->patches, function (ClassPatchInterface $patch1, ClassPatchInterface $patch2) { + return $patch2->getPriority() - $patch1->getPriority(); + }); + } + + /** + * Creates double from specific class or/and list of interfaces. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces Array of ReflectionClass instances + * @param array $args Constructor arguments + * + * @return DoubleInterface + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function double(ReflectionClass $class = null, array $interfaces, array $args = null) + { + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `Doubler::double(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + } + + $classname = $this->createDoubleClass($class, $interfaces); + $reflection = new ReflectionClass($classname); + + if (null !== $args) { + return $reflection->newInstanceArgs($args); + } + if ((null === $constructor = $reflection->getConstructor()) + || ($constructor->isPublic() && !$constructor->isFinal())) { + return $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + return $this->instantiator->instantiate($classname); + } + + /** + * Creates double class and returns its FQN. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + protected function createDoubleClass(ReflectionClass $class = null, array $interfaces) + { + $name = $this->namer->name($class, $interfaces); + $node = $this->mirror->reflect($class, $interfaces); + + foreach ($this->patches as $patch) { + if ($patch->supports($node)) { + $patch->apply($node); + } + } + + $this->creator->create($name, $node); + + return $name; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php new file mode 100644 index 0000000..52e5e04 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php @@ -0,0 +1,110 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Doubler\Generator\Node\ReturnTypeNode; +use Prophecy\Doubler\Generator\Node\TypeNodeAbstract; + +/** + * Class code creator. + * Generates PHP code for specific class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassCodeGenerator +{ + public function __construct(TypeHintReference $typeHintReference = null) + { + } + + /** + * Generates PHP code for class node. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return string + */ + public function generate($classname, Node\ClassNode $class) + { + $parts = explode('\\', $classname); + $classname = array_pop($parts); + $namespace = implode('\\', $parts); + + $code = sprintf("class %s extends \%s implements %s {\n", + $classname, $class->getParentClass(), implode(', ', + array_map(function ($interface) {return '\\'.$interface;}, $class->getInterfaces()) + ) + ); + + foreach ($class->getProperties() as $name => $visibility) { + $code .= sprintf("%s \$%s;\n", $visibility, $name); + } + $code .= "\n"; + + foreach ($class->getMethods() as $method) { + $code .= $this->generateMethod($method)."\n"; + } + $code .= "\n}"; + + return sprintf("namespace %s {\n%s\n}", $namespace, $code); + } + + private function generateMethod(Node\MethodNode $method) + { + $php = sprintf("%s %s function %s%s(%s)%s {\n", + $method->getVisibility(), + $method->isStatic() ? 'static' : '', + $method->returnsReference() ? '&':'', + $method->getName(), + implode(', ', $this->generateArguments($method->getArguments())), + ($ret = $this->generateTypes($method->getReturnTypeNode())) ? ': '.$ret : '' + ); + $php .= $method->getCode()."\n"; + + return $php.'}'; + } + + private function generateTypes(TypeNodeAbstract $typeNode): string + { + if (!$typeNode->getTypes()) { + return ''; + } + + // When we require PHP 8 we can stop generating ?foo nullables and remove this first block + if ($typeNode->canUseNullShorthand()) { + return sprintf( '?%s', $typeNode->getNonNullTypes()[0]); + } else { + return join('|', $typeNode->getTypes()); + } + } + + private function generateArguments(array $arguments) + { + return array_map(function (Node\ArgumentNode $argument){ + + $php = $this->generateTypes($argument->getTypeNode()); + + $php .= ' '.($argument->isPassedByReference() ? '&' : ''); + + $php .= $argument->isVariadic() ? '...' : ''; + + $php .= '$'.$argument->getName(); + + if ($argument->isOptional() && !$argument->isVariadic()) { + $php .= ' = '.var_export($argument->getDefault(), true); + } + + return $php; + }, $arguments); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php new file mode 100644 index 0000000..882a4a4 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php @@ -0,0 +1,67 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Exception\Doubler\ClassCreatorException; + +/** + * Class creator. + * Creates specific class in current environment. + * + * @author Konstantin Kudryashov + */ +class ClassCreator +{ + private $generator; + + /** + * Initializes creator. + * + * @param ClassCodeGenerator $generator + */ + public function __construct(ClassCodeGenerator $generator = null) + { + $this->generator = $generator ?: new ClassCodeGenerator; + } + + /** + * Creates class. + * + * @param string $classname + * @param Node\ClassNode $class + * + * @return mixed + * + * @throws \Prophecy\Exception\Doubler\ClassCreatorException + */ + public function create($classname, Node\ClassNode $class) + { + $code = $this->generator->generate($classname, $class); + $return = eval($code); + + if (!class_exists($classname, false)) { + if (count($class->getInterfaces())) { + throw new ClassCreatorException(sprintf( + 'Could not double `%s` and implement interfaces: [%s].', + $class->getParentClass(), implode(', ', $class->getInterfaces()) + ), $class); + } + + throw new ClassCreatorException( + sprintf('Could not double `%s`.', $class->getParentClass()), + $class + ); + } + + return $return; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php new file mode 100644 index 0000000..6b21623 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php @@ -0,0 +1,243 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +use Prophecy\Doubler\Generator\Node\ArgumentTypeNode; +use Prophecy\Doubler\Generator\Node\ReturnTypeNode; +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Doubler\ClassMirrorException; +use ReflectionClass; +use ReflectionMethod; +use ReflectionNamedType; +use ReflectionParameter; +use ReflectionType; +use ReflectionUnionType; + +/** + * Class mirror. + * Core doubler class. Mirrors specific class and/or interfaces into class node tree. + * + * @author Konstantin Kudryashov + */ +class ClassMirror +{ + private static $reflectableMethods = array( + '__construct', + '__destruct', + '__sleep', + '__wakeup', + '__toString', + '__call', + '__invoke' + ); + + /** + * Reflects provided arguments into class node. + * + * @param ReflectionClass|null $class + * @param ReflectionClass[] $interfaces + * + * @return Node\ClassNode + * + */ + public function reflect(?ReflectionClass $class, array $interfaces) + { + $node = new Node\ClassNode; + + if (null !== $class) { + if (true === $class->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as a class, because it\n". + "is interface - use the second argument instead.", + $class->getName() + )); + } + + $this->reflectClassToNode($class, $node); + } + + foreach ($interfaces as $interface) { + if (!$interface instanceof ReflectionClass) { + throw new InvalidArgumentException(sprintf( + "[ReflectionClass \$interface1 [, ReflectionClass \$interface2]] array expected as\n". + "a second argument to `ClassMirror::reflect(...)`, but got %s.", + is_object($interface) ? get_class($interface).' class' : gettype($interface) + )); + } + if (false === $interface->isInterface()) { + throw new InvalidArgumentException(sprintf( + "Could not reflect %s as an interface, because it\n". + "is class - use the first argument instead.", + $interface->getName() + )); + } + + $this->reflectInterfaceToNode($interface, $node); + } + + $node->addInterface('Prophecy\Doubler\Generator\ReflectionInterface'); + + return $node; + } + + private function reflectClassToNode(ReflectionClass $class, Node\ClassNode $node) + { + if (true === $class->isFinal()) { + throw new ClassMirrorException(sprintf( + 'Could not reflect class %s as it is marked final.', $class->getName() + ), $class); + } + + $node->setParentClass($class->getName()); + + foreach ($class->getMethods(ReflectionMethod::IS_ABSTRACT) as $method) { + if (false === $method->isProtected()) { + continue; + } + + $this->reflectMethodToNode($method, $node); + } + + foreach ($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) { + if (0 === strpos($method->getName(), '_') + && !in_array($method->getName(), self::$reflectableMethods)) { + continue; + } + + if (true === $method->isFinal()) { + $node->addUnextendableMethod($method->getName()); + continue; + } + + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectInterfaceToNode(ReflectionClass $interface, Node\ClassNode $node) + { + $node->addInterface($interface->getName()); + + foreach ($interface->getMethods() as $method) { + $this->reflectMethodToNode($method, $node); + } + } + + private function reflectMethodToNode(ReflectionMethod $method, Node\ClassNode $classNode) + { + $node = new Node\MethodNode($method->getName()); + + if (true === $method->isProtected()) { + $node->setVisibility('protected'); + } + + if (true === $method->isStatic()) { + $node->setStatic(); + } + + if (true === $method->returnsReference()) { + $node->setReturnsReference(); + } + + if ($method->hasReturnType()) { + $returnTypes = $this->getTypeHints($method->getReturnType(), $method->getDeclaringClass(), $method->getReturnType()->allowsNull()); + $node->setReturnTypeNode(new ReturnTypeNode(...$returnTypes)); + } + + if (is_array($params = $method->getParameters()) && count($params)) { + foreach ($params as $param) { + $this->reflectArgumentToNode($param, $node); + } + } + + $classNode->addMethod($node); + } + + private function reflectArgumentToNode(ReflectionParameter $parameter, Node\MethodNode $methodNode) + { + $name = $parameter->getName() == '...' ? '__dot_dot_dot__' : $parameter->getName(); + $node = new Node\ArgumentNode($name); + + $typeHints = $this->getTypeHints($parameter->getType(), $parameter->getDeclaringClass(), $parameter->allowsNull()); + + $node->setTypeNode(new ArgumentTypeNode(...$typeHints)); + + if ($parameter->isVariadic()) { + $node->setAsVariadic(); + } + + if ($this->hasDefaultValue($parameter)) { + $node->setDefault($this->getDefaultValue($parameter)); + } + + if ($parameter->isPassedByReference()) { + $node->setAsPassedByReference(); + } + + + $methodNode->addArgument($node); + } + + private function hasDefaultValue(ReflectionParameter $parameter) + { + if ($parameter->isVariadic()) { + return false; + } + + if ($parameter->isDefaultValueAvailable()) { + return true; + } + + return $parameter->isOptional() || ($parameter->allowsNull() && $parameter->getType()); + } + + private function getDefaultValue(ReflectionParameter $parameter) + { + if (!$parameter->isDefaultValueAvailable()) { + return null; + } + + return $parameter->getDefaultValue(); + } + + private function getTypeHints(?ReflectionType $type, ?ReflectionClass $class, bool $allowsNull) : array + { + $types = []; + + if ($type instanceof ReflectionNamedType) { + $types = [$type->getName()]; + + } + elseif ($type instanceof ReflectionUnionType) { + $types = $type->getTypes(); + } + + $types = array_map( + function(string $type) use ($class) { + if ($type === 'self') { + return $class->getName(); + } + if ($type === 'parent') { + return $class->getParentClass()->getName(); + } + + return $type; + }, + $types + ); + + if ($types && $types != ['mixed'] && $allowsNull) { + $types[] = 'null'; + } + + return $types; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php new file mode 100644 index 0000000..da7fed4 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php @@ -0,0 +1,133 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +/** + * Argument node. + * + * @author Konstantin Kudryashov + */ +class ArgumentNode +{ + private $name; + private $default; + private $optional = false; + private $byReference = false; + private $isVariadic = false; + + /** @var ArgumentTypeNode */ + private $typeNode; + + /** + * @param string $name + */ + public function __construct($name) + { + $this->name = $name; + $this->typeNode = new ArgumentTypeNode(); + } + + public function getName() + { + return $this->name; + } + + public function setTypeNode(ArgumentTypeNode $typeNode) + { + $this->typeNode = $typeNode; + } + + public function getTypeNode() : ArgumentTypeNode + { + return $this->typeNode; + } + + public function hasDefault() + { + return $this->isOptional() && !$this->isVariadic(); + } + + public function getDefault() + { + return $this->default; + } + + public function setDefault($default = null) + { + $this->optional = true; + $this->default = $default; + } + + public function isOptional() + { + return $this->optional; + } + + public function setAsPassedByReference($byReference = true) + { + $this->byReference = $byReference; + } + + public function isPassedByReference() + { + return $this->byReference; + } + + public function setAsVariadic($isVariadic = true) + { + $this->isVariadic = $isVariadic; + } + + public function isVariadic() + { + return $this->isVariadic; + } + + /** + * @deprecated use getArgumentTypeNode instead + * @return string|null + */ + public function getTypeHint() + { + $type = $this->typeNode->getNonNullTypes() ? $this->typeNode->getNonNullTypes()[0] : null; + + return $type ? ltrim($type, '\\') : null; + } + + /** + * @deprecated use setArgumentTypeNode instead + * @param string|null $typeHint + */ + public function setTypeHint($typeHint = null) + { + $this->typeNode = ($typeHint === null) ? new ArgumentTypeNode() : new ArgumentTypeNode($typeHint); + } + + /** + * @deprecated use getArgumentTypeNode instead + * @return bool + */ + public function isNullable() + { + return $this->typeNode->canUseNullShorthand(); + } + + /** + * @deprecated use getArgumentTypeNode instead + * @param bool $isNullable + */ + public function setAsNullable($isNullable = true) + { + $nonNullTypes = $this->typeNode->getNonNullTypes(); + $this->typeNode = $isNullable ? new ArgumentTypeNode('null', ...$nonNullTypes) : new ArgumentTypeNode(...$nonNullTypes); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentTypeNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentTypeNode.php new file mode 100644 index 0000000..0a18b91 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentTypeNode.php @@ -0,0 +1,10 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Exception\Doubler\MethodNotExtendableException; +use Prophecy\Exception\InvalidArgumentException; + +/** + * Class node. + * + * @author Konstantin Kudryashov + */ +class ClassNode +{ + private $parentClass = 'stdClass'; + private $interfaces = array(); + private $properties = array(); + private $unextendableMethods = array(); + + /** + * @var MethodNode[] + */ + private $methods = array(); + + public function getParentClass() + { + return $this->parentClass; + } + + /** + * @param string $class + */ + public function setParentClass($class) + { + $this->parentClass = $class ?: 'stdClass'; + } + + /** + * @return string[] + */ + public function getInterfaces() + { + return $this->interfaces; + } + + /** + * @param string $interface + */ + public function addInterface($interface) + { + if ($this->hasInterface($interface)) { + return; + } + + array_unshift($this->interfaces, $interface); + } + + /** + * @param string $interface + * + * @return bool + */ + public function hasInterface($interface) + { + return in_array($interface, $this->interfaces); + } + + public function getProperties() + { + return $this->properties; + } + + public function addProperty($name, $visibility = 'public') + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` property visibility is not supported.', $visibility + )); + } + + $this->properties[$name] = $visibility; + } + + /** + * @return MethodNode[] + */ + public function getMethods() + { + return $this->methods; + } + + public function addMethod(MethodNode $method, $force = false) + { + if (!$this->isExtendable($method->getName())){ + $message = sprintf( + 'Method `%s` is not extendable, so can not be added.', $method->getName() + ); + throw new MethodNotExtendableException($message, $this->getParentClass(), $method->getName()); + } + + if ($force || !isset($this->methods[$method->getName()])) { + $this->methods[$method->getName()] = $method; + } + } + + public function removeMethod($name) + { + unset($this->methods[$name]); + } + + /** + * @param string $name + * + * @return MethodNode|null + */ + public function getMethod($name) + { + return $this->hasMethod($name) ? $this->methods[$name] : null; + } + + /** + * @param string $name + * + * @return bool + */ + public function hasMethod($name) + { + return isset($this->methods[$name]); + } + + /** + * @return string[] + */ + public function getUnextendableMethods() + { + return $this->unextendableMethods; + } + + /** + * @param string $unextendableMethod + */ + public function addUnextendableMethod($unextendableMethod) + { + if (!$this->isExtendable($unextendableMethod)){ + return; + } + $this->unextendableMethods[] = $unextendableMethod; + } + + /** + * @param string $method + * @return bool + */ + public function isExtendable($method) + { + return !in_array($method, $this->unextendableMethods); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php new file mode 100644 index 0000000..ece652f --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php @@ -0,0 +1,210 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator\Node; + +use Prophecy\Doubler\Generator\TypeHintReference; +use Prophecy\Exception\InvalidArgumentException; + +/** + * Method node. + * + * @author Konstantin Kudryashov + */ +class MethodNode +{ + private $name; + private $code; + private $visibility = 'public'; + private $static = false; + private $returnsReference = false; + + /** @var ReturnTypeNode */ + private $returnTypeNode; + + /** + * @var ArgumentNode[] + */ + private $arguments = array(); + + /** + * @param string $name + * @param string $code + */ + public function __construct($name, $code = null, TypeHintReference $typeHintReference = null) + { + $this->name = $name; + $this->code = $code; + $this->returnTypeNode = new ReturnTypeNode(); + } + + public function getVisibility() + { + return $this->visibility; + } + + /** + * @param string $visibility + */ + public function setVisibility($visibility) + { + $visibility = strtolower($visibility); + + if (!in_array($visibility, array('public', 'private', 'protected'))) { + throw new InvalidArgumentException(sprintf( + '`%s` method visibility is not supported.', $visibility + )); + } + + $this->visibility = $visibility; + } + + public function isStatic() + { + return $this->static; + } + + public function setStatic($static = true) + { + $this->static = (bool) $static; + } + + public function returnsReference() + { + return $this->returnsReference; + } + + public function setReturnsReference() + { + $this->returnsReference = true; + } + + public function getName() + { + return $this->name; + } + + public function addArgument(ArgumentNode $argument) + { + $this->arguments[] = $argument; + } + + /** + * @return ArgumentNode[] + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * @deprecated use getReturnTypeNode instead + * @return bool + */ + public function hasReturnType() + { + return (bool) $this->returnTypeNode->getNonNullTypes(); + } + + public function setReturnTypeNode(ReturnTypeNode $returnTypeNode): void + { + $this->returnTypeNode = $returnTypeNode; + } + + /** + * @deprecated use setReturnTypeNode instead + * @param string $type + */ + public function setReturnType($type = null) + { + $this->returnTypeNode = ($type === '' || $type === null) ? new ReturnTypeNode() : new ReturnTypeNode($type); + } + + /** + * @deprecated use setReturnTypeNode instead + * @param bool $bool + */ + public function setNullableReturnType($bool = true) + { + if ($bool) { + $this->returnTypeNode = new ReturnTypeNode('null', ...$this->returnTypeNode->getTypes()); + } + else { + $this->returnTypeNode = new ReturnTypeNode(...$this->returnTypeNode->getNonNullTypes()); + } + } + + /** + * @deprecated use getReturnTypeNode instead + * @return string|null + */ + public function getReturnType() + { + if ($types = $this->returnTypeNode->getNonNullTypes()) + { + return $types[0]; + } + + return null; + } + + public function getReturnTypeNode() : ReturnTypeNode + { + return $this->returnTypeNode; + } + + /** + * @deprecated use getReturnTypeNode instead + * @return bool + */ + public function hasNullableReturnType() + { + return $this->returnTypeNode->canUseNullShorthand(); + } + + /** + * @param string $code + */ + public function setCode($code) + { + $this->code = $code; + } + + public function getCode() + { + if ($this->returnsReference) + { + return "throw new \Prophecy\Exception\Doubler\ReturnByReferenceException('Returning by reference not supported', get_class(\$this), '{$this->name}');"; + } + + return (string) $this->code; + } + + public function useParentCode() + { + $this->code = sprintf( + 'return parent::%s(%s);', $this->getName(), implode(', ', + array_map(array($this, 'generateArgument'), $this->arguments) + ) + ); + } + + private function generateArgument(ArgumentNode $arg) + { + $argument = '$'.$arg->getName(); + + if ($arg->isVariadic()) { + $argument = '...'.$argument; + } + + return $argument; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ReturnTypeNode.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ReturnTypeNode.php new file mode 100644 index 0000000..f688537 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ReturnTypeNode.php @@ -0,0 +1,31 @@ +types['void']) && count($this->types) !== 1) { + throw new DoubleException('void cannot be part of a union'); + } + + parent::guardIsValidType(); + } + + public function isVoid(): bool + { + return $this->types == ['void' => 'void']; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php new file mode 100644 index 0000000..3b79cfb --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php @@ -0,0 +1,87 @@ +getRealType($type); + $this->types[$type] = $type; + } + + $this->guardIsValidType(); + } + + public function canUseNullShorthand(): bool + { + return isset($this->types['null']) && count($this->types) <= 2; + } + + public function getTypes(): array + { + return array_values($this->types); + } + + public function getNonNullTypes(): array + { + $nonNullTypes = $this->types; + unset($nonNullTypes['null']); + + return array_values($nonNullTypes); + } + + protected function prefixWithNsSeparator(string $type): string + { + return '\\' . ltrim($type, '\\'); + } + + protected function getRealType(string $type): string + { + switch ($type) { + // type aliases + case 'double': + case 'real': + return 'float'; + case 'boolean': + return 'bool'; + case 'integer': + return 'int'; + + // built in types + case 'self': + case 'array': + case 'callable': + case 'bool': + case 'float': + case 'int': + case 'string': + case 'iterable': + case 'object': + case 'null': + return $type; + case 'mixed': + return \PHP_VERSION_ID < 80000 ? $this->prefixWithNsSeparator($type) : $type; + + default: + return $this->prefixWithNsSeparator($type); + } + } + + protected function guardIsValidType() + { + if ($this->types == ['null' => 'null']) { + throw new DoubleException('Argument type cannot be standalone null'); + } + + if (\PHP_VERSION_ID >= 80000 && isset($this->types['mixed']) && count($this->types) !== 1) { + throw new DoubleException('mixed cannot be part of a union'); + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php new file mode 100644 index 0000000..d720b15 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php @@ -0,0 +1,22 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler\Generator; + +/** + * Reflection interface. + * All reflected classes implement this interface. + * + * @author Konstantin Kudryashov + */ +interface ReflectionInterface +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php new file mode 100644 index 0000000..5e8aa30 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php @@ -0,0 +1,43 @@ += 80000; + + default: + return false; + } + } + + public function isBuiltInReturnTypeHint($type) + { + if ($type === 'void') { + return true; + } + + return $this->isBuiltInParamTypeHint($type); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php new file mode 100644 index 0000000..8a99c4c --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php @@ -0,0 +1,127 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use Prophecy\Exception\Doubler\DoubleException; +use Prophecy\Exception\Doubler\ClassNotFoundException; +use Prophecy\Exception\Doubler\InterfaceNotFoundException; +use ReflectionClass; + +/** + * Lazy double. + * Gives simple interface to describe double before creating it. + * + * @author Konstantin Kudryashov + */ +class LazyDouble +{ + private $doubler; + private $class; + private $interfaces = array(); + private $arguments = null; + private $double; + + /** + * Initializes lazy double. + * + * @param Doubler $doubler + */ + public function __construct(Doubler $doubler) + { + $this->doubler = $doubler; + } + + /** + * Tells doubler to use specific class as parent one for double. + * + * @param string|ReflectionClass $class + * + * @throws \Prophecy\Exception\Doubler\ClassNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function setParentClass($class) + { + if (null !== $this->double) { + throw new DoubleException('Can not extend class with already instantiated double.'); + } + + if (!$class instanceof ReflectionClass) { + if (!class_exists($class)) { + throw new ClassNotFoundException(sprintf('Class %s not found.', $class), $class); + } + + $class = new ReflectionClass($class); + } + + $this->class = $class; + } + + /** + * Tells doubler to implement specific interface with double. + * + * @param string|ReflectionClass $interface + * + * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + */ + public function addInterface($interface) + { + if (null !== $this->double) { + throw new DoubleException( + 'Can not implement interface with already instantiated double.' + ); + } + + if (!$interface instanceof ReflectionClass) { + if (!interface_exists($interface)) { + throw new InterfaceNotFoundException( + sprintf('Interface %s not found.', $interface), + $interface + ); + } + + $interface = new ReflectionClass($interface); + } + + $this->interfaces[] = $interface; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + */ + public function setArguments(array $arguments = null) + { + $this->arguments = $arguments; + } + + /** + * Creates double instance or returns already created one. + * + * @return DoubleInterface + */ + public function getInstance() + { + if (null === $this->double) { + if (null !== $this->arguments) { + return $this->double = $this->doubler->double( + $this->class, $this->interfaces, $this->arguments + ); + } + + $this->double = $this->doubler->double($this->class, $this->interfaces); + } + + return $this->double; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php new file mode 100644 index 0000000..d67ec6a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php @@ -0,0 +1,52 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Doubler; + +use ReflectionClass; + +/** + * Name generator. + * Generates classname for double. + * + * @author Konstantin Kudryashov + */ +class NameGenerator +{ + private static $counter = 1; + + /** + * Generates name. + * + * @param ReflectionClass $class + * @param ReflectionClass[] $interfaces + * + * @return string + */ + public function name(ReflectionClass $class = null, array $interfaces) + { + $parts = array(); + + if (null !== $class) { + $parts[] = $class->getName(); + } else { + foreach ($interfaces as $interface) { + $parts[] = $interface->getShortName(); + } + } + + if (!count($parts)) { + $parts[] = 'stdClass'; + } + + return sprintf('Double\%s\P%d', implode('\\', $parts), self::$counter++); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php new file mode 100644 index 0000000..48ed225 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php @@ -0,0 +1,40 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Call; + +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Prophecy\ObjectProphecy; + +class UnexpectedCallException extends ObjectProphecyException +{ + private $methodName; + private $arguments; + + public function __construct($message, ObjectProphecy $objectProphecy, + $methodName, array $arguments) + { + parent::__construct($message, $objectProphecy); + + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php new file mode 100644 index 0000000..822918a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Doubler\Generator\Node\ClassNode; + +class ClassCreatorException extends \RuntimeException implements DoublerException +{ + private $node; + + public function __construct($message, ClassNode $node) + { + parent::__construct($message); + + $this->node = $node; + } + + public function getClassNode() + { + return $this->node; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php new file mode 100644 index 0000000..8fc53b8 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use ReflectionClass; + +class ClassMirrorException extends \RuntimeException implements DoublerException +{ + private $class; + + public function __construct($message, ReflectionClass $class) + { + parent::__construct($message); + + $this->class = $class; + } + + public function getReflectedClass() + { + return $this->class; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php new file mode 100644 index 0000000..5bc826d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php @@ -0,0 +1,33 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ClassNotFoundException extends DoubleException +{ + private $classname; + + /** + * @param string $message + * @param string $classname + */ + public function __construct($message, $classname) + { + parent::__construct($message); + + $this->classname = $classname; + } + + public function getClassname() + { + return $this->classname; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php new file mode 100644 index 0000000..6642a58 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use RuntimeException; + +class DoubleException extends RuntimeException implements DoublerException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php new file mode 100644 index 0000000..9d6be17 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +use Prophecy\Exception\Exception; + +interface DoublerException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php new file mode 100644 index 0000000..e344dea --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php @@ -0,0 +1,20 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class InterfaceNotFoundException extends ClassNotFoundException +{ + public function getInterfaceName() + { + return $this->getClassname(); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php new file mode 100644 index 0000000..56f47b1 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php @@ -0,0 +1,41 @@ +methodName = $methodName; + $this->className = $className; + } + + + /** + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * @return string + */ + public function getClassName() + { + return $this->className; + } + + } diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php new file mode 100644 index 0000000..a538349 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php @@ -0,0 +1,60 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class MethodNotFoundException extends DoubleException +{ + /** + * @var string|object + */ + private $classname; + + /** + * @var string + */ + private $methodName; + + /** + * @var array + */ + private $arguments; + + /** + * @param string $message + * @param string|object $classname + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + */ + public function __construct($message, $classname, $methodName, $arguments = null) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + $this->arguments = $arguments; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } + + public function getArguments() + { + return $this->arguments; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php new file mode 100644 index 0000000..6303049 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php @@ -0,0 +1,41 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Doubler; + +class ReturnByReferenceException extends DoubleException +{ + private $classname; + private $methodName; + + /** + * @param string $message + * @param string $classname + * @param string $methodName + */ + public function __construct($message, $classname, $methodName) + { + parent::__construct($message); + + $this->classname = $classname; + $this->methodName = $methodName; + } + + public function getClassname() + { + return $this->classname; + } + + public function getMethodName() + { + return $this->methodName; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php new file mode 100644 index 0000000..ac9fe4d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php @@ -0,0 +1,26 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +/** + * Core Prophecy exception interface. + * All Prophecy exceptions implement it. + * + * @author Konstantin Kudryashov + */ +interface Exception +{ + /** + * @return string + */ + public function getMessage(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..bc91c69 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php @@ -0,0 +1,16 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception; + +class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php new file mode 100644 index 0000000..a00dfb0 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php @@ -0,0 +1,51 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\ObjectProphecy; + +class AggregateException extends \RuntimeException implements PredictionException +{ + private $exceptions = array(); + private $objectProphecy; + + public function append(PredictionException $exception) + { + $message = $exception->getMessage(); + $message = strtr($message, array("\n" => "\n "))."\n"; + $message = empty($this->exceptions) ? $message : "\n" . $message; + + $this->message = rtrim($this->message.$message); + $this->exceptions[] = $exception; + } + + /** + * @return PredictionException[] + */ + public function getExceptions() + { + return $this->exceptions; + } + + public function setObjectProphecy(ObjectProphecy $objectProphecy) + { + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php new file mode 100644 index 0000000..bbbbc3d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php @@ -0,0 +1,24 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use RuntimeException; + +/** + * Basic failed prediction exception. + * Use it for custom prediction failures. + * + * @author Konstantin Kudryashov + */ +class FailedPredictionException extends RuntimeException implements PredictionException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php new file mode 100644 index 0000000..05ea4aa --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class NoCallsException extends MethodProphecyException implements PredictionException +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php new file mode 100644 index 0000000..2596b1e --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Exception\Exception; + +interface PredictionException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php new file mode 100644 index 0000000..9d90543 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php @@ -0,0 +1,31 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; + +class UnexpectedCallsCountException extends UnexpectedCallsException +{ + private $expectedCount; + + public function __construct($message, MethodProphecy $methodProphecy, $count, array $calls) + { + parent::__construct($message, $methodProphecy, $calls); + + $this->expectedCount = intval($count); + } + + public function getExpectedCount() + { + return $this->expectedCount; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php new file mode 100644 index 0000000..7a99c2d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php @@ -0,0 +1,32 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prediction; + +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\Prophecy\MethodProphecyException; + +class UnexpectedCallsException extends MethodProphecyException implements PredictionException +{ + private $calls = array(); + + public function __construct($message, MethodProphecy $methodProphecy, array $calls) + { + parent::__construct($message, $methodProphecy); + + $this->calls = $calls; + } + + public function getCalls() + { + return $this->calls; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php new file mode 100644 index 0000000..1b03eaf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\MethodProphecy; + +class MethodProphecyException extends ObjectProphecyException +{ + private $methodProphecy; + + public function __construct($message, MethodProphecy $methodProphecy) + { + parent::__construct($message, $methodProphecy->getObjectProphecy()); + + $this->methodProphecy = $methodProphecy; + } + + /** + * @return MethodProphecy + */ + public function getMethodProphecy() + { + return $this->methodProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php new file mode 100644 index 0000000..e345402 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Prophecy\ObjectProphecy; + +class ObjectProphecyException extends \RuntimeException implements ProphecyException +{ + private $objectProphecy; + + public function __construct($message, ObjectProphecy $objectProphecy) + { + parent::__construct($message); + + $this->objectProphecy = $objectProphecy; + } + + /** + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php new file mode 100644 index 0000000..9157332 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php @@ -0,0 +1,18 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Exception\Prophecy; + +use Prophecy\Exception\Exception; + +interface ProphecyException extends Exception +{ +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php new file mode 100644 index 0000000..209821c --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php @@ -0,0 +1,69 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; +use phpDocumentor\Reflection\DocBlock\Tags\Method; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class ClassAndInterfaceTagRetriever implements MethodTagRetrieverInterface +{ + private $classRetriever; + + public function __construct(MethodTagRetrieverInterface $classRetriever = null) + { + if (null !== $classRetriever) { + $this->classRetriever = $classRetriever; + + return; + } + + $this->classRetriever = class_exists('phpDocumentor\Reflection\DocBlockFactory') && class_exists('phpDocumentor\Reflection\Types\ContextFactory') + ? new ClassTagRetriever() + : new LegacyClassTagRetriever() + ; + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + return array_merge( + $this->classRetriever->getTagList($reflectionClass), + $this->getInterfacesTagList($reflectionClass) + ); + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + private function getInterfacesTagList(\ReflectionClass $reflectionClass) + { + $interfaces = $reflectionClass->getInterfaces(); + $tagList = array(); + + foreach($interfaces as $interface) { + $tagList = array_merge($tagList, $this->classRetriever->getTagList($interface)); + } + + return $tagList; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php new file mode 100644 index 0000000..9817a44 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php @@ -0,0 +1,60 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tags\Method; +use phpDocumentor\Reflection\DocBlockFactory; +use phpDocumentor\Reflection\Types\ContextFactory; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class ClassTagRetriever implements MethodTagRetrieverInterface +{ + private $docBlockFactory; + private $contextFactory; + + public function __construct() + { + $this->docBlockFactory = DocBlockFactory::createInstance(); + $this->contextFactory = new ContextFactory(); + } + + /** + * @param \ReflectionClass $reflectionClass + * + * @return Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + try { + $phpdoc = $this->docBlockFactory->create( + $reflectionClass, + $this->contextFactory->createFromReflector($reflectionClass) + ); + + $methods = array(); + + foreach ($phpdoc->getTagsByName('method') as $tag) { + if ($tag instanceof Method) { + $methods[] = $tag; + } + } + + return $methods; + } catch (\InvalidArgumentException $e) { + return array(); + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php new file mode 100644 index 0000000..c0dec3d --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php @@ -0,0 +1,35 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; + +/** + * @author Théo FIDRY + * + * @internal + */ +final class LegacyClassTagRetriever implements MethodTagRetrieverInterface +{ + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[] + */ + public function getTagList(\ReflectionClass $reflectionClass) + { + $phpdoc = new DocBlock($reflectionClass->getDocComment()); + + return $phpdoc->getTagsByName('method'); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php new file mode 100644 index 0000000..d3989da --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php @@ -0,0 +1,30 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\PhpDocumentor; + +use phpDocumentor\Reflection\DocBlock\Tag\MethodTag as LegacyMethodTag; +use phpDocumentor\Reflection\DocBlock\Tags\Method; + +/** + * @author Théo FIDRY + * + * @internal + */ +interface MethodTagRetrieverInterface +{ + /** + * @param \ReflectionClass $reflectionClass + * + * @return LegacyMethodTag[]|Method[] + */ + public function getTagList(\ReflectionClass $reflectionClass); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php new file mode 100644 index 0000000..b478736 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php @@ -0,0 +1,86 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\NoCallsException; + +/** + * Call prediction. + * + * @author Konstantin Kudryashov + */ +class CallPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was at least one call. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\NoCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($methodCalls)) { + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.\n". + "Recorded `%s(...)` calls:\n%s", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ), $method); + } + + throw new NoCallsException(sprintf( + "No calls have been made that match:\n". + " %s->%s(%s)\n". + "but expected at least one.", + + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ), $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php new file mode 100644 index 0000000..31c6c57 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php @@ -0,0 +1,107 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Argument\Token\AnyValuesToken; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsCountException; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +class CallTimesPrediction implements PredictionInterface +{ + private $times; + private $util; + + /** + * Initializes prediction. + * + * @param int $times + * @param StringUtil $util + */ + public function __construct($times, StringUtil $util = null) + { + $this->times = intval($times); + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there was exact amount of calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsCountException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if ($this->times == count($calls)) { + return; + } + + $methodCalls = $object->findProphecyMethodCalls( + $method->getMethodName(), + new ArgumentsWildcard(array(new AnyValuesToken)) + ); + + if (count($calls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but %d were made:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $this->util->stringifyCalls($calls) + ); + } elseif (count($methodCalls)) { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.\n". + "Recorded `%s(...)` calls:\n%s", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + $method->getMethodName(), + $this->util->stringifyCalls($methodCalls) + ); + } else { + $message = sprintf( + "Expected exactly %d calls that match:\n". + " %s->%s(%s)\n". + "but none were made.", + + $this->times, + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard() + ); + } + + throw new UnexpectedCallsCountException($message, $method, $this->times, $calls); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php new file mode 100644 index 0000000..44bc782 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php @@ -0,0 +1,65 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback prediction. + * + * @author Konstantin Kudryashov + */ +class CallbackPrediction implements PredictionInterface +{ + private $callback; + + /** + * Initializes callback prediction. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPrediction, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Executes preset callback. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + call_user_func($callback, $calls, $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php new file mode 100644 index 0000000..46ac5bf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php @@ -0,0 +1,68 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\UnexpectedCallsException; + +/** + * No calls prediction. + * + * @author Konstantin Kudryashov + */ +class NoCallsPrediction implements PredictionInterface +{ + private $util; + + /** + * Initializes prediction. + * + * @param null|StringUtil $util + */ + public function __construct(StringUtil $util = null) + { + $this->util = $util ?: new StringUtil; + } + + /** + * Tests that there were no calls made. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws \Prophecy\Exception\Prediction\UnexpectedCallsException + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method) + { + if (!count($calls)) { + return; + } + + $verb = count($calls) === 1 ? 'was' : 'were'; + + throw new UnexpectedCallsException(sprintf( + "No calls expected that match:\n". + " %s->%s(%s)\n". + "but %d %s made:\n%s", + get_class($object->reveal()), + $method->getMethodName(), + $method->getArgumentsWildcard(), + count($calls), + $verb, + $this->util->stringifyCalls($calls) + ), $method, $calls); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php new file mode 100644 index 0000000..f7fb06a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php @@ -0,0 +1,37 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prediction; + +use Prophecy\Call\Call; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Prediction interface. + * Predictions are logical test blocks, tied to `should...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PredictionInterface +{ + /** + * Tests that double fulfilled prediction. + * + * @param Call[] $calls + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + * @return void + */ + public function check(array $calls, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php new file mode 100644 index 0000000..5f406bf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php @@ -0,0 +1,66 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use Closure; + +/** + * Callback promise. + * + * @author Konstantin Kudryashov + */ +class CallbackPromise implements PromiseInterface +{ + private $callback; + + /** + * Initializes callback promise. + * + * @param callable $callback Custom callback + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($callback) + { + if (!is_callable($callback)) { + throw new InvalidArgumentException(sprintf( + 'Callable expected as an argument to CallbackPromise, but got %s.', + gettype($callback) + )); + } + + $this->callback = $callback; + } + + /** + * Evaluates promise callback. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $callback = $this->callback; + + if ($callback instanceof Closure && method_exists('Closure', 'bind')) { + $callback = Closure::bind($callback, $object); + } + + return call_user_func($callback, $args, $object, $method); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php new file mode 100644 index 0000000..382537b --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php @@ -0,0 +1,35 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Promise interface. + * Promises are logical blocks, tied to `will...` keyword. + * + * @author Konstantin Kudryashov + */ +interface PromiseInterface +{ + /** + * Evaluates promise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php new file mode 100644 index 0000000..39bfeea --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php @@ -0,0 +1,61 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return argument promise. + * + * @author Konstantin Kudryashov + */ +class ReturnArgumentPromise implements PromiseInterface +{ + /** + * @var int + */ + private $index; + + /** + * Initializes callback promise. + * + * @param int $index The zero-indexed number of the argument to return + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($index = 0) + { + if (!is_int($index) || $index < 0) { + throw new InvalidArgumentException(sprintf( + 'Zero-based index expected as argument to ReturnArgumentPromise, but got %s.', + $index + )); + } + $this->index = $index; + } + + /** + * Returns nth argument if has one, null otherwise. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return null|mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + return count($args) > $this->index ? $args[$this->index] : null; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php new file mode 100644 index 0000000..c7d5ac5 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php @@ -0,0 +1,55 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; + +/** + * Return promise. + * + * @author Konstantin Kudryashov + */ +class ReturnPromise implements PromiseInterface +{ + private $returnValues = array(); + + /** + * Initializes promise. + * + * @param array $returnValues Array of values + */ + public function __construct(array $returnValues) + { + $this->returnValues = $returnValues; + } + + /** + * Returns saved values one by one until last one, then continuously returns last value. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @return mixed + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + $value = array_shift($this->returnValues); + + if (!count($this->returnValues)) { + $this->returnValues[] = $value; + } + + return $value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php new file mode 100644 index 0000000..26ec19e --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php @@ -0,0 +1,100 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Promise; + +use Doctrine\Instantiator\Instantiator; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Exception\InvalidArgumentException; +use ReflectionClass; + +/** + * Throw promise. + * + * @author Konstantin Kudryashov + */ +class ThrowPromise implements PromiseInterface +{ + private $exception; + + /** + * @var \Doctrine\Instantiator\Instantiator + */ + private $instantiator; + + /** + * Initializes promise. + * + * @param string|\Exception|\Throwable $exception Exception class name or instance + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function __construct($exception) + { + if (is_string($exception)) { + if ((!class_exists($exception) && !interface_exists($exception)) || !$this->isAValidThrowable($exception)) { + throw new InvalidArgumentException(sprintf( + 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.', + $exception + )); + } + } elseif (!$exception instanceof \Exception && !$exception instanceof \Throwable) { + throw new InvalidArgumentException(sprintf( + 'Exception / Throwable class or instance expected as argument to ThrowPromise, but got %s.', + is_object($exception) ? get_class($exception) : gettype($exception) + )); + } + + $this->exception = $exception; + } + + /** + * Throws predefined exception. + * + * @param array $args + * @param ObjectProphecy $object + * @param MethodProphecy $method + * + * @throws object + */ + public function execute(array $args, ObjectProphecy $object, MethodProphecy $method) + { + if (is_string($this->exception)) { + $classname = $this->exception; + $reflection = new ReflectionClass($classname); + $constructor = $reflection->getConstructor(); + + if ($constructor->isPublic() && 0 == $constructor->getNumberOfRequiredParameters()) { + throw $reflection->newInstance(); + } + + if (!$this->instantiator) { + $this->instantiator = new Instantiator(); + } + + throw $this->instantiator->instantiate($classname); + } + + throw $this->exception; + } + + /** + * @param string $exception + * + * @return bool + */ + private function isAValidThrowable($exception) + { + return is_a($exception, 'Exception', true) + || is_a($exception, 'Throwable', true); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php new file mode 100644 index 0000000..a2f5073 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php @@ -0,0 +1,565 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use Prophecy\Argument; +use Prophecy\Prophet; +use Prophecy\Promise; +use Prophecy\Prediction; +use Prophecy\Exception\Doubler\MethodNotFoundException; +use Prophecy\Exception\InvalidArgumentException; +use Prophecy\Exception\Prophecy\MethodProphecyException; +use ReflectionNamedType; +use ReflectionType; +use ReflectionUnionType; + +/** + * Method prophecy. + * + * @author Konstantin Kudryashov + */ +class MethodProphecy +{ + private $objectProphecy; + private $methodName; + private $argumentsWildcard; + private $promise; + private $prediction; + private $checkedPredictions = array(); + private $bound = false; + private $voidReturnType = false; + + /** + * Initializes method prophecy. + * + * @param ObjectProphecy $objectProphecy + * @param string $methodName + * @param null|Argument\ArgumentsWildcard|array $arguments + * + * @throws \Prophecy\Exception\Doubler\MethodNotFoundException If method not found + */ + public function __construct(ObjectProphecy $objectProphecy, $methodName, $arguments = null) + { + $double = $objectProphecy->reveal(); + if (!method_exists($double, $methodName)) { + throw new MethodNotFoundException(sprintf( + 'Method `%s::%s()` is not defined.', get_class($double), $methodName + ), get_class($double), $methodName, $arguments); + } + + $this->objectProphecy = $objectProphecy; + $this->methodName = $methodName; + + $reflectedMethod = new \ReflectionMethod($double, $methodName); + if ($reflectedMethod->isFinal()) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as it is a final method.", + get_class($double), + $methodName + ), $this); + } + + if (null !== $arguments) { + $this->withArguments($arguments); + } + + if (true === $reflectedMethod->hasReturnType()) { + + $reflectionType = $reflectedMethod->getReturnType(); + + if ($reflectionType instanceof ReflectionNamedType) { + $types = [$reflectionType]; + } + elseif ($reflectionType instanceof ReflectionUnionType) { + $types = $reflectionType->getTypes(); + } + + $types = array_map( + function(ReflectionType $type) { return $type->getName(); }, + $types + ); + + usort( + $types, + static function(string $type1, string $type2) { + + // null is lowest priority + if ($type2 == 'null') { + return -1; + } + elseif ($type1 == 'null') { + return 1; + } + + // objects are higher priority than scalars + $isObject = static function($type) { + return class_exists($type) || interface_exists($type); + }; + + if($isObject($type1) && !$isObject($type2)) { + return -1; + } + elseif(!$isObject($type1) && $isObject($type2)) + { + return 1; + } + + // don't sort both-scalars or both-objects + return 0; + } + ); + + $defaultType = $types[0]; + + if ('void' === $defaultType) { + $this->voidReturnType = true; + } + + $this->will(function () use ($defaultType) { + switch ($defaultType) { + case 'void': return; + case 'string': return ''; + case 'float': return 0.0; + case 'int': return 0; + case 'bool': return false; + case 'array': return array(); + + case 'callable': + case 'Closure': + return function () {}; + + case 'Traversable': + case 'Generator': + return (function () { yield; })(); + + default: + $prophet = new Prophet; + return $prophet->prophesize($defaultType)->reveal(); + } + }); + } + } + + /** + * Sets argument wildcard. + * + * @param array|Argument\ArgumentsWildcard $arguments + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function withArguments($arguments) + { + if (is_array($arguments)) { + $arguments = new Argument\ArgumentsWildcard($arguments); + } + + if (!$arguments instanceof Argument\ArgumentsWildcard) { + throw new InvalidArgumentException(sprintf( + "Either an array or an instance of ArgumentsWildcard expected as\n". + 'a `MethodProphecy::withArguments()` argument, but got %s.', + gettype($arguments) + )); + } + + $this->argumentsWildcard = $arguments; + + return $this; + } + + /** + * Sets custom promise to the prophecy. + * + * @param callable|Promise\PromiseInterface $promise + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function will($promise) + { + if (is_callable($promise)) { + $promise = new Promise\CallbackPromise($promise); + } + + if (!$promise instanceof Promise\PromiseInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PromiseInterface, but got %s.', + gettype($promise) + )); + } + + $this->bindToObjectProphecy(); + $this->promise = $promise; + + return $this; + } + + /** + * Sets return promise to the prophecy. + * + * @see \Prophecy\Promise\ReturnPromise + * + * @return $this + */ + public function willReturn() + { + if ($this->voidReturnType) { + throw new MethodProphecyException( + "The method \"$this->methodName\" has a void return type, and so cannot return anything", + $this + ); + } + + return $this->will(new Promise\ReturnPromise(func_get_args())); + } + + /** + * @param array $items + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function willYield($items) + { + if ($this->voidReturnType) { + throw new MethodProphecyException( + "The method \"$this->methodName\" has a void return type, and so cannot yield anything", + $this + ); + } + + if (!is_array($items)) { + throw new InvalidArgumentException(sprintf( + 'Expected array, but got %s.', + gettype($items) + )); + } + + $generator = function() use ($items) { + foreach ($items as $key => $value) { + yield $key => $value; + } + }; + + return $this->will($generator); + } + + /** + * Sets return argument promise to the prophecy. + * + * @param int $index The zero-indexed number of the argument to return + * + * @see \Prophecy\Promise\ReturnArgumentPromise + * + * @return $this + */ + public function willReturnArgument($index = 0) + { + if ($this->voidReturnType) { + throw new MethodProphecyException("The method \"$this->methodName\" has a void return type", $this); + } + + return $this->will(new Promise\ReturnArgumentPromise($index)); + } + + /** + * Sets throw promise to the prophecy. + * + * @see \Prophecy\Promise\ThrowPromise + * + * @param string|\Exception $exception Exception class or instance + * + * @return $this + */ + public function willThrow($exception) + { + return $this->will(new Promise\ThrowPromise($exception)); + } + + /** + * Sets custom prediction to the prophecy. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function should($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + $this->bindToObjectProphecy(); + $this->prediction = $prediction; + + return $this; + } + + /** + * Sets call prediction to the prophecy. + * + * @see \Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldBeCalled() + { + return $this->should(new Prediction\CallPrediction); + } + + /** + * Sets no calls prediction to the prophecy. + * + * @see \Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotBeCalled() + { + return $this->should(new Prediction\NoCallsPrediction); + } + + /** + * Sets call times prediction to the prophecy. + * + * @see \Prophecy\Prediction\CallTimesPrediction + * + * @param $count + * + * @return $this + */ + public function shouldBeCalledTimes($count) + { + return $this->should(new Prediction\CallTimesPrediction($count)); + } + + /** + * Sets call times prediction to the prophecy. + * + * @see \Prophecy\Prediction\CallTimesPrediction + * + * @return $this + */ + public function shouldBeCalledOnce() + { + return $this->shouldBeCalledTimes(1); + } + + /** + * Checks provided prediction immediately. + * + * @param callable|Prediction\PredictionInterface $prediction + * + * @return $this + * + * @throws \Prophecy\Exception\InvalidArgumentException + */ + public function shouldHave($prediction) + { + if (is_callable($prediction)) { + $prediction = new Prediction\CallbackPrediction($prediction); + } + + if (!$prediction instanceof Prediction\PredictionInterface) { + throw new InvalidArgumentException(sprintf( + 'Expected callable or instance of PredictionInterface, but got %s.', + gettype($prediction) + )); + } + + if (null === $this->promise && !$this->voidReturnType) { + $this->willReturn(); + } + + $calls = $this->getObjectProphecy()->findProphecyMethodCalls( + $this->getMethodName(), + $this->getArgumentsWildcard() + ); + + try { + $prediction->check($calls, $this->getObjectProphecy(), $this); + $this->checkedPredictions[] = $prediction; + } catch (\Exception $e) { + $this->checkedPredictions[] = $prediction; + + throw $e; + } + + return $this; + } + + /** + * Checks call prediction. + * + * @see \Prophecy\Prediction\CallPrediction + * + * @return $this + */ + public function shouldHaveBeenCalled() + { + return $this->shouldHave(new Prediction\CallPrediction); + } + + /** + * Checks no calls prediction. + * + * @see \Prophecy\Prediction\NoCallsPrediction + * + * @return $this + */ + public function shouldNotHaveBeenCalled() + { + return $this->shouldHave(new Prediction\NoCallsPrediction); + } + + /** + * Checks no calls prediction. + * + * @see \Prophecy\Prediction\NoCallsPrediction + * @deprecated + * + * @return $this + */ + public function shouldNotBeenCalled() + { + return $this->shouldNotHaveBeenCalled(); + } + + /** + * Checks call times prediction. + * + * @see \Prophecy\Prediction\CallTimesPrediction + * + * @param int $count + * + * @return $this + */ + public function shouldHaveBeenCalledTimes($count) + { + return $this->shouldHave(new Prediction\CallTimesPrediction($count)); + } + + /** + * Checks call times prediction. + * + * @see \Prophecy\Prediction\CallTimesPrediction + * + * @return $this + */ + public function shouldHaveBeenCalledOnce() + { + return $this->shouldHaveBeenCalledTimes(1); + } + + /** + * Checks currently registered [with should(...)] prediction. + */ + public function checkPrediction() + { + if (null === $this->prediction) { + return; + } + + $this->shouldHave($this->prediction); + } + + /** + * Returns currently registered promise. + * + * @return null|Promise\PromiseInterface + */ + public function getPromise() + { + return $this->promise; + } + + /** + * Returns currently registered prediction. + * + * @return null|Prediction\PredictionInterface + */ + public function getPrediction() + { + return $this->prediction; + } + + /** + * Returns predictions that were checked on this object. + * + * @return Prediction\PredictionInterface[] + */ + public function getCheckedPredictions() + { + return $this->checkedPredictions; + } + + /** + * Returns object prophecy this method prophecy is tied to. + * + * @return ObjectProphecy + */ + public function getObjectProphecy() + { + return $this->objectProphecy; + } + + /** + * Returns method name. + * + * @return string + */ + public function getMethodName() + { + return $this->methodName; + } + + /** + * Returns arguments wildcard. + * + * @return Argument\ArgumentsWildcard + */ + public function getArgumentsWildcard() + { + return $this->argumentsWildcard; + } + + /** + * @return bool + */ + public function hasReturnVoid() + { + return $this->voidReturnType; + } + + private function bindToObjectProphecy() + { + if ($this->bound) { + return; + } + + $this->getObjectProphecy()->addMethodProphecy($this); + $this->bound = true; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php new file mode 100644 index 0000000..11b87cf --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php @@ -0,0 +1,286 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +use SebastianBergmann\Comparator\ComparisonFailure; +use Prophecy\Comparator\Factory as ComparatorFactory; +use Prophecy\Call\Call; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Argument\ArgumentsWildcard; +use Prophecy\Call\CallCenter; +use Prophecy\Exception\Prophecy\ObjectProphecyException; +use Prophecy\Exception\Prophecy\MethodProphecyException; +use Prophecy\Exception\Prediction\AggregateException; +use Prophecy\Exception\Prediction\PredictionException; + +/** + * Object prophecy. + * + * @author Konstantin Kudryashov + */ +class ObjectProphecy implements ProphecyInterface +{ + private $lazyDouble; + private $callCenter; + private $revealer; + private $comparatorFactory; + + /** + * @var MethodProphecy[][] + */ + private $methodProphecies = array(); + + /** + * Initializes object prophecy. + * + * @param LazyDouble $lazyDouble + * @param CallCenter $callCenter + * @param RevealerInterface $revealer + * @param ComparatorFactory $comparatorFactory + */ + public function __construct( + LazyDouble $lazyDouble, + CallCenter $callCenter = null, + RevealerInterface $revealer = null, + ComparatorFactory $comparatorFactory = null + ) { + $this->lazyDouble = $lazyDouble; + $this->callCenter = $callCenter ?: new CallCenter; + $this->revealer = $revealer ?: new Revealer; + + $this->comparatorFactory = $comparatorFactory ?: ComparatorFactory::getInstance(); + } + + /** + * Forces double to extend specific class. + * + * @param string $class + * + * @return $this + */ + public function willExtend($class) + { + $this->lazyDouble->setParentClass($class); + + return $this; + } + + /** + * Forces double to implement specific interface. + * + * @param string $interface + * + * @return $this + */ + public function willImplement($interface) + { + $this->lazyDouble->addInterface($interface); + + return $this; + } + + /** + * Sets constructor arguments. + * + * @param array $arguments + * + * @return $this + */ + public function willBeConstructedWith(array $arguments = null) + { + $this->lazyDouble->setArguments($arguments); + + return $this; + } + + /** + * Reveals double. + * + * @return object + * + * @throws \Prophecy\Exception\Prophecy\ObjectProphecyException If double doesn't implement needed interface + */ + public function reveal() + { + $double = $this->lazyDouble->getInstance(); + + if (null === $double || !$double instanceof ProphecySubjectInterface) { + throw new ObjectProphecyException( + "Generated double must implement ProphecySubjectInterface, but it does not.\n". + 'It seems you have wrongly configured doubler without required ClassPatch.', + $this + ); + } + + $double->setProphecy($this); + + return $double; + } + + /** + * Adds method prophecy to object prophecy. + * + * @param MethodProphecy $methodProphecy + * + * @throws \Prophecy\Exception\Prophecy\MethodProphecyException If method prophecy doesn't + * have arguments wildcard + */ + public function addMethodProphecy(MethodProphecy $methodProphecy) + { + $argumentsWildcard = $methodProphecy->getArgumentsWildcard(); + if (null === $argumentsWildcard) { + throw new MethodProphecyException(sprintf( + "Can not add prophecy for a method `%s::%s()`\n". + "as you did not specify arguments wildcard for it.", + get_class($this->reveal()), + $methodProphecy->getMethodName() + ), $methodProphecy); + } + + $methodName = strtolower($methodProphecy->getMethodName()); + + if (!isset($this->methodProphecies[$methodName])) { + $this->methodProphecies[$methodName] = array(); + } + + $this->methodProphecies[$methodName][] = $methodProphecy; + } + + /** + * Returns either all or related to single method prophecies. + * + * @param null|string $methodName + * + * @return MethodProphecy[] + */ + public function getMethodProphecies($methodName = null) + { + if (null === $methodName) { + return $this->methodProphecies; + } + + $methodName = strtolower($methodName); + + if (!isset($this->methodProphecies[$methodName])) { + return array(); + } + + return $this->methodProphecies[$methodName]; + } + + /** + * Makes specific method call. + * + * @param string $methodName + * @param array $arguments + * + * @return mixed + */ + public function makeProphecyMethodCall($methodName, array $arguments) + { + $arguments = $this->revealer->reveal($arguments); + $return = $this->callCenter->makeCall($this, $methodName, $arguments); + + return $this->revealer->reveal($return); + } + + /** + * Finds calls by method name & arguments wildcard. + * + * @param string $methodName + * @param ArgumentsWildcard $wildcard + * + * @return Call[] + */ + public function findProphecyMethodCalls($methodName, ArgumentsWildcard $wildcard) + { + return $this->callCenter->findCalls($methodName, $wildcard); + } + + /** + * Checks that registered method predictions do not fail. + * + * @throws \Prophecy\Exception\Prediction\AggregateException If any of registered predictions fail + * @throws \Prophecy\Exception\Call\UnexpectedCallException + */ + public function checkProphecyMethodsPredictions() + { + $exception = new AggregateException(sprintf("%s:\n", get_class($this->reveal()))); + $exception->setObjectProphecy($this); + + $this->callCenter->checkUnexpectedCalls(); + + foreach ($this->methodProphecies as $prophecies) { + foreach ($prophecies as $prophecy) { + try { + $prophecy->checkPrediction(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } + + /** + * Creates new method prophecy using specified method name and arguments. + * + * @param string $methodName + * @param array $arguments + * + * @return MethodProphecy + */ + public function __call($methodName, array $arguments) + { + $arguments = new ArgumentsWildcard($this->revealer->reveal($arguments)); + + foreach ($this->getMethodProphecies($methodName) as $prophecy) { + $argumentsWildcard = $prophecy->getArgumentsWildcard(); + $comparator = $this->comparatorFactory->getComparatorFor( + $argumentsWildcard, $arguments + ); + + try { + $comparator->assertEquals($argumentsWildcard, $arguments); + return $prophecy; + } catch (ComparisonFailure $failure) {} + } + + return new MethodProphecy($this, $methodName, $arguments); + } + + /** + * Tries to get property value from double. + * + * @param string $name + * + * @return mixed + */ + public function __get($name) + { + return $this->reveal()->$name; + } + + /** + * Tries to set property value to double. + * + * @param string $name + * @param mixed $value + */ + public function __set($name, $value) + { + $this->reveal()->$name = $this->revealer->reveal($value); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php new file mode 100644 index 0000000..462f15a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php @@ -0,0 +1,27 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Core Prophecy interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecyInterface +{ + /** + * Reveals prophecy object (double) . + * + * @return object + */ + public function reveal(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php new file mode 100644 index 0000000..2d83958 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php @@ -0,0 +1,34 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Controllable doubles interface. + * + * @author Konstantin Kudryashov + */ +interface ProphecySubjectInterface +{ + /** + * Sets subject prophecy. + * + * @param ProphecyInterface $prophecy + */ + public function setProphecy(ProphecyInterface $prophecy); + + /** + * Returns subject prophecy. + * + * @return ProphecyInterface + */ + public function getProphecy(); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php new file mode 100644 index 0000000..60ecdac --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php @@ -0,0 +1,44 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Basic prophecies revealer. + * + * @author Konstantin Kudryashov + */ +class Revealer implements RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value) + { + if (is_array($value)) { + return array_map(array($this, __FUNCTION__), $value); + } + + if (!is_object($value)) { + return $value; + } + + if ($value instanceof ProphecyInterface) { + $value = $value->reveal(); + } + + return $value; + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php new file mode 100644 index 0000000..ffc82bb --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php @@ -0,0 +1,29 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Prophecy; + +/** + * Prophecies revealer interface. + * + * @author Konstantin Kudryashov + */ +interface RevealerInterface +{ + /** + * Unwraps value(s). + * + * @param mixed $value + * + * @return mixed + */ + public function reveal($value); +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Prophet.php b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php new file mode 100644 index 0000000..d37c92a --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Prophet.php @@ -0,0 +1,138 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy; + +use Prophecy\Doubler\CachedDoubler; +use Prophecy\Doubler\Doubler; +use Prophecy\Doubler\LazyDouble; +use Prophecy\Doubler\ClassPatch; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophecy\RevealerInterface; +use Prophecy\Prophecy\Revealer; +use Prophecy\Call\CallCenter; +use Prophecy\Util\StringUtil; +use Prophecy\Exception\Prediction\PredictionException; +use Prophecy\Exception\Prediction\AggregateException; + +/** + * Prophet creates prophecies. + * + * @author Konstantin Kudryashov + */ +class Prophet +{ + private $doubler; + private $revealer; + private $util; + + /** + * @var ObjectProphecy[] + */ + private $prophecies = array(); + + /** + * Initializes Prophet. + * + * @param null|Doubler $doubler + * @param null|RevealerInterface $revealer + * @param null|StringUtil $util + */ + public function __construct( + Doubler $doubler = null, + RevealerInterface $revealer = null, + StringUtil $util = null + ) { + if (null === $doubler) { + $doubler = new CachedDoubler(); + $doubler->registerClassPatch(new ClassPatch\SplFileInfoPatch); + $doubler->registerClassPatch(new ClassPatch\TraversablePatch); + $doubler->registerClassPatch(new ClassPatch\ThrowablePatch); + $doubler->registerClassPatch(new ClassPatch\DisableConstructorPatch); + $doubler->registerClassPatch(new ClassPatch\ProphecySubjectPatch); + $doubler->registerClassPatch(new ClassPatch\ReflectionClassNewInstancePatch); + $doubler->registerClassPatch(new ClassPatch\HhvmExceptionPatch()); + $doubler->registerClassPatch(new ClassPatch\MagicCallPatch); + $doubler->registerClassPatch(new ClassPatch\KeywordPatch); + } + + $this->doubler = $doubler; + $this->revealer = $revealer ?: new Revealer; + $this->util = $util ?: new StringUtil; + } + + /** + * Creates new object prophecy. + * + * @param null|string $classOrInterface Class or interface name + * + * @return ObjectProphecy + */ + public function prophesize($classOrInterface = null) + { + $this->prophecies[] = $prophecy = new ObjectProphecy( + new LazyDouble($this->doubler), + new CallCenter($this->util), + $this->revealer + ); + + if ($classOrInterface && class_exists($classOrInterface)) { + return $prophecy->willExtend($classOrInterface); + } + + if ($classOrInterface && interface_exists($classOrInterface)) { + return $prophecy->willImplement($classOrInterface); + } + + return $prophecy; + } + + /** + * Returns all created object prophecies. + * + * @return ObjectProphecy[] + */ + public function getProphecies() + { + return $this->prophecies; + } + + /** + * Returns Doubler instance assigned to this Prophet. + * + * @return Doubler + */ + public function getDoubler() + { + return $this->doubler; + } + + /** + * Checks all predictions defined by prophecies of this Prophet. + * + * @throws Exception\Prediction\AggregateException If any prediction fails + */ + public function checkPredictions() + { + $exception = new AggregateException("Some predictions failed:\n"); + foreach ($this->prophecies as $prophecy) { + try { + $prophecy->checkProphecyMethodsPredictions(); + } catch (PredictionException $e) { + $exception->append($e); + } + } + + if (count($exception->getExceptions())) { + throw $exception; + } + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php new file mode 100644 index 0000000..1090a80 --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php @@ -0,0 +1,210 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * This class is a modification from sebastianbergmann/exporter + * @see https://github.com/sebastianbergmann/exporter + */ +class ExportUtil +{ + /** + * Exports a value as a string + * + * The output of this method is similar to the output of print_r(), but + * improved in various aspects: + * + * - NULL is rendered as "null" (instead of "") + * - TRUE is rendered as "true" (instead of "1") + * - FALSE is rendered as "false" (instead of "") + * - Strings are always quoted with single quotes + * - Carriage returns and newlines are normalized to \n + * - Recursion and repeated rendering is treated properly + * + * @param mixed $value + * @param int $indentation The indentation level of the 2nd+ line + * @return string + */ + public static function export($value, $indentation = 0) + { + return self::recursiveExport($value, $indentation); + } + + /** + * Converts an object to an array containing all of its private, protected + * and public properties. + * + * @param mixed $value + * @return array + */ + public static function toArray($value) + { + if (!is_object($value)) { + return (array) $value; + } + + $array = array(); + + foreach ((array) $value as $key => $val) { + // properties are transformed to keys in the following way: + // private $property => "\0Classname\0property" + // protected $property => "\0*\0property" + // public $property => "property" + if (preg_match('/^\0.+\0(.+)$/', $key, $matches)) { + $key = $matches[1]; + } + + // See https://github.com/php/php-src/commit/5721132 + if ($key === "\0gcdata") { + continue; + } + + $array[$key] = $val; + } + + // Some internal classes like SplObjectStorage don't work with the + // above (fast) mechanism nor with reflection in Zend. + // Format the output similarly to print_r() in this case + if ($value instanceof \SplObjectStorage) { + // However, the fast method does work in HHVM, and exposes the + // internal implementation. Hide it again. + if (property_exists('\SplObjectStorage', '__storage')) { + unset($array['__storage']); + } elseif (property_exists('\SplObjectStorage', 'storage')) { + unset($array['storage']); + } + + if (property_exists('\SplObjectStorage', '__key')) { + unset($array['__key']); + } + + foreach ($value as $key => $val) { + $array[spl_object_hash($val)] = array( + 'obj' => $val, + 'inf' => $value->getInfo(), + ); + } + } + + return $array; + } + + /** + * Recursive implementation of export + * + * @param mixed $value The value to export + * @param int $indentation The indentation level of the 2nd+ line + * @param \SebastianBergmann\RecursionContext\Context $processed Previously processed objects + * @return string + * @see SebastianBergmann\Exporter\Exporter::export + */ + protected static function recursiveExport(&$value, $indentation, $processed = null) + { + if ($value === null) { + return 'null'; + } + + if ($value === true) { + return 'true'; + } + + if ($value === false) { + return 'false'; + } + + if (is_float($value) && floatval(intval($value)) === $value) { + return "$value.0"; + } + + if (is_resource($value)) { + return sprintf( + 'resource(%d) of type (%s)', + $value, + get_resource_type($value) + ); + } + + if (is_string($value)) { + // Match for most non printable chars somewhat taking multibyte chars into account + if (preg_match('/[^\x09-\x0d\x20-\xff]/', $value)) { + return 'Binary String: 0x' . bin2hex($value); + } + + return "'" . + str_replace(array("\r\n", "\n\r", "\r"), array("\n", "\n", "\n"), $value) . + "'"; + } + + $whitespace = str_repeat(' ', 4 * $indentation); + + if (!$processed) { + $processed = new Context; + } + + if (is_array($value)) { + if (($key = $processed->contains($value)) !== false) { + return 'Array &' . $key; + } + + $array = $value; + $key = $processed->add($value); + $values = ''; + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + self::recursiveExport($k, $indentation), + self::recursiveExport($value[$k], $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('Array &%s (%s)', $key, $values); + } + + if (is_object($value)) { + $class = get_class($value); + + if ($hash = $processed->contains($value)) { + return sprintf('%s:%s Object', $class, $hash); + } + + $hash = $processed->add($value); + $values = ''; + $array = self::toArray($value); + + if (count($array) > 0) { + foreach ($array as $k => $v) { + $values .= sprintf( + '%s %s => %s' . "\n", + $whitespace, + self::recursiveExport($k, $indentation), + self::recursiveExport($v, $indentation + 1, $processed) + ); + } + + $values = "\n" . $values . $whitespace; + } + + return sprintf('%s:%s Object (%s)', $class, $hash, $values); + } + + return var_export($value, true); + } +} diff --git a/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php new file mode 100644 index 0000000..ba4faff --- /dev/null +++ b/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php @@ -0,0 +1,99 @@ + + * Marcello Duarte + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Prophecy\Util; + +use Prophecy\Call\Call; + +/** + * String utility. + * + * @author Konstantin Kudryashov + */ +class StringUtil +{ + private $verbose; + + /** + * @param bool $verbose + */ + public function __construct($verbose = true) + { + $this->verbose = $verbose; + } + + /** + * Stringifies any provided value. + * + * @param mixed $value + * @param boolean $exportObject + * + * @return string + */ + public function stringify($value, $exportObject = true) + { + if (is_array($value)) { + if (range(0, count($value) - 1) === array_keys($value)) { + return '['.implode(', ', array_map(array($this, __FUNCTION__), $value)).']'; + } + + $stringify = array($this, __FUNCTION__); + + return '['.implode(', ', array_map(function ($item, $key) use ($stringify) { + return (is_integer($key) ? $key : '"'.$key.'"'). + ' => '.call_user_func($stringify, $item); + }, $value, array_keys($value))).']'; + } + if (is_resource($value)) { + return get_resource_type($value).':'.$value; + } + if (is_object($value)) { + return $exportObject ? ExportUtil::export($value) : sprintf('%s:%s', get_class($value), spl_object_hash($value)); + } + if (true === $value || false === $value) { + return $value ? 'true' : 'false'; + } + if (is_string($value)) { + $str = sprintf('"%s"', str_replace("\n", '\\n', $value)); + + if (!$this->verbose && 50 <= strlen($str)) { + return substr($str, 0, 50).'"...'; + } + + return $str; + } + if (null === $value) { + return 'null'; + } + + return (string) $value; + } + + /** + * Stringifies provided array of calls. + * + * @param Call[] $calls Array of Call instances + * + * @return string + */ + public function stringifyCalls(array $calls) + { + $self = $this; + + return implode(PHP_EOL, array_map(function (Call $call) use ($self) { + return sprintf(' - %s(%s) @ %s', + $call->getMethodName(), + implode(', ', array_map(array($self, 'stringify'), $call->getArguments())), + str_replace(GETCWD().DIRECTORY_SEPARATOR, '', $call->getCallPlace()) + ); + }, $calls)); + } +} diff --git a/vendor/phpunit/php-code-coverage/.gitattributes b/vendor/phpunit/php-code-coverage/.gitattributes new file mode 100644 index 0000000..34d242b --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.gitattributes @@ -0,0 +1,3 @@ +/tools export-ignore + +*.php diff=php diff --git a/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md b/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md new file mode 100644 index 0000000..3339250 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.github/CONTRIBUTING.md @@ -0,0 +1 @@ +Please refer to [https://github.com/sebastianbergmann/phpunit/blob/master/CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/.github/CONTRIBUTING.md) for details on how to contribute to this project. diff --git a/vendor/phpunit/php-code-coverage/.github/FUNDING.yml b/vendor/phpunit/php-code-coverage/.github/FUNDING.yml new file mode 100644 index 0000000..c2fba0f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.github/FUNDING.yml @@ -0,0 +1 @@ +github: sebastianbergmann diff --git a/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md b/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..dc8e3b0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,18 @@ +| Q | A +| --------------------------| --------------- +| php-code-coverage version | x.y.z +| PHP version | x.y.z +| Driver | Xdebug / PHPDBG +| Xdebug version (if used) | x.y.z +| Installation Method | Composer / PHPUnit PHAR +| Usage Method | PHPUnit / other +| PHPUnit version (if used) | x.y.z + + + diff --git a/vendor/phpunit/php-code-coverage/.gitignore b/vendor/phpunit/php-code-coverage/.gitignore new file mode 100644 index 0000000..3c77ffd --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.gitignore @@ -0,0 +1,7 @@ +/tests/_files/tmp +/vendor +/composer.lock +/.idea +/.php_cs +/.php_cs.cache +/.phpunit.result.cache diff --git a/vendor/phpunit/php-code-coverage/.php_cs.dist b/vendor/phpunit/php-code-coverage/.php_cs.dist new file mode 100644 index 0000000..cc20644 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.php_cs.dist @@ -0,0 +1,197 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules( + [ + 'align_multiline_comment' => true, + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'operators' => [ + '=' => 'align', + '=>' => 'align', + ], + ], + 'blank_line_after_namespace' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', + 'continue', + 'declare', + 'do', + 'for', + 'foreach', + 'if', + 'include', + 'include_once', + 'require', + 'require_once', + 'return', + 'switch', + 'throw', + 'try', + 'while', + 'yield', + ], + ], + 'braces' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => ['elements' => ['const', 'method', 'property']], + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_strict_types' => true, + 'dir_constant' => true, + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => true, + 'header_comment' => ['header' => $header, 'separate' => 'none'], + 'indentation_type' => true, + 'is_null' => true, + 'line_ending' => true, + 'list_syntax' => ['syntax' => 'short'], + 'logical_operators' => true, + 'lowercase_cast' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => ['ensure_fully_multiline' => true], + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => true, + 'native_constant_invocation' => true, + 'native_function_casing' => true, + 'native_function_invocation' => true, + 'new_with_braces' => false, + 'no_alias_functions' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => ['use' => 'print'], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_null_property_initialization' => true, + 'no_php4_constructor' => true, + 'no_short_bool_cast' => true, + 'no_short_echo_tag' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_superfluous_phpdoc_tags' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_curly_braces' => true, + 'no_unneeded_final_method' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unset_on_property' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public_static', + 'property_protected_static', + 'property_private_static', + 'property_public', + 'property_protected', + 'property_private', + 'method_public_static', + 'construct', + 'destruct', + 'magic', + 'phpunit', + 'method_public', + 'method_protected', + 'method_private', + 'method_protected_static', + 'method_private_static', + ], + ], + 'ordered_imports' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_align' => true, + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => ['groups' => ['simple', 'meta']], + 'phpdoc_types_order' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'return_assignment' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'self_accessor' => true, + 'semicolon_after_instruction' => true, + 'set_type_to_cast' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => true, + 'single_blank_line_at_eof' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline_array' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'visibility_required' => [ + 'elements' => [ + 'const', + 'method', + 'property', + ], + ], + 'void_return' => true, + 'whitespace_after_comma_in_array' => true, + ] + ) + ->setFinder( + PhpCsFixer\Finder::create() + ->files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests/tests') + ); diff --git a/vendor/phpunit/php-code-coverage/.travis.yml b/vendor/phpunit/php-code-coverage/.travis.yml new file mode 100644 index 0000000..1bf5648 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/.travis.yml @@ -0,0 +1,60 @@ +language: php + +php: + - 7.2 + - 7.3 + - 7.4snapshot + +matrix: + fast_finish: true + +env: + matrix: + - DRIVER="xdebug" DEPENDENCIES="high" + - DRIVER="phpdbg" DEPENDENCIES="high" + - DRIVER="pcov" DEPENDENCIES="high" + - DRIVER="xdebug" DEPENDENCIES="low" + - DRIVER="phpdbg" DEPENDENCIES="low" + - DRIVER="pcov" DEPENDENCIES="low" + global: + - DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest" + +before_install: + - ./tools/composer clear-cache + +install: + - if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry ./tools/composer update $DEFAULT_COMPOSER_FLAGS; fi + - if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry ./tools/composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi + +before_script: + - | + if [[ "$DRIVER" = 'pcov' ]]; then + echo > $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/xdebug.ini + git clone --single-branch --branch=v1.0.6 --depth=1 https://github.com/krakjoe/pcov + cd pcov + phpize + ./configure + make clean install + echo "extension=pcov.so" > $HOME/.phpenv/versions/$TRAVIS_PHP_VERSION/etc/conf.d/pcov.ini + cd $TRAVIS_BUILD_DIR + fi + +script: + - if [[ "$DRIVER" = 'phpdbg' ]]; then phpdbg -qrr vendor/bin/phpunit --coverage-clover=coverage.xml; fi + - if [[ "$DRIVER" != 'phpdbg' ]]; then vendor/bin/phpunit --coverage-clover=coverage.xml; fi + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false + +jobs: + include: + - stage: Static Code Analysis + php: 7.3 + env: php-cs-fixer + install: + - phpenv config-rm xdebug.ini + script: + - ./tools/php-cs-fixer fix --dry-run -v --show-progress=dots --diff-format=udiff diff --git a/vendor/phpunit/php-code-coverage/ChangeLog.md b/vendor/phpunit/php-code-coverage/ChangeLog.md new file mode 100644 index 0000000..94596db --- /dev/null +++ b/vendor/phpunit/php-code-coverage/ChangeLog.md @@ -0,0 +1,131 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [7.0.10] - 2019-11-20 + +### Fixed + +* Fixed [#710](https://github.com/sebastianbergmann/php-code-coverage/pull/710): Code Coverage does not work in PhpStorm + +## [7.0.9] - 2019-11-20 + +### Changed + +* Implemented [#709](https://github.com/sebastianbergmann/php-code-coverage/pull/709): Prioritize PCOV over Xdebug + +## [7.0.8] - 2019-09-17 + +### Changed + +* Update HTML report Bootstrap 4.3.1, jQuery 3.4.1, and popper.js 1.15.0 + +## [7.0.7] - 2019-07-25 + +### Changed + +* Bumped required version of php-token-stream + +## [7.0.6] - 2019-07-08 + +### Changed + +* Bumped required version of php-token-stream + +## [7.0.5] - 2019-06-06 + +### Fixed + +* Fixed [#681](https://github.com/sebastianbergmann/php-code-coverage/pull/681): `use function` statements are not ignored + +## [7.0.4] - 2019-05-29 + +### Fixed + +* Fixed [#682](https://github.com/sebastianbergmann/php-code-coverage/pull/682): Code that is not executed is reported as being executed when using PCOV + +## [7.0.3] - 2019-02-26 + +### Fixed + +* Fixed [#671](https://github.com/sebastianbergmann/php-code-coverage/issues/671): `TypeError` when directory name is a number + +## [7.0.2] - 2019-02-15 + +### Changed + +* Updated HTML report to Bootstrap 4.3.0 + +### Fixed + +* Fixed [#667](https://github.com/sebastianbergmann/php-code-coverage/pull/667): `TypeError` in PHP reporter + +## [7.0.1] - 2019-02-01 + +### Fixed + +* Fixed [#664](https://github.com/sebastianbergmann/php-code-coverage/issues/664): `TypeError` when whitelisted file does not exist + +## [7.0.0] - 2019-02-01 + +### Added + +* Implemented [#663](https://github.com/sebastianbergmann/php-code-coverage/pull/663): Support for PCOV + +### Fixed + +* Fixed [#654](https://github.com/sebastianbergmann/php-code-coverage/issues/654): HTML report fails to load assets +* Fixed [#655](https://github.com/sebastianbergmann/php-code-coverage/issues/655): Popin pops in outside of screen + +### Removed + +* This component is no longer supported on PHP 7.1 + +## [6.1.4] - 2018-10-31 + +### Fixed + +* Fixed [#650](https://github.com/sebastianbergmann/php-code-coverage/issues/650): Wasted screen space in HTML code coverage report + +## [6.1.3] - 2018-10-23 + +### Changed + +* Use `^3.1` of `sebastian/environment` again due to [regression](https://github.com/sebastianbergmann/environment/issues/31) + +## [6.1.2] - 2018-10-23 + +### Fixed + +* Fixed [#645](https://github.com/sebastianbergmann/php-code-coverage/pull/645): Crash that can occur when php-token-stream parses invalid files + +## [6.1.1] - 2018-10-18 + +### Changed + +* This component now allows `^4` of `sebastian/environment` + +## [6.1.0] - 2018-10-16 + +### Changed + +* Class names are now abbreviated (unqualified name shown, fully qualified name shown on hover) in the file view of the HTML report +* Update HTML report to Bootstrap 4 + +[7.0.10]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.9...7.0.10 +[7.0.9]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.8...7.0.9 +[7.0.8]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.7...7.0.8 +[7.0.7]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.6...7.0.7 +[7.0.6]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.5...7.0.6 +[7.0.5]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.4...7.0.5 +[7.0.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.3...7.0.4 +[7.0.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.2...7.0.3 +[7.0.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.1...7.0.2 +[7.0.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/7.0.0...7.0.1 +[7.0.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.4...7.0.0 +[6.1.4]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.3...6.1.4 +[6.1.3]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.2...6.1.3 +[6.1.2]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.1...6.1.2 +[6.1.1]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.1.0...6.1.1 +[6.1.0]: https://github.com/sebastianbergmann/php-code-coverage/compare/6.0...6.1.0 + diff --git a/vendor/phpunit/php-code-coverage/LICENSE b/vendor/phpunit/php-code-coverage/LICENSE new file mode 100644 index 0000000..b1a0140 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/LICENSE @@ -0,0 +1,33 @@ +php-code-coverage + +Copyright (c) 2009-2019, Sebastian Bergmann . +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/php-code-coverage/README.md b/vendor/phpunit/php-code-coverage/README.md new file mode 100644 index 0000000..bd4a169 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/README.md @@ -0,0 +1,40 @@ +[![Latest Stable Version](https://poser.pugx.org/phpunit/php-code-coverage/v/stable.png)](https://packagist.org/packages/phpunit/php-code-coverage) +[![Build Status](https://travis-ci.org/sebastianbergmann/php-code-coverage.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-code-coverage) + +# SebastianBergmann\CodeCoverage + +**SebastianBergmann\CodeCoverage** is a library that provides collection, processing, and rendering functionality for PHP code coverage information. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phpunit/php-code-coverage + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phpunit/php-code-coverage + +## Using the SebastianBergmann\CodeCoverage API + +```php +filter()->addDirectoryToWhitelist('/path/to/src'); + +$coverage->start(''); + +// ... + +$coverage->stop(); + +$writer = new \SebastianBergmann\CodeCoverage\Report\Clover; +$writer->process($coverage, '/tmp/clover.xml'); + +$writer = new \SebastianBergmann\CodeCoverage\Report\Html\Facade; +$writer->process($coverage, '/tmp/code-coverage-report'); +``` + diff --git a/vendor/phpunit/php-code-coverage/build.xml b/vendor/phpunit/php-code-coverage/build.xml new file mode 100644 index 0000000..df8408e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/build.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/composer.json b/vendor/phpunit/php-code-coverage/composer.json new file mode 100644 index 0000000..19f8586 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/composer.json @@ -0,0 +1,61 @@ +{ + "name": "phpunit/php-code-coverage", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "type": "library", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues" + }, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "prefer-stable": true, + "require": { + "php": "^7.2", + "ext-dom": "*", + "ext-xmlwriter": "*", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-token-stream": "^3.1.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" + }, + "require-dev": { + "phpunit/phpunit": "^8.2.2" + }, + "suggest": { + "ext-xdebug": "^2.7.2" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "files": [ + "tests/TestCase.php", + "tests/_files/BankAccountTest.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "7.0-dev" + } + } +} diff --git a/vendor/phpunit/php-code-coverage/phive.xml b/vendor/phpunit/php-code-coverage/phive.xml new file mode 100644 index 0000000..3ec79ee --- /dev/null +++ b/vendor/phpunit/php-code-coverage/phive.xml @@ -0,0 +1,4 @@ + + + + diff --git a/vendor/phpunit/php-code-coverage/phpunit.xml b/vendor/phpunit/php-code-coverage/phpunit.xml new file mode 100644 index 0000000..37e2219 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/phpunit.xml @@ -0,0 +1,21 @@ + + + + tests/tests + + + + + src + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/CodeCoverage.php b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php new file mode 100644 index 0000000..ced3b75 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/CodeCoverage.php @@ -0,0 +1,1006 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use PHPUnit\Framework\TestCase; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\Util\Test; +use SebastianBergmann\CodeCoverage\Driver\Driver; +use SebastianBergmann\CodeCoverage\Driver\PCOV; +use SebastianBergmann\CodeCoverage\Driver\PHPDBG; +use SebastianBergmann\CodeCoverage\Driver\Xdebug; +use SebastianBergmann\CodeCoverage\Node\Builder; +use SebastianBergmann\CodeCoverage\Node\Directory; +use SebastianBergmann\CodeUnitReverseLookup\Wizard; +use SebastianBergmann\Environment\Runtime; + +/** + * Provides collection functionality for PHP code coverage information. + */ +final class CodeCoverage +{ + /** + * @var Driver + */ + private $driver; + + /** + * @var Filter + */ + private $filter; + + /** + * @var Wizard + */ + private $wizard; + + /** + * @var bool + */ + private $cacheTokens = false; + + /** + * @var bool + */ + private $checkForUnintentionallyCoveredCode = false; + + /** + * @var bool + */ + private $forceCoversAnnotation = false; + + /** + * @var bool + */ + private $checkForUnexecutedCoveredCode = false; + + /** + * @var bool + */ + private $checkForMissingCoversAnnotation = false; + + /** + * @var bool + */ + private $addUncoveredFilesFromWhitelist = true; + + /** + * @var bool + */ + private $processUncoveredFilesFromWhitelist = false; + + /** + * @var bool + */ + private $ignoreDeprecatedCode = false; + + /** + * @var PhptTestCase|string|TestCase + */ + private $currentId; + + /** + * Code coverage data. + * + * @var array + */ + private $data = []; + + /** + * @var array + */ + private $ignoredLines = []; + + /** + * @var bool + */ + private $disableIgnoredLines = false; + + /** + * Test data. + * + * @var array + */ + private $tests = []; + + /** + * @var string[] + */ + private $unintentionallyCoveredSubclassesWhitelist = []; + + /** + * Determine if the data has been initialized or not + * + * @var bool + */ + private $isInitialized = false; + + /** + * Determine whether we need to check for dead and unused code on each test + * + * @var bool + */ + private $shouldCheckForDeadAndUnused = true; + + /** + * @var Directory + */ + private $report; + + /** + * @throws RuntimeException + */ + public function __construct(Driver $driver = null, Filter $filter = null) + { + if ($filter === null) { + $filter = new Filter; + } + + if ($driver === null) { + $driver = $this->selectDriver($filter); + } + + $this->driver = $driver; + $this->filter = $filter; + + $this->wizard = new Wizard; + } + + /** + * Returns the code coverage information as a graph of node objects. + */ + public function getReport(): Directory + { + if ($this->report === null) { + $this->report = (new Builder)->build($this); + } + + return $this->report; + } + + /** + * Clears collected code coverage data. + */ + public function clear(): void + { + $this->isInitialized = false; + $this->currentId = null; + $this->data = []; + $this->tests = []; + $this->report = null; + } + + /** + * Returns the filter object used. + */ + public function filter(): Filter + { + return $this->filter; + } + + /** + * Returns the collected code coverage data. + */ + public function getData(bool $raw = false): array + { + if (!$raw && $this->addUncoveredFilesFromWhitelist) { + $this->addUncoveredFilesFromWhitelist(); + } + + return $this->data; + } + + /** + * Sets the coverage data. + */ + public function setData(array $data): void + { + $this->data = $data; + $this->report = null; + } + + /** + * Returns the test data. + */ + public function getTests(): array + { + return $this->tests; + } + + /** + * Sets the test data. + */ + public function setTests(array $tests): void + { + $this->tests = $tests; + } + + /** + * Start collection of code coverage information. + * + * @param PhptTestCase|string|TestCase $id + * + * @throws RuntimeException + */ + public function start($id, bool $clear = false): void + { + if ($clear) { + $this->clear(); + } + + if ($this->isInitialized === false) { + $this->initializeData(); + } + + $this->currentId = $id; + + $this->driver->start($this->shouldCheckForDeadAndUnused); + } + + /** + * Stop collection of code coverage information. + * + * @param array|false $linesToBeCovered + * + * @throws MissingCoversAnnotationException + * @throws CoveredCodeNotExecutedException + * @throws RuntimeException + * @throws InvalidArgumentException + * @throws \ReflectionException + */ + public function stop(bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], bool $ignoreForceCoversAnnotation = false): array + { + if (!\is_array($linesToBeCovered) && $linesToBeCovered !== false) { + throw InvalidArgumentException::create( + 2, + 'array or false' + ); + } + + $data = $this->driver->stop(); + $this->append($data, null, $append, $linesToBeCovered, $linesToBeUsed, $ignoreForceCoversAnnotation); + + $this->currentId = null; + + return $data; + } + + /** + * Appends code coverage data. + * + * @param PhptTestCase|string|TestCase $id + * @param array|false $linesToBeCovered + * + * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException + * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException + * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException + * @throws \ReflectionException + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + * @throws RuntimeException + */ + public function append(array $data, $id = null, bool $append = true, $linesToBeCovered = [], array $linesToBeUsed = [], bool $ignoreForceCoversAnnotation = false): void + { + if ($id === null) { + $id = $this->currentId; + } + + if ($id === null) { + throw new RuntimeException; + } + + $this->applyWhitelistFilter($data); + $this->applyIgnoredLinesFilter($data); + $this->initializeFilesThatAreSeenTheFirstTime($data); + + if (!$append) { + return; + } + + if ($id !== 'UNCOVERED_FILES_FROM_WHITELIST') { + $this->applyCoversAnnotationFilter( + $data, + $linesToBeCovered, + $linesToBeUsed, + $ignoreForceCoversAnnotation + ); + } + + if (empty($data)) { + return; + } + + $size = 'unknown'; + $status = -1; + + if ($id instanceof TestCase) { + $_size = $id->getSize(); + + if ($_size === Test::SMALL) { + $size = 'small'; + } elseif ($_size === Test::MEDIUM) { + $size = 'medium'; + } elseif ($_size === Test::LARGE) { + $size = 'large'; + } + + $status = $id->getStatus(); + $id = \get_class($id) . '::' . $id->getName(); + } elseif ($id instanceof PhptTestCase) { + $size = 'large'; + $id = $id->getName(); + } + + $this->tests[$id] = ['size' => $size, 'status' => $status]; + + foreach ($data as $file => $lines) { + if (!$this->filter->isFile($file)) { + continue; + } + + foreach ($lines as $k => $v) { + if ($v === Driver::LINE_EXECUTED) { + if (empty($this->data[$file][$k]) || !\in_array($id, $this->data[$file][$k])) { + $this->data[$file][$k][] = $id; + } + } + } + } + + $this->report = null; + } + + /** + * Merges the data from another instance. + * + * @param CodeCoverage $that + */ + public function merge(self $that): void + { + $this->filter->setWhitelistedFiles( + \array_merge($this->filter->getWhitelistedFiles(), $that->filter()->getWhitelistedFiles()) + ); + + foreach ($that->data as $file => $lines) { + if (!isset($this->data[$file])) { + if (!$this->filter->isFiltered($file)) { + $this->data[$file] = $lines; + } + + continue; + } + + // we should compare the lines if any of two contains data + $compareLineNumbers = \array_unique( + \array_merge( + \array_keys($this->data[$file]), + \array_keys($that->data[$file]) + ) + ); + + foreach ($compareLineNumbers as $line) { + $thatPriority = $this->getLinePriority($that->data[$file], $line); + $thisPriority = $this->getLinePriority($this->data[$file], $line); + + if ($thatPriority > $thisPriority) { + $this->data[$file][$line] = $that->data[$file][$line]; + } elseif ($thatPriority === $thisPriority && \is_array($this->data[$file][$line])) { + $this->data[$file][$line] = \array_unique( + \array_merge($this->data[$file][$line], $that->data[$file][$line]) + ); + } + } + } + + $this->tests = \array_merge($this->tests, $that->getTests()); + $this->report = null; + } + + public function setCacheTokens(bool $flag): void + { + $this->cacheTokens = $flag; + } + + public function getCacheTokens(): bool + { + return $this->cacheTokens; + } + + public function setCheckForUnintentionallyCoveredCode(bool $flag): void + { + $this->checkForUnintentionallyCoveredCode = $flag; + } + + public function setForceCoversAnnotation(bool $flag): void + { + $this->forceCoversAnnotation = $flag; + } + + public function setCheckForMissingCoversAnnotation(bool $flag): void + { + $this->checkForMissingCoversAnnotation = $flag; + } + + public function setCheckForUnexecutedCoveredCode(bool $flag): void + { + $this->checkForUnexecutedCoveredCode = $flag; + } + + public function setAddUncoveredFilesFromWhitelist(bool $flag): void + { + $this->addUncoveredFilesFromWhitelist = $flag; + } + + public function setProcessUncoveredFilesFromWhitelist(bool $flag): void + { + $this->processUncoveredFilesFromWhitelist = $flag; + } + + public function setDisableIgnoredLines(bool $flag): void + { + $this->disableIgnoredLines = $flag; + } + + public function setIgnoreDeprecatedCode(bool $flag): void + { + $this->ignoreDeprecatedCode = $flag; + } + + public function setUnintentionallyCoveredSubclassesWhitelist(array $whitelist): void + { + $this->unintentionallyCoveredSubclassesWhitelist = $whitelist; + } + + /** + * Determine the priority for a line + * + * 1 = the line is not set + * 2 = the line has not been tested + * 3 = the line is dead code + * 4 = the line has been tested + * + * During a merge, a higher number is better. + * + * @param array $data + * @param int $line + * + * @return int + */ + private function getLinePriority($data, $line) + { + if (!\array_key_exists($line, $data)) { + return 1; + } + + if (\is_array($data[$line]) && \count($data[$line]) === 0) { + return 2; + } + + if ($data[$line] === null) { + return 3; + } + + return 4; + } + + /** + * Applies the @covers annotation filtering. + * + * @param array|false $linesToBeCovered + * + * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException + * @throws \ReflectionException + * @throws MissingCoversAnnotationException + * @throws UnintentionallyCoveredCodeException + */ + private function applyCoversAnnotationFilter(array &$data, $linesToBeCovered, array $linesToBeUsed, bool $ignoreForceCoversAnnotation): void + { + if ($linesToBeCovered === false || + ($this->forceCoversAnnotation && empty($linesToBeCovered) && !$ignoreForceCoversAnnotation)) { + if ($this->checkForMissingCoversAnnotation) { + throw new MissingCoversAnnotationException; + } + + $data = []; + + return; + } + + if (empty($linesToBeCovered)) { + return; + } + + if ($this->checkForUnintentionallyCoveredCode && + (!$this->currentId instanceof TestCase || + (!$this->currentId->isMedium() && !$this->currentId->isLarge()))) { + $this->performUnintentionallyCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed); + } + + if ($this->checkForUnexecutedCoveredCode) { + $this->performUnexecutedCoveredCodeCheck($data, $linesToBeCovered, $linesToBeUsed); + } + + $data = \array_intersect_key($data, $linesToBeCovered); + + foreach (\array_keys($data) as $filename) { + $_linesToBeCovered = \array_flip($linesToBeCovered[$filename]); + $data[$filename] = \array_intersect_key($data[$filename], $_linesToBeCovered); + } + } + + private function applyWhitelistFilter(array &$data): void + { + foreach (\array_keys($data) as $filename) { + if ($this->filter->isFiltered($filename)) { + unset($data[$filename]); + } + } + } + + /** + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + */ + private function applyIgnoredLinesFilter(array &$data): void + { + foreach (\array_keys($data) as $filename) { + if (!$this->filter->isFile($filename)) { + continue; + } + + foreach ($this->getLinesToBeIgnored($filename) as $line) { + unset($data[$filename][$line]); + } + } + } + + private function initializeFilesThatAreSeenTheFirstTime(array $data): void + { + foreach ($data as $file => $lines) { + if (!isset($this->data[$file]) && $this->filter->isFile($file)) { + $this->data[$file] = []; + + foreach ($lines as $k => $v) { + $this->data[$file][$k] = $v === -2 ? null : []; + } + } + } + } + + /** + * @throws CoveredCodeNotExecutedException + * @throws InvalidArgumentException + * @throws MissingCoversAnnotationException + * @throws RuntimeException + * @throws UnintentionallyCoveredCodeException + * @throws \ReflectionException + */ + private function addUncoveredFilesFromWhitelist(): void + { + $data = []; + $uncoveredFiles = \array_diff( + $this->filter->getWhitelist(), + \array_keys($this->data) + ); + + foreach ($uncoveredFiles as $uncoveredFile) { + if (!\file_exists($uncoveredFile)) { + continue; + } + + $data[$uncoveredFile] = []; + + $lines = \count(\file($uncoveredFile)); + + for ($i = 1; $i <= $lines; $i++) { + $data[$uncoveredFile][$i] = Driver::LINE_NOT_EXECUTED; + } + } + + $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); + } + + private function getLinesToBeIgnored(string $fileName): array + { + if (isset($this->ignoredLines[$fileName])) { + return $this->ignoredLines[$fileName]; + } + + try { + return $this->getLinesToBeIgnoredInner($fileName); + } catch (\OutOfBoundsException $e) { + // This can happen with PHP_Token_Stream if the file is syntactically invalid, + // and probably affects a file that wasn't executed. + return []; + } + } + + private function getLinesToBeIgnoredInner(string $fileName): array + { + $this->ignoredLines[$fileName] = []; + + $lines = \file($fileName); + + foreach ($lines as $index => $line) { + if (!\trim($line)) { + $this->ignoredLines[$fileName][] = $index + 1; + } + } + + if ($this->cacheTokens) { + $tokens = \PHP_Token_Stream_CachingFactory::get($fileName); + } else { + $tokens = new \PHP_Token_Stream($fileName); + } + + foreach ($tokens->getInterfaces() as $interface) { + $interfaceStartLine = $interface['startLine']; + $interfaceEndLine = $interface['endLine']; + + foreach (\range($interfaceStartLine, $interfaceEndLine) as $line) { + $this->ignoredLines[$fileName][] = $line; + } + } + + foreach (\array_merge($tokens->getClasses(), $tokens->getTraits()) as $classOrTrait) { + $classOrTraitStartLine = $classOrTrait['startLine']; + $classOrTraitEndLine = $classOrTrait['endLine']; + + if (empty($classOrTrait['methods'])) { + foreach (\range($classOrTraitStartLine, $classOrTraitEndLine) as $line) { + $this->ignoredLines[$fileName][] = $line; + } + + continue; + } + + $firstMethod = \array_shift($classOrTrait['methods']); + $firstMethodStartLine = $firstMethod['startLine']; + $lastMethodEndLine = $firstMethod['endLine']; + + do { + $lastMethod = \array_pop($classOrTrait['methods']); + } while ($lastMethod !== null && 0 === \strpos($lastMethod['signature'], 'anonymousFunction')); + + if ($lastMethod !== null) { + $lastMethodEndLine = $lastMethod['endLine']; + } + + foreach (\range($classOrTraitStartLine, $firstMethodStartLine) as $line) { + $this->ignoredLines[$fileName][] = $line; + } + + foreach (\range($lastMethodEndLine + 1, $classOrTraitEndLine) as $line) { + $this->ignoredLines[$fileName][] = $line; + } + } + + if ($this->disableIgnoredLines) { + $this->ignoredLines[$fileName] = \array_unique($this->ignoredLines[$fileName]); + \sort($this->ignoredLines[$fileName]); + + return $this->ignoredLines[$fileName]; + } + + $ignore = false; + $stop = false; + + foreach ($tokens->tokens() as $token) { + switch (\get_class($token)) { + case \PHP_Token_COMMENT::class: + case \PHP_Token_DOC_COMMENT::class: + $_token = \trim((string) $token); + $_line = \trim($lines[$token->getLine() - 1]); + + if ($_token === '// @codeCoverageIgnore' || + $_token === '//@codeCoverageIgnore') { + $ignore = true; + $stop = true; + } elseif ($_token === '// @codeCoverageIgnoreStart' || + $_token === '//@codeCoverageIgnoreStart') { + $ignore = true; + } elseif ($_token === '// @codeCoverageIgnoreEnd' || + $_token === '//@codeCoverageIgnoreEnd') { + $stop = true; + } + + if (!$ignore) { + $start = $token->getLine(); + $end = $start + \substr_count((string) $token, "\n"); + + // Do not ignore the first line when there is a token + // before the comment + if (0 !== \strpos($_token, $_line)) { + $start++; + } + + for ($i = $start; $i < $end; $i++) { + $this->ignoredLines[$fileName][] = $i; + } + + // A DOC_COMMENT token or a COMMENT token starting with "/*" + // does not contain the final \n character in its text + if (isset($lines[$i - 1]) && 0 === \strpos($_token, '/*') && '*/' === \substr(\trim($lines[$i - 1]), -2)) { + $this->ignoredLines[$fileName][] = $i; + } + } + + break; + + case \PHP_Token_INTERFACE::class: + case \PHP_Token_TRAIT::class: + case \PHP_Token_CLASS::class: + case \PHP_Token_FUNCTION::class: + /* @var \PHP_Token_Interface $token */ + + $docblock = (string) $token->getDocblock(); + + $this->ignoredLines[$fileName][] = $token->getLine(); + + if (\strpos($docblock, '@codeCoverageIgnore') || ($this->ignoreDeprecatedCode && \strpos($docblock, '@deprecated'))) { + $endLine = $token->getEndLine(); + + for ($i = $token->getLine(); $i <= $endLine; $i++) { + $this->ignoredLines[$fileName][] = $i; + } + } + + break; + + /* @noinspection PhpMissingBreakStatementInspection */ + case \PHP_Token_NAMESPACE::class: + $this->ignoredLines[$fileName][] = $token->getEndLine(); + + // Intentional fallthrough + case \PHP_Token_DECLARE::class: + case \PHP_Token_OPEN_TAG::class: + case \PHP_Token_CLOSE_TAG::class: + case \PHP_Token_USE::class: + case \PHP_Token_USE_FUNCTION::class: + $this->ignoredLines[$fileName][] = $token->getLine(); + + break; + } + + if ($ignore) { + $this->ignoredLines[$fileName][] = $token->getLine(); + + if ($stop) { + $ignore = false; + $stop = false; + } + } + } + + $this->ignoredLines[$fileName][] = \count($lines) + 1; + + $this->ignoredLines[$fileName] = \array_unique( + $this->ignoredLines[$fileName] + ); + + $this->ignoredLines[$fileName] = \array_unique($this->ignoredLines[$fileName]); + \sort($this->ignoredLines[$fileName]); + + return $this->ignoredLines[$fileName]; + } + + /** + * @throws \ReflectionException + * @throws UnintentionallyCoveredCodeException + */ + private function performUnintentionallyCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed): void + { + $allowedLines = $this->getAllowedLines( + $linesToBeCovered, + $linesToBeUsed + ); + + $unintentionallyCoveredUnits = []; + + foreach ($data as $file => $_data) { + foreach ($_data as $line => $flag) { + if ($flag === 1 && !isset($allowedLines[$file][$line])) { + $unintentionallyCoveredUnits[] = $this->wizard->lookup($file, $line); + } + } + } + + $unintentionallyCoveredUnits = $this->processUnintentionallyCoveredUnits($unintentionallyCoveredUnits); + + if (!empty($unintentionallyCoveredUnits)) { + throw new UnintentionallyCoveredCodeException( + $unintentionallyCoveredUnits + ); + } + } + + /** + * @throws CoveredCodeNotExecutedException + */ + private function performUnexecutedCoveredCodeCheck(array &$data, array $linesToBeCovered, array $linesToBeUsed): void + { + $executedCodeUnits = $this->coverageToCodeUnits($data); + $message = ''; + + foreach ($this->linesToCodeUnits($linesToBeCovered) as $codeUnit) { + if (!\in_array($codeUnit, $executedCodeUnits)) { + $message .= \sprintf( + '- %s is expected to be executed (@covers) but was not executed' . "\n", + $codeUnit + ); + } + } + + foreach ($this->linesToCodeUnits($linesToBeUsed) as $codeUnit) { + if (!\in_array($codeUnit, $executedCodeUnits)) { + $message .= \sprintf( + '- %s is expected to be executed (@uses) but was not executed' . "\n", + $codeUnit + ); + } + } + + if (!empty($message)) { + throw new CoveredCodeNotExecutedException($message); + } + } + + private function getAllowedLines(array $linesToBeCovered, array $linesToBeUsed): array + { + $allowedLines = []; + + foreach (\array_keys($linesToBeCovered) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = []; + } + + $allowedLines[$file] = \array_merge( + $allowedLines[$file], + $linesToBeCovered[$file] + ); + } + + foreach (\array_keys($linesToBeUsed) as $file) { + if (!isset($allowedLines[$file])) { + $allowedLines[$file] = []; + } + + $allowedLines[$file] = \array_merge( + $allowedLines[$file], + $linesToBeUsed[$file] + ); + } + + foreach (\array_keys($allowedLines) as $file) { + $allowedLines[$file] = \array_flip( + \array_unique($allowedLines[$file]) + ); + } + + return $allowedLines; + } + + /** + * @throws RuntimeException + */ + private function selectDriver(Filter $filter): Driver + { + $runtime = new Runtime; + + if ($runtime->hasPHPDBGCodeCoverage()) { + return new PHPDBG; + } + + if ($runtime->hasPCOV()) { + return new PCOV; + } + + if ($runtime->hasXdebug()) { + return new Xdebug($filter); + } + + throw new RuntimeException('No code coverage driver available'); + } + + private function processUnintentionallyCoveredUnits(array $unintentionallyCoveredUnits): array + { + $unintentionallyCoveredUnits = \array_unique($unintentionallyCoveredUnits); + \sort($unintentionallyCoveredUnits); + + foreach (\array_keys($unintentionallyCoveredUnits) as $k => $v) { + $unit = \explode('::', $unintentionallyCoveredUnits[$k]); + + if (\count($unit) !== 2) { + continue; + } + + $class = new \ReflectionClass($unit[0]); + + foreach ($this->unintentionallyCoveredSubclassesWhitelist as $whitelisted) { + if ($class->isSubclassOf($whitelisted)) { + unset($unintentionallyCoveredUnits[$k]); + + break; + } + } + } + + return \array_values($unintentionallyCoveredUnits); + } + + /** + * @throws CoveredCodeNotExecutedException + * @throws InvalidArgumentException + * @throws MissingCoversAnnotationException + * @throws RuntimeException + * @throws UnintentionallyCoveredCodeException + * @throws \ReflectionException + */ + private function initializeData(): void + { + $this->isInitialized = true; + + if ($this->processUncoveredFilesFromWhitelist) { + $this->shouldCheckForDeadAndUnused = false; + + $this->driver->start(); + + foreach ($this->filter->getWhitelist() as $file) { + if ($this->filter->isFile($file)) { + include_once $file; + } + } + + $data = []; + + foreach ($this->driver->stop() as $file => $fileCoverage) { + if ($this->filter->isFiltered($file)) { + continue; + } + + foreach (\array_keys($fileCoverage) as $key) { + if ($fileCoverage[$key] === Driver::LINE_EXECUTED) { + $fileCoverage[$key] = Driver::LINE_NOT_EXECUTED; + } + } + + $data[$file] = $fileCoverage; + } + + $this->append($data, 'UNCOVERED_FILES_FROM_WHITELIST'); + } + } + + private function coverageToCodeUnits(array $data): array + { + $codeUnits = []; + + foreach ($data as $filename => $lines) { + foreach ($lines as $line => $flag) { + if ($flag === 1) { + $codeUnits[] = $this->wizard->lookup($filename, $line); + } + } + } + + return \array_unique($codeUnits); + } + + private function linesToCodeUnits(array $data): array + { + $codeUnits = []; + + foreach ($data as $filename => $lines) { + foreach ($lines as $line) { + $codeUnits[] = $this->wizard->lookup($filename, $line); + } + } + + return \array_unique($codeUnits); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Driver/Driver.php b/vendor/phpunit/php-code-coverage/src/Driver/Driver.php new file mode 100644 index 0000000..17acbf6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Driver/Driver.php @@ -0,0 +1,47 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Driver; + +/** + * Interface for code coverage drivers. + */ +interface Driver +{ + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + public const LINE_EXECUTED = 1; + + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + public const LINE_NOT_EXECUTED = -1; + + /** + * @var int + * + * @see http://xdebug.org/docs/code_coverage + */ + public const LINE_NOT_EXECUTABLE = -2; + + /** + * Start collection of code coverage information. + */ + public function start(bool $determineUnusedAndDead = true): void; + + /** + * Stop collection of code coverage information. + */ + public function stop(): array; +} diff --git a/vendor/phpunit/php-code-coverage/src/Driver/PCOV.php b/vendor/phpunit/php-code-coverage/src/Driver/PCOV.php new file mode 100644 index 0000000..7a6a3b6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Driver/PCOV.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Driver; + +/** + * Driver for PCOV code coverage functionality. + * + * @codeCoverageIgnore + */ +final class PCOV implements Driver +{ + /** + * Start collection of code coverage information. + */ + public function start(bool $determineUnusedAndDead = true): void + { + \pcov\start(); + } + + /** + * Stop collection of code coverage information. + */ + public function stop(): array + { + \pcov\stop(); + + $waiting = \pcov\waiting(); + $collect = []; + + if ($waiting) { + $collect = \pcov\collect(\pcov\inclusive, $waiting); + + \pcov\clear(); + } + + return $collect; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php b/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php new file mode 100644 index 0000000..e9f999a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Driver/PHPDBG.php @@ -0,0 +1,96 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Driver; + +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Driver for PHPDBG's code coverage functionality. + * + * @codeCoverageIgnore + */ +final class PHPDBG implements Driver +{ + /** + * @throws RuntimeException + */ + public function __construct() + { + if (\PHP_SAPI !== 'phpdbg') { + throw new RuntimeException( + 'This driver requires the PHPDBG SAPI' + ); + } + + if (!\function_exists('phpdbg_start_oplog')) { + throw new RuntimeException( + 'This build of PHPDBG does not support code coverage' + ); + } + } + + /** + * Start collection of code coverage information. + */ + public function start(bool $determineUnusedAndDead = true): void + { + \phpdbg_start_oplog(); + } + + /** + * Stop collection of code coverage information. + */ + public function stop(): array + { + static $fetchedLines = []; + + $dbgData = \phpdbg_end_oplog(); + + if ($fetchedLines == []) { + $sourceLines = \phpdbg_get_executable(); + } else { + $newFiles = \array_diff(\get_included_files(), \array_keys($fetchedLines)); + + $sourceLines = []; + + if ($newFiles) { + $sourceLines = phpdbg_get_executable(['files' => $newFiles]); + } + } + + foreach ($sourceLines as $file => $lines) { + foreach ($lines as $lineNo => $numExecuted) { + $sourceLines[$file][$lineNo] = self::LINE_NOT_EXECUTED; + } + } + + $fetchedLines = \array_merge($fetchedLines, $sourceLines); + + return $this->detectExecutedLines($fetchedLines, $dbgData); + } + + /** + * Convert phpdbg based data into the format CodeCoverage expects + */ + private function detectExecutedLines(array $sourceLines, array $dbgData): array + { + foreach ($dbgData as $file => $coveredLines) { + foreach ($coveredLines as $lineNo => $numExecuted) { + // phpdbg also reports $lineNo=0 when e.g. exceptions get thrown. + // make sure we only mark lines executed which are actually executable. + if (isset($sourceLines[$file][$lineNo])) { + $sourceLines[$file][$lineNo] = self::LINE_EXECUTED; + } + } + } + + return $sourceLines; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php b/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php new file mode 100644 index 0000000..7379496 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Driver/Xdebug.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Driver; + +use SebastianBergmann\CodeCoverage\Filter; +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Driver for Xdebug's code coverage functionality. + * + * @codeCoverageIgnore + */ +final class Xdebug implements Driver +{ + /** + * @var array + */ + private $cacheNumLines = []; + + /** + * @var Filter + */ + private $filter; + + /** + * @throws RuntimeException + */ + public function __construct(Filter $filter = null) + { + if (!\extension_loaded('xdebug')) { + throw new RuntimeException('This driver requires Xdebug'); + } + + if (!\ini_get('xdebug.coverage_enable')) { + throw new RuntimeException('xdebug.coverage_enable=On has to be set in php.ini'); + } + + if ($filter === null) { + $filter = new Filter; + } + + $this->filter = $filter; + } + + /** + * Start collection of code coverage information. + */ + public function start(bool $determineUnusedAndDead = true): void + { + if ($determineUnusedAndDead) { + \xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE); + } else { + \xdebug_start_code_coverage(); + } + } + + /** + * Stop collection of code coverage information. + */ + public function stop(): array + { + $data = \xdebug_get_code_coverage(); + + \xdebug_stop_code_coverage(); + + return $this->cleanup($data); + } + + private function cleanup(array $data): array + { + foreach (\array_keys($data) as $file) { + unset($data[$file][0]); + + if (!$this->filter->isFile($file)) { + continue; + } + + $numLines = $this->getNumberOfLinesInFile($file); + + foreach (\array_keys($data[$file]) as $line) { + if ($line > $numLines) { + unset($data[$file][$line]); + } + } + } + + return $data; + } + + private function getNumberOfLinesInFile(string $fileName): int + { + if (!isset($this->cacheNumLines[$fileName])) { + $buffer = \file_get_contents($fileName); + $lines = \substr_count($buffer, "\n"); + + if (\substr($buffer, -1) !== "\n") { + $lines++; + } + + $this->cacheNumLines[$fileName] = $lines; + } + + return $this->cacheNumLines[$fileName]; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php b/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php new file mode 100644 index 0000000..a88ab34 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/CoveredCodeNotExecutedException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when covered code is not executed. + */ +final class CoveredCodeNotExecutedException extends RuntimeException +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/Exception.php b/vendor/phpunit/php-code-coverage/src/Exception/Exception.php new file mode 100644 index 0000000..32bf894 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +/** + * Exception interface for php-code-coverage component. + */ +interface Exception +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php b/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..cf2fcfc --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/InvalidArgumentException.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +final class InvalidArgumentException extends \InvalidArgumentException implements Exception +{ + /** + * @param int $argument + * @param string $type + * @param null|mixed $value + * + * @return InvalidArgumentException + */ + public static function create($argument, $type, $value = null): self + { + $stack = \debug_backtrace(0); + + return new self( + \sprintf( + 'Argument #%d%sof %s::%s() must be a %s', + $argument, + $value !== null ? ' (' . \gettype($value) . '#' . $value . ')' : ' (No Value) ', + $stack[1]['class'], + $stack[1]['function'], + $type + ) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php b/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php new file mode 100644 index 0000000..56c4736 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/MissingCoversAnnotationException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when @covers must be used but is not. + */ +final class MissingCoversAnnotationException extends RuntimeException +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php b/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php new file mode 100644 index 0000000..608650d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/RuntimeException.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php b/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php new file mode 100644 index 0000000..ef219b5 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Exception/UnintentionallyCoveredCodeException.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +/** + * Exception that is raised when code is unintentionally covered. + */ +final class UnintentionallyCoveredCodeException extends RuntimeException +{ + /** + * @var array + */ + private $unintentionallyCoveredUnits = []; + + public function __construct(array $unintentionallyCoveredUnits) + { + $this->unintentionallyCoveredUnits = $unintentionallyCoveredUnits; + + parent::__construct($this->toString()); + } + + public function getUnintentionallyCoveredUnits(): array + { + return $this->unintentionallyCoveredUnits; + } + + private function toString(): string + { + $message = ''; + + foreach ($this->unintentionallyCoveredUnits as $unit) { + $message .= '- ' . $unit . "\n"; + } + + return $message; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Filter.php b/vendor/phpunit/php-code-coverage/src/Filter.php new file mode 100644 index 0000000..b3c2d2d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Filter.php @@ -0,0 +1,174 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; + +/** + * Filter for whitelisting of code coverage information. + */ +final class Filter +{ + /** + * Source files that are whitelisted. + * + * @var array + */ + private $whitelistedFiles = []; + + /** + * Remembers the result of the `is_file()` calls. + * + * @var bool[] + */ + private $isFileCallsCache = []; + + /** + * Adds a directory to the whitelist (recursively). + */ + public function addDirectoryToWhitelist(string $directory, string $suffix = '.php', string $prefix = ''): void + { + $facade = new FileIteratorFacade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Adds a file to the whitelist. + */ + public function addFileToWhitelist(string $filename): void + { + $filename = \realpath($filename); + + if (!$filename) { + return; + } + + $this->whitelistedFiles[$filename] = true; + } + + /** + * Adds files to the whitelist. + * + * @param string[] $files + */ + public function addFilesToWhitelist(array $files): void + { + foreach ($files as $file) { + $this->addFileToWhitelist($file); + } + } + + /** + * Removes a directory from the whitelist (recursively). + */ + public function removeDirectoryFromWhitelist(string $directory, string $suffix = '.php', string $prefix = ''): void + { + $facade = new FileIteratorFacade; + $files = $facade->getFilesAsArray($directory, $suffix, $prefix); + + foreach ($files as $file) { + $this->removeFileFromWhitelist($file); + } + } + + /** + * Removes a file from the whitelist. + */ + public function removeFileFromWhitelist(string $filename): void + { + $filename = \realpath($filename); + + if (!$filename || !isset($this->whitelistedFiles[$filename])) { + return; + } + + unset($this->whitelistedFiles[$filename]); + } + + /** + * Checks whether a filename is a real filename. + */ + public function isFile(string $filename): bool + { + if (isset($this->isFileCallsCache[$filename])) { + return $this->isFileCallsCache[$filename]; + } + + if ($filename === '-' || + \strpos($filename, 'vfs://') === 0 || + \strpos($filename, 'xdebug://debug-eval') !== false || + \strpos($filename, 'eval()\'d code') !== false || + \strpos($filename, 'runtime-created function') !== false || + \strpos($filename, 'runkit created function') !== false || + \strpos($filename, 'assert code') !== false || + \strpos($filename, 'regexp code') !== false || + \strpos($filename, 'Standard input code') !== false) { + $isFile = false; + } else { + $isFile = \file_exists($filename); + } + + $this->isFileCallsCache[$filename] = $isFile; + + return $isFile; + } + + /** + * Checks whether or not a file is filtered. + */ + public function isFiltered(string $filename): bool + { + if (!$this->isFile($filename)) { + return true; + } + + return !isset($this->whitelistedFiles[$filename]); + } + + /** + * Returns the list of whitelisted files. + * + * @return string[] + */ + public function getWhitelist(): array + { + return \array_keys($this->whitelistedFiles); + } + + /** + * Returns whether this filter has a whitelist. + */ + public function hasWhitelist(): bool + { + return !empty($this->whitelistedFiles); + } + + /** + * Returns the whitelisted files. + * + * @return string[] + */ + public function getWhitelistedFiles(): array + { + return $this->whitelistedFiles; + } + + /** + * Sets the whitelisted files. + */ + public function setWhitelistedFiles(array $whitelistedFiles): void + { + $this->whitelistedFiles = $whitelistedFiles; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php b/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php new file mode 100644 index 0000000..116a09f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Node/AbstractNode.php @@ -0,0 +1,328 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\Util; + +/** + * Base class for nodes in the code coverage information tree. + */ +abstract class AbstractNode implements \Countable +{ + /** + * @var string + */ + private $name; + + /** + * @var string + */ + private $path; + + /** + * @var array + */ + private $pathArray; + + /** + * @var AbstractNode + */ + private $parent; + + /** + * @var string + */ + private $id; + + public function __construct(string $name, self $parent = null) + { + if (\substr($name, -1) == \DIRECTORY_SEPARATOR) { + $name = \substr($name, 0, -1); + } + + $this->name = $name; + $this->parent = $parent; + } + + public function getName(): string + { + return $this->name; + } + + public function getId(): string + { + if ($this->id === null) { + $parent = $this->getParent(); + + if ($parent === null) { + $this->id = 'index'; + } else { + $parentId = $parent->getId(); + + if ($parentId === 'index') { + $this->id = \str_replace(':', '_', $this->name); + } else { + $this->id = $parentId . '/' . $this->name; + } + } + } + + return $this->id; + } + + public function getPath(): string + { + if ($this->path === null) { + if ($this->parent === null || $this->parent->getPath() === null || $this->parent->getPath() === false) { + $this->path = $this->name; + } else { + $this->path = $this->parent->getPath() . \DIRECTORY_SEPARATOR . $this->name; + } + } + + return $this->path; + } + + public function getPathAsArray(): array + { + if ($this->pathArray === null) { + if ($this->parent === null) { + $this->pathArray = []; + } else { + $this->pathArray = $this->parent->getPathAsArray(); + } + + $this->pathArray[] = $this; + } + + return $this->pathArray; + } + + public function getParent(): ?self + { + return $this->parent; + } + + /** + * Returns the percentage of classes that has been tested. + * + * @return int|string + */ + public function getTestedClassesPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedClasses(), + $this->getNumClasses(), + $asString + ); + } + + /** + * Returns the percentage of traits that has been tested. + * + * @return int|string + */ + public function getTestedTraitsPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedTraits(), + $this->getNumTraits(), + $asString + ); + } + + /** + * Returns the percentage of classes and traits that has been tested. + * + * @return int|string + */ + public function getTestedClassesAndTraitsPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedClassesAndTraits(), + $this->getNumClassesAndTraits(), + $asString + ); + } + + /** + * Returns the percentage of functions that has been tested. + * + * @return int|string + */ + public function getTestedFunctionsPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedFunctions(), + $this->getNumFunctions(), + $asString + ); + } + + /** + * Returns the percentage of methods that has been tested. + * + * @return int|string + */ + public function getTestedMethodsPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedMethods(), + $this->getNumMethods(), + $asString + ); + } + + /** + * Returns the percentage of functions and methods that has been tested. + * + * @return int|string + */ + public function getTestedFunctionsAndMethodsPercent(bool $asString = true) + { + return Util::percent( + $this->getNumTestedFunctionsAndMethods(), + $this->getNumFunctionsAndMethods(), + $asString + ); + } + + /** + * Returns the percentage of executed lines. + * + * @return int|string + */ + public function getLineExecutedPercent(bool $asString = true) + { + return Util::percent( + $this->getNumExecutedLines(), + $this->getNumExecutableLines(), + $asString + ); + } + + /** + * Returns the number of classes and traits. + */ + public function getNumClassesAndTraits(): int + { + return $this->getNumClasses() + $this->getNumTraits(); + } + + /** + * Returns the number of tested classes and traits. + */ + public function getNumTestedClassesAndTraits(): int + { + return $this->getNumTestedClasses() + $this->getNumTestedTraits(); + } + + /** + * Returns the classes and traits of this node. + */ + public function getClassesAndTraits(): array + { + return \array_merge($this->getClasses(), $this->getTraits()); + } + + /** + * Returns the number of functions and methods. + */ + public function getNumFunctionsAndMethods(): int + { + return $this->getNumFunctions() + $this->getNumMethods(); + } + + /** + * Returns the number of tested functions and methods. + */ + public function getNumTestedFunctionsAndMethods(): int + { + return $this->getNumTestedFunctions() + $this->getNumTestedMethods(); + } + + /** + * Returns the functions and methods of this node. + */ + public function getFunctionsAndMethods(): array + { + return \array_merge($this->getFunctions(), $this->getMethods()); + } + + /** + * Returns the classes of this node. + */ + abstract public function getClasses(): array; + + /** + * Returns the traits of this node. + */ + abstract public function getTraits(): array; + + /** + * Returns the functions of this node. + */ + abstract public function getFunctions(): array; + + /** + * Returns the LOC/CLOC/NCLOC of this node. + */ + abstract public function getLinesOfCode(): array; + + /** + * Returns the number of executable lines. + */ + abstract public function getNumExecutableLines(): int; + + /** + * Returns the number of executed lines. + */ + abstract public function getNumExecutedLines(): int; + + /** + * Returns the number of classes. + */ + abstract public function getNumClasses(): int; + + /** + * Returns the number of tested classes. + */ + abstract public function getNumTestedClasses(): int; + + /** + * Returns the number of traits. + */ + abstract public function getNumTraits(): int; + + /** + * Returns the number of tested traits. + */ + abstract public function getNumTestedTraits(): int; + + /** + * Returns the number of methods. + */ + abstract public function getNumMethods(): int; + + /** + * Returns the number of tested methods. + */ + abstract public function getNumTestedMethods(): int; + + /** + * Returns the number of functions. + */ + abstract public function getNumFunctions(): int; + + /** + * Returns the number of tested functions. + */ + abstract public function getNumTestedFunctions(): int; +} diff --git a/vendor/phpunit/php-code-coverage/src/Node/Builder.php b/vendor/phpunit/php-code-coverage/src/Node/Builder.php new file mode 100644 index 0000000..5e34bcc --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Node/Builder.php @@ -0,0 +1,227 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\CodeCoverage; + +final class Builder +{ + public function build(CodeCoverage $coverage): Directory + { + $files = $coverage->getData(); + $commonPath = $this->reducePaths($files); + $root = new Directory( + $commonPath, + null + ); + + $this->addItems( + $root, + $this->buildDirectoryStructure($files), + $coverage->getTests(), + $coverage->getCacheTokens() + ); + + return $root; + } + + private function addItems(Directory $root, array $items, array $tests, bool $cacheTokens): void + { + foreach ($items as $key => $value) { + $key = (string) $key; + + if (\substr($key, -2) === '/f') { + $key = \substr($key, 0, -2); + + if (\file_exists($root->getPath() . \DIRECTORY_SEPARATOR . $key)) { + $root->addFile($key, $value, $tests, $cacheTokens); + } + } else { + $child = $root->addDirectory($key); + $this->addItems($child, $value, $tests, $cacheTokens); + } + } + } + + /** + * Builds an array representation of the directory structure. + * + * For instance, + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is transformed into + * + * + * Array + * ( + * [.] => Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * ) + * + */ + private function buildDirectoryStructure(array $files): array + { + $result = []; + + foreach ($files as $path => $file) { + $path = \explode(\DIRECTORY_SEPARATOR, $path); + $pointer = &$result; + $max = \count($path); + + for ($i = 0; $i < $max; $i++) { + $type = ''; + + if ($i === ($max - 1)) { + $type = '/f'; + } + + $pointer = &$pointer[$path[$i] . $type]; + } + + $pointer = $file; + } + + return $result; + } + + /** + * Reduces the paths by cutting the longest common start path. + * + * For instance, + * + * + * Array + * ( + * [/home/sb/Money/Money.php] => Array + * ( + * ... + * ) + * + * [/home/sb/Money/MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + * + * is reduced to + * + * + * Array + * ( + * [Money.php] => Array + * ( + * ... + * ) + * + * [MoneyBag.php] => Array + * ( + * ... + * ) + * ) + * + */ + private function reducePaths(array &$files): string + { + if (empty($files)) { + return '.'; + } + + $commonPath = ''; + $paths = \array_keys($files); + + if (\count($files) === 1) { + $commonPath = \dirname($paths[0]) . \DIRECTORY_SEPARATOR; + $files[\basename($paths[0])] = $files[$paths[0]]; + + unset($files[$paths[0]]); + + return $commonPath; + } + + $max = \count($paths); + + for ($i = 0; $i < $max; $i++) { + // strip phar:// prefixes + if (\strpos($paths[$i], 'phar://') === 0) { + $paths[$i] = \substr($paths[$i], 7); + $paths[$i] = \str_replace('/', \DIRECTORY_SEPARATOR, $paths[$i]); + } + $paths[$i] = \explode(\DIRECTORY_SEPARATOR, $paths[$i]); + + if (empty($paths[$i][0])) { + $paths[$i][0] = \DIRECTORY_SEPARATOR; + } + } + + $done = false; + $max = \count($paths); + + while (!$done) { + for ($i = 0; $i < $max - 1; $i++) { + if (!isset($paths[$i][0]) || + !isset($paths[$i + 1][0]) || + $paths[$i][0] !== $paths[$i + 1][0]) { + $done = true; + + break; + } + } + + if (!$done) { + $commonPath .= $paths[0][0]; + + if ($paths[0][0] !== \DIRECTORY_SEPARATOR) { + $commonPath .= \DIRECTORY_SEPARATOR; + } + + for ($i = 0; $i < $max; $i++) { + \array_shift($paths[$i]); + } + } + } + + $original = \array_keys($files); + $max = \count($original); + + for ($i = 0; $i < $max; $i++) { + $files[\implode(\DIRECTORY_SEPARATOR, $paths[$i])] = $files[$original[$i]]; + unset($files[$original[$i]]); + } + + \ksort($files); + + return \substr($commonPath, 0, -1); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Node/Directory.php b/vendor/phpunit/php-code-coverage/src/Node/Directory.php new file mode 100644 index 0000000..7f1b5b2 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Node/Directory.php @@ -0,0 +1,427 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Node; + +use SebastianBergmann\CodeCoverage\InvalidArgumentException; + +/** + * Represents a directory in the code coverage information tree. + */ +final class Directory extends AbstractNode implements \IteratorAggregate +{ + /** + * @var AbstractNode[] + */ + private $children = []; + + /** + * @var Directory[] + */ + private $directories = []; + + /** + * @var File[] + */ + private $files = []; + + /** + * @var array + */ + private $classes; + + /** + * @var array + */ + private $traits; + + /** + * @var array + */ + private $functions; + + /** + * @var array + */ + private $linesOfCode; + + /** + * @var int + */ + private $numFiles = -1; + + /** + * @var int + */ + private $numExecutableLines = -1; + + /** + * @var int + */ + private $numExecutedLines = -1; + + /** + * @var int + */ + private $numClasses = -1; + + /** + * @var int + */ + private $numTestedClasses = -1; + + /** + * @var int + */ + private $numTraits = -1; + + /** + * @var int + */ + private $numTestedTraits = -1; + + /** + * @var int + */ + private $numMethods = -1; + + /** + * @var int + */ + private $numTestedMethods = -1; + + /** + * @var int + */ + private $numFunctions = -1; + + /** + * @var int + */ + private $numTestedFunctions = -1; + + /** + * Returns the number of files in/under this node. + */ + public function count(): int + { + if ($this->numFiles === -1) { + $this->numFiles = 0; + + foreach ($this->children as $child) { + $this->numFiles += \count($child); + } + } + + return $this->numFiles; + } + + /** + * Returns an iterator for this node. + */ + public function getIterator(): \RecursiveIteratorIterator + { + return new \RecursiveIteratorIterator( + new Iterator($this), + \RecursiveIteratorIterator::SELF_FIRST + ); + } + + /** + * Adds a new directory. + */ + public function addDirectory(string $name): self + { + $directory = new self($name, $this); + + $this->children[] = $directory; + $this->directories[] = &$this->children[\count($this->children) - 1]; + + return $directory; + } + + /** + * Adds a new file. + * + * @throws InvalidArgumentException + */ + public function addFile(string $name, array $coverageData, array $testData, bool $cacheTokens): File + { + $file = new File($name, $this, $coverageData, $testData, $cacheTokens); + + $this->children[] = $file; + $this->files[] = &$this->children[\count($this->children) - 1]; + + $this->numExecutableLines = -1; + $this->numExecutedLines = -1; + + return $file; + } + + /** + * Returns the directories in this directory. + */ + public function getDirectories(): array + { + return $this->directories; + } + + /** + * Returns the files in this directory. + */ + public function getFiles(): array + { + return $this->files; + } + + /** + * Returns the child nodes of this node. + */ + public function getChildNodes(): array + { + return $this->children; + } + + /** + * Returns the classes of this node. + */ + public function getClasses(): array + { + if ($this->classes === null) { + $this->classes = []; + + foreach ($this->children as $child) { + $this->classes = \array_merge( + $this->classes, + $child->getClasses() + ); + } + } + + return $this->classes; + } + + /** + * Returns the traits of this node. + */ + public function getTraits(): array + { + if ($this->traits === null) { + $this->traits = []; + + foreach ($this->children as $child) { + $this->traits = \array_merge( + $this->traits, + $child->getTraits() + ); + } + } + + return $this->traits; + } + + /** + * Returns the functions of this node. + */ + public function getFunctions(): array + { + if ($this->functions === null) { + $this->functions = []; + + foreach ($this->children as $child) { + $this->functions = \array_merge( + $this->functions, + $child->getFunctions() + ); + } + } + + return $this->functions; + } + + /** + * Returns the LOC/CLOC/NCLOC of this node. + */ + public function getLinesOfCode(): array + { + if ($this->linesOfCode === null) { + $this->linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0]; + + foreach ($this->children as $child) { + $linesOfCode = $child->getLinesOfCode(); + + $this->linesOfCode['loc'] += $linesOfCode['loc']; + $this->linesOfCode['cloc'] += $linesOfCode['cloc']; + $this->linesOfCode['ncloc'] += $linesOfCode['ncloc']; + } + } + + return $this->linesOfCode; + } + + /** + * Returns the number of executable lines. + */ + public function getNumExecutableLines(): int + { + if ($this->numExecutableLines === -1) { + $this->numExecutableLines = 0; + + foreach ($this->children as $child) { + $this->numExecutableLines += $child->getNumExecutableLines(); + } + } + + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + */ + public function getNumExecutedLines(): int + { + if ($this->numExecutedLines === -1) { + $this->numExecutedLines = 0; + + foreach ($this->children as $child) { + $this->numExecutedLines += $child->getNumExecutedLines(); + } + } + + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + */ + public function getNumClasses(): int + { + if ($this->numClasses === -1) { + $this->numClasses = 0; + + foreach ($this->children as $child) { + $this->numClasses += $child->getNumClasses(); + } + } + + return $this->numClasses; + } + + /** + * Returns the number of tested classes. + */ + public function getNumTestedClasses(): int + { + if ($this->numTestedClasses === -1) { + $this->numTestedClasses = 0; + + foreach ($this->children as $child) { + $this->numTestedClasses += $child->getNumTestedClasses(); + } + } + + return $this->numTestedClasses; + } + + /** + * Returns the number of traits. + */ + public function getNumTraits(): int + { + if ($this->numTraits === -1) { + $this->numTraits = 0; + + foreach ($this->children as $child) { + $this->numTraits += $child->getNumTraits(); + } + } + + return $this->numTraits; + } + + /** + * Returns the number of tested traits. + */ + public function getNumTestedTraits(): int + { + if ($this->numTestedTraits === -1) { + $this->numTestedTraits = 0; + + foreach ($this->children as $child) { + $this->numTestedTraits += $child->getNumTestedTraits(); + } + } + + return $this->numTestedTraits; + } + + /** + * Returns the number of methods. + */ + public function getNumMethods(): int + { + if ($this->numMethods === -1) { + $this->numMethods = 0; + + foreach ($this->children as $child) { + $this->numMethods += $child->getNumMethods(); + } + } + + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + */ + public function getNumTestedMethods(): int + { + if ($this->numTestedMethods === -1) { + $this->numTestedMethods = 0; + + foreach ($this->children as $child) { + $this->numTestedMethods += $child->getNumTestedMethods(); + } + } + + return $this->numTestedMethods; + } + + /** + * Returns the number of functions. + */ + public function getNumFunctions(): int + { + if ($this->numFunctions === -1) { + $this->numFunctions = 0; + + foreach ($this->children as $child) { + $this->numFunctions += $child->getNumFunctions(); + } + } + + return $this->numFunctions; + } + + /** + * Returns the number of tested functions. + */ + public function getNumTestedFunctions(): int + { + if ($this->numTestedFunctions === -1) { + $this->numTestedFunctions = 0; + + foreach ($this->children as $child) { + $this->numTestedFunctions += $child->getNumTestedFunctions(); + } + } + + return $this->numTestedFunctions; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Node/File.php b/vendor/phpunit/php-code-coverage/src/Node/File.php new file mode 100644 index 0000000..840d119 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Node/File.php @@ -0,0 +1,611 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Node; + +/** + * Represents a file in the code coverage information tree. + */ +final class File extends AbstractNode +{ + /** + * @var array + */ + private $coverageData; + + /** + * @var array + */ + private $testData; + + /** + * @var int + */ + private $numExecutableLines = 0; + + /** + * @var int + */ + private $numExecutedLines = 0; + + /** + * @var array + */ + private $classes = []; + + /** + * @var array + */ + private $traits = []; + + /** + * @var array + */ + private $functions = []; + + /** + * @var array + */ + private $linesOfCode = []; + + /** + * @var int + */ + private $numClasses; + + /** + * @var int + */ + private $numTestedClasses = 0; + + /** + * @var int + */ + private $numTraits; + + /** + * @var int + */ + private $numTestedTraits = 0; + + /** + * @var int + */ + private $numMethods; + + /** + * @var int + */ + private $numTestedMethods; + + /** + * @var int + */ + private $numTestedFunctions; + + /** + * @var bool + */ + private $cacheTokens; + + /** + * @var array + */ + private $codeUnitsByLine = []; + + public function __construct(string $name, AbstractNode $parent, array $coverageData, array $testData, bool $cacheTokens) + { + parent::__construct($name, $parent); + + $this->coverageData = $coverageData; + $this->testData = $testData; + $this->cacheTokens = $cacheTokens; + + $this->calculateStatistics(); + } + + /** + * Returns the number of files in/under this node. + */ + public function count(): int + { + return 1; + } + + /** + * Returns the code coverage data of this node. + */ + public function getCoverageData(): array + { + return $this->coverageData; + } + + /** + * Returns the test data of this node. + */ + public function getTestData(): array + { + return $this->testData; + } + + /** + * Returns the classes of this node. + */ + public function getClasses(): array + { + return $this->classes; + } + + /** + * Returns the traits of this node. + */ + public function getTraits(): array + { + return $this->traits; + } + + /** + * Returns the functions of this node. + */ + public function getFunctions(): array + { + return $this->functions; + } + + /** + * Returns the LOC/CLOC/NCLOC of this node. + */ + public function getLinesOfCode(): array + { + return $this->linesOfCode; + } + + /** + * Returns the number of executable lines. + */ + public function getNumExecutableLines(): int + { + return $this->numExecutableLines; + } + + /** + * Returns the number of executed lines. + */ + public function getNumExecutedLines(): int + { + return $this->numExecutedLines; + } + + /** + * Returns the number of classes. + */ + public function getNumClasses(): int + { + if ($this->numClasses === null) { + $this->numClasses = 0; + + foreach ($this->classes as $class) { + foreach ($class['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numClasses++; + + continue 2; + } + } + } + } + + return $this->numClasses; + } + + /** + * Returns the number of tested classes. + */ + public function getNumTestedClasses(): int + { + return $this->numTestedClasses; + } + + /** + * Returns the number of traits. + */ + public function getNumTraits(): int + { + if ($this->numTraits === null) { + $this->numTraits = 0; + + foreach ($this->traits as $trait) { + foreach ($trait['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numTraits++; + + continue 2; + } + } + } + } + + return $this->numTraits; + } + + /** + * Returns the number of tested traits. + */ + public function getNumTestedTraits(): int + { + return $this->numTestedTraits; + } + + /** + * Returns the number of methods. + */ + public function getNumMethods(): int + { + if ($this->numMethods === null) { + $this->numMethods = 0; + + foreach ($this->classes as $class) { + foreach ($class['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numMethods++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait['methods'] as $method) { + if ($method['executableLines'] > 0) { + $this->numMethods++; + } + } + } + } + + return $this->numMethods; + } + + /** + * Returns the number of tested methods. + */ + public function getNumTestedMethods(): int + { + if ($this->numTestedMethods === null) { + $this->numTestedMethods = 0; + + foreach ($this->classes as $class) { + foreach ($class['methods'] as $method) { + if ($method['executableLines'] > 0 && + $method['coverage'] === 100) { + $this->numTestedMethods++; + } + } + } + + foreach ($this->traits as $trait) { + foreach ($trait['methods'] as $method) { + if ($method['executableLines'] > 0 && + $method['coverage'] === 100) { + $this->numTestedMethods++; + } + } + } + } + + return $this->numTestedMethods; + } + + /** + * Returns the number of functions. + */ + public function getNumFunctions(): int + { + return \count($this->functions); + } + + /** + * Returns the number of tested functions. + */ + public function getNumTestedFunctions(): int + { + if ($this->numTestedFunctions === null) { + $this->numTestedFunctions = 0; + + foreach ($this->functions as $function) { + if ($function['executableLines'] > 0 && + $function['coverage'] === 100) { + $this->numTestedFunctions++; + } + } + } + + return $this->numTestedFunctions; + } + + private function calculateStatistics(): void + { + if ($this->cacheTokens) { + $tokens = \PHP_Token_Stream_CachingFactory::get($this->getPath()); + } else { + $tokens = new \PHP_Token_Stream($this->getPath()); + } + + $this->linesOfCode = $tokens->getLinesOfCode(); + + foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) { + $this->codeUnitsByLine[$lineNumber] = []; + } + + try { + $this->processClasses($tokens); + $this->processTraits($tokens); + $this->processFunctions($tokens); + } catch (\OutOfBoundsException $e) { + // This can happen with PHP_Token_Stream if the file is syntactically invalid, + // and probably affects a file that wasn't executed. + } + unset($tokens); + + foreach (\range(1, $this->linesOfCode['loc']) as $lineNumber) { + if (isset($this->coverageData[$lineNumber])) { + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit['executableLines']++; + } + + unset($codeUnit); + + $this->numExecutableLines++; + + if (\count($this->coverageData[$lineNumber]) > 0) { + foreach ($this->codeUnitsByLine[$lineNumber] as &$codeUnit) { + $codeUnit['executedLines']++; + } + + unset($codeUnit); + + $this->numExecutedLines++; + } + } + } + + foreach ($this->traits as &$trait) { + foreach ($trait['methods'] as &$method) { + if ($method['executableLines'] > 0) { + $method['coverage'] = ($method['executedLines'] / + $method['executableLines']) * 100; + } else { + $method['coverage'] = 100; + } + + $method['crap'] = $this->crap( + $method['ccn'], + $method['coverage'] + ); + + $trait['ccn'] += $method['ccn']; + } + + unset($method); + + if ($trait['executableLines'] > 0) { + $trait['coverage'] = ($trait['executedLines'] / + $trait['executableLines']) * 100; + + if ($trait['coverage'] === 100) { + $this->numTestedClasses++; + } + } else { + $trait['coverage'] = 100; + } + + $trait['crap'] = $this->crap( + $trait['ccn'], + $trait['coverage'] + ); + } + + unset($trait); + + foreach ($this->classes as &$class) { + foreach ($class['methods'] as &$method) { + if ($method['executableLines'] > 0) { + $method['coverage'] = ($method['executedLines'] / + $method['executableLines']) * 100; + } else { + $method['coverage'] = 100; + } + + $method['crap'] = $this->crap( + $method['ccn'], + $method['coverage'] + ); + + $class['ccn'] += $method['ccn']; + } + + unset($method); + + if ($class['executableLines'] > 0) { + $class['coverage'] = ($class['executedLines'] / + $class['executableLines']) * 100; + + if ($class['coverage'] === 100) { + $this->numTestedClasses++; + } + } else { + $class['coverage'] = 100; + } + + $class['crap'] = $this->crap( + $class['ccn'], + $class['coverage'] + ); + } + + unset($class); + + foreach ($this->functions as &$function) { + if ($function['executableLines'] > 0) { + $function['coverage'] = ($function['executedLines'] / + $function['executableLines']) * 100; + } else { + $function['coverage'] = 100; + } + + if ($function['coverage'] === 100) { + $this->numTestedFunctions++; + } + + $function['crap'] = $this->crap( + $function['ccn'], + $function['coverage'] + ); + } + } + + private function processClasses(\PHP_Token_Stream $tokens): void + { + $classes = $tokens->getClasses(); + $link = $this->getId() . '.html#'; + + foreach ($classes as $className => $class) { + if (\strpos($className, 'anonymous') === 0) { + continue; + } + + if (!empty($class['package']['namespace'])) { + $className = $class['package']['namespace'] . '\\' . $className; + } + + $this->classes[$className] = [ + 'className' => $className, + 'methods' => [], + 'startLine' => $class['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => 0, + 'coverage' => 0, + 'crap' => 0, + 'package' => $class['package'], + 'link' => $link . $class['startLine'], + ]; + + foreach ($class['methods'] as $methodName => $method) { + if (\strpos($methodName, 'anonymous') === 0) { + continue; + } + + $this->classes[$className]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); + + foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) { + $this->codeUnitsByLine[$lineNumber] = [ + &$this->classes[$className], + &$this->classes[$className]['methods'][$methodName], + ]; + } + } + } + } + + private function processTraits(\PHP_Token_Stream $tokens): void + { + $traits = $tokens->getTraits(); + $link = $this->getId() . '.html#'; + + foreach ($traits as $traitName => $trait) { + $this->traits[$traitName] = [ + 'traitName' => $traitName, + 'methods' => [], + 'startLine' => $trait['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => 0, + 'coverage' => 0, + 'crap' => 0, + 'package' => $trait['package'], + 'link' => $link . $trait['startLine'], + ]; + + foreach ($trait['methods'] as $methodName => $method) { + if (\strpos($methodName, 'anonymous') === 0) { + continue; + } + + $this->traits[$traitName]['methods'][$methodName] = $this->newMethod($methodName, $method, $link); + + foreach (\range($method['startLine'], $method['endLine']) as $lineNumber) { + $this->codeUnitsByLine[$lineNumber] = [ + &$this->traits[$traitName], + &$this->traits[$traitName]['methods'][$methodName], + ]; + } + } + } + } + + private function processFunctions(\PHP_Token_Stream $tokens): void + { + $functions = $tokens->getFunctions(); + $link = $this->getId() . '.html#'; + + foreach ($functions as $functionName => $function) { + if (\strpos($functionName, 'anonymous') === 0) { + continue; + } + + $this->functions[$functionName] = [ + 'functionName' => $functionName, + 'signature' => $function['signature'], + 'startLine' => $function['startLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => $function['ccn'], + 'coverage' => 0, + 'crap' => 0, + 'link' => $link . $function['startLine'], + ]; + + foreach (\range($function['startLine'], $function['endLine']) as $lineNumber) { + $this->codeUnitsByLine[$lineNumber] = [&$this->functions[$functionName]]; + } + } + } + + private function crap(int $ccn, float $coverage): string + { + if ($coverage === 0.0) { + return (string) ($ccn ** 2 + $ccn); + } + + if ($coverage >= 95) { + return (string) $ccn; + } + + return \sprintf( + '%01.2F', + $ccn ** 2 * (1 - $coverage / 100) ** 3 + $ccn + ); + } + + private function newMethod(string $methodName, array $method, string $link): array + { + return [ + 'methodName' => $methodName, + 'visibility' => $method['visibility'], + 'signature' => $method['signature'], + 'startLine' => $method['startLine'], + 'endLine' => $method['endLine'], + 'executableLines' => 0, + 'executedLines' => 0, + 'ccn' => $method['ccn'], + 'coverage' => 0, + 'crap' => 0, + 'link' => $link . $method['startLine'], + ]; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Node/Iterator.php b/vendor/phpunit/php-code-coverage/src/Node/Iterator.php new file mode 100644 index 0000000..f2dd9a7 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Node/Iterator.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Node; + +/** + * Recursive iterator for node object graphs. + */ +final class Iterator implements \RecursiveIterator +{ + /** + * @var int + */ + private $position; + + /** + * @var AbstractNode[] + */ + private $nodes; + + public function __construct(Directory $node) + { + $this->nodes = $node->getChildNodes(); + } + + /** + * Rewinds the Iterator to the first element. + */ + public function rewind(): void + { + $this->position = 0; + } + + /** + * Checks if there is a current element after calls to rewind() or next(). + */ + public function valid(): bool + { + return $this->position < \count($this->nodes); + } + + /** + * Returns the key of the current element. + */ + public function key(): int + { + return $this->position; + } + + /** + * Returns the current element. + */ + public function current(): AbstractNode + { + return $this->valid() ? $this->nodes[$this->position] : null; + } + + /** + * Moves forward to next element. + */ + public function next(): void + { + $this->position++; + } + + /** + * Returns the sub iterator for the current element. + * + * @return Iterator + */ + public function getChildren(): self + { + return new self($this->nodes[$this->position]); + } + + /** + * Checks whether the current element has children. + */ + public function hasChildren(): bool + { + return $this->nodes[$this->position] instanceof Directory; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Clover.php b/vendor/phpunit/php-code-coverage/src/Report/Clover.php new file mode 100644 index 0000000..e0f893c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Clover.php @@ -0,0 +1,258 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\File; +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Generates a Clover XML logfile from a code coverage object. + */ +final class Clover +{ + /** + * @throws \RuntimeException + */ + public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string + { + $xmlDocument = new \DOMDocument('1.0', 'UTF-8'); + $xmlDocument->formatOutput = true; + + $xmlCoverage = $xmlDocument->createElement('coverage'); + $xmlCoverage->setAttribute('generated', (string) $_SERVER['REQUEST_TIME']); + $xmlDocument->appendChild($xmlCoverage); + + $xmlProject = $xmlDocument->createElement('project'); + $xmlProject->setAttribute('timestamp', (string) $_SERVER['REQUEST_TIME']); + + if (\is_string($name)) { + $xmlProject->setAttribute('name', $name); + } + + $xmlCoverage->appendChild($xmlProject); + + $packages = []; + $report = $coverage->getReport(); + + foreach ($report as $item) { + if (!$item instanceof File) { + continue; + } + + /* @var File $item */ + + $xmlFile = $xmlDocument->createElement('file'); + $xmlFile->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + $coverageData = $item->getCoverageData(); + $lines = []; + $namespace = 'global'; + + foreach ($classes as $className => $class) { + $classStatements = 0; + $coveredClassStatements = 0; + $coveredMethods = 0; + $classMethods = 0; + + foreach ($class['methods'] as $methodName => $method) { + if ($method['executableLines'] == 0) { + continue; + } + + $classMethods++; + $classStatements += $method['executableLines']; + $coveredClassStatements += $method['executedLines']; + + if ($method['coverage'] == 100) { + $coveredMethods++; + } + + $methodCount = 0; + + foreach (\range($method['startLine'], $method['endLine']) as $line) { + if (isset($coverageData[$line]) && ($coverageData[$line] !== null)) { + $methodCount = \max($methodCount, \count($coverageData[$line])); + } + } + + $lines[$method['startLine']] = [ + 'ccn' => $method['ccn'], + 'count' => $methodCount, + 'crap' => $method['crap'], + 'type' => 'method', + 'visibility' => $method['visibility'], + 'name' => $methodName, + ]; + } + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $xmlClass = $xmlDocument->createElement('class'); + $xmlClass->setAttribute('name', $className); + $xmlClass->setAttribute('namespace', $namespace); + + if (!empty($class['package']['fullPackage'])) { + $xmlClass->setAttribute( + 'fullPackage', + $class['package']['fullPackage'] + ); + } + + if (!empty($class['package']['category'])) { + $xmlClass->setAttribute( + 'category', + $class['package']['category'] + ); + } + + if (!empty($class['package']['package'])) { + $xmlClass->setAttribute( + 'package', + $class['package']['package'] + ); + } + + if (!empty($class['package']['subpackage'])) { + $xmlClass->setAttribute( + 'subpackage', + $class['package']['subpackage'] + ); + } + + $xmlFile->appendChild($xmlClass); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('complexity', (string) $class['ccn']); + $xmlMetrics->setAttribute('methods', (string) $classMethods); + $xmlMetrics->setAttribute('coveredmethods', (string) $coveredMethods); + $xmlMetrics->setAttribute('conditionals', '0'); + $xmlMetrics->setAttribute('coveredconditionals', '0'); + $xmlMetrics->setAttribute('statements', (string) $classStatements); + $xmlMetrics->setAttribute('coveredstatements', (string) $coveredClassStatements); + $xmlMetrics->setAttribute('elements', (string) ($classMethods + $classStatements /* + conditionals */)); + $xmlMetrics->setAttribute('coveredelements', (string) ($coveredMethods + $coveredClassStatements /* + coveredconditionals */)); + $xmlClass->appendChild($xmlMetrics); + } + + foreach ($coverageData as $line => $data) { + if ($data === null || isset($lines[$line])) { + continue; + } + + $lines[$line] = [ + 'count' => \count($data), 'type' => 'stmt', + ]; + } + + \ksort($lines); + + foreach ($lines as $line => $data) { + $xmlLine = $xmlDocument->createElement('line'); + $xmlLine->setAttribute('num', (string) $line); + $xmlLine->setAttribute('type', $data['type']); + + if (isset($data['name'])) { + $xmlLine->setAttribute('name', $data['name']); + } + + if (isset($data['visibility'])) { + $xmlLine->setAttribute('visibility', $data['visibility']); + } + + if (isset($data['ccn'])) { + $xmlLine->setAttribute('complexity', (string) $data['ccn']); + } + + if (isset($data['crap'])) { + $xmlLine->setAttribute('crap', (string) $data['crap']); + } + + $xmlLine->setAttribute('count', (string) $data['count']); + $xmlFile->appendChild($xmlLine); + } + + $linesOfCode = $item->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('loc', (string) $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['ncloc']); + $xmlMetrics->setAttribute('classes', (string) $item->getNumClassesAndTraits()); + $xmlMetrics->setAttribute('methods', (string) $item->getNumMethods()); + $xmlMetrics->setAttribute('coveredmethods', (string) $item->getNumTestedMethods()); + $xmlMetrics->setAttribute('conditionals', '0'); + $xmlMetrics->setAttribute('coveredconditionals', '0'); + $xmlMetrics->setAttribute('statements', (string) $item->getNumExecutableLines()); + $xmlMetrics->setAttribute('coveredstatements', (string) $item->getNumExecutedLines()); + $xmlMetrics->setAttribute('elements', (string) ($item->getNumMethods() + $item->getNumExecutableLines() /* + conditionals */)); + $xmlMetrics->setAttribute('coveredelements', (string) ($item->getNumTestedMethods() + $item->getNumExecutedLines() /* + coveredconditionals */)); + $xmlFile->appendChild($xmlMetrics); + + if ($namespace === 'global') { + $xmlProject->appendChild($xmlFile); + } else { + if (!isset($packages[$namespace])) { + $packages[$namespace] = $xmlDocument->createElement( + 'package' + ); + + $packages[$namespace]->setAttribute('name', $namespace); + $xmlProject->appendChild($packages[$namespace]); + } + + $packages[$namespace]->appendChild($xmlFile); + } + } + + $linesOfCode = $report->getLinesOfCode(); + + $xmlMetrics = $xmlDocument->createElement('metrics'); + $xmlMetrics->setAttribute('files', (string) \count($report)); + $xmlMetrics->setAttribute('loc', (string) $linesOfCode['loc']); + $xmlMetrics->setAttribute('ncloc', (string) $linesOfCode['ncloc']); + $xmlMetrics->setAttribute('classes', (string) $report->getNumClassesAndTraits()); + $xmlMetrics->setAttribute('methods', (string) $report->getNumMethods()); + $xmlMetrics->setAttribute('coveredmethods', (string) $report->getNumTestedMethods()); + $xmlMetrics->setAttribute('conditionals', '0'); + $xmlMetrics->setAttribute('coveredconditionals', '0'); + $xmlMetrics->setAttribute('statements', (string) $report->getNumExecutableLines()); + $xmlMetrics->setAttribute('coveredstatements', (string) $report->getNumExecutedLines()); + $xmlMetrics->setAttribute('elements', (string) ($report->getNumMethods() + $report->getNumExecutableLines() /* + conditionals */)); + $xmlMetrics->setAttribute('coveredelements', (string) ($report->getNumTestedMethods() + $report->getNumExecutedLines() /* + coveredconditionals */)); + $xmlProject->appendChild($xmlMetrics); + + $buffer = $xmlDocument->saveXML(); + + if ($target !== null) { + if (!$this->createDirectory(\dirname($target))) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', \dirname($target))); + } + + if (@\file_put_contents($target, $buffer) === false) { + throw new RuntimeException( + \sprintf( + 'Could not write to "%s', + $target + ) + ); + } + } + + return $buffer; + } + + private function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php b/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php new file mode 100644 index 0000000..6713be0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Crap4j.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\File; +use SebastianBergmann\CodeCoverage\RuntimeException; + +final class Crap4j +{ + /** + * @var int + */ + private $threshold; + + public function __construct(int $threshold = 30) + { + $this->threshold = $threshold; + } + + /** + * @throws \RuntimeException + */ + public function process(CodeCoverage $coverage, ?string $target = null, ?string $name = null): string + { + $document = new \DOMDocument('1.0', 'UTF-8'); + $document->formatOutput = true; + + $root = $document->createElement('crap_result'); + $document->appendChild($root); + + $project = $document->createElement('project', \is_string($name) ? $name : ''); + $root->appendChild($project); + $root->appendChild($document->createElement('timestamp', \date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']))); + + $stats = $document->createElement('stats'); + $methodsNode = $document->createElement('methods'); + + $report = $coverage->getReport(); + unset($coverage); + + $fullMethodCount = 0; + $fullCrapMethodCount = 0; + $fullCrapLoad = 0; + $fullCrap = 0; + + foreach ($report as $item) { + $namespace = 'global'; + + if (!$item instanceof File) { + continue; + } + + $file = $document->createElement('file'); + $file->setAttribute('name', $item->getPath()); + + $classes = $item->getClassesAndTraits(); + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + $crapLoad = $this->getCrapLoad($method['crap'], $method['ccn'], $method['coverage']); + + $fullCrap += $method['crap']; + $fullCrapLoad += $crapLoad; + $fullMethodCount++; + + if ($method['crap'] >= $this->threshold) { + $fullCrapMethodCount++; + } + + $methodNode = $document->createElement('method'); + + if (!empty($class['package']['namespace'])) { + $namespace = $class['package']['namespace']; + } + + $methodNode->appendChild($document->createElement('package', $namespace)); + $methodNode->appendChild($document->createElement('className', $className)); + $methodNode->appendChild($document->createElement('methodName', $methodName)); + $methodNode->appendChild($document->createElement('methodSignature', \htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('fullMethod', \htmlspecialchars($method['signature']))); + $methodNode->appendChild($document->createElement('crap', (string) $this->roundValue($method['crap']))); + $methodNode->appendChild($document->createElement('complexity', (string) $method['ccn'])); + $methodNode->appendChild($document->createElement('coverage', (string) $this->roundValue($method['coverage']))); + $methodNode->appendChild($document->createElement('crapLoad', (string) \round($crapLoad))); + + $methodsNode->appendChild($methodNode); + } + } + } + + $stats->appendChild($document->createElement('name', 'Method Crap Stats')); + $stats->appendChild($document->createElement('methodCount', (string) $fullMethodCount)); + $stats->appendChild($document->createElement('crapMethodCount', (string) $fullCrapMethodCount)); + $stats->appendChild($document->createElement('crapLoad', (string) \round($fullCrapLoad))); + $stats->appendChild($document->createElement('totalCrap', (string) $fullCrap)); + + $crapMethodPercent = 0; + + if ($fullMethodCount > 0) { + $crapMethodPercent = $this->roundValue((100 * $fullCrapMethodCount) / $fullMethodCount); + } + + $stats->appendChild($document->createElement('crapMethodPercent', (string) $crapMethodPercent)); + + $root->appendChild($stats); + $root->appendChild($methodsNode); + + $buffer = $document->saveXML(); + + if ($target !== null) { + if (!$this->createDirectory(\dirname($target))) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', \dirname($target))); + } + + if (@\file_put_contents($target, $buffer) === false) { + throw new RuntimeException( + \sprintf( + 'Could not write to "%s', + $target + ) + ); + } + } + + return $buffer; + } + + /** + * @param float $crapValue + * @param int $cyclomaticComplexity + * @param float $coveragePercent + */ + private function getCrapLoad($crapValue, $cyclomaticComplexity, $coveragePercent): float + { + $crapLoad = 0; + + if ($crapValue >= $this->threshold) { + $crapLoad += $cyclomaticComplexity * (1.0 - $coveragePercent / 100); + $crapLoad += $cyclomaticComplexity / $this->threshold; + } + + return $crapLoad; + } + + /** + * @param float $value + */ + private function roundValue($value): float + { + return \round($value, 2); + } + + private function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php new file mode 100644 index 0000000..318b49a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Facade.php @@ -0,0 +1,167 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Generates an HTML report from a code coverage object. + */ +final class Facade +{ + /** + * @var string + */ + private $templatePath; + + /** + * @var string + */ + private $generator; + + /** + * @var int + */ + private $lowUpperBound; + + /** + * @var int + */ + private $highLowerBound; + + public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, string $generator = '') + { + $this->generator = $generator; + $this->highLowerBound = $highLowerBound; + $this->lowUpperBound = $lowUpperBound; + $this->templatePath = __DIR__ . '/Renderer/Template/'; + } + + /** + * @throws RuntimeException + * @throws \InvalidArgumentException + * @throws \RuntimeException + */ + public function process(CodeCoverage $coverage, string $target): void + { + $target = $this->getDirectory($target); + $report = $coverage->getReport(); + + if (!isset($_SERVER['REQUEST_TIME'])) { + $_SERVER['REQUEST_TIME'] = \time(); + } + + $date = \date('D M j G:i:s T Y', $_SERVER['REQUEST_TIME']); + + $dashboard = new Dashboard( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory = new Directory( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $file = new File( + $this->templatePath, + $this->generator, + $date, + $this->lowUpperBound, + $this->highLowerBound + ); + + $directory->render($report, $target . 'index.html'); + $dashboard->render($report, $target . 'dashboard.html'); + + foreach ($report as $node) { + $id = $node->getId(); + + if ($node instanceof DirectoryNode) { + if (!$this->createDirectory($target . $id)) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', $target . $id)); + } + + $directory->render($node, $target . $id . '/index.html'); + $dashboard->render($node, $target . $id . '/dashboard.html'); + } else { + $dir = \dirname($target . $id); + + if (!$this->createDirectory($dir)) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', $dir)); + } + + $file->render($node, $target . $id . '.html'); + } + } + + $this->copyFiles($target); + } + + /** + * @throws RuntimeException + */ + private function copyFiles(string $target): void + { + $dir = $this->getDirectory($target . '_css'); + + \copy($this->templatePath . 'css/bootstrap.min.css', $dir . 'bootstrap.min.css'); + \copy($this->templatePath . 'css/nv.d3.min.css', $dir . 'nv.d3.min.css'); + \copy($this->templatePath . 'css/style.css', $dir . 'style.css'); + \copy($this->templatePath . 'css/custom.css', $dir . 'custom.css'); + \copy($this->templatePath . 'css/octicons.css', $dir . 'octicons.css'); + + $dir = $this->getDirectory($target . '_icons'); + \copy($this->templatePath . 'icons/file-code.svg', $dir . 'file-code.svg'); + \copy($this->templatePath . 'icons/file-directory.svg', $dir . 'file-directory.svg'); + + $dir = $this->getDirectory($target . '_js'); + \copy($this->templatePath . 'js/bootstrap.min.js', $dir . 'bootstrap.min.js'); + \copy($this->templatePath . 'js/popper.min.js', $dir . 'popper.min.js'); + \copy($this->templatePath . 'js/d3.min.js', $dir . 'd3.min.js'); + \copy($this->templatePath . 'js/jquery.min.js', $dir . 'jquery.min.js'); + \copy($this->templatePath . 'js/nv.d3.min.js', $dir . 'nv.d3.min.js'); + \copy($this->templatePath . 'js/file.js', $dir . 'file.js'); + } + + /** + * @throws RuntimeException + */ + private function getDirectory(string $directory): string + { + if (\substr($directory, -1, 1) != \DIRECTORY_SEPARATOR) { + $directory .= \DIRECTORY_SEPARATOR; + } + + if (!$this->createDirectory($directory)) { + throw new RuntimeException( + \sprintf( + 'Directory "%s" does not exist.', + $directory + ) + ); + } + + return $directory; + } + + private function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php new file mode 100644 index 0000000..2a9024c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer.php @@ -0,0 +1,277 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\Version; +use SebastianBergmann\Environment\Runtime; + +/** + * Base class for node renderers. + */ +abstract class Renderer +{ + /** + * @var string + */ + protected $templatePath; + + /** + * @var string + */ + protected $generator; + + /** + * @var string + */ + protected $date; + + /** + * @var int + */ + protected $lowUpperBound; + + /** + * @var int + */ + protected $highLowerBound; + + /** + * @var string + */ + protected $version; + + public function __construct(string $templatePath, string $generator, string $date, int $lowUpperBound, int $highLowerBound) + { + $this->templatePath = $templatePath; + $this->generator = $generator; + $this->date = $date; + $this->lowUpperBound = $lowUpperBound; + $this->highLowerBound = $highLowerBound; + $this->version = Version::id(); + } + + protected function renderItemTemplate(\Text_Template $template, array $data): string + { + $numSeparator = ' / '; + + if (isset($data['numClasses']) && $data['numClasses'] > 0) { + $classesLevel = $this->getColorLevel($data['testedClassesPercent']); + + $classesNumber = $data['numTestedClasses'] . $numSeparator . + $data['numClasses']; + + $classesBar = $this->getCoverageBar( + $data['testedClassesPercent'] + ); + } else { + $classesLevel = ''; + $classesNumber = '0' . $numSeparator . '0'; + $classesBar = ''; + $data['testedClassesPercentAsString'] = 'n/a'; + } + + if ($data['numMethods'] > 0) { + $methodsLevel = $this->getColorLevel($data['testedMethodsPercent']); + + $methodsNumber = $data['numTestedMethods'] . $numSeparator . + $data['numMethods']; + + $methodsBar = $this->getCoverageBar( + $data['testedMethodsPercent'] + ); + } else { + $methodsLevel = ''; + $methodsNumber = '0' . $numSeparator . '0'; + $methodsBar = ''; + $data['testedMethodsPercentAsString'] = 'n/a'; + } + + if ($data['numExecutableLines'] > 0) { + $linesLevel = $this->getColorLevel($data['linesExecutedPercent']); + + $linesNumber = $data['numExecutedLines'] . $numSeparator . + $data['numExecutableLines']; + + $linesBar = $this->getCoverageBar( + $data['linesExecutedPercent'] + ); + } else { + $linesLevel = ''; + $linesNumber = '0' . $numSeparator . '0'; + $linesBar = ''; + $data['linesExecutedPercentAsString'] = 'n/a'; + } + + $template->setVar( + [ + 'icon' => $data['icon'] ?? '', + 'crap' => $data['crap'] ?? '', + 'name' => $data['name'], + 'lines_bar' => $linesBar, + 'lines_executed_percent' => $data['linesExecutedPercentAsString'], + 'lines_level' => $linesLevel, + 'lines_number' => $linesNumber, + 'methods_bar' => $methodsBar, + 'methods_tested_percent' => $data['testedMethodsPercentAsString'], + 'methods_level' => $methodsLevel, + 'methods_number' => $methodsNumber, + 'classes_bar' => $classesBar, + 'classes_tested_percent' => $data['testedClassesPercentAsString'] ?? '', + 'classes_level' => $classesLevel, + 'classes_number' => $classesNumber, + ] + ); + + return $template->render(); + } + + protected function setCommonTemplateVariables(\Text_Template $template, AbstractNode $node): void + { + $template->setVar( + [ + 'id' => $node->getId(), + 'full_path' => $node->getPath(), + 'path_to_root' => $this->getPathToRoot($node), + 'breadcrumbs' => $this->getBreadcrumbs($node), + 'date' => $this->date, + 'version' => $this->version, + 'runtime' => $this->getRuntimeString(), + 'generator' => $this->generator, + 'low_upper_bound' => $this->lowUpperBound, + 'high_lower_bound' => $this->highLowerBound, + ] + ); + } + + protected function getBreadcrumbs(AbstractNode $node): string + { + $breadcrumbs = ''; + $path = $node->getPathAsArray(); + $pathToRoot = []; + $max = \count($path); + + if ($node instanceof FileNode) { + $max--; + } + + for ($i = 0; $i < $max; $i++) { + $pathToRoot[] = \str_repeat('../', $i); + } + + foreach ($path as $step) { + if ($step !== $node) { + $breadcrumbs .= $this->getInactiveBreadcrumb( + $step, + \array_pop($pathToRoot) + ); + } else { + $breadcrumbs .= $this->getActiveBreadcrumb($step); + } + } + + return $breadcrumbs; + } + + protected function getActiveBreadcrumb(AbstractNode $node): string + { + $buffer = \sprintf( + ' ' . "\n", + $node->getName() + ); + + if ($node instanceof DirectoryNode) { + $buffer .= ' ' . "\n"; + } + + return $buffer; + } + + protected function getInactiveBreadcrumb(AbstractNode $node, string $pathToRoot): string + { + return \sprintf( + ' ' . "\n", + $pathToRoot, + $node->getName() + ); + } + + protected function getPathToRoot(AbstractNode $node): string + { + $id = $node->getId(); + $depth = \substr_count($id, '/'); + + if ($id !== 'index' && + $node instanceof DirectoryNode) { + $depth++; + } + + return \str_repeat('../', $depth); + } + + protected function getCoverageBar(float $percent): string + { + $level = $this->getColorLevel($percent); + + $template = new \Text_Template( + $this->templatePath . 'coverage_bar.html', + '{{', + '}}' + ); + + $template->setVar(['level' => $level, 'percent' => \sprintf('%.2F', $percent)]); + + return $template->render(); + } + + protected function getColorLevel(float $percent): string + { + if ($percent <= $this->lowUpperBound) { + return 'danger'; + } + + if ($percent > $this->lowUpperBound && + $percent < $this->highLowerBound) { + return 'warning'; + } + + return 'success'; + } + + private function getRuntimeString(): string + { + $runtime = new Runtime; + + $buffer = \sprintf( + '%s %s', + $runtime->getVendorUrl(), + $runtime->getName(), + $runtime->getVersion() + ); + + if ($runtime->hasXdebug() && !$runtime->hasPHPDBGCodeCoverage()) { + $buffer .= \sprintf( + ' with Xdebug %s', + \phpversion('xdebug') + ); + } + + if ($runtime->hasPCOV() && !$runtime->hasPHPDBGCodeCoverage()) { + $buffer .= \sprintf( + ' with PCOV %s', + \phpversion('pcov') + ); + } + + return $buffer; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php new file mode 100644 index 0000000..cc801b6 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Dashboard.php @@ -0,0 +1,281 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; + +/** + * Renders the dashboard for a directory node. + */ +final class Dashboard extends Renderer +{ + /** + * @throws \InvalidArgumentException + * @throws \RuntimeException + */ + public function render(DirectoryNode $node, string $file): void + { + $classes = $node->getClassesAndTraits(); + $template = new \Text_Template( + $this->templatePath . 'dashboard.html', + '{{', + '}}' + ); + + $this->setCommonTemplateVariables($template, $node); + + $baseLink = $node->getId() . '/'; + $complexity = $this->complexity($classes, $baseLink); + $coverageDistribution = $this->coverageDistribution($classes); + $insufficientCoverage = $this->insufficientCoverage($classes, $baseLink); + $projectRisks = $this->projectRisks($classes, $baseLink); + + $template->setVar( + [ + 'insufficient_coverage_classes' => $insufficientCoverage['class'], + 'insufficient_coverage_methods' => $insufficientCoverage['method'], + 'project_risks_classes' => $projectRisks['class'], + 'project_risks_methods' => $projectRisks['method'], + 'complexity_class' => $complexity['class'], + 'complexity_method' => $complexity['method'], + 'class_coverage_distribution' => $coverageDistribution['class'], + 'method_coverage_distribution' => $coverageDistribution['method'], + ] + ); + + $template->renderTo($file); + } + + /** + * Returns the data for the Class/Method Complexity charts. + */ + protected function complexity(array $classes, string $baseLink): array + { + $result = ['class' => [], 'method' => []]; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($className !== '*') { + $methodName = $className . '::' . $methodName; + } + + $result['method'][] = [ + $method['coverage'], + $method['ccn'], + \sprintf( + '%s', + \str_replace($baseLink, '', $method['link']), + $methodName + ), + ]; + } + + $result['class'][] = [ + $class['coverage'], + $class['ccn'], + \sprintf( + '%s', + \str_replace($baseLink, '', $class['link']), + $className + ), + ]; + } + + return [ + 'class' => \json_encode($result['class']), + 'method' => \json_encode($result['method']), + ]; + } + + /** + * Returns the data for the Class / Method Coverage Distribution chart. + */ + protected function coverageDistribution(array $classes): array + { + $result = [ + 'class' => [ + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0, + ], + 'method' => [ + '0%' => 0, + '0-10%' => 0, + '10-20%' => 0, + '20-30%' => 0, + '30-40%' => 0, + '40-50%' => 0, + '50-60%' => 0, + '60-70%' => 0, + '70-80%' => 0, + '80-90%' => 0, + '90-100%' => 0, + '100%' => 0, + ], + ]; + + foreach ($classes as $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] === 0) { + $result['method']['0%']++; + } elseif ($method['coverage'] === 100) { + $result['method']['100%']++; + } else { + $key = \floor($method['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['method'][$key]++; + } + } + + if ($class['coverage'] === 0) { + $result['class']['0%']++; + } elseif ($class['coverage'] === 100) { + $result['class']['100%']++; + } else { + $key = \floor($class['coverage'] / 10) * 10; + $key = $key . '-' . ($key + 10) . '%'; + $result['class'][$key]++; + } + } + + return [ + 'class' => \json_encode(\array_values($result['class'])), + 'method' => \json_encode(\array_values($result['method'])), + ]; + } + + /** + * Returns the classes / methods with insufficient coverage. + */ + protected function insufficientCoverage(array $classes, string $baseLink): array + { + $leastTestedClasses = []; + $leastTestedMethods = []; + $result = ['class' => '', 'method' => '']; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound) { + $key = $methodName; + + if ($className !== '*') { + $key = $className . '::' . $methodName; + } + + $leastTestedMethods[$key] = $method['coverage']; + } + } + + if ($class['coverage'] < $this->highLowerBound) { + $leastTestedClasses[$className] = $class['coverage']; + } + } + + \asort($leastTestedClasses); + \asort($leastTestedMethods); + + foreach ($leastTestedClasses as $className => $coverage) { + $result['class'] .= \sprintf( + ' %s%d%%' . "\n", + \str_replace($baseLink, '', $classes[$className]['link']), + $className, + $coverage + ); + } + + foreach ($leastTestedMethods as $methodName => $coverage) { + [$class, $method] = \explode('::', $methodName); + + $result['method'] .= \sprintf( + ' %s%d%%' . "\n", + \str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $coverage + ); + } + + return $result; + } + + /** + * Returns the project risks according to the CRAP index. + */ + protected function projectRisks(array $classes, string $baseLink): array + { + $classRisks = []; + $methodRisks = []; + $result = ['class' => '', 'method' => '']; + + foreach ($classes as $className => $class) { + foreach ($class['methods'] as $methodName => $method) { + if ($method['coverage'] < $this->highLowerBound && $method['ccn'] > 1) { + $key = $methodName; + + if ($className !== '*') { + $key = $className . '::' . $methodName; + } + + $methodRisks[$key] = $method['crap']; + } + } + + if ($class['coverage'] < $this->highLowerBound && + $class['ccn'] > \count($class['methods'])) { + $classRisks[$className] = $class['crap']; + } + } + + \arsort($classRisks); + \arsort($methodRisks); + + foreach ($classRisks as $className => $crap) { + $result['class'] .= \sprintf( + ' %s%d' . "\n", + \str_replace($baseLink, '', $classes[$className]['link']), + $className, + $crap + ); + } + + foreach ($methodRisks as $methodName => $crap) { + [$class, $method] = \explode('::', $methodName); + + $result['method'] .= \sprintf( + ' %s%d' . "\n", + \str_replace($baseLink, '', $classes[$class]['methods'][$method]['link']), + $methodName, + $method, + $crap + ); + } + + return $result; + } + + protected function getActiveBreadcrumb(AbstractNode $node): string + { + return \sprintf( + ' ' . "\n" . + ' ' . "\n", + $node->getName() + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php new file mode 100644 index 0000000..c2f0860 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Directory.php @@ -0,0 +1,98 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\AbstractNode as Node; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; + +/** + * Renders a directory node. + */ +final class Directory extends Renderer +{ + /** + * @throws \InvalidArgumentException + * @throws \RuntimeException + */ + public function render(DirectoryNode $node, string $file): void + { + $template = new \Text_Template($this->templatePath . 'directory.html', '{{', '}}'); + + $this->setCommonTemplateVariables($template, $node); + + $items = $this->renderItem($node, true); + + foreach ($node->getDirectories() as $item) { + $items .= $this->renderItem($item); + } + + foreach ($node->getFiles() as $item) { + $items .= $this->renderItem($item); + } + + $template->setVar( + [ + 'id' => $node->getId(), + 'items' => $items, + ] + ); + + $template->renderTo($file); + } + + protected function renderItem(Node $node, bool $total = false): string + { + $data = [ + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumFunctionsAndMethods(), + 'numTestedMethods' => $node->getNumTestedFunctionsAndMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedFunctionsAndMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(), + ]; + + if ($total) { + $data['name'] = 'Total'; + } else { + if ($node instanceof DirectoryNode) { + $data['name'] = \sprintf( + '%s', + $node->getName(), + $node->getName() + ); + + $up = \str_repeat('../', \count($node->getPathAsArray()) - 2); + + $data['icon'] = \sprintf('', $up); + } else { + $data['name'] = \sprintf( + '%s', + $node->getName(), + $node->getName() + ); + + $up = \str_repeat('../', \count($node->getPathAsArray()) - 2); + + $data['icon'] = \sprintf('', $up); + } + } + + return $this->renderItemTemplate( + new \Text_Template($this->templatePath . 'directory_item.html', '{{', '}}'), + $data + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php new file mode 100644 index 0000000..f0604bf --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/File.php @@ -0,0 +1,529 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\Util; + +/** + * Renders a file node. + */ +final class File extends Renderer +{ + /** + * @var int + */ + private $htmlSpecialCharsFlags = \ENT_COMPAT | \ENT_HTML401 | \ENT_SUBSTITUTE; + + /** + * @throws \RuntimeException + */ + public function render(FileNode $node, string $file): void + { + $template = new \Text_Template($this->templatePath . 'file.html', '{{', '}}'); + + $template->setVar( + [ + 'items' => $this->renderItems($node), + 'lines' => $this->renderSource($node), + ] + ); + + $this->setCommonTemplateVariables($template, $node); + + $template->renderTo($file); + } + + protected function renderItems(FileNode $node): string + { + $template = new \Text_Template($this->templatePath . 'file_item.html', '{{', '}}'); + + $methodItemTemplate = new \Text_Template( + $this->templatePath . 'method_item.html', + '{{', + '}}' + ); + + $items = $this->renderItemTemplate( + $template, + [ + 'name' => 'Total', + 'numClasses' => $node->getNumClassesAndTraits(), + 'numTestedClasses' => $node->getNumTestedClassesAndTraits(), + 'numMethods' => $node->getNumFunctionsAndMethods(), + 'numTestedMethods' => $node->getNumTestedFunctionsAndMethods(), + 'linesExecutedPercent' => $node->getLineExecutedPercent(false), + 'linesExecutedPercentAsString' => $node->getLineExecutedPercent(), + 'numExecutedLines' => $node->getNumExecutedLines(), + 'numExecutableLines' => $node->getNumExecutableLines(), + 'testedMethodsPercent' => $node->getTestedFunctionsAndMethodsPercent(false), + 'testedMethodsPercentAsString' => $node->getTestedFunctionsAndMethodsPercent(), + 'testedClassesPercent' => $node->getTestedClassesAndTraitsPercent(false), + 'testedClassesPercentAsString' => $node->getTestedClassesAndTraitsPercent(), + 'crap' => 'CRAP', + ] + ); + + $items .= $this->renderFunctionItems( + $node->getFunctions(), + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getTraits(), + $template, + $methodItemTemplate + ); + + $items .= $this->renderTraitOrClassItems( + $node->getClasses(), + $template, + $methodItemTemplate + ); + + return $items; + } + + protected function renderTraitOrClassItems(array $items, \Text_Template $template, \Text_Template $methodItemTemplate): string + { + $buffer = ''; + + if (empty($items)) { + return $buffer; + } + + foreach ($items as $name => $item) { + $numMethods = 0; + $numTestedMethods = 0; + + foreach ($item['methods'] as $method) { + if ($method['executableLines'] > 0) { + $numMethods++; + + if ($method['executedLines'] === $method['executableLines']) { + $numTestedMethods++; + } + } + } + + if ($item['executableLines'] > 0) { + $numClasses = 1; + $numTestedClasses = $numTestedMethods == $numMethods ? 1 : 0; + $linesExecutedPercentAsString = Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ); + } else { + $numClasses = 'n/a'; + $numTestedClasses = 'n/a'; + $linesExecutedPercentAsString = 'n/a'; + } + + $buffer .= $this->renderItemTemplate( + $template, + [ + 'name' => $this->abbreviateClassName($name), + 'numClasses' => $numClasses, + 'numTestedClasses' => $numTestedClasses, + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'], + false + ), + 'linesExecutedPercentAsString' => $linesExecutedPercentAsString, + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedMethods, + $numMethods + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedMethods, + $numMethods, + true + ), + 'testedClassesPercent' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1 + ), + 'testedClassesPercentAsString' => Util::percent( + $numTestedMethods == $numMethods ? 1 : 0, + 1, + true + ), + 'crap' => $item['crap'], + ] + ); + + foreach ($item['methods'] as $method) { + $buffer .= $this->renderFunctionOrMethodItem( + $methodItemTemplate, + $method, + ' ' + ); + } + } + + return $buffer; + } + + protected function renderFunctionItems(array $functions, \Text_Template $template): string + { + if (empty($functions)) { + return ''; + } + + $buffer = ''; + + foreach ($functions as $function) { + $buffer .= $this->renderFunctionOrMethodItem( + $template, + $function + ); + } + + return $buffer; + } + + protected function renderFunctionOrMethodItem(\Text_Template $template, array $item, string $indent = ''): string + { + $numMethods = 0; + $numTestedMethods = 0; + + if ($item['executableLines'] > 0) { + $numMethods = 1; + + if ($item['executedLines'] === $item['executableLines']) { + $numTestedMethods = 1; + } + } + + return $this->renderItemTemplate( + $template, + [ + 'name' => \sprintf( + '%s%s', + $indent, + $item['startLine'], + \htmlspecialchars($item['signature'], $this->htmlSpecialCharsFlags), + $item['functionName'] ?? $item['methodName'] + ), + 'numMethods' => $numMethods, + 'numTestedMethods' => $numTestedMethods, + 'linesExecutedPercent' => Util::percent( + $item['executedLines'], + $item['executableLines'] + ), + 'linesExecutedPercentAsString' => Util::percent( + $item['executedLines'], + $item['executableLines'], + true + ), + 'numExecutedLines' => $item['executedLines'], + 'numExecutableLines' => $item['executableLines'], + 'testedMethodsPercent' => Util::percent( + $numTestedMethods, + 1 + ), + 'testedMethodsPercentAsString' => Util::percent( + $numTestedMethods, + 1, + true + ), + 'crap' => $item['crap'], + ] + ); + } + + protected function renderSource(FileNode $node): string + { + $coverageData = $node->getCoverageData(); + $testData = $node->getTestData(); + $codeLines = $this->loadFile($node->getPath()); + $lines = ''; + $i = 1; + + foreach ($codeLines as $line) { + $trClass = ''; + $popoverContent = ''; + $popoverTitle = ''; + + if (\array_key_exists($i, $coverageData)) { + $numTests = ($coverageData[$i] ? \count($coverageData[$i]) : 0); + + if ($coverageData[$i] === null) { + $trClass = ' class="warning"'; + } elseif ($numTests == 0) { + $trClass = ' class="danger"'; + } else { + $lineCss = 'covered-by-large-tests'; + $popoverContent = '
    '; + + if ($numTests > 1) { + $popoverTitle = $numTests . ' tests cover line ' . $i; + } else { + $popoverTitle = '1 test covers line ' . $i; + } + + foreach ($coverageData[$i] as $test) { + if ($lineCss == 'covered-by-large-tests' && $testData[$test]['size'] == 'medium') { + $lineCss = 'covered-by-medium-tests'; + } elseif ($testData[$test]['size'] == 'small') { + $lineCss = 'covered-by-small-tests'; + } + + switch ($testData[$test]['status']) { + case 0: + switch ($testData[$test]['size']) { + case 'small': + $testCSS = ' class="covered-by-small-tests"'; + + break; + + case 'medium': + $testCSS = ' class="covered-by-medium-tests"'; + + break; + + default: + $testCSS = ' class="covered-by-large-tests"'; + + break; + } + + break; + + case 1: + case 2: + $testCSS = ' class="warning"'; + + break; + + case 3: + $testCSS = ' class="danger"'; + + break; + + case 4: + $testCSS = ' class="danger"'; + + break; + + default: + $testCSS = ''; + } + + $popoverContent .= \sprintf( + '%s', + $testCSS, + \htmlspecialchars($test, $this->htmlSpecialCharsFlags) + ); + } + + $popoverContent .= '
'; + $trClass = ' class="' . $lineCss . ' popin"'; + } + } + + $popover = ''; + + if (!empty($popoverTitle)) { + $popover = \sprintf( + ' data-title="%s" data-content="%s" data-placement="top" data-html="true"', + $popoverTitle, + \htmlspecialchars($popoverContent, $this->htmlSpecialCharsFlags) + ); + } + + $lines .= \sprintf( + ' %s' . "\n", + $trClass, + $popover, + $i, + $i, + $i, + $line + ); + + $i++; + } + + return $lines; + } + + /** + * @param string $file + */ + protected function loadFile($file): array + { + $buffer = \file_get_contents($file); + $tokens = \token_get_all($buffer); + $result = ['']; + $i = 0; + $stringFlag = false; + $fileEndsWithNewLine = \substr($buffer, -1) == "\n"; + + unset($buffer); + + foreach ($tokens as $j => $token) { + if (\is_string($token)) { + if ($token === '"' && $tokens[$j - 1] !== '\\') { + $result[$i] .= \sprintf( + '%s', + \htmlspecialchars($token, $this->htmlSpecialCharsFlags) + ); + + $stringFlag = !$stringFlag; + } else { + $result[$i] .= \sprintf( + '%s', + \htmlspecialchars($token, $this->htmlSpecialCharsFlags) + ); + } + + continue; + } + + [$token, $value] = $token; + + $value = \str_replace( + ["\t", ' '], + ['    ', ' '], + \htmlspecialchars($value, $this->htmlSpecialCharsFlags) + ); + + if ($value === "\n") { + $result[++$i] = ''; + } else { + $lines = \explode("\n", $value); + + foreach ($lines as $jj => $line) { + $line = \trim($line); + + if ($line !== '') { + if ($stringFlag) { + $colour = 'string'; + } else { + switch ($token) { + case \T_INLINE_HTML: + $colour = 'html'; + + break; + + case \T_COMMENT: + case \T_DOC_COMMENT: + $colour = 'comment'; + + break; + + case \T_ABSTRACT: + case \T_ARRAY: + case \T_AS: + case \T_BREAK: + case \T_CALLABLE: + case \T_CASE: + case \T_CATCH: + case \T_CLASS: + case \T_CLONE: + case \T_CONTINUE: + case \T_DEFAULT: + case \T_ECHO: + case \T_ELSE: + case \T_ELSEIF: + case \T_EMPTY: + case \T_ENDDECLARE: + case \T_ENDFOR: + case \T_ENDFOREACH: + case \T_ENDIF: + case \T_ENDSWITCH: + case \T_ENDWHILE: + case \T_EXIT: + case \T_EXTENDS: + case \T_FINAL: + case \T_FINALLY: + case \T_FOREACH: + case \T_FUNCTION: + case \T_GLOBAL: + case \T_IF: + case \T_IMPLEMENTS: + case \T_INCLUDE: + case \T_INCLUDE_ONCE: + case \T_INSTANCEOF: + case \T_INSTEADOF: + case \T_INTERFACE: + case \T_ISSET: + case \T_LOGICAL_AND: + case \T_LOGICAL_OR: + case \T_LOGICAL_XOR: + case \T_NAMESPACE: + case \T_NEW: + case \T_PRIVATE: + case \T_PROTECTED: + case \T_PUBLIC: + case \T_REQUIRE: + case \T_REQUIRE_ONCE: + case \T_RETURN: + case \T_STATIC: + case \T_THROW: + case \T_TRAIT: + case \T_TRY: + case \T_UNSET: + case \T_USE: + case \T_VAR: + case \T_WHILE: + case \T_YIELD: + $colour = 'keyword'; + + break; + + default: + $colour = 'default'; + } + } + + $result[$i] .= \sprintf( + '%s', + $colour, + $line + ); + } + + if (isset($lines[$jj + 1])) { + $result[++$i] = ''; + } + } + } + } + + if ($fileEndsWithNewLine) { + unset($result[\count($result) - 1]); + } + + return $result; + } + + private function abbreviateClassName(string $className): string + { + $tmp = \explode('\\', $className); + + if (\count($tmp) > 1) { + $className = \sprintf( + '%s', + $className, + \array_pop($tmp) + ); + } + + return $className; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist new file mode 100644 index 0000000..7fcf6f4 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/coverage_bar.html.dist @@ -0,0 +1,5 @@ +
+
+ {{percent}}% covered ({{level}}) +
+
diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css new file mode 100644 index 0000000..92e3fe8 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/bootstrap.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:transparent}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-weight:500;line-height:1.2}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014\00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.5em + .5rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(1.5em + 1rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{border-color:#28a745}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label::before{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:calc(1.5em + .75rem);background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E");background-repeat:no-repeat;background-position:center right calc(.375em + .1875rem);background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:calc(1.5em + .75rem);background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc((1em + .75rem) * 3 / 4 + 1.75rem);background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23dc3545' viewBox='-2 -2 7 7'%3e%3cpath stroke='%23dc3545' d='M0 0l3 3m0-3L0 3'/%3e%3ccircle r='.5'/%3e%3ccircle cx='3' r='.5'/%3e%3ccircle cy='3' r='.5'/%3e%3ccircle cx='3' cy='3' r='.5'/%3e%3c/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{border-color:#dc3545}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label::before{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;-ms-flex-negative:0;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:underline}.btn-link.focus,.btn-link:focus{text-decoration:underline;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:1 1 auto;flex:1 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(1.5em + 1rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.5em + .5rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;border-color:#007bff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:focus:not(:checked)~.custom-control-label::before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label::before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";background-color:#fff;border:#adb5bd solid 1px}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{border-color:#007bff;background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3e%3cpath stroke='%23fff' d='M0 2h4'/%3e%3c/svg%3e")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label::before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label::after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label::after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label::after{background-color:#fff;-webkit-transform:translateX(.75rem);transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3e%3cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3e%3c/svg%3e") no-repeat right .75rem center/8px 10px;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select-sm{height:calc(1.5em + .5rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:.875rem}.custom-select-lg{height:calc(1.5em + 1rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:1.25rem}.custom-file{position:relative;display:inline-block;width:100%;height:calc(1.5em + .75rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(1.5em + .75rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]::after{content:attr(data-browse)}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(1.5em + .75rem + 2px);padding:.375rem .75rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(1.5em + .75rem);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:calc(1rem + .4rem);padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml,%3csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3e%3cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion>.card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion>.card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.accordion>.card .card-header{margin-bottom:-1px}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#212529;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#212529;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#212529;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#212529;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-horizontal{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}@media (min-width:576px){.list-group-horizontal-sm{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-sm .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-sm .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:768px){.list-group-horizontal-md{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-md .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-md .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:992px){.list-group-horizontal-lg{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-lg .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-lg .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}@media (min-width:1200px){.list-group-horizontal-xl{-ms-flex-direction:row;flex-direction:row}.list-group-horizontal-xl .list-group-item{margin-right:-1px;margin-bottom:0}.list-group-horizontal-xl .list-group-item:first-child{border-top-left-radius:.25rem;border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{margin-right:0;border-top-right-radius:.25rem;border-bottom-right-radius:.25rem;border-bottom-left-radius:0}}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush .list-group-item:last-child{margin-bottom:-1px}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{margin-bottom:0;border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:rgba(255,255,255,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:rgba(255,255,255,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-50px);transform:translate(0,-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:none;transform:none}.modal-dialog-scrollable{display:-ms-flexbox;display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{-ms-flex-negative:0;flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered::before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable::before{content:none}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem 1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem 1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #dee2e6;border-bottom-right-radius:.3rem;border-bottom-left-radius:.3rem}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered::before{height:calc(100vh - 3.5rem)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,"Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top]>.arrow::before,.bs-popover-top>.arrow::before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow::after,.bs-popover-top>.arrow::after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow::before,.bs-popover-right>.arrow::before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow::after,.bs-popover-right>.arrow::after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom]>.arrow::before,.bs-popover-bottom>.arrow::before{top:0;border-width:0 .5rem .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow::after,.bs-popover-bottom>.arrow::after{top:1px;border-width:0 .5rem .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow::before,.bs-popover-left>.arrow::before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow::after,.bs-popover-left>.arrow::after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{-ms-touch-action:pan-y;touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner::after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:-webkit-transform .6s ease-in-out;transition:transform .6s ease-in-out;transition:transform .6s ease-in-out,-webkit-transform .6s ease-in-out}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){-webkit-transform:translateX(100%);transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){-webkit-transform:translateX(-100%);transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;-webkit-transform:none;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:0s .6s opacity}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3e%3c/svg%3e")}.carousel-control-next-icon{background-image:url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3e%3cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3e%3c/svg%3e")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-border{to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid currentColor;border-right-color:transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{-webkit-transform:scale(0);transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link::after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:rgba(0,0,0,0)}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/custom.css new file mode 100644 index 0000000..e69de29 diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css new file mode 100644 index 0000000..7a6f7fe --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/nv.d3.min.css @@ -0,0 +1 @@ +.nvd3 .nv-axis{pointer-events:none;opacity:1}.nvd3 .nv-axis path{fill:none;stroke:#000;stroke-opacity:.75;shape-rendering:crispEdges}.nvd3 .nv-axis path.domain{stroke-opacity:.75}.nvd3 .nv-axis.nv-x path.domain{stroke-opacity:0}.nvd3 .nv-axis line{fill:none;stroke:#e5e5e5;shape-rendering:crispEdges}.nvd3 .nv-axis .zero line,.nvd3 .nv-axis line.zero{stroke-opacity:.75}.nvd3 .nv-axis .nv-axisMaxMin text{font-weight:700}.nvd3 .x .nv-axis .nv-axisMaxMin text,.nvd3 .x2 .nv-axis .nv-axisMaxMin text,.nvd3 .x3 .nv-axis .nv-axisMaxMin text{text-anchor:middle}.nvd3 .nv-axis.nv-disabled{opacity:0}.nvd3 .nv-bars rect{fill-opacity:.75;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-bars rect.hover{fill-opacity:1}.nvd3 .nv-bars .hover rect{fill:#add8e6}.nvd3 .nv-bars text{fill:rgba(0,0,0,0)}.nvd3 .nv-bars .hover text{fill:rgba(0,0,0,1)}.nvd3 .nv-multibar .nv-groups rect,.nvd3 .nv-multibarHorizontal .nv-groups rect,.nvd3 .nv-discretebar .nv-groups rect{stroke-opacity:0;transition:fill-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear}.nvd3 .nv-multibar .nv-groups rect:hover,.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,.nvd3 .nv-candlestickBar .nv-ticks rect:hover,.nvd3 .nv-discretebar .nv-groups rect:hover{fill-opacity:1}.nvd3 .nv-discretebar .nv-groups text,.nvd3 .nv-multibarHorizontal .nv-groups text{font-weight:700;fill:rgba(0,0,0,1);stroke:rgba(0,0,0,0)}.nvd3 .nv-boxplot circle{fill-opacity:.5}.nvd3 .nv-boxplot circle:hover{fill-opacity:1}.nvd3 .nv-boxplot rect:hover{fill-opacity:1}.nvd3 line.nv-boxplot-median{stroke:#000}.nv-boxplot-tick:hover{stroke-width:2.5px}.nvd3.nv-bullet{font:10px sans-serif}.nvd3.nv-bullet .nv-measure{fill-opacity:.8}.nvd3.nv-bullet .nv-measure:hover{fill-opacity:1}.nvd3.nv-bullet .nv-marker{stroke:#000;stroke-width:2px}.nvd3.nv-bullet .nv-markerTriangle{stroke:#000;fill:#fff;stroke-width:1.5px}.nvd3.nv-bullet .nv-tick line{stroke:#666;stroke-width:.5px}.nvd3.nv-bullet .nv-range.nv-s0{fill:#eee}.nvd3.nv-bullet .nv-range.nv-s1{fill:#ddd}.nvd3.nv-bullet .nv-range.nv-s2{fill:#ccc}.nvd3.nv-bullet .nv-title{font-size:14px;font-weight:700}.nvd3.nv-bullet .nv-subtitle{fill:#999}.nvd3.nv-bullet .nv-range{fill:#bababa;fill-opacity:.4}.nvd3.nv-bullet .nv-range:hover{fill-opacity:.7}.nvd3.nv-candlestickBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.positive rect{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-candlestickBar .nv-ticks .nv-tick.negative rect{stroke:#d62728;fill:#d62728}.with-transitions .nv-candlestickBar .nv-ticks .nv-tick{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-candlestickBar .nv-ticks line{stroke:#333}.nvd3 .nv-legend .nv-disabled rect{}.nvd3 .nv-check-box .nv-box{fill-opacity:0;stroke-width:2}.nvd3 .nv-check-box .nv-check{fill-opacity:0;stroke-width:4}.nvd3 .nv-series.nv-disabled .nv-check-box .nv-check{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-controlsWrap .nv-legend .nv-check-box .nv-check{opacity:0}.nvd3.nv-linePlusBar .nv-bar rect{fill-opacity:.75}.nvd3.nv-linePlusBar .nv-bar rect:hover{fill-opacity:1}.nvd3 .nv-groups path.nv-line{fill:none}.nvd3 .nv-groups path.nv-area{stroke:none}.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point{fill-opacity:0;stroke-opacity:0}.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point{fill-opacity:.5!important;stroke-opacity:.5!important}.with-transitions .nvd3 .nv-groups .nv-point{transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-scatter .nv-groups .nv-point.hover,.nvd3 .nv-groups .nv-point.hover{stroke-width:7px;fill-opacity:.95!important;stroke-opacity:.95!important}.nvd3 .nv-point-paths path{stroke:#aaa;stroke-opacity:0;fill:#eee;fill-opacity:0}.nvd3 .nv-indexLine{cursor:ew-resize}svg.nvd3-svg{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-ms-user-select:none;-moz-user-select:none;user-select:none;display:block;width:100%;height:100%}.nvtooltip.with-3d-shadow,.with-3d-shadow .nvtooltip{-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.nvd3 text{font:400 12px Arial}.nvd3 .title{font:700 14px Arial}.nvd3 .nv-background{fill:#fff;fill-opacity:0}.nvd3.nv-noData{font-size:18px;font-weight:700}.nv-brush .extent{fill-opacity:.125;shape-rendering:crispEdges}.nv-brush .resize path{fill:#eee;stroke:#666}.nvd3 .nv-legend .nv-series{cursor:pointer}.nvd3 .nv-legend .nv-disabled circle{fill-opacity:0}.nvd3 .nv-brush .extent{fill-opacity:0!important}.nvd3 .nv-brushBackground rect{stroke:#000;stroke-width:.4;fill:#fff;fill-opacity:.7}.nvd3.nv-ohlcBar .nv-ticks .nv-tick{stroke-width:1px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.hover{stroke-width:2px}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.positive{stroke:#2ca02c}.nvd3.nv-ohlcBar .nv-ticks .nv-tick.negative{stroke:#d62728}.nvd3 .background path{fill:none;stroke:#EEE;stroke-opacity:.4;shape-rendering:crispEdges}.nvd3 .foreground path{fill:none;stroke-opacity:.7}.nvd3 .nv-parallelCoordinates-brush .extent{fill:#fff;fill-opacity:.6;stroke:gray;shape-rendering:crispEdges}.nvd3 .nv-parallelCoordinates .hover{fill-opacity:1;stroke-width:3px}.nvd3 .missingValuesline line{fill:none;stroke:#000;stroke-width:1;stroke-opacity:1;stroke-dasharray:5,5}.nvd3.nv-pie path{stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-width 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-pie .nv-pie-title{font-size:24px;fill:rgba(19,196,249,.59)}.nvd3.nv-pie .nv-slice text{stroke:#000;stroke-width:0}.nvd3.nv-pie path{stroke:#fff;stroke-width:1px;stroke-opacity:1}.nvd3.nv-pie .hover path{fill-opacity:.7}.nvd3.nv-pie .nv-label{pointer-events:none}.nvd3.nv-pie .nv-label rect{fill-opacity:0;stroke-opacity:0}.nvd3 .nv-groups .nv-point.hover{stroke-width:20px;stroke-opacity:.5}.nvd3 .nv-scatter .nv-point.hover{fill-opacity:1}.nv-noninteractive{pointer-events:none}.nv-distx,.nv-disty{pointer-events:none}.nvd3.nv-sparkline path{fill:none}.nvd3.nv-sparklineplus g.nv-hoverValue{pointer-events:none}.nvd3.nv-sparklineplus .nv-hoverValue line{stroke:#333;stroke-width:1.5px}.nvd3.nv-sparklineplus,.nvd3.nv-sparklineplus g{pointer-events:all}.nvd3 .nv-hoverArea{fill-opacity:0;stroke-opacity:0}.nvd3.nv-sparklineplus .nv-xValue,.nvd3.nv-sparklineplus .nv-yValue{stroke-width:0;font-size:.9em;font-weight:400}.nvd3.nv-sparklineplus .nv-yValue{stroke:#f66}.nvd3.nv-sparklineplus .nv-maxValue{stroke:#2ca02c;fill:#2ca02c}.nvd3.nv-sparklineplus .nv-minValue{stroke:#d62728;fill:#d62728}.nvd3.nv-sparklineplus .nv-currentValue{font-weight:700;font-size:1.1em}.nvd3.nv-stackedarea path.nv-area{fill-opacity:.7;stroke-opacity:0;transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-moz-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear;-webkit-transition:fill-opacity 250ms linear,stroke-opacity 250ms linear}.nvd3.nv-stackedarea path.nv-area.hover{fill-opacity:.9}.nvd3.nv-stackedarea .nv-groups .nv-point{stroke-opacity:0;fill-opacity:0}.nvtooltip{position:absolute;background-color:rgba(255,255,255,1);color:rgba(0,0,0,1);padding:1px;border:1px solid rgba(0,0,0,.2);z-index:10000;display:block;font-family:Arial;font-size:13px;text-align:left;pointer-events:none;white-space:nowrap;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.nvtooltip{background:rgba(255,255,255,.8);border:1px solid rgba(0,0,0,.5);border-radius:4px}.nvtooltip.with-transitions,.with-transitions .nvtooltip{transition:opacity 50ms linear;-moz-transition:opacity 50ms linear;-webkit-transition:opacity 50ms linear;transition-delay:200ms;-moz-transition-delay:200ms;-webkit-transition-delay:200ms}.nvtooltip.x-nvtooltip,.nvtooltip.y-nvtooltip{padding:8px}.nvtooltip h3{margin:0;padding:4px 14px;line-height:18px;font-weight:400;background-color:rgba(247,247,247,.75);color:rgba(0,0,0,1);text-align:center;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0}.nvtooltip p{margin:0;padding:5px 14px;text-align:center}.nvtooltip span{display:inline-block;margin:2px 0}.nvtooltip table{margin:6px;border-spacing:0}.nvtooltip table td{padding:2px 9px 2px 0;vertical-align:middle}.nvtooltip table td.key{font-weight:400}.nvtooltip table td.value{text-align:right;font-weight:700}.nvtooltip table tr.highlight td{padding:1px 9px 1px 0;border-bottom-style:solid;border-bottom-width:1px;border-top-style:solid;border-top-width:1px}.nvtooltip table td.legend-color-guide div{width:8px;height:8px;vertical-align:middle}.nvtooltip table td.legend-color-guide div{width:12px;height:12px;border:1px solid #999}.nvtooltip .footer{padding:3px;text-align:center}.nvtooltip-pending-removal{pointer-events:none;display:none}.nvd3 .nv-interactiveGuideLine{pointer-events:none}.nvd3 line.nv-guideline{stroke:#ccc} \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css new file mode 100644 index 0000000..31d9786 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/octicons.css @@ -0,0 +1,5 @@ +.octicon { + display: inline-block; + vertical-align: text-top; + fill: currentColor; +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css new file mode 100644 index 0000000..6d9c21e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/css/style.css @@ -0,0 +1,122 @@ +body { + padding-top: 10px; +} + +.popover { + max-width: none; +} + +.octicon { + margin-right:.25em; +} + +.table-bordered>thead>tr>td { + border-bottom-width: 1px; +} + +.table tbody>tr>td, .table thead>tr>td { + padding-top: 3px; + padding-bottom: 3px; +} + +.table-condensed tbody>tr>td { + padding-top: 0; + padding-bottom: 0; +} + +.table .progress { + margin-bottom: inherit; +} + +.table-borderless th, .table-borderless td { + border: 0 !important; +} + +.table tbody tr.covered-by-large-tests, li.covered-by-large-tests, tr.success, td.success, li.success, span.success { + background-color: #dff0d8; +} + +.table tbody tr.covered-by-medium-tests, li.covered-by-medium-tests { + background-color: #c3e3b5; +} + +.table tbody tr.covered-by-small-tests, li.covered-by-small-tests { + background-color: #99cb84; +} + +.table tbody tr.danger, .table tbody td.danger, li.danger, span.danger { + background-color: #f2dede; +} + +.table tbody td.warning, li.warning, span.warning { + background-color: #fcf8e3; +} + +.table tbody td.info { + background-color: #d9edf7; +} + +td.big { + width: 117px; +} + +td.small { +} + +td.codeLine { + font-family: "Source Code Pro", "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; + white-space: pre; +} + +td span.comment { + color: #888a85; +} + +td span.default { + color: #2e3436; +} + +td span.html { + color: #888a85; +} + +td span.keyword { + color: #2e3436; + font-weight: bold; +} + +pre span.string { + color: #2e3436; +} + +span.success, span.warning, span.danger { + margin-right: 2px; + padding-left: 10px; + padding-right: 10px; + text-align: center; +} + +#classCoverageDistribution, #classComplexity { + height: 200px; + width: 475px; +} + +#toplink { + position: fixed; + left: 5px; + bottom: 5px; + outline: 0; +} + +svg text { + font-family: "Lucida Grande", "Lucida Sans Unicode", Verdana, Arial, Helvetica, sans-serif; + font-size: 11px; + color: #666; + fill: #666; +} + +.scrollbox { + height:245px; + overflow-x:hidden; + overflow-y:scroll; +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist new file mode 100644 index 0000000..aa51bcb --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/dashboard.html.dist @@ -0,0 +1,281 @@ + + + + + Dashboard for {{full_path}} + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+
+

Classes

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + +{{insufficient_coverage_classes}} + +
ClassCoverage
+
+
+
+

Project Risks

+
+ + + + + + + + +{{project_risks_classes}} + +
ClassCRAP
+
+
+
+
+
+

Methods

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + +{{insufficient_coverage_methods}} + +
MethodCoverage
+
+
+
+

Project Risks

+
+ + + + + + + + +{{project_risks_methods}} + +
MethodCRAP
+
+
+
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist new file mode 100644 index 0000000..a263463 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory.html.dist @@ -0,0 +1,60 @@ + + + + + Code Coverage for {{full_path}} + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + +{{items}} + +
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
+
+
+
+

Legend

+

+ Low: 0% to {{low_upper_bound}}% + Medium: {{low_upper_bound}}% to {{high_lower_bound}}% + High: {{high_lower_bound}}% to 100% +

+

+ Generated by php-code-coverage {{version}} using {{runtime}}{{generator}} at {{date}}. +

+
+
+ + diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist new file mode 100644 index 0000000..f6941a4 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/directory_item.html.dist @@ -0,0 +1,13 @@ + + {{icon}}{{name}} + {{lines_bar}} +
{{lines_executed_percent}}
+
{{lines_number}}
+ {{methods_bar}} +
{{methods_tested_percent}}
+
{{methods_number}}
+ {{classes_bar}} +
{{classes_tested_percent}}
+
{{classes_number}}
+ + diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist new file mode 100644 index 0000000..0ca65ed --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file.html.dist @@ -0,0 +1,72 @@ + + + + + Code Coverage for {{full_path}} + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + +{{items}} + +
 
Code Coverage
 
Classes and Traits
Functions and Methods
Lines
+
+ + +{{lines}} + +
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist new file mode 100644 index 0000000..dc754b3 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/file_item.html.dist @@ -0,0 +1,14 @@ + + {{name}} + {{classes_bar}} +
{{classes_tested_percent}}
+
{{classes_number}}
+ {{methods_bar}} +
{{methods_tested_percent}}
+
{{methods_number}}
+ {{crap}} + {{lines_bar}} +
{{lines_executed_percent}}
+
{{lines_number}}
+ + diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg new file mode 100644 index 0000000..5b4b199 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-code.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg new file mode 100644 index 0000000..4bf1f1c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/icons/file-directory.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js new file mode 100644 index 0000000..c4c0d1f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.3.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e((t=t||self).bootstrap={},t.jQuery,t.Popper)}(this,function(t,g,u){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)g(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent",sanitize:!0,sanitizeFn:null,whiteList:Ee},je="show",He="out",Re={HIDE:"hide"+De,HIDDEN:"hidden"+De,SHOW:"show"+De,SHOWN:"shown"+De,INSERTED:"inserted"+De,CLICK:"click"+De,FOCUSIN:"focusin"+De,FOCUSOUT:"focusout"+De,MOUSEENTER:"mouseenter"+De,MOUSELEAVE:"mouseleave"+De},xe="fade",Fe="show",Ue=".tooltip-inner",We=".arrow",qe="hover",Me="focus",Ke="click",Qe="manual",Be=function(){function i(t,e){if("undefined"==typeof u)throw new TypeError("Bootstrap's tooltips require Popper.js (https://popper.js.org/)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=g(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(g(this.getTipElement()).hasClass(Fe))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),g.removeData(this.element,this.constructor.DATA_KEY),g(this.element).off(this.constructor.EVENT_KEY),g(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&g(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===g(this.element).css("display"))throw new Error("Please use show on visible elements");var t=g.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){g(this.element).trigger(t);var n=_.findShadowRoot(this.element),i=g.contains(null!==n?n:this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!i)return;var o=this.getTipElement(),r=_.getUID(this.constructor.NAME);o.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&g(o).addClass(xe);var s="function"==typeof this.config.placement?this.config.placement.call(this,o,this.element):this.config.placement,a=this._getAttachment(s);this.addAttachmentClass(a);var l=this._getContainer();g(o).data(this.constructor.DATA_KEY,this),g.contains(this.element.ownerDocument.documentElement,this.tip)||g(o).appendTo(l),g(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new u(this.element,o,{placement:a,modifiers:{offset:this._getOffset(),flip:{behavior:this.config.fallbackPlacement},arrow:{element:We},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){return e._handlePopperPlacementChange(t)}}),g(o).addClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().on("mouseover",null,g.noop);var c=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,g(e.element).trigger(e.constructor.Event.SHOWN),t===He&&e._leave(null,e)};if(g(this.tip).hasClass(xe)){var h=_.getTransitionDurationFromElement(this.tip);g(this.tip).one(_.TRANSITION_END,c).emulateTransitionEnd(h)}else c()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=g.Event(this.constructor.Event.HIDE),o=function(){e._hoverState!==je&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),g(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(g(this.element).trigger(i),!i.isDefaultPrevented()){if(g(n).removeClass(Fe),"ontouchstart"in document.documentElement&&g(document.body).children().off("mouseover",null,g.noop),this._activeTrigger[Ke]=!1,this._activeTrigger[Me]=!1,this._activeTrigger[qe]=!1,g(this.tip).hasClass(xe)){var r=_.getTransitionDurationFromElement(n);g(n).one(_.TRANSITION_END,o).emulateTransitionEnd(r)}else o();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){g(this.getTipElement()).addClass(Ae+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},t.setContent=function(){var t=this.getTipElement();this.setElementContent(g(t.querySelectorAll(Ue)),this.getTitle()),g(t).removeClass(xe+" "+Fe)},t.setElementContent=function(t,e){"object"!=typeof e||!e.nodeType&&!e.jquery?this.config.html?(this.config.sanitize&&(e=Se(e,this.config.whiteList,this.config.sanitizeFn)),t.html(e)):t.text(e):this.config.html?g(e).parent().is(t)||t.empty().append(e):t.text(g(e).text())},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getOffset=function(){var e=this,t={};return"function"==typeof this.config.offset?t.fn=function(t){return t.offsets=l({},t.offsets,e.config.offset(t.offsets,e.element)||{}),t}:t.offset=this.config.offset,t},t._getContainer=function(){return!1===this.config.container?document.body:_.isElement(this.config.container)?g(this.config.container):g(document).find(this.config.container)},t._getAttachment=function(t){return Pe[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)g(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==Qe){var e=t===qe?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===qe?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;g(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}}),g(this.element).closest(".modal").on("hide.bs.modal",function(){i.element&&i.hide()}),this.config.selector?this.config=l({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Me:qe]=!0),g(e.getTipElement()).hasClass(Fe)||e._hoverState===je?e._hoverState=je:(clearTimeout(e._timeout),e._hoverState=je,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===je&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||g(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),g(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Me:qe]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=He,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===He&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){var e=g(this.element).data();return Object.keys(e).forEach(function(t){-1!==Oe.indexOf(t)&&delete e[t]}),"number"==typeof(t=l({},this.constructor.Default,e,"object"==typeof t&&t?t:{})).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),_.typeCheckConfig(be,t,this.constructor.DefaultType),t.sanitize&&(t.template=Se(t.template,t.whiteList,t.sanitizeFn)),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ne);null!==e&&e.length&&t.removeClass(e.join(""))},t._handlePopperPlacementChange=function(t){var e=t.instance;this.tip=e.popper,this._cleanTipClass(),this.addAttachmentClass(this._getAttachment(t.placement))},t._fixTransition=function(){var t=this.getTipElement(),e=this.config.animation;null===t.getAttribute("x-placement")&&(g(t).removeClass(xe),this.config.animation=!1,this.hide(),this.show(),this.config.animation=e)},i._jQueryInterface=function(n){return this.each(function(){var t=g(this).data(Ie),e="object"==typeof n&&n;if((t||!/dispose|hide/.test(n))&&(t||(t=new i(this,e),g(this).data(Ie,t)),"string"==typeof n)){if("undefined"==typeof t[n])throw new TypeError('No method named "'+n+'"');t[n]()}})},s(i,null,[{key:"VERSION",get:function(){return"4.3.1"}},{key:"Default",get:function(){return Le}},{key:"NAME",get:function(){return be}},{key:"DATA_KEY",get:function(){return Ie}},{key:"Event",get:function(){return Re}},{key:"EVENT_KEY",get:function(){return De}},{key:"DefaultType",get:function(){return ke}}]),i}();g.fn[be]=Be._jQueryInterface,g.fn[be].Constructor=Be,g.fn[be].noConflict=function(){return g.fn[be]=we,Be._jQueryInterface};var Ve="popover",Ye="bs.popover",ze="."+Ye,Xe=g.fn[Ve],$e="bs-popover",Ge=new RegExp("(^|\\s)"+$e+"\\S+","g"),Je=l({},Be.Default,{placement:"right",trigger:"click",content:"",template:''}),Ze=l({},Be.DefaultType,{content:"(string|element|function)"}),tn="fade",en="show",nn=".popover-header",on=".popover-body",rn={HIDE:"hide"+ze,HIDDEN:"hidden"+ze,SHOW:"show"+ze,SHOWN:"shown"+ze,INSERTED:"inserted"+ze,CLICK:"click"+ze,FOCUSIN:"focusin"+ze,FOCUSOUT:"focusout"+ze,MOUSEENTER:"mouseenter"+ze,MOUSELEAVE:"mouseleave"+ze},sn=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var o=i.prototype;return o.isWithContent=function(){return this.getTitle()||this._getContent()},o.addAttachmentClass=function(t){g(this.getTipElement()).addClass($e+"-"+t)},o.getTipElement=function(){return this.tip=this.tip||g(this.config.template)[0],this.tip},o.setContent=function(){var t=g(this.getTipElement());this.setElementContent(t.find(nn),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(on),e),t.removeClass(tn+" "+en)},o._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},o._cleanTipClass=function(){var t=g(this.getTipElement()),e=t.attr("class").match(Ge);null!==e&&0=this._offsets[o]&&("undefined"==typeof this._offsets[o+1]||tn?-1:n>t?1:n>=t?0:NaN}function r(n){return null===n?NaN:+n}function i(n){return!isNaN(n)}function u(n){return{left:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)<0?r=u+1:i=u}return r},right:function(t,e,r,i){for(arguments.length<3&&(r=0),arguments.length<4&&(i=t.length);i>r;){var u=r+i>>>1;n(t[u],e)>0?i=u:r=u+1}return r}}}function o(n){return n.length}function a(n){for(var t=1;n*t%1;)t*=10;return t}function l(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function c(){this._=Object.create(null)}function f(n){return(n+="")===bo||n[0]===_o?_o+n:n}function s(n){return(n+="")[0]===_o?n.slice(1):n}function h(n){return f(n)in this._}function p(n){return(n=f(n))in this._&&delete this._[n]}function g(){var n=[];for(var t in this._)n.push(s(t));return n}function v(){var n=0;for(var t in this._)++n;return n}function d(){for(var n in this._)return!1;return!0}function y(){this._=Object.create(null)}function m(n){return n}function M(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function x(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=wo.length;r>e;++e){var i=wo[e]+t;if(i in n)return i}}function b(){}function _(){}function w(n){function t(){for(var t,r=e,i=-1,u=r.length;++ie;e++)for(var i,u=n[e],o=0,a=u.length;a>o;o++)(i=u[o])&&t(i,o,e);return n}function Z(n){return ko(n,qo),n}function V(n){var t,e;return function(r,i,u){var o,a=n[u].update,l=a.length;for(u!=e&&(e=u,t=0),i>=t&&(t=i+1);!(o=a[t])&&++t0&&(n=n.slice(0,a));var c=To.get(n);return c&&(n=c,l=B),a?t?i:r:t?b:u}function $(n,t){return function(e){var r=ao.event;ao.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ao.event=r}}}function B(n,t){var e=$(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function W(e){var r=".dragsuppress-"+ ++Do,i="click"+r,u=ao.select(t(e)).on("touchmove"+r,S).on("dragstart"+r,S).on("selectstart"+r,S);if(null==Ro&&(Ro="onselectstart"in e?!1:x(e.style,"userSelect")),Ro){var o=n(e).style,a=o[Ro];o[Ro]="none"}return function(n){if(u.on(r,null),Ro&&(o[Ro]=a),n){var t=function(){u.on(i,null)};u.on(i,function(){S(),t()},!0),setTimeout(t,0)}}}function J(n,e){e.changedTouches&&(e=e.changedTouches[0]);var r=n.ownerSVGElement||n;if(r.createSVGPoint){var i=r.createSVGPoint();if(0>Po){var u=t(n);if(u.scrollX||u.scrollY){r=ao.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var o=r[0][0].getScreenCTM();Po=!(o.f||o.e),r.remove()}}return Po?(i.x=e.pageX,i.y=e.pageY):(i.x=e.clientX,i.y=e.clientY),i=i.matrixTransform(n.getScreenCTM().inverse()),[i.x,i.y]}var a=n.getBoundingClientRect();return[e.clientX-a.left-n.clientLeft,e.clientY-a.top-n.clientTop]}function G(){return ao.event.changedTouches[0].identifier}function K(n){return n>0?1:0>n?-1:0}function Q(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function nn(n){return n>1?0:-1>n?Fo:Math.acos(n)}function tn(n){return n>1?Io:-1>n?-Io:Math.asin(n)}function en(n){return((n=Math.exp(n))-1/n)/2}function rn(n){return((n=Math.exp(n))+1/n)/2}function un(n){return((n=Math.exp(2*n))-1)/(n+1)}function on(n){return(n=Math.sin(n/2))*n}function an(){}function ln(n,t,e){return this instanceof ln?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ln?new ln(n.h,n.s,n.l):_n(""+n,wn,ln):new ln(n,t,e)}function cn(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?u+(o-u)*n/60:180>n?o:240>n?u+(o-u)*(240-n)/60:u}function i(n){return Math.round(255*r(n))}var u,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,u=2*e-o,new mn(i(n+120),i(n),i(n-120))}function fn(n,t,e){return this instanceof fn?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof fn?new fn(n.h,n.c,n.l):n instanceof hn?gn(n.l,n.a,n.b):gn((n=Sn((n=ao.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new fn(n,t,e)}function sn(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new hn(e,Math.cos(n*=Yo)*t,Math.sin(n)*t)}function hn(n,t,e){return this instanceof hn?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof hn?new hn(n.l,n.a,n.b):n instanceof fn?sn(n.h,n.c,n.l):Sn((n=mn(n)).r,n.g,n.b):new hn(n,t,e)}function pn(n,t,e){var r=(n+16)/116,i=r+t/500,u=r-e/200;return i=vn(i)*na,r=vn(r)*ta,u=vn(u)*ea,new mn(yn(3.2404542*i-1.5371385*r-.4985314*u),yn(-.969266*i+1.8760108*r+.041556*u),yn(.0556434*i-.2040259*r+1.0572252*u))}function gn(n,t,e){return n>0?new fn(Math.atan2(e,t)*Zo,Math.sqrt(t*t+e*e),n):new fn(NaN,NaN,n)}function vn(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function dn(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function yn(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function mn(n,t,e){return this instanceof mn?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof mn?new mn(n.r,n.g,n.b):_n(""+n,mn,cn):new mn(n,t,e)}function Mn(n){return new mn(n>>16,n>>8&255,255&n)}function xn(n){return Mn(n)+""}function bn(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function _n(n,t,e){var r,i,u,o=0,a=0,l=0;if(r=/([a-z]+)\((.*)\)/.exec(n=n.toLowerCase()))switch(i=r[2].split(","),r[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Nn(i[0]),Nn(i[1]),Nn(i[2]))}return(u=ua.get(n))?t(u.r,u.g,u.b):(null==n||"#"!==n.charAt(0)||isNaN(u=parseInt(n.slice(1),16))||(4===n.length?(o=(3840&u)>>4,o=o>>4|o,a=240&u,a=a>>4|a,l=15&u,l=l<<4|l):7===n.length&&(o=(16711680&u)>>16,a=(65280&u)>>8,l=255&u)),t(o,a,l))}function wn(n,t,e){var r,i,u=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-u,l=(o+u)/2;return a?(i=.5>l?a/(o+u):a/(2-o-u),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=NaN,i=l>0&&1>l?0:r),new ln(r,i,l)}function Sn(n,t,e){n=kn(n),t=kn(t),e=kn(e);var r=dn((.4124564*n+.3575761*t+.1804375*e)/na),i=dn((.2126729*n+.7151522*t+.072175*e)/ta),u=dn((.0193339*n+.119192*t+.9503041*e)/ea);return hn(116*i-16,500*(r-i),200*(i-u))}function kn(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Nn(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function En(n){return"function"==typeof n?n:function(){return n}}function An(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Cn(t,e,n,r)}}function Cn(n,t,e,r){function i(){var n,t=l.status;if(!t&&Ln(l)||t>=200&&300>t||304===t){try{n=e.call(u,l)}catch(r){return void o.error.call(u,r)}o.load.call(u,n)}else o.error.call(u,l)}var u={},o=ao.dispatch("beforesend","progress","load","error"),a={},l=new XMLHttpRequest,c=null;return!this.XDomainRequest||"withCredentials"in l||!/^(http(s)?:)?\/\//.test(n)||(l=new XDomainRequest),"onload"in l?l.onload=l.onerror=i:l.onreadystatechange=function(){l.readyState>3&&i()},l.onprogress=function(n){var t=ao.event;ao.event=n;try{o.progress.call(u,l)}finally{ao.event=t}},u.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",u)},u.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",u):t},u.responseType=function(n){return arguments.length?(c=n,u):c},u.response=function(n){return e=n,u},["get","post"].forEach(function(n){u[n]=function(){return u.send.apply(u,[n].concat(co(arguments)))}}),u.send=function(e,r,i){if(2===arguments.length&&"function"==typeof r&&(i=r,r=null),l.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),l.setRequestHeader)for(var f in a)l.setRequestHeader(f,a[f]);return null!=t&&l.overrideMimeType&&l.overrideMimeType(t),null!=c&&(l.responseType=c),null!=i&&u.on("error",i).on("load",function(n){i(null,n)}),o.beforesend.call(u,l),l.send(null==r?null:r),u},u.abort=function(){return l.abort(),u},ao.rebind(u,o,"on"),null==r?u:u.get(zn(r))}function zn(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Ln(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qn(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var i=e+t,u={c:n,t:i,n:null};return aa?aa.n=u:oa=u,aa=u,la||(ca=clearTimeout(ca),la=1,fa(Tn)),u}function Tn(){var n=Rn(),t=Dn()-n;t>24?(isFinite(t)&&(clearTimeout(ca),ca=setTimeout(Tn,t)),la=0):(la=1,fa(Tn))}function Rn(){for(var n=Date.now(),t=oa;t;)n>=t.t&&t.c(n-t.t)&&(t.c=null),t=t.n;return n}function Dn(){for(var n,t=oa,e=1/0;t;)t.c?(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function jn(n){var t=n.decimal,e=n.thousands,r=n.grouping,i=n.currency,u=r&&e?function(n,t){for(var i=n.length,u=[],o=0,a=r[0],l=0;i>0&&a>0&&(l+a+1>t&&(a=Math.max(1,t-l)),u.push(n.substring(i-=a,i+a)),!((l+=a+1)>t));)a=r[o=(o+1)%r.length];return u.reverse().join(e)}:m;return function(n){var e=ha.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",l=e[4]||"",c=e[5],f=+e[6],s=e[7],h=e[8],p=e[9],g=1,v="",d="",y=!1,m=!0;switch(h&&(h=+h.substring(1)),(c||"0"===r&&"="===o)&&(c=r="0",o="="),p){case"n":s=!0,p="g";break;case"%":g=100,d="%",p="f";break;case"p":g=100,d="%",p="r";break;case"b":case"o":case"x":case"X":"#"===l&&(v="0"+p.toLowerCase());case"c":m=!1;case"d":y=!0,h=0;break;case"s":g=-1,p="r"}"$"===l&&(v=i[0],d=i[1]),"r"!=p||h||(p="g"),null!=h&&("g"==p?h=Math.max(1,Math.min(21,h)):"e"!=p&&"f"!=p||(h=Math.max(0,Math.min(20,h)))),p=pa.get(p)||Fn;var M=c&&s;return function(n){var e=d;if(y&&n%1)return"";var i=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>g){var l=ao.formatPrefix(n,h);n=l.scale(n),e=l.symbol+d}else n*=g;n=p(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=m?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!c&&s&&(x=u(x,1/0));var S=v.length+x.length+b.length+(M?0:i.length),k=f>S?new Array(S=f-S+1).join(r):"";return M&&(x=u(k+x,k.length?f-b.length:1/0)),i+=v,n=x+b,("<"===o?i+n+k:">"===o?k+i+n:"^"===o?k.substring(0,S>>=1)+i+n+k.substring(S):i+(M?n:k+n))+e}}}function Fn(n){return n+""}function Hn(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function On(n,t,e){function r(t){var e=n(t),r=u(e,1);return r-t>t-e?e:r}function i(e){return t(e=n(new va(e-1)),1),e}function u(n,e){return t(n=new va(+n),e),n}function o(n,r,u){var o=i(n),a=[];if(u>1)for(;r>o;)e(o)%u||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{va=Hn;var r=new Hn;return r._=n,o(r,t,e)}finally{va=Date}}n.floor=n,n.round=r,n.ceil=i,n.offset=u,n.range=o;var l=n.utc=In(n);return l.floor=l,l.round=In(r),l.ceil=In(i),l.offset=In(u),l.range=a,n}function In(n){return function(t,e){try{va=Hn;var r=new Hn;return r._=t,n(r,e)._}finally{va=Date}}}function Yn(n){function t(n){function t(t){for(var e,i,u,o=[],a=-1,l=0;++aa;){if(r>=c)return-1;if(i=t.charCodeAt(a++),37===i){if(o=t.charAt(a++),u=C[o in ya?t.charAt(a++):o],!u||(r=u(n,e,r))<0)return-1}else if(i!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){N.lastIndex=0;var r=N.exec(t.slice(e));return r?(n.m=E.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,A.c.toString(),t,r)}function l(n,t,r){return e(n,A.x.toString(),t,r)}function c(n,t,r){return e(n,A.X.toString(),t,r)}function f(n,t,e){var r=M.get(t.slice(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var s=n.dateTime,h=n.date,p=n.time,g=n.periods,v=n.days,d=n.shortDays,y=n.months,m=n.shortMonths;t.utc=function(n){function e(n){try{va=Hn;var t=new va;return t._=n,r(t)}finally{va=Date}}var r=t(n);return e.parse=function(n){try{va=Hn;var t=r.parse(n);return t&&t._}finally{va=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ct;var M=ao.map(),x=Vn(v),b=Xn(v),_=Vn(d),w=Xn(d),S=Vn(y),k=Xn(y),N=Vn(m),E=Xn(m);g.forEach(function(n,t){M.set(n.toLowerCase(),t)});var A={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return m[n.getMonth()]},B:function(n){return y[n.getMonth()]},c:t(s),d:function(n,t){return Zn(n.getDate(),t,2)},e:function(n,t){return Zn(n.getDate(),t,2)},H:function(n,t){return Zn(n.getHours(),t,2)},I:function(n,t){return Zn(n.getHours()%12||12,t,2)},j:function(n,t){return Zn(1+ga.dayOfYear(n),t,3)},L:function(n,t){return Zn(n.getMilliseconds(),t,3)},m:function(n,t){return Zn(n.getMonth()+1,t,2)},M:function(n,t){return Zn(n.getMinutes(),t,2)},p:function(n){return g[+(n.getHours()>=12)]},S:function(n,t){return Zn(n.getSeconds(),t,2)},U:function(n,t){return Zn(ga.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Zn(ga.mondayOfYear(n),t,2)},x:t(h),X:t(p),y:function(n,t){return Zn(n.getFullYear()%100,t,2)},Y:function(n,t){return Zn(n.getFullYear()%1e4,t,4)},Z:at,"%":function(){return"%"}},C={a:r,A:i,b:u,B:o,c:a,d:tt,e:tt,H:rt,I:rt,j:et,L:ot,m:nt,M:it,p:f,S:ut,U:Bn,w:$n,W:Wn,x:l,X:c,y:Gn,Y:Jn,Z:Kn,"%":lt};return t}function Zn(n,t,e){var r=0>n?"-":"",i=(r?-n:n)+"",u=i.length;return r+(e>u?new Array(e-u+1).join(t)+i:i)}function Vn(n){return new RegExp("^(?:"+n.map(ao.requote).join("|")+")","i")}function Xn(n){for(var t=new c,e=-1,r=n.length;++e68?1900:2e3)}function nt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function tt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function et(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function rt(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function it(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function ut(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ot(n,t,e){ma.lastIndex=0;var r=ma.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function at(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=xo(t)/60|0,i=xo(t)%60;return e+Zn(r,"0",2)+Zn(i,"0",2)}function lt(n,t,e){Ma.lastIndex=0;var r=Ma.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ct(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,l=Math.cos(t),c=Math.sin(t),f=u*c,s=i*l+f*Math.cos(a),h=f*o*Math.sin(a);ka.add(Math.atan2(h,s)),r=n,i=l,u=c}var t,e,r,i,u;Na.point=function(o,a){Na.point=n,r=(t=o)*Yo,i=Math.cos(a=(e=a)*Yo/2+Fo/4),u=Math.sin(a)},Na.lineEnd=function(){n(t,e)}}function dt(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function yt(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function mt(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function Mt(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function xt(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function bt(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function _t(n){return[Math.atan2(n[1],n[0]),tn(n[2])]}function wt(n,t){return xo(n[0]-t[0])a;++a)i.point((e=n[a])[0],e[1]);return void i.lineEnd()}var l=new Tt(e,n,null,!0),c=new Tt(e,null,l,!1);l.o=c,u.push(l),o.push(c),l=new Tt(r,n,null,!1),c=new Tt(r,null,l,!0),l.o=c,u.push(l),o.push(c)}}),o.sort(t),qt(u),qt(o),u.length){for(var a=0,l=e,c=o.length;c>a;++a)o[a].e=l=!l;for(var f,s,h=u[0];;){for(var p=h,g=!0;p.v;)if((p=p.n)===h)return;f=p.z,i.lineStart();do{if(p.v=p.o.v=!0,p.e){if(g)for(var a=0,c=f.length;c>a;++a)i.point((s=f[a])[0],s[1]);else r(p.x,p.n.x,1,i);p=p.n}else{if(g){f=p.p.z;for(var a=f.length-1;a>=0;--a)i.point((s=f[a])[0],s[1])}else r(p.x,p.p.x,-1,i);p=p.p}p=p.o,f=p.z,g=!g}while(!p.v);i.lineEnd()}}}function qt(n){if(t=n.length){for(var t,e,r=0,i=n[0];++r0){for(b||(u.polygonStart(),b=!0),u.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),p.push(e.filter(Dt))}var p,g,v,d=t(u),y=i.invert(r[0],r[1]),m={point:o,lineStart:l,lineEnd:c,polygonStart:function(){m.point=f,m.lineStart=s,m.lineEnd=h,p=[],g=[]},polygonEnd:function(){m.point=o,m.lineStart=l,m.lineEnd=c,p=ao.merge(p);var n=Ot(y,g);p.length?(b||(u.polygonStart(),b=!0),Lt(p,Ut,n,e,u)):n&&(b||(u.polygonStart(),b=!0),u.lineStart(),e(null,null,1,u),u.lineEnd()),b&&(u.polygonEnd(),b=!1),p=g=null},sphere:function(){u.polygonStart(),u.lineStart(),e(null,null,1,u),u.lineEnd(),u.polygonEnd()}},M=Pt(),x=t(M),b=!1;return m}}function Dt(n){return n.length>1}function Pt(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:b,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ut(n,t){return((n=n.x)[0]<0?n[1]-Io-Uo:Io-n[1])-((t=t.x)[0]<0?t[1]-Io-Uo:Io-t[1])}function jt(n){var t,e=NaN,r=NaN,i=NaN;return{lineStart:function(){n.lineStart(),t=1},point:function(u,o){var a=u>0?Fo:-Fo,l=xo(u-e);xo(l-Fo)0?Io:-Io),n.point(i,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(u,r),t=0):i!==a&&l>=Fo&&(xo(e-i)Uo?Math.atan((Math.sin(t)*(u=Math.cos(r))*Math.sin(e)-Math.sin(r)*(i=Math.cos(t))*Math.sin(n))/(i*u*o)):(t+r)/2}function Ht(n,t,e,r){var i;if(null==n)i=e*Io,r.point(-Fo,i),r.point(0,i),r.point(Fo,i),r.point(Fo,0),r.point(Fo,-i),r.point(0,-i),r.point(-Fo,-i),r.point(-Fo,0),r.point(-Fo,i);else if(xo(n[0]-t[0])>Uo){var u=n[0]a;++a){var c=t[a],f=c.length;if(f)for(var s=c[0],h=s[0],p=s[1]/2+Fo/4,g=Math.sin(p),v=Math.cos(p),d=1;;){d===f&&(d=0),n=c[d];var y=n[0],m=n[1]/2+Fo/4,M=Math.sin(m),x=Math.cos(m),b=y-h,_=b>=0?1:-1,w=_*b,S=w>Fo,k=g*M;if(ka.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),u+=S?b+_*Ho:b,S^h>=e^y>=e){var N=mt(dt(s),dt(n));bt(N);var E=mt(i,N);bt(E);var A=(S^b>=0?-1:1)*tn(E[2]);(r>A||r===A&&(N[0]||N[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=y,g=M,v=x,s=n}}return(-Uo>u||Uo>u&&-Uo>ka)^1&o}function It(n){function t(n,t){return Math.cos(n)*Math.cos(t)>u}function e(n){var e,u,l,c,f;return{lineStart:function(){c=l=!1,f=1},point:function(s,h){var p,g=[s,h],v=t(s,h),d=o?v?0:i(s,h):v?i(s+(0>s?Fo:-Fo),h):0;if(!e&&(c=l=v)&&n.lineStart(),v!==l&&(p=r(e,g),(wt(e,p)||wt(g,p))&&(g[0]+=Uo,g[1]+=Uo,v=t(g[0],g[1]))),v!==l)f=0,v?(n.lineStart(),p=r(g,e),n.point(p[0],p[1])):(p=r(e,g),n.point(p[0],p[1]),n.lineEnd()),e=p;else if(a&&e&&o^v){var y;d&u||!(y=r(g,e,!0))||(f=0,o?(n.lineStart(),n.point(y[0][0],y[0][1]),n.point(y[1][0],y[1][1]),n.lineEnd()):(n.point(y[1][0],y[1][1]),n.lineEnd(),n.lineStart(),n.point(y[0][0],y[0][1])))}!v||e&&wt(e,g)||n.point(g[0],g[1]),e=g,l=v,u=d},lineEnd:function(){l&&n.lineEnd(),e=null},clean:function(){return f|(c&&l)<<1}}}function r(n,t,e){var r=dt(n),i=dt(t),o=[1,0,0],a=mt(r,i),l=yt(a,a),c=a[0],f=l-c*c;if(!f)return!e&&n;var s=u*l/f,h=-u*c/f,p=mt(o,a),g=xt(o,s),v=xt(a,h);Mt(g,v);var d=p,y=yt(g,d),m=yt(d,d),M=y*y-m*(yt(g,g)-1);if(!(0>M)){var x=Math.sqrt(M),b=xt(d,(-y-x)/m);if(Mt(b,g),b=_t(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],N=t[1];w>S&&(_=w,w=S,S=_);var E=S-w,A=xo(E-Fo)E;if(!A&&k>N&&(_=k,k=N,N=_),C?A?k+N>0^b[1]<(xo(b[0]-w)Fo^(w<=b[0]&&b[0]<=S)){var z=xt(d,(-y+x)/m);return Mt(z,g),[b,_t(z)]}}}function i(t,e){var r=o?n:Fo-n,i=0;return-r>t?i|=1:t>r&&(i|=2),-r>e?i|=4:e>r&&(i|=8),i}var u=Math.cos(n),o=u>0,a=xo(u)>Uo,l=ve(n,6*Yo);return Rt(t,e,l,o?[0,-n]:[-Fo,n-Fo])}function Yt(n,t,e,r){return function(i){var u,o=i.a,a=i.b,l=o.x,c=o.y,f=a.x,s=a.y,h=0,p=1,g=f-l,v=s-c;if(u=n-l,g||!(u>0)){if(u/=g,0>g){if(h>u)return;p>u&&(p=u)}else if(g>0){if(u>p)return;u>h&&(h=u)}if(u=e-l,g||!(0>u)){if(u/=g,0>g){if(u>p)return;u>h&&(h=u)}else if(g>0){if(h>u)return;p>u&&(p=u)}if(u=t-c,v||!(u>0)){if(u/=v,0>v){if(h>u)return;p>u&&(p=u)}else if(v>0){if(u>p)return;u>h&&(h=u)}if(u=r-c,v||!(0>u)){if(u/=v,0>v){if(u>p)return;u>h&&(h=u)}else if(v>0){if(h>u)return;p>u&&(p=u)}return h>0&&(i.a={x:l+h*g,y:c+h*v}),1>p&&(i.b={x:l+p*g,y:c+p*v}),i}}}}}}function Zt(n,t,e,r){function i(r,i){return xo(r[0]-n)0?0:3:xo(r[0]-e)0?2:1:xo(r[1]-t)0?1:0:i>0?3:2}function u(n,t){return o(n.x,t.x)}function o(n,t){var e=i(n,1),r=i(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function l(n){for(var t=0,e=d.length,r=n[1],i=0;e>i;++i)for(var u,o=1,a=d[i],l=a.length,c=a[0];l>o;++o)u=a[o],c[1]<=r?u[1]>r&&Q(c,u,n)>0&&++t:u[1]<=r&&Q(c,u,n)<0&&--t,c=u;return 0!==t}function c(u,a,l,c){var f=0,s=0;if(null==u||(f=i(u,l))!==(s=i(a,l))||o(u,a)<0^l>0){do c.point(0===f||3===f?n:e,f>1?r:t);while((f=(f+l+4)%4)!==s)}else c.point(a[0],a[1])}function f(i,u){return i>=n&&e>=i&&u>=t&&r>=u}function s(n,t){f(n,t)&&a.point(n,t)}function h(){C.point=g,d&&d.push(y=[]),S=!0,w=!1,b=_=NaN}function p(){v&&(g(m,M),x&&w&&E.rejoin(),v.push(E.buffer())),C.point=s,w&&a.lineEnd()}function g(n,t){n=Math.max(-Ha,Math.min(Ha,n)),t=Math.max(-Ha,Math.min(Ha,t));var e=f(n,t);if(d&&y.push([n,t]),S)m=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};A(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}b=n,_=t,w=e}var v,d,y,m,M,x,b,_,w,S,k,N=a,E=Pt(),A=Yt(n,t,e,r),C={point:s,lineStart:h,lineEnd:p,polygonStart:function(){a=E,v=[],d=[],k=!0},polygonEnd:function(){a=N,v=ao.merge(v);var t=l([n,r]),e=k&&t,i=v.length;(e||i)&&(a.polygonStart(),e&&(a.lineStart(),c(null,null,1,a),a.lineEnd()),i&&Lt(v,u,t,c,a),a.polygonEnd()),v=d=y=null}};return C}}function Vt(n){var t=0,e=Fo/3,r=ae(n),i=r(t,e);return i.parallels=function(n){return arguments.length?r(t=n[0]*Fo/180,e=n[1]*Fo/180):[t/Fo*180,e/Fo*180]},i}function Xt(n,t){function e(n,t){var e=Math.sqrt(u-2*i*Math.sin(t))/i;return[e*Math.sin(n*=i),o-e*Math.cos(n)]}var r=Math.sin(n),i=(r+Math.sin(t))/2,u=1+r*(2*i-r),o=Math.sqrt(u)/i;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/i,tn((u-(n*n+e*e)*i*i)/(2*i))]},e}function $t(){function n(n,t){Ia+=i*n-r*t,r=n,i=t}var t,e,r,i;$a.point=function(u,o){$a.point=n,t=r=u,e=i=o},$a.lineEnd=function(){n(t,e)}}function Bt(n,t){Ya>n&&(Ya=n),n>Va&&(Va=n),Za>t&&(Za=t),t>Xa&&(Xa=t)}function Wt(){function n(n,t){o.push("M",n,",",t,u)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function i(){o.push("Z")}var u=Jt(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return u=Jt(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Jt(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Gt(n,t){Ca+=n,za+=t,++La}function Kt(){function n(n,r){var i=n-t,u=r-e,o=Math.sqrt(i*i+u*u);qa+=o*(t+n)/2,Ta+=o*(e+r)/2,Ra+=o,Gt(t=n,e=r)}var t,e;Wa.point=function(r,i){Wa.point=n,Gt(t=r,e=i)}}function Qt(){Wa.point=Gt}function ne(){function n(n,t){var e=n-r,u=t-i,o=Math.sqrt(e*e+u*u);qa+=o*(r+n)/2,Ta+=o*(i+t)/2,Ra+=o,o=i*n-r*t,Da+=o*(r+n),Pa+=o*(i+t),Ua+=3*o,Gt(r=n,i=t)}var t,e,r,i;Wa.point=function(u,o){Wa.point=n,Gt(t=r=u,e=i=o)},Wa.lineEnd=function(){n(t,e)}}function te(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Ho)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function i(){a.point=t}function u(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:i,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=i,a.point=t},pointRadius:function(n){return o=n,a},result:b};return a}function ee(n){function t(n){return(a?r:e)(n)}function e(t){return ue(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){M=NaN,S.point=u,t.lineStart()}function u(e,r){var u=dt([e,r]),o=n(e,r);i(M,x,m,b,_,w,M=o[0],x=o[1],m=e,b=u[0],_=u[1],w=u[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function l(){ +r(),S.point=c,S.lineEnd=f}function c(n,t){u(s=n,h=t),p=M,g=x,v=b,d=_,y=w,S.point=u}function f(){i(M,x,m,b,_,w,p,g,s,v,d,y,a,t),S.lineEnd=o,o()}var s,h,p,g,v,d,y,m,M,x,b,_,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=l},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function i(t,e,r,a,l,c,f,s,h,p,g,v,d,y){var m=f-t,M=s-e,x=m*m+M*M;if(x>4*u&&d--){var b=a+p,_=l+g,w=c+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),N=xo(xo(w)-1)u||xo((m*z+M*L)/x-.5)>.3||o>a*p+l*g+c*v)&&(i(t,e,r,a,l,c,A,C,N,b/=S,_/=S,w,d,y),y.point(A,C),i(A,C,N,b,_,w,f,s,h,p,g,v,d,y))}}var u=.5,o=Math.cos(30*Yo),a=16;return t.precision=function(n){return arguments.length?(a=(u=n*n)>0&&16,t):Math.sqrt(u)},t}function re(n){var t=ee(function(t,e){return n([t*Zo,e*Zo])});return function(n){return le(t(n))}}function ie(n){this.stream=n}function ue(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function oe(n){return ae(function(){return n})()}function ae(n){function t(n){return n=a(n[0]*Yo,n[1]*Yo),[n[0]*h+l,c-n[1]*h]}function e(n){return n=a.invert((n[0]-l)/h,(c-n[1])/h),n&&[n[0]*Zo,n[1]*Zo]}function r(){a=Ct(o=se(y,M,x),u);var n=u(v,d);return l=p-n[0]*h,c=g+n[1]*h,i()}function i(){return f&&(f.valid=!1,f=null),t}var u,o,a,l,c,f,s=ee(function(n,t){return n=u(n,t),[n[0]*h+l,c-n[1]*h]}),h=150,p=480,g=250,v=0,d=0,y=0,M=0,x=0,b=Fa,_=m,w=null,S=null;return t.stream=function(n){return f&&(f.valid=!1),f=le(b(o,s(_(n)))),f.valid=!0,f},t.clipAngle=function(n){return arguments.length?(b=null==n?(w=n,Fa):It((w=+n)*Yo),i()):w},t.clipExtent=function(n){return arguments.length?(S=n,_=n?Zt(n[0][0],n[0][1],n[1][0],n[1][1]):m,i()):S},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(p=+n[0],g=+n[1],r()):[p,g]},t.center=function(n){return arguments.length?(v=n[0]%360*Yo,d=n[1]%360*Yo,r()):[v*Zo,d*Zo]},t.rotate=function(n){return arguments.length?(y=n[0]%360*Yo,M=n[1]%360*Yo,x=n.length>2?n[2]%360*Yo:0,r()):[y*Zo,M*Zo,x*Zo]},ao.rebind(t,s,"precision"),function(){return u=n.apply(this,arguments),t.invert=u.invert&&e,r()}}function le(n){return ue(n,function(t,e){n.point(t*Yo,e*Yo)})}function ce(n,t){return[n,t]}function fe(n,t){return[n>Fo?n-Ho:-Fo>n?n+Ho:n,t]}function se(n,t,e){return n?t||e?Ct(pe(n),ge(t,e)):pe(n):t||e?ge(t,e):fe}function he(n){return function(t,e){return t+=n,[t>Fo?t-Ho:-Fo>t?t+Ho:t,e]}}function pe(n){var t=he(n);return t.invert=he(-n),t}function ge(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*r+a*i;return[Math.atan2(l*u-f*o,a*r-c*i),tn(f*u+l*o)]}var r=Math.cos(n),i=Math.sin(n),u=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,l=Math.sin(n)*e,c=Math.sin(t),f=c*u-l*o;return[Math.atan2(l*u+c*o,a*r+f*i),tn(f*r-a*i)]},e}function ve(n,t){var e=Math.cos(n),r=Math.sin(n);return function(i,u,o,a){var l=o*t;null!=i?(i=de(e,i),u=de(e,u),(o>0?u>i:i>u)&&(i+=o*Ho)):(i=n+o*Ho,u=n-.5*l);for(var c,f=i;o>0?f>u:u>f;f-=l)a.point((c=_t([e,-r*Math.cos(f),-r*Math.sin(f)]))[0],c[1])}}function de(n,t){var e=dt(t);e[0]-=n,bt(e);var r=nn(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Uo)%(2*Math.PI)}function ye(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function me(n,t,e){var r=ao.range(n,t-Uo,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function Me(n){return n.source}function xe(n){return n.target}function be(n,t,e,r){var i=Math.cos(t),u=Math.sin(t),o=Math.cos(r),a=Math.sin(r),l=i*Math.cos(n),c=i*Math.sin(n),f=o*Math.cos(e),s=o*Math.sin(e),h=2*Math.asin(Math.sqrt(on(r-t)+i*o*on(e-n))),p=1/Math.sin(h),g=h?function(n){var t=Math.sin(n*=h)*p,e=Math.sin(h-n)*p,r=e*l+t*f,i=e*c+t*s,o=e*u+t*a;return[Math.atan2(i,r)*Zo,Math.atan2(o,Math.sqrt(r*r+i*i))*Zo]}:function(){return[n*Zo,t*Zo]};return g.distance=h,g}function _e(){function n(n,i){var u=Math.sin(i*=Yo),o=Math.cos(i),a=xo((n*=Yo)-t),l=Math.cos(a);Ja+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*u-e*o*l)*a),e*u+r*o*l),t=n,e=u,r=o}var t,e,r;Ga.point=function(i,u){t=i*Yo,e=Math.sin(u*=Yo),r=Math.cos(u),Ga.point=n},Ga.lineEnd=function(){Ga.point=Ga.lineEnd=b}}function we(n,t){function e(t,e){var r=Math.cos(t),i=Math.cos(e),u=n(r*i);return[u*i*Math.sin(t),u*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),i=t(r),u=Math.sin(i),o=Math.cos(i);return[Math.atan2(n*u,r*o),Math.asin(r&&e*u/r)]},e}function Se(n,t){function e(n,t){o>0?-Io+Uo>t&&(t=-Io+Uo):t>Io-Uo&&(t=Io-Uo);var e=o/Math.pow(i(t),u);return[e*Math.sin(u*n),o-e*Math.cos(u*n)]}var r=Math.cos(n),i=function(n){return Math.tan(Fo/4+n/2)},u=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(i(t)/i(n)),o=r*Math.pow(i(n),u)/u;return u?(e.invert=function(n,t){var e=o-t,r=K(u)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/u,2*Math.atan(Math.pow(o/r,1/u))-Io]},e):Ne}function ke(n,t){function e(n,t){var e=u-t;return[e*Math.sin(i*n),u-e*Math.cos(i*n)]}var r=Math.cos(n),i=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),u=r/i+n;return xo(i)i;i++){for(;r>1&&Q(n[e[r-2]],n[e[r-1]],n[i])<=0;)--r;e[r++]=i}return e.slice(0,r)}function qe(n,t){return n[0]-t[0]||n[1]-t[1]}function Te(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Re(n,t,e,r){var i=n[0],u=e[0],o=t[0]-i,a=r[0]-u,l=n[1],c=e[1],f=t[1]-l,s=r[1]-c,h=(a*(l-c)-s*(i-u))/(s*o-a*f);return[i+h*o,l+h*f]}function De(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Pe(){rr(this),this.edge=this.site=this.circle=null}function Ue(n){var t=cl.pop()||new Pe;return t.site=n,t}function je(n){Be(n),ol.remove(n),cl.push(n),rr(n)}function Fe(n){var t=n.circle,e=t.x,r=t.cy,i={x:e,y:r},u=n.P,o=n.N,a=[n];je(n);for(var l=u;l.circle&&xo(e-l.circle.x)f;++f)c=a[f],l=a[f-1],nr(c.edge,l.site,c.site,i);l=a[0],c=a[s-1],c.edge=Ke(l.site,c.site,null,i),$e(l),$e(c)}function He(n){for(var t,e,r,i,u=n.x,o=n.y,a=ol._;a;)if(r=Oe(a,o)-u,r>Uo)a=a.L;else{if(i=u-Ie(a,o),!(i>Uo)){r>-Uo?(t=a.P,e=a):i>-Uo?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var l=Ue(n);if(ol.insert(t,l),t||e){if(t===e)return Be(t),e=Ue(t.site),ol.insert(l,e),l.edge=e.edge=Ke(t.site,l.site),$e(t),void $e(e);if(!e)return void(l.edge=Ke(t.site,l.site));Be(t),Be(e);var c=t.site,f=c.x,s=c.y,h=n.x-f,p=n.y-s,g=e.site,v=g.x-f,d=g.y-s,y=2*(h*d-p*v),m=h*h+p*p,M=v*v+d*d,x={x:(d*m-p*M)/y+f,y:(h*M-v*m)/y+s};nr(e.edge,c,g,x),l.edge=Ke(c,n,null,x),e.edge=Ke(n,g,null,x),$e(t),$e(e)}}function Oe(n,t){var e=n.site,r=e.x,i=e.y,u=i-t;if(!u)return r;var o=n.P;if(!o)return-(1/0);e=o.site;var a=e.x,l=e.y,c=l-t;if(!c)return a;var f=a-r,s=1/u-1/c,h=f/c;return s?(-h+Math.sqrt(h*h-2*s*(f*f/(-2*c)-l+c/2+i-u/2)))/s+r:(r+a)/2}function Ie(n,t){var e=n.N;if(e)return Oe(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ye(n){this.site=n,this.edges=[]}function Ze(n){for(var t,e,r,i,u,o,a,l,c,f,s=n[0][0],h=n[1][0],p=n[0][1],g=n[1][1],v=ul,d=v.length;d--;)if(u=v[d],u&&u.prepare())for(a=u.edges,l=a.length,o=0;l>o;)f=a[o].end(),r=f.x,i=f.y,c=a[++o%l].start(),t=c.x,e=c.y,(xo(r-t)>Uo||xo(i-e)>Uo)&&(a.splice(o,0,new tr(Qe(u.site,f,xo(r-s)Uo?{x:s,y:xo(t-s)Uo?{x:xo(e-g)Uo?{x:h,y:xo(t-h)Uo?{x:xo(e-p)=-jo)){var p=l*l+c*c,g=f*f+s*s,v=(s*p-c*g)/h,d=(l*g-f*p)/h,s=d+a,y=fl.pop()||new Xe;y.arc=n,y.site=i,y.x=v+o,y.y=s+Math.sqrt(v*v+d*d),y.cy=s,n.circle=y;for(var m=null,M=ll._;M;)if(y.yd||d>=a)return;if(h>g){if(u){if(u.y>=c)return}else u={x:d,y:l};e={x:d,y:c}}else{if(u){if(u.yr||r>1)if(h>g){if(u){if(u.y>=c)return}else u={x:(l-i)/r,y:l};e={x:(c-i)/r,y:c}}else{if(u){if(u.yp){if(u){if(u.x>=a)return}else u={x:o,y:r*o+i};e={x:a,y:r*a+i}}else{if(u){if(u.xu||s>o||r>h||i>p)){if(g=n.point){var g,v=t-n.x,d=e-n.y,y=v*v+d*d;if(l>y){var m=Math.sqrt(l=y);r=t-m,i=e-m,u=t+m,o=e+m,a=g}}for(var M=n.nodes,x=.5*(f+h),b=.5*(s+p),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:c(n,f,s,x,b);break;case 1:c(n,x,s,h,b);break;case 2:c(n,f,b,x,p);break;case 3:c(n,x,b,h,p)}}}(n,r,i,u,o),a}function vr(n,t){n=ao.rgb(n),t=ao.rgb(t);var e=n.r,r=n.g,i=n.b,u=t.r-e,o=t.g-r,a=t.b-i;return function(n){return"#"+bn(Math.round(e+u*n))+bn(Math.round(r+o*n))+bn(Math.round(i+a*n))}}function dr(n,t){var e,r={},i={};for(e in n)e in t?r[e]=Mr(n[e],t[e]):i[e]=n[e];for(e in t)e in n||(i[e]=t[e]);return function(n){for(e in r)i[e]=r[e](n);return i}}function yr(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function mr(n,t){var e,r,i,u=hl.lastIndex=pl.lastIndex=0,o=-1,a=[],l=[];for(n+="",t+="";(e=hl.exec(n))&&(r=pl.exec(t));)(i=r.index)>u&&(i=t.slice(u,i),a[o]?a[o]+=i:a[++o]=i),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,l.push({i:o,x:yr(e,r)})),u=pl.lastIndex;return ur;++r)a[(e=l[r]).i]=e.x(n);return a.join("")})}function Mr(n,t){for(var e,r=ao.interpolators.length;--r>=0&&!(e=ao.interpolators[r](n,t)););return e}function xr(n,t){var e,r=[],i=[],u=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(Mr(n[e],t[e]));for(;u>e;++e)i[e]=n[e];for(;o>e;++e)i[e]=t[e];return function(n){for(e=0;a>e;++e)i[e]=r[e](n);return i}}function br(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function _r(n){return function(t){return 1-n(1-t)}}function wr(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function Sr(n){return n*n}function kr(n){return n*n*n}function Nr(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Er(n){return function(t){return Math.pow(t,n)}}function Ar(n){return 1-Math.cos(n*Io)}function Cr(n){return Math.pow(2,10*(n-1))}function zr(n){return 1-Math.sqrt(1-n*n)}function Lr(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Ho*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Ho/t)}}function qr(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Tr(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Rr(n,t){n=ao.hcl(n),t=ao.hcl(t);var e=n.h,r=n.c,i=n.l,u=t.h-e,o=t.c-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return sn(e+u*n,r+o*n,i+a*n)+""}}function Dr(n,t){n=ao.hsl(n),t=ao.hsl(t);var e=n.h,r=n.s,i=n.l,u=t.h-e,o=t.s-r,a=t.l-i;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(u)?(u=0,e=isNaN(e)?t.h:e):u>180?u-=360:-180>u&&(u+=360),function(n){return cn(e+u*n,r+o*n,i+a*n)+""}}function Pr(n,t){n=ao.lab(n),t=ao.lab(t);var e=n.l,r=n.a,i=n.b,u=t.l-e,o=t.a-r,a=t.b-i;return function(n){return pn(e+u*n,r+o*n,i+a*n)+""}}function Ur(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function jr(n){var t=[n.a,n.b],e=[n.c,n.d],r=Hr(t),i=Fr(t,e),u=Hr(Or(e,t,-i))||0;t[0]*e[1]180?t+=360:t-n>180&&(n+=360),r.push({i:e.push(Ir(e)+"rotate(",null,")")-2,x:yr(n,t)})):t&&e.push(Ir(e)+"rotate("+t+")")}function Vr(n,t,e,r){n!==t?r.push({i:e.push(Ir(e)+"skewX(",null,")")-2,x:yr(n,t)}):t&&e.push(Ir(e)+"skewX("+t+")")}function Xr(n,t,e,r){if(n[0]!==t[0]||n[1]!==t[1]){var i=e.push(Ir(e)+"scale(",null,",",null,")");r.push({i:i-4,x:yr(n[0],t[0])},{i:i-2,x:yr(n[1],t[1])})}else 1===t[0]&&1===t[1]||e.push(Ir(e)+"scale("+t+")")}function $r(n,t){var e=[],r=[];return n=ao.transform(n),t=ao.transform(t),Yr(n.translate,t.translate,e,r),Zr(n.rotate,t.rotate,e,r),Vr(n.skew,t.skew,e,r),Xr(n.scale,t.scale,e,r),n=t=null,function(n){for(var t,i=-1,u=r.length;++i=0;)e.push(i[r])}function oi(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(u=n.children)&&(i=u.length))for(var i,u,o=-1;++oe;++e)(t=n[e][1])>i&&(r=e,i=t);return r}function yi(n){return n.reduce(mi,0)}function mi(n,t){return n+t[1]}function Mi(n,t){return xi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function xi(n,t){for(var e=-1,r=+n[0],i=(n[1]-r)/t,u=[];++e<=t;)u[e]=i*e+r;return u}function bi(n){return[ao.min(n),ao.max(n)]}function _i(n,t){return n.value-t.value}function wi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Si(n,t){n._pack_next=t,t._pack_prev=n}function ki(n,t){var e=t.x-n.x,r=t.y-n.y,i=n.r+t.r;return.999*i*i>e*e+r*r}function Ni(n){function t(n){f=Math.min(n.x-n.r,f),s=Math.max(n.x+n.r,s),h=Math.min(n.y-n.r,h),p=Math.max(n.y+n.r,p)}if((e=n.children)&&(c=e.length)){var e,r,i,u,o,a,l,c,f=1/0,s=-(1/0),h=1/0,p=-(1/0);if(e.forEach(Ei),r=e[0],r.x=-r.r,r.y=0,t(r),c>1&&(i=e[1],i.x=i.r,i.y=0,t(i),c>2))for(u=e[2],zi(r,i,u),t(u),wi(r,u),r._pack_prev=u,wi(u,i),i=r._pack_next,o=3;c>o;o++){zi(r,i,u=e[o]);var g=0,v=1,d=1;for(a=i._pack_next;a!==i;a=a._pack_next,v++)if(ki(a,u)){g=1;break}if(1==g)for(l=r._pack_prev;l!==a._pack_prev&&!ki(l,u);l=l._pack_prev,d++);g?(d>v||v==d&&i.ro;o++)u=e[o],u.x-=y,u.y-=m,M=Math.max(M,u.r+Math.sqrt(u.x*u.x+u.y*u.y));n.r=M,e.forEach(Ai)}}function Ei(n){n._pack_next=n._pack_prev=n}function Ai(n){delete n._pack_next,delete n._pack_prev}function Ci(n,t,e,r){var i=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,i)for(var u=-1,o=i.length;++u=0;)t=i[u],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Pi(n,t,e){return n.a.parent===t.parent?n.a:e}function Ui(n){return 1+ao.max(n,function(n){return n.y})}function ji(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Fi(n){var t=n.children;return t&&t.length?Fi(t[0]):n}function Hi(n){var t,e=n.children;return e&&(t=e.length)?Hi(e[t-1]):n}function Oi(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Ii(n,t){var e=n.x+t[3],r=n.y+t[0],i=n.dx-t[1]-t[3],u=n.dy-t[0]-t[2];return 0>i&&(e+=i/2,i=0),0>u&&(r+=u/2,u=0),{x:e,y:r,dx:i,dy:u}}function Yi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Zi(n){return n.rangeExtent?n.rangeExtent():Yi(n.range())}function Vi(n,t,e,r){var i=e(n[0],n[1]),u=r(t[0],t[1]);return function(n){return u(i(n))}}function Xi(n,t){var e,r=0,i=n.length-1,u=n[r],o=n[i];return u>o&&(e=r,r=i,i=e,e=u,u=o,o=e),n[r]=t.floor(u),n[i]=t.ceil(o),n}function $i(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:Sl}function Bi(n,t,e,r){var i=[],u=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Bi:Vi,l=r?Wr:Br;return o=i(n,t,l,e),a=i(t,n,l,Mr),u}function u(n){return o(n)}var o,a;return u.invert=function(n){return a(n)},u.domain=function(t){return arguments.length?(n=t.map(Number),i()):n},u.range=function(n){return arguments.length?(t=n,i()):t},u.rangeRound=function(n){return u.range(n).interpolate(Ur)},u.clamp=function(n){return arguments.length?(r=n,i()):r},u.interpolate=function(n){return arguments.length?(e=n,i()):e},u.ticks=function(t){return Qi(n,t)},u.tickFormat=function(t,e){return nu(n,t,e)},u.nice=function(t){return Gi(n,t),i()},u.copy=function(){return Wi(n,t,e,r)},i()}function Ji(n,t){return ao.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Gi(n,t){return Xi(n,$i(Ki(n,t)[2])),Xi(n,$i(Ki(n,t)[2])),n}function Ki(n,t){null==t&&(t=10);var e=Yi(n),r=e[1]-e[0],i=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),u=t/r*i;return.15>=u?i*=10:.35>=u?i*=5:.75>=u&&(i*=2),e[0]=Math.ceil(e[0]/i)*i,e[1]=Math.floor(e[1]/i)*i+.5*i,e[2]=i,e}function Qi(n,t){return ao.range.apply(ao,Ki(n,t))}function nu(n,t,e){var r=Ki(n,t);if(e){var i=ha.exec(e);if(i.shift(),"s"===i[8]){var u=ao.formatPrefix(Math.max(xo(r[0]),xo(r[1])));return i[7]||(i[7]="."+tu(u.scale(r[2]))),i[8]="f",e=ao.format(i.join("")),function(n){return e(u.scale(n))+u.symbol}}i[7]||(i[7]="."+eu(i[8],r)),e=i.join("")}else e=",."+tu(r[2])+"f";return ao.format(e)}function tu(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function eu(n,t){var e=tu(t[2]);return n in kl?Math.abs(e-tu(Math.max(xo(t[0]),xo(t[1]))))+ +("e"!==n):e-2*("%"===n)}function ru(n,t,e,r){function i(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function u(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(i(t))}return o.invert=function(t){return u(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(i)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(i)),o):t},o.nice=function(){var t=Xi(r.map(i),e?Math:El);return n.domain(t),r=t.map(u),o},o.ticks=function(){var n=Yi(r),o=[],a=n[0],l=n[1],c=Math.floor(i(a)),f=Math.ceil(i(l)),s=t%1?2:t;if(isFinite(f-c)){if(e){for(;f>c;c++)for(var h=1;s>h;h++)o.push(u(c)*h);o.push(u(c))}else for(o.push(u(c));c++0;h--)o.push(u(c)*h);for(c=0;o[c]l;f--);o=o.slice(c,f)}return o},o.tickFormat=function(n,e){if(!arguments.length)return Nl;arguments.length<2?e=Nl:"function"!=typeof e&&(e=ao.format(e));var r=Math.max(1,t*n/o.ticks().length);return function(n){var o=n/u(Math.round(i(n)));return t-.5>o*t&&(o*=t),r>=o?e(n):""}},o.copy=function(){return ru(n.copy(),t,e,r)},Ji(o,n)}function iu(n,t,e){function r(t){return n(i(t))}var i=uu(t),u=uu(1/t);return r.invert=function(t){return u(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(i)),r):e},r.ticks=function(n){return Qi(e,n)},r.tickFormat=function(n,t){return nu(e,n,t)},r.nice=function(n){return r.domain(Gi(e,n))},r.exponent=function(o){return arguments.length?(i=uu(t=o),u=uu(1/t),n.domain(e.map(i)),r):t},r.copy=function(){return iu(n.copy(),t,e)},Ji(r,n)}function uu(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function ou(n,t){function e(e){return u[((i.get(e)||("range"===t.t?i.set(e,n.push(e)):NaN))-1)%u.length]}function r(t,e){return ao.range(n.length).map(function(n){return t+e*n})}var i,u,o;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new c;for(var u,o=-1,a=r.length;++oe?[NaN,NaN]:[e>0?a[e-1]:n[0],et?NaN:t/u+n,[t,t+1/u]},r.copy=function(){return lu(n,t,e)},i()}function cu(n,t){function e(e){return e>=e?t[ao.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return cu(n,t)},e}function fu(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Qi(n,t)},t.tickFormat=function(t,e){return nu(n,t,e)},t.copy=function(){return fu(n)},t}function su(){return 0}function hu(n){return n.innerRadius}function pu(n){return n.outerRadius}function gu(n){return n.startAngle}function vu(n){return n.endAngle}function du(n){return n&&n.padAngle}function yu(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function mu(n,t,e,r,i){var u=n[0]-t[0],o=n[1]-t[1],a=(i?r:-r)/Math.sqrt(u*u+o*o),l=a*o,c=-a*u,f=n[0]+l,s=n[1]+c,h=t[0]+l,p=t[1]+c,g=(f+h)/2,v=(s+p)/2,d=h-f,y=p-s,m=d*d+y*y,M=e-r,x=f*p-h*s,b=(0>y?-1:1)*Math.sqrt(Math.max(0,M*M*m-x*x)),_=(x*y-d*b)/m,w=(-x*d-y*b)/m,S=(x*y+d*b)/m,k=(-x*d+y*b)/m,N=_-g,E=w-v,A=S-g,C=k-v;return N*N+E*E>A*A+C*C&&(_=S,w=k),[[_-l,w-c],[_*e/M,w*e/M]]}function Mu(n){function t(t){function o(){c.push("M",u(n(f),a))}for(var l,c=[],f=[],s=-1,h=t.length,p=En(e),g=En(r);++s1?n.join("L"):n+"Z"}function bu(n){return n.join("L")+"Z"}function _u(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1&&i.push("H",r[0]),i.join("")}function wu(n){for(var t=0,e=n.length,r=n[0],i=[r[0],",",r[1]];++t1){a=t[1],u=n[l],l++,r+="C"+(i[0]+o[0])+","+(i[1]+o[1])+","+(u[0]-a[0])+","+(u[1]-a[1])+","+u[0]+","+u[1];for(var c=2;c9&&(i=3*t/Math.sqrt(i),o[a]=i*e,o[a+1]=i*r));for(a=-1;++a<=l;)i=(n[Math.min(l,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),u.push([i||0,o[a]*i||0]);return u}function Fu(n){return n.length<3?xu(n):n[0]+Au(n,ju(n))}function Hu(n){for(var t,e,r,i=-1,u=n.length;++i=t?o(n-t):void(f.c=o)}function o(e){var i=g.active,u=g[i];u&&(u.timer.c=null,u.timer.t=NaN,--g.count,delete g[i],u.event&&u.event.interrupt.call(n,n.__data__,u.index));for(var o in g)if(r>+o){var c=g[o];c.timer.c=null,c.timer.t=NaN,--g.count,delete g[o]}f.c=a,qn(function(){return f.c&&a(e||1)&&(f.c=null,f.t=NaN),1},0,l),g.active=r,v.event&&v.event.start.call(n,n.__data__,t),p=[],v.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&p.push(r)}),h=v.ease,s=v.duration}function a(i){for(var u=i/s,o=h(u),a=p.length;a>0;)p[--a].call(n,o);return u>=1?(v.event&&v.event.end.call(n,n.__data__,t),--g.count?delete g[r]:delete n[e],1):void 0}var l,f,s,h,p,g=n[e]||(n[e]={active:0,count:0}),v=g[r];v||(l=i.time,f=qn(u,0,l),v=g[r]={tween:new c,time:l,timer:f,delay:i.delay,duration:i.duration,ease:i.ease,index:t},i=null,++g.count)}function no(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function to(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function eo(n){return n.toISOString()}function ro(n,t,e){function r(t){return n(t)}function i(n,e){var r=n[1]-n[0],i=r/e,u=ao.bisect(Kl,i);return u==Kl.length?[t.year,Ki(n.map(function(n){return n/31536e6}),e)[2]]:u?t[i/Kl[u-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Yi(r.domain()),u=null==n?i(e,10):"number"==typeof n?i(e,n):!n.range&&[{range:n},t];return u&&(n=u[0],t=u[1]),n.range(e[0],io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return ro(n.copy(),t,e)},Ji(r,n)}function io(n){return new Date(n)}function uo(n){return JSON.parse(n.responseText)}function oo(n){var t=fo.createRange();return t.selectNode(fo.body),t.createContextualFragment(n.responseText)}var ao={version:"3.5.17"},lo=[].slice,co=function(n){return lo.call(n)},fo=this.document;if(fo)try{co(fo.documentElement.childNodes)[0].nodeType}catch(so){co=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}if(Date.now||(Date.now=function(){return+new Date}),fo)try{fo.createElement("DIV").style.setProperty("opacity",0,"")}catch(ho){var po=this.Element.prototype,go=po.setAttribute,vo=po.setAttributeNS,yo=this.CSSStyleDeclaration.prototype,mo=yo.setProperty;po.setAttribute=function(n,t){go.call(this,n,t+"")},po.setAttributeNS=function(n,t,e){vo.call(this,n,t,e+"")},yo.setProperty=function(n,t,e){mo.call(this,n,t+"",e)}}ao.ascending=e,ao.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:NaN},ao.min=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ir&&(e=r)}else{for(;++i=r){e=r;break}for(;++ir&&(e=r)}return e},ao.max=function(n,t){var e,r,i=-1,u=n.length;if(1===arguments.length){for(;++i=r){e=r;break}for(;++ie&&(e=r)}else{for(;++i=r){e=r;break}for(;++ie&&(e=r)}return e},ao.extent=function(n,t){var e,r,i,u=-1,o=n.length;if(1===arguments.length){for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}else{for(;++u=r){e=i=r;break}for(;++ur&&(e=r),r>i&&(i=r))}return[e,i]},ao.sum=function(n,t){var e,r=0,u=n.length,o=-1;if(1===arguments.length)for(;++o1?l/(f-1):void 0},ao.deviation=function(){var n=ao.variance.apply(this,arguments);return n?Math.sqrt(n):n};var Mo=u(e);ao.bisectLeft=Mo.left,ao.bisect=ao.bisectRight=Mo.right,ao.bisector=function(n){return u(1===n.length?function(t,r){return e(n(t),r)}:n)},ao.shuffle=function(n,t,e){(u=arguments.length)<3&&(e=n.length,2>u&&(t=0));for(var r,i,u=e-t;u;)i=Math.random()*u--|0,r=n[u+t],n[u+t]=n[i+t],n[i+t]=r;return n},ao.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ao.pairs=function(n){for(var t,e=0,r=n.length-1,i=n[0],u=new Array(0>r?0:r);r>e;)u[e]=[t=i,i=n[++e]];return u},ao.transpose=function(n){if(!(i=n.length))return[];for(var t=-1,e=ao.min(n,o),r=new Array(e);++t=0;)for(r=n[i],t=r.length;--t>=0;)e[--o]=r[t];return e};var xo=Math.abs;ao.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),(t-n)/e===1/0)throw new Error("infinite range");var r,i=[],u=a(xo(e)),o=-1;if(n*=u,t*=u,e*=u,0>e)for(;(r=n+e*++o)>t;)i.push(r/u);else for(;(r=n+e*++o)=u.length)return r?r.call(i,o):e?o.sort(e):o;for(var l,f,s,h,p=-1,g=o.length,v=u[a++],d=new c;++p=u.length)return n;var r=[],i=o[e++];return n.forEach(function(n,i){r.push({key:n,values:t(i,e)})}),i?r.sort(function(n,t){return i(n.key,t.key)}):r}var e,r,i={},u=[],o=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(ao.map,e,0),0)},i.key=function(n){return u.push(n),i},i.sortKeys=function(n){return o[u.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},ao.set=function(n){var t=new y;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},l(y,{has:h,add:function(n){return this._[f(n+="")]=!0,n},remove:p,values:g,size:v,empty:d,forEach:function(n){for(var t in this._)n.call(this,s(t))}}),ao.behavior={},ao.rebind=function(n,t){for(var e,r=1,i=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},ao.event=null,ao.requote=function(n){return n.replace(So,"\\$&")};var So=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,ko={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},No=function(n,t){return t.querySelector(n)},Eo=function(n,t){return t.querySelectorAll(n)},Ao=function(n,t){var e=n.matches||n[x(n,"matchesSelector")];return(Ao=function(n,t){return e.call(n,t)})(n,t)};"function"==typeof Sizzle&&(No=function(n,t){return Sizzle(n,t)[0]||null},Eo=Sizzle,Ao=Sizzle.matchesSelector),ao.selection=function(){return ao.select(fo.documentElement)};var Co=ao.selection.prototype=[];Co.select=function(n){var t,e,r,i,u=[];n=A(n);for(var o=-1,a=this.length;++o=0&&"xmlns"!==(e=n.slice(0,t))&&(n=n.slice(t+1)),Lo.hasOwnProperty(e)?{space:Lo[e],local:n}:n}},Co.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ao.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(z(t,n[t]));return this}return this.each(z(n,t))},Co.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=T(n)).length,i=-1;if(t=e.classList){for(;++ii){if("string"!=typeof n){2>i&&(e="");for(r in n)this.each(P(r,n[r],e));return this}if(2>i){var u=this.node();return t(u).getComputedStyle(u,null).getPropertyValue(n)}r=""}return this.each(P(n,e,r))},Co.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(U(t,n[t]));return this}return this.each(U(n,t))},Co.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},Co.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},Co.append=function(n){return n=j(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},Co.insert=function(n,t){return n=j(n),t=A(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},Co.remove=function(){return this.each(F)},Co.data=function(n,t){function e(n,e){var r,i,u,o=n.length,s=e.length,h=Math.min(o,s),p=new Array(s),g=new Array(s),v=new Array(o);if(t){var d,y=new c,m=new Array(o);for(r=-1;++rr;++r)g[r]=H(e[r]);for(;o>r;++r)v[r]=n[r]}g.update=p,g.parentNode=p.parentNode=v.parentNode=n.parentNode,a.push(g),l.push(p),f.push(v)}var r,i,u=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(r=this[0]).length);++uu;u++){i.push(t=[]),t.parentNode=(e=this[u]).parentNode;for(var a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return E(i)},Co.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[i])&&(u&&u!==e.nextSibling&&u.parentNode.insertBefore(e,u),u=e);return this},Co.sort=function(n){n=I.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,i=e.length;i>r;r++){var u=e[r];if(u)return u}return null},Co.size=function(){var n=0;return Y(this,function(){++n}),n};var qo=[];ao.selection.enter=Z,ao.selection.enter.prototype=qo,qo.append=Co.append,qo.empty=Co.empty,qo.node=Co.node,qo.call=Co.call,qo.size=Co.size,qo.select=function(n){for(var t,e,r,i,u,o=[],a=-1,l=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(X(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(X(n,t,e))};var To=ao.map({mouseenter:"mouseover",mouseleave:"mouseout"});fo&&To.forEach(function(n){"on"+n in fo&&To.remove(n)});var Ro,Do=0;ao.mouse=function(n){return J(n,k())};var Po=this.navigator&&/WebKit/.test(this.navigator.userAgent)?-1:0;ao.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=k().changedTouches),t)for(var r,i=0,u=t.length;u>i;++i)if((r=t[i]).identifier===e)return J(n,r)},ao.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",o)}function e(n,t,e,u,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-M[0],e=r[1]-M[1],g|=n|e,M=r,p({type:"drag",x:r[0]+c[0],y:r[1]+c[1],dx:n,dy:e}))}function l(){t(h,v)&&(y.on(u+d,null).on(o+d,null),m(g),p({type:"dragend"}))}var c,f=this,s=ao.event.target.correspondingElement||ao.event.target,h=f.parentNode,p=r.of(f,arguments),g=0,v=n(),d=".drag"+(null==v?"":"-"+v),y=ao.select(e(s)).on(u+d,a).on(o+d,l),m=W(s),M=t(h,v);i?(c=i.apply(f,arguments),c=[c.x-M[0],c.y-M[1]]):c=[0,0],p({type:"dragstart"})}}var r=N(n,"drag","dragstart","dragend"),i=null,u=e(b,ao.mouse,t,"mousemove","mouseup"),o=e(G,ao.touch,m,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},ao.rebind(n,r,"on")},ao.touches=function(n,t){return arguments.length<2&&(t=k().touches),t?co(t).map(function(t){var e=J(n,t);return e.identifier=t.identifier,e}):[]};var Uo=1e-6,jo=Uo*Uo,Fo=Math.PI,Ho=2*Fo,Oo=Ho-Uo,Io=Fo/2,Yo=Fo/180,Zo=180/Fo,Vo=Math.SQRT2,Xo=2,$o=4;ao.interpolateZoom=function(n,t){var e,r,i=n[0],u=n[1],o=n[2],a=t[0],l=t[1],c=t[2],f=a-i,s=l-u,h=f*f+s*s;if(jo>h)r=Math.log(c/o)/Vo,e=function(n){return[i+n*f,u+n*s,o*Math.exp(Vo*n*r)]};else{var p=Math.sqrt(h),g=(c*c-o*o+$o*h)/(2*o*Xo*p),v=(c*c-o*o-$o*h)/(2*c*Xo*p),d=Math.log(Math.sqrt(g*g+1)-g),y=Math.log(Math.sqrt(v*v+1)-v);r=(y-d)/Vo,e=function(n){var t=n*r,e=rn(d),a=o/(Xo*p)*(e*un(Vo*t+d)-en(d));return[i+a*f,u+a*s,o*e/rn(Vo*t+d)]}}return e.duration=1e3*r,e},ao.behavior.zoom=function(){function n(n){n.on(L,s).on(Wo+".zoom",p).on("dblclick.zoom",g).on(R,h)}function e(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function r(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function i(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=r(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function o(t,e,r,o){t.__chart__={x:k.x,y:k.y,k:k.k},i(Math.pow(2,o)),u(d=e,r),t=ao.select(t),C>0&&(t=t.transition().duration(C)),t.call(n.event)}function a(){b&&b.domain(x.range().map(function(n){return(n-k.x)/k.k}).map(x.invert)),w&&w.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function l(n){z++||n({type:"zoomstart"})}function c(n){a(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function f(n){--z||(n({type:"zoomend"}),d=null)}function s(){function n(){a=1,u(ao.mouse(i),h),c(o)}function r(){s.on(q,null).on(T,null),p(a),f(o)}var i=this,o=D.of(i,arguments),a=0,s=ao.select(t(i)).on(q,n).on(T,r),h=e(ao.mouse(i)),p=W(i);Il.call(i),l(o)}function h(){function n(){var n=ao.touches(g);return p=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=e(n))}),n}function t(){var t=ao.event.target;ao.select(t).on(x,r).on(b,a),_.push(t);for(var e=ao.event.changedTouches,i=0,u=e.length;u>i;++i)d[e[i].identifier]=null;var l=n(),c=Date.now();if(1===l.length){if(500>c-M){var f=l[0];o(g,f,d[f.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),S()}M=c}else if(l.length>1){var f=l[0],s=l[1],h=f[0]-s[0],p=f[1]-s[1];y=h*h+p*p}}function r(){var n,t,e,r,o=ao.touches(g);Il.call(g);for(var a=0,l=o.length;l>a;++a,r=null)if(e=o[a],r=d[e.identifier]){if(t)break;n=e,t=r}if(r){var f=(f=e[0]-n[0])*f+(f=e[1]-n[1])*f,s=y&&Math.sqrt(f/y);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+r[0])/2,(t[1]+r[1])/2],i(s*p)}M=null,u(n,t),c(v)}function a(){if(ao.event.touches.length){for(var t=ao.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var i in d)return void n()}ao.selectAll(_).on(m,null),w.on(L,s).on(R,h),N(),f(v)}var p,g=this,v=D.of(g,arguments),d={},y=0,m=".zoom-"+ao.event.changedTouches[0].identifier,x="touchmove"+m,b="touchend"+m,_=[],w=ao.select(g),N=W(g);t(),l(v),w.on(L,null).on(R,t)}function p(){var n=D.of(this,arguments);m?clearTimeout(m):(Il.call(this),v=e(d=y||ao.mouse(this)),l(n)),m=setTimeout(function(){m=null,f(n)},50),S(),i(Math.pow(2,.002*Bo())*k.k),u(d,v),c(n)}function g(){var n=ao.mouse(this),t=Math.log(k.k)/Math.LN2;o(this,n,e(n),ao.event.shiftKey?Math.ceil(t)-1:Math.floor(t)+1)}var v,d,y,m,M,x,b,_,w,k={x:0,y:0,k:1},E=[960,500],A=Jo,C=250,z=0,L="mousedown.zoom",q="mousemove.zoom",T="mouseup.zoom",R="touchstart.zoom",D=N(n,"zoomstart","zoom","zoomend");return Wo||(Wo="onwheel"in fo?(Bo=function(){return-ao.event.deltaY*(ao.event.deltaMode?120:1)},"wheel"):"onmousewheel"in fo?(Bo=function(){return ao.event.wheelDelta},"mousewheel"):(Bo=function(){return-ao.event.detail},"MozMousePixelScroll")),n.event=function(n){n.each(function(){var n=D.of(this,arguments),t=k;Hl?ao.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},l(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],i=d?d[0]:e/2,u=d?d[1]:r/2,o=ao.interpolateZoom([(i-k.x)/k.k,(u-k.y)/k.k,e/k.k],[(i-t.x)/t.k,(u-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:i-r[0]*a,y:u-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){f(n)}).each("end.zoom",function(){f(n)}):(this.__chart__=k,l(n),c(n),f(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},a(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:null},i(+t),a(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Jo:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(y=t&&[+t[0],+t[1]],n):y},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(C=+t,n):C},n.x=function(t){return arguments.length?(b=t,x=t.copy(),k={x:0,y:0,k:1},n):b},n.y=function(t){return arguments.length?(w=t,_=t.copy(),k={x:0,y:0,k:1},n):w},ao.rebind(n,D,"on")};var Bo,Wo,Jo=[0,1/0];ao.color=an,an.prototype.toString=function(){return this.rgb()+""},ao.hsl=ln;var Go=ln.prototype=new an;Go.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,this.l/n)},Go.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ln(this.h,this.s,n*this.l)},Go.rgb=function(){return cn(this.h,this.s,this.l)},ao.hcl=fn;var Ko=fn.prototype=new an;Ko.brighter=function(n){return new fn(this.h,this.c,Math.min(100,this.l+Qo*(arguments.length?n:1)))},Ko.darker=function(n){return new fn(this.h,this.c,Math.max(0,this.l-Qo*(arguments.length?n:1)))},Ko.rgb=function(){return sn(this.h,this.c,this.l).rgb()},ao.lab=hn;var Qo=18,na=.95047,ta=1,ea=1.08883,ra=hn.prototype=new an;ra.brighter=function(n){return new hn(Math.min(100,this.l+Qo*(arguments.length?n:1)),this.a,this.b)},ra.darker=function(n){return new hn(Math.max(0,this.l-Qo*(arguments.length?n:1)),this.a,this.b)},ra.rgb=function(){return pn(this.l,this.a,this.b)},ao.rgb=mn;var ia=mn.prototype=new an;ia.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,i=30;return t||e||r?(t&&i>t&&(t=i),e&&i>e&&(e=i),r&&i>r&&(r=i),new mn(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new mn(i,i,i)},ia.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new mn(n*this.r,n*this.g,n*this.b)},ia.hsl=function(){return wn(this.r,this.g,this.b)},ia.toString=function(){return"#"+bn(this.r)+bn(this.g)+bn(this.b)};var ua=ao.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});ua.forEach(function(n,t){ua.set(n,Mn(t))}),ao.functor=En,ao.xhr=An(m),ao.dsv=function(n,t){function e(n,e,u){arguments.length<3&&(u=e,e=null);var o=Cn(n,t,null==e?r:i(e),u);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:i(n)):e},o}function r(n){return e.parse(n.responseText)}function i(n){return function(t){return e.parse(t.responseText,n)}}function u(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),l=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var i=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(i(n),e)}:i})},e.parseRows=function(n,t){function e(){if(f>=c)return o;if(i)return i=!1,u;var t=f;if(34===n.charCodeAt(t)){for(var e=t;e++f;){var r=n.charCodeAt(f++),a=1;if(10===r)i=!0;else if(13===r)i=!0,10===n.charCodeAt(f)&&(++f,++a);else if(r!==l)continue;return n.slice(t,f-a)}return n.slice(t)}for(var r,i,u={},o={},a=[],c=n.length,f=0,s=0;(r=e())!==o;){for(var h=[];r!==u&&r!==o;)h.push(r),r=e();t&&null==(h=t(h,s++))||a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new y,i=[];return t.forEach(function(n){for(var t in n)r.has(t)||i.push(r.add(t))}),[i.map(o).join(n)].concat(t.map(function(t){return i.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(u).join("\n")},e},ao.csv=ao.dsv(",","text/csv"),ao.tsv=ao.dsv(" ","text/tab-separated-values");var oa,aa,la,ca,fa=this[x(this,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ao.timer=function(){qn.apply(this,arguments)},ao.timer.flush=function(){Rn(),Dn()},ao.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var sa=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Un);ao.formatPrefix=function(n,t){var e=0;return(n=+n)&&(0>n&&(n*=-1),t&&(n=ao.round(n,Pn(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),sa[8+e/3]};var ha=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,pa=ao.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=ao.round(n,Pn(n,t))).toFixed(Math.max(0,Math.min(20,Pn(n*(1+1e-15),t))))}}),ga=ao.time={},va=Date;Hn.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){da.setUTCDate.apply(this._,arguments)},setDay:function(){da.setUTCDay.apply(this._,arguments)},setFullYear:function(){da.setUTCFullYear.apply(this._,arguments)},setHours:function(){da.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){da.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){da.setUTCMinutes.apply(this._,arguments)},setMonth:function(){da.setUTCMonth.apply(this._,arguments)},setSeconds:function(){da.setUTCSeconds.apply(this._,arguments)},setTime:function(){da.setTime.apply(this._,arguments)}};var da=Date.prototype;ga.year=On(function(n){return n=ga.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),ga.years=ga.year.range,ga.years.utc=ga.year.utc.range,ga.day=On(function(n){var t=new va(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),ga.days=ga.day.range,ga.days.utc=ga.day.utc.range,ga.dayOfYear=function(n){var t=ga.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=ga[n]=On(function(n){return(n=ga.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});ga[n+"s"]=e.range,ga[n+"s"].utc=e.utc.range,ga[n+"OfYear"]=function(n){var e=ga.year(n).getDay();return Math.floor((ga.dayOfYear(n)+(e+t)%7)/7)}}),ga.week=ga.sunday,ga.weeks=ga.sunday.range,ga.weeks.utc=ga.sunday.utc.range,ga.weekOfYear=ga.sundayOfYear;var ya={"-":"",_:" ",0:"0"},ma=/^\s*\d+/,Ma=/^%/;ao.locale=function(n){return{numberFormat:jn(n),timeFormat:Yn(n)}};var xa=ao.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], +shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});ao.format=xa.numberFormat,ao.geo={},ft.prototype={s:0,t:0,add:function(n){st(n,this.t,ba),st(ba.s,this.s,this),this.s?this.t+=ba.t:this.s=ba.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var ba=new ft;ao.geo.stream=function(n,t){n&&_a.hasOwnProperty(n.type)?_a[n.type](n,t):ht(n,t)};var _a={Feature:function(n,t){ht(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,i=e.length;++rn?4*Fo+n:n,Na.lineStart=Na.lineEnd=Na.point=b}};ao.geo.bounds=function(){function n(n,t){M.push(x=[f=n,h=n]),s>t&&(s=t),t>p&&(p=t)}function t(t,e){var r=dt([t*Yo,e*Yo]);if(y){var i=mt(y,r),u=[i[1],-i[0],0],o=mt(u,i);bt(o),o=_t(o);var l=t-g,c=l>0?1:-1,v=o[0]*Zo*c,d=xo(l)>180;if(d^(v>c*g&&c*t>v)){var m=o[1]*Zo;m>p&&(p=m)}else if(v=(v+360)%360-180,d^(v>c*g&&c*t>v)){var m=-o[1]*Zo;s>m&&(s=m)}else s>e&&(s=e),e>p&&(p=e);d?g>t?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t):h>=f?(f>t&&(f=t),t>h&&(h=t)):t>g?a(f,t)>a(f,h)&&(h=t):a(t,h)>a(f,h)&&(f=t)}else n(t,e);y=r,g=t}function e(){b.point=t}function r(){x[0]=f,x[1]=h,b.point=n,y=null}function i(n,e){if(y){var r=n-g;m+=xo(r)>180?r+(r>0?360:-360):r}else v=n,d=e;Na.point(n,e),t(n,e)}function u(){Na.lineStart()}function o(){i(v,d),Na.lineEnd(),xo(m)>Uo&&(f=-(h=180)),x[0]=f,x[1]=h,y=null}function a(n,t){return(t-=n)<0?t+360:t}function l(n,t){return n[0]-t[0]}function c(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nka?(f=-(h=180),s=-(p=90)):m>Uo?p=90:-Uo>m&&(s=-90),x[0]=f,x[1]=h}};return function(n){p=h=-(f=s=1/0),M=[],ao.geo.stream(n,b);var t=M.length;if(t){M.sort(l);for(var e,r=1,i=M[0],u=[i];t>r;++r)e=M[r],c(e[0],i)||c(e[1],i)?(a(i[0],e[1])>a(i[0],i[1])&&(i[1]=e[1]),a(e[0],i[1])>a(i[0],i[1])&&(i[0]=e[0])):u.push(i=e);for(var o,e,g=-(1/0),t=u.length-1,r=0,i=u[t];t>=r;i=e,++r)e=u[r],(o=a(i[1],e[0]))>g&&(g=o,f=e[0],h=i[1])}return M=x=null,f===1/0||s===1/0?[[NaN,NaN],[NaN,NaN]]:[[f,s],[h,p]]}}(),ao.geo.centroid=function(n){Ea=Aa=Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,ja);var t=Da,e=Pa,r=Ua,i=t*t+e*e+r*r;return jo>i&&(t=qa,e=Ta,r=Ra,Uo>Aa&&(t=Ca,e=za,r=La),i=t*t+e*e+r*r,jo>i)?[NaN,NaN]:[Math.atan2(e,t)*Zo,tn(r/Math.sqrt(i))*Zo]};var Ea,Aa,Ca,za,La,qa,Ta,Ra,Da,Pa,Ua,ja={sphere:b,point:St,lineStart:Nt,lineEnd:Et,polygonStart:function(){ja.lineStart=At},polygonEnd:function(){ja.lineStart=Nt}},Fa=Rt(zt,jt,Ht,[-Fo,-Fo/2]),Ha=1e9;ao.geo.clipExtent=function(){var n,t,e,r,i,u,o={stream:function(n){return i&&(i.valid=!1),i=u(n),i.valid=!0,i},extent:function(a){return arguments.length?(u=Zt(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),i&&(i.valid=!1,i=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(ao.geo.conicEqualArea=function(){return Vt(Xt)}).raw=Xt,ao.geo.albers=function(){return ao.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ao.geo.albersUsa=function(){function n(n){var u=n[0],o=n[1];return t=null,e(u,o),t||(r(u,o),t)||i(u,o),t}var t,e,r,i,u=ao.geo.albers(),o=ao.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ao.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),l={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=u.scale(),e=u.translate(),r=(n[0]-e[0])/t,i=(n[1]-e[1])/t;return(i>=.12&&.234>i&&r>=-.425&&-.214>r?o:i>=.166&&.234>i&&r>=-.214&&-.115>r?a:u).invert(n)},n.stream=function(n){var t=u.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,i){t.point(n,i),e.point(n,i),r.point(n,i)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(u.precision(t),o.precision(t),a.precision(t),n):u.precision()},n.scale=function(t){return arguments.length?(u.scale(t),o.scale(.35*t),a.scale(t),n.translate(u.translate())):u.scale()},n.translate=function(t){if(!arguments.length)return u.translate();var c=u.scale(),f=+t[0],s=+t[1];return e=u.translate(t).clipExtent([[f-.455*c,s-.238*c],[f+.455*c,s+.238*c]]).stream(l).point,r=o.translate([f-.307*c,s+.201*c]).clipExtent([[f-.425*c+Uo,s+.12*c+Uo],[f-.214*c-Uo,s+.234*c-Uo]]).stream(l).point,i=a.translate([f-.205*c,s+.212*c]).clipExtent([[f-.214*c+Uo,s+.166*c+Uo],[f-.115*c-Uo,s+.234*c-Uo]]).stream(l).point,n},n.scale(1070)};var Oa,Ia,Ya,Za,Va,Xa,$a={point:b,lineStart:b,lineEnd:b,polygonStart:function(){Ia=0,$a.lineStart=$t},polygonEnd:function(){$a.lineStart=$a.lineEnd=$a.point=b,Oa+=xo(Ia/2)}},Ba={point:Bt,lineStart:b,lineEnd:b,polygonStart:b,polygonEnd:b},Wa={point:Gt,lineStart:Kt,lineEnd:Qt,polygonStart:function(){Wa.lineStart=ne},polygonEnd:function(){Wa.point=Gt,Wa.lineStart=Kt,Wa.lineEnd=Qt}};ao.geo.path=function(){function n(n){return n&&("function"==typeof a&&u.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=i(u)),ao.geo.stream(n,o)),u.result()}function t(){return o=null,n}var e,r,i,u,o,a=4.5;return n.area=function(n){return Oa=0,ao.geo.stream(n,i($a)),Oa},n.centroid=function(n){return Ca=za=La=qa=Ta=Ra=Da=Pa=Ua=0,ao.geo.stream(n,i(Wa)),Ua?[Da/Ua,Pa/Ua]:Ra?[qa/Ra,Ta/Ra]:La?[Ca/La,za/La]:[NaN,NaN]},n.bounds=function(n){return Va=Xa=-(Ya=Za=1/0),ao.geo.stream(n,i(Ba)),[[Ya,Za],[Va,Xa]]},n.projection=function(n){return arguments.length?(i=(e=n)?n.stream||re(n):m,t()):e},n.context=function(n){return arguments.length?(u=null==(r=n)?new Wt:new te(n),"function"!=typeof a&&u.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(u.pointRadius(+t),+t),n):a},n.projection(ao.geo.albersUsa()).context(null)},ao.geo.transform=function(n){return{stream:function(t){var e=new ie(t);for(var r in n)e[r]=n[r];return e}}},ie.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},ao.geo.projection=oe,ao.geo.projectionMutator=ae,(ao.geo.equirectangular=function(){return oe(ce)}).raw=ce.invert=ce,ao.geo.rotation=function(n){function t(t){return t=n(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t}return n=se(n[0]%360*Yo,n[1]*Yo,n.length>2?n[2]*Yo:0),t.invert=function(t){return t=n.invert(t[0]*Yo,t[1]*Yo),t[0]*=Zo,t[1]*=Zo,t},t},fe.invert=ce,ao.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=se(-n[0]*Yo,-n[1]*Yo,0).invert,i=[];return e(null,null,1,{point:function(n,e){i.push(n=t(n,e)),n[0]*=Zo,n[1]*=Zo}}),{type:"Polygon",coordinates:[i]}}var t,e,r=[0,0],i=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=ve((t=+r)*Yo,i*Yo),n):t},n.precision=function(r){return arguments.length?(e=ve(t*Yo,(i=+r)*Yo),n):i},n.angle(90)},ao.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Yo,i=n[1]*Yo,u=t[1]*Yo,o=Math.sin(r),a=Math.cos(r),l=Math.sin(i),c=Math.cos(i),f=Math.sin(u),s=Math.cos(u);return Math.atan2(Math.sqrt((e=s*o)*e+(e=c*f-l*s*a)*e),l*f+c*s*a)},ao.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ao.range(Math.ceil(u/d)*d,i,d).map(h).concat(ao.range(Math.ceil(c/y)*y,l,y).map(p)).concat(ao.range(Math.ceil(r/g)*g,e,g).filter(function(n){return xo(n%d)>Uo}).map(f)).concat(ao.range(Math.ceil(a/v)*v,o,v).filter(function(n){return xo(n%y)>Uo}).map(s))}var e,r,i,u,o,a,l,c,f,s,h,p,g=10,v=g,d=90,y=360,m=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(u).concat(p(l).slice(1),h(i).reverse().slice(1),p(c).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(u=+t[0][0],i=+t[1][0],c=+t[0][1],l=+t[1][1],u>i&&(t=u,u=i,i=t),c>l&&(t=c,c=l,l=t),n.precision(m)):[[u,c],[i,l]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(m)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],y=+t[1],n):[d,y]},n.minorStep=function(t){return arguments.length?(g=+t[0],v=+t[1],n):[g,v]},n.precision=function(t){return arguments.length?(m=+t,f=ye(a,o,90),s=me(r,e,m),h=ye(c,l,90),p=me(u,i,m),n):m},n.majorExtent([[-180,-90+Uo],[180,90-Uo]]).minorExtent([[-180,-80-Uo],[180,80+Uo]])},ao.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||i.apply(this,arguments)]}}var t,e,r=Me,i=xe;return n.distance=function(){return ao.geo.distance(t||r.apply(this,arguments),e||i.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(i=t,e="function"==typeof t?null:t,n):i},n.precision=function(){return arguments.length?n:0},n},ao.geo.interpolate=function(n,t){return be(n[0]*Yo,n[1]*Yo,t[0]*Yo,t[1]*Yo)},ao.geo.length=function(n){return Ja=0,ao.geo.stream(n,Ga),Ja};var Ja,Ga={sphere:b,point:b,lineStart:_e,lineEnd:b,polygonStart:b,polygonEnd:b},Ka=we(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ao.geo.azimuthalEqualArea=function(){return oe(Ka)}).raw=Ka;var Qa=we(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},m);(ao.geo.azimuthalEquidistant=function(){return oe(Qa)}).raw=Qa,(ao.geo.conicConformal=function(){return Vt(Se)}).raw=Se,(ao.geo.conicEquidistant=function(){return Vt(ke)}).raw=ke;var nl=we(function(n){return 1/n},Math.atan);(ao.geo.gnomonic=function(){return oe(nl)}).raw=nl,Ne.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Io]},(ao.geo.mercator=function(){return Ee(Ne)}).raw=Ne;var tl=we(function(){return 1},Math.asin);(ao.geo.orthographic=function(){return oe(tl)}).raw=tl;var el=we(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ao.geo.stereographic=function(){return oe(el)}).raw=el,Ae.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Io]},(ao.geo.transverseMercator=function(){var n=Ee(Ae),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=Ae,ao.geom={},ao.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,i=En(e),u=En(r),o=n.length,a=[],l=[];for(t=0;o>t;t++)a.push([+i.call(this,n[t],t),+u.call(this,n[t],t),t]);for(a.sort(qe),t=0;o>t;t++)l.push([a[t][0],-a[t][1]]);var c=Le(a),f=Le(l),s=f[0]===c[0],h=f[f.length-1]===c[c.length-1],p=[];for(t=c.length-1;t>=0;--t)p.push(n[a[c[t]][2]]);for(t=+s;t=r&&c.x<=u&&c.y>=i&&c.y<=o?[[r,o],[u,o],[u,i],[r,i]]:[];f.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(u(n,t)/Uo)*Uo,y:Math.round(o(n,t)/Uo)*Uo,i:t}})}var r=Ce,i=ze,u=r,o=i,a=sl;return n?t(n):(t.links=function(n){return ar(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return ar(e(n)).cells.forEach(function(e,r){for(var i,u,o=e.site,a=e.edges.sort(Ve),l=-1,c=a.length,f=a[c-1].edge,s=f.l===o?f.r:f.l;++l=c,h=r>=f,p=h<<1|s;n.leaf=!1,n=n.nodes[p]||(n.nodes[p]=hr()),s?i=c:a=c,h?o=f:l=f,u(n,t,e,r,i,o,a,l)}var f,s,h,p,g,v,d,y,m,M=En(a),x=En(l);if(null!=t)v=t,d=e,y=r,m=i;else if(y=m=-(v=d=1/0),s=[],h=[],g=n.length,o)for(p=0;g>p;++p)f=n[p],f.xy&&(y=f.x),f.y>m&&(m=f.y),s.push(f.x),h.push(f.y);else for(p=0;g>p;++p){var b=+M(f=n[p],p),_=+x(f,p);v>b&&(v=b),d>_&&(d=_),b>y&&(y=b),_>m&&(m=_),s.push(b),h.push(_)}var w=y-v,S=m-d;w>S?m=d+w:y=v+S;var k=hr();if(k.add=function(n){u(k,n,+M(n,++p),+x(n,p),v,d,y,m)},k.visit=function(n){pr(n,k,v,d,y,m)},k.find=function(n){return gr(k,n[0],n[1],v,d,y,m)},p=-1,null==t){for(;++p=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=vl.get(e)||gl,r=dl.get(r)||m,br(r(e.apply(null,lo.call(arguments,1))))},ao.interpolateHcl=Rr,ao.interpolateHsl=Dr,ao.interpolateLab=Pr,ao.interpolateRound=Ur,ao.transform=function(n){var t=fo.createElementNS(ao.ns.prefix.svg,"g");return(ao.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new jr(e?e.matrix:yl)})(n)},jr.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var yl={a:1,b:0,c:0,d:1,e:0,f:0};ao.interpolateTransform=$r,ao.layout={},ao.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/y){if(v>l){var c=t.charge/l;n.px-=u*c,n.py-=o*c}return!0}if(t.point&&l&&v>l){var c=t.pointCharge/l;n.px-=u*c,n.py-=o*c}}return!t.charge}}function t(n){n.px=ao.event.x,n.py=ao.event.y,l.resume()}var e,r,i,u,o,a,l={},c=ao.dispatch("start","tick","end"),f=[1,1],s=.9,h=ml,p=Ml,g=-30,v=xl,d=.1,y=.64,M=[],x=[];return l.tick=function(){if((i*=.99)<.005)return e=null,c.end({type:"end",alpha:i=0}),!0;var t,r,l,h,p,v,y,m,b,_=M.length,w=x.length;for(r=0;w>r;++r)l=x[r],h=l.source,p=l.target,m=p.x-h.x,b=p.y-h.y,(v=m*m+b*b)&&(v=i*o[r]*((v=Math.sqrt(v))-u[r])/v,m*=v,b*=v,p.x-=m*(y=h.weight+p.weight?h.weight/(h.weight+p.weight):.5),p.y-=b*y,h.x+=m*(y=1-y),h.y+=b*y);if((y=i*d)&&(m=f[0]/2,b=f[1]/2,r=-1,y))for(;++r<_;)l=M[r],l.x+=(m-l.x)*y,l.y+=(b-l.y)*y;if(g)for(ri(t=ao.geom.quadtree(M),i,a),r=-1;++r<_;)(l=M[r]).fixed||t.visit(n(l));for(r=-1;++r<_;)l=M[r],l.fixed?(l.x=l.px,l.y=l.py):(l.x-=(l.px-(l.px=l.x))*s,l.y-=(l.py-(l.py=l.y))*s);c.tick({type:"tick",alpha:i})},l.nodes=function(n){return arguments.length?(M=n,l):M},l.links=function(n){return arguments.length?(x=n,l):x},l.size=function(n){return arguments.length?(f=n,l):f},l.linkDistance=function(n){return arguments.length?(h="function"==typeof n?n:+n,l):h},l.distance=l.linkDistance,l.linkStrength=function(n){return arguments.length?(p="function"==typeof n?n:+n,l):p},l.friction=function(n){return arguments.length?(s=+n,l):s},l.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,l):g},l.chargeDistance=function(n){return arguments.length?(v=n*n,l):Math.sqrt(v)},l.gravity=function(n){return arguments.length?(d=+n,l):d},l.theta=function(n){return arguments.length?(y=n*n,l):Math.sqrt(y)},l.alpha=function(n){return arguments.length?(n=+n,i?n>0?i=n:(e.c=null,e.t=NaN,e=null,c.end({type:"end",alpha:i=0})):n>0&&(c.start({type:"start",alpha:i=n}),e=qn(l.tick)),l):i},l.start=function(){function n(n,r){if(!e){for(e=new Array(i),l=0;i>l;++l)e[l]=[];for(l=0;c>l;++l){var u=x[l];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var o,a=e[t],l=-1,f=a.length;++lt;++t)(r=M[t]).index=t,r.weight=0;for(t=0;c>t;++t)r=x[t],"number"==typeof r.source&&(r.source=M[r.source]),"number"==typeof r.target&&(r.target=M[r.target]),++r.source.weight,++r.target.weight;for(t=0;i>t;++t)r=M[t],isNaN(r.x)&&(r.x=n("x",s)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof h)for(t=0;c>t;++t)u[t]=+h.call(this,x[t],t);else for(t=0;c>t;++t)u[t]=h;if(o=[],"function"==typeof p)for(t=0;c>t;++t)o[t]=+p.call(this,x[t],t);else for(t=0;c>t;++t)o[t]=p;if(a=[],"function"==typeof g)for(t=0;i>t;++t)a[t]=+g.call(this,M[t],t);else for(t=0;i>t;++t)a[t]=g;return l.resume()},l.resume=function(){return l.alpha(.1)},l.stop=function(){return l.alpha(0)},l.drag=function(){return r||(r=ao.behavior.drag().origin(m).on("dragstart.force",Qr).on("drag.force",t).on("dragend.force",ni)),arguments.length?void this.on("mouseover.force",ti).on("mouseout.force",ei).call(r):r},ao.rebind(l,c,"on")};var ml=20,Ml=1,xl=1/0;ao.layout.hierarchy=function(){function n(i){var u,o=[i],a=[];for(i.depth=0;null!=(u=o.pop());)if(a.push(u),(c=e.call(n,u,u.depth))&&(l=c.length)){for(var l,c,f;--l>=0;)o.push(f=c[l]),f.parent=u,f.depth=u.depth+1;r&&(u.value=0),u.children=c}else r&&(u.value=+r.call(n,u,u.depth)||0),delete u.children;return oi(i,function(n){var e,i;t&&(e=n.children)&&e.sort(t),r&&(i=n.parent)&&(i.value+=n.value)}),a}var t=ci,e=ai,r=li;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&(ui(t,function(n){n.children&&(n.value=0)}),oi(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},ao.layout.partition=function(){function n(t,e,r,i){var u=t.children;if(t.x=e,t.y=t.depth*i,t.dx=r,t.dy=i,u&&(o=u.length)){var o,a,l,c=-1;for(r=t.value?r/t.value:0;++cs?-1:1),g=ao.sum(c),v=g?(s-l*p)/g:0,d=ao.range(l),y=[];return null!=e&&d.sort(e===bl?function(n,t){return c[t]-c[n]}:function(n,t){return e(o[n],o[t])}),d.forEach(function(n){y[n]={data:o[n],value:a=c[n],startAngle:f,endAngle:f+=a*v+p,padAngle:h}}),y}var t=Number,e=bl,r=0,i=Ho,u=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(i=t,n):i},n.padAngle=function(t){return arguments.length?(u=t,n):u},n};var bl={};ao.layout.stack=function(){function n(a,l){if(!(h=a.length))return a;var c=a.map(function(e,r){return t.call(n,e,r)}),f=c.map(function(t){return t.map(function(t,e){return[u.call(n,t,e),o.call(n,t,e)]})}),s=e.call(n,f,l);c=ao.permute(c,s),f=ao.permute(f,s);var h,p,g,v,d=r.call(n,f,l),y=c[0].length;for(g=0;y>g;++g)for(i.call(n,c[0][g],v=d[g],f[0][g][1]),p=1;h>p;++p)i.call(n,c[p][g],v+=f[p-1][g][1],f[p][g][1]);return a}var t=m,e=gi,r=vi,i=pi,u=si,o=hi;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:_l.get(t)||gi,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:wl.get(t)||vi,n):r},n.x=function(t){return arguments.length?(u=t,n):u},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(i=t,n):i},n};var _l=ao.map({"inside-out":function(n){var t,e,r=n.length,i=n.map(di),u=n.map(yi),o=ao.range(r).sort(function(n,t){return i[n]-i[t]}),a=0,l=0,c=[],f=[];for(t=0;r>t;++t)e=o[t],l>a?(a+=u[e],c.push(e)):(l+=u[e],f.push(e));return f.reverse().concat(c)},reverse:function(n){return ao.range(n.length).reverse()},"default":gi}),wl=ao.map({silhouette:function(n){var t,e,r,i=n.length,u=n[0].length,o=[],a=0,l=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;u>e;++e)l[e]=(a-o[e])/2;return l},wiggle:function(n){var t,e,r,i,u,o,a,l,c,f=n.length,s=n[0],h=s.length,p=[];for(p[0]=l=c=0,e=1;h>e;++e){for(t=0,i=0;f>t;++t)i+=n[t][e][1];for(t=0,u=0,a=s[e][0]-s[e-1][0];f>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;u+=o*n[t][e][1]}p[e]=l-=i?u/i*a:0,c>l&&(c=l)}for(e=0;h>e;++e)p[e]-=c;return p},expand:function(n){var t,e,r,i=n.length,u=n[0].length,o=1/i,a=[];for(e=0;u>e;++e){for(t=0,r=0;i>t;t++)r+=n[t][e][1];if(r)for(t=0;i>t;t++)n[t][e][1]/=r;else for(t=0;i>t;t++)n[t][e][1]=o}for(e=0;u>e;++e)a[e]=0;return a},zero:vi});ao.layout.histogram=function(){function n(n,u){for(var o,a,l=[],c=n.map(e,this),f=r.call(this,c,u),s=i.call(this,f,c,u),u=-1,h=c.length,p=s.length-1,g=t?1:1/h;++u0)for(u=-1;++u=f[0]&&a<=f[1]&&(o=l[ao.bisect(s,a,1,p)-1],o.y+=g,o.push(n[u]));return l}var t=!0,e=Number,r=bi,i=Mi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=En(t),n):r},n.bins=function(t){return arguments.length?(i="number"==typeof t?function(n){return xi(n,t)}:En(t),n):i},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ao.layout.pack=function(){function n(n,u){var o=e.call(this,n,u),a=o[0],l=i[0],c=i[1],f=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,oi(a,function(n){n.r=+f(n.value)}),oi(a,Ni),r){var s=r*(t?1:Math.max(2*a.r/l,2*a.r/c))/2;oi(a,function(n){n.r+=s}),oi(a,Ni),oi(a,function(n){n.r-=s})}return Ci(a,l/2,c/2,t?1:1/Math.max(2*a.r/l,2*a.r/c)),o}var t,e=ao.layout.hierarchy().sort(_i),r=0,i=[1,1];return n.size=function(t){return arguments.length?(i=t,n):i},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},ii(n,e)},ao.layout.tree=function(){function n(n,i){var f=o.call(this,n,i),s=f[0],h=t(s);if(oi(h,e),h.parent.m=-h.z,ui(h,r),c)ui(s,u);else{var p=s,g=s,v=s;ui(s,function(n){n.xg.x&&(g=n),n.depth>v.depth&&(v=n)});var d=a(p,g)/2-p.x,y=l[0]/(g.x+a(g,p)/2+d),m=l[1]/(v.depth||1);ui(s,function(n){n.x=(n.x+d)*y,n.y=n.depth*m})}return f}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var i,u=t.children,o=0,a=u.length;a>o;++o)r.push((u[o]=i={_:u[o],parent:t,children:(i=u[o].children)&&i.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=i);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){Di(n);var u=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-u):n.z=u}else r&&(n.z=r.z+a(n._,r._));n.parent.A=i(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function i(n,t,e){if(t){for(var r,i=n,u=n,o=t,l=i.parent.children[0],c=i.m,f=u.m,s=o.m,h=l.m;o=Ti(o),i=qi(i),o&&i;)l=qi(l),u=Ti(u),u.a=n,r=o.z+s-i.z-c+a(o._,i._),r>0&&(Ri(Pi(o,n,e),n,r),c+=r,f+=r),s+=o.m,c+=i.m,h+=l.m,f+=u.m;o&&!Ti(u)&&(u.t=o,u.m+=s-f),i&&!qi(l)&&(l.t=i,l.m+=c-h,e=n)}return e}function u(n){n.x*=l[0],n.y=n.depth*l[1]}var o=ao.layout.hierarchy().sort(null).value(null),a=Li,l=[1,1],c=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(c=null==(l=t)?u:null,n):c?null:l},n.nodeSize=function(t){return arguments.length?(c=null==(l=t)?null:u,n):c?l:null},ii(n,o)},ao.layout.cluster=function(){function n(n,u){var o,a=t.call(this,n,u),l=a[0],c=0;oi(l,function(n){var t=n.children;t&&t.length?(n.x=ji(t),n.y=Ui(t)):(n.x=o?c+=e(n,o):0,n.y=0,o=n)});var f=Fi(l),s=Hi(l),h=f.x-e(f,s)/2,p=s.x+e(s,f)/2;return oi(l,i?function(n){n.x=(n.x-l.x)*r[0],n.y=(l.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(p-h)*r[0],n.y=(1-(l.y?n.y/l.y:1))*r[1]}),a}var t=ao.layout.hierarchy().sort(null).value(null),e=Li,r=[1,1],i=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(i=null==(r=t),n):i?null:r},n.nodeSize=function(t){return arguments.length?(i=null!=(r=t),n):i?r:null},ii(n,t)},ao.layout.treemap=function(){function n(n,t){for(var e,r,i=-1,u=n.length;++it?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var u=e.children;if(u&&u.length){var o,a,l,c=s(e),f=[],h=u.slice(),g=1/0,v="slice"===p?c.dx:"dice"===p?c.dy:"slice-dice"===p?1&e.depth?c.dy:c.dx:Math.min(c.dx,c.dy);for(n(h,c.dx*c.dy/e.value),f.area=0;(l=h.length)>0;)f.push(o=h[l-1]),f.area+=o.area,"squarify"!==p||(a=r(f,v))<=g?(h.pop(),g=a):(f.area-=f.pop().area,i(f,v,c,!1),v=Math.min(c.dx,c.dy),f.length=f.area=0,g=1/0);f.length&&(i(f,v,c,!0),f.length=f.area=0),u.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var u,o=s(t),a=r.slice(),l=[];for(n(a,o.dx*o.dy/t.value),l.area=0;u=a.pop();)l.push(u),l.area+=u.area,null!=u.z&&(i(l,u.z?o.dx:o.dy,o,!a.length),l.length=l.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,i=0,u=1/0,o=-1,a=n.length;++oe&&(u=e),e>i&&(i=e));return r*=r,t*=t,r?Math.max(t*i*g/r,r/(t*u*g)):1/0}function i(n,t,e,r){var i,u=-1,o=n.length,a=e.x,c=e.y,f=t?l(n.area/t):0; +if(t==e.dx){for((r||f>e.dy)&&(f=e.dy);++ue.dx)&&(f=e.dx);++ue&&(t=1),1>e&&(n=0),function(){var e,r,i;do e=2*Math.random()-1,r=2*Math.random()-1,i=e*e+r*r;while(!i||i>1);return n+t*e*Math.sqrt(-2*Math.log(i)/i)}},logNormal:function(){var n=ao.random.normal.apply(ao,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ao.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},ao.scale={};var Sl={floor:m,ceil:m};ao.scale.linear=function(){return Wi([0,1],[0,1],Mr,!1)};var kl={s:1,g:1,p:1,r:1,e:1};ao.scale.log=function(){return ru(ao.scale.linear().domain([0,1]),10,!0,[1,10])};var Nl=ao.format(".0e"),El={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ao.scale.pow=function(){return iu(ao.scale.linear(),1,[0,1])},ao.scale.sqrt=function(){return ao.scale.pow().exponent(.5)},ao.scale.ordinal=function(){return ou([],{t:"range",a:[[]]})},ao.scale.category10=function(){return ao.scale.ordinal().range(Al)},ao.scale.category20=function(){return ao.scale.ordinal().range(Cl)},ao.scale.category20b=function(){return ao.scale.ordinal().range(zl)},ao.scale.category20c=function(){return ao.scale.ordinal().range(Ll)};var Al=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(xn),Cl=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(xn),zl=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(xn),Ll=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(xn);ao.scale.quantile=function(){return au([],[])},ao.scale.quantize=function(){return lu(0,1,[0,1])},ao.scale.threshold=function(){return cu([.5],[0,1])},ao.scale.identity=function(){return fu([0,1])},ao.svg={},ao.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),c=Math.max(0,+r.apply(this,arguments)),f=o.apply(this,arguments)-Io,s=a.apply(this,arguments)-Io,h=Math.abs(s-f),p=f>s?0:1;if(n>c&&(g=c,c=n,n=g),h>=Oo)return t(c,p)+(n?t(n,1-p):"")+"Z";var g,v,d,y,m,M,x,b,_,w,S,k,N=0,E=0,A=[];if((y=(+l.apply(this,arguments)||0)/2)&&(d=u===ql?Math.sqrt(n*n+c*c):+u.apply(this,arguments),p||(E*=-1),c&&(E=tn(d/c*Math.sin(y))),n&&(N=tn(d/n*Math.sin(y)))),c){m=c*Math.cos(f+E),M=c*Math.sin(f+E),x=c*Math.cos(s-E),b=c*Math.sin(s-E);var C=Math.abs(s-f-2*E)<=Fo?0:1;if(E&&yu(m,M,x,b)===p^C){var z=(f+s)/2;m=c*Math.cos(z),M=c*Math.sin(z),x=b=null}}else m=M=0;if(n){_=n*Math.cos(s-N),w=n*Math.sin(s-N),S=n*Math.cos(f+N),k=n*Math.sin(f+N);var L=Math.abs(f-s+2*N)<=Fo?0:1;if(N&&yu(_,w,S,k)===1-p^L){var q=(f+s)/2;_=n*Math.cos(q),w=n*Math.sin(q),S=k=null}}else _=w=0;if(h>Uo&&(g=Math.min(Math.abs(c-n)/2,+i.apply(this,arguments)))>.001){v=c>n^p?0:1;var T=g,R=g;if(Fo>h){var D=null==S?[_,w]:null==x?[m,M]:Re([m,M],[S,k],[x,b],[_,w]),P=m-D[0],U=M-D[1],j=x-D[0],F=b-D[1],H=1/Math.sin(Math.acos((P*j+U*F)/(Math.sqrt(P*P+U*U)*Math.sqrt(j*j+F*F)))/2),O=Math.sqrt(D[0]*D[0]+D[1]*D[1]);R=Math.min(g,(n-O)/(H-1)),T=Math.min(g,(c-O)/(H+1))}if(null!=x){var I=mu(null==S?[_,w]:[S,k],[m,M],c,T,p),Y=mu([x,b],[_,w],c,T,p);g===T?A.push("M",I[0],"A",T,",",T," 0 0,",v," ",I[1],"A",c,",",c," 0 ",1-p^yu(I[1][0],I[1][1],Y[1][0],Y[1][1]),",",p," ",Y[1],"A",T,",",T," 0 0,",v," ",Y[0]):A.push("M",I[0],"A",T,",",T," 0 1,",v," ",Y[0])}else A.push("M",m,",",M);if(null!=S){var Z=mu([m,M],[S,k],n,-R,p),V=mu([_,w],null==x?[m,M]:[x,b],n,-R,p);g===R?A.push("L",V[0],"A",R,",",R," 0 0,",v," ",V[1],"A",n,",",n," 0 ",p^yu(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-p," ",Z[1],"A",R,",",R," 0 0,",v," ",Z[0]):A.push("L",V[0],"A",R,",",R," 0 0,",v," ",Z[0])}else A.push("L",_,",",w)}else A.push("M",m,",",M),null!=x&&A.push("A",c,",",c," 0 ",C,",",p," ",x,",",b),A.push("L",_,",",w),null!=S&&A.push("A",n,",",n," 0 ",L,",",1-p," ",S,",",k);return A.push("Z"),A.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=hu,r=pu,i=su,u=ql,o=gu,a=vu,l=du;return n.innerRadius=function(t){return arguments.length?(e=En(t),n):e},n.outerRadius=function(t){return arguments.length?(r=En(t),n):r},n.cornerRadius=function(t){return arguments.length?(i=En(t),n):i},n.padRadius=function(t){return arguments.length?(u=t==ql?ql:En(t),n):u},n.startAngle=function(t){return arguments.length?(o=En(t),n):o},n.endAngle=function(t){return arguments.length?(a=En(t),n):a},n.padAngle=function(t){return arguments.length?(l=En(t),n):l},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-Io;return[Math.cos(t)*n,Math.sin(t)*n]},n};var ql="auto";ao.svg.line=function(){return Mu(m)};var Tl=ao.map({linear:xu,"linear-closed":bu,step:_u,"step-before":wu,"step-after":Su,basis:zu,"basis-open":Lu,"basis-closed":qu,bundle:Tu,cardinal:Eu,"cardinal-open":ku,"cardinal-closed":Nu,monotone:Fu});Tl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Rl=[0,2/3,1/3,0],Dl=[0,1/3,2/3,0],Pl=[0,1/6,2/3,1/6];ao.svg.line.radial=function(){var n=Mu(Hu);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},wu.reverse=Su,Su.reverse=wu,ao.svg.area=function(){return Ou(m)},ao.svg.area.radial=function(){var n=Ou(Hu);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},ao.svg.chord=function(){function n(n,a){var l=t(this,u,n,a),c=t(this,o,n,a);return"M"+l.p0+r(l.r,l.p1,l.a1-l.a0)+(e(l,c)?i(l.r,l.p1,l.r,l.p0):i(l.r,l.p1,c.r,c.p0)+r(c.r,c.p1,c.a1-c.a0)+i(c.r,c.p1,l.r,l.p0))+"Z"}function t(n,t,e,r){var i=t.call(n,e,r),u=a.call(n,i,r),o=l.call(n,i,r)-Io,f=c.call(n,i,r)-Io;return{r:u,a0:o,a1:f,p0:[u*Math.cos(o),u*Math.sin(o)],p1:[u*Math.cos(f),u*Math.sin(f)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Fo)+",1 "+t}function i(n,t,e,r){return"Q 0,0 "+r}var u=Me,o=xe,a=Iu,l=gu,c=vu;return n.radius=function(t){return arguments.length?(a=En(t),n):a},n.source=function(t){return arguments.length?(u=En(t),n):u},n.target=function(t){return arguments.length?(o=En(t),n):o},n.startAngle=function(t){return arguments.length?(l=En(t),n):l},n.endAngle=function(t){return arguments.length?(c=En(t),n):c},n},ao.svg.diagonal=function(){function n(n,i){var u=t.call(this,n,i),o=e.call(this,n,i),a=(u.y+o.y)/2,l=[u,{x:u.x,y:a},{x:o.x,y:a},o];return l=l.map(r),"M"+l[0]+"C"+l[1]+" "+l[2]+" "+l[3]}var t=Me,e=xe,r=Yu;return n.source=function(e){return arguments.length?(t=En(e),n):t},n.target=function(t){return arguments.length?(e=En(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ao.svg.diagonal.radial=function(){var n=ao.svg.diagonal(),t=Yu,e=n.projection;return n.projection=function(n){return arguments.length?e(Zu(t=n)):t},n},ao.svg.symbol=function(){function n(n,r){return(Ul.get(t.call(this,n,r))||$u)(e.call(this,n,r))}var t=Xu,e=Vu;return n.type=function(e){return arguments.length?(t=En(e),n):t},n.size=function(t){return arguments.length?(e=En(t),n):e},n};var Ul=ao.map({circle:$u,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Fl)),e=t*Fl;return"M0,"+-t+"L"+e+",0 0,"+t+" "+-e+",0Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/jl),e=t*jl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ao.svg.symbolTypes=Ul.keys();var jl=Math.sqrt(3),Fl=Math.tan(30*Yo);Co.transition=function(n){for(var t,e,r=Hl||++Zl,i=Ku(n),u=[],o=Ol||{time:Date.now(),ease:Nr,delay:0,duration:250},a=-1,l=this.length;++au;u++){i.push(t=[]);for(var e=this[u],a=0,l=e.length;l>a;a++)(r=e[a])&&n.call(r,r.__data__,a,u)&&t.push(r)}return Wu(i,this.namespace,this.id)},Yl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):Y(this,null==t?function(t){t[r][e].tween.remove(n)}:function(i){i[r][e].tween.set(n,t)})},Yl.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function i(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function u(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?$r:Mr,a=ao.ns.qualify(n);return Ju(this,"attr."+n,t,a.local?u:i)},Yl.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(i));return r&&function(n){this.setAttribute(i,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(i.space,i.local));return r&&function(n){this.setAttributeNS(i.space,i.local,r(n))}}var i=ao.ns.qualify(n);return this.tween("attr."+n,i.local?r:e)},Yl.style=function(n,e,r){function i(){this.style.removeProperty(n)}function u(e){return null==e?i:(e+="",function(){var i,u=t(this).getComputedStyle(this,null).getPropertyValue(n);return u!==e&&(i=Mr(u,e),function(t){this.style.setProperty(n,i(t),r)})})}var o=arguments.length;if(3>o){if("string"!=typeof n){2>o&&(e="");for(r in n)this.style(r,n[r],e);return this}r=""}return Ju(this,"style."+n,e,u)},Yl.styleTween=function(n,e,r){function i(i,u){var o=e.call(this,i,u,t(this).getComputedStyle(this,null).getPropertyValue(n));return o&&function(t){this.style.setProperty(n,o(t),r)}}return arguments.length<3&&(r=""),this.tween("style."+n,i)},Yl.text=function(n){return Ju(this,"text",n,Gu)},Yl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Yl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ao.ease.apply(ao,arguments)),Y(this,function(r){r[e][t].ease=n}))},Yl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:Y(this,"function"==typeof n?function(r,i,u){r[e][t].delay=+n.call(r,r.__data__,i,u)}:(n=+n,function(r){r[e][t].delay=n}))},Yl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:Y(this,"function"==typeof n?function(r,i,u){r[e][t].duration=Math.max(1,n.call(r,r.__data__,i,u))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Yl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var i=Ol,u=Hl;try{Hl=e,Y(this,function(t,i,u){Ol=t[r][e],n.call(t,t.__data__,i,u)})}finally{Ol=i,Hl=u}}else Y(this,function(i){var u=i[r][e];(u.event||(u.event=ao.dispatch("start","end","interrupt"))).on(n,t)});return this},Yl.transition=function(){for(var n,t,e,r,i=this.id,u=++Zl,o=this.namespace,a=[],l=0,c=this.length;c>l;l++){a.push(n=[]);for(var t=this[l],f=0,s=t.length;s>f;f++)(e=t[f])&&(r=e[o][i],Qu(e,f,o,u,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Wu(a,o,u)},ao.svg.axis=function(){function n(n){n.each(function(){var n,c=ao.select(this),f=this.__chart__||e,s=this.__chart__=e.copy(),h=null==l?s.ticks?s.ticks.apply(s,a):s.domain():l,p=null==t?s.tickFormat?s.tickFormat.apply(s,a):m:t,g=c.selectAll(".tick").data(h,s),v=g.enter().insert("g",".domain").attr("class","tick").style("opacity",Uo),d=ao.transition(g.exit()).style("opacity",Uo).remove(),y=ao.transition(g.order()).style("opacity",1),M=Math.max(i,0)+o,x=Zi(s),b=c.selectAll(".domain").data([0]),_=(b.enter().append("path").attr("class","domain"),ao.transition(b));v.append("line"),v.append("text");var w,S,k,N,E=v.select("line"),A=y.select("line"),C=g.select("text").text(p),z=v.select("text"),L=y.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=no,w="x",k="y",S="x2",N="y2",C.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),_.attr("d","M"+x[0]+","+q*u+"V0H"+x[1]+"V"+q*u)):(n=to,w="y",k="x",S="y2",N="x2",C.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),_.attr("d","M"+q*u+","+x[0]+"H0V"+x[1]+"H"+q*u)),E.attr(N,q*i),z.attr(k,q*M),A.attr(S,0).attr(N,q*i),L.attr(w,0).attr(k,q*M),s.rangeBand){var T=s,R=T.rangeBand()/2;f=s=function(n){return T(n)+R}}else f.rangeBand?f=s:d.call(n,s,f);v.call(n,f,s),y.call(n,s,s)})}var t,e=ao.scale.linear(),r=Vl,i=6,u=6,o=3,a=[10],l=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Xl?t+"":Vl,n):r},n.ticks=function(){return arguments.length?(a=co(arguments),n):a},n.tickValues=function(t){return arguments.length?(l=t,n):l},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(i=+t,u=+arguments[e-1],n):i},n.innerTickSize=function(t){return arguments.length?(i=+t,n):i},n.outerTickSize=function(t){return arguments.length?(u=+t,n):u},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Vl="bottom",Xl={top:1,right:1,bottom:1,left:1};ao.svg.brush=function(){function n(t){t.each(function(){var t=ao.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=t.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),t.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=t.selectAll(".resize").data(v,m);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return $l[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,s=ao.transition(t),h=ao.transition(o);c&&(l=Zi(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),r(s)),f&&(l=Zi(f),h.attr("y",l[0]).attr("height",l[1]-l[0]),i(s)),e(s)})}function e(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+h[+/^s/.test(n)]+")"})}function r(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[0])}function i(n){n.select(".extent").attr("y",h[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",h[1]-h[0])}function u(){function u(){32==ao.event.keyCode&&(C||(M=null,L[0]-=s[1],L[1]-=h[1],C=2),S())}function v(){32==ao.event.keyCode&&2==C&&(L[0]+=s[1],L[1]+=h[1],C=0,S())}function d(){var n=ao.mouse(b),t=!1;x&&(n[0]+=x[0],n[1]+=x[1]),C||(ao.event.altKey?(M||(M=[(s[0]+s[1])/2,(h[0]+h[1])/2]),L[0]=s[+(n[0]f?(i=r,r=f):i=f),v[0]!=r||v[1]!=i?(e?a=null:o=null,v[0]=r,v[1]=i,!0):void 0}function m(){d(),k.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),ao.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),z(),w({type:"brushend"})}var M,x,b=this,_=ao.select(ao.event.target),w=l.of(b,arguments),k=ao.select(b),N=_.datum(),E=!/^(n|s)$/.test(N)&&c,A=!/^(e|w)$/.test(N)&&f,C=_.classed("extent"),z=W(b),L=ao.mouse(b),q=ao.select(t(b)).on("keydown.brush",u).on("keyup.brush",v);if(ao.event.changedTouches?q.on("touchmove.brush",d).on("touchend.brush",m):q.on("mousemove.brush",d).on("mouseup.brush",m),k.interrupt().selectAll("*").interrupt(),C)L[0]=s[0]-L[0],L[1]=h[0]-L[1];else if(N){var T=+/w$/.test(N),R=+/^n/.test(N);x=[s[1-T]-L[0],h[1-R]-L[1]],L[0]=s[T],L[1]=h[R]}else ao.event.altKey&&(M=L.slice());k.style("pointer-events","none").selectAll(".resize").style("display",null),ao.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),d()}var o,a,l=N(n,"brushstart","brush","brushend"),c=null,f=null,s=[0,0],h=[0,0],p=!0,g=!0,v=Bl[0];return n.event=function(n){n.each(function(){var n=l.of(this,arguments),t={x:s,y:h,i:o,j:a},e=this.__chart__||t;this.__chart__=t,Hl?ao.select(this).transition().each("start.brush",function(){o=e.i,a=e.j,s=e.x,h=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=xr(s,t.x),r=xr(h,t.y);return o=a=null,function(i){s=t.x=e(i),h=t.y=r(i),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){o=t.i,a=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,v=Bl[!c<<1|!f],n):c},n.y=function(t){return arguments.length?(f=t,v=Bl[!c<<1|!f],n):f},n.clamp=function(t){return arguments.length?(c&&f?(p=!!t[0],g=!!t[1]):c?p=!!t:f&&(g=!!t),n):c&&f?[p,g]:c?p:f?g:null},n.extent=function(t){var e,r,i,u,l;return arguments.length?(c&&(e=t[0],r=t[1],f&&(e=e[0],r=r[0]),o=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(l=e,e=r,r=l),e==s[0]&&r==s[1]||(s=[e,r])),f&&(i=t[0],u=t[1],c&&(i=i[1],u=u[1]),a=[i,u],f.invert&&(i=f(i),u=f(u)),i>u&&(l=i,i=u,u=l),i==h[0]&&u==h[1]||(h=[i,u])),n):(c&&(o?(e=o[0],r=o[1]):(e=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(l=e,e=r,r=l))),f&&(a?(i=a[0],u=a[1]):(i=h[0],u=h[1],f.invert&&(i=f.invert(i),u=f.invert(u)),i>u&&(l=i,i=u,u=l))),c&&f?[[e,i],[r,u]]:c?[e,r]:f&&[i,u])},n.clear=function(){return n.empty()||(s=[0,0],h=[0,0],o=a=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!f&&h[0]==h[1]},ao.rebind(n,l,"on")};var $l={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Bl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Wl=ga.format=xa.timeFormat,Jl=Wl.utc,Gl=Jl("%Y-%m-%dT%H:%M:%S.%LZ");Wl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?eo:Gl,eo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},eo.toString=Gl.toString,ga.second=On(function(n){return new va(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),ga.seconds=ga.second.range,ga.seconds.utc=ga.second.utc.range,ga.minute=On(function(n){return new va(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),ga.minutes=ga.minute.range,ga.minutes.utc=ga.minute.utc.range,ga.hour=On(function(n){var t=n.getTimezoneOffset()/60;return new va(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),ga.hours=ga.hour.range,ga.hours.utc=ga.hour.utc.range,ga.month=On(function(n){return n=ga.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),ga.months=ga.month.range,ga.months.utc=ga.month.utc.range;var Kl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Ql=[[ga.second,1],[ga.second,5],[ga.second,15],[ga.second,30],[ga.minute,1],[ga.minute,5],[ga.minute,15],[ga.minute,30],[ga.hour,1],[ga.hour,3],[ga.hour,6],[ga.hour,12],[ga.day,1],[ga.day,2],[ga.week,1],[ga.month,1],[ga.month,3],[ga.year,1]],nc=Wl.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",zt]]),tc={range:function(n,t,e){return ao.range(Math.ceil(n/e)*e,+t,e).map(io)},floor:m,ceil:m};Ql.year=ga.year,ga.scale=function(){return ro(ao.scale.linear(),Ql,nc)};var ec=Ql.map(function(n){return[n[0].utc,n[1]]}),rc=Jl.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",zt]]);ec.year=ga.year.utc,ga.scale.utc=function(){return ro(ao.scale.linear(),ec,rc)},ao.text=An(function(n){return n.responseText}),ao.json=function(n,t){return Cn(n,"application/json",uo,t)},ao.html=function(n,t){return Cn(n,"text/html",oo,t)},ao.xml=An(function(n){return n.responseXML}),"function"==typeof define&&define.amd?(this.d3=ao,define(ao)):"object"==typeof module&&module.exports?module.exports=ao:this.d3=ao}(); \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js new file mode 100644 index 0000000..29cacd4 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/file.js @@ -0,0 +1,62 @@ + $(function() { + var $window = $(window) + , $top_link = $('#toplink') + , $body = $('body, html') + , offset = $('#code').offset().top + , hidePopover = function ($target) { + $target.data('popover-hover', false); + + setTimeout(function () { + if (!$target.data('popover-hover')) { + $target.popover('hide'); + } + }, 300); + }; + + $top_link.hide().click(function(event) { + event.preventDefault(); + $body.animate({scrollTop:0}, 800); + }); + + $window.scroll(function() { + if($window.scrollTop() > offset) { + $top_link.fadeIn(); + } else { + $top_link.fadeOut(); + } + }).scroll(); + + $('.popin') + .popover({trigger: 'manual'}) + .on({ + 'mouseenter.popover': function () { + var $target = $(this); + var $container = $target.children().first(); + + $target.data('popover-hover', true); + + // popover already displayed + if ($target.next('.popover').length) { + return; + } + + // show the popover + $container.popover('show'); + + // register mouse events on the popover + $target.next('.popover:not(.popover-initialized)') + .on({ + 'mouseenter': function () { + $target.data('popover-hover', true); + }, + 'mouseleave': function () { + hidePopover($container); + } + }) + .addClass('popover-initialized'); + }, + 'mouseleave.popover': function () { + hidePopover($(this).children().first()); + } + }); + }); diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js new file mode 100644 index 0000000..a1c07fd --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/jquery.min.js @@ -0,0 +1,2 @@ +/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ +!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0f&&(e=a.render.queue[f]);f++)d=e.generate(),typeof e.callback==typeof Function&&e.callback(d);a.render.queue.splice(0,f),a.render.queue.length?setTimeout(c):(a.dispatch.render_end(),a.render.active=!1)};setTimeout(c)},a.render.active=!1,a.render.queue=[],a.addGraph=function(b){typeof arguments[0]==typeof Function&&(b={generate:arguments[0],callback:arguments[1]}),a.render.queue.push(b),a.render.active||a.render()},"undefined"!=typeof module&&"undefined"!=typeof exports&&(module.exports=a),"undefined"!=typeof window&&(window.nv=a),a.dom.write=function(a){return void 0!==window.fastdom?fastdom.write(a):a()},a.dom.read=function(a){return void 0!==window.fastdom?fastdom.read(a):a()},a.interactiveGuideline=function(){"use strict";function b(l){l.each(function(l){function m(){var a=d3.mouse(this),d=a[0],e=a[1],i=!0,j=!1;if(k&&(d=d3.event.offsetX,e=d3.event.offsetY,"svg"!==d3.event.target.tagName&&(i=!1),d3.event.target.className.baseVal.match("nv-legend")&&(j=!0)),i&&(d-=f.left,e-=f.top),0>d||0>e||d>o||e>p||d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement||j){if(k&&d3.event.relatedTarget&&void 0===d3.event.relatedTarget.ownerSVGElement&&(void 0===d3.event.relatedTarget.className||d3.event.relatedTarget.className.match(c.nvPointerEventsClass)))return;return h.elementMouseout({mouseX:d,mouseY:e}),b.renderGuideLine(null),void c.hidden(!0)}c.hidden(!1);var l=g.invert(d);h.elementMousemove({mouseX:d,mouseY:e,pointXValue:l}),"dblclick"===d3.event.type&&h.elementDblclick({mouseX:d,mouseY:e,pointXValue:l}),"click"===d3.event.type&&h.elementClick({mouseX:d,mouseY:e,pointXValue:l})}var n=d3.select(this),o=d||960,p=e||400,q=n.selectAll("g.nv-wrap.nv-interactiveLineLayer").data([l]),r=q.enter().append("g").attr("class"," nv-wrap nv-interactiveLineLayer");r.append("g").attr("class","nv-interactiveGuideLine"),j&&(j.on("touchmove",m).on("mousemove",m,!0).on("mouseout",m,!0).on("dblclick",m).on("click",m),b.guideLine=null,b.renderGuideLine=function(c){i&&(b.guideLine&&b.guideLine.attr("x1")===c||a.dom.write(function(){var b=q.select(".nv-interactiveGuideLine").selectAll("line").data(null!=c?[a.utils.NaNtoZero(c)]:[],String);b.enter().append("line").attr("class","nv-guideline").attr("x1",function(a){return a}).attr("x2",function(a){return a}).attr("y1",p).attr("y2",0),b.exit().remove()}))})})}var c=a.models.tooltip();c.duration(0).hideDelay(0)._isInteractiveLayer(!0).hidden(!1);var d=null,e=null,f={left:0,top:0},g=d3.scale.linear(),h=d3.dispatch("elementMousemove","elementMouseout","elementClick","elementDblclick"),i=!0,j=null,k="ActiveXObject"in window;return b.dispatch=h,b.tooltip=c,b.margin=function(a){return arguments.length?(f.top="undefined"!=typeof a.top?a.top:f.top,f.left="undefined"!=typeof a.left?a.left:f.left,b):f},b.width=function(a){return arguments.length?(d=a,b):d},b.height=function(a){return arguments.length?(e=a,b):e},b.xScale=function(a){return arguments.length?(g=a,b):g},b.showGuideLine=function(a){return arguments.length?(i=a,b):i},b.svgContainer=function(a){return arguments.length?(j=a,b):j},b},a.interactiveBisect=function(a,b,c){"use strict";if(!(a instanceof Array))return null;var d;d="function"!=typeof c?function(a){return a.x}:c;var e=function(a,b){return d(a)-b},f=d3.bisector(e).left,g=d3.max([0,f(a,b)-1]),h=d(a[g]);if("undefined"==typeof h&&(h=g),h===b)return g;var i=d3.min([g+1,a.length-1]),j=d(a[i]);return"undefined"==typeof j&&(j=i),Math.abs(j-b)>=Math.abs(h-b)?g:i},a.nearestValueIndex=function(a,b,c){"use strict";var d=1/0,e=null;return a.forEach(function(a,f){var g=Math.abs(b-a);null!=a&&d>=g&&c>g&&(d=g,e=f)}),e},function(){"use strict";a.models.tooltip=function(){function b(){if(k){var a=d3.select(k);"svg"!==a.node().tagName&&(a=a.select("svg"));var b=a.node()?a.attr("viewBox"):null;if(b){b=b.split(" ");var c=parseInt(a.style("width"),10)/b[2];p.left=p.left*c,p.top=p.top*c}}}function c(){if(!n){var a;a=k?k:document.body,n=d3.select(a).append("div").attr("class","nvtooltip "+(j?j:"xy-tooltip")).attr("id",v),n.style("top",0).style("left",0),n.style("opacity",0),n.selectAll("div, table, td, tr").classed(w,!0),n.classed(w,!0),o=n.node()}}function d(){if(r&&B(e)){b();var f=p.left,g=null!==i?i:p.top;return a.dom.write(function(){c();var b=A(e);b&&(o.innerHTML=b),k&&u?a.dom.read(function(){var a=k.getElementsByTagName("svg")[0],b={left:0,top:0};if(a){var c=a.getBoundingClientRect(),d=k.getBoundingClientRect(),e=c.top;if(0>e){var i=k.getBoundingClientRect();e=Math.abs(e)>i.height?0:e}b.top=Math.abs(e-d.top),b.left=Math.abs(c.left-d.left)}f+=k.offsetLeft+b.left-2*k.scrollLeft,g+=k.offsetTop+b.top-2*k.scrollTop,h&&h>0&&(g=Math.floor(g/h)*h),C([f,g])}):C([f,g])}),d}}var e=null,f="w",g=25,h=0,i=null,j=null,k=null,l=!0,m=400,n=null,o=null,p={left:null,top:null},q={left:0,top:0},r=!0,s=100,t=!0,u=!1,v="nvtooltip-"+Math.floor(1e5*Math.random()),w="nv-pointer-events-none",x=function(a){return a},y=function(a){return a},z=function(a){return a},A=function(a){if(null===a)return"";var b=d3.select(document.createElement("table"));if(t){var c=b.selectAll("thead").data([a]).enter().append("thead");c.append("tr").append("td").attr("colspan",3).append("strong").classed("x-value",!0).html(y(a.value))}var d=b.selectAll("tbody").data([a]).enter().append("tbody"),e=d.selectAll("tr").data(function(a){return a.series}).enter().append("tr").classed("highlight",function(a){return a.highlight});e.append("td").classed("legend-color-guide",!0).append("div").style("background-color",function(a){return a.color}),e.append("td").classed("key",!0).html(function(a,b){return z(a.key,b)}),e.append("td").classed("value",!0).html(function(a,b){return x(a.value,b)}),e.selectAll("td").each(function(a){if(a.highlight){var b=d3.scale.linear().domain([0,1]).range(["#fff",a.color]),c=.6;d3.select(this).style("border-bottom-color",b(c)).style("border-top-color",b(c))}});var f=b.node().outerHTML;return void 0!==a.footer&&(f+=""),f},B=function(a){if(a&&a.series){if(a.series instanceof Array)return!!a.series.length;if(a.series instanceof Object)return a.series=[a.series],!0}return!1},C=function(b){o&&a.dom.read(function(){var c,d,e=parseInt(o.offsetHeight,10),h=parseInt(o.offsetWidth,10),i=a.utils.windowSize().width,j=a.utils.windowSize().height,k=window.pageYOffset,p=window.pageXOffset;j=window.innerWidth>=document.body.scrollWidth?j:j-16,i=window.innerHeight>=document.body.scrollHeight?i:i-16;var r,t,u=function(a){var b=d;do isNaN(a.offsetTop)||(b+=a.offsetTop),a=a.offsetParent;while(a);return b},v=function(a){var b=c;do isNaN(a.offsetLeft)||(b+=a.offsetLeft),a=a.offsetParent;while(a);return b};switch(f){case"e":c=b[0]-h-g,d=b[1]-e/2,r=v(o),t=u(o),p>r&&(c=b[0]+g>p?b[0]+g:p-r+c),k>t&&(d=k-t+d),t+e>k+j&&(d=k+j-t+d-e);break;case"w":c=b[0]+g,d=b[1]-e/2,r=v(o),t=u(o),r+h>i&&(c=b[0]-h-g),k>t&&(d=k+5),t+e>k+j&&(d=k+j-t+d-e);break;case"n":c=b[0]-h/2-5,d=b[1]+g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),t+e>k+j&&(d=k+j-t+d-e);break;case"s":c=b[0]-h/2,d=b[1]-e-g,r=v(o),t=u(o),p>r&&(c=p+5),r+h>i&&(c=c-h/2+5),k>t&&(d=k);break;case"none":c=b[0],d=b[1]-g,r=v(o),t=u(o)}c-=q.left,d-=q.top;var w=o.getBoundingClientRect(),k=window.pageYOffset||document.documentElement.scrollTop,p=window.pageXOffset||document.documentElement.scrollLeft,x="translate("+(w.left+p)+"px, "+(w.top+k)+"px)",y="translate("+c+"px, "+d+"px)",z=d3.interpolateString(x,y),A=n.style("opacity")<.1;l?n.transition().delay(m).duration(0).style("opacity",0):n.interrupt().transition().duration(A?0:s).styleTween("transform",function(){return z},"important").style("-webkit-transform",y).style("opacity",1)})};return d.nvPointerEventsClass=w,d.options=a.utils.optionsFunc.bind(d),d._options=Object.create({},{duration:{get:function(){return s},set:function(a){s=a}},gravity:{get:function(){return f},set:function(a){f=a}},distance:{get:function(){return g},set:function(a){g=a}},snapDistance:{get:function(){return h},set:function(a){h=a}},classes:{get:function(){return j},set:function(a){j=a}},chartContainer:{get:function(){return k},set:function(a){k=a}},fixedTop:{get:function(){return i},set:function(a){i=a}},enabled:{get:function(){return r},set:function(a){r=a}},hideDelay:{get:function(){return m},set:function(a){m=a}},contentGenerator:{get:function(){return A},set:function(a){A=a}},valueFormatter:{get:function(){return x},set:function(a){x=a}},headerFormatter:{get:function(){return y},set:function(a){y=a}},keyFormatter:{get:function(){return z},set:function(a){z=a}},headerEnabled:{get:function(){return t},set:function(a){t=a}},_isInteractiveLayer:{get:function(){return u},set:function(a){u=!!a}},position:{get:function(){return p},set:function(a){p.left=void 0!==a.left?a.left:p.left,p.top=void 0!==a.top?a.top:p.top}},offset:{get:function(){return q},set:function(a){q.left=void 0!==a.left?a.left:q.left,q.top=void 0!==a.top?a.top:q.top}},hidden:{get:function(){return l},set:function(a){l!=a&&(l=!!a,d())}},data:{get:function(){return e},set:function(a){a.point&&(a.value=a.point.x,a.series=a.series||{},a.series.value=a.point.y,a.series.color=a.point.color||a.series.color),e=a}},tooltipElem:{get:function(){return o},set:function(){}},id:{get:function(){return v},set:function(){}}}),a.utils.initOptions(d),d}}(),a.utils.windowSize=function(){var a={width:640,height:480};return window.innerWidth&&window.innerHeight?(a.width=window.innerWidth,a.height=window.innerHeight,a):"CSS1Compat"==document.compatMode&&document.documentElement&&document.documentElement.offsetWidth?(a.width=document.documentElement.offsetWidth,a.height=document.documentElement.offsetHeight,a):document.body&&document.body.offsetWidth?(a.width=document.body.offsetWidth,a.height=document.body.offsetHeight,a):a},a.utils.windowResize=function(b){return window.addEventListener?window.addEventListener("resize",b):a.log("ERROR: Failed to bind to window.resize with: ",b),{callback:b,clear:function(){window.removeEventListener("resize",b)}}},a.utils.getColor=function(b){if(void 0===b)return a.utils.defaultColor();if(Array.isArray(b)){var c=d3.scale.ordinal().range(b);return function(a,b){var d=void 0===b?a:b;return a.color||c(d)}}return b},a.utils.defaultColor=function(){return a.utils.getColor(d3.scale.category20().range())},a.utils.customTheme=function(a,b,c){b=b||function(a){return a.key},c=c||d3.scale.category20().range();var d=c.length;return function(e){var f=b(e);return"function"==typeof a[f]?a[f]():void 0!==a[f]?a[f]:(d||(d=c.length),d-=1,c[d])}},a.utils.pjax=function(b,c){var d=function(d){d3.html(d,function(d){var e=d3.select(c).node();e.parentNode.replaceChild(d3.select(d).select(c).node(),e),a.utils.pjax(b,c)})};d3.selectAll(b).on("click",function(){history.pushState(this.href,this.textContent,this.href),d(this.href),d3.event.preventDefault()}),d3.select(window).on("popstate",function(){d3.event.state&&d(d3.event.state)})},a.utils.calcApproxTextWidth=function(a){if("function"==typeof a.style&&"function"==typeof a.text){var b=parseInt(a.style("font-size").replace("px",""),10),c=a.text().length;return c*b*.5}return 0},a.utils.NaNtoZero=function(a){return"number"!=typeof a||isNaN(a)||null===a||1/0===a||a===-1/0?0:a},d3.selection.prototype.watchTransition=function(a){var b=[this].concat([].slice.call(arguments,1));return a.transition.apply(a,b)},a.utils.renderWatch=function(b,c){if(!(this instanceof a.utils.renderWatch))return new a.utils.renderWatch(b,c);var d=void 0!==c?c:250,e=[],f=this;this.models=function(a){return a=[].slice.call(arguments,0),a.forEach(function(a){a.__rendered=!1,function(a){a.dispatch.on("renderEnd",function(){a.__rendered=!0,f.renderEnd("model")})}(a),e.indexOf(a)<0&&e.push(a)}),this},this.reset=function(a){void 0!==a&&(d=a),e=[]},this.transition=function(a,b,c){if(b=arguments.length>1?[].slice.call(arguments,1):[],c=b.length>1?b.pop():void 0!==d?d:250,a.__rendered=!1,e.indexOf(a)<0&&e.push(a),0===c)return a.__rendered=!0,a.delay=function(){return this},a.duration=function(){return this},a;a.__rendered=0===a.length?!0:a.every(function(a){return!a.length})?!0:!1;var g=0;return a.transition().duration(c).each(function(){++g}).each("end",function(){0===--g&&(a.__rendered=!0,f.renderEnd.apply(this,b))})},this.renderEnd=function(){e.every(function(a){return a.__rendered})&&(e.forEach(function(a){a.__rendered=!1}),b.renderEnd.apply(this,arguments))}},a.utils.deepExtend=function(b){var c=arguments.length>1?[].slice.call(arguments,1):[];c.forEach(function(c){for(var d in c){var e=b[d]instanceof Array,f="object"==typeof b[d],g="object"==typeof c[d];f&&!e&&g?a.utils.deepExtend(b[d],c[d]):b[d]=c[d]}})},a.utils.state=function(){if(!(this instanceof a.utils.state))return new a.utils.state;var b={},c=function(){},d=function(){return{}},e=null,f=null;this.dispatch=d3.dispatch("change","set"),this.dispatch.on("set",function(a){c(a,!0)}),this.getter=function(a){return d=a,this},this.setter=function(a,b){return b||(b=function(){}),c=function(c,d){a(c),d&&b()},this},this.init=function(b){e=e||{},a.utils.deepExtend(e,b)};var g=function(){var a=d();if(JSON.stringify(a)===JSON.stringify(b))return!1;for(var c in a)void 0===b[c]&&(b[c]={}),b[c]=a[c],f=!0;return!0};this.update=function(){e&&(c(e,!1),e=null),g.call(this)&&this.dispatch.change(b)}},a.utils.optionsFunc=function(a){return a&&d3.map(a).forEach(function(a,b){"function"==typeof this[a]&&this[a](b)}.bind(this)),this},a.utils.calcTicksX=function(b,c){var d=1,e=0;for(e;ed?f:d}return a.log("Requested number of ticks: ",b),a.log("Calculated max values to be: ",d),b=b>d?b=d-1:b,b=1>b?1:b,b=Math.floor(b),a.log("Calculating tick count as: ",b),b},a.utils.calcTicksY=function(b,c){return a.utils.calcTicksX(b,c)},a.utils.initOption=function(a,b){a._calls&&a._calls[b]?a[b]=a._calls[b]:(a[b]=function(c){return arguments.length?(a._overrides[b]=!0,a._options[b]=c,a):a._options[b]},a["_"+b]=function(c){return arguments.length?(a._overrides[b]||(a._options[b]=c),a):a._options[b]})},a.utils.initOptions=function(b){b._overrides=b._overrides||{};var c=Object.getOwnPropertyNames(b._options||{}),d=Object.getOwnPropertyNames(b._calls||{});c=c.concat(d);for(var e in c)a.utils.initOption(b,c[e])},a.utils.inheritOptionsD3=function(a,b,c){a._d3options=c.concat(a._d3options||[]),c.unshift(b),c.unshift(a),d3.rebind.apply(this,c)},a.utils.arrayUnique=function(a){return a.sort().filter(function(b,c){return!c||b!=a[c-1]})},a.utils.symbolMap=d3.map(),a.utils.symbol=function(){function b(b,e){var f=c.call(this,b,e),g=d.call(this,b,e);return-1!==d3.svg.symbolTypes.indexOf(f)?d3.svg.symbol().type(f).size(g)():a.utils.symbolMap.get(f)(g)}var c,d=64;return b.type=function(a){return arguments.length?(c=d3.functor(a),b):c},b.size=function(a){return arguments.length?(d=d3.functor(a),b):d},b},a.utils.inheritOptions=function(b,c){var d=Object.getOwnPropertyNames(c._options||{}),e=Object.getOwnPropertyNames(c._calls||{}),f=c._inherited||[],g=c._d3options||[],h=d.concat(e).concat(f).concat(g);h.unshift(c),h.unshift(b),d3.rebind.apply(this,h),b._inherited=a.utils.arrayUnique(d.concat(e).concat(f).concat(d).concat(b._inherited||[])),b._d3options=a.utils.arrayUnique(g.concat(b._d3options||[]))},a.utils.initSVG=function(a){a.classed({"nvd3-svg":!0})},a.utils.sanitizeHeight=function(a,b){return a||parseInt(b.style("height"),10)||400},a.utils.sanitizeWidth=function(a,b){return a||parseInt(b.style("width"),10)||960},a.utils.availableHeight=function(b,c,d){return a.utils.sanitizeHeight(b,c)-d.top-d.bottom},a.utils.availableWidth=function(b,c,d){return a.utils.sanitizeWidth(b,c)-d.left-d.right},a.utils.noData=function(b,c){var d=b.options(),e=d.margin(),f=d.noData(),g=null==f?["No Data Available."]:[f],h=a.utils.availableHeight(d.height(),c,e),i=a.utils.availableWidth(d.width(),c,e),j=e.left+i/2,k=e.top+h/2;c.selectAll("g").remove();var l=c.selectAll(".nv-noData").data(g);l.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),l.attr("x",j).attr("y",k).text(function(a){return a})},a.models.axis=function(){"use strict";function b(g){return s.reset(),g.each(function(b){var g=d3.select(this);a.utils.initSVG(g);var p=g.selectAll("g.nv-wrap.nv-axis").data([b]),q=p.enter().append("g").attr("class","nvd3 nv-wrap nv-axis"),t=(q.append("g"),p.select("g"));null!==n?c.ticks(n):("top"==c.orient()||"bottom"==c.orient())&&c.ticks(Math.abs(d.range()[1]-d.range()[0])/100),t.watchTransition(s,"axis").call(c),r=r||c.scale();var u=c.tickFormat();null==u&&(u=r.tickFormat());var v=t.selectAll("text.nv-axislabel").data([h||null]);v.exit().remove();var w,x,y;switch(c.orient()){case"top":v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",0).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b))+",0)"}).select("text").attr("dy","-0.5em").attr("y",-c.tickPadding()).attr("text-anchor","middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max top").attr("transform",function(b,c){return"translate("+a.utils.NaNtoZero(d.range()[c])+",0)"}));break;case"bottom":w=o+36;var z=30,A=0,B=t.selectAll("g").select("text"),C="";if(j%360){B.each(function(){var a=this.getBoundingClientRect(),b=a.width;A=a.height,b>z&&(z=b)}),C="rotate("+j+" 0,"+(A/2+c.tickPadding())+")";var D=Math.abs(Math.sin(j*Math.PI/180));w=(D?D*z:z)+30,B.attr("transform",C).style("text-anchor",j%360>0?"start":"end")}v.enter().append("text").attr("class","nv-axislabel"),y=d.range().length<2?0:2===d.range().length?d.range()[1]:d.range()[d.range().length-1]+(d.range()[1]-d.range()[0]),v.attr("text-anchor","middle").attr("y",w).attr("x",y/2),i&&(x=p.selectAll("g.nv-axisMaxMin").data([d.domain()[0],d.domain()[d.domain().length-1]]),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-x",0==b?"nv-axisMin-x":"nv-axisMax-x"].join(" ")}).append("text"),x.exit().remove(),x.attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"}).select("text").attr("dy",".71em").attr("y",c.tickPadding()).attr("transform",C).style("text-anchor",j?j%360>0?"start":"end":"middle").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max bottom").attr("transform",function(b){return"translate("+a.utils.NaNtoZero(d(b)+(m?d.rangeBand()/2:0))+",0)"})),l&&B.attr("transform",function(a,b){return"translate(0,"+(b%2==0?"0":"12")+")"});break;case"right":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"begin").attr("transform",k?"rotate(90)":"").attr("y",k?-Math.max(e.right,f)+12:-10).attr("x",k?d3.max(d.range())/2:c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(d(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",c.tickPadding()).style("text-anchor","start").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1));break;case"left":v.enter().append("text").attr("class","nv-axislabel"),v.style("text-anchor",k?"middle":"end").attr("transform",k?"rotate(-90)":"").attr("y",k?-Math.max(e.left,f)+25-(o||0):-10).attr("x",k?-d3.max(d.range())/2:-c.tickPadding()),i&&(x=p.selectAll("g.nv-axisMaxMin").data(d.domain()),x.enter().append("g").attr("class",function(a,b){return["nv-axisMaxMin","nv-axisMaxMin-y",0==b?"nv-axisMin-y":"nv-axisMax-y"].join(" ")}).append("text").style("opacity",0),x.exit().remove(),x.attr("transform",function(b){return"translate(0,"+a.utils.NaNtoZero(r(b))+")"}).select("text").attr("dy",".32em").attr("y",0).attr("x",-c.tickPadding()).attr("text-anchor","end").text(function(a){var b=u(a);return(""+b).match("NaN")?"":b}),x.watchTransition(s,"min-max right").attr("transform",function(b,c){return"translate(0,"+a.utils.NaNtoZero(d.range()[c])+")"}).select("text").style("opacity",1))}if(v.text(function(a){return a}),!i||"left"!==c.orient()&&"right"!==c.orient()||(t.selectAll("g").each(function(a){d3.select(this).select("text").attr("opacity",1),(d(a)d.range()[0]-10)&&((a>1e-10||-1e-10>a)&&d3.select(this).attr("opacity",0),d3.select(this).select("text").attr("opacity",0))}),d.domain()[0]==d.domain()[1]&&0==d.domain()[0]&&p.selectAll("g.nv-axisMaxMin").style("opacity",function(a,b){return b?0:1})),i&&("top"===c.orient()||"bottom"===c.orient())){var E=[];p.selectAll("g.nv-axisMaxMin").each(function(a,b){try{E.push(b?d(a)-this.getBoundingClientRect().width-4:d(a)+this.getBoundingClientRect().width+4)}catch(c){E.push(b?d(a)-4:d(a)+4)}}),t.selectAll("g").each(function(a){(d(a)E[1])&&(a>1e-10||-1e-10>a?d3.select(this).remove():d3.select(this).select("text").remove())})}t.selectAll(".tick").filter(function(a){return!parseFloat(Math.round(1e5*a)/1e6)&&void 0!==a}).classed("zero",!0),r=d.copy()}),s.renderEnd("axis immediate"),b}var c=d3.svg.axis(),d=d3.scale.linear(),e={top:0,right:0,bottom:0,left:0},f=75,g=60,h=null,i=!0,j=0,k=!0,l=!1,m=!1,n=null,o=0,p=250,q=d3.dispatch("renderEnd");c.scale(d).orient("bottom").tickFormat(function(a){return a});var r,s=a.utils.renderWatch(q,p);return b.axis=c,b.dispatch=q,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{axisLabelDistance:{get:function(){return o},set:function(a){o=a}},staggerLabels:{get:function(){return l},set:function(a){l=a}},rotateLabels:{get:function(){return j},set:function(a){j=a}},rotateYLabel:{get:function(){return k},set:function(a){k=a}},showMaxMin:{get:function(){return i},set:function(a){i=a}},axisLabel:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return g},set:function(a){g=a}},ticks:{get:function(){return n},set:function(a){n=a}},width:{get:function(){return f},set:function(a){f=a}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},duration:{get:function(){return p},set:function(a){p=a,s.reset(p)}},scale:{get:function(){return d},set:function(e){d=e,c.scale(d),m="function"==typeof d.rangeBands,a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"])}}}),a.utils.initOptions(b),a.utils.inheritOptionsD3(b,c,["orient","tickValues","tickSubdivide","tickSize","tickPadding","tickFormat"]),a.utils.inheritOptionsD3(b,d,["domain","range","rangeBand","rangeBands"]),b},a.models.boxPlot=function(){"use strict";function b(l){return v.reset(),l.each(function(b){var l=j-i.left-i.right,p=k-i.top-i.bottom;r=d3.select(this),a.utils.initSVG(r),m.domain(c||b.map(function(a,b){return o(a,b)})).rangeBands(e||[0,l],.1);var w=[];if(!d){var x=d3.min(b.map(function(a){var b=[];return b.push(a.values.Q1),a.values.hasOwnProperty("whisker_low")&&null!==a.values.whisker_low&&b.push(a.values.whisker_low),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.min(b)})),y=d3.max(b.map(function(a){var b=[];return b.push(a.values.Q3),a.values.hasOwnProperty("whisker_high")&&null!==a.values.whisker_high&&b.push(a.values.whisker_high),a.values.hasOwnProperty("outliers")&&null!==a.values.outliers&&(b=b.concat(a.values.outliers)),d3.max(b)}));w=[x,y]}n.domain(d||w),n.range(f||[p,0]),g=g||m,h=h||n.copy().range([n(0),n(0)]);{var z=r.selectAll("g.nv-wrap").data([b]);z.enter().append("g").attr("class","nvd3 nv-wrap")}z.attr("transform","translate("+i.left+","+i.top+")");var A=z.selectAll(".nv-boxplot").data(function(a){return a}),B=A.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);A.attr("class","nv-boxplot").attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}).classed("hover",function(a){return a.hover}),A.watchTransition(v,"nv-boxplot: boxplots").style("stroke-opacity",1).style("fill-opacity",.75).delay(function(a,c){return c*t/b.length}).attr("transform",function(a,b){return"translate("+(m(o(a,b))+.05*m.rangeBand())+", 0)"}),A.exit().remove(),B.each(function(a,b){var c=d3.select(this);["low","high"].forEach(function(d){a.values.hasOwnProperty("whisker_"+d)&&null!==a.values["whisker_"+d]&&(c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-whisker nv-boxplot-"+d),c.append("line").style("stroke",a.color?a.color:q(a,b)).attr("class","nv-boxplot-tick nv-boxplot-"+d))})});var C=A.selectAll(".nv-boxplot-outlier").data(function(a){return a.values.hasOwnProperty("outliers")&&null!==a.values.outliers?a.values.outliers:[]});C.enter().append("circle").style("fill",function(a,b,c){return q(a,c)}).style("stroke",function(a,b,c){return q(a,c)}).on("mouseover",function(a,b,c){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:a,color:q(a,c)},e:d3.event})}).on("mouseout",function(a,b,c){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:a,color:q(a,c)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),C.attr("class","nv-boxplot-outlier"),C.watchTransition(v,"nv-boxplot: nv-boxplot-outlier").attr("cx",.45*m.rangeBand()).attr("cy",function(a){return n(a)}).attr("r","3"),C.exit().remove();var D=function(){return null===u?.9*m.rangeBand():Math.min(75,.9*m.rangeBand())},E=function(){return.45*m.rangeBand()-D()/2},F=function(){return.45*m.rangeBand()+D()/2};["low","high"].forEach(function(a){var b="low"===a?"Q1":"Q3";A.select("line.nv-boxplot-whisker.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",.45*m.rangeBand()).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",.45*m.rangeBand()).attr("y2",function(a){return n(a.values[b])}),A.select("line.nv-boxplot-tick.nv-boxplot-"+a).watchTransition(v,"nv-boxplot: boxplots").attr("x1",E).attr("y1",function(b){return n(b.values["whisker_"+a])}).attr("x2",F).attr("y2",function(b){return n(b.values["whisker_"+a])})}),["low","high"].forEach(function(a){B.selectAll(".nv-boxplot-"+a).on("mouseover",function(b,c,d){d3.select(this).classed("hover",!0),s.elementMouseover({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mouseout",function(b,c,d){d3.select(this).classed("hover",!1),s.elementMouseout({series:{key:b.values["whisker_"+a],color:q(b,d)},e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})})}),B.append("rect").attr("class","nv-boxplot-box").on("mouseover",function(a,b){d3.select(this).classed("hover",!0),s.elementMouseover({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),s.elementMouseout({key:a.label,value:a.label,series:[{key:"Q3",value:a.values.Q3,color:a.color||q(a,b)},{key:"Q2",value:a.values.Q2,color:a.color||q(a,b)},{key:"Q1",value:a.values.Q1,color:a.color||q(a,b)}],data:a,index:b,e:d3.event})}).on("mousemove",function(){s.elementMousemove({e:d3.event})}),A.select("rect.nv-boxplot-box").watchTransition(v,"nv-boxplot: boxes").attr("y",function(a){return n(a.values.Q3)}).attr("width",D).attr("x",E).attr("height",function(a){return Math.abs(n(a.values.Q3)-n(a.values.Q1))||1}).style("fill",function(a,b){return a.color||q(a,b)}).style("stroke",function(a,b){return a.color||q(a,b)}),B.append("line").attr("class","nv-boxplot-median"),A.select("line.nv-boxplot-median").watchTransition(v,"nv-boxplot: boxplots line").attr("x1",E).attr("y1",function(a){return n(a.values.Q2)}).attr("x2",F).attr("y2",function(a){return n(a.values.Q2)}),g=m.copy(),h=n.copy()}),v.renderEnd("nv-boxplot immediate"),b}var c,d,e,f,g,h,i={top:0,right:0,bottom:0,left:0},j=960,k=500,l=Math.floor(1e4*Math.random()),m=d3.scale.ordinal(),n=d3.scale.linear(),o=function(a){return a.x},p=function(a){return a.y},q=a.utils.defaultColor(),r=null,s=d3.dispatch("elementMouseover","elementMouseout","elementMousemove","renderEnd"),t=250,u=null,v=a.utils.renderWatch(s,t);return b.dispatch=s,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},maxBoxWidth:{get:function(){return u},set:function(a){u=a}},x:{get:function(){return o},set:function(a){o=a}},y:{get:function(){return p},set:function(a){p=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return l},set:function(a){l=a}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}},duration:{get:function(){return t},set:function(a){t=a,v.reset(t)}}}),a.utils.initOptions(b),b},a.models.boxPlotChart=function(){"use strict";function b(k){return t.reset(),t.models(e),l&&t.models(f),m&&t.models(g),k.each(function(k){var p=d3.select(this);a.utils.initSVG(p);var t=(i||parseInt(p.style("width"))||960)-h.left-h.right,u=(j||parseInt(p.style("height"))||400)-h.top-h.bottom;if(b.update=function(){r.beforeUpdate(),p.transition().duration(s).call(b)},b.container=this,!(k&&k.length&&k.filter(function(a){return a.values.hasOwnProperty("Q1")&&a.values.hasOwnProperty("Q2")&&a.values.hasOwnProperty("Q3")}).length)){var v=p.selectAll(".nv-noData").data([q]);return v.enter().append("text").attr("class","nvd3 nv-noData").attr("dy","-.7em").style("text-anchor","middle"),v.attr("x",h.left+t/2).attr("y",h.top+u/2).text(function(a){return a}),b}p.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var w=p.selectAll("g.nv-wrap.nv-boxPlotWithAxes").data([k]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-boxPlotWithAxes").append("g"),y=x.append("defs"),z=w.select("g"); +x.append("g").attr("class","nv-x nv-axis"),x.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),x.append("g").attr("class","nv-barsWrap"),z.attr("transform","translate("+h.left+","+h.top+")"),n&&z.select(".nv-y.nv-axis").attr("transform","translate("+t+",0)"),e.width(t).height(u);var A=z.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));if(A.transition().call(e),y.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),z.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(o?2:1)).attr("height",16).attr("x",-c.rangeBand()/(o?1:2)),l){f.scale(c).ticks(a.utils.calcTicksX(t/100,k)).tickSize(-u,0),z.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),z.select(".nv-x.nv-axis").call(f);var B=z.select(".nv-x.nv-axis").selectAll("g");o&&B.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}m&&(g.scale(d).ticks(Math.floor(u/36)).tickSize(-t,0),z.select(".nv-y.nv-axis").call(g)),z.select(".nv-zeroLine line").attr("x1",0).attr("x2",t).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("nv-boxplot chart immediate"),b}var c,d,e=a.models.boxPlot(),f=a.models.axis(),g=a.models.axis(),h={top:15,right:10,bottom:50,left:60},i=null,j=null,k=a.utils.getColor(),l=!0,m=!0,n=!1,o=!1,p=a.models.tooltip(),q="No Data Available.",r=d3.dispatch("tooltipShow","tooltipHide","beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(n?"right":"left").tickFormat(d3.format(",.1f")),p.duration(0);var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){p.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(a){p.data(a).hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){p.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.boxplot=e,b.xAxis=f,b.yAxis=g,b.tooltip=p,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},staggerLabels:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return l},set:function(a){l=a}},showYAxis:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return tooltips},set:function(a){tooltips=a}},tooltipContent:{get:function(){return p},set:function(a){p=a}},noData:{get:function(){return q},set:function(a){q=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!==a.top?a.top:h.top,h.right=void 0!==a.right?a.right:h.right,h.bottom=void 0!==a.bottom?a.bottom:h.bottom,h.left=void 0!==a.left?a.left:h.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}},rightAlignYAxis:{get:function(){return n},set:function(a){n=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.bullet=function(){"use strict";function b(d){return d.each(function(b,d){var p=m-c.left-c.right,s=n-c.top-c.bottom;o=d3.select(this),a.utils.initSVG(o);{var t=f.call(this,b,d).slice().sort(d3.descending),u=g.call(this,b,d).slice().sort(d3.descending),v=h.call(this,b,d).slice().sort(d3.descending),w=i.call(this,b,d).slice(),x=j.call(this,b,d).slice(),y=k.call(this,b,d).slice(),z=d3.scale.linear().domain(d3.extent(d3.merge([l,t]))).range(e?[p,0]:[0,p]);this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range())}this.__chart__=z;var A=d3.min(t),B=d3.max(t),C=t[1],D=o.selectAll("g.nv-wrap.nv-bullet").data([b]),E=D.enter().append("g").attr("class","nvd3 nv-wrap nv-bullet"),F=E.append("g"),G=D.select("g");F.append("rect").attr("class","nv-range nv-rangeMax"),F.append("rect").attr("class","nv-range nv-rangeAvg"),F.append("rect").attr("class","nv-range nv-rangeMin"),F.append("rect").attr("class","nv-measure"),D.attr("transform","translate("+c.left+","+c.top+")");var H=function(a){return Math.abs(z(a)-z(0))},I=function(a){return z(0>a?a:0)};G.select("rect.nv-rangeMax").attr("height",s).attr("width",H(B>0?B:A)).attr("x",I(B>0?B:A)).datum(B>0?B:A),G.select("rect.nv-rangeAvg").attr("height",s).attr("width",H(C)).attr("x",I(C)).datum(C),G.select("rect.nv-rangeMin").attr("height",s).attr("width",H(B)).attr("x",I(B)).attr("width",H(B>0?A:B)).attr("x",I(B>0?A:B)).datum(B>0?A:B),G.select("rect.nv-measure").style("fill",q).attr("height",s/3).attr("y",s/3).attr("width",0>v?z(0)-z(v[0]):z(v[0])-z(0)).attr("x",I(v)).on("mouseover",function(){r.elementMouseover({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})}).on("mouseout",function(){r.elementMouseout({value:v[0],label:y[0]||"Current",color:d3.select(this).style("fill")})});var J=s/6,K=u.map(function(a,b){return{value:a,label:x[b]}});F.selectAll("path.nv-markerTriangle").data(K).enter().append("path").attr("class","nv-markerTriangle").attr("transform",function(a){return"translate("+z(a.value)+","+s/2+")"}).attr("d","M0,"+J+"L"+J+","+-J+" "+-J+","+-J+"Z").on("mouseover",function(a){r.elementMouseover({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill"),pos:[z(a.value),s/2]})}).on("mousemove",function(a){r.elementMousemove({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a){r.elementMouseout({value:a.value,label:a.label||"Previous",color:d3.select(this).style("fill")})}),D.selectAll(".nv-range").on("mouseover",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseover({value:a,label:c,color:d3.select(this).style("fill")})}).on("mousemove",function(){r.elementMousemove({value:v[0],label:y[0]||"Previous",color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){var c=w[b]||(b?1==b?"Mean":"Minimum":"Maximum");r.elementMouseout({value:a,label:c,color:d3.select(this).style("fill")})})}),b}var c={top:0,right:0,bottom:0,left:0},d="left",e=!1,f=function(a){return a.ranges},g=function(a){return a.markers?a.markers:[0]},h=function(a){return a.measures},i=function(a){return a.rangeLabels?a.rangeLabels:[]},j=function(a){return a.markerLabels?a.markerLabels:[]},k=function(a){return a.measureLabels?a.measureLabels:[]},l=[0],m=380,n=30,o=null,p=null,q=a.utils.getColor(["#1f77b4"]),r=d3.dispatch("elementMouseover","elementMouseout","elementMousemove");return b.dispatch=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return f},set:function(a){f=a}},markers:{get:function(){return g},set:function(a){g=a}},measures:{get:function(){return h},set:function(a){h=a}},forceX:{get:function(){return l},set:function(a){l=a}},width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},tickFormat:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},orient:{get:function(){return d},set:function(a){d=a,e="right"==d||"bottom"==d}},color:{get:function(){return q},set:function(b){q=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.bulletChart=function(){"use strict";function b(d){return d.each(function(e,o){var p=d3.select(this);a.utils.initSVG(p);var q=a.utils.availableWidth(k,p,g),r=l-g.top-g.bottom;if(b.update=function(){b(d)},b.container=this,!e||!h.call(this,e,o))return a.utils.noData(b,p),b;p.selectAll(".nv-noData").remove();var s=h.call(this,e,o).slice().sort(d3.descending),t=i.call(this,e,o).slice().sort(d3.descending),u=j.call(this,e,o).slice().sort(d3.descending),v=p.selectAll("g.nv-wrap.nv-bulletChart").data([e]),w=v.enter().append("g").attr("class","nvd3 nv-wrap nv-bulletChart"),x=w.append("g"),y=v.select("g");x.append("g").attr("class","nv-bulletWrap"),x.append("g").attr("class","nv-titles"),v.attr("transform","translate("+g.left+","+g.top+")");var z=d3.scale.linear().domain([0,Math.max(s[0],t[0],u[0])]).range(f?[q,0]:[0,q]),A=this.__chart__||d3.scale.linear().domain([0,1/0]).range(z.range());this.__chart__=z;var B=x.select(".nv-titles").append("g").attr("text-anchor","end").attr("transform","translate(-6,"+(l-g.top-g.bottom)/2+")");B.append("text").attr("class","nv-title").text(function(a){return a.title}),B.append("text").attr("class","nv-subtitle").attr("dy","1em").text(function(a){return a.subtitle}),c.width(q).height(r);var C=y.select(".nv-bulletWrap");d3.transition(C).call(c);var D=m||z.tickFormat(q/100),E=y.selectAll("g.nv-tick").data(z.ticks(n?n:q/50),function(a){return this.textContent||D(a)}),F=E.enter().append("g").attr("class","nv-tick").attr("transform",function(a){return"translate("+A(a)+",0)"}).style("opacity",1e-6);F.append("line").attr("y1",r).attr("y2",7*r/6),F.append("text").attr("text-anchor","middle").attr("dy","1em").attr("y",7*r/6).text(D);var G=d3.transition(E).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1);G.select("line").attr("y1",r).attr("y2",7*r/6),G.select("text").attr("y",7*r/6),d3.transition(E.exit()).attr("transform",function(a){return"translate("+z(a)+",0)"}).style("opacity",1e-6).remove()}),d3.timer.flush(),b}var c=a.models.bullet(),d=a.models.tooltip(),e="left",f=!1,g={top:5,right:40,bottom:20,left:120},h=function(a){return a.ranges},i=function(a){return a.markers?a.markers:[0]},j=function(a){return a.measures},k=null,l=55,m=null,n=null,o=null,p=d3.dispatch("tooltipShow","tooltipHide");return d.duration(0).headerEnabled(!1),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.label,value:a.value,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.bullet=c,b.dispatch=p,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{ranges:{get:function(){return h},set:function(a){h=a}},markers:{get:function(){return i},set:function(a){i=a}},measures:{get:function(){return j},set:function(a){j=a}},width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},tickFormat:{get:function(){return m},set:function(a){m=a}},ticks:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return o},set:function(a){o=a}},tooltips:{get:function(){return d.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),d.enabled(!!b)}},tooltipContent:{get:function(){return d.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),d.contentGenerator(b)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},orient:{get:function(){return e},set:function(a){e=a,f="right"==e||"bottom"==e}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.candlestickBar=function(){"use strict";function b(x){return x.each(function(b){c=d3.select(this);var x=a.utils.availableWidth(i,c,h),y=a.utils.availableHeight(j,c,h);a.utils.initSVG(c);var A=x/b[0].values.length*.45;l.domain(d||d3.extent(b[0].values.map(n).concat(t))),l.range(v?f||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:f||[5+A/2,x-A/2-5]),m.domain(e||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(g||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var B=d3.select(this).selectAll("g.nv-wrap.nv-candlestickBar").data([b[0].values]),C=B.enter().append("g").attr("class","nvd3 nv-wrap nv-candlestickBar"),D=C.append("defs"),E=C.append("g"),F=B.select("g");E.append("g").attr("class","nv-ticks"),B.attr("transform","translate("+h.left+","+h.top+")"),c.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:k})}),D.append("clipPath").attr("id","nv-chart-clip-path-"+k).append("rect"),B.select("#nv-chart-clip-path-"+k+" rect").attr("width",x).attr("height",y),F.attr("clip-path",w?"url(#nv-chart-clip-path-"+k+")":"");var G=B.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});G.exit().remove();{var H=G.enter().append("g").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b});H.append("line").attr("class","nv-candlestick-lines").attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),H.append("rect").attr("class","nv-candlestick-rects nv-bars").attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}c.selectAll(".nv-candlestick-lines").transition().attr("transform",function(a,b){return"translate("+l(n(a,b))+",0)"}).attr("x1",0).attr("y1",function(a,b){return m(r(a,b))}).attr("x2",0).attr("y2",function(a,b){return m(s(a,b))}),c.selectAll(".nv-candlestick-rects").transition().attr("transform",function(a,b){return"translate("+(l(n(a,b))-A/2)+","+(m(o(a,b))-(p(a,b)>q(a,b)?m(q(a,b))-m(p(a,b)):0))+")"}).attr("x",0).attr("y",0).attr("width",A).attr("height",function(a,b){var c=p(a,b),d=q(a,b);return c>d?m(d)-m(c):m(c)-m(d)})}),b}var c,d,e,f,g,h={top:0,right:0,bottom:0,left:0},i=null,j=null,k=Math.floor(1e4*Math.random()),l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,d){b.clearHighlights(),c.select(".nv-candlestickBar .nv-tick-0-"+a).classed("hover",d)},b.clearHighlights=function(){c.select(".nv-candlestickBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return i},set:function(a){i=a}},height:{get:function(){return j},set:function(a){j=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return k},set:function(a){k=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return h},set:function(a){h.top=void 0!=a.top?a.top:h.top,h.right=void 0!=a.right?a.right:h.right,h.bottom=void 0!=a.bottom?a.bottom:h.bottom,h.left=void 0!=a.left?a.left:h.left}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.cumulativeLineChart=function(){"use strict";function b(l){return H.reset(),H.models(f),r&&H.models(g),s&&H.models(h),l.each(function(l){function A(){d3.select(b.container).style("cursor","ew-resize")}function E(){G.x=d3.event.x,G.i=Math.round(F.invert(G.x)),K()}function H(){d3.select(b.container).style("cursor","auto"),y.index=G.i,C.stateChange(y)}function K(){bb.data([G]);var a=b.duration();b.duration(0),b.update(),b.duration(a)}var L=d3.select(this);a.utils.initSVG(L),L.classed("nv-chart-"+x,!0);var M=this,N=a.utils.availableWidth(o,L,m),O=a.utils.availableHeight(p,L,m);if(b.update=function(){0===D?L.call(b):L.transition().duration(D).call(b)},b.container=this,y.setter(J(l),b.update).getter(I(l)).update(),y.disabled=l.map(function(a){return!!a.disabled}),!z){var P;z={};for(P in y)z[P]=y[P]instanceof Array?y[P].slice(0):y[P]}var Q=d3.behavior.drag().on("dragstart",A).on("drag",E).on("dragend",H);if(!(l&&l.length&&l.filter(function(a){return a.values.length}).length))return a.utils.noData(b,L),b;if(L.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale(),w)f.yDomain(null);else{var R=l.filter(function(a){return!a.disabled}).map(function(a){var b=d3.extent(a.values,f.y());return b[0]<-.95&&(b[0]=-.95),[(b[0]-b[1])/(1+b[1]),(b[1]-b[0])/(1+b[0])]}),S=[d3.min(R,function(a){return a[0]}),d3.max(R,function(a){return a[1]})];f.yDomain(S)}F.domain([0,l[0].values.length-1]).range([0,N]).clamp(!0);var l=c(G.i,l),T=v?"none":"all",U=L.selectAll("g.nv-wrap.nv-cumulativeLine").data([l]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-cumulativeLine").append("g"),W=U.select("g");if(V.append("g").attr("class","nv-interactive"),V.append("g").attr("class","nv-x nv-axis").style("pointer-events","none"),V.append("g").attr("class","nv-y nv-axis"),V.append("g").attr("class","nv-background"),V.append("g").attr("class","nv-linesWrap").style("pointer-events",T),V.append("g").attr("class","nv-avgLinesWrap").style("pointer-events","none"),V.append("g").attr("class","nv-legendWrap"),V.append("g").attr("class","nv-controlsWrap"),q&&(i.width(N),W.select(".nv-legendWrap").datum(l).call(i),m.top!=i.height()&&(m.top=i.height(),O=a.utils.availableHeight(p,L,m)),W.select(".nv-legendWrap").attr("transform","translate(0,"+-m.top+")")),u){var X=[{key:"Re-scale y-axis",disabled:!w}];j.width(140).color(["#444","#444","#444"]).rightAlign(!1).margin({top:5,right:0,bottom:5,left:20}),W.select(".nv-controlsWrap").datum(X).attr("transform","translate(0,"+-m.top+")").call(j)}U.attr("transform","translate("+m.left+","+m.top+")"),t&&W.select(".nv-y.nv-axis").attr("transform","translate("+N+",0)");var Y=l.filter(function(a){return a.tempDisabled});U.select(".tempDisabled").remove(),Y.length&&U.append("text").attr("class","tempDisabled").attr("x",N/2).attr("y","-.71em").style("text-anchor","end").text(Y.map(function(a){return a.key}).join(", ")+" values cannot be calculated for this time period."),v&&(k.width(N).height(O).margin({left:m.left,top:m.top}).svgContainer(L).xScale(d),U.select(".nv-interactive").call(k)),V.select(".nv-background").append("rect"),W.select(".nv-background rect").attr("width",N).attr("height",O),f.y(function(a){return a.display.y}).width(N).height(O).color(l.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!l[b].disabled&&!l[b].tempDisabled}));var Z=W.select(".nv-linesWrap").datum(l.filter(function(a){return!a.disabled&&!a.tempDisabled}));Z.call(f),l.forEach(function(a,b){a.seriesIndex=b});var $=l.filter(function(a){return!a.disabled&&!!B(a)}),_=W.select(".nv-avgLinesWrap").selectAll("line").data($,function(a){return a.key}),ab=function(a){var b=e(B(a));return 0>b?0:b>O?O:b};_.enter().append("line").style("stroke-width",2).style("stroke-dasharray","10,10").style("stroke",function(a){return f.color()(a,a.seriesIndex)}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.style("stroke-opacity",function(a){var b=e(B(a));return 0>b||b>O?0:1}).attr("x1",0).attr("x2",N).attr("y1",ab).attr("y2",ab),_.exit().remove();var bb=Z.selectAll(".nv-indexLine").data([G]);bb.enter().append("rect").attr("class","nv-indexLine").attr("width",3).attr("x",-2).attr("fill","red").attr("fill-opacity",.5).style("pointer-events","all").call(Q),bb.attr("transform",function(a){return"translate("+F(a.i)+",0)"}).attr("height",O),r&&(g.scale(d)._ticks(a.utils.calcTicksX(N/70,l)).tickSize(-O,0),W.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),W.select(".nv-x.nv-axis").call(g)),s&&(h.scale(e)._ticks(a.utils.calcTicksY(O/36,l)).tickSize(-N,0),W.select(".nv-y.nv-axis").call(h)),W.select(".nv-background rect").on("click",function(){G.x=d3.mouse(this)[0],G.i=Math.round(F.invert(G.x)),y.index=G.i,C.stateChange(y),K()}),f.dispatch.on("elementClick",function(a){G.i=a.pointIndex,G.x=F(G.i),y.index=G.i,C.stateChange(y),K()}),j.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,w=!a.disabled,y.rescaleY=w,C.stateChange(y),b.update()}),i.dispatch.on("stateChange",function(a){for(var c in a)y[c]=a[c];C.stateChange(y),b.update()}),k.dispatch.on("elementMousemove",function(c){f.clearHighlights();var d,e,i,j=[];if(l.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g,h){e=a.interactiveBisect(g.values,c.pointXValue,b.x()),f.highlightPoint(h,e,!0);var k=g.values[e];"undefined"!=typeof k&&("undefined"==typeof d&&(d=k),"undefined"==typeof i&&(i=b.xScale()(b.x()(k,e))),j.push({key:g.key,value:b.y()(k,e),color:n(g,g.seriesIndex)}))}),j.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(j.map(function(a){return a.value}),o,q);null!==r&&(j[r].highlight=!0)}var s=g.tickFormat()(b.x()(d,e),e);k.tooltip.position({left:i+m.left,top:c.mouseY+m.top}).chartContainer(M.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:s,series:j})(),k.renderGuideLine(i)}),k.dispatch.on("elementMouseout",function(){f.clearHighlights()}),C.on("changeState",function(a){"undefined"!=typeof a.disabled&&(l.forEach(function(b,c){b.disabled=a.disabled[c]}),y.disabled=a.disabled),"undefined"!=typeof a.index&&(G.i=a.index,G.x=F(G.i),y.index=a.index,bb.data([G])),"undefined"!=typeof a.rescaleY&&(w=a.rescaleY),b.update()})}),H.renderEnd("cumulativeLineChart immediate"),b}function c(a,b){return K||(K=f.y()),b.map(function(b){if(!b.values)return b;var c=b.values[a];if(null==c)return b;var d=K(c,a);return-.95>d&&!E?(b.tempDisabled=!0,b):(b.tempDisabled=!1,b.values=b.values.map(function(a,b){return a.display={y:(K(a,b)-d)/(1+d)},a}),b)})}var d,e,f=a.models.line(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.models.legend(),k=a.interactiveGuideline(),l=a.models.tooltip(),m={top:30,right:30,bottom:50,left:60},n=a.utils.defaultColor(),o=null,p=null,q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=!0,x=f.id(),y=a.utils.state(),z=null,A=null,B=function(a){return a.average},C=d3.dispatch("stateChange","changeState","renderEnd"),D=250,E=!1;y.index=0,y.rescaleY=w,g.orient("bottom").tickPadding(7),h.orient(t?"right":"left"),l.valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)}),j.updateState(!1);var F=d3.scale.linear(),G={i:0,x:0},H=a.utils.renderWatch(C,D),I=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),index:G.i,rescaleY:w}}},J=function(a){return function(b){void 0!==b.index&&(G.i=b.index),void 0!==b.rescaleY&&(w=b.rescaleY),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};f.dispatch.on("elementMouseover.tooltip",function(a){var c={x:b.x()(a.point),y:b.y()(a.point),color:a.point.color};a.point=c,l.data(a).position(a.pos).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){l.hidden(!0)});var K=null;return b.dispatch=C,b.lines=f,b.legend=i,b.controls=j,b.xAxis=g,b.yAxis=h,b.interactiveLayer=k,b.state=y,b.tooltip=l,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return o},set:function(a){o=a}},height:{get:function(){return p},set:function(a){p=a}},rescaleY:{get:function(){return w},set:function(a){w=a}},showControls:{get:function(){return u},set:function(a){u=a}},showLegend:{get:function(){return q},set:function(a){q=a}},average:{get:function(){return B},set:function(a){B=a}},defaultState:{get:function(){return z},set:function(a){z=a}},noData:{get:function(){return A},set:function(a){A=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},noErrorCheck:{get:function(){return E},set:function(a){E=a}},tooltips:{get:function(){return l.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),l.enabled(!!b)}},tooltipContent:{get:function(){return l.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),l.contentGenerator(b)}},margin:{get:function(){return m},set:function(a){m.top=void 0!==a.top?a.top:m.top,m.right=void 0!==a.right?a.right:m.right,m.bottom=void 0!==a.bottom?a.bottom:m.bottom,m.left=void 0!==a.left?a.left:m.left}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),i.color(n)}},useInteractiveGuideline:{get:function(){return v},set:function(a){v=a,a===!0&&(b.interactive(!1),b.useVoronoi(!1))}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,h.orient(a?"right":"left")}},duration:{get:function(){return D},set:function(a){D=a,f.duration(D),g.duration(D),h.duration(D),H.reset(D)}}}),a.utils.inheritOptions(b,f),a.utils.initOptions(b),b},a.models.discreteBar=function(){"use strict";function b(m){return y.reset(),m.each(function(b){var m=k-j.left-j.right,x=l-j.top-j.bottom;c=d3.select(this),a.utils.initSVG(c),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var z=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),y0:a.y0}})});n.domain(d||d3.merge(z).map(function(a){return a.x})).rangeBands(f||[0,m],.1),o.domain(e||d3.extent(d3.merge(z).map(function(a){return a.y}).concat(r))),o.range(t?g||[x-(o.domain()[0]<0?12:0),o.domain()[1]>0?12:0]:g||[x,0]),h=h||n,i=i||o.copy().range([o(0),o(0)]);{var A=c.selectAll("g.nv-wrap.nv-discretebar").data([b]),B=A.enter().append("g").attr("class","nvd3 nv-wrap nv-discretebar"),C=B.append("g");A.select("g")}C.append("g").attr("class","nv-groups"),A.attr("transform","translate("+j.left+","+j.top+")");var D=A.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});D.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),D.exit().watchTransition(y,"discreteBar: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),D.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),D.watchTransition(y,"discreteBar: groups").style("stroke-opacity",1).style("fill-opacity",.75);var E=D.selectAll("g.nv-bar").data(function(a){return a.values});E.exit().remove();var F=E.enter().append("g").attr("transform",function(a,b){return"translate("+(n(p(a,b))+.05*n.rangeBand())+", "+o(0)+")"}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),v.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),v.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){v.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){v.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()});F.append("rect").attr("height",0).attr("width",.9*n.rangeBand()/b.length),t?(F.append("text").attr("text-anchor","middle"),E.select("text").text(function(a,b){return u(q(a,b))}).watchTransition(y,"discreteBar: bars text").attr("x",.9*n.rangeBand()/2).attr("y",function(a,b){return q(a,b)<0?o(q(a,b))-o(0)+12:-4})):E.selectAll("text").remove(),E.attr("class",function(a,b){return q(a,b)<0?"nv-bar negative":"nv-bar positive"}).style("fill",function(a,b){return a.color||s(a,b)}).style("stroke",function(a,b){return a.color||s(a,b)}).select("rect").attr("class",w).watchTransition(y,"discreteBar: bars rect").attr("width",.9*n.rangeBand()/b.length),E.watchTransition(y,"discreteBar: bars").attr("transform",function(a,b){var c=n(p(a,b))+.05*n.rangeBand(),d=q(a,b)<0?o(0):o(0)-o(q(a,b))<1?o(0)-1:o(q(a,b));return"translate("+c+", "+d+")"}).select("rect").attr("height",function(a,b){return Math.max(Math.abs(o(q(a,b))-o(e&&e[0]||0))||1)}),h=n.copy(),i=o.copy()}),y.renderEnd("discreteBar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=d3.scale.ordinal(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=[0],s=a.utils.defaultColor(),t=!1,u=d3.format(",.2f"),v=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),w="discreteBar",x=250,y=a.utils.renderWatch(v,x);return b.dispatch=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},forceY:{get:function(){return r},set:function(a){r=a}},showValues:{get:function(){return t},set:function(a){t=a}},x:{get:function(){return p},set:function(a){p=a}},y:{get:function(){return q},set:function(a){q=a}},xScale:{get:function(){return n},set:function(a){n=a}},yScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},valueFormat:{get:function(){return u},set:function(a){u=a}},id:{get:function(){return m},set:function(a){m=a}},rectClass:{get:function(){return w},set:function(a){w=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b)}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x)}}}),a.utils.initOptions(b),b},a.models.discreteBarChart=function(){"use strict";function b(h){return t.reset(),t.models(e),m&&t.models(f),n&&t.models(g),h.each(function(h){var l=d3.select(this);a.utils.initSVG(l);var q=a.utils.availableWidth(j,l,i),t=a.utils.availableHeight(k,l,i);if(b.update=function(){r.beforeUpdate(),l.transition().duration(s).call(b)},b.container=this,!(h&&h.length&&h.filter(function(a){return a.values.length}).length))return a.utils.noData(b,l),b;l.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale().clamp(!0);var u=l.selectAll("g.nv-wrap.nv-discreteBarWithAxes").data([h]),v=u.enter().append("g").attr("class","nvd3 nv-wrap nv-discreteBarWithAxes").append("g"),w=v.append("defs"),x=u.select("g");v.append("g").attr("class","nv-x nv-axis"),v.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),v.append("g").attr("class","nv-barsWrap"),x.attr("transform","translate("+i.left+","+i.top+")"),o&&x.select(".nv-y.nv-axis").attr("transform","translate("+q+",0)"),e.width(q).height(t);var y=x.select(".nv-barsWrap").datum(h.filter(function(a){return!a.disabled}));if(y.transition().call(e),w.append("clipPath").attr("id","nv-x-label-clip-"+e.id()).append("rect"),x.select("#nv-x-label-clip-"+e.id()+" rect").attr("width",c.rangeBand()*(p?2:1)).attr("height",16).attr("x",-c.rangeBand()/(p?1:2)),m){f.scale(c)._ticks(a.utils.calcTicksX(q/100,h)).tickSize(-t,0),x.select(".nv-x.nv-axis").attr("transform","translate(0,"+(d.range()[0]+(e.showValues()&&d.domain()[0]<0?16:0))+")"),x.select(".nv-x.nv-axis").call(f); +var z=x.select(".nv-x.nv-axis").selectAll("g");p&&z.selectAll("text").attr("transform",function(a,b,c){return"translate(0,"+(c%2==0?"5":"17")+")"})}n&&(g.scale(d)._ticks(a.utils.calcTicksY(t/36,h)).tickSize(-q,0),x.select(".nv-y.nv-axis").call(g)),x.select(".nv-zeroLine line").attr("x1",0).attr("x2",q).attr("y1",d(0)).attr("y2",d(0))}),t.renderEnd("discreteBar chart immediate"),b}var c,d,e=a.models.discreteBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.tooltip(),i={top:15,right:10,bottom:50,left:60},j=null,k=null,l=a.utils.getColor(),m=!0,n=!0,o=!1,p=!1,q=null,r=d3.dispatch("beforeUpdate","renderEnd"),s=250;f.orient("bottom").showMaxMin(!1).tickFormat(function(a){return a}),g.orient(o?"right":"left").tickFormat(d3.format(",.1f")),h.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).keyFormatter(function(a,b){return f.tickFormat()(a,b)});var t=a.utils.renderWatch(r,s);return e.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},h.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){h.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){h.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=r,b.discretebar=e,b.xAxis=f,b.yAxis=g,b.tooltip=h,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return j},set:function(a){j=a}},height:{get:function(){return k},set:function(a){k=a}},staggerLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return m},set:function(a){m=a}},showYAxis:{get:function(){return n},set:function(a){n=a}},noData:{get:function(){return q},set:function(a){q=a}},tooltips:{get:function(){return h.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),h.enabled(!!b)}},tooltipContent:{get:function(){return h.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),h.contentGenerator(b)}},margin:{get:function(){return i},set:function(a){i.top=void 0!==a.top?a.top:i.top,i.right=void 0!==a.right?a.right:i.right,i.bottom=void 0!==a.bottom?a.bottom:i.bottom,i.left=void 0!==a.left?a.left:i.left}},duration:{get:function(){return s},set:function(a){s=a,t.reset(s),e.duration(s),f.duration(s),g.duration(s)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),e.color(l)}},rightAlignYAxis:{get:function(){return o},set:function(a){o=a,g.orient(a?"right":"left")}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.distribution=function(){"use strict";function b(k){return m.reset(),k.each(function(b){var k=(e-("x"===g?d.left+d.right:d.top+d.bottom),"x"==g?"y":"x"),l=d3.select(this);a.utils.initSVG(l),c=c||j;var n=l.selectAll("g.nv-distribution").data([b]),o=n.enter().append("g").attr("class","nvd3 nv-distribution"),p=(o.append("g"),n.select("g"));n.attr("transform","translate("+d.left+","+d.top+")");var q=p.selectAll("g.nv-dist").data(function(a){return a},function(a){return a.key});q.enter().append("g"),q.attr("class",function(a,b){return"nv-dist nv-series-"+b}).style("stroke",function(a,b){return i(a,b)});var r=q.selectAll("line.nv-dist"+g).data(function(a){return a.values});r.enter().append("line").attr(g+"1",function(a,b){return c(h(a,b))}).attr(g+"2",function(a,b){return c(h(a,b))}),m.transition(q.exit().selectAll("line.nv-dist"+g),"dist exit").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}).style("stroke-opacity",0).remove(),r.attr("class",function(a,b){return"nv-dist"+g+" nv-dist"+g+"-"+b}).attr(k+"1",0).attr(k+"2",f),m.transition(r,"dist").attr(g+"1",function(a,b){return j(h(a,b))}).attr(g+"2",function(a,b){return j(h(a,b))}),c=j.copy()}),m.renderEnd("distribution immediate"),b}var c,d={top:0,right:0,bottom:0,left:0},e=400,f=8,g="x",h=function(a){return a[g]},i=a.utils.defaultColor(),j=d3.scale.linear(),k=250,l=d3.dispatch("renderEnd"),m=a.utils.renderWatch(l,k);return b.options=a.utils.optionsFunc.bind(b),b.dispatch=l,b.margin=function(a){return arguments.length?(d.top="undefined"!=typeof a.top?a.top:d.top,d.right="undefined"!=typeof a.right?a.right:d.right,d.bottom="undefined"!=typeof a.bottom?a.bottom:d.bottom,d.left="undefined"!=typeof a.left?a.left:d.left,b):d},b.width=function(a){return arguments.length?(e=a,b):e},b.axis=function(a){return arguments.length?(g=a,b):g},b.size=function(a){return arguments.length?(f=a,b):f},b.getData=function(a){return arguments.length?(h=d3.functor(a),b):h},b.scale=function(a){return arguments.length?(j=a,b):j},b.color=function(c){return arguments.length?(i=a.utils.getColor(c),b):i},b.duration=function(a){return arguments.length?(k=a,m.reset(k),b):k},b},a.models.furiousLegend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?g(a,b):"#fff":m?void 0:a.disabled?g(a,b):"#fff"}function r(a,b){return m&&"furious"==o?a.disengaged?"#fff":g(a,b):a.disabled?"#fff":g(a,b)}return p.each(function(b){var p=d-c.left-c.right,s=d3.select(this);a.utils.initSVG(s);var t=s.selectAll("g.nv-legend").data([b]),u=(t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),t.select("g"));t.attr("transform","translate("+c.left+","+c.top+")");var v,w=u.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),x=w.enter().append("g").attr("class","nv-series");if("classic"==o)x.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),v=w.select("circle");else if("furious"==o){x.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),v=w.select("rect"),x.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var y=w.select(".nv-check-box");y.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}x.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var z=w.select("text.nv-legend-text");w.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=w.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=w.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),w.classed("nv-disabled",function(a){return a.userDisabled}),w.exit().remove(),z.attr("fill",q).text(f);var A;switch(o){case"furious":A=23;break;case"classic":A=20}if(h){var B=[];w.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}B.push(b+i)});for(var C=0,D=0,E=[];p>D&&Cp&&C>1;){E=[],C--;for(var F=0;F(E[F%C]||0)&&(E[F%C]=B[F]);D=E.reduce(function(a,b){return a+b})}for(var G=[],H=0,I=0;C>H;H++)G[H]=I,I+=E[H];w.attr("transform",function(a,b){return"translate("+G[b%C]+","+(5+Math.floor(b/C)*A)+")"}),j?u.attr("transform","translate("+(d-c.right-D)+","+c.top+")"):u.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(B.length/C)*A}else{var J,K=5,L=5,M=0;w.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return J=L,dM&&(M=L),"translate("+J+","+K+")"}),u.attr("transform","translate("+(d-c.right-M)+","+c.top+")"),e=c.top+c.bottom+K+15}"furious"==o&&v.attr("width",function(a,b){return z[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),v.style("fill",r).style("stroke",function(a,b){return a.color||g(a,b)})}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=28,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBar=function(){"use strict";function b(x){return x.each(function(b){w.reset(),k=d3.select(this);var x=a.utils.availableWidth(h,k,g),y=a.utils.availableHeight(i,k,g);a.utils.initSVG(k),l.domain(c||d3.extent(b[0].values.map(n).concat(p))),l.range(r?e||[.5*x/b[0].values.length,x*(b[0].values.length-.5)/b[0].values.length]:e||[0,x]),m.domain(d||d3.extent(b[0].values.map(o).concat(q))).range(f||[y,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var z=k.selectAll("g.nv-wrap.nv-historicalBar-"+j).data([b[0].values]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBar-"+j),B=A.append("defs"),C=A.append("g"),D=z.select("g");C.append("g").attr("class","nv-bars"),z.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){u.chartClick({data:a,index:b,pos:d3.event,id:j})}),B.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),z.select("#nv-chart-clip-path-"+j+" rect").attr("width",x).attr("height",y),D.attr("clip-path",s?"url(#nv-chart-clip-path-"+j+")":"");var E=z.select(".nv-bars").selectAll(".nv-bar").data(function(a){return a},function(a,b){return n(a,b)});E.exit().remove(),E.enter().append("rect").attr("x",0).attr("y",function(b,c){return a.utils.NaNtoZero(m(Math.max(0,o(b,c))))}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.abs(m(o(b,c))-m(0)))}).attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).on("mouseover",function(a,b){v&&(d3.select(this).classed("hover",!0),u.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mouseout",function(a,b){v&&(d3.select(this).classed("hover",!1),u.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")}))}).on("mousemove",function(a,b){v&&u.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){v&&(u.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}).on("dblclick",function(a,b){v&&(u.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation())}),E.attr("fill",function(a,b){return t(a,b)}).attr("class",function(a,b,c){return(o(a,b)<0?"nv-bar negative":"nv-bar positive")+" nv-bar-"+c+"-"+b}).watchTransition(w,"bars").attr("transform",function(a,c){return"translate("+(l(n(a,c))-x/b[0].values.length*.45)+",0)"}).attr("width",x/b[0].values.length*.9),E.watchTransition(w,"bars").attr("y",function(b,c){var d=o(b,c)<0?m(0):m(0)-m(o(b,c))<1?m(0)-1:m(o(b,c));return a.utils.NaNtoZero(d)}).attr("height",function(b,c){return a.utils.NaNtoZero(Math.max(Math.abs(m(o(b,c))-m(0)),1))})}),w.renderEnd("historicalBar immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=[],q=[0],r=!1,s=!0,t=a.utils.defaultColor(),u=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),v=!0,w=a.utils.renderWatch(u,0);return b.highlightPoint=function(a,b){k.select(".nv-bars .nv-bar-0-"+a).classed("hover",b)},b.clearHighlights=function(){k.select(".nv-bars .nv-bar.hover").classed("hover",!1)},b.dispatch=u,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},forceX:{get:function(){return p},set:function(a){p=a}},forceY:{get:function(){return q},set:function(a){q=a}},padData:{get:function(){return r},set:function(a){r=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},clipEdge:{get:function(){return s},set:function(a){s=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return v},set:function(a){v=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return t},set:function(b){t=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.historicalBarChart=function(b){"use strict";function c(b){return b.each(function(k){z.reset(),z.models(f),q&&z.models(g),r&&z.models(h);var w=d3.select(this),A=this;a.utils.initSVG(w);var B=a.utils.availableWidth(n,w,l),C=a.utils.availableHeight(o,w,l);if(c.update=function(){w.transition().duration(y).call(c)},c.container=this,u.disabled=k.map(function(a){return!!a.disabled}),!v){var D;v={};for(D in u)v[D]=u[D]instanceof Array?u[D].slice(0):u[D]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(c,w),c;w.selectAll(".nv-noData").remove(),d=f.xScale(),e=f.yScale();var E=w.selectAll("g.nv-wrap.nv-historicalBarChart").data([k]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-historicalBarChart").append("g"),G=E.select("g");F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-barsWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),p&&(i.width(B),G.select(".nv-legendWrap").datum(k).call(i),l.top!=i.height()&&(l.top=i.height(),C=a.utils.availableHeight(o,w,l)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-l.top+")")),E.attr("transform","translate("+l.left+","+l.top+")"),s&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),t&&(j.width(B).height(C).margin({left:l.left,top:l.top}).svgContainer(w).xScale(d),E.select(".nv-interactive").call(j)),f.width(B).height(C).color(k.map(function(a,b){return a.color||m(a,b)}).filter(function(a,b){return!k[b].disabled}));var H=G.select(".nv-barsWrap").datum(k.filter(function(a){return!a.disabled}));H.transition().call(f),q&&(g.scale(d)._ticks(a.utils.calcTicksX(B/100,k)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+e.range()[0]+")"),G.select(".nv-x.nv-axis").transition().call(g)),r&&(h.scale(e)._ticks(a.utils.calcTicksY(C/36,k)).tickSize(-B,0),G.select(".nv-y.nv-axis").transition().call(h)),j.dispatch.on("elementMousemove",function(b){f.clearHighlights();var d,e,i,n=[];k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(g){e=a.interactiveBisect(g.values,b.pointXValue,c.x()),f.highlightPoint(e,!0);var h=g.values[e];void 0!==h&&(void 0===d&&(d=h),void 0===i&&(i=c.xScale()(c.x()(h,e))),n.push({key:g.key,value:c.y()(h,e),color:m(g,g.seriesIndex),data:g.values[e]}))});var o=g.tickFormat()(c.x()(d,e));j.tooltip.position({left:i+l.left,top:b.mouseY+l.top}).chartContainer(A.parentNode).valueFormatter(function(a){return h.tickFormat()(a)}).data({value:o,index:e,series:n})(),j.renderGuideLine(i)}),j.dispatch.on("elementMouseout",function(){x.tooltipHide(),f.clearHighlights()}),i.dispatch.on("legendClick",function(a){a.disabled=!a.disabled,k.filter(function(a){return!a.disabled}).length||k.map(function(a){return a.disabled=!1,E.selectAll(".nv-series").classed("disabled",!1),a}),u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),b.transition().call(c)}),i.dispatch.on("legendDblclick",function(a){k.forEach(function(a){a.disabled=!0}),a.disabled=!1,u.disabled=k.map(function(a){return!!a.disabled}),x.stateChange(u),c.update()}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),c.update()})}),z.renderEnd("historicalBarChart immediate"),c}var d,e,f=b||a.models.historicalBar(),g=a.models.axis(),h=a.models.axis(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:90,bottom:50,left:90},m=a.utils.defaultColor(),n=null,o=null,p=!1,q=!0,r=!0,s=!1,t=!1,u={},v=null,w=null,x=d3.dispatch("tooltipHide","stateChange","changeState","renderEnd"),y=250;g.orient("bottom").tickPadding(7),h.orient(s?"right":"left"),k.duration(0).headerEnabled(!1).valueFormatter(function(a,b){return h.tickFormat()(a,b)}).headerFormatter(function(a,b){return g.tickFormat()(a,b)});var z=a.utils.renderWatch(x,0);return f.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:c.x()(a.data),value:c.y()(a.data),color:a.color},k.data(a).hidden(!1)}),f.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),f.dispatch.on("elementMousemove.tooltip",function(){k.position({top:d3.event.pageY,left:d3.event.pageX})()}),c.dispatch=x,c.bars=f,c.legend=i,c.xAxis=g,c.yAxis=h,c.interactiveLayer=j,c.tooltip=k,c.options=a.utils.optionsFunc.bind(c),c._options=Object.create({},{width:{get:function(){return n},set:function(a){n=a}},height:{get:function(){return o},set:function(a){o=a}},showLegend:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return q},set:function(a){q=a}},showYAxis:{get:function(){return r},set:function(a){r=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b),i.color(m),f.color(m)}},duration:{get:function(){return y},set:function(a){y=a,z.reset(y),h.duration(y),g.duration(y)}},rightAlignYAxis:{get:function(){return s},set:function(a){s=a,h.orient(a?"right":"left")}},useInteractiveGuideline:{get:function(){return t},set:function(a){t=a,a===!0&&c.interactive(!1)}}}),a.utils.inheritOptions(c,f),a.utils.initOptions(c),c},a.models.ohlcBarChart=function(){var b=a.models.historicalBarChart(a.models.ohlcBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.candlestickBarChart=function(){var b=a.models.historicalBarChart(a.models.candlestickBar());return b.useInteractiveGuideline(!0),b.interactiveLayer.tooltip.contentGenerator(function(a){var c=a.series[0].data,d=c.open'+a.value+"
open:"+b.yAxis.tickFormat()(c.open)+"
close:"+b.yAxis.tickFormat()(c.close)+"
high"+b.yAxis.tickFormat()(c.high)+"
low:"+b.yAxis.tickFormat()(c.low)+"
"}),b},a.models.legend=function(){"use strict";function b(p){function q(a,b){return"furious"!=o?"#000":m?a.disengaged?"#000":"#fff":m?void 0:(a.color||(a.color=g(a,b)),a.disabled?a.color:"#fff")}function r(a,b){return m&&"furious"==o&&a.disengaged?"#eee":a.color||g(a,b)}function s(a){return m&&"furious"==o?1:a.disabled?0:1}return p.each(function(b){var g=d-c.left-c.right,p=d3.select(this);a.utils.initSVG(p);var t=p.selectAll("g.nv-legend").data([b]),u=t.enter().append("g").attr("class","nvd3 nv-legend").append("g"),v=t.select("g");t.attr("transform","translate("+c.left+","+c.top+")");var w,x,y=v.selectAll(".nv-series").data(function(a){return"furious"!=o?a:a.filter(function(a){return m?!0:!a.disengaged})}),z=y.enter().append("g").attr("class","nv-series");switch(o){case"furious":x=23;break;case"classic":x=20}if("classic"==o)z.append("circle").style("stroke-width",2).attr("class","nv-legend-symbol").attr("r",5),w=y.select("circle");else if("furious"==o){z.append("rect").style("stroke-width",2).attr("class","nv-legend-symbol").attr("rx",3).attr("ry",3),w=y.select(".nv-legend-symbol"),z.append("g").attr("class","nv-check-box").property("innerHTML",'').attr("transform","translate(-10,-8)scale(0.5)");var A=y.select(".nv-check-box");A.each(function(a,b){d3.select(this).selectAll("path").attr("stroke",q(a,b))})}z.append("text").attr("text-anchor","start").attr("class","nv-legend-text").attr("dy",".32em").attr("dx","8");var B=y.select("text.nv-legend-text");y.on("mouseover",function(a,b){n.legendMouseover(a,b)}).on("mouseout",function(a,b){n.legendMouseout(a,b)}).on("click",function(a,b){n.legendClick(a,b);var c=y.data();if(k){if("classic"==o)l?(c.forEach(function(a){a.disabled=!0}),a.disabled=!1):(a.disabled=!a.disabled,c.every(function(a){return a.disabled})&&c.forEach(function(a){a.disabled=!1}));else if("furious"==o)if(m)a.disengaged=!a.disengaged,a.userDisabled=void 0==a.userDisabled?!!a.disabled:a.userDisabled,a.disabled=a.disengaged||a.userDisabled;else if(!m){a.disabled=!a.disabled,a.userDisabled=a.disabled;var d=c.filter(function(a){return!a.disengaged});d.every(function(a){return a.userDisabled})&&c.forEach(function(a){a.disabled=a.userDisabled=!1})}n.stateChange({disabled:c.map(function(a){return!!a.disabled}),disengaged:c.map(function(a){return!!a.disengaged})})}}).on("dblclick",function(a,b){if(("furious"!=o||!m)&&(n.legendDblclick(a,b),k)){var c=y.data();c.forEach(function(a){a.disabled=!0,"furious"==o&&(a.userDisabled=a.disabled)}),a.disabled=!1,"furious"==o&&(a.userDisabled=a.disabled),n.stateChange({disabled:c.map(function(a){return!!a.disabled})})}}),y.classed("nv-disabled",function(a){return a.userDisabled}),y.exit().remove(),B.attr("fill",q).text(f);var C=0;if(h){var D=[];y.each(function(){var b,c=d3.select(this).select("text");try{if(b=c.node().getComputedTextLength(),0>=b)throw Error()}catch(d){b=a.utils.calcApproxTextWidth(c)}D.push(b+i)});var E=0,F=[];for(C=0;g>C&&Eg&&E>1;){F=[],E--;for(var G=0;G(F[G%E]||0)&&(F[G%E]=D[G]);C=F.reduce(function(a,b){return a+b})}for(var H=[],I=0,J=0;E>I;I++)H[I]=J,J+=F[I];y.attr("transform",function(a,b){return"translate("+H[b%E]+","+(5+Math.floor(b/E)*x)+")"}),j?v.attr("transform","translate("+(d-c.right-C)+","+c.top+")"):v.attr("transform","translate(0,"+c.top+")"),e=c.top+c.bottom+Math.ceil(D.length/E)*x}else{var K,L=5,M=5,N=0;y.attr("transform",function(){var a=d3.select(this).select("text").node().getComputedTextLength()+i;return K=M,dN&&(N=M),K+N>C&&(C=K+N),"translate("+K+","+L+")"}),v.attr("transform","translate("+(d-c.right-N)+","+c.top+")"),e=c.top+c.bottom+L+15}if("furious"==o){w.attr("width",function(a,b){return B[0][b].getComputedTextLength()+27}).attr("height",18).attr("y",-9).attr("x",-15),u.insert("rect",":first-child").attr("class","nv-legend-bg").attr("fill","#eee").attr("opacity",0);var O=v.select(".nv-legend-bg");O.transition().duration(300).attr("x",-x).attr("width",C+x-12).attr("height",e+10).attr("y",-c.top-10).attr("opacity",m?1:0)}w.style("fill",r).style("fill-opacity",s).style("stroke",r)}),b}var c={top:5,right:0,bottom:5,left:0},d=400,e=20,f=function(a){return a.key},g=a.utils.getColor(),h=!0,i=32,j=!0,k=!0,l=!1,m=!1,n=d3.dispatch("legendClick","legendDblclick","legendMouseover","legendMouseout","stateChange"),o="classic";return b.dispatch=n,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},key:{get:function(){return f},set:function(a){f=a}},align:{get:function(){return h},set:function(a){h=a}},rightAlign:{get:function(){return j},set:function(a){j=a}},padding:{get:function(){return i},set:function(a){i=a}},updateState:{get:function(){return k},set:function(a){k=a}},radioButtonMode:{get:function(){return l},set:function(a){l=a}},expanded:{get:function(){return m},set:function(a){m=a}},vers:{get:function(){return o},set:function(a){o=a}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return g},set:function(b){g=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.line=function(){"use strict";function b(r){return v.reset(),v.models(e),r.each(function(b){i=d3.select(this);var r=a.utils.availableWidth(g,i,f),s=a.utils.availableHeight(h,i,f);a.utils.initSVG(i),c=e.xScale(),d=e.yScale(),t=t||c,u=u||d;var w=i.selectAll("g.nv-wrap.nv-line").data([b]),x=w.enter().append("g").attr("class","nvd3 nv-wrap nv-line"),y=x.append("defs"),z=x.append("g"),A=w.select("g");z.append("g").attr("class","nv-groups"),z.append("g").attr("class","nv-scatterWrap"),w.attr("transform","translate("+f.left+","+f.top+")"),e.width(r).height(s);var B=w.select(".nv-scatterWrap");B.call(e),y.append("clipPath").attr("id","nv-edge-clip-"+e.id()).append("rect"),w.select("#nv-edge-clip-"+e.id()+" rect").attr("width",r).attr("height",s>0?s:0),A.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":""),B.attr("clip-path",p?"url(#nv-edge-clip-"+e.id()+")":"");var C=w.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});C.enter().append("g").style("stroke-opacity",1e-6).style("stroke-width",function(a){return a.strokeWidth||j}).style("fill-opacity",1e-6),C.exit().remove(),C.attr("class",function(a,b){return(a.classed||"")+" nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return k(a,b)}).style("stroke",function(a,b){return k(a,b)}),C.watchTransition(v,"line: groups").style("stroke-opacity",1).style("fill-opacity",function(a){return a.fillOpacity||.5});var D=C.selectAll("path.nv-area").data(function(a){return o(a)?[a]:[]});D.enter().append("path").attr("class","nv-area").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y0(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))}).y1(function(){return u(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])}),C.exit().selectAll("path.nv-area").remove(),D.watchTransition(v,"line: areaPaths").attr("d",function(b){return d3.svg.area().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y0(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))}).y1(function(){return d(d.domain()[0]<=0?d.domain()[1]>=0?0:d.domain()[1]:d.domain()[0])}).apply(this,[b.values])});var E=C.selectAll("path.nv-line").data(function(a){return[a.values]});E.enter().append("path").attr("class","nv-line").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,c){return a.utils.NaNtoZero(t(l(b,c)))}).y(function(b,c){return a.utils.NaNtoZero(u(m(b,c)))})),E.watchTransition(v,"line: linePaths").attr("d",d3.svg.line().interpolate(q).defined(n).x(function(b,d){return a.utils.NaNtoZero(c(l(b,d)))}).y(function(b,c){return a.utils.NaNtoZero(d(m(b,c)))})),t=c.copy(),u=d.copy()}),v.renderEnd("line immediate"),b}var c,d,e=a.models.scatter(),f={top:0,right:0,bottom:0,left:0},g=960,h=500,i=null,j=1.5,k=a.utils.defaultColor(),l=function(a){return a.x},m=function(a){return a.y},n=function(a,b){return!isNaN(m(a,b))&&null!==m(a,b)},o=function(a){return a.area},p=!1,q="linear",r=250,s=d3.dispatch("elementClick","elementMouseover","elementMouseout","renderEnd");e.pointSize(16).pointDomain([16,256]);var t,u,v=a.utils.renderWatch(s,r);return b.dispatch=s,b.scatter=e,e.dispatch.on("elementClick",function(){s.elementClick.apply(this,arguments)}),e.dispatch.on("elementMouseover",function(){s.elementMouseover.apply(this,arguments)}),e.dispatch.on("elementMouseout",function(){s.elementMouseout.apply(this,arguments)}),b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},defined:{get:function(){return n},set:function(a){n=a}},interpolate:{get:function(){return q},set:function(a){q=a}},clipEdge:{get:function(){return p},set:function(a){p=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}},duration:{get:function(){return r},set:function(a){r=a,v.reset(r),e.duration(r)}},isArea:{get:function(){return o},set:function(a){o=d3.functor(a)}},x:{get:function(){return l},set:function(a){l=a,e.x(a)}},y:{get:function(){return m},set:function(a){m=a,e.y(a)}},color:{get:function(){return k},set:function(b){k=a.utils.getColor(b),e.color(k)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.lineChart=function(){"use strict";function b(j){return y.reset(),y.models(e),p&&y.models(f),q&&y.models(g),j.each(function(j){var v=d3.select(this),y=this;a.utils.initSVG(v);var B=a.utils.availableWidth(m,v,k),C=a.utils.availableHeight(n,v,k);if(b.update=function(){0===x?v.call(b):v.transition().duration(x).call(b)},b.container=this,t.setter(A(j),b.update).getter(z(j)).update(),t.disabled=j.map(function(a){return!!a.disabled}),!u){var D;u={};for(D in t)u[D]=t[D]instanceof Array?t[D].slice(0):t[D] +}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,v),b;v.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var E=v.selectAll("g.nv-wrap.nv-lineChart").data([j]),F=E.enter().append("g").attr("class","nvd3 nv-wrap nv-lineChart").append("g"),G=E.select("g");F.append("rect").style("opacity",0),F.append("g").attr("class","nv-x nv-axis"),F.append("g").attr("class","nv-y nv-axis"),F.append("g").attr("class","nv-linesWrap"),F.append("g").attr("class","nv-legendWrap"),F.append("g").attr("class","nv-interactive"),G.select("rect").attr("width",B).attr("height",C>0?C:0),o&&(h.width(B),G.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),C=a.utils.availableHeight(n,v,k)),E.select(".nv-legendWrap").attr("transform","translate(0,"+-k.top+")")),E.attr("transform","translate("+k.left+","+k.top+")"),r&&G.select(".nv-y.nv-axis").attr("transform","translate("+B+",0)"),s&&(i.width(B).height(C).margin({left:k.left,top:k.top}).svgContainer(v).xScale(c),E.select(".nv-interactive").call(i)),e.width(B).height(C).color(j.map(function(a,b){return a.color||l(a,b)}).filter(function(a,b){return!j[b].disabled}));var H=G.select(".nv-linesWrap").datum(j.filter(function(a){return!a.disabled}));H.call(e),p&&(f.scale(c)._ticks(a.utils.calcTicksX(B/100,j)).tickSize(-C,0),G.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),G.select(".nv-x.nv-axis").call(f)),q&&(g.scale(d)._ticks(a.utils.calcTicksY(C/36,j)).tickSize(-B,0),G.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)t[c]=a[c];w.stateChange(t),b.update()}),i.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,h,m,n=[];if(j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,g){h=a.interactiveBisect(f.values,c.pointXValue,b.x());var i=f.values[h],j=b.y()(i,h);null!=j&&e.highlightPoint(g,h,!0),void 0!==i&&(void 0===d&&(d=i),void 0===m&&(m=b.xScale()(b.x()(i,h))),n.push({key:f.key,value:j,color:l(f,f.seriesIndex)}))}),n.length>2){var o=b.yScale().invert(c.mouseY),p=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),q=.03*p,r=a.nearestValueIndex(n.map(function(a){return a.value}),o,q);null!==r&&(n[r].highlight=!0)}var s=f.tickFormat()(b.x()(d,h));i.tooltip.position({left:c.mouseX+k.left,top:c.mouseY+k.top}).chartContainer(y.parentNode).valueFormatter(function(a){return null==a?"N/A":g.tickFormat()(a)}).data({value:s,index:h,series:n})(),i.renderGuideLine(m)}),i.dispatch.on("elementClick",function(c){var d,f=[];j.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(e){var g=a.interactiveBisect(e.values,c.pointXValue,b.x()),h=e.values[g];if("undefined"!=typeof h){"undefined"==typeof d&&(d=b.xScale()(b.x()(h,g)));var i=b.yScale()(b.y()(h,g));f.push({point:h,pointIndex:g,pos:[d,i],seriesIndex:e.seriesIndex,series:e})}}),e.dispatch.elementClick(f)}),i.dispatch.on("elementMouseout",function(){e.clearHighlights()}),w.on("changeState",function(a){"undefined"!=typeof a.disabled&&j.length===a.disabled.length&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),t.disabled=a.disabled),b.update()})}),y.renderEnd("lineChart immediate"),b}var c,d,e=a.models.line(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.interactiveGuideline(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=a.utils.defaultColor(),m=null,n=null,o=!0,p=!0,q=!0,r=!1,s=!1,t=a.utils.state(),u=null,v=null,w=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),x=250;f.orient("bottom").tickPadding(7),g.orient(r?"right":"left"),j.valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)});var y=a.utils.renderWatch(w,x),z=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},A=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){j.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),b.dispatch=w,b.lines=e,b.legend=h,b.xAxis=f,b.yAxis=g,b.interactiveLayer=i,b.tooltip=j,b.dispatch=w,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return o},set:function(a){o=a}},showXAxis:{get:function(){return p},set:function(a){p=a}},showYAxis:{get:function(){return q},set:function(a){q=a}},defaultState:{get:function(){return u},set:function(a){u=a}},noData:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return x},set:function(a){x=a,y.reset(x),e.duration(x),f.duration(x),g.duration(x)}},color:{get:function(){return l},set:function(b){l=a.utils.getColor(b),h.color(l),e.color(l)}},rightAlignYAxis:{get:function(){return r},set:function(a){r=a,g.orient(r?"right":"left")}},useInteractiveGuideline:{get:function(){return s},set:function(a){s=a,s&&(e.interactive(!1),e.useVoronoi(!1))}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.linePlusBarChart=function(){"use strict";function b(v){return v.each(function(v){function J(a){var b=+("e"==a),c=b?1:-1,d=X/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function S(){u.empty()||u.extent(I),kb.data([u.empty()?e.domain():I]).each(function(a){var b=e(a[0])-e.range()[0],c=e.range()[1]-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>c?0:c)})}function T(){I=u.empty()?null:u.extent(),c=u.empty()?e.domain():u.extent(),K.brush({extent:c,brush:u}),S(),l.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),j.width(V).height(W).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var b=db.select(".nv-focus .nv-barsWrap").datum(Z.length?Z.map(function(a){return{key:a.key,values:a.values.filter(function(a,b){return l.x()(a,b)>=c[0]&&l.x()(a,b)<=c[1]})}}):[{values:[]}]),h=db.select(".nv-focus .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$.map(function(a){return{area:a.area,fillOpacity:a.fillOpacity,key:a.key,values:a.values.filter(function(a,b){return j.x()(a,b)>=c[0]&&j.x()(a,b)<=c[1]})}}));d=Z.length?l.xScale():j.xScale(),n.scale(d)._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-W,0),n.domain([Math.ceil(c[0]),Math.floor(c[1])]),db.select(".nv-x.nv-axis").transition().duration(L).call(n),b.transition().duration(L).call(l),h.transition().duration(L).call(j),db.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),p.scale(f)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(-V,0),q.scale(g)._ticks(a.utils.calcTicksY(W/36,v)).tickSize(Z.length?0:-V,0),db.select(".nv-focus .nv-y1.nv-axis").style("opacity",Z.length?1:0),db.select(".nv-focus .nv-y2.nv-axis").style("opacity",$.length&&!$[0].disabled?1:0).attr("transform","translate("+d.range()[1]+",0)"),db.select(".nv-focus .nv-y1.nv-axis").transition().duration(L).call(p),db.select(".nv-focus .nv-y2.nv-axis").transition().duration(L).call(q)}var U=d3.select(this);a.utils.initSVG(U);var V=a.utils.availableWidth(y,U,w),W=a.utils.availableHeight(z,U,w)-(E?H:0),X=H-x.top-x.bottom;if(b.update=function(){U.transition().duration(L).call(b)},b.container=this,M.setter(R(v),b.update).getter(Q(v)).update(),M.disabled=v.map(function(a){return!!a.disabled}),!N){var Y;N={};for(Y in M)N[Y]=M[Y]instanceof Array?M[Y].slice(0):M[Y]}if(!(v&&v.length&&v.filter(function(a){return a.values.length}).length))return a.utils.noData(b,U),b;U.selectAll(".nv-noData").remove();var Z=v.filter(function(a){return!a.disabled&&a.bar}),$=v.filter(function(a){return!a.bar});d=l.xScale(),e=o.scale(),f=l.yScale(),g=j.yScale(),h=m.yScale(),i=k.yScale();var _=v.filter(function(a){return!a.disabled&&a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})}),ab=v.filter(function(a){return!a.disabled&&!a.bar}).map(function(a){return a.values.map(function(a,b){return{x:A(a,b),y:B(a,b)}})});d.range([0,V]),e.domain(d3.extent(d3.merge(_.concat(ab)),function(a){return a.x})).range([0,V]);var bb=U.selectAll("g.nv-wrap.nv-linePlusBar").data([v]),cb=bb.enter().append("g").attr("class","nvd3 nv-wrap nv-linePlusBar").append("g"),db=bb.select("g");cb.append("g").attr("class","nv-legendWrap");var eb=cb.append("g").attr("class","nv-focus");eb.append("g").attr("class","nv-x nv-axis"),eb.append("g").attr("class","nv-y1 nv-axis"),eb.append("g").attr("class","nv-y2 nv-axis"),eb.append("g").attr("class","nv-barsWrap"),eb.append("g").attr("class","nv-linesWrap");var fb=cb.append("g").attr("class","nv-context");if(fb.append("g").attr("class","nv-x nv-axis"),fb.append("g").attr("class","nv-y1 nv-axis"),fb.append("g").attr("class","nv-y2 nv-axis"),fb.append("g").attr("class","nv-barsWrap"),fb.append("g").attr("class","nv-linesWrap"),fb.append("g").attr("class","nv-brushBackground"),fb.append("g").attr("class","nv-x nv-brush"),D){var gb=t.align()?V/2:V,hb=t.align()?gb:0;t.width(gb),db.select(".nv-legendWrap").datum(v.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(a.bar?O:P),a})).call(t),w.top!=t.height()&&(w.top=t.height(),W=a.utils.availableHeight(z,U,w)-H),db.select(".nv-legendWrap").attr("transform","translate("+hb+","+-w.top+")")}bb.attr("transform","translate("+w.left+","+w.top+")"),db.select(".nv-context").style("display",E?"initial":"none"),m.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&v[b].bar})),k.width(V).height(X).color(v.map(function(a,b){return a.color||C(a,b)}).filter(function(a,b){return!v[b].disabled&&!v[b].bar}));var ib=db.select(".nv-context .nv-barsWrap").datum(Z.length?Z:[{values:[]}]),jb=db.select(".nv-context .nv-linesWrap").datum($[0].disabled?[{values:[]}]:$);db.select(".nv-context").attr("transform","translate(0,"+(W+w.bottom+x.top)+")"),ib.transition().call(m),jb.transition().call(k),G&&(o._ticks(a.utils.calcTicksX(V/100,v)).tickSize(-X,0),db.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+h.range()[0]+")"),db.select(".nv-context .nv-x.nv-axis").transition().call(o)),F&&(r.scale(h)._ticks(X/36).tickSize(-V,0),s.scale(i)._ticks(X/36).tickSize(Z.length?0:-V,0),db.select(".nv-context .nv-y3.nv-axis").style("opacity",Z.length?1:0).attr("transform","translate(0,"+e.range()[0]+")"),db.select(".nv-context .nv-y2.nv-axis").style("opacity",$.length?1:0).attr("transform","translate("+e.range()[1]+",0)"),db.select(".nv-context .nv-y1.nv-axis").transition().call(r),db.select(".nv-context .nv-y2.nv-axis").transition().call(s)),u.x(e).on("brush",T),I&&u.extent(I);var kb=db.select(".nv-brushBackground").selectAll("g").data([I||u.extent()]),lb=kb.enter().append("g");lb.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",X),lb.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",X);var mb=db.select(".nv-x.nv-brush").call(u);mb.selectAll("rect").attr("height",X),mb.selectAll(".resize").append("path").attr("d",J),t.dispatch.on("stateChange",function(a){for(var c in a)M[c]=a[c];K.stateChange(M),b.update()}),K.on("changeState",function(a){"undefined"!=typeof a.disabled&&(v.forEach(function(b,c){b.disabled=a.disabled[c]}),M.disabled=a.disabled),b.update()}),T()}),b}var c,d,e,f,g,h,i,j=a.models.line(),k=a.models.line(),l=a.models.historicalBar(),m=a.models.historicalBar(),n=a.models.axis(),o=a.models.axis(),p=a.models.axis(),q=a.models.axis(),r=a.models.axis(),s=a.models.axis(),t=a.models.legend(),u=d3.svg.brush(),v=a.models.tooltip(),w={top:30,right:30,bottom:30,left:60},x={top:0,right:30,bottom:20,left:60},y=null,z=null,A=function(a){return a.x},B=function(a){return a.y},C=a.utils.defaultColor(),D=!0,E=!0,F=!1,G=!0,H=50,I=null,J=null,K=d3.dispatch("brush","stateChange","changeState"),L=0,M=a.utils.state(),N=null,O=" (left axis)",P=" (right axis)";j.clipEdge(!0),k.interactive(!1),n.orient("bottom").tickPadding(5),p.orient("left"),q.orient("right"),o.orient("bottom").tickPadding(5),r.orient("left"),s.orient("right"),v.headerEnabled(!0).headerFormatter(function(a,b){return n.tickFormat()(a,b)});var Q=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},R=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return j.dispatch.on("elementMouseover.tooltip",function(a){v.duration(100).valueFormatter(function(a,b){return q.tickFormat()(a,b)}).data(a).position(a.pos).hidden(!1)}),j.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={value:b.y()(a.data),color:a.color},v.duration(0).valueFormatter(function(a,b){return p.tickFormat()(a,b)}).data(a).hidden(!1)}),l.dispatch.on("elementMouseout.tooltip",function(){v.hidden(!0)}),l.dispatch.on("elementMousemove.tooltip",function(){v.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=K,b.legend=t,b.lines=j,b.lines2=k,b.bars=l,b.bars2=m,b.xAxis=n,b.x2Axis=o,b.y1Axis=p,b.y2Axis=q,b.y3Axis=r,b.y4Axis=s,b.tooltip=v,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return y},set:function(a){y=a}},height:{get:function(){return z},set:function(a){z=a}},showLegend:{get:function(){return D},set:function(a){D=a}},brushExtent:{get:function(){return I},set:function(a){I=a}},noData:{get:function(){return J},set:function(a){J=a}},focusEnable:{get:function(){return E},set:function(a){E=a}},focusHeight:{get:function(){return H},set:function(a){H=a}},focusShowAxisX:{get:function(){return G},set:function(a){G=a}},focusShowAxisY:{get:function(){return F},set:function(a){F=a}},legendLeftAxisHint:{get:function(){return O},set:function(a){O=a}},legendRightAxisHint:{get:function(){return P},set:function(a){P=a}},tooltips:{get:function(){return v.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),v.enabled(!!b)}},tooltipContent:{get:function(){return v.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),v.contentGenerator(b)}},margin:{get:function(){return w},set:function(a){w.top=void 0!==a.top?a.top:w.top,w.right=void 0!==a.right?a.right:w.right,w.bottom=void 0!==a.bottom?a.bottom:w.bottom,w.left=void 0!==a.left?a.left:w.left}},duration:{get:function(){return L},set:function(a){L=a}},color:{get:function(){return C},set:function(b){C=a.utils.getColor(b),t.color(C)}},x:{get:function(){return A},set:function(a){A=a,j.x(a),k.x(a),l.x(a),m.x(a)}},y:{get:function(){return B},set:function(a){B=a,j.y(a),k.y(a),l.y(a),m.y(a)}}}),a.utils.inheritOptions(b,j),a.utils.initOptions(b),b},a.models.lineWithFocusChart=function(){"use strict";function b(o){return o.each(function(o){function z(a){var b=+("e"==a),c=b?1:-1,d=M/3;return"M"+.5*c+","+d+"A6,6 0 0 "+b+" "+6.5*c+","+(d+6)+"V"+(2*d-6)+"A6,6 0 0 "+b+" "+.5*c+","+2*d+"ZM"+2.5*c+","+(d+8)+"V"+(2*d-8)+"M"+4.5*c+","+(d+8)+"V"+(2*d-8)}function G(){n.empty()||n.extent(y),U.data([n.empty()?e.domain():y]).each(function(a){var b=e(a[0])-c.range()[0],d=K-e(a[1]);d3.select(this).select(".left").attr("width",0>b?0:b),d3.select(this).select(".right").attr("x",e(a[1])).attr("width",0>d?0:d)})}function H(){y=n.empty()?null:n.extent();var a=n.empty()?e.domain():n.extent();if(!(Math.abs(a[0]-a[1])<=1)){A.brush({extent:a,brush:n}),G();var b=Q.select(".nv-focus .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}).map(function(b){return{key:b.key,area:b.area,values:b.values.filter(function(b,c){return g.x()(b,c)>=a[0]&&g.x()(b,c)<=a[1]})}}));b.transition().duration(B).call(g),Q.select(".nv-focus .nv-x.nv-axis").transition().duration(B).call(i),Q.select(".nv-focus .nv-y.nv-axis").transition().duration(B).call(j)}}var I=d3.select(this),J=this;a.utils.initSVG(I);var K=a.utils.availableWidth(t,I,q),L=a.utils.availableHeight(u,I,q)-v,M=v-r.top-r.bottom;if(b.update=function(){I.transition().duration(B).call(b)},b.container=this,C.setter(F(o),b.update).getter(E(o)).update(),C.disabled=o.map(function(a){return!!a.disabled}),!D){var N;D={};for(N in C)D[N]=C[N]instanceof Array?C[N].slice(0):C[N]}if(!(o&&o.length&&o.filter(function(a){return a.values.length}).length))return a.utils.noData(b,I),b;I.selectAll(".nv-noData").remove(),c=g.xScale(),d=g.yScale(),e=h.xScale(),f=h.yScale();var O=I.selectAll("g.nv-wrap.nv-lineWithFocusChart").data([o]),P=O.enter().append("g").attr("class","nvd3 nv-wrap nv-lineWithFocusChart").append("g"),Q=O.select("g");P.append("g").attr("class","nv-legendWrap");var R=P.append("g").attr("class","nv-focus");R.append("g").attr("class","nv-x nv-axis"),R.append("g").attr("class","nv-y nv-axis"),R.append("g").attr("class","nv-linesWrap"),R.append("g").attr("class","nv-interactive");var S=P.append("g").attr("class","nv-context");S.append("g").attr("class","nv-x nv-axis"),S.append("g").attr("class","nv-y nv-axis"),S.append("g").attr("class","nv-linesWrap"),S.append("g").attr("class","nv-brushBackground"),S.append("g").attr("class","nv-x nv-brush"),x&&(m.width(K),Q.select(".nv-legendWrap").datum(o).call(m),q.top!=m.height()&&(q.top=m.height(),L=a.utils.availableHeight(u,I,q)-v),Q.select(".nv-legendWrap").attr("transform","translate(0,"+-q.top+")")),O.attr("transform","translate("+q.left+","+q.top+")"),w&&(p.width(K).height(L).margin({left:q.left,top:q.top}).svgContainer(I).xScale(c),O.select(".nv-interactive").call(p)),g.width(K).height(L).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),h.defined(g.defined()).width(K).height(M).color(o.map(function(a,b){return a.color||s(a,b)}).filter(function(a,b){return!o[b].disabled})),Q.select(".nv-context").attr("transform","translate(0,"+(L+q.bottom+r.top)+")");var T=Q.select(".nv-context .nv-linesWrap").datum(o.filter(function(a){return!a.disabled}));d3.transition(T).call(h),i.scale(c)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-L,0),j.scale(d)._ticks(a.utils.calcTicksY(L/36,o)).tickSize(-K,0),Q.select(".nv-focus .nv-x.nv-axis").attr("transform","translate(0,"+L+")"),n.x(e).on("brush",function(){H()}),y&&n.extent(y);var U=Q.select(".nv-brushBackground").selectAll("g").data([y||n.extent()]),V=U.enter().append("g");V.append("rect").attr("class","left").attr("x",0).attr("y",0).attr("height",M),V.append("rect").attr("class","right").attr("x",0).attr("y",0).attr("height",M);var W=Q.select(".nv-x.nv-brush").call(n);W.selectAll("rect").attr("height",M),W.selectAll(".resize").append("path").attr("d",z),H(),k.scale(e)._ticks(a.utils.calcTicksX(K/100,o)).tickSize(-M,0),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),d3.transition(Q.select(".nv-context .nv-x.nv-axis")).call(k),l.scale(f)._ticks(a.utils.calcTicksY(M/36,o)).tickSize(-K,0),d3.transition(Q.select(".nv-context .nv-y.nv-axis")).call(l),Q.select(".nv-context .nv-x.nv-axis").attr("transform","translate(0,"+f.range()[0]+")"),m.dispatch.on("stateChange",function(a){for(var c in a)C[c]=a[c];A.stateChange(C),b.update()}),p.dispatch.on("elementMousemove",function(c){g.clearHighlights();var d,f,h,k=[];if(o.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(i,j){var l=n.empty()?e.domain():n.extent(),m=i.values.filter(function(a,b){return g.x()(a,b)>=l[0]&&g.x()(a,b)<=l[1]});f=a.interactiveBisect(m,c.pointXValue,g.x());var o=m[f],p=b.y()(o,f);null!=p&&g.highlightPoint(j,f,!0),void 0!==o&&(void 0===d&&(d=o),void 0===h&&(h=b.xScale()(b.x()(o,f))),k.push({key:i.key,value:b.y()(o,f),color:s(i,i.seriesIndex)}))}),k.length>2){var l=b.yScale().invert(c.mouseY),m=Math.abs(b.yScale().domain()[0]-b.yScale().domain()[1]),r=.03*m,t=a.nearestValueIndex(k.map(function(a){return a.value}),l,r);null!==t&&(k[t].highlight=!0)}var u=i.tickFormat()(b.x()(d,f));p.tooltip.position({left:c.mouseX+q.left,top:c.mouseY+q.top}).chartContainer(J.parentNode).valueFormatter(function(a){return null==a?"N/A":j.tickFormat()(a)}).data({value:u,index:f,series:k})(),p.renderGuideLine(h)}),p.dispatch.on("elementMouseout",function(){g.clearHighlights()}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&o.forEach(function(b,c){b.disabled=a.disabled[c]}),b.update()})}),b}var c,d,e,f,g=a.models.line(),h=a.models.line(),i=a.models.axis(),j=a.models.axis(),k=a.models.axis(),l=a.models.axis(),m=a.models.legend(),n=d3.svg.brush(),o=a.models.tooltip(),p=a.interactiveGuideline(),q={top:30,right:30,bottom:30,left:60},r={top:0,right:30,bottom:20,left:60},s=a.utils.defaultColor(),t=null,u=null,v=50,w=!1,x=!0,y=null,z=null,A=d3.dispatch("brush","stateChange","changeState"),B=250,C=a.utils.state(),D=null;g.clipEdge(!0).duration(0),h.interactive(!1),i.orient("bottom").tickPadding(5),j.orient("left"),k.orient("bottom").tickPadding(5),l.orient("left"),o.valueFormatter(function(a,b){return j.tickFormat()(a,b)}).headerFormatter(function(a,b){return i.tickFormat()(a,b)});var E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return g.dispatch.on("elementMouseover.tooltip",function(a){o.data(a).position(a.pos).hidden(!1)}),g.dispatch.on("elementMouseout.tooltip",function(){o.hidden(!0)}),b.dispatch=A,b.legend=m,b.lines=g,b.lines2=h,b.xAxis=i,b.yAxis=j,b.x2Axis=k,b.y2Axis=l,b.interactiveLayer=p,b.tooltip=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return t},set:function(a){t=a}},height:{get:function(){return u},set:function(a){u=a}},focusHeight:{get:function(){return v},set:function(a){v=a}},showLegend:{get:function(){return x},set:function(a){x=a}},brushExtent:{get:function(){return y},set:function(a){y=a}},defaultState:{get:function(){return D},set:function(a){D=a}},noData:{get:function(){return z},set:function(a){z=a}},tooltips:{get:function(){return o.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),o.enabled(!!b)}},tooltipContent:{get:function(){return o.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),o.contentGenerator(b)}},margin:{get:function(){return q},set:function(a){q.top=void 0!==a.top?a.top:q.top,q.right=void 0!==a.right?a.right:q.right,q.bottom=void 0!==a.bottom?a.bottom:q.bottom,q.left=void 0!==a.left?a.left:q.left}},color:{get:function(){return s},set:function(b){s=a.utils.getColor(b),m.color(s)}},interpolate:{get:function(){return g.interpolate()},set:function(a){g.interpolate(a),h.interpolate(a)}},xTickFormat:{get:function(){return i.tickFormat()},set:function(a){i.tickFormat(a),k.tickFormat(a)}},yTickFormat:{get:function(){return j.tickFormat()},set:function(a){j.tickFormat(a),l.tickFormat(a)}},duration:{get:function(){return B},set:function(a){B=a,j.duration(B),l.duration(B),i.duration(B),k.duration(B)}},x:{get:function(){return g.x()},set:function(a){g.x(a),h.x(a)}},y:{get:function(){return g.y()},set:function(a){g.y(a),h.y(a)}},useInteractiveGuideline:{get:function(){return w},set:function(a){w=a,w&&(g.interactive(!1),g.useVoronoi(!1))}}}),a.utils.inheritOptions(b,g),a.utils.initOptions(b),b},a.models.multiBar=function(){"use strict";function b(E){return C.reset(),E.each(function(b){var E=k-j.left-j.right,F=l-j.top-j.bottom;p=d3.select(this),a.utils.initSVG(p);var G=0;if(x&&b.length&&(x=[{values:b[0].values.map(function(a){return{x:a.x,y:0,series:a.series,size:.01}})}]),u){var H=d3.layout.stack().offset(v).values(function(a){return a.values}).y(r)(!b.length&&x?x:b);H.forEach(function(a,c){a.nonStackable?(b[c].nonStackableSeries=G++,H[c]=b[c]):c>0&&H[c-1].nonStackable&&H[c].values.map(function(a,b){a.y0-=H[c-1].values[b].y,a.y1=a.y0+a.y})}),b=H}b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),u&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a,f){if(!b[f].nonStackable){var g=a.values[c];g.size=Math.abs(g.y),g.y<0?(g.y1=e,e-=g.size):(g.y1=g.size+d,d+=g.size)}})});var I=d&&e?[]:b.map(function(a,b){return a.values.map(function(a,c){return{x:q(a,c),y:r(a,c),y0:a.y0,y1:a.y1,idx:b}})});m.domain(d||d3.merge(I).map(function(a){return a.x})).rangeBands(f||[0,E],A),n.domain(e||d3.extent(d3.merge(I).map(function(a){var c=a.y;return u&&!b[a.idx].nonStackable&&(c=a.y>0?a.y1:a.y1+a.y),c}).concat(s))).range(g||[F,0]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]+.01*n.domain()[0],n.domain()[1]-.01*n.domain()[1]]:[-1,1]),h=h||m,i=i||n;var J=p.selectAll("g.nv-wrap.nv-multibar").data([b]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multibar"),L=K.append("defs"),M=K.append("g"),N=J.select("g");M.append("g").attr("class","nv-groups"),J.attr("transform","translate("+j.left+","+j.top+")"),L.append("clipPath").attr("id","nv-edge-clip-"+o).append("rect"),J.select("#nv-edge-clip-"+o+" rect").attr("width",E).attr("height",F),N.attr("clip-path",t?"url(#nv-edge-clip-"+o+")":"");var O=J.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});O.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6);var P=C.transition(O.exit().selectAll("rect.nv-bar"),"multibarExit",Math.min(100,z)).attr("y",function(a){var c=i(0)||0;return u&&b[a.series]&&!b[a.series].nonStackable&&(c=i(a.y0)),c}).attr("height",0).remove();P.delay&&P.delay(function(a,b){var c=b*(z/(D+1))-b;return c}),O.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return w(a,b)}).style("stroke",function(a,b){return w(a,b)}),O.style("stroke-opacity",1).style("fill-opacity",.75);var Q=O.selectAll("rect.nv-bar").data(function(a){return x&&!b.length?x.values:a.values});Q.exit().remove();Q.enter().append("rect").attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("x",function(a,c,d){return u&&!b[d].nonStackable?0:d*m.rangeBand()/b.length}).attr("y",function(a,c,d){return i(u&&!b[d].nonStackable?a.y0:0)||0}).attr("height",0).attr("width",function(a,c,d){return m.rangeBand()/(u&&!b[d].nonStackable?1:b.length)}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"});Q.style("fill",function(a,b,c){return w(a,c,b)}).style("stroke",function(a,b,c){return w(a,c,b)}).on("mouseover",function(a,b){d3.select(this).classed("hover",!0),B.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),B.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){B.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){B.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){B.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),Q.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}).attr("transform",function(a,b){return"translate("+m(q(a,b))+",0)"}),y&&(c||(c=b.map(function(){return!0})),Q.style("fill",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(y(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}));var R=Q.watchTransition(C,"multibar",Math.min(250,z)).delay(function(a,c){return c*z/b[0].values.length});u?R.attr("y",function(a,c,d){var e=0;return e=b[d].nonStackable?r(a,c)<0?n(0):n(0)-n(r(a,c))<-1?n(0)-1:n(r(a,c))||0:n(a.y1)}).attr("height",function(a,c,d){return b[d].nonStackable?Math.max(Math.abs(n(r(a,c))-n(0)),1)||0:Math.max(Math.abs(n(a.y+a.y0)-n(a.y0)),1)}).attr("x",function(a,c,d){var e=0;return b[d].nonStackable&&(e=a.series*m.rangeBand()/b.length,b.length!==G&&(e=b[d].nonStackableSeries*m.rangeBand()/(2*G))),e}).attr("width",function(a,c,d){if(b[d].nonStackable){var e=m.rangeBand()/G;return b.length!==G&&(e=m.rangeBand()/(2*G)),e}return m.rangeBand()}):R.attr("x",function(a){return a.series*m.rangeBand()/b.length}).attr("width",m.rangeBand()/b.length).attr("y",function(a,b){return r(a,b)<0?n(0):n(0)-n(r(a,b))<1?n(0)-1:n(r(a,b))||0}).attr("height",function(a,b){return Math.max(Math.abs(n(r(a,b))-n(0)),1)||0}),h=m.copy(),i=n.copy(),b[0]&&b[0].values&&(D=b[0].values.length)}),C.renderEnd("multibar immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=d3.scale.ordinal(),n=d3.scale.linear(),o=Math.floor(1e4*Math.random()),p=null,q=function(a){return a.x},r=function(a){return a.y},s=[0],t=!0,u=!1,v="zero",w=a.utils.defaultColor(),x=!1,y=null,z=500,A=.1,B=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),C=a.utils.renderWatch(B,z),D=0;return b.dispatch=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return s},set:function(a){s=a}},stacked:{get:function(){return u},set:function(a){u=a}},stackOffset:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return t},set:function(a){t=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return o},set:function(a){o=a}},hideable:{get:function(){return x},set:function(a){x=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z)}},color:{get:function(){return w},set:function(b){w=a.utils.getColor(b)}},barColor:{get:function(){return y},set:function(b){y=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarChart=function(){"use strict";function b(j){return D.reset(),D.models(e),r&&D.models(f),s&&D.models(g),j.each(function(j){var z=d3.select(this);a.utils.initSVG(z);var D=a.utils.availableWidth(l,z,k),H=a.utils.availableHeight(m,z,k);if(b.update=function(){0===C?z.call(b):z.transition().duration(C).call(b)},b.container=this,x.setter(G(j),b.update).getter(F(j)).update(),x.disabled=j.map(function(a){return!!a.disabled}),!y){var I;y={};for(I in x)y[I]=x[I]instanceof Array?x[I].slice(0):x[I]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,z),b;z.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale(); +var J=z.selectAll("g.nv-wrap.nv-multiBarWithLegend").data([j]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarWithLegend").append("g"),L=J.select("g");if(K.append("g").attr("class","nv-x nv-axis"),K.append("g").attr("class","nv-y nv-axis"),K.append("g").attr("class","nv-barsWrap"),K.append("g").attr("class","nv-legendWrap"),K.append("g").attr("class","nv-controlsWrap"),q&&(h.width(D-B()),L.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),H=a.utils.availableHeight(m,z,k)),L.select(".nv-legendWrap").attr("transform","translate("+B()+","+-k.top+")")),o){var M=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(B()).color(["#444","#444","#444"]),L.select(".nv-controlsWrap").datum(M).attr("transform","translate(0,"+-k.top+")").call(i)}J.attr("transform","translate("+k.left+","+k.top+")"),t&&L.select(".nv-y.nv-axis").attr("transform","translate("+D+",0)"),e.disabled(j.map(function(a){return a.disabled})).width(D).height(H).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var N=L.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(N.call(e),r){f.scale(c)._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-H,0),L.select(".nv-x.nv-axis").attr("transform","translate(0,"+d.range()[0]+")"),L.select(".nv-x.nv-axis").call(f);var O=L.select(".nv-x.nv-axis > g").selectAll("g");if(O.selectAll("line, text").style("opacity",1),v){var P=function(a,b){return"translate("+a+","+b+")"},Q=5,R=17;O.selectAll("text").attr("transform",function(a,b,c){return P(0,c%2==0?Q:R)});var S=d3.selectAll(".nv-x.nv-axis .nv-wrap g g text")[0].length;L.selectAll(".nv-x.nv-axis .nv-axisMaxMin text").attr("transform",function(a,b){return P(0,0===b||S%2!==0?R:Q)})}u&&O.filter(function(a,b){return b%Math.ceil(j[0].values.length/(D/100))!==0}).selectAll("text, line").style("opacity",0),w&&O.selectAll(".tick text").attr("transform","rotate("+w+" 0,0)").style("text-anchor",w>0?"start":"end"),L.select(".nv-x.nv-axis").selectAll("g.nv-axisMaxMin text").style("opacity",1)}s&&(g.scale(d)._ticks(a.utils.calcTicksY(H/36,j)).tickSize(-D,0),L.select(".nv-y.nv-axis").call(g)),h.dispatch.on("stateChange",function(a){for(var c in a)x[c]=a[c];A.stateChange(x),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(M=M.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":case p.grouped:e.stacked(!1);break;case"Stacked":case p.stacked:e.stacked(!0)}x.stacked=e.stacked(),A.stateChange(x),b.update()}}),A.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),x.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),x.stacked=a.stacked,E=a.stacked),b.update()})}),D.renderEnd("multibarchart immediate"),b}var c,d,e=a.models.multiBar(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=!0,v=!1,w=0,x=a.utils.state(),y=null,z=null,A=d3.dispatch("stateChange","changeState","renderEnd"),B=function(){return o?180:0},C=250;x.stacked=!1,e.stacked(!1),f.orient("bottom").tickPadding(7).showMaxMin(!1).tickFormat(function(a){return a}),g.orient(t?"right":"left").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var D=a.utils.renderWatch(A),E=!1,F=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:E}}},G=function(a){return function(b){void 0!==b.stacked&&(E=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=A,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=x,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return y},set:function(a){y=a}},noData:{get:function(){return z},set:function(a){z=a}},reduceXTicks:{get:function(){return u},set:function(a){u=a}},rotateLabels:{get:function(){return w},set:function(a){w=a}},staggerLabels:{get:function(){return v},set:function(a){v=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return C},set:function(a){C=a,e.duration(C),f.duration(C),g.duration(C),D.reset(C)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiBarHorizontal=function(){"use strict";function b(m){return E.reset(),m.each(function(b){var m=k-j.left-j.right,C=l-j.top-j.bottom;n=d3.select(this),a.utils.initSVG(n),w&&(b=d3.layout.stack().offset("zero").values(function(a){return a.values}).y(r)(b)),b.forEach(function(a,b){a.values.forEach(function(c){c.series=b,c.key=a.key})}),w&&b[0].values.map(function(a,c){var d=0,e=0;b.map(function(a){var b=a.values[c];b.size=Math.abs(b.y),b.y<0?(b.y1=e-b.size,e-=b.size):(b.y1=d,d+=b.size)})});var F=d&&e?[]:b.map(function(a){return a.values.map(function(a,b){return{x:q(a,b),y:r(a,b),y0:a.y0,y1:a.y1}})});o.domain(d||d3.merge(F).map(function(a){return a.x})).rangeBands(f||[0,C],A),p.domain(e||d3.extent(d3.merge(F).map(function(a){return w?a.y>0?a.y1+a.y:a.y1:a.y}).concat(t))),p.range(x&&!w?g||[p.domain()[0]<0?z:0,m-(p.domain()[1]>0?z:0)]:g||[0,m]),h=h||o,i=i||d3.scale.linear().domain(p.domain()).range([p(0),p(0)]);{var G=d3.select(this).selectAll("g.nv-wrap.nv-multibarHorizontal").data([b]),H=G.enter().append("g").attr("class","nvd3 nv-wrap nv-multibarHorizontal"),I=(H.append("defs"),H.append("g"));G.select("g")}I.append("g").attr("class","nv-groups"),G.attr("transform","translate("+j.left+","+j.top+")");var J=G.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a,b){return b});J.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),J.exit().watchTransition(E,"multibarhorizontal: exit groups").style("stroke-opacity",1e-6).style("fill-opacity",1e-6).remove(),J.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}).style("fill",function(a,b){return u(a,b)}).style("stroke",function(a,b){return u(a,b)}),J.watchTransition(E,"multibarhorizontal: groups").style("stroke-opacity",1).style("fill-opacity",.75);var K=J.selectAll("g.nv-bar").data(function(a){return a.values});K.exit().remove();var L=K.enter().append("g").attr("transform",function(a,c,d){return"translate("+i(w?a.y0:0)+","+(w?0:d*o.rangeBand()/b.length+o(q(a,c)))+")"});L.append("rect").attr("width",0).attr("height",o.rangeBand()/(w?1:b.length)),K.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),D.elementMouseover({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){d3.select(this).classed("hover",!1),D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mouseout",function(a,b){D.elementMouseout({data:a,index:b,color:d3.select(this).style("fill")})}).on("mousemove",function(a,b){D.elementMousemove({data:a,index:b,color:d3.select(this).style("fill")})}).on("click",function(a,b){D.elementClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}).on("dblclick",function(a,b){D.elementDblClick({data:a,index:b,color:d3.select(this).style("fill")}),d3.event.stopPropagation()}),s(b[0],0)&&(L.append("polyline"),K.select("polyline").attr("fill","none").attr("points",function(a,c){var d=s(a,c),e=.8*o.rangeBand()/(2*(w?1:b.length));d=d.length?d:[-Math.abs(d),Math.abs(d)],d=d.map(function(a){return p(a)-p(0)});var f=[[d[0],-e],[d[0],e],[d[0],0],[d[1],0],[d[1],-e],[d[1],e]];return f.map(function(a){return a.join(",")}).join(" ")}).attr("transform",function(a,c){var d=o.rangeBand()/(2*(w?1:b.length));return"translate("+(r(a,c)<0?0:p(r(a,c))-p(0))+", "+d+")"})),L.append("text"),x&&!w?(K.select("text").attr("text-anchor",function(a,b){return r(a,b)<0?"end":"start"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){var c=B(r(a,b)),d=s(a,b);return void 0===d?c:d.length?c+"+"+B(Math.abs(d[1]))+"-"+B(Math.abs(d[0])):c+"±"+B(Math.abs(d))}),K.watchTransition(E,"multibarhorizontal: bars").select("text").attr("x",function(a,b){return r(a,b)<0?-4:p(r(a,b))-p(0)+4})):K.selectAll("text").text(""),y&&!w?(L.append("text").classed("nv-bar-label",!0),K.select("text.nv-bar-label").attr("text-anchor",function(a,b){return r(a,b)<0?"start":"end"}).attr("y",o.rangeBand()/(2*b.length)).attr("dy",".32em").text(function(a,b){return q(a,b)}),K.watchTransition(E,"multibarhorizontal: bars").select("text.nv-bar-label").attr("x",function(a,b){return r(a,b)<0?p(0)-p(r(a,b))+4:-4})):K.selectAll("text.nv-bar-label").text(""),K.attr("class",function(a,b){return r(a,b)<0?"nv-bar negative":"nv-bar positive"}),v&&(c||(c=b.map(function(){return!0})),K.style("fill",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()}).style("stroke",function(a,b,d){return d3.rgb(v(a,b)).darker(c.map(function(a,b){return b}).filter(function(a,b){return!c[b]})[d]).toString()})),w?K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,b){return"translate("+p(a.y1)+","+o(q(a,b))+")"}).select("rect").attr("width",function(a,b){return Math.abs(p(r(a,b)+a.y0)-p(a.y0))}).attr("height",o.rangeBand()):K.watchTransition(E,"multibarhorizontal: bars").attr("transform",function(a,c){return"translate("+p(r(a,c)<0?r(a,c):0)+","+(a.series*o.rangeBand()/b.length+o(q(a,c)))+")"}).select("rect").attr("height",o.rangeBand()/b.length).attr("width",function(a,b){return Math.max(Math.abs(p(r(a,b))-p(0)),1)}),h=o.copy(),i=p.copy()}),E.renderEnd("multibarHorizontal immediate"),b}var c,d,e,f,g,h,i,j={top:0,right:0,bottom:0,left:0},k=960,l=500,m=Math.floor(1e4*Math.random()),n=null,o=d3.scale.ordinal(),p=d3.scale.linear(),q=function(a){return a.x},r=function(a){return a.y},s=function(a){return a.yErr},t=[0],u=a.utils.defaultColor(),v=null,w=!1,x=!1,y=!1,z=60,A=.1,B=d3.format(",.2f"),C=250,D=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),E=a.utils.renderWatch(D,C);return b.dispatch=D,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},x:{get:function(){return q},set:function(a){q=a}},y:{get:function(){return r},set:function(a){r=a}},yErr:{get:function(){return s},set:function(a){s=a}},xScale:{get:function(){return o},set:function(a){o=a}},yScale:{get:function(){return p},set:function(a){p=a}},xDomain:{get:function(){return d},set:function(a){d=a}},yDomain:{get:function(){return e},set:function(a){e=a}},xRange:{get:function(){return f},set:function(a){f=a}},yRange:{get:function(){return g},set:function(a){g=a}},forceY:{get:function(){return t},set:function(a){t=a}},stacked:{get:function(){return w},set:function(a){w=a}},showValues:{get:function(){return x},set:function(a){x=a}},disabled:{get:function(){return c},set:function(a){c=a}},id:{get:function(){return m},set:function(a){m=a}},valueFormat:{get:function(){return B},set:function(a){B=a}},valuePadding:{get:function(){return z},set:function(a){z=a}},groupSpacing:{get:function(){return A},set:function(a){A=a}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},duration:{get:function(){return C},set:function(a){C=a,E.reset(C)}},color:{get:function(){return u},set:function(b){u=a.utils.getColor(b)}},barColor:{get:function(){return v},set:function(b){v=b?a.utils.getColor(b):null}}}),a.utils.initOptions(b),b},a.models.multiBarHorizontalChart=function(){"use strict";function b(j){return C.reset(),C.models(e),r&&C.models(f),s&&C.models(g),j.each(function(j){var w=d3.select(this);a.utils.initSVG(w);var C=a.utils.availableWidth(l,w,k),D=a.utils.availableHeight(m,w,k);if(b.update=function(){w.transition().duration(z).call(b)},b.container=this,t=e.stacked(),u.setter(B(j),b.update).getter(A(j)).update(),u.disabled=j.map(function(a){return!!a.disabled}),!v){var E;v={};for(E in u)v[E]=u[E]instanceof Array?u[E].slice(0):u[E]}if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,w),b;w.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var F=w.selectAll("g.nv-wrap.nv-multiBarHorizontalChart").data([j]),G=F.enter().append("g").attr("class","nvd3 nv-wrap nv-multiBarHorizontalChart").append("g"),H=F.select("g");if(G.append("g").attr("class","nv-x nv-axis"),G.append("g").attr("class","nv-y nv-axis").append("g").attr("class","nv-zeroLine").append("line"),G.append("g").attr("class","nv-barsWrap"),G.append("g").attr("class","nv-legendWrap"),G.append("g").attr("class","nv-controlsWrap"),q&&(h.width(C-y()),H.select(".nv-legendWrap").datum(j).call(h),k.top!=h.height()&&(k.top=h.height(),D=a.utils.availableHeight(m,w,k)),H.select(".nv-legendWrap").attr("transform","translate("+y()+","+-k.top+")")),o){var I=[{key:p.grouped||"Grouped",disabled:e.stacked()},{key:p.stacked||"Stacked",disabled:!e.stacked()}];i.width(y()).color(["#444","#444","#444"]),H.select(".nv-controlsWrap").datum(I).attr("transform","translate(0,"+-k.top+")").call(i)}F.attr("transform","translate("+k.left+","+k.top+")"),e.disabled(j.map(function(a){return a.disabled})).width(C).height(D).color(j.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!j[b].disabled}));var J=H.select(".nv-barsWrap").datum(j.filter(function(a){return!a.disabled}));if(J.transition().call(e),r){f.scale(c)._ticks(a.utils.calcTicksY(D/24,j)).tickSize(-C,0),H.select(".nv-x.nv-axis").call(f);var K=H.select(".nv-x.nv-axis").selectAll("g");K.selectAll("line, text")}s&&(g.scale(d)._ticks(a.utils.calcTicksX(C/100,j)).tickSize(-D,0),H.select(".nv-y.nv-axis").attr("transform","translate(0,"+D+")"),H.select(".nv-y.nv-axis").call(g)),H.select(".nv-zeroLine line").attr("x1",d(0)).attr("x2",d(0)).attr("y1",0).attr("y2",-D),h.dispatch.on("stateChange",function(a){for(var c in a)u[c]=a[c];x.stateChange(u),b.update()}),i.dispatch.on("legendClick",function(a){if(a.disabled){switch(I=I.map(function(a){return a.disabled=!0,a}),a.disabled=!1,a.key){case"Grouped":e.stacked(!1);break;case"Stacked":e.stacked(!0)}u.stacked=e.stacked(),x.stateChange(u),t=e.stacked(),b.update()}}),x.on("changeState",function(a){"undefined"!=typeof a.disabled&&(j.forEach(function(b,c){b.disabled=a.disabled[c]}),u.disabled=a.disabled),"undefined"!=typeof a.stacked&&(e.stacked(a.stacked),u.stacked=a.stacked,t=a.stacked),b.update()})}),C.renderEnd("multibar horizontal chart immediate"),b}var c,d,e=a.models.multiBarHorizontal(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend().height(30),i=a.models.legend().height(30),j=a.models.tooltip(),k={top:30,right:20,bottom:50,left:60},l=null,m=null,n=a.utils.defaultColor(),o=!0,p={},q=!0,r=!0,s=!0,t=!1,u=a.utils.state(),v=null,w=null,x=d3.dispatch("stateChange","changeState","renderEnd"),y=function(){return o?180:0},z=250;u.stacked=!1,e.stacked(t),f.orient("left").tickPadding(5).showMaxMin(!1).tickFormat(function(a){return a}),g.orient("bottom").tickFormat(d3.format(",.1f")),j.duration(0).valueFormatter(function(a,b){return g.tickFormat()(a,b)}).headerFormatter(function(a,b){return f.tickFormat()(a,b)}),i.updateState(!1);var A=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),stacked:t}}},B=function(a){return function(b){void 0!==b.stacked&&(t=b.stacked),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},C=a.utils.renderWatch(x,z);return e.dispatch.on("elementMouseover.tooltip",function(a){a.value=b.x()(a.data),a.series={key:a.data.key,value:b.y()(a.data),color:a.color},j.data(a).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){j.hidden(!0)}),e.dispatch.on("elementMousemove.tooltip",function(){j.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=x,b.multibar=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.state=u,b.tooltip=j,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return l},set:function(a){l=a}},height:{get:function(){return m},set:function(a){m=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showControls:{get:function(){return o},set:function(a){o=a}},controlLabels:{get:function(){return p},set:function(a){p=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return v},set:function(a){v=a}},noData:{get:function(){return w},set:function(a){w=a}},tooltips:{get:function(){return j.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),j.enabled(!!b)}},tooltipContent:{get:function(){return j.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),j.contentGenerator(b)}},margin:{get:function(){return k},set:function(a){k.top=void 0!==a.top?a.top:k.top,k.right=void 0!==a.right?a.right:k.right,k.bottom=void 0!==a.bottom?a.bottom:k.bottom,k.left=void 0!==a.left?a.left:k.left}},duration:{get:function(){return z},set:function(a){z=a,C.reset(z),e.duration(z),f.duration(z),g.duration(z)}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),h.color(n)}},barColor:{get:function(){return e.barColor},set:function(a){e.barColor(a),h.color(function(a,b){return d3.rgb("#ccc").darker(1.5*b).toString()})}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.multiChart=function(){"use strict";function b(j){return j.each(function(j){function k(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.value=a.point.x,a.series={value:a.point.y,color:a.point.color},B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function l(a){var b=2===j[a.seriesIndex].yAxis?z:y;a.point.x=v.x()(a.point),a.point.y=v.y()(a.point),B.duration(100).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).position(a.pos).hidden(!1)}function n(a){var b=2===j[a.data.series].yAxis?z:y;a.value=t.x()(a.data),a.series={value:t.y()(a.data),color:a.color},B.duration(0).valueFormatter(function(a,c){return b.tickFormat()(a,c)}).data(a).hidden(!1)}var C=d3.select(this);a.utils.initSVG(C),b.update=function(){C.transition().call(b)},b.container=this;var D=a.utils.availableWidth(g,C,e),E=a.utils.availableHeight(h,C,e),F=j.filter(function(a){return"line"==a.type&&1==a.yAxis}),G=j.filter(function(a){return"line"==a.type&&2==a.yAxis}),H=j.filter(function(a){return"bar"==a.type&&1==a.yAxis}),I=j.filter(function(a){return"bar"==a.type&&2==a.yAxis}),J=j.filter(function(a){return"area"==a.type&&1==a.yAxis}),K=j.filter(function(a){return"area"==a.type&&2==a.yAxis});if(!(j&&j.length&&j.filter(function(a){return a.values.length}).length))return a.utils.noData(b,C),b;C.selectAll(".nv-noData").remove();var L=j.filter(function(a){return!a.disabled&&1==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})}),M=j.filter(function(a){return!a.disabled&&2==a.yAxis}).map(function(a){return a.values.map(function(a){return{x:a.x,y:a.y}})});o.domain(d3.extent(d3.merge(L.concat(M)),function(a){return a.x})).range([0,D]);var N=C.selectAll("g.wrap.multiChart").data([j]),O=N.enter().append("g").attr("class","wrap nvd3 multiChart").append("g");O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y1 nv-axis"),O.append("g").attr("class","nv-y2 nv-axis"),O.append("g").attr("class","lines1Wrap"),O.append("g").attr("class","lines2Wrap"),O.append("g").attr("class","bars1Wrap"),O.append("g").attr("class","bars2Wrap"),O.append("g").attr("class","stack1Wrap"),O.append("g").attr("class","stack2Wrap"),O.append("g").attr("class","legendWrap");var P=N.select("g"),Q=j.map(function(a,b){return j[b].color||f(a,b)});if(i){var R=A.align()?D/2:D,S=A.align()?R:0;A.width(R),A.color(Q),P.select(".legendWrap").datum(j.map(function(a){return a.originalKey=void 0===a.originalKey?a.key:a.originalKey,a.key=a.originalKey+(1==a.yAxis?"":" (right axis)"),a})).call(A),e.top!=A.height()&&(e.top=A.height(),E=a.utils.availableHeight(h,C,e)),P.select(".legendWrap").attr("transform","translate("+S+","+-e.top+")")}r.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"line"==j[b].type})),s.width(D).height(E).interpolate(m).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"line"==j[b].type})),t.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"bar"==j[b].type})),u.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"bar"==j[b].type})),v.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&1==j[b].yAxis&&"area"==j[b].type})),w.width(D).height(E).color(Q.filter(function(a,b){return!j[b].disabled&&2==j[b].yAxis&&"area"==j[b].type})),P.attr("transform","translate("+e.left+","+e.top+")");var T=P.select(".lines1Wrap").datum(F.filter(function(a){return!a.disabled})),U=P.select(".bars1Wrap").datum(H.filter(function(a){return!a.disabled})),V=P.select(".stack1Wrap").datum(J.filter(function(a){return!a.disabled})),W=P.select(".lines2Wrap").datum(G.filter(function(a){return!a.disabled})),X=P.select(".bars2Wrap").datum(I.filter(function(a){return!a.disabled})),Y=P.select(".stack2Wrap").datum(K.filter(function(a){return!a.disabled})),Z=J.length?J.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[],$=K.length?K.map(function(a){return a.values}).reduce(function(a,b){return a.map(function(a,c){return{x:a.x,y:a.y+b[c].y}})}).concat([{x:0,y:0}]):[];p.domain(c||d3.extent(d3.merge(L).concat(Z),function(a){return a.y})).range([0,E]),q.domain(d||d3.extent(d3.merge(M).concat($),function(a){return a.y})).range([0,E]),r.yDomain(p.domain()),t.yDomain(p.domain()),v.yDomain(p.domain()),s.yDomain(q.domain()),u.yDomain(q.domain()),w.yDomain(q.domain()),J.length&&d3.transition(V).call(v),K.length&&d3.transition(Y).call(w),H.length&&d3.transition(U).call(t),I.length&&d3.transition(X).call(u),F.length&&d3.transition(T).call(r),G.length&&d3.transition(W).call(s),x._ticks(a.utils.calcTicksX(D/100,j)).tickSize(-E,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+E+")"),d3.transition(P.select(".nv-x.nv-axis")).call(x),y._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y1.nv-axis")).call(y),z._ticks(a.utils.calcTicksY(E/36,j)).tickSize(-D,0),d3.transition(P.select(".nv-y2.nv-axis")).call(z),P.select(".nv-y1.nv-axis").classed("nv-disabled",L.length?!1:!0).attr("transform","translate("+o.range()[0]+",0)"),P.select(".nv-y2.nv-axis").classed("nv-disabled",M.length?!1:!0).attr("transform","translate("+o.range()[1]+",0)"),A.dispatch.on("stateChange",function(){b.update()}),r.dispatch.on("elementMouseover.tooltip",k),s.dispatch.on("elementMouseover.tooltip",k),r.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),s.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),v.dispatch.on("elementMouseover.tooltip",l),w.dispatch.on("elementMouseover.tooltip",l),v.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),w.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMouseover.tooltip",n),u.dispatch.on("elementMouseover.tooltip",n),t.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),u.dispatch.on("elementMouseout.tooltip",function(){B.hidden(!0)}),t.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()}),u.dispatch.on("elementMousemove.tooltip",function(){B.position({top:d3.event.pageY,left:d3.event.pageX})()})}),b}var c,d,e={top:30,right:20,bottom:50,left:60},f=a.utils.defaultColor(),g=null,h=null,i=!0,j=null,k=function(a){return a.x},l=function(a){return a.y},m="monotone",n=!0,o=d3.scale.linear(),p=d3.scale.linear(),q=d3.scale.linear(),r=a.models.line().yScale(p),s=a.models.line().yScale(q),t=a.models.multiBar().stacked(!1).yScale(p),u=a.models.multiBar().stacked(!1).yScale(q),v=a.models.stackedArea().yScale(p),w=a.models.stackedArea().yScale(q),x=a.models.axis().scale(o).orient("bottom").tickPadding(5),y=a.models.axis().scale(p).orient("left"),z=a.models.axis().scale(q).orient("right"),A=a.models.legend().height(30),B=a.models.tooltip(),C=d3.dispatch();return b.dispatch=C,b.lines1=r,b.lines2=s,b.bars1=t,b.bars2=u,b.stack1=v,b.stack2=w,b.xAxis=x,b.yAxis1=y,b.yAxis2=z,b.tooltip=B,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},showLegend:{get:function(){return i},set:function(a){i=a}},yDomain1:{get:function(){return c},set:function(a){c=a}},yDomain2:{get:function(){return d},set:function(a){d=a}},noData:{get:function(){return j},set:function(a){j=a}},interpolate:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return B.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),B.enabled(!!b)}},tooltipContent:{get:function(){return B.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),B.contentGenerator(b)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return f},set:function(b){f=a.utils.getColor(b)}},x:{get:function(){return k},set:function(a){k=a,r.x(a),s.x(a),t.x(a),u.x(a),v.x(a),w.x(a)}},y:{get:function(){return l},set:function(a){l=a,r.y(a),s.y(a),v.y(a),w.y(a),t.y(a),u.y(a)}},useVoronoi:{get:function(){return n},set:function(a){n=a,r.useVoronoi(a),s.useVoronoi(a),v.useVoronoi(a),w.useVoronoi(a)}}}),a.utils.initOptions(b),b},a.models.ohlcBar=function(){"use strict";function b(y){return y.each(function(b){k=d3.select(this);var y=a.utils.availableWidth(h,k,g),A=a.utils.availableHeight(i,k,g);a.utils.initSVG(k);var B=y/b[0].values.length*.9;l.domain(c||d3.extent(b[0].values.map(n).concat(t))),l.range(v?e||[.5*y/b[0].values.length,y*(b[0].values.length-.5)/b[0].values.length]:e||[5+B/2,y-B/2-5]),m.domain(d||[d3.min(b[0].values.map(s).concat(u)),d3.max(b[0].values.map(r).concat(u))]).range(f||[A,0]),l.domain()[0]===l.domain()[1]&&l.domain(l.domain()[0]?[l.domain()[0]-.01*l.domain()[0],l.domain()[1]+.01*l.domain()[1]]:[-1,1]),m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]+.01*m.domain()[0],m.domain()[1]-.01*m.domain()[1]]:[-1,1]);var C=d3.select(this).selectAll("g.nv-wrap.nv-ohlcBar").data([b[0].values]),D=C.enter().append("g").attr("class","nvd3 nv-wrap nv-ohlcBar"),E=D.append("defs"),F=D.append("g"),G=C.select("g");F.append("g").attr("class","nv-ticks"),C.attr("transform","translate("+g.left+","+g.top+")"),k.on("click",function(a,b){z.chartClick({data:a,index:b,pos:d3.event,id:j})}),E.append("clipPath").attr("id","nv-chart-clip-path-"+j).append("rect"),C.select("#nv-chart-clip-path-"+j+" rect").attr("width",y).attr("height",A),G.attr("clip-path",w?"url(#nv-chart-clip-path-"+j+")":"");var H=C.select(".nv-ticks").selectAll(".nv-tick").data(function(a){return a});H.exit().remove(),H.enter().append("path").attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}).attr("d",function(a,b){return"m0,0l0,"+(m(p(a,b))-m(r(a,b)))+"l"+-B/2+",0l"+B/2+",0l0,"+(m(s(a,b))-m(p(a,b)))+"l0,"+(m(q(a,b))-m(s(a,b)))+"l"+B/2+",0l"+-B/2+",0z"}).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("fill",function(){return x[0]}).attr("stroke",function(){return x[0]}).attr("x",0).attr("y",function(a,b){return m(Math.max(0,o(a,b)))}).attr("height",function(a,b){return Math.abs(m(o(a,b))-m(0))}),H.attr("class",function(a,b,c){return(p(a,b)>q(a,b)?"nv-tick negative":"nv-tick positive")+" nv-tick-"+c+"-"+b}),d3.transition(H).attr("transform",function(a,b){return"translate("+l(n(a,b))+","+m(r(a,b))+")"}).attr("d",function(a,c){var d=y/b[0].values.length*.9;return"m0,0l0,"+(m(p(a,c))-m(r(a,c)))+"l"+-d/2+",0l"+d/2+",0l0,"+(m(s(a,c))-m(p(a,c)))+"l0,"+(m(q(a,c))-m(s(a,c)))+"l"+d/2+",0l"+-d/2+",0z"})}),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=Math.floor(1e4*Math.random()),k=null,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=function(a){return a.open},q=function(a){return a.close},r=function(a){return a.high},s=function(a){return a.low},t=[],u=[],v=!1,w=!0,x=a.utils.defaultColor(),y=!1,z=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd","chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove");return b.highlightPoint=function(a,c){b.clearHighlights(),k.select(".nv-ohlcBar .nv-tick-0-"+a).classed("hover",c)},b.clearHighlights=function(){k.select(".nv-ohlcBar .nv-tick.hover").classed("hover",!1)},b.dispatch=z,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},padData:{get:function(){return v},set:function(a){v=a}},clipEdge:{get:function(){return w},set:function(a){w=a}},id:{get:function(){return j},set:function(a){j=a}},interactive:{get:function(){return y},set:function(a){y=a}},x:{get:function(){return n},set:function(a){n=a}},y:{get:function(){return o},set:function(a){o=a}},open:{get:function(){return p()},set:function(a){p=a}},close:{get:function(){return q()},set:function(a){q=a}},high:{get:function(){return r},set:function(a){r=a}},low:{get:function(){return s},set:function(a){s=a}},margin:{get:function(){return g},set:function(a){g.top=void 0!=a.top?a.top:g.top,g.right=void 0!=a.right?a.right:g.right,g.bottom=void 0!=a.bottom?a.bottom:g.bottom,g.left=void 0!=a.left?a.left:g.left +}},color:{get:function(){return x},set:function(b){x=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.parallelCoordinates=function(){"use strict";function b(p){return p.each(function(b){function p(a){return F(h.map(function(b){if(isNaN(a[b])||isNaN(parseFloat(a[b]))){var c=g[b].domain(),d=g[b].range(),e=c[0]-(c[1]-c[0])/9;if(J.indexOf(b)<0){var h=d3.scale.linear().domain([e,c[1]]).range([x-12,d[1]]);g[b].brush.y(h),J.push(b)}return[f(b),g[b](e)]}return J.length>0?(D.style("display","inline"),E.style("display","inline")):(D.style("display","none"),E.style("display","none")),[f(b),g[b](a[b])]}))}function q(){var a=h.filter(function(a){return!g[a].brush.empty()}),b=a.map(function(a){return g[a].brush.extent()});k=[],a.forEach(function(a,c){k[c]={dimension:a,extent:b[c]}}),l=[],M.style("display",function(c){var d=a.every(function(a,d){return isNaN(c[a])&&b[d][0]==g[a].brush.y().domain()[0]?!0:b[d][0]<=c[a]&&c[a]<=b[d][1]});return d&&l.push(c),d?null:"none"}),o.brush({filters:k,active:l})}function r(a){m[a]=this.parentNode.__origin__=f(a),L.attr("visibility","hidden")}function s(a){m[a]=Math.min(w,Math.max(0,this.parentNode.__origin__+=d3.event.x)),M.attr("d",p),h.sort(function(a,b){return u(a)-u(b)}),f.domain(h),N.attr("transform",function(a){return"translate("+u(a)+")"})}function t(a){delete this.parentNode.__origin__,delete m[a],d3.select(this.parentNode).attr("transform","translate("+f(a)+")"),M.attr("d",p),L.attr("d",p).attr("visibility",null)}function u(a){var b=m[a];return null==b?f(a):b}var v=d3.select(this),w=a.utils.availableWidth(d,v,c),x=a.utils.availableHeight(e,v,c);a.utils.initSVG(v),l=b,f.rangePoints([0,w],1).domain(h);var y={};h.forEach(function(a){var c=d3.extent(b,function(b){return+b[a]});return y[a]=!1,void 0===c[0]&&(y[a]=!0,c[0]=0,c[1]=0),c[0]===c[1]&&(c[0]=c[0]-1,c[1]=c[1]+1),g[a]=d3.scale.linear().domain(c).range([.9*(x-12),0]),g[a].brush=d3.svg.brush().y(g[a]).on("brush",q),"name"!=a});var z=v.selectAll("g.nv-wrap.nv-parallelCoordinates").data([b]),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-parallelCoordinates"),B=A.append("g"),C=z.select("g");B.append("g").attr("class","nv-parallelCoordinates background"),B.append("g").attr("class","nv-parallelCoordinates foreground"),B.append("g").attr("class","nv-parallelCoordinates missingValuesline"),z.attr("transform","translate("+c.left+","+c.top+")");var D,E,F=d3.svg.line().interpolate("cardinal").tension(n),G=d3.svg.axis().orient("left"),H=d3.behavior.drag().on("dragstart",r).on("drag",s).on("dragend",t),I=f.range()[1]-f.range()[0],J=[],K=[0+I/2,x-12,w-I/2,x-12];D=z.select(".missingValuesline").selectAll("line").data([K]),D.enter().append("line"),D.exit().remove(),D.attr("x1",function(a){return a[0]}).attr("y1",function(a){return a[1]}).attr("x2",function(a){return a[2]}).attr("y2",function(a){return a[3]}),E=z.select(".missingValuesline").selectAll("text").data(["undefined values"]),E.append("text").data(["undefined values"]),E.enter().append("text"),E.exit().remove(),E.attr("y",x).attr("x",w-92-I/2).text(function(a){return a});var L=z.select(".background").selectAll("path").data(b);L.enter().append("path"),L.exit().remove(),L.attr("d",p);var M=z.select(".foreground").selectAll("path").data(b);M.enter().append("path"),M.exit().remove(),M.attr("d",p).attr("stroke",j),M.on("mouseover",function(a,b){d3.select(this).classed("hover",!0),o.elementMouseover({label:a.name,data:a.data,index:b,pos:[d3.mouse(this.parentNode)[0],d3.mouse(this.parentNode)[1]]})}),M.on("mouseout",function(a,b){d3.select(this).classed("hover",!1),o.elementMouseout({label:a.name,data:a.data,index:b})});var N=C.selectAll(".dimension").data(h),O=N.enter().append("g").attr("class","nv-parallelCoordinates dimension");O.append("g").attr("class","nv-parallelCoordinates nv-axis"),O.append("g").attr("class","nv-parallelCoordinates-brush"),O.append("text").attr("class","nv-parallelCoordinates nv-label"),N.attr("transform",function(a){return"translate("+f(a)+",0)"}),N.exit().remove(),N.select(".nv-label").style("cursor","move").attr("dy","-1em").attr("text-anchor","middle").text(String).on("mouseover",function(a){o.elementMouseover({dim:a,pos:[d3.mouse(this.parentNode.parentNode)[0],d3.mouse(this.parentNode.parentNode)[1]]})}).on("mouseout",function(a){o.elementMouseout({dim:a})}).call(H),N.select(".nv-axis").each(function(a,b){d3.select(this).call(G.scale(g[a]).tickFormat(d3.format(i[b])))}),N.select(".nv-parallelCoordinates-brush").each(function(a){d3.select(this).call(g[a].brush)}).selectAll("rect").attr("x",-8).attr("width",16)}),b}var c={top:30,right:0,bottom:10,left:0},d=null,e=null,f=d3.scale.ordinal(),g={},h=[],i=[],j=a.utils.defaultColor(),k=[],l=[],m=[],n=1,o=d3.dispatch("brush","elementMouseover","elementMouseout");return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},dimensionNames:{get:function(){return h},set:function(a){h=a}},dimensionFormats:{get:function(){return i},set:function(a){i=a}},lineTension:{get:function(){return n},set:function(a){n=a}},dimensions:{get:function(){return h},set:function(b){a.deprecated("dimensions","use dimensionNames instead"),h=b}},margin:{get:function(){return c},set:function(a){c.top=void 0!==a.top?a.top:c.top,c.right=void 0!==a.right?a.right:c.right,c.bottom=void 0!==a.bottom?a.bottom:c.bottom,c.left=void 0!==a.left?a.left:c.left}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.pie=function(){"use strict";function b(E){return D.reset(),E.each(function(b){function E(a,b){a.endAngle=isNaN(a.endAngle)?0:a.endAngle,a.startAngle=isNaN(a.startAngle)?0:a.startAngle,p||(a.innerRadius=0);var c=d3.interpolate(this._current,a);return this._current=c(0),function(a){return B[b](c(a))}}var F=d-c.left-c.right,G=e-c.top-c.bottom,H=Math.min(F,G)/2,I=[],J=[];if(i=d3.select(this),0===z.length)for(var K=H-H/5,L=y*H,M=0;Mc)return"";if("function"==typeof n)d=n(a,b,{key:f(a.data),value:g(a.data),percent:k(c)});else switch(n){case"key":d=f(a.data);break;case"value":d=k(g(a.data));break;case"percent":d=d3.format("%")(c)}return d})}}),D.renderEnd("pie immediate"),b}var c={top:0,right:0,bottom:0,left:0},d=500,e=500,f=function(a){return a.x},g=function(a){return a.y},h=Math.floor(1e4*Math.random()),i=null,j=a.utils.defaultColor(),k=d3.format(",.2f"),l=!0,m=!1,n="key",o=.02,p=!1,q=!1,r=!0,s=0,t=!1,u=!1,v=!1,w=!1,x=0,y=.5,z=[],A=d3.dispatch("chartClick","elementClick","elementDblClick","elementMouseover","elementMouseout","elementMousemove","renderEnd"),B=[],C=[],D=a.utils.renderWatch(A);return b.dispatch=A,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{arcsRadius:{get:function(){return z},set:function(a){z=a}},width:{get:function(){return d},set:function(a){d=a}},height:{get:function(){return e},set:function(a){e=a}},showLabels:{get:function(){return l},set:function(a){l=a}},title:{get:function(){return q},set:function(a){q=a}},titleOffset:{get:function(){return s},set:function(a){s=a}},labelThreshold:{get:function(){return o},set:function(a){o=a}},valueFormat:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return f},set:function(a){f=a}},id:{get:function(){return h},set:function(a){h=a}},endAngle:{get:function(){return w},set:function(a){w=a}},startAngle:{get:function(){return u},set:function(a){u=a}},padAngle:{get:function(){return v},set:function(a){v=a}},cornerRadius:{get:function(){return x},set:function(a){x=a}},donutRatio:{get:function(){return y},set:function(a){y=a}},labelsOutside:{get:function(){return m},set:function(a){m=a}},labelSunbeamLayout:{get:function(){return t},set:function(a){t=a}},donut:{get:function(){return p},set:function(a){p=a}},growOnHover:{get:function(){return r},set:function(a){r=a}},pieLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("pieLabelsOutside","use labelsOutside instead")}},donutLabelsOutside:{get:function(){return m},set:function(b){m=b,a.deprecated("donutLabelsOutside","use labelsOutside instead")}},labelFormat:{get:function(){return k},set:function(b){k=b,a.deprecated("labelFormat","use valueFormat instead")}},margin:{get:function(){return c},set:function(a){c.top="undefined"!=typeof a.top?a.top:c.top,c.right="undefined"!=typeof a.right?a.right:c.right,c.bottom="undefined"!=typeof a.bottom?a.bottom:c.bottom,c.left="undefined"!=typeof a.left?a.left:c.left}},y:{get:function(){return g},set:function(a){g=d3.functor(a)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},labelType:{get:function(){return n},set:function(a){n=a||"key"}}}),a.utils.initOptions(b),b},a.models.pieChart=function(){"use strict";function b(e){return q.reset(),q.models(c),e.each(function(e){var k=d3.select(this);a.utils.initSVG(k);var n=a.utils.availableWidth(g,k,f),o=a.utils.availableHeight(h,k,f);if(b.update=function(){k.transition().call(b)},b.container=this,l.setter(s(e),b.update).getter(r(e)).update(),l.disabled=e.map(function(a){return!!a.disabled}),!m){var q;m={};for(q in l)m[q]=l[q]instanceof Array?l[q].slice(0):l[q]}if(!e||!e.length)return a.utils.noData(b,k),b;k.selectAll(".nv-noData").remove();var t=k.selectAll("g.nv-wrap.nv-pieChart").data([e]),u=t.enter().append("g").attr("class","nvd3 nv-wrap nv-pieChart").append("g"),v=t.select("g");if(u.append("g").attr("class","nv-pieWrap"),u.append("g").attr("class","nv-legendWrap"),i)if("top"===j)d.width(n).key(c.x()),t.select(".nv-legendWrap").datum(e).call(d),f.top!=d.height()&&(f.top=d.height(),o=a.utils.availableHeight(h,k,f)),t.select(".nv-legendWrap").attr("transform","translate(0,"+-f.top+")");else if("right"===j){var w=a.models.legend().width();w>n/2&&(w=n/2),d.height(o).key(c.x()),d.width(w),n-=d.width(),t.select(".nv-legendWrap").datum(e).call(d).attr("transform","translate("+n+",0)")}t.attr("transform","translate("+f.left+","+f.top+")"),c.width(n).height(o);var x=v.select(".nv-pieWrap").datum([e]);d3.transition(x).call(c),d.dispatch.on("stateChange",function(a){for(var c in a)l[c]=a[c];p.stateChange(l),b.update()}),p.on("changeState",function(a){"undefined"!=typeof a.disabled&&(e.forEach(function(b,c){b.disabled=a.disabled[c]}),l.disabled=a.disabled),b.update()})}),q.renderEnd("pieChart immediate"),b}var c=a.models.pie(),d=a.models.legend(),e=a.models.tooltip(),f={top:30,right:20,bottom:20,left:20},g=null,h=null,i=!0,j="top",k=a.utils.defaultColor(),l=a.utils.state(),m=null,n=null,o=250,p=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd");e.headerEnabled(!1).duration(0).valueFormatter(function(a,b){return c.valueFormat()(a,b)});var q=a.utils.renderWatch(p),r=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},s=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:b.x()(a.data),value:b.y()(a.data),color:a.color},e.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){e.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){e.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.legend=d,b.dispatch=p,b.pie=c,b.tooltip=e,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return i},set:function(a){i=a}},legendPosition:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return m},set:function(a){m=a}},tooltips:{get:function(){return e.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),e.enabled(!!b)}},tooltipContent:{get:function(){return e.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),e.contentGenerator(b)}},color:{get:function(){return k},set:function(a){k=a,d.color(k),c.color(k)}},duration:{get:function(){return o},set:function(a){o=a,q.reset(o)}},margin:{get:function(){return f},set:function(a){f.top=void 0!==a.top?a.top:f.top,f.right=void 0!==a.right?a.right:f.right,f.bottom=void 0!==a.bottom?a.bottom:f.bottom,f.left=void 0!==a.left?a.left:f.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.scatter=function(){"use strict";function b(N){return P.reset(),N.each(function(b){function N(){if(O=!1,!w)return!1;if(M===!0){var a=d3.merge(b.map(function(a,b){return a.values.map(function(a,c){var d=p(a,c),e=q(a,c);return[m(d)+1e-4*Math.random(),n(e)+1e-4*Math.random(),b,c,a]}).filter(function(a,b){return x(a[4],b)})}));if(0==a.length)return!1;a.length<3&&(a.push([m.range()[0]-20,n.range()[0]-20,null,null]),a.push([m.range()[1]+20,n.range()[1]+20,null,null]),a.push([m.range()[0]-20,n.range()[0]+20,null,null]),a.push([m.range()[1]+20,n.range()[1]-20,null,null]));var c=d3.geom.polygon([[-10,-10],[-10,i+10],[h+10,i+10],[h+10,-10]]),d=d3.geom.voronoi(a).map(function(b,d){return{data:c.clip(b),series:a[d][2],point:a[d][3]}});U.select(".nv-point-paths").selectAll("path").remove();var e=U.select(".nv-point-paths").selectAll("path").data(d),f=e.enter().append("svg:path").attr("d",function(a){return a&&a.data&&0!==a.data.length?"M"+a.data.join(",")+"Z":"M 0 0"}).attr("id",function(a,b){return"nv-path-"+b}).attr("clip-path",function(a,b){return"url(#nv-clip-"+b+")"});C&&f.style("fill",d3.rgb(230,230,230)).style("fill-opacity",.4).style("stroke-opacity",1).style("stroke",d3.rgb(200,200,200)),B&&(U.select(".nv-point-clips").selectAll("clipPath").remove(),U.select(".nv-point-clips").selectAll("clipPath").data(a).enter().append("svg:clipPath").attr("id",function(a,b){return"nv-clip-"+b}).append("svg:circle").attr("cx",function(a){return a[0]}).attr("cy",function(a){return a[1]}).attr("r",D));var k=function(a,c){if(O)return 0;var d=b[a.series];if(void 0!==d){var e=d.values[a.point];e.color=j(d,a.series),e.x=p(e),e.y=q(e);var f=l.node().getBoundingClientRect(),h=window.pageYOffset||document.documentElement.scrollTop,i=window.pageXOffset||document.documentElement.scrollLeft,k={left:m(p(e,a.point))+f.left+i+g.left+10,top:n(q(e,a.point))+f.top+h+g.top+10};c({point:e,series:d,pos:k,seriesIndex:a.series,pointIndex:a.point})}};e.on("click",function(a){k(a,L.elementClick)}).on("dblclick",function(a){k(a,L.elementDblClick)}).on("mouseover",function(a){k(a,L.elementMouseover)}).on("mouseout",function(a){k(a,L.elementMouseout)})}else U.select(".nv-groups").selectAll(".nv-group").selectAll(".nv-point").on("click",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("dblclick",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementDblClick({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c})}).on("mouseover",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseover({point:e,series:d,pos:[m(p(e,c))+g.left,n(q(e,c))+g.top],seriesIndex:a.series,pointIndex:c,color:j(a,c)})}).on("mouseout",function(a,c){if(O||!b[a.series])return 0;var d=b[a.series],e=d.values[c];L.elementMouseout({point:e,series:d,seriesIndex:a.series,pointIndex:c,color:j(a,c)})})}l=d3.select(this);var R=a.utils.availableWidth(h,l,g),S=a.utils.availableHeight(i,l,g);a.utils.initSVG(l),b.forEach(function(a,b){a.values.forEach(function(a){a.series=b})});var T=E&&F&&I?[]:d3.merge(b.map(function(a){return a.values.map(function(a,b){return{x:p(a,b),y:q(a,b),size:r(a,b)}})}));m.domain(E||d3.extent(T.map(function(a){return a.x}).concat(t))),m.range(y&&b[0]?G||[(R*z+R)/(2*b[0].values.length),R-R*(1+z)/(2*b[0].values.length)]:G||[0,R]),n.domain(F||d3.extent(T.map(function(a){return a.y}).concat(u))).range(H||[S,0]),o.domain(I||d3.extent(T.map(function(a){return a.size}).concat(v))).range(J||Q),K=m.domain()[0]===m.domain()[1]||n.domain()[0]===n.domain()[1],m.domain()[0]===m.domain()[1]&&m.domain(m.domain()[0]?[m.domain()[0]-.01*m.domain()[0],m.domain()[1]+.01*m.domain()[1]]:[-1,1]),n.domain()[0]===n.domain()[1]&&n.domain(n.domain()[0]?[n.domain()[0]-.01*n.domain()[0],n.domain()[1]+.01*n.domain()[1]]:[-1,1]),isNaN(m.domain()[0])&&m.domain([-1,1]),isNaN(n.domain()[0])&&n.domain([-1,1]),c=c||m,d=d||n,e=e||o;var U=l.selectAll("g.nv-wrap.nv-scatter").data([b]),V=U.enter().append("g").attr("class","nvd3 nv-wrap nv-scatter nv-chart-"+k),W=V.append("defs"),X=V.append("g"),Y=U.select("g");U.classed("nv-single-point",K),X.append("g").attr("class","nv-groups"),X.append("g").attr("class","nv-point-paths"),V.append("g").attr("class","nv-point-clips"),U.attr("transform","translate("+g.left+","+g.top+")"),W.append("clipPath").attr("id","nv-edge-clip-"+k).append("rect"),U.select("#nv-edge-clip-"+k+" rect").attr("width",R).attr("height",S>0?S:0),Y.attr("clip-path",A?"url(#nv-edge-clip-"+k+")":""),O=!0;var Z=U.select(".nv-groups").selectAll(".nv-group").data(function(a){return a},function(a){return a.key});Z.enter().append("g").style("stroke-opacity",1e-6).style("fill-opacity",1e-6),Z.exit().remove(),Z.attr("class",function(a,b){return"nv-group nv-series-"+b}).classed("hover",function(a){return a.hover}),Z.watchTransition(P,"scatter: groups").style("fill",function(a,b){return j(a,b)}).style("stroke",function(a,b){return j(a,b)}).style("stroke-opacity",1).style("fill-opacity",.5);var $=Z.selectAll("path.nv-point").data(function(a){return a.values.map(function(a,b){return[a,b]}).filter(function(a,b){return x(a[0],b)})});$.enter().append("path").style("fill",function(a){return a.color}).style("stroke",function(a){return a.color}).attr("transform",function(a){return"translate("+c(p(a[0],a[1]))+","+d(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),$.exit().remove(),Z.exit().selectAll("path.nv-point").watchTransition(P,"scatter exit").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).remove(),$.each(function(a){d3.select(this).classed("nv-point",!0).classed("nv-point-"+a[1],!0).classed("nv-noninteractive",!w).classed("hover",!1)}),$.watchTransition(P,"scatter points").attr("transform",function(a){return"translate("+m(p(a[0],a[1]))+","+n(q(a[0],a[1]))+")"}).attr("d",a.utils.symbol().type(function(a){return s(a[0])}).size(function(a){return o(r(a[0],a[1]))})),clearTimeout(f),f=setTimeout(N,300),c=m.copy(),d=n.copy(),e=o.copy()}),P.renderEnd("scatter immediate"),b}var c,d,e,f,g={top:0,right:0,bottom:0,left:0},h=null,i=null,j=a.utils.defaultColor(),k=Math.floor(1e5*Math.random()),l=null,m=d3.scale.linear(),n=d3.scale.linear(),o=d3.scale.linear(),p=function(a){return a.x},q=function(a){return a.y},r=function(a){return a.size||1},s=function(a){return a.shape||"circle"},t=[],u=[],v=[],w=!0,x=function(a){return!a.notActive},y=!1,z=.1,A=!1,B=!0,C=!1,D=function(){return 25},E=null,F=null,G=null,H=null,I=null,J=null,K=!1,L=d3.dispatch("elementClick","elementDblClick","elementMouseover","elementMouseout","renderEnd"),M=!0,N=250,O=!1,P=a.utils.renderWatch(L,N),Q=[16,256];return b.dispatch=L,b.options=a.utils.optionsFunc.bind(b),b._calls=new function(){this.clearHighlights=function(){return a.dom.write(function(){l.selectAll(".nv-point.hover").classed("hover",!1)}),null},this.highlightPoint=function(b,c,d){a.dom.write(function(){l.select(" .nv-series-"+b+" .nv-point-"+c).classed("hover",d)})}},L.on("elementMouseover.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!0)}),L.on("elementMouseout.point",function(a){w&&b._calls.highlightPoint(a.seriesIndex,a.pointIndex,!1)}),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xScale:{get:function(){return m},set:function(a){m=a}},yScale:{get:function(){return n},set:function(a){n=a}},pointScale:{get:function(){return o},set:function(a){o=a}},xDomain:{get:function(){return E},set:function(a){E=a}},yDomain:{get:function(){return F},set:function(a){F=a}},pointDomain:{get:function(){return I},set:function(a){I=a}},xRange:{get:function(){return G},set:function(a){G=a}},yRange:{get:function(){return H},set:function(a){H=a}},pointRange:{get:function(){return J},set:function(a){J=a}},forceX:{get:function(){return t},set:function(a){t=a}},forceY:{get:function(){return u},set:function(a){u=a}},forcePoint:{get:function(){return v},set:function(a){v=a}},interactive:{get:function(){return w},set:function(a){w=a}},pointActive:{get:function(){return x},set:function(a){x=a}},padDataOuter:{get:function(){return z},set:function(a){z=a}},padData:{get:function(){return y},set:function(a){y=a}},clipEdge:{get:function(){return A},set:function(a){A=a}},clipVoronoi:{get:function(){return B},set:function(a){B=a}},clipRadius:{get:function(){return D},set:function(a){D=a}},showVoronoi:{get:function(){return C},set:function(a){C=a}},id:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return p},set:function(a){p=d3.functor(a)}},y:{get:function(){return q},set:function(a){q=d3.functor(a)}},pointSize:{get:function(){return r},set:function(a){r=d3.functor(a)}},pointShape:{get:function(){return s},set:function(a){s=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},duration:{get:function(){return N},set:function(a){N=a,P.reset(N)}},color:{get:function(){return j},set:function(b){j=a.utils.getColor(b)}},useVoronoi:{get:function(){return M},set:function(a){M=a,M===!1&&(B=!1)}}}),a.utils.initOptions(b),b},a.models.scatterChart=function(){"use strict";function b(z){return D.reset(),D.models(c),t&&D.models(d),u&&D.models(e),q&&D.models(g),r&&D.models(h),z.each(function(z){m=d3.select(this),a.utils.initSVG(m);var G=a.utils.availableWidth(k,m,j),H=a.utils.availableHeight(l,m,j);if(b.update=function(){0===A?m.call(b):m.transition().duration(A).call(b)},b.container=this,w.setter(F(z),b.update).getter(E(z)).update(),w.disabled=z.map(function(a){return!!a.disabled}),!x){var I;x={};for(I in w)x[I]=w[I]instanceof Array?w[I].slice(0):w[I]}if(!(z&&z.length&&z.filter(function(a){return a.values.length}).length))return a.utils.noData(b,m),D.renderEnd("scatter immediate"),b;m.selectAll(".nv-noData").remove(),o=c.xScale(),p=c.yScale();var J=m.selectAll("g.nv-wrap.nv-scatterChart").data([z]),K=J.enter().append("g").attr("class","nvd3 nv-wrap nv-scatterChart nv-chart-"+c.id()),L=K.append("g"),M=J.select("g");if(L.append("rect").attr("class","nvd3 nv-background").style("pointer-events","none"),L.append("g").attr("class","nv-x nv-axis"),L.append("g").attr("class","nv-y nv-axis"),L.append("g").attr("class","nv-scatterWrap"),L.append("g").attr("class","nv-regressionLinesWrap"),L.append("g").attr("class","nv-distWrap"),L.append("g").attr("class","nv-legendWrap"),v&&M.select(".nv-y.nv-axis").attr("transform","translate("+G+",0)"),s){var N=G;f.width(N),J.select(".nv-legendWrap").datum(z).call(f),j.top!=f.height()&&(j.top=f.height(),H=a.utils.availableHeight(l,m,j)),J.select(".nv-legendWrap").attr("transform","translate(0,"+-j.top+")")}J.attr("transform","translate("+j.left+","+j.top+")"),c.width(G).height(H).color(z.map(function(a,b){return a.color=a.color||n(a,b),a.color}).filter(function(a,b){return!z[b].disabled})),J.select(".nv-scatterWrap").datum(z.filter(function(a){return!a.disabled})).call(c),J.select(".nv-regressionLinesWrap").attr("clip-path","url(#nv-edge-clip-"+c.id()+")");var O=J.select(".nv-regressionLinesWrap").selectAll(".nv-regLines").data(function(a){return a});O.enter().append("g").attr("class","nv-regLines");var P=O.selectAll(".nv-regLine").data(function(a){return[a]});P.enter().append("line").attr("class","nv-regLine").style("stroke-opacity",0),P.filter(function(a){return a.intercept&&a.slope}).watchTransition(D,"scatterPlusLineChart: regline").attr("x1",o.range()[0]).attr("x2",o.range()[1]).attr("y1",function(a){return p(o.domain()[0]*a.slope+a.intercept)}).attr("y2",function(a){return p(o.domain()[1]*a.slope+a.intercept)}).style("stroke",function(a,b,c){return n(a,c)}).style("stroke-opacity",function(a){return a.disabled||"undefined"==typeof a.slope||"undefined"==typeof a.intercept?0:1}),t&&(d.scale(o)._ticks(a.utils.calcTicksX(G/100,z)).tickSize(-H,0),M.select(".nv-x.nv-axis").attr("transform","translate(0,"+p.range()[0]+")").call(d)),u&&(e.scale(p)._ticks(a.utils.calcTicksY(H/36,z)).tickSize(-G,0),M.select(".nv-y.nv-axis").call(e)),q&&(g.getData(c.x()).scale(o).width(G).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionX"),M.select(".nv-distributionX").attr("transform","translate(0,"+p.range()[0]+")").datum(z.filter(function(a){return!a.disabled})).call(g)),r&&(h.getData(c.y()).scale(p).width(H).color(z.map(function(a,b){return a.color||n(a,b)}).filter(function(a,b){return!z[b].disabled})),L.select(".nv-distWrap").append("g").attr("class","nv-distributionY"),M.select(".nv-distributionY").attr("transform","translate("+(v?G:-h.size())+",0)").datum(z.filter(function(a){return!a.disabled})).call(h)),f.dispatch.on("stateChange",function(a){for(var c in a)w[c]=a[c];y.stateChange(w),b.update()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&(z.forEach(function(b,c){b.disabled=a.disabled[c]}),w.disabled=a.disabled),b.update()}),c.dispatch.on("elementMouseout.tooltip",function(a){i.hidden(!0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",0),m.select(".nv-chart-"+c.id()+" .nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",h.size())}),c.dispatch.on("elementMouseover.tooltip",function(a){m.select(".nv-series-"+a.seriesIndex+" .nv-distx-"+a.pointIndex).attr("y1",a.pos.top-H-j.top),m.select(".nv-series-"+a.seriesIndex+" .nv-disty-"+a.pointIndex).attr("x2",a.pos.left+g.size()-j.left),i.position(a.pos).data(a).hidden(!1)}),B=o.copy(),C=p.copy()}),D.renderEnd("scatter with line immediate"),b}var c=a.models.scatter(),d=a.models.axis(),e=a.models.axis(),f=a.models.legend(),g=a.models.distribution(),h=a.models.distribution(),i=a.models.tooltip(),j={top:30,right:20,bottom:50,left:75},k=null,l=null,m=null,n=a.utils.defaultColor(),o=c.xScale(),p=c.yScale(),q=!1,r=!1,s=!0,t=!0,u=!0,v=!1,w=a.utils.state(),x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=null,A=250;c.xScale(o).yScale(p),d.orient("bottom").tickPadding(10),e.orient(v?"right":"left").tickPadding(10),g.axis("x"),h.axis("y"),i.headerFormatter(function(a,b){return d.tickFormat()(a,b)}).valueFormatter(function(a,b){return e.tickFormat()(a,b)});var B,C,D=a.utils.renderWatch(y,A),E=function(a){return function(){return{active:a.map(function(a){return!a.disabled})}}},F=function(a){return function(b){void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}};return b.dispatch=y,b.scatter=c,b.legend=f,b.xAxis=d,b.yAxis=e,b.distX=g,b.distY=h,b.tooltip=i,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return k},set:function(a){k=a}},height:{get:function(){return l},set:function(a){l=a}},container:{get:function(){return m},set:function(a){m=a}},showDistX:{get:function(){return q},set:function(a){q=a}},showDistY:{get:function(){return r},set:function(a){r=a}},showLegend:{get:function(){return s},set:function(a){s=a}},showXAxis:{get:function(){return t},set:function(a){t=a}},showYAxis:{get:function(){return u},set:function(a){u=a}},defaultState:{get:function(){return x},set:function(a){x=a}},noData:{get:function(){return z},set:function(a){z=a}},duration:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return i.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),i.enabled(!!b) +}},tooltipContent:{get:function(){return i.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),i.contentGenerator(b)}},tooltipXContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},tooltipYContent:{get:function(){return i.contentGenerator()},set:function(){a.deprecated("tooltipContent","This option is removed, put values into main tooltip.")}},margin:{get:function(){return j},set:function(a){j.top=void 0!==a.top?a.top:j.top,j.right=void 0!==a.right?a.right:j.right,j.bottom=void 0!==a.bottom?a.bottom:j.bottom,j.left=void 0!==a.left?a.left:j.left}},rightAlignYAxis:{get:function(){return v},set:function(a){v=a,e.orient(a?"right":"left")}},color:{get:function(){return n},set:function(b){n=a.utils.getColor(b),f.color(n),g.color(n),h.color(n)}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.models.sparkline=function(){"use strict";function b(k){return k.each(function(b){var k=h-g.left-g.right,q=i-g.top-g.bottom;j=d3.select(this),a.utils.initSVG(j),l.domain(c||d3.extent(b,n)).range(e||[0,k]),m.domain(d||d3.extent(b,o)).range(f||[q,0]);{var r=j.selectAll("g.nv-wrap.nv-sparkline").data([b]),s=r.enter().append("g").attr("class","nvd3 nv-wrap nv-sparkline");s.append("g"),r.select("g")}r.attr("transform","translate("+g.left+","+g.top+")");var t=r.selectAll("path").data(function(a){return[a]});t.enter().append("path"),t.exit().remove(),t.style("stroke",function(a,b){return a.color||p(a,b)}).attr("d",d3.svg.line().x(function(a,b){return l(n(a,b))}).y(function(a,b){return m(o(a,b))}));var u=r.selectAll("circle.nv-point").data(function(a){function b(b){if(-1!=b){var c=a[b];return c.pointIndex=b,c}return null}var c=a.map(function(a,b){return o(a,b)}),d=b(c.lastIndexOf(m.domain()[1])),e=b(c.indexOf(m.domain()[0])),f=b(c.length-1);return[e,d,f].filter(function(a){return null!=a})});u.enter().append("circle"),u.exit().remove(),u.attr("cx",function(a){return l(n(a,a.pointIndex))}).attr("cy",function(a){return m(o(a,a.pointIndex))}).attr("r",2).attr("class",function(a){return n(a,a.pointIndex)==l.domain()[1]?"nv-point nv-currentValue":o(a,a.pointIndex)==m.domain()[0]?"nv-point nv-minValue":"nv-point nv-maxValue"})}),b}var c,d,e,f,g={top:2,right:0,bottom:2,left:0},h=400,i=32,j=null,k=!0,l=d3.scale.linear(),m=d3.scale.linear(),n=function(a){return a.x},o=function(a){return a.y},p=a.utils.getColor(["#000"]);return b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return h},set:function(a){h=a}},height:{get:function(){return i},set:function(a){i=a}},xDomain:{get:function(){return c},set:function(a){c=a}},yDomain:{get:function(){return d},set:function(a){d=a}},xRange:{get:function(){return e},set:function(a){e=a}},yRange:{get:function(){return f},set:function(a){f=a}},xScale:{get:function(){return l},set:function(a){l=a}},yScale:{get:function(){return m},set:function(a){m=a}},animate:{get:function(){return k},set:function(a){k=a}},x:{get:function(){return n},set:function(a){n=d3.functor(a)}},y:{get:function(){return o},set:function(a){o=d3.functor(a)}},margin:{get:function(){return g},set:function(a){g.top=void 0!==a.top?a.top:g.top,g.right=void 0!==a.right?a.right:g.right,g.bottom=void 0!==a.bottom?a.bottom:g.bottom,g.left=void 0!==a.left?a.left:g.left}},color:{get:function(){return p},set:function(b){p=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sparklinePlus=function(){"use strict";function b(p){return p.each(function(p){function q(){if(!j){var a=z.selectAll(".nv-hoverValue").data(i),b=a.enter().append("g").attr("class","nv-hoverValue").style("stroke-opacity",0).style("fill-opacity",0);a.exit().transition().duration(250).style("stroke-opacity",0).style("fill-opacity",0).remove(),a.attr("transform",function(a){return"translate("+c(e.x()(p[a],a))+",0)"}).transition().duration(250).style("stroke-opacity",1).style("fill-opacity",1),i.length&&(b.append("line").attr("x1",0).attr("y1",-f.top).attr("x2",0).attr("y2",u),b.append("text").attr("class","nv-xValue").attr("x",-6).attr("y",-f.top).attr("text-anchor","end").attr("dy",".9em"),z.select(".nv-hoverValue .nv-xValue").text(k(e.x()(p[i[0]],i[0]))),b.append("text").attr("class","nv-yValue").attr("x",6).attr("y",-f.top).attr("text-anchor","start").attr("dy",".9em"),z.select(".nv-hoverValue .nv-yValue").text(l(e.y()(p[i[0]],i[0]))))}}function r(){function a(a,b){for(var c=Math.abs(e.x()(a[0],0)-b),d=0,f=0;fc;++c){for(b=0,d=0;bb;b++)a[b][c][1]/=d;else for(b=0;e>b;b++)a[b][c][1]=0}for(c=0;f>c;++c)g[c]=0;return g}}),u.renderEnd("stackedArea immediate"),b}var c,d,e={top:0,right:0,bottom:0,left:0},f=960,g=500,h=a.utils.defaultColor(),i=Math.floor(1e5*Math.random()),j=null,k=function(a){return a.x},l=function(a){return a.y},m="stack",n="zero",o="default",p="linear",q=!1,r=a.models.scatter(),s=250,t=d3.dispatch("areaClick","areaMouseover","areaMouseout","renderEnd","elementClick","elementMouseover","elementMouseout");r.pointSize(2.2).pointDomain([2.2,2.2]);var u=a.utils.renderWatch(t,s);return b.dispatch=t,b.scatter=r,r.dispatch.on("elementClick",function(){t.elementClick.apply(this,arguments)}),r.dispatch.on("elementMouseover",function(){t.elementMouseover.apply(this,arguments)}),r.dispatch.on("elementMouseout",function(){t.elementMouseout.apply(this,arguments)}),b.interpolate=function(a){return arguments.length?(p=a,b):p},b.duration=function(a){return arguments.length?(s=a,u.reset(s),r.duration(s),b):s},b.dispatch=t,b.scatter=r,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return f},set:function(a){f=a}},height:{get:function(){return g},set:function(a){g=a}},clipEdge:{get:function(){return q},set:function(a){q=a}},offset:{get:function(){return n},set:function(a){n=a}},order:{get:function(){return o},set:function(a){o=a}},interpolate:{get:function(){return p},set:function(a){p=a}},x:{get:function(){return k},set:function(a){k=d3.functor(a)}},y:{get:function(){return l},set:function(a){l=d3.functor(a)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}},color:{get:function(){return h},set:function(b){h=a.utils.getColor(b)}},style:{get:function(){return m},set:function(a){switch(m=a){case"stack":b.offset("zero"),b.order("default");break;case"stream":b.offset("wiggle"),b.order("inside-out");break;case"stream-center":b.offset("silhouette"),b.order("inside-out");break;case"expand":b.offset("expand"),b.order("default");break;case"stack_percent":b.offset(b.d3_stackedOffset_stackPercent),b.order("default")}}},duration:{get:function(){return s},set:function(a){s=a,u.reset(s),r.duration(s)}}}),a.utils.inheritOptions(b,r),a.utils.initOptions(b),b},a.models.stackedAreaChart=function(){"use strict";function b(k){return F.reset(),F.models(e),r&&F.models(f),s&&F.models(g),k.each(function(k){var x=d3.select(this),F=this;a.utils.initSVG(x);var K=a.utils.availableWidth(m,x,l),L=a.utils.availableHeight(n,x,l);if(b.update=function(){x.transition().duration(C).call(b)},b.container=this,v.setter(I(k),b.update).getter(H(k)).update(),v.disabled=k.map(function(a){return!!a.disabled}),!w){var M;w={};for(M in v)w[M]=v[M]instanceof Array?v[M].slice(0):v[M]}if(!(k&&k.length&&k.filter(function(a){return a.values.length}).length))return a.utils.noData(b,x),b;x.selectAll(".nv-noData").remove(),c=e.xScale(),d=e.yScale();var N=x.selectAll("g.nv-wrap.nv-stackedAreaChart").data([k]),O=N.enter().append("g").attr("class","nvd3 nv-wrap nv-stackedAreaChart").append("g"),P=N.select("g");if(O.append("rect").style("opacity",0),O.append("g").attr("class","nv-x nv-axis"),O.append("g").attr("class","nv-y nv-axis"),O.append("g").attr("class","nv-stackedWrap"),O.append("g").attr("class","nv-legendWrap"),O.append("g").attr("class","nv-controlsWrap"),O.append("g").attr("class","nv-interactive"),P.select("rect").attr("width",K).attr("height",L),q){var Q=p?K-z:K;h.width(Q),P.select(".nv-legendWrap").datum(k).call(h),l.top!=h.height()&&(l.top=h.height(),L=a.utils.availableHeight(n,x,l)),P.select(".nv-legendWrap").attr("transform","translate("+(K-Q)+","+-l.top+")")}if(p){var R=[{key:B.stacked||"Stacked",metaKey:"Stacked",disabled:"stack"!=e.style(),style:"stack"},{key:B.stream||"Stream",metaKey:"Stream",disabled:"stream"!=e.style(),style:"stream"},{key:B.expanded||"Expanded",metaKey:"Expanded",disabled:"expand"!=e.style(),style:"expand"},{key:B.stack_percent||"Stack %",metaKey:"Stack_Percent",disabled:"stack_percent"!=e.style(),style:"stack_percent"}];z=A.length/3*260,R=R.filter(function(a){return-1!==A.indexOf(a.metaKey)}),i.width(z).color(["#444","#444","#444"]),P.select(".nv-controlsWrap").datum(R).call(i),l.top!=Math.max(i.height(),h.height())&&(l.top=Math.max(i.height(),h.height()),L=a.utils.availableHeight(n,x,l)),P.select(".nv-controlsWrap").attr("transform","translate(0,"+-l.top+")")}N.attr("transform","translate("+l.left+","+l.top+")"),t&&P.select(".nv-y.nv-axis").attr("transform","translate("+K+",0)"),u&&(j.width(K).height(L).margin({left:l.left,top:l.top}).svgContainer(x).xScale(c),N.select(".nv-interactive").call(j)),e.width(K).height(L);var S=P.select(".nv-stackedWrap").datum(k);if(S.transition().call(e),r&&(f.scale(c)._ticks(a.utils.calcTicksX(K/100,k)).tickSize(-L,0),P.select(".nv-x.nv-axis").attr("transform","translate(0,"+L+")"),P.select(".nv-x.nv-axis").transition().duration(0).call(f)),s){var T;if(T="wiggle"===e.offset()?0:a.utils.calcTicksY(L/36,k),g.scale(d)._ticks(T).tickSize(-K,0),"expand"===e.style()||"stack_percent"===e.style()){var U=g.tickFormat();D&&U===J||(D=U),g.tickFormat(J)}else D&&(g.tickFormat(D),D=null);P.select(".nv-y.nv-axis").transition().duration(0).call(g)}e.dispatch.on("areaClick.toggle",function(a){k.forEach(1===k.filter(function(a){return!a.disabled}).length?function(a){a.disabled=!1}:function(b,c){b.disabled=c!=a.seriesIndex}),v.disabled=k.map(function(a){return!!a.disabled}),y.stateChange(v),b.update()}),h.dispatch.on("stateChange",function(a){for(var c in a)v[c]=a[c];y.stateChange(v),b.update()}),i.dispatch.on("legendClick",function(a){a.disabled&&(R=R.map(function(a){return a.disabled=!0,a}),a.disabled=!1,e.style(a.style),v.style=e.style(),y.stateChange(v),b.update())}),j.dispatch.on("elementMousemove",function(c){e.clearHighlights();var d,g,h,i=[];if(k.filter(function(a,b){return a.seriesIndex=b,!a.disabled}).forEach(function(f,j){g=a.interactiveBisect(f.values,c.pointXValue,b.x());var k=f.values[g],l=b.y()(k,g);if(null!=l&&e.highlightPoint(j,g,!0),"undefined"!=typeof k){"undefined"==typeof d&&(d=k),"undefined"==typeof h&&(h=b.xScale()(b.x()(k,g)));var m="expand"==e.style()?k.display.y:b.y()(k,g);i.push({key:f.key,value:m,color:o(f,f.seriesIndex),stackedValue:k.display})}}),i.reverse(),i.length>2){var m=b.yScale().invert(c.mouseY),n=null;i.forEach(function(a,b){m=Math.abs(m);var c=Math.abs(a.stackedValue.y0),d=Math.abs(a.stackedValue.y);return m>=c&&d+c>=m?void(n=b):void 0}),null!=n&&(i[n].highlight=!0)}var p=f.tickFormat()(b.x()(d,g)),q=j.tooltip.valueFormatter();"expand"===e.style()||"stack_percent"===e.style()?(E||(E=q),q=d3.format(".1%")):E&&(q=E,E=null),j.tooltip.position({left:h+l.left,top:c.mouseY+l.top}).chartContainer(F.parentNode).valueFormatter(q).data({value:p,series:i})(),j.renderGuideLine(h)}),j.dispatch.on("elementMouseout",function(){e.clearHighlights()}),y.on("changeState",function(a){"undefined"!=typeof a.disabled&&k.length===a.disabled.length&&(k.forEach(function(b,c){b.disabled=a.disabled[c]}),v.disabled=a.disabled),"undefined"!=typeof a.style&&(e.style(a.style),G=a.style),b.update()})}),F.renderEnd("stacked Area chart immediate"),b}var c,d,e=a.models.stackedArea(),f=a.models.axis(),g=a.models.axis(),h=a.models.legend(),i=a.models.legend(),j=a.interactiveGuideline(),k=a.models.tooltip(),l={top:30,right:25,bottom:50,left:60},m=null,n=null,o=a.utils.defaultColor(),p=!0,q=!0,r=!0,s=!0,t=!1,u=!1,v=a.utils.state(),w=null,x=null,y=d3.dispatch("stateChange","changeState","renderEnd"),z=250,A=["Stacked","Stream","Expanded"],B={},C=250;v.style=e.style(),f.orient("bottom").tickPadding(7),g.orient(t?"right":"left"),k.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)}),j.tooltip.headerFormatter(function(a,b){return f.tickFormat()(a,b)}).valueFormatter(function(a,b){return g.tickFormat()(a,b)});var D=null,E=null;i.updateState(!1);var F=a.utils.renderWatch(y),G=e.style(),H=function(a){return function(){return{active:a.map(function(a){return!a.disabled}),style:e.style()}}},I=function(a){return function(b){void 0!==b.style&&(G=b.style),void 0!==b.active&&a.forEach(function(a,c){a.disabled=!b.active[c]})}},J=d3.format("%");return e.dispatch.on("elementMouseover.tooltip",function(a){a.point.x=e.x()(a.point),a.point.y=e.y()(a.point),k.data(a).position(a.pos).hidden(!1)}),e.dispatch.on("elementMouseout.tooltip",function(){k.hidden(!0)}),b.dispatch=y,b.stacked=e,b.legend=h,b.controls=i,b.xAxis=f,b.yAxis=g,b.interactiveLayer=j,b.tooltip=k,b.dispatch=y,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return m},set:function(a){m=a}},height:{get:function(){return n},set:function(a){n=a}},showLegend:{get:function(){return q},set:function(a){q=a}},showXAxis:{get:function(){return r},set:function(a){r=a}},showYAxis:{get:function(){return s},set:function(a){s=a}},defaultState:{get:function(){return w},set:function(a){w=a}},noData:{get:function(){return x},set:function(a){x=a}},showControls:{get:function(){return p},set:function(a){p=a}},controlLabels:{get:function(){return B},set:function(a){B=a}},controlOptions:{get:function(){return A},set:function(a){A=a}},tooltips:{get:function(){return k.enabled()},set:function(b){a.deprecated("tooltips","use chart.tooltip.enabled() instead"),k.enabled(!!b)}},tooltipContent:{get:function(){return k.contentGenerator()},set:function(b){a.deprecated("tooltipContent","use chart.tooltip.contentGenerator() instead"),k.contentGenerator(b)}},margin:{get:function(){return l},set:function(a){l.top=void 0!==a.top?a.top:l.top,l.right=void 0!==a.right?a.right:l.right,l.bottom=void 0!==a.bottom?a.bottom:l.bottom,l.left=void 0!==a.left?a.left:l.left}},duration:{get:function(){return C},set:function(a){C=a,F.reset(C),e.duration(C),f.duration(C),g.duration(C)}},color:{get:function(){return o},set:function(b){o=a.utils.getColor(b),h.color(o),e.color(o)}},rightAlignYAxis:{get:function(){return t},set:function(a){t=a,g.orient(t?"right":"left")}},useInteractiveGuideline:{get:function(){return u},set:function(a){u=!!a,b.interactive(!a),b.useVoronoi(!a),e.scatter.interactive(!a)}}}),a.utils.inheritOptions(b,e),a.utils.initOptions(b),b},a.models.sunburst=function(){"use strict";function b(u){return t.reset(),u.each(function(b){function t(a){a.x0=a.x,a.dx0=a.dx}function u(a){var b=d3.interpolate(p.domain(),[a.x,a.x+a.dx]),c=d3.interpolate(q.domain(),[a.y,1]),d=d3.interpolate(q.range(),[a.y?20:0,y]);return function(a,e){return e?function(){return s(a)}:function(e){return p.domain(b(e)),q.domain(c(e)).range(d(e)),s(a)}}}l=d3.select(this);var v,w=a.utils.availableWidth(g,l,f),x=a.utils.availableHeight(h,l,f),y=Math.min(w,x)/2;a.utils.initSVG(l);var z=l.selectAll(".nv-wrap.nv-sunburst").data(b),A=z.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburst nv-chart-"+k),B=A.selectAll("nv-sunburst");z.attr("transform","translate("+w/2+","+x/2+")"),l.on("click",function(a,b){o.chartClick({data:a,index:b,pos:d3.event,id:k})}),q.range([0,y]),c=c||b,e=b[0],r.value(j[i]||j.count),v=B.data(r.nodes).enter().append("path").attr("d",s).style("fill",function(a){return m((a.children?a:a.parent).name)}).style("stroke","#FFF").on("click",function(a){d!==c&&c!==a&&(d=c),c=a,v.transition().duration(n).attrTween("d",u(a))}).each(t).on("dblclick",function(a){d.parent==a&&v.transition().duration(n).attrTween("d",u(e))}).each(t).on("mouseover",function(a){d3.select(this).classed("hover",!0).style("opacity",.8),o.elementMouseover({data:a,color:d3.select(this).style("fill")})}).on("mouseout",function(a){d3.select(this).classed("hover",!1).style("opacity",1),o.elementMouseout({data:a})}).on("mousemove",function(a){o.elementMousemove({data:a})})}),t.renderEnd("sunburst immediate"),b}var c,d,e,f={top:0,right:0,bottom:0,left:0},g=null,h=null,i="count",j={count:function(){return 1},size:function(a){return a.size}},k=Math.floor(1e4*Math.random()),l=null,m=a.utils.defaultColor(),n=500,o=d3.dispatch("chartClick","elementClick","elementDblClick","elementMousemove","elementMouseover","elementMouseout","renderEnd"),p=d3.scale.linear().range([0,2*Math.PI]),q=d3.scale.sqrt(),r=d3.layout.partition().sort(null).value(function(){return 1}),s=d3.svg.arc().startAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x)))}).endAngle(function(a){return Math.max(0,Math.min(2*Math.PI,p(a.x+a.dx)))}).innerRadius(function(a){return Math.max(0,q(a.y))}).outerRadius(function(a){return Math.max(0,q(a.y+a.dy))}),t=a.utils.renderWatch(o);return b.dispatch=o,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{width:{get:function(){return g},set:function(a){g=a}},height:{get:function(){return h},set:function(a){h=a}},mode:{get:function(){return i},set:function(a){i=a}},id:{get:function(){return k},set:function(a){k=a}},duration:{get:function(){return n},set:function(a){n=a}},margin:{get:function(){return f},set:function(a){f.top=void 0!=a.top?a.top:f.top,f.right=void 0!=a.right?a.right:f.right,f.bottom=void 0!=a.bottom?a.bottom:f.bottom,f.left=void 0!=a.left?a.left:f.left}},color:{get:function(){return m},set:function(b){m=a.utils.getColor(b)}}}),a.utils.initOptions(b),b},a.models.sunburstChart=function(){"use strict";function b(d){return m.reset(),m.models(c),d.each(function(d){var h=d3.select(this);a.utils.initSVG(h);var i=a.utils.availableWidth(f,h,e),j=a.utils.availableHeight(g,h,e);if(b.update=function(){0===k?h.call(b):h.transition().duration(k).call(b)},b.container=this,!d||!d.length)return a.utils.noData(b,h),b;h.selectAll(".nv-noData").remove();var l=h.selectAll("g.nv-wrap.nv-sunburstChart").data(d),m=l.enter().append("g").attr("class","nvd3 nv-wrap nv-sunburstChart").append("g"),n=l.select("g");m.append("g").attr("class","nv-sunburstWrap"),l.attr("transform","translate("+e.left+","+e.top+")"),c.width(i).height(j);var o=n.select(".nv-sunburstWrap").datum(d);d3.transition(o).call(c)}),m.renderEnd("sunburstChart immediate"),b}var c=a.models.sunburst(),d=a.models.tooltip(),e={top:30,right:20,bottom:20,left:20},f=null,g=null,h=a.utils.defaultColor(),i=(Math.round(1e5*Math.random()),null),j=null,k=250,l=d3.dispatch("tooltipShow","tooltipHide","stateChange","changeState","renderEnd"),m=a.utils.renderWatch(l);return d.headerEnabled(!1).duration(0).valueFormatter(function(a){return a}),c.dispatch.on("elementMouseover.tooltip",function(a){a.series={key:a.data.name,value:a.data.size,color:a.color},d.data(a).hidden(!1)}),c.dispatch.on("elementMouseout.tooltip",function(){d.hidden(!0)}),c.dispatch.on("elementMousemove.tooltip",function(){d.position({top:d3.event.pageY,left:d3.event.pageX})()}),b.dispatch=l,b.sunburst=c,b.tooltip=d,b.options=a.utils.optionsFunc.bind(b),b._options=Object.create({},{noData:{get:function(){return j},set:function(a){j=a}},defaultState:{get:function(){return i},set:function(a){i=a}},color:{get:function(){return h},set:function(a){h=a,c.color(h)}},duration:{get:function(){return k},set:function(a){k=a,m.reset(k),c.duration(k)}},margin:{get:function(){return e},set:function(a){e.top=void 0!==a.top?a.top:e.top,e.right=void 0!==a.right?a.right:e.right,e.bottom=void 0!==a.bottom?a.bottom:e.bottom,e.left=void 0!==a.left?a.left:e.left}}}),a.utils.inheritOptions(b,c),a.utils.initOptions(b),b},a.version="1.8.1"}(); \ No newline at end of file diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js new file mode 100644 index 0000000..36c2aeb --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/js/popper.min.js @@ -0,0 +1,5 @@ +/* + Copyright (C) Federico Zivolo 2019 + Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). + */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=e.ownerDocument.defaultView,n=o.getComputedStyle(e,null);return t?n[t]:n}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e)return document.body;switch(e.nodeName){case'HTML':case'BODY':return e.ownerDocument.body;case'#document':return e.body;}var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll|overlay)/.test(r+s+p)?e:n(o(e))}function r(e){return 11===e?pe:10===e?se:pe||se}function p(e){if(!e)return document.documentElement;for(var o=r(10)?document.body:null,n=e.offsetParent||null;n===o&&e.nextElementSibling;)n=(e=e.nextElementSibling).offsetParent;var i=n&&n.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TH','TD','TABLE'].indexOf(n.nodeName)&&'static'===t(n,'position')?p(n):n:e?e.ownerDocument.documentElement:document.documentElement}function s(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||p(e.firstElementChild)===e)}function d(e){return null===e.parentNode?e:d(e.parentNode)}function a(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,n=o?e:t,i=o?t:e,r=document.createRange();r.setStart(n,0),r.setEnd(i,0);var l=r.commonAncestorContainer;if(e!==l&&t!==l||n.contains(i))return s(l)?l:p(l);var f=d(e);return f.host?a(f.host,t):a(e,d(t).host)}function l(e){var t=1=o.clientWidth&&n>=o.clientHeight}),l=0a[e]&&!t.escapeWithReference&&(n=Q(f[o],a[e]-('right'===e?f.width:f.height))),le({},o,n)}};return l.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';f=fe({},f,m[t](e))}),e.offsets.popper=f,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,n=t.reference,i=e.placement.split('-')[0],r=Z,p=-1!==['top','bottom'].indexOf(i),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(n[s])&&(e.offsets.popper[d]=r(n[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,o){var n;if(!K(e.instance.modifiers,'arrow','keepTogether'))return e;var i=o.element;if('string'==typeof i){if(i=e.instance.popper.querySelector(i),!i)return e;}else if(!e.instance.popper.contains(i))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var r=e.placement.split('-')[0],p=e.offsets,s=p.popper,d=p.reference,a=-1!==['left','right'].indexOf(r),l=a?'height':'width',f=a?'Top':'Left',m=f.toLowerCase(),h=a?'left':'top',c=a?'bottom':'right',u=S(i)[l];d[c]-us[c]&&(e.offsets.popper[m]+=d[m]+u-s[c]),e.offsets.popper=g(e.offsets.popper);var b=d[m]+d[l]/2-u/2,w=t(e.instance.popper),y=parseFloat(w['margin'+f],10),E=parseFloat(w['border'+f+'Width'],10),v=b-e.offsets.popper[m]-y-E;return v=ee(Q(s[l]-u,v),0),e.arrowElement=i,e.offsets.arrow=(n={},le(n,m,$(v)),le(n,h,''),n),e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=v(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement,e.positionFixed),n=e.placement.split('-')[0],i=T(n),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case ge.FLIP:p=[n,i];break;case ge.CLOCKWISE:p=G(n);break;case ge.COUNTERCLOCKWISE:p=G(n,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(n!==s||p.length===d+1)return e;n=e.placement.split('-')[0],i=T(n);var a=e.offsets.popper,l=e.offsets.reference,f=Z,m='left'===n&&f(a.right)>f(l.left)||'right'===n&&f(a.left)f(l.top)||'bottom'===n&&f(a.top)f(o.right),g=f(a.top)f(o.bottom),b='left'===n&&h||'right'===n&&c||'top'===n&&g||'bottom'===n&&u,w=-1!==['top','bottom'].indexOf(n),y=!!t.flipVariations&&(w&&'start'===r&&h||w&&'end'===r&&c||!w&&'start'===r&&g||!w&&'end'===r&&u),E=!!t.flipVariationsByContent&&(w&&'start'===r&&c||w&&'end'===r&&h||!w&&'start'===r&&u||!w&&'end'===r&&g),v=y||E;(m||b||v)&&(e.flipped=!0,(m||b)&&(n=p[d+1]),v&&(r=z(r)),e.placement=n+(r?'-'+r:''),e.offsets.popper=fe({},e.offsets.popper,C(e.instance.popper,e.offsets.reference,e.placement)),e=P(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport',flipVariations:!1,flipVariationsByContent:!1},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],n=e.offsets,i=n.popper,r=n.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return i[p?'left':'top']=r[o]-(s?i[p?'width':'height']:0),e.placement=T(t),e.offsets.popper=g(i),e}},hide:{order:800,enabled:!0,fn:function(e){if(!K(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=D(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.rightwindow.devicePixelRatio||!me),c='bottom'===o?'top':'bottom',g='right'===n?'left':'right',b=B('transform');if(d='bottom'==c?'HTML'===l.nodeName?-l.clientHeight+h.bottom:-f.height+h.bottom:h.top,s='right'==g?'HTML'===l.nodeName?-l.clientWidth+h.right:-f.width+h.right:h.left,a&&b)m[b]='translate3d('+s+'px, '+d+'px, 0)',m[c]=0,m[g]=0,m.willChange='transform';else{var w='bottom'==c?-1:1,y='right'==g?-1:1;m[c]=d*w,m[g]=s*y,m.willChange=c+', '+g}var E={"x-placement":e.placement};return e.attributes=fe({},E,e.attributes),e.styles=fe({},m,e.styles),e.arrowStyles=fe({},e.offsets.arrow,e.arrowStyles),e},gpuAcceleration:!0,x:'bottom',y:'right'},applyStyle:{order:900,enabled:!0,fn:function(e){return V(e.instance.popper,e.styles),j(e.instance.popper,e.attributes),e.arrowElement&&Object.keys(e.arrowStyles).length&&V(e.arrowElement,e.arrowStyles),e},onLoad:function(e,t,o,n,i){var r=L(i,t,e,o.positionFixed),p=O(o.placement,r,t,e,o.modifiers.flip.boundariesElement,o.modifiers.flip.padding);return t.setAttribute('x-placement',p),V(t,{position:o.positionFixed?'fixed':'absolute'}),o},gpuAcceleration:void 0}}},ue}); +//# sourceMappingURL=popper.min.js.map diff --git a/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist new file mode 100644 index 0000000..d8890ed --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Html/Renderer/Template/method_item.html.dist @@ -0,0 +1,11 @@ + + {{name}} + {{methods_bar}} +
{{methods_tested_percent}}
+
{{methods_number}}
+ {{crap}} + {{lines_bar}} +
{{lines_executed_percent}}
+
{{lines_number}}
+ + diff --git a/vendor/phpunit/php-code-coverage/src/Report/PHP.php b/vendor/phpunit/php-code-coverage/src/Report/PHP.php new file mode 100644 index 0000000..73e2f4d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/PHP.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\RuntimeException; + +/** + * Uses var_export() to write a SebastianBergmann\CodeCoverage\CodeCoverage object to a file. + */ +final class PHP +{ + /** + * @throws \SebastianBergmann\CodeCoverage\RuntimeException + */ + public function process(CodeCoverage $coverage, ?string $target = null): string + { + $filter = $coverage->filter(); + + $buffer = \sprintf( + 'setData(%s); +$coverage->setTests(%s); + +$filter = $coverage->filter(); +$filter->setWhitelistedFiles(%s); + +return $coverage;', + \var_export($coverage->getData(true), true), + \var_export($coverage->getTests(), true), + \var_export($filter->getWhitelistedFiles(), true) + ); + + if ($target !== null) { + if (!$this->createDirectory(\dirname($target))) { + throw new \RuntimeException(\sprintf('Directory "%s" was not created', \dirname($target))); + } + + if (@\file_put_contents($target, $buffer) === false) { + throw new RuntimeException( + \sprintf( + 'Could not write to "%s', + $target + ) + ); + } + } + + return $buffer; + } + + private function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Text.php b/vendor/phpunit/php-code-coverage/src/Report/Text.php new file mode 100644 index 0000000..9593a22 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Text.php @@ -0,0 +1,283 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\File; +use SebastianBergmann\CodeCoverage\Util; + +/** + * Generates human readable output from a code coverage object. + * + * The output gets put into a text file our written to the CLI. + */ +final class Text +{ + /** + * @var string + */ + private const COLOR_GREEN = "\x1b[30;42m"; + + /** + * @var string + */ + private const COLOR_YELLOW = "\x1b[30;43m"; + + /** + * @var string + */ + private const COLOR_RED = "\x1b[37;41m"; + + /** + * @var string + */ + private const COLOR_HEADER = "\x1b[1;37;40m"; + + /** + * @var string + */ + private const COLOR_RESET = "\x1b[0m"; + + /** + * @var string + */ + private const COLOR_EOL = "\x1b[2K"; + + /** + * @var int + */ + private $lowUpperBound; + + /** + * @var int + */ + private $highLowerBound; + + /** + * @var bool + */ + private $showUncoveredFiles; + + /** + * @var bool + */ + private $showOnlySummary; + + public function __construct(int $lowUpperBound = 50, int $highLowerBound = 90, bool $showUncoveredFiles = false, bool $showOnlySummary = false) + { + $this->lowUpperBound = $lowUpperBound; + $this->highLowerBound = $highLowerBound; + $this->showUncoveredFiles = $showUncoveredFiles; + $this->showOnlySummary = $showOnlySummary; + } + + public function process(CodeCoverage $coverage, bool $showColors = false): string + { + $output = \PHP_EOL . \PHP_EOL; + $report = $coverage->getReport(); + + $colors = [ + 'header' => '', + 'classes' => '', + 'methods' => '', + 'lines' => '', + 'reset' => '', + 'eol' => '', + ]; + + if ($showColors) { + $colors['classes'] = $this->getCoverageColor( + $report->getNumTestedClassesAndTraits(), + $report->getNumClassesAndTraits() + ); + + $colors['methods'] = $this->getCoverageColor( + $report->getNumTestedMethods(), + $report->getNumMethods() + ); + + $colors['lines'] = $this->getCoverageColor( + $report->getNumExecutedLines(), + $report->getNumExecutableLines() + ); + + $colors['reset'] = self::COLOR_RESET; + $colors['header'] = self::COLOR_HEADER; + $colors['eol'] = self::COLOR_EOL; + } + + $classes = \sprintf( + ' Classes: %6s (%d/%d)', + Util::percent( + $report->getNumTestedClassesAndTraits(), + $report->getNumClassesAndTraits(), + true + ), + $report->getNumTestedClassesAndTraits(), + $report->getNumClassesAndTraits() + ); + + $methods = \sprintf( + ' Methods: %6s (%d/%d)', + Util::percent( + $report->getNumTestedMethods(), + $report->getNumMethods(), + true + ), + $report->getNumTestedMethods(), + $report->getNumMethods() + ); + + $lines = \sprintf( + ' Lines: %6s (%d/%d)', + Util::percent( + $report->getNumExecutedLines(), + $report->getNumExecutableLines(), + true + ), + $report->getNumExecutedLines(), + $report->getNumExecutableLines() + ); + + $padding = \max(\array_map('strlen', [$classes, $methods, $lines])); + + if ($this->showOnlySummary) { + $title = 'Code Coverage Report Summary:'; + $padding = \max($padding, \strlen($title)); + + $output .= $this->format($colors['header'], $padding, $title); + } else { + $date = \date(' Y-m-d H:i:s', $_SERVER['REQUEST_TIME']); + $title = 'Code Coverage Report:'; + + $output .= $this->format($colors['header'], $padding, $title); + $output .= $this->format($colors['header'], $padding, $date); + $output .= $this->format($colors['header'], $padding, ''); + $output .= $this->format($colors['header'], $padding, ' Summary:'); + } + + $output .= $this->format($colors['classes'], $padding, $classes); + $output .= $this->format($colors['methods'], $padding, $methods); + $output .= $this->format($colors['lines'], $padding, $lines); + + if ($this->showOnlySummary) { + return $output . \PHP_EOL; + } + + $classCoverage = []; + + foreach ($report as $item) { + if (!$item instanceof File) { + continue; + } + + $classes = $item->getClassesAndTraits(); + + foreach ($classes as $className => $class) { + $classStatements = 0; + $coveredClassStatements = 0; + $coveredMethods = 0; + $classMethods = 0; + + foreach ($class['methods'] as $method) { + if ($method['executableLines'] == 0) { + continue; + } + + $classMethods++; + $classStatements += $method['executableLines']; + $coveredClassStatements += $method['executedLines']; + + if ($method['coverage'] == 100) { + $coveredMethods++; + } + } + + $namespace = ''; + + if (!empty($class['package']['namespace'])) { + $namespace = '\\' . $class['package']['namespace'] . '::'; + } elseif (!empty($class['package']['fullPackage'])) { + $namespace = '@' . $class['package']['fullPackage'] . '::'; + } + + $classCoverage[$namespace . $className] = [ + 'namespace' => $namespace, + 'className ' => $className, + 'methodsCovered' => $coveredMethods, + 'methodCount' => $classMethods, + 'statementsCovered' => $coveredClassStatements, + 'statementCount' => $classStatements, + ]; + } + } + + \ksort($classCoverage); + + $methodColor = ''; + $linesColor = ''; + $resetColor = ''; + + foreach ($classCoverage as $fullQualifiedPath => $classInfo) { + if ($this->showUncoveredFiles || $classInfo['statementsCovered'] != 0) { + if ($showColors) { + $methodColor = $this->getCoverageColor($classInfo['methodsCovered'], $classInfo['methodCount']); + $linesColor = $this->getCoverageColor($classInfo['statementsCovered'], $classInfo['statementCount']); + $resetColor = $colors['reset']; + } + + $output .= \PHP_EOL . $fullQualifiedPath . \PHP_EOL + . ' ' . $methodColor . 'Methods: ' . $this->printCoverageCounts($classInfo['methodsCovered'], $classInfo['methodCount'], 2) . $resetColor . ' ' + . ' ' . $linesColor . 'Lines: ' . $this->printCoverageCounts($classInfo['statementsCovered'], $classInfo['statementCount'], 3) . $resetColor; + } + } + + return $output . \PHP_EOL; + } + + private function getCoverageColor(int $numberOfCoveredElements, int $totalNumberOfElements): string + { + $coverage = Util::percent( + $numberOfCoveredElements, + $totalNumberOfElements + ); + + if ($coverage >= $this->highLowerBound) { + return self::COLOR_GREEN; + } + + if ($coverage > $this->lowUpperBound) { + return self::COLOR_YELLOW; + } + + return self::COLOR_RED; + } + + private function printCoverageCounts(int $numberOfCoveredElements, int $totalNumberOfElements, int $precision): string + { + $format = '%' . $precision . 's'; + + return Util::percent( + $numberOfCoveredElements, + $totalNumberOfElements, + true, + true + ) . + ' (' . \sprintf($format, $numberOfCoveredElements) . '/' . + \sprintf($format, $totalNumberOfElements) . ')'; + } + + private function format($color, $padding, $string): string + { + $reset = $color ? self::COLOR_RESET : ''; + + return $color . \str_pad($string, $padding) . $reset . \PHP_EOL; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php new file mode 100644 index 0000000..c12a5d2 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/BuildInformation.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use SebastianBergmann\Environment\Runtime; + +final class BuildInformation +{ + /** + * @var \DOMElement + */ + private $contextNode; + + public function __construct(\DOMElement $contextNode) + { + $this->contextNode = $contextNode; + } + + public function setRuntimeInformation(Runtime $runtime): void + { + $runtimeNode = $this->getNodeByName('runtime'); + + $runtimeNode->setAttribute('name', $runtime->getName()); + $runtimeNode->setAttribute('version', $runtime->getVersion()); + $runtimeNode->setAttribute('url', $runtime->getVendorUrl()); + + $driverNode = $this->getNodeByName('driver'); + + if ($runtime->hasPHPDBGCodeCoverage()) { + $driverNode->setAttribute('name', 'phpdbg'); + $driverNode->setAttribute('version', \constant('PHPDBG_VERSION')); + } + + if ($runtime->hasXdebug()) { + $driverNode->setAttribute('name', 'xdebug'); + $driverNode->setAttribute('version', \phpversion('xdebug')); + } + + if ($runtime->hasPCOV()) { + $driverNode->setAttribute('name', 'pcov'); + $driverNode->setAttribute('version', \phpversion('pcov')); + } + } + + public function setBuildTime(\DateTime $date): void + { + $this->contextNode->setAttribute('time', $date->format('D M j G:i:s T Y')); + } + + public function setGeneratorVersions(string $phpUnitVersion, string $coverageVersion): void + { + $this->contextNode->setAttribute('phpunit', $phpUnitVersion); + $this->contextNode->setAttribute('coverage', $coverageVersion); + } + + private function getNodeByName(string $name): \DOMElement + { + $node = $this->contextNode->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + $name + )->item(0); + + if (!$node) { + $node = $this->contextNode->appendChild( + $this->contextNode->ownerDocument->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + $name + ) + ); + } + + return $node; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php new file mode 100644 index 0000000..996a619 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Coverage.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use SebastianBergmann\CodeCoverage\RuntimeException; + +final class Coverage +{ + /** + * @var \XMLWriter + */ + private $writer; + + /** + * @var \DOMElement + */ + private $contextNode; + + /** + * @var bool + */ + private $finalized = false; + + public function __construct(\DOMElement $context, string $line) + { + $this->contextNode = $context; + + $this->writer = new \XMLWriter(); + $this->writer->openMemory(); + $this->writer->startElementNS(null, $context->nodeName, 'https://schema.phpunit.de/coverage/1.0'); + $this->writer->writeAttribute('nr', $line); + } + + /** + * @throws RuntimeException + */ + public function addTest(string $test): void + { + if ($this->finalized) { + throw new RuntimeException('Coverage Report already finalized'); + } + + $this->writer->startElement('covered'); + $this->writer->writeAttribute('by', $test); + $this->writer->endElement(); + } + + public function finalize(): void + { + $this->writer->endElement(); + + $fragment = $this->contextNode->ownerDocument->createDocumentFragment(); + $fragment->appendXML($this->writer->outputMemory()); + + $this->contextNode->parentNode->replaceChild( + $fragment, + $this->contextNode + ); + + $this->finalized = true; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php new file mode 100644 index 0000000..b182321 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Directory.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Directory extends Node +{ +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php new file mode 100644 index 0000000..c908a15 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Facade.php @@ -0,0 +1,287 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Node\AbstractNode; +use SebastianBergmann\CodeCoverage\Node\Directory as DirectoryNode; +use SebastianBergmann\CodeCoverage\Node\File as FileNode; +use SebastianBergmann\CodeCoverage\RuntimeException; +use SebastianBergmann\CodeCoverage\Version; +use SebastianBergmann\Environment\Runtime; + +final class Facade +{ + /** + * @var string + */ + private $target; + + /** + * @var Project + */ + private $project; + + /** + * @var string + */ + private $phpUnitVersion; + + public function __construct(string $version) + { + $this->phpUnitVersion = $version; + } + + /** + * @throws RuntimeException + */ + public function process(CodeCoverage $coverage, string $target): void + { + if (\substr($target, -1, 1) !== \DIRECTORY_SEPARATOR) { + $target .= \DIRECTORY_SEPARATOR; + } + + $this->target = $target; + $this->initTargetDirectory($target); + + $report = $coverage->getReport(); + + $this->project = new Project( + $coverage->getReport()->getName() + ); + + $this->setBuildInformation(); + $this->processTests($coverage->getTests()); + $this->processDirectory($report, $this->project); + + $this->saveDocument($this->project->asDom(), 'index'); + } + + private function setBuildInformation(): void + { + $buildNode = $this->project->getBuildInformation(); + $buildNode->setRuntimeInformation(new Runtime()); + $buildNode->setBuildTime(\DateTime::createFromFormat('U', (string) $_SERVER['REQUEST_TIME'])); + $buildNode->setGeneratorVersions($this->phpUnitVersion, Version::id()); + } + + /** + * @throws RuntimeException + */ + private function initTargetDirectory(string $directory): void + { + if (\file_exists($directory)) { + if (!\is_dir($directory)) { + throw new RuntimeException( + "'$directory' exists but is not a directory." + ); + } + + if (!\is_writable($directory)) { + throw new RuntimeException( + "'$directory' exists but is not writable." + ); + } + } elseif (!$this->createDirectory($directory)) { + throw new RuntimeException( + "'$directory' could not be created." + ); + } + } + + private function processDirectory(DirectoryNode $directory, Node $context): void + { + $directoryName = $directory->getName(); + + if ($this->project->getProjectSourceDirectory() === $directoryName) { + $directoryName = '/'; + } + + $directoryObject = $context->addDirectory($directoryName); + + $this->setTotals($directory, $directoryObject->getTotals()); + + foreach ($directory->getDirectories() as $node) { + $this->processDirectory($node, $directoryObject); + } + + foreach ($directory->getFiles() as $node) { + $this->processFile($node, $directoryObject); + } + } + + /** + * @throws RuntimeException + */ + private function processFile(FileNode $file, Directory $context): void + { + $fileObject = $context->addFile( + $file->getName(), + $file->getId() . '.xml' + ); + + $this->setTotals($file, $fileObject->getTotals()); + + $path = \substr( + $file->getPath(), + \strlen($this->project->getProjectSourceDirectory()) + ); + + $fileReport = new Report($path); + + $this->setTotals($file, $fileReport->getTotals()); + + foreach ($file->getClassesAndTraits() as $unit) { + $this->processUnit($unit, $fileReport); + } + + foreach ($file->getFunctions() as $function) { + $this->processFunction($function, $fileReport); + } + + foreach ($file->getCoverageData() as $line => $tests) { + if (!\is_array($tests) || \count($tests) === 0) { + continue; + } + + $coverage = $fileReport->getLineCoverage((string) $line); + + foreach ($tests as $test) { + $coverage->addTest($test); + } + + $coverage->finalize(); + } + + $fileReport->getSource()->setSourceCode( + \file_get_contents($file->getPath()) + ); + + $this->saveDocument($fileReport->asDom(), $file->getId()); + } + + private function processUnit(array $unit, Report $report): void + { + if (isset($unit['className'])) { + $unitObject = $report->getClassObject($unit['className']); + } else { + $unitObject = $report->getTraitObject($unit['traitName']); + } + + $unitObject->setLines( + $unit['startLine'], + $unit['executableLines'], + $unit['executedLines'] + ); + + $unitObject->setCrap((float) $unit['crap']); + + $unitObject->setPackage( + $unit['package']['fullPackage'], + $unit['package']['package'], + $unit['package']['subpackage'], + $unit['package']['category'] + ); + + $unitObject->setNamespace($unit['package']['namespace']); + + foreach ($unit['methods'] as $method) { + $methodObject = $unitObject->addMethod($method['methodName']); + $methodObject->setSignature($method['signature']); + $methodObject->setLines((string) $method['startLine'], (string) $method['endLine']); + $methodObject->setCrap($method['crap']); + $methodObject->setTotals( + (string) $method['executableLines'], + (string) $method['executedLines'], + (string) $method['coverage'] + ); + } + } + + private function processFunction(array $function, Report $report): void + { + $functionObject = $report->getFunctionObject($function['functionName']); + + $functionObject->setSignature($function['signature']); + $functionObject->setLines((string) $function['startLine']); + $functionObject->setCrap($function['crap']); + $functionObject->setTotals((string) $function['executableLines'], (string) $function['executedLines'], (string) $function['coverage']); + } + + private function processTests(array $tests): void + { + $testsObject = $this->project->getTests(); + + foreach ($tests as $test => $result) { + if ($test === 'UNCOVERED_FILES_FROM_WHITELIST') { + continue; + } + + $testsObject->addTest($test, $result); + } + } + + private function setTotals(AbstractNode $node, Totals $totals): void + { + $loc = $node->getLinesOfCode(); + + $totals->setNumLines( + $loc['loc'], + $loc['cloc'], + $loc['ncloc'], + $node->getNumExecutableLines(), + $node->getNumExecutedLines() + ); + + $totals->setNumClasses( + $node->getNumClasses(), + $node->getNumTestedClasses() + ); + + $totals->setNumTraits( + $node->getNumTraits(), + $node->getNumTestedTraits() + ); + + $totals->setNumMethods( + $node->getNumMethods(), + $node->getNumTestedMethods() + ); + + $totals->setNumFunctions( + $node->getNumFunctions(), + $node->getNumTestedFunctions() + ); + } + + private function getTargetDirectory(): string + { + return $this->target; + } + + /** + * @throws RuntimeException + */ + private function saveDocument(\DOMDocument $document, string $name): void + { + $filename = \sprintf('%s/%s.xml', $this->getTargetDirectory(), $name); + + $document->formatOutput = true; + $document->preserveWhiteSpace = false; + $this->initTargetDirectory(\dirname($filename)); + + $document->save($filename); + } + + private function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php new file mode 100644 index 0000000..02af644 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/File.php @@ -0,0 +1,81 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +class File +{ + /** + * @var \DOMDocument + */ + private $dom; + + /** + * @var \DOMElement + */ + private $contextNode; + + public function __construct(\DOMElement $context) + { + $this->dom = $context->ownerDocument; + $this->contextNode = $context; + } + + public function getTotals(): Totals + { + $totalsContainer = $this->contextNode->firstChild; + + if (!$totalsContainer) { + $totalsContainer = $this->contextNode->appendChild( + $this->dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'totals' + ) + ); + } + + return new Totals($totalsContainer); + } + + public function getLineCoverage(string $line): Coverage + { + $coverage = $this->contextNode->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'coverage' + )->item(0); + + if (!$coverage) { + $coverage = $this->contextNode->appendChild( + $this->dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'coverage' + ) + ); + } + + $lineNode = $coverage->appendChild( + $this->dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'line' + ) + ); + + return new Coverage($lineNode, $line); + } + + protected function getContextNode(): \DOMElement + { + return $this->contextNode; + } + + protected function getDomDocument(): \DOMDocument + { + return $this->dom; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php new file mode 100644 index 0000000..b6a7f16 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Method.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Method +{ + /** + * @var \DOMElement + */ + private $contextNode; + + public function __construct(\DOMElement $context, string $name) + { + $this->contextNode = $context; + + $this->setName($name); + } + + public function setSignature(string $signature): void + { + $this->contextNode->setAttribute('signature', $signature); + } + + public function setLines(string $start, ?string $end = null): void + { + $this->contextNode->setAttribute('start', $start); + + if ($end !== null) { + $this->contextNode->setAttribute('end', $end); + } + } + + public function setTotals(string $executable, string $executed, string $coverage): void + { + $this->contextNode->setAttribute('executable', $executable); + $this->contextNode->setAttribute('executed', $executed); + $this->contextNode->setAttribute('coverage', $coverage); + } + + public function setCrap(string $crap): void + { + $this->contextNode->setAttribute('crap', $crap); + } + + private function setName(string $name): void + { + $this->contextNode->setAttribute('name', $name); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php new file mode 100644 index 0000000..d3ba223 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Node.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +abstract class Node +{ + /** + * @var \DOMDocument + */ + private $dom; + + /** + * @var \DOMElement + */ + private $contextNode; + + public function __construct(\DOMElement $context) + { + $this->setContextNode($context); + } + + public function getDom(): \DOMDocument + { + return $this->dom; + } + + public function getTotals(): Totals + { + $totalsContainer = $this->getContextNode()->firstChild; + + if (!$totalsContainer) { + $totalsContainer = $this->getContextNode()->appendChild( + $this->dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'totals' + ) + ); + } + + return new Totals($totalsContainer); + } + + public function addDirectory(string $name): Directory + { + $dirNode = $this->getDom()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'directory' + ); + + $dirNode->setAttribute('name', $name); + $this->getContextNode()->appendChild($dirNode); + + return new Directory($dirNode); + } + + public function addFile(string $name, string $href): File + { + $fileNode = $this->getDom()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'file' + ); + + $fileNode->setAttribute('name', $name); + $fileNode->setAttribute('href', $href); + $this->getContextNode()->appendChild($fileNode); + + return new File($fileNode); + } + + protected function setContextNode(\DOMElement $context): void + { + $this->dom = $context->ownerDocument; + $this->contextNode = $context; + } + + protected function getContextNode(): \DOMElement + { + return $this->contextNode; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php new file mode 100644 index 0000000..5f32852 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Project.php @@ -0,0 +1,85 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Project extends Node +{ + public function __construct(string $directory) + { + $this->init(); + $this->setProjectSourceDirectory($directory); + } + + public function getProjectSourceDirectory(): string + { + return $this->getContextNode()->getAttribute('source'); + } + + public function getBuildInformation(): BuildInformation + { + $buildNode = $this->getDom()->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'build' + )->item(0); + + if (!$buildNode) { + $buildNode = $this->getDom()->documentElement->appendChild( + $this->getDom()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'build' + ) + ); + } + + return new BuildInformation($buildNode); + } + + public function getTests(): Tests + { + $testsNode = $this->getContextNode()->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'tests' + )->item(0); + + if (!$testsNode) { + $testsNode = $this->getContextNode()->appendChild( + $this->getDom()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'tests' + ) + ); + } + + return new Tests($testsNode); + } + + public function asDom(): \DOMDocument + { + return $this->getDom(); + } + + private function init(): void + { + $dom = new \DOMDocument; + $dom->loadXML(''); + + $this->setContextNode( + $dom->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'project' + )->item(0) + ); + } + + private function setProjectSourceDirectory(string $name): void + { + $this->getContextNode()->setAttribute('source', $name); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php new file mode 100644 index 0000000..6ec94c1 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Report.php @@ -0,0 +1,92 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Report extends File +{ + public function __construct(string $name) + { + $dom = new \DOMDocument(); + $dom->loadXML(''); + + $contextNode = $dom->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'file' + )->item(0); + + parent::__construct($contextNode); + + $this->setName($name); + } + + public function asDom(): \DOMDocument + { + return $this->getDomDocument(); + } + + public function getFunctionObject($name): Method + { + $node = $this->getContextNode()->appendChild( + $this->getDomDocument()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'function' + ) + ); + + return new Method($node, $name); + } + + public function getClassObject($name): Unit + { + return $this->getUnitObject('class', $name); + } + + public function getTraitObject($name): Unit + { + return $this->getUnitObject('trait', $name); + } + + public function getSource(): Source + { + $source = $this->getContextNode()->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'source' + )->item(0); + + if (!$source) { + $source = $this->getContextNode()->appendChild( + $this->getDomDocument()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'source' + ) + ); + } + + return new Source($source); + } + + private function setName($name): void + { + $this->getContextNode()->setAttribute('name', \basename($name)); + $this->getContextNode()->setAttribute('path', \dirname($name)); + } + + private function getUnitObject($tagName, $name): Unit + { + $node = $this->getContextNode()->appendChild( + $this->getDomDocument()->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + $tagName + ) + ); + + return new Unit($node, $name); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php new file mode 100644 index 0000000..67bf9cb --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Source.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use TheSeer\Tokenizer\NamespaceUri; +use TheSeer\Tokenizer\Tokenizer; +use TheSeer\Tokenizer\XMLSerializer; + +final class Source +{ + /** @var \DOMElement */ + private $context; + + public function __construct(\DOMElement $context) + { + $this->context = $context; + } + + public function setSourceCode(string $source): void + { + $context = $this->context; + + $tokens = (new Tokenizer())->parse($source); + $srcDom = (new XMLSerializer(new NamespaceUri($context->namespaceURI)))->toDom($tokens); + + $context->parentNode->replaceChild( + $context->ownerDocument->importNode($srcDom->documentElement, true), + $context + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php new file mode 100644 index 0000000..c1bcd25 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Tests.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Tests +{ + private $contextNode; + + private $codeMap = [ + -1 => 'UNKNOWN', // PHPUnit_Runner_BaseTestRunner::STATUS_UNKNOWN + 0 => 'PASSED', // PHPUnit_Runner_BaseTestRunner::STATUS_PASSED + 1 => 'SKIPPED', // PHPUnit_Runner_BaseTestRunner::STATUS_SKIPPED + 2 => 'INCOMPLETE', // PHPUnit_Runner_BaseTestRunner::STATUS_INCOMPLETE + 3 => 'FAILURE', // PHPUnit_Runner_BaseTestRunner::STATUS_FAILURE + 4 => 'ERROR', // PHPUnit_Runner_BaseTestRunner::STATUS_ERROR + 5 => 'RISKY', // PHPUnit_Runner_BaseTestRunner::STATUS_RISKY + 6 => 'WARNING', // PHPUnit_Runner_BaseTestRunner::STATUS_WARNING + ]; + + public function __construct(\DOMElement $context) + { + $this->contextNode = $context; + } + + public function addTest(string $test, array $result): void + { + $node = $this->contextNode->appendChild( + $this->contextNode->ownerDocument->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'test' + ) + ); + + $node->setAttribute('name', $test); + $node->setAttribute('size', $result['size']); + $node->setAttribute('result', (string) $result['status']); + $node->setAttribute('status', $this->codeMap[(int) $result['status']]); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php new file mode 100644 index 0000000..019f348 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Totals.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use SebastianBergmann\CodeCoverage\Util; + +final class Totals +{ + /** + * @var \DOMNode + */ + private $container; + + /** + * @var \DOMElement + */ + private $linesNode; + + /** + * @var \DOMElement + */ + private $methodsNode; + + /** + * @var \DOMElement + */ + private $functionsNode; + + /** + * @var \DOMElement + */ + private $classesNode; + + /** + * @var \DOMElement + */ + private $traitsNode; + + public function __construct(\DOMElement $container) + { + $this->container = $container; + $dom = $container->ownerDocument; + + $this->linesNode = $dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'lines' + ); + + $this->methodsNode = $dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'methods' + ); + + $this->functionsNode = $dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'functions' + ); + + $this->classesNode = $dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'classes' + ); + + $this->traitsNode = $dom->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'traits' + ); + + $container->appendChild($this->linesNode); + $container->appendChild($this->methodsNode); + $container->appendChild($this->functionsNode); + $container->appendChild($this->classesNode); + $container->appendChild($this->traitsNode); + } + + public function getContainer(): \DOMNode + { + return $this->container; + } + + public function setNumLines(int $loc, int $cloc, int $ncloc, int $executable, int $executed): void + { + $this->linesNode->setAttribute('total', (string) $loc); + $this->linesNode->setAttribute('comments', (string) $cloc); + $this->linesNode->setAttribute('code', (string) $ncloc); + $this->linesNode->setAttribute('executable', (string) $executable); + $this->linesNode->setAttribute('executed', (string) $executed); + $this->linesNode->setAttribute( + 'percent', + $executable === 0 ? '0' : \sprintf('%01.2F', Util::percent($executed, $executable)) + ); + } + + public function setNumClasses(int $count, int $tested): void + { + $this->classesNode->setAttribute('count', (string) $count); + $this->classesNode->setAttribute('tested', (string) $tested); + $this->classesNode->setAttribute( + 'percent', + $count === 0 ? '0' : \sprintf('%01.2F', Util::percent($tested, $count)) + ); + } + + public function setNumTraits(int $count, int $tested): void + { + $this->traitsNode->setAttribute('count', (string) $count); + $this->traitsNode->setAttribute('tested', (string) $tested); + $this->traitsNode->setAttribute( + 'percent', + $count === 0 ? '0' : \sprintf('%01.2F', Util::percent($tested, $count)) + ); + } + + public function setNumMethods(int $count, int $tested): void + { + $this->methodsNode->setAttribute('count', (string) $count); + $this->methodsNode->setAttribute('tested', (string) $tested); + $this->methodsNode->setAttribute( + 'percent', + $count === 0 ? '0' : \sprintf('%01.2F', Util::percent($tested, $count)) + ); + } + + public function setNumFunctions(int $count, int $tested): void + { + $this->functionsNode->setAttribute('count', (string) $count); + $this->functionsNode->setAttribute('tested', (string) $tested); + $this->functionsNode->setAttribute( + 'percent', + $count === 0 ? '0' : \sprintf('%01.2F', Util::percent($tested, $count)) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php b/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php new file mode 100644 index 0000000..c235dfb --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Report/Xml/Unit.php @@ -0,0 +1,95 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +final class Unit +{ + /** + * @var \DOMElement + */ + private $contextNode; + + public function __construct(\DOMElement $context, string $name) + { + $this->contextNode = $context; + + $this->setName($name); + } + + public function setLines(int $start, int $executable, int $executed): void + { + $this->contextNode->setAttribute('start', (string) $start); + $this->contextNode->setAttribute('executable', (string) $executable); + $this->contextNode->setAttribute('executed', (string) $executed); + } + + public function setCrap(float $crap): void + { + $this->contextNode->setAttribute('crap', (string) $crap); + } + + public function setPackage(string $full, string $package, string $sub, string $category): void + { + $node = $this->contextNode->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'package' + )->item(0); + + if (!$node) { + $node = $this->contextNode->appendChild( + $this->contextNode->ownerDocument->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'package' + ) + ); + } + + $node->setAttribute('full', $full); + $node->setAttribute('name', $package); + $node->setAttribute('sub', $sub); + $node->setAttribute('category', $category); + } + + public function setNamespace(string $namespace): void + { + $node = $this->contextNode->getElementsByTagNameNS( + 'https://schema.phpunit.de/coverage/1.0', + 'namespace' + )->item(0); + + if (!$node) { + $node = $this->contextNode->appendChild( + $this->contextNode->ownerDocument->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'namespace' + ) + ); + } + + $node->setAttribute('name', $namespace); + } + + public function addMethod(string $name): Method + { + $node = $this->contextNode->appendChild( + $this->contextNode->ownerDocument->createElementNS( + 'https://schema.phpunit.de/coverage/1.0', + 'method' + ) + ); + + return new Method($node, $name); + } + + private function setName(string $name): void + { + $this->contextNode->setAttribute('name', $name); + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Util.php b/vendor/phpunit/php-code-coverage/src/Util.php new file mode 100644 index 0000000..ee8894c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Util.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +/** + * Utility methods. + */ +final class Util +{ + /** + * @return float|int|string + */ + public static function percent(float $a, float $b, bool $asString = false, bool $fixedWidth = false) + { + if ($asString && $b == 0) { + return ''; + } + + $percent = 100; + + if ($b > 0) { + $percent = ($a / $b) * 100; + } + + if ($asString) { + $format = $fixedWidth ? '%6.2F%%' : '%01.2F%%'; + + return \sprintf($format, $percent); + } + + return $percent; + } +} diff --git a/vendor/phpunit/php-code-coverage/src/Version.php b/vendor/phpunit/php-code-coverage/src/Version.php new file mode 100644 index 0000000..bcf232d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/src/Version.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use SebastianBergmann\Version as VersionId; + +final class Version +{ + /** + * @var string + */ + private static $version; + + public static function id(): string + { + if (self::$version === null) { + $version = new VersionId('7.0.10', \dirname(__DIR__)); + self::$version = $version->getVersion(); + } + + return self::$version; + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/TestCase.php b/vendor/phpunit/php-code-coverage/tests/TestCase.php new file mode 100644 index 0000000..6a9824e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/TestCase.php @@ -0,0 +1,395 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\CodeCoverage; + +use SebastianBergmann\CodeCoverage\Driver\Driver; +use SebastianBergmann\CodeCoverage\Report\Xml\Coverage; + +abstract class TestCase extends \PHPUnit\Framework\TestCase +{ + protected static $TEST_TMP_PATH; + + public static function setUpBeforeClass(): void + { + self::$TEST_TMP_PATH = TEST_FILES_PATH . 'tmp'; + } + + protected function getXdebugDataForBankAccount() + { + return [ + [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => 1, + 9 => -2, + 13 => -1, + 14 => -1, + 15 => -1, + 16 => -1, + 18 => -1, + 22 => -1, + 24 => -1, + 25 => -2, + 29 => -1, + 31 => -1, + 32 => -2 + ] + ], + [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => 1, + 13 => 1, + 16 => 1, + 29 => 1, + ] + ], + [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => 1, + 13 => 1, + 16 => 1, + 22 => 1, + ] + ], + [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => 1, + 13 => 1, + 14 => 1, + 15 => 1, + 18 => 1, + 22 => 1, + 24 => 1, + 29 => 1, + 31 => 1, + ] + ] + ]; + } + + protected function getCoverageForBankAccount(): CodeCoverage + { + $data = $this->getXdebugDataForBankAccount(); + + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->onConsecutiveCalls( + $data[0], + $data[1], + $data[2], + $data[3] + )); + + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php'); + + $coverage = new CodeCoverage($stub, $filter); + + $coverage->start( + new \BankAccountTest('testBalanceIsInitiallyZero'), + true + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(6, 9)] + ); + + $coverage->start( + new \BankAccountTest('testBalanceCannotBecomeNegative') + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(27, 32)] + ); + + $coverage->start( + new \BankAccountTest('testBalanceCannotBecomeNegative2') + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(20, 25)] + ); + + $coverage->start( + new \BankAccountTest('testDepositWithdrawMoney') + ); + + $coverage->stop( + true, + [ + TEST_FILES_PATH . 'BankAccount.php' => array_merge( + range(6, 9), + range(20, 25), + range(27, 32) + ) + ] + ); + + return $coverage; + } + + protected function getCoverageForBankAccountForFirstTwoTests(): CodeCoverage + { + $data = $this->getXdebugDataForBankAccount(); + + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->onConsecutiveCalls( + $data[0], + $data[1] + )); + + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php'); + + $coverage = new CodeCoverage($stub, $filter); + + $coverage->start( + new \BankAccountTest('testBalanceIsInitiallyZero'), + true + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(6, 9)] + ); + + $coverage->start( + new \BankAccountTest('testBalanceCannotBecomeNegative') + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(27, 32)] + ); + + return $coverage; + } + + protected function getCoverageForBankAccountForLastTwoTests() + { + $data = $this->getXdebugDataForBankAccount(); + + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->onConsecutiveCalls( + $data[2], + $data[3] + )); + + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'BankAccount.php'); + + $coverage = new CodeCoverage($stub, $filter); + + $coverage->start( + new \BankAccountTest('testBalanceCannotBecomeNegative2') + ); + + $coverage->stop( + true, + [TEST_FILES_PATH . 'BankAccount.php' => range(20, 25)] + ); + + $coverage->start( + new \BankAccountTest('testDepositWithdrawMoney') + ); + + $coverage->stop( + true, + [ + TEST_FILES_PATH . 'BankAccount.php' => array_merge( + range(6, 9), + range(20, 25), + range(27, 32) + ) + ] + ); + + return $coverage; + } + + protected function getExpectedDataArrayForBankAccount(): array + { + return [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => [ + 0 => 'BankAccountTest::testBalanceIsInitiallyZero', + 1 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 9 => null, + 13 => [], + 14 => [], + 15 => [], + 16 => [], + 18 => [], + 22 => [ + 0 => 'BankAccountTest::testBalanceCannotBecomeNegative2', + 1 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 24 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney', + ], + 25 => null, + 29 => [ + 0 => 'BankAccountTest::testBalanceCannotBecomeNegative', + 1 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 31 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 32 => null + ] + ]; + } + + protected function getExpectedDataArrayForBankAccountInReverseOrder(): array + { + return [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 8 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney', + 1 => 'BankAccountTest::testBalanceIsInitiallyZero' + ], + 9 => null, + 13 => [], + 14 => [], + 15 => [], + 16 => [], + 18 => [], + 22 => [ + 0 => 'BankAccountTest::testBalanceCannotBecomeNegative2', + 1 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 24 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney', + ], + 25 => null, + 29 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney', + 1 => 'BankAccountTest::testBalanceCannotBecomeNegative' + ], + 31 => [ + 0 => 'BankAccountTest::testDepositWithdrawMoney' + ], + 32 => null + ] + ]; + } + + protected function getCoverageForFileWithIgnoredLines(): CodeCoverage + { + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'source_with_ignore.php'); + + $coverage = new CodeCoverage( + $this->setUpXdebugStubForFileWithIgnoredLines(), + $filter + ); + + $coverage->start('FileWithIgnoredLines', true); + $coverage->stop(); + + return $coverage; + } + + protected function setUpXdebugStubForFileWithIgnoredLines(): Driver + { + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->returnValue( + [ + TEST_FILES_PATH . 'source_with_ignore.php' => [ + 2 => 1, + 4 => -1, + 6 => -1, + 7 => 1 + ] + ] + )); + + return $stub; + } + + protected function getCoverageForClassWithAnonymousFunction(): CodeCoverage + { + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php'); + + $coverage = new CodeCoverage( + $this->setUpXdebugStubForClassWithAnonymousFunction(), + $filter + ); + + $coverage->start('ClassWithAnonymousFunction', true); + $coverage->stop(); + + return $coverage; + } + + protected function setUpXdebugStubForClassWithAnonymousFunction(): Driver + { + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->returnValue( + [ + TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php' => [ + 7 => 1, + 9 => 1, + 10 => -1, + 11 => 1, + 12 => 1, + 13 => 1, + 14 => 1, + 17 => 1, + 18 => 1 + ] + ] + )); + + return $stub; + } + + protected function getCoverageForCrashParsing(): CodeCoverage + { + $filter = new Filter; + $filter->addFileToWhitelist(TEST_FILES_PATH . 'Crash.php'); + + // This is a file with invalid syntax, so it isn't executed. + return new CodeCoverage( + $this->setUpXdebugStubForCrashParsing(), + $filter + ); + } + + protected function setUpXdebugStubForCrashParsing(): Driver + { + $stub = $this->createMock(Driver::class); + + $stub->expects($this->any()) + ->method('stop') + ->will($this->returnValue([])); + return $stub; + } + +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml new file mode 100644 index 0000000..2f11d81 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-clover.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml new file mode 100644 index 0000000..f2f56ea --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-crap4j.xml @@ -0,0 +1,59 @@ + + + BankAccount + %s + + Method Crap Stats + 4 + 0 + 0 + 9 + 0 + + + + global + BankAccount + getBalance + getBalance() + getBalance() + 1 + 1 + 100 + 0 + + + global + BankAccount + setBalance + setBalance($balance) + setBalance($balance) + 6 + 2 + 0 + 0 + + + global + BankAccount + depositMoney + depositMoney($balance) + depositMoney($balance) + 1 + 1 + 100 + 0 + + + global + BankAccount + withdrawMoney + withdrawMoney($balance) + withdrawMoney($balance) + 1 + 1 + 100 + 0 + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt new file mode 100644 index 0000000..892d834 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount-text.txt @@ -0,0 +1,12 @@ + + +Code Coverage Report: + %s + + Summary: + Classes: 0.00% (0/1) + Methods: 75.00% (3/4) + Lines: 50.00% (5/10) + +BankAccount + Methods: 75.00% ( 3/ 4) Lines: 50.00% ( 5/ 10) diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php new file mode 100644 index 0000000..4238c15 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccount.php @@ -0,0 +1,33 @@ +balance; + } + + protected function setBalance($balance) + { + if ($balance >= 0) { + $this->balance = $balance; + } else { + throw new RuntimeException; + } + } + + public function depositMoney($balance) + { + $this->setBalance($this->getBalance() + $balance); + + return $this->getBalance(); + } + + public function withdrawMoney($balance) + { + $this->setBalance($this->getBalance() - $balance); + + return $this->getBalance(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php b/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php new file mode 100644 index 0000000..803c892 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/BankAccountTest.php @@ -0,0 +1,66 @@ +ba = new BankAccount; + } + + /** + * @covers BankAccount::getBalance + */ + public function testBalanceIsInitiallyZero() + { + $this->assertEquals(0, $this->ba->getBalance()); + } + + /** + * @covers BankAccount::withdrawMoney + */ + public function testBalanceCannotBecomeNegative() + { + try { + $this->ba->withdrawMoney(1); + } catch (RuntimeException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::depositMoney + */ + public function testBalanceCannotBecomeNegative2() + { + try { + $this->ba->depositMoney(-1); + } catch (RuntimeException $e) { + $this->assertEquals(0, $this->ba->getBalance()); + + return; + } + + $this->fail(); + } + + /** + * @covers BankAccount::getBalance + * @covers BankAccount::depositMoney + * @covers BankAccount::withdrawMoney + */ + public function testDepositWithdrawMoney() + { + $this->assertEquals(0, $this->ba->getBalance()); + $this->ba->depositMoney(1); + $this->assertEquals(1, $this->ba->getBalance()); + $this->ba->withdrawMoney(1); + $this->assertEquals(0, $this->ba->getBalance()); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php new file mode 100644 index 0000000..e6d496e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassExtendedTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php new file mode 100644 index 0000000..baa04d8 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageClassTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php new file mode 100644 index 0000000..560e381 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageFunctionParenthesesTest.php @@ -0,0 +1,13 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php new file mode 100644 index 0000000..b624ed9 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php new file mode 100644 index 0000000..20d2e75 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodParenthesesWhitespaceTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php new file mode 100644 index 0000000..fb7a882 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageMethodTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php new file mode 100644 index 0000000..d8d9cae --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNoneTest.php @@ -0,0 +1,11 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php new file mode 100644 index 0000000..e98efd8 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPrivateTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php new file mode 100644 index 0000000..7c9c488 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotProtectedTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php new file mode 100644 index 0000000..202724a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNotPublicTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php new file mode 100644 index 0000000..4e1c0d0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageNothingTest.php @@ -0,0 +1,15 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php new file mode 100644 index 0000000..849c348 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePrivateTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php new file mode 100644 index 0000000..6ae3544 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageProtectedTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php new file mode 100644 index 0000000..d977090 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveragePublicTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php b/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php new file mode 100644 index 0000000..06949cb --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoverageTwoDefaultClassAnnotations.php @@ -0,0 +1,17 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } + +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php new file mode 100644 index 0000000..f382ce9 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveredClass.php @@ -0,0 +1,36 @@ +privateMethod(); + } + + public function publicMethod() + { + $this->protectedMethod(); + } +} + +class CoveredClass extends CoveredParentClass +{ + private function privateMethod() + { + } + + protected function protectedMethod() + { + parent::protectedMethod(); + $this->privateMethod(); + } + + public function publicMethod() + { + parent::publicMethod(); + $this->protectedMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php b/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php new file mode 100644 index 0000000..9989eb0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/CoveredFunction.php @@ -0,0 +1,4 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php new file mode 100644 index 0000000..2b91f1f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageClassTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php new file mode 100644 index 0000000..d3bc1a9 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassPublicTest.php @@ -0,0 +1,17 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php new file mode 100644 index 0000000..67752dd --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageCoversClassTest.php @@ -0,0 +1,22 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php new file mode 100644 index 0000000..f83ae5f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageMethodTest.php @@ -0,0 +1,14 @@ +publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php new file mode 100644 index 0000000..b4983c7 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPrivateTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php new file mode 100644 index 0000000..ceb7b35 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotProtectedTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php new file mode 100644 index 0000000..60aff7a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageNotPublicTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php new file mode 100644 index 0000000..d5eb77e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePrivateTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php new file mode 100644 index 0000000..6a6eaca --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoverageProtectedTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php new file mode 100644 index 0000000..f32803e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveragePublicTest.php @@ -0,0 +1,14 @@ + + */ + public function testSomething() + { + $o = new Foo\CoveredClass; + $o->publicMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php new file mode 100644 index 0000000..5bd0ddf --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NamespaceCoveredClass.php @@ -0,0 +1,38 @@ +privateMethod(); + } + + public function publicMethod() + { + $this->protectedMethod(); + } +} + +class CoveredClass extends CoveredParentClass +{ + private function privateMethod() + { + } + + protected function protectedMethod() + { + parent::protectedMethod(); + $this->privateMethod(); + } + + public function publicMethod() + { + parent::publicMethod(); + $this->protectedMethod(); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php b/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php new file mode 100644 index 0000000..0836a8c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/NotExistingCoveredElementTest.php @@ -0,0 +1,26 @@ + + */ + public function testThree() + { + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html new file mode 100644 index 0000000..467602e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/BankAccount.php.html @@ -0,0 +1,249 @@ + + + + + Code Coverage for %s%eBankAccount.php + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 75.00% covered (warning) +
+
+
75.00%
3 / 4
CRAP
+
+ 50.00% covered (danger) +
+
+
50.00%
5 / 10
BankAccount
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 75.00% covered (warning) +
+
+
75.00%
3 / 4
8.12
+
+ 50.00% covered (danger) +
+
+
50.00%
5 / 10
 getBalance
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
1
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
 setBalance
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
6
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 5
 depositMoney
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
1
+
+ 100.00% covered (success) +
+
+
100.00%
2 / 2
 withdrawMoney
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
1
+
+ 100.00% covered (success) +
+
+
100.00%
2 / 2
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
<?php
class BankAccount
{
    protected $balance = 0;
    public function getBalance()
    {
        return $this->balance;
    }
    protected function setBalance($balance)
    {
        if ($balance >= 0) {
            $this->balance = $balance;
        } else {
            throw new RuntimeException;
        }
    }
    public function depositMoney($balance)
    {
        $this->setBalance($this->getBalance() + $balance);
        return $this->getBalance();
    }
    public function withdrawMoney($balance)
    {
        $this->setBalance($this->getBalance() - $balance);
        return $this->getBalance();
    }
}
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html new file mode 100644 index 0000000..e47929f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/dashboard.html @@ -0,0 +1,287 @@ + + + + + Dashboard for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+
+

Classes

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + + +
ClassCoverage
BankAccount50%
+
+
+
+

Project Risks

+
+ + + + + + + + + + + +
ClassCRAP
BankAccount8
+
+
+
+
+
+

Methods

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + + +
MethodCoverage
setBalance0%
+
+
+
+

Project Risks

+
+ + + + + + + + + + + +
MethodCRAP
setBalance6
+
+
+
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html new file mode 100644 index 0000000..e0c9ed9 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForBankAccount/index.html @@ -0,0 +1,118 @@ + + + + + Code Coverage for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
+
+ 50.00% covered (danger) +
+
+
50.00%
5 / 10
+
+ 75.00% covered (warning) +
+
+
75.00%
3 / 4
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
BankAccount.php
+
+ 50.00% covered (danger) +
+
+
50.00%
5 / 10
+
+ 75.00% covered (warning) +
+
+
75.00%
3 / 4
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+
+
+

Legend

+

+ Low: 0% to 50% + Medium: 50% to 90% + High: 90% to 100% +

+

+ Generated by php-code-coverage %s using %s at %s. +

+
+
+ + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html new file mode 100644 index 0000000..8b27809 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/dashboard.html @@ -0,0 +1,285 @@ + + + + + Dashboard for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+
+

Classes

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + + +
ClassCoverage
CoveredClassWithAnonymousFunctionInStaticMethod87%
+
+
+
+

Project Risks

+
+ + + + + + + + + + +
ClassCRAP
+
+
+
+
+
+

Methods

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + + +
MethodCoverage
runAnonymous87%
+
+
+
+

Project Risks

+
+ + + + + + + + + + +
MethodCRAP
+
+
+
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html new file mode 100644 index 0000000..68318d0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/index.html @@ -0,0 +1,118 @@ + + + + + Code Coverage for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
+
+ 87.50% covered (warning) +
+
+
87.50%
7 / 8
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
source_with_class_and_anonymous_function.php
+
+ 87.50% covered (warning) +
+
+
87.50%
7 / 8
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+
+
+

Legend

+

+ Low: 0% to 50% + Medium: 50% to 90% + High: 90% to 100% +

+

+ Generated by php-code-coverage %s using %s at %s. +

+
+
+ + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html new file mode 100644 index 0000000..c261c6e --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.html @@ -0,0 +1,172 @@ + + + + + Code Coverage for %s%esource_with_class_and_anonymous_function.php + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
CRAP
+
+ 87.50% covered (warning) +
+
+
87.50%
7 / 8
CoveredClassWithAnonymousFunctionInStaticMethod
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
1.00
+
+ 87.50% covered (warning) +
+
+
87.50%
7 / 8
 runAnonymous
+
+ 0.00% covered (danger) +
+
+
0.00%
0 / 1
1.00
+
+ 87.50% covered (warning) +
+
+
87.50%
7 / 8
+
+ + + + + + + + + + + + + + + + + + + + + + + +
<?php
class CoveredClassWithAnonymousFunctionInStaticMethod
{
    public static function runAnonymous()
    {
        $filter = ['abc124', 'abc123', '123'];
        array_walk(
            $filter,
            function (&$val, $key) {
                $val = preg_replace('|[^0-9]|', '', $val);
            }
        );
        // Should be covered
        $extravar = true;
    }
}
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html new file mode 100644 index 0000000..4cf93ad --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/dashboard.html @@ -0,0 +1,283 @@ + + + + + Dashboard for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+
+

Classes

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + +
ClassCoverage
+
+
+
+

Project Risks

+
+ + + + + + + + + + +
ClassCRAP
+
+
+
+
+
+

Methods

+
+
+
+
+

Coverage Distribution

+
+ +
+
+
+

Complexity

+
+ +
+
+
+
+
+

Insufficient Coverage

+
+ + + + + + + + + + +
MethodCoverage
+
+
+
+

Project Risks

+
+ + + + + + + + + + +
MethodCRAP
+
+
+
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html new file mode 100644 index 0000000..7d4cfff --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/index.html @@ -0,0 +1,108 @@ + + + + + Code Coverage for %s + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
+
+ 50.00% covered (danger) +
+
+
50.00%
1 / 2
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
n/a
0 / 0
source_with_ignore.php
+
+ 50.00% covered (danger) +
+
+
50.00%
1 / 2
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
n/a
0 / 0
+
+
+
+

Legend

+

+ Low: 0% to 50% + Medium: 50% to 90% + High: 90% to 100% +

+

+ Generated by php-code-coverage %s using %s at %s. +

+
+
+ + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html new file mode 100644 index 0000000..a18a5aa --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/HTML/CoverageForFileWithIgnoredLines/source_with_ignore.php.html @@ -0,0 +1,196 @@ + + + + + Code Coverage for %s%esource_with_ignore.php + + + + + + + +
+
+
+
+ +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
 
Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
n/a
0 / 0
+
+ 100.00% covered (success) +
+
+
100.00%
1 / 1
CRAP
+
+ 50.00% covered (danger) +
+
+
50.00%
1 / 2
baz
n/a
0 / 0
1
n/a
0 / 0
Foo
n/a
0 / 0
n/a
0 / 0
1
n/a
0 / 0
 bar
n/a
0 / 0
1
n/a
0 / 0
Bar
n/a
0 / 0
n/a
0 / 0
1
n/a
0 / 0
 foo
n/a
0 / 0
1
n/a
0 / 0
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
<?php
if ($neverHappens) {
    // @codeCoverageIgnoreStart
    print '*';
    // @codeCoverageIgnoreEnd
}
/**
 * @codeCoverageIgnore
 */
class Foo
{
    public function bar()
    {
    }
}
class Bar
{
    /**
     * @codeCoverageIgnore
     */
    public function foo()
    {
    }
}
function baz()
{
    print '*'; // @codeCoverageIgnore
}
interface Bor
{
    public function foo();
}
+ +
+ + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml new file mode 100644 index 0000000..238548b --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/BankAccount.php.xml @@ -0,0 +1,262 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?php + + + class + + BankAccount + + + { + + + + protected + + $balance + + = + + 0 + ; + + + + + public + + function + + getBalance + ( + ) + + + + { + + + + return + + $this + -> + balance + ; + + + + } + + + + + protected + + function + + setBalance + ( + $balance + ) + + + + { + + + + if + + ( + $balance + + >= + + 0 + ) + + { + + + + $this + -> + balance + + = + + $balance + ; + + + + } + + else + + { + + + + throw + + new + + RuntimeException + ; + + + + } + + + + } + + + + + public + + function + + depositMoney + ( + $balance + ) + + + + { + + + + $this + -> + setBalance + ( + $this + -> + getBalance + ( + ) + + + + + $balance + ) + ; + + + + + return + + $this + -> + getBalance + ( + ) + ; + + + + } + + + + + public + + function + + withdrawMoney + ( + $balance + ) + + + + { + + + + $this + -> + setBalance + ( + $this + -> + getBalance + ( + ) + + - + + $balance + ) + ; + + + + + return + + $this + -> + getBalance + ( + ) + ; + + + + } + + + } + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml new file mode 100644 index 0000000..df433b0 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForBankAccount/index.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml new file mode 100644 index 0000000..c8d90ba --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/index.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml new file mode 100644 index 0000000..a413174 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForClassWithAnonymousFunction/source_with_class_and_anonymous_function.php.xml @@ -0,0 +1,161 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?php + + + + class + + CoveredClassWithAnonymousFunctionInStaticMethod + + + { + + + + public + + static + + function + + runAnonymous + ( + ) + + + + { + + + + $filter + + = + + [ + 'abc124' + , + + 'abc123' + , + + '123' + ] + ; + + + + + array_walk + ( + + + + $filter + , + + + + function + + ( + & + $val + , + + $key + ) + + { + + + + $val + + = + + preg_replace + ( + '|[^0-9]|' + , + + '' + , + + $val + ) + ; + + + + } + + + + ) + ; + + + + + // Should be covered + + + + $extravar + + = + + true + ; + + + + } + + + } + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml new file mode 100644 index 0000000..d44f970 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/index.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml new file mode 100644 index 0000000..5ff1d6b --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/Report/XML/CoverageForFileWithIgnoredLines/source_with_ignore.php.xml @@ -0,0 +1,187 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + <?php + + + if + + ( + $neverHappens + ) + + { + + + + // @codeCoverageIgnoreStart + + + + print + + '*' + ; + + + + // @codeCoverageIgnoreEnd + + + } + + + + /** + + + * @codeCoverageIgnore + + + */ + + + class + + Foo + + + { + + + + public + + function + + bar + ( + ) + + + + { + + + + } + + + } + + + + class + + Bar + + + { + + + + /** + + + * @codeCoverageIgnore + + + */ + + + + public + + function + + foo + ( + ) + + + + { + + + + } + + + } + + + + function + + baz + ( + ) + + + { + + + + print + + '*' + ; + + // @codeCoverageIgnore + + + } + + + + interface + + Bor + + + { + + + + public + + function + + foo + ( + ) + ; + + + + } + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml new file mode 100644 index 0000000..008db55 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-clover.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml new file mode 100644 index 0000000..5bd2535 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-crap4j.xml @@ -0,0 +1,26 @@ + + + CoverageForClassWithAnonymousFunction + %s + + Method Crap Stats + 1 + 0 + 0 + 1 + 0 + + + + global + CoveredClassWithAnonymousFunctionInStaticMethod + runAnonymous + runAnonymous() + runAnonymous() + 1 + 1 + 87.5 + 0 + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt new file mode 100644 index 0000000..e4204cc --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/class-with-anonymous-function-text.txt @@ -0,0 +1,12 @@ + + +Code Coverage Report: + %s + + Summary: + Classes: 0.00% (0/1) + Methods: 0.00% (0/1) + Lines: 87.50% (7/8) + +CoveredClassWithAnonymousFunctionInStaticMethod + Methods: 0.00% ( 0/ 1) Lines: 87.50% ( 7/ 8) diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml new file mode 100644 index 0000000..efd3801 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-clover.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml new file mode 100644 index 0000000..2607b59 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-crap4j.xml @@ -0,0 +1,37 @@ + + + CoverageForFileWithIgnoredLines + %s + + Method Crap Stats + 2 + 0 + 0 + 2 + 0 + + + + global + Foo + bar + bar() + bar() + 1 + 1 + 100 + 0 + + + global + Bar + foo + foo() + foo() + 1 + 1 + 100 + 0 + + + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt new file mode 100644 index 0000000..6e8e149 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/ignored-lines-text.txt @@ -0,0 +1,10 @@ + + +Code Coverage Report:%w + %s +%w + Summary:%w + Classes: (0/0) + Methods: (0/0) + Lines: 50.00% (1/2) + diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php b/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php new file mode 100644 index 0000000..72aa938 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/source_with_class_and_anonymous_function.php @@ -0,0 +1,19 @@ + 1, 'b' => 2, 'c' => 3, 'd' => 4], + static function ($v, $k) + { + return $k === 'b' || $v === 4; + }, + ARRAY_FILTER_USE_BOTH + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php b/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php new file mode 100644 index 0000000..be4e836 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/_files/source_without_ignore.php @@ -0,0 +1,4 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\Node\Builder; +use SebastianBergmann\CodeCoverage\TestCase; + +class BuilderTest extends TestCase +{ + protected $factory; + + protected function setUp(): void + { + $this->factory = new Builder; + } + + public function testSomething(): void + { + $root = $this->getCoverageForBankAccount()->getReport(); + + $expectedPath = \rtrim(TEST_FILES_PATH, \DIRECTORY_SEPARATOR); + $this->assertEquals($expectedPath, $root->getName()); + $this->assertEquals($expectedPath, $root->getPath()); + $this->assertEquals(10, $root->getNumExecutableLines()); + $this->assertEquals(5, $root->getNumExecutedLines()); + $this->assertEquals(1, $root->getNumClasses()); + $this->assertEquals(0, $root->getNumTestedClasses()); + $this->assertEquals(4, $root->getNumMethods()); + $this->assertEquals(3, $root->getNumTestedMethods()); + $this->assertEquals('0.00%', $root->getTestedClassesPercent()); + $this->assertEquals('75.00%', $root->getTestedMethodsPercent()); + $this->assertEquals('50.00%', $root->getLineExecutedPercent()); + $this->assertEquals(0, $root->getNumFunctions()); + $this->assertEquals(0, $root->getNumTestedFunctions()); + $this->assertNull($root->getParent()); + $this->assertEquals([], $root->getDirectories()); + #$this->assertEquals(array(), $root->getFiles()); + #$this->assertEquals(array(), $root->getChildNodes()); + + $this->assertEquals( + [ + 'BankAccount' => [ + 'methods' => [ + 'getBalance' => [ + 'signature' => 'getBalance()', + 'startLine' => 6, + 'endLine' => 9, + 'executableLines' => 1, + 'executedLines' => 1, + 'ccn' => 1, + 'coverage' => 100, + 'crap' => '1', + 'link' => 'BankAccount.php.html#6', + 'methodName' => 'getBalance', + 'visibility' => 'public', + ], + 'setBalance' => [ + 'signature' => 'setBalance($balance)', + 'startLine' => 11, + 'endLine' => 18, + 'executableLines' => 5, + 'executedLines' => 0, + 'ccn' => 2, + 'coverage' => 0, + 'crap' => 6, + 'link' => 'BankAccount.php.html#11', + 'methodName' => 'setBalance', + 'visibility' => 'protected', + ], + 'depositMoney' => [ + 'signature' => 'depositMoney($balance)', + 'startLine' => 20, + 'endLine' => 25, + 'executableLines' => 2, + 'executedLines' => 2, + 'ccn' => 1, + 'coverage' => 100, + 'crap' => '1', + 'link' => 'BankAccount.php.html#20', + 'methodName' => 'depositMoney', + 'visibility' => 'public', + ], + 'withdrawMoney' => [ + 'signature' => 'withdrawMoney($balance)', + 'startLine' => 27, + 'endLine' => 32, + 'executableLines' => 2, + 'executedLines' => 2, + 'ccn' => 1, + 'coverage' => 100, + 'crap' => '1', + 'link' => 'BankAccount.php.html#27', + 'methodName' => 'withdrawMoney', + 'visibility' => 'public', + ], + ], + 'startLine' => 2, + 'executableLines' => 10, + 'executedLines' => 5, + 'ccn' => 5, + 'coverage' => 50, + 'crap' => '8.12', + 'package' => [ + 'namespace' => '', + 'fullPackage' => '', + 'category' => '', + 'package' => '', + 'subpackage' => '', + ], + 'link' => 'BankAccount.php.html#2', + 'className' => 'BankAccount', + ], + ], + $root->getClasses() + ); + + $this->assertEquals([], $root->getFunctions()); + } + + public function testNotCrashParsing(): void + { + $coverage = $this->getCoverageForCrashParsing(); + $root = $coverage->getReport(); + + $expectedPath = \rtrim(TEST_FILES_PATH, \DIRECTORY_SEPARATOR); + $this->assertEquals($expectedPath, $root->getName()); + $this->assertEquals($expectedPath, $root->getPath()); + $this->assertEquals(2, $root->getNumExecutableLines()); + $this->assertEquals(0, $root->getNumExecutedLines()); + $data = $coverage->getData(); + $expectedFile = $expectedPath . \DIRECTORY_SEPARATOR . 'Crash.php'; + $this->assertSame([$expectedFile => [1 => [], 2 => []]], $data); + } + + public function testBuildDirectoryStructure(): void + { + $s = \DIRECTORY_SEPARATOR; + + $method = new \ReflectionMethod( + Builder::class, + 'buildDirectoryStructure' + ); + + $method->setAccessible(true); + + $this->assertEquals( + [ + 'src' => [ + 'Money.php/f' => [], + 'MoneyBag.php/f' => [], + 'Foo' => [ + 'Bar' => [ + 'Baz' => [ + 'Foo.php/f' => [], + ], + ], + ], + ], + ], + $method->invoke( + $this->factory, + [ + "src{$s}Money.php" => [], + "src{$s}MoneyBag.php" => [], + "src{$s}Foo{$s}Bar{$s}Baz{$s}Foo.php" => [], + ] + ) + ); + } + + /** + * @dataProvider reducePathsProvider + */ + public function testReducePaths($reducedPaths, $commonPath, $paths): void + { + $method = new \ReflectionMethod( + Builder::class, + 'reducePaths' + ); + + $method->setAccessible(true); + + $_commonPath = $method->invokeArgs($this->factory, [&$paths]); + + $this->assertEquals($reducedPaths, $paths); + $this->assertEquals($commonPath, $_commonPath); + } + + public function reducePathsProvider() + { + $s = \DIRECTORY_SEPARATOR; + + yield [ + [], + '.', + [], + ]; + + $prefixes = ["C:$s", "$s"]; + + foreach ($prefixes as $p) { + yield [ + [ + 'Money.php' => [], + ], + "{$p}home{$s}sb{$s}Money{$s}", + [ + "{$p}home{$s}sb{$s}Money{$s}Money.php" => [], + ], + ]; + + yield [ + [ + 'Money.php' => [], + 'MoneyBag.php' => [], + ], + "{$p}home{$s}sb{$s}Money", + [ + "{$p}home{$s}sb{$s}Money{$s}Money.php" => [], + "{$p}home{$s}sb{$s}Money{$s}MoneyBag.php" => [], + ], + ]; + + yield [ + [ + 'Money.php' => [], + 'MoneyBag.php' => [], + "Cash.phar{$s}Cash.php" => [], + ], + "{$p}home{$s}sb{$s}Money", + [ + "{$p}home{$s}sb{$s}Money{$s}Money.php" => [], + "{$p}home{$s}sb{$s}Money{$s}MoneyBag.php" => [], + "phar://{$p}home{$s}sb{$s}Money{$s}Cash.phar{$s}Cash.php" => [], + ], + ]; + } + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php b/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php new file mode 100644 index 0000000..7fdbf7d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/CloverTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\TestCase; + +/** + * @covers SebastianBergmann\CodeCoverage\Report\Clover + */ +class CloverTest extends TestCase +{ + public function testCloverForBankAccountTest(): void + { + $clover = new Clover; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'BankAccount-clover.xml', + $clover->process($this->getCoverageForBankAccount(), null, 'BankAccount') + ); + } + + public function testCloverForFileWithIgnoredLines(): void + { + $clover = new Clover; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'ignored-lines-clover.xml', + $clover->process($this->getCoverageForFileWithIgnoredLines()) + ); + } + + public function testCloverForClassWithAnonymousFunction(): void + { + $clover = new Clover; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'class-with-anonymous-function-clover.xml', + $clover->process($this->getCoverageForClassWithAnonymousFunction()) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php b/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php new file mode 100644 index 0000000..ce2471a --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/CodeCoverageTest.php @@ -0,0 +1,359 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use SebastianBergmann\CodeCoverage\Driver\Driver; +use SebastianBergmann\Environment\Runtime; + +/** + * @covers SebastianBergmann\CodeCoverage\CodeCoverage + */ +class CodeCoverageTest extends TestCase +{ + /** + * @var CodeCoverage + */ + private $coverage; + + protected function setUp(): void + { + $runtime = new Runtime; + + if (!$runtime->canCollectCodeCoverage()) { + $this->markTestSkipped('No code coverage driver available'); + } + + $this->coverage = new CodeCoverage; + } + + public function testCannotStopWithInvalidSecondArgument(): void + { + $this->expectException(Exception::class); + + $this->coverage->stop(true, null); + } + + public function testCannotAppendWithInvalidArgument(): void + { + $this->expectException(Exception::class); + + $this->coverage->append([], null); + } + + public function testCollect(): void + { + $coverage = $this->getCoverageForBankAccount(); + + $this->assertEquals( + $this->getExpectedDataArrayForBankAccount(), + $coverage->getData() + ); + + $this->assertEquals( + [ + 'BankAccountTest::testBalanceIsInitiallyZero' => ['size' => 'unknown', 'status' => -1], + 'BankAccountTest::testBalanceCannotBecomeNegative' => ['size' => 'unknown', 'status' => -1], + 'BankAccountTest::testBalanceCannotBecomeNegative2' => ['size' => 'unknown', 'status' => -1], + 'BankAccountTest::testDepositWithdrawMoney' => ['size' => 'unknown', 'status' => -1], + ], + $coverage->getTests() + ); + } + + public function testMerge(): void + { + $coverage = $this->getCoverageForBankAccountForFirstTwoTests(); + $coverage->merge($this->getCoverageForBankAccountForLastTwoTests()); + + $this->assertEquals( + $this->getExpectedDataArrayForBankAccount(), + $coverage->getData() + ); + } + + public function testMergeReverseOrder(): void + { + $coverage = $this->getCoverageForBankAccountForLastTwoTests(); + $coverage->merge($this->getCoverageForBankAccountForFirstTwoTests()); + + $this->assertEquals( + $this->getExpectedDataArrayForBankAccountInReverseOrder(), + $coverage->getData() + ); + } + + public function testMerge2(): void + { + $coverage = new CodeCoverage( + $this->createMock(Driver::class), + new Filter + ); + + $coverage->merge($this->getCoverageForBankAccount()); + + $this->assertEquals( + $this->getExpectedDataArrayForBankAccount(), + $coverage->getData() + ); + } + + public function testGetLinesToBeIgnored(): void + { + $this->assertEquals( + [ + 1, + 3, + 4, + 5, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 30, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + ], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_with_ignore.php' + ) + ); + } + + public function testGetLinesToBeIgnored2(): void + { + $this->assertEquals( + [1, 5], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_without_ignore.php' + ) + ); + } + + public function testGetLinesToBeIgnored3(): void + { + $this->assertEquals( + [ + 1, + 2, + 3, + 4, + 5, + 8, + 11, + 15, + 16, + 19, + 20, + ], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php' + ) + ); + } + + public function testGetLinesToBeIgnoredOneLineAnnotations(): void + { + $this->assertEquals( + [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 14, + 15, + 16, + 18, + 20, + 21, + 23, + 24, + 25, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 37, + ], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_with_oneline_annotations.php' + ) + ); + } + + public function testGetLinesToBeIgnoredWhenIgnoreIsDisabled(): void + { + $this->coverage->setDisableIgnoredLines(true); + + $this->assertEquals( + [ + 7, + 11, + 12, + 13, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 26, + 27, + 32, + 33, + 34, + 35, + 36, + 37, + ], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_with_ignore.php' + ) + ); + } + + public function testUseStatementsAreIgnored(): void + { + $this->assertEquals( + [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 13, + 16, + 23, + 24, + ], + $this->getLinesToBeIgnored()->invoke( + $this->coverage, + TEST_FILES_PATH . 'source_with_use_statements.php' + ) + ); + } + + public function testAppendThrowsExceptionIfCoveredCodeWasNotExecuted(): void + { + $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH); + $this->coverage->setCheckForUnexecutedCoveredCode(true); + + $data = [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 29 => -1, + 31 => -1, + ], + ]; + + $linesToBeCovered = [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 22, + 24, + ], + ]; + + $linesToBeUsed = []; + + $this->expectException(CoveredCodeNotExecutedException::class); + + $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed); + } + + public function testAppendThrowsExceptionIfUsedCodeWasNotExecuted(): void + { + $this->coverage->filter()->addDirectoryToWhitelist(TEST_FILES_PATH); + $this->coverage->setCheckForUnexecutedCoveredCode(true); + + $data = [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 29 => -1, + 31 => -1, + ], + ]; + + $linesToBeCovered = [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 29, + 31, + ], + ]; + + $linesToBeUsed = [ + TEST_FILES_PATH . 'BankAccount.php' => [ + 22, + 24, + ], + ]; + + $this->expectException(CoveredCodeNotExecutedException::class); + + $this->coverage->append($data, 'File1.php', true, $linesToBeCovered, $linesToBeUsed); + } + + /** + * @return \ReflectionMethod + */ + private function getLinesToBeIgnored() + { + $getLinesToBeIgnored = new \ReflectionMethod( + 'SebastianBergmann\CodeCoverage\CodeCoverage', + 'getLinesToBeIgnored' + ); + + $getLinesToBeIgnored->setAccessible(true); + + return $getLinesToBeIgnored; + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php b/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php new file mode 100644 index 0000000..033fe4c --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/Crap4jTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\TestCase; + +/** + * @covers SebastianBergmann\CodeCoverage\Report\Crap4j + */ +class Crap4jTest extends TestCase +{ + public function testForBankAccountTest(): void + { + $crap4j = new Crap4j; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'BankAccount-crap4j.xml', + $crap4j->process($this->getCoverageForBankAccount(), null, 'BankAccount') + ); + } + + public function testForFileWithIgnoredLines(): void + { + $crap4j = new Crap4j; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'ignored-lines-crap4j.xml', + $crap4j->process($this->getCoverageForFileWithIgnoredLines(), null, 'CoverageForFileWithIgnoredLines') + ); + } + + public function testForClassWithAnonymousFunction(): void + { + $crap4j = new Crap4j; + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'class-with-anonymous-function-crap4j.xml', + $crap4j->process($this->getCoverageForClassWithAnonymousFunction(), null, 'CoverageForClassWithAnonymousFunction') + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php b/vendor/phpunit/php-code-coverage/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php new file mode 100644 index 0000000..dffc227 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/Exception/UnintentionallyCoveredCodeExceptionTest.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\tests\Exception; + +use PHPUnit\Framework\TestCase; +use SebastianBergmann\CodeCoverage\RuntimeException; +use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; + +final class UnintentionallyCoveredCodeExceptionTest extends TestCase +{ + public function testCanConstructWithEmptyArray(): void + { + $unintentionallyCoveredUnits = []; + + $exception = new UnintentionallyCoveredCodeException($unintentionallyCoveredUnits); + + $this->assertInstanceOf(RuntimeException::class, $exception); + $this->assertSame($unintentionallyCoveredUnits, $exception->getUnintentionallyCoveredUnits()); + $this->assertSame('', $exception->getMessage()); + } + + public function testCanConstructWithNonEmptyArray(): void + { + $unintentionallyCoveredUnits = [ + 'foo', + 'bar', + 'baz', + ]; + + $exception = new UnintentionallyCoveredCodeException($unintentionallyCoveredUnits); + + $this->assertInstanceOf(RuntimeException::class, $exception); + $this->assertSame($unintentionallyCoveredUnits, $exception->getUnintentionallyCoveredUnits()); + + $expected = <<assertSame($expected, $exception->getMessage()); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php b/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php new file mode 100644 index 0000000..373b349 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/FilterTest.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use PHPUnit\Framework\TestCase; +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; + +class FilterTest extends TestCase +{ + /** + * @var Filter + */ + private $filter; + + /** + * @var array + */ + private $files = []; + + protected function setUp(): void + { + $this->filter = \unserialize('O:37:"SebastianBergmann\CodeCoverage\Filter":0:{}'); + + $this->files = [ + TEST_FILES_PATH . 'BankAccount.php', + TEST_FILES_PATH . 'BankAccountTest.php', + TEST_FILES_PATH . 'CoverageClassExtendedTest.php', + TEST_FILES_PATH . 'CoverageClassTest.php', + TEST_FILES_PATH . 'CoverageFunctionParenthesesTest.php', + TEST_FILES_PATH . 'CoverageFunctionParenthesesWhitespaceTest.php', + TEST_FILES_PATH . 'CoverageFunctionTest.php', + TEST_FILES_PATH . 'CoverageMethodOneLineAnnotationTest.php', + TEST_FILES_PATH . 'CoverageMethodParenthesesTest.php', + TEST_FILES_PATH . 'CoverageMethodParenthesesWhitespaceTest.php', + TEST_FILES_PATH . 'CoverageMethodTest.php', + TEST_FILES_PATH . 'CoverageNoneTest.php', + TEST_FILES_PATH . 'CoverageNotPrivateTest.php', + TEST_FILES_PATH . 'CoverageNotProtectedTest.php', + TEST_FILES_PATH . 'CoverageNotPublicTest.php', + TEST_FILES_PATH . 'CoverageNothingTest.php', + TEST_FILES_PATH . 'CoveragePrivateTest.php', + TEST_FILES_PATH . 'CoverageProtectedTest.php', + TEST_FILES_PATH . 'CoveragePublicTest.php', + TEST_FILES_PATH . 'CoverageTwoDefaultClassAnnotations.php', + TEST_FILES_PATH . 'CoveredClass.php', + TEST_FILES_PATH . 'CoveredFunction.php', + TEST_FILES_PATH . 'Crash.php', + TEST_FILES_PATH . 'NamespaceCoverageClassExtendedTest.php', + TEST_FILES_PATH . 'NamespaceCoverageClassTest.php', + TEST_FILES_PATH . 'NamespaceCoverageCoversClassPublicTest.php', + TEST_FILES_PATH . 'NamespaceCoverageCoversClassTest.php', + TEST_FILES_PATH . 'NamespaceCoverageMethodTest.php', + TEST_FILES_PATH . 'NamespaceCoverageNotPrivateTest.php', + TEST_FILES_PATH . 'NamespaceCoverageNotProtectedTest.php', + TEST_FILES_PATH . 'NamespaceCoverageNotPublicTest.php', + TEST_FILES_PATH . 'NamespaceCoveragePrivateTest.php', + TEST_FILES_PATH . 'NamespaceCoverageProtectedTest.php', + TEST_FILES_PATH . 'NamespaceCoveragePublicTest.php', + TEST_FILES_PATH . 'NamespaceCoveredClass.php', + TEST_FILES_PATH . 'NotExistingCoveredElementTest.php', + TEST_FILES_PATH . 'source_with_class_and_anonymous_function.php', + TEST_FILES_PATH . 'source_with_ignore.php', + TEST_FILES_PATH . 'source_with_namespace.php', + TEST_FILES_PATH . 'source_with_oneline_annotations.php', + TEST_FILES_PATH . 'source_with_use_statements.php', + TEST_FILES_PATH . 'source_without_ignore.php', + TEST_FILES_PATH . 'source_without_namespace.php', + ]; + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::addFileToWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + */ + public function testAddingAFileToTheWhitelistWorks(): void + { + $this->filter->addFileToWhitelist($this->files[0]); + + $this->assertEquals( + [$this->files[0]], + $this->filter->getWhitelist() + ); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::removeFileFromWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + */ + public function testRemovingAFileFromTheWhitelistWorks(): void + { + $this->filter->addFileToWhitelist($this->files[0]); + $this->filter->removeFileFromWhitelist($this->files[0]); + + $this->assertEquals([], $this->filter->getWhitelist()); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::addDirectoryToWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + * @depends testAddingAFileToTheWhitelistWorks + */ + public function testAddingADirectoryToTheWhitelistWorks(): void + { + $this->filter->addDirectoryToWhitelist(TEST_FILES_PATH); + + $whitelist = $this->filter->getWhitelist(); + \sort($whitelist); + + $this->assertEquals($this->files, $whitelist); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::addFilesToWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + */ + public function testAddingFilesToTheWhitelistWorks(): void + { + $facade = new FileIteratorFacade; + + $files = $facade->getFilesAsArray( + TEST_FILES_PATH, + $suffixes = '.php' + ); + + $this->filter->addFilesToWhitelist($files); + + $whitelist = $this->filter->getWhitelist(); + \sort($whitelist); + + $this->assertEquals($this->files, $whitelist); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::removeDirectoryFromWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + * @depends testAddingADirectoryToTheWhitelistWorks + */ + public function testRemovingADirectoryFromTheWhitelistWorks(): void + { + $this->filter->addDirectoryToWhitelist(TEST_FILES_PATH); + $this->filter->removeDirectoryFromWhitelist(TEST_FILES_PATH); + + $this->assertEquals([], $this->filter->getWhitelist()); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::isFile + */ + public function testIsFile(): void + { + $this->assertFalse($this->filter->isFile('vfs://root/a/path')); + $this->assertFalse($this->filter->isFile('xdebug://debug-eval')); + $this->assertFalse($this->filter->isFile('eval()\'d code')); + $this->assertFalse($this->filter->isFile('runtime-created function')); + $this->assertFalse($this->filter->isFile('assert code')); + $this->assertFalse($this->filter->isFile('regexp code')); + $this->assertTrue($this->filter->isFile(__FILE__)); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered + */ + public function testWhitelistedFileIsNotFiltered(): void + { + $this->filter->addFileToWhitelist($this->files[0]); + $this->assertFalse($this->filter->isFiltered($this->files[0])); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered + */ + public function testNotWhitelistedFileIsFiltered(): void + { + $this->filter->addFileToWhitelist($this->files[0]); + $this->assertTrue($this->filter->isFiltered($this->files[1])); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::isFiltered + * @covers SebastianBergmann\CodeCoverage\Filter::isFile + */ + public function testNonFilesAreFiltered(): void + { + $this->assertTrue($this->filter->isFiltered('vfs://root/a/path')); + $this->assertTrue($this->filter->isFiltered('xdebug://debug-eval')); + $this->assertTrue($this->filter->isFiltered('eval()\'d code')); + $this->assertTrue($this->filter->isFiltered('runtime-created function')); + $this->assertTrue($this->filter->isFiltered('assert code')); + $this->assertTrue($this->filter->isFiltered('regexp code')); + } + + /** + * @covers SebastianBergmann\CodeCoverage\Filter::addFileToWhitelist + * @covers SebastianBergmann\CodeCoverage\Filter::getWhitelist + * + * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/664 + */ + public function testTryingToAddFileThatDoesNotExistDoesNotChangeFilter(): void + { + $filter = new Filter; + + $filter->addFileToWhitelist('does_not_exist'); + + $this->assertEmpty($filter->getWhitelistedFiles()); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php b/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php new file mode 100644 index 0000000..0ddd85d --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/HTMLTest.php @@ -0,0 +1,102 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Html; + +use SebastianBergmann\CodeCoverage\TestCase; + +class HTMLTest extends TestCase +{ + private static $TEST_REPORT_PATH_SOURCE; + + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + + self::$TEST_REPORT_PATH_SOURCE = TEST_FILES_PATH . 'Report' . \DIRECTORY_SEPARATOR . 'HTML'; + } + + protected function tearDown(): void + { + parent::tearDown(); + + $tmpFilesIterator = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator(self::$TEST_TMP_PATH, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + foreach ($tmpFilesIterator as $path => $fileInfo) { + /* @var \SplFileInfo $fileInfo */ + $pathname = $fileInfo->getPathname(); + $fileInfo->isDir() ? \rmdir($pathname) : \unlink($pathname); + } + } + + public function testForBankAccountTest(): void + { + $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForBankAccount'; + + $report = new Facade; + $report->process($this->getCoverageForBankAccount(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + public function testForFileWithIgnoredLines(): void + { + $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForFileWithIgnoredLines'; + + $report = new Facade; + $report->process($this->getCoverageForFileWithIgnoredLines(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + public function testForClassWithAnonymousFunction(): void + { + $expectedFilesPath = + self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForClassWithAnonymousFunction'; + + $report = new Facade; + $report->process($this->getCoverageForClassWithAnonymousFunction(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + /** + * @param string $expectedFilesPath + * @param string $actualFilesPath + */ + private function assertFilesEquals($expectedFilesPath, $actualFilesPath): void + { + $expectedFilesIterator = new \FilesystemIterator($expectedFilesPath); + $actualFilesIterator = new \RegexIterator(new \FilesystemIterator($actualFilesPath), '/.html/'); + + $this->assertEquals( + \iterator_count($expectedFilesIterator), + \iterator_count($actualFilesIterator), + 'Generated files and expected files not match' + ); + + foreach ($expectedFilesIterator as $path => $fileInfo) { + /* @var \SplFileInfo $fileInfo */ + $filename = $fileInfo->getFilename(); + + $actualFile = $actualFilesPath . \DIRECTORY_SEPARATOR . $filename; + + $this->assertFileExists($actualFile); + + $this->assertStringMatchesFormatFile( + $fileInfo->getPathname(), + \str_replace(\PHP_EOL, "\n", \file_get_contents($actualFile)), + "${filename} not match" + ); + } + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php b/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php new file mode 100644 index 0000000..501226f --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/TextTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report; + +use SebastianBergmann\CodeCoverage\TestCase; + +/** + * @covers SebastianBergmann\CodeCoverage\Report\Text + */ +class TextTest extends TestCase +{ + public function testTextForBankAccountTest(): void + { + $text = new Text(50, 90, false, false); + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'BankAccount-text.txt', + \str_replace(\PHP_EOL, "\n", $text->process($this->getCoverageForBankAccount())) + ); + } + + public function testTextForFileWithIgnoredLines(): void + { + $text = new Text(50, 90, false, false); + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'ignored-lines-text.txt', + \str_replace(\PHP_EOL, "\n", $text->process($this->getCoverageForFileWithIgnoredLines())) + ); + } + + public function testTextForClassWithAnonymousFunction(): void + { + $text = new Text(50, 90, false, false); + + $this->assertStringMatchesFormatFile( + TEST_FILES_PATH . 'class-with-anonymous-function-text.txt', + \str_replace(\PHP_EOL, "\n", $text->process($this->getCoverageForClassWithAnonymousFunction())) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php b/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php new file mode 100644 index 0000000..2ebfb61 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/UtilTest.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage; + +use PHPUnit\Framework\TestCase; + +/** + * @covers SebastianBergmann\CodeCoverage\Util + */ +class UtilTest extends TestCase +{ + public function testPercent(): void + { + $this->assertEquals(100, Util::percent(100, 0)); + $this->assertEquals(100, Util::percent(100, 100)); + $this->assertEquals( + '100.00%', + Util::percent(100, 100, true) + ); + } +} diff --git a/vendor/phpunit/php-code-coverage/tests/tests/XmlTest.php b/vendor/phpunit/php-code-coverage/tests/tests/XmlTest.php new file mode 100644 index 0000000..13045a7 --- /dev/null +++ b/vendor/phpunit/php-code-coverage/tests/tests/XmlTest.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\CodeCoverage\Report\Xml; + +use SebastianBergmann\CodeCoverage\TestCase; + +class XmlTest extends TestCase +{ + private static $TEST_REPORT_PATH_SOURCE; + + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + + self::$TEST_REPORT_PATH_SOURCE = TEST_FILES_PATH . 'Report' . \DIRECTORY_SEPARATOR . 'XML'; + } + + protected function tearDown(): void + { + parent::tearDown(); + + $tmpFilesIterator = new \FilesystemIterator(self::$TEST_TMP_PATH); + + foreach ($tmpFilesIterator as $path => $fileInfo) { + /* @var \SplFileInfo $fileInfo */ + \unlink($fileInfo->getPathname()); + } + } + + public function testForBankAccountTest(): void + { + $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForBankAccount'; + + $xml = new Facade('1.0.0'); + $xml->process($this->getCoverageForBankAccount(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + public function testForFileWithIgnoredLines(): void + { + $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForFileWithIgnoredLines'; + + $xml = new Facade('1.0.0'); + $xml->process($this->getCoverageForFileWithIgnoredLines(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + public function testForClassWithAnonymousFunction(): void + { + $expectedFilesPath = self::$TEST_REPORT_PATH_SOURCE . \DIRECTORY_SEPARATOR . 'CoverageForClassWithAnonymousFunction'; + + $xml = new Facade('1.0.0'); + $xml->process($this->getCoverageForClassWithAnonymousFunction(), self::$TEST_TMP_PATH); + + $this->assertFilesEquals($expectedFilesPath, self::$TEST_TMP_PATH); + } + + /** + * @param string $expectedFilesPath + * @param string $actualFilesPath + */ + private function assertFilesEquals($expectedFilesPath, $actualFilesPath): void + { + $expectedFilesIterator = new \FilesystemIterator($expectedFilesPath); + $actualFilesIterator = new \FilesystemIterator($actualFilesPath); + + $this->assertEquals( + \iterator_count($expectedFilesIterator), + \iterator_count($actualFilesIterator), + 'Generated files and expected files not match' + ); + + foreach ($expectedFilesIterator as $path => $fileInfo) { + /* @var \SplFileInfo $fileInfo */ + $filename = $fileInfo->getFilename(); + + $actualFile = $actualFilesPath . \DIRECTORY_SEPARATOR . $filename; + + $this->assertFileExists($actualFile); + + $this->assertStringMatchesFormatFile( + $fileInfo->getPathname(), + \file_get_contents($actualFile), + "${filename} not match" + ); + } + } +} diff --git a/vendor/phpunit/php-file-iterator/.gitattributes b/vendor/phpunit/php-file-iterator/.gitattributes new file mode 100644 index 0000000..461090b --- /dev/null +++ b/vendor/phpunit/php-file-iterator/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/vendor/phpunit/php-file-iterator/.github/stale.yml b/vendor/phpunit/php-file-iterator/.github/stale.yml new file mode 100644 index 0000000..4eadca3 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/.github/stale.yml @@ -0,0 +1,40 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 60 + +# Number of days of inactivity before a stale Issue or Pull Request is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 7 + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - enhancement + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Label to use when marking as stale +staleLabel: stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had activity within the last 60 days. It will be closed after 7 days if no further activity occurs. Thank you for your contributions. + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +closeComment: > + This issue has been automatically closed because it has not had activity since it was marked as stale. Thank you for your contributions. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: issues + diff --git a/vendor/phpunit/php-file-iterator/.gitignore b/vendor/phpunit/php-file-iterator/.gitignore new file mode 100644 index 0000000..5ad7a64 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/.gitignore @@ -0,0 +1,5 @@ +/.idea +/vendor/ +/.php_cs +/.php_cs.cache +/composer.lock diff --git a/vendor/phpunit/php-file-iterator/.php_cs.dist b/vendor/phpunit/php-file-iterator/.php_cs.dist new file mode 100644 index 0000000..efc649f --- /dev/null +++ b/vendor/phpunit/php-file-iterator/.php_cs.dist @@ -0,0 +1,168 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules( + [ + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'operators' => [ + '=' => 'align', + '=>' => 'align', + ], + ], + 'blank_line_after_namespace' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', + 'continue', + 'declare', + 'do', + 'for', + 'foreach', + 'if', + 'include', + 'include_once', + 'require', + 'require_once', + 'return', + 'switch', + 'throw', + 'try', + 'while', + 'yield', + ], + ], + 'braces' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => ['elements' => ['method']], + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'dir_constant' => true, + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => true, + 'header_comment' => ['header' => $header, 'separate' => 'none'], + 'indentation_type' => true, + 'line_ending' => true, + 'list_syntax' => ['syntax' => 'short'], + 'lowercase_cast' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => ['ensure_fully_multiline' => true], + 'modernize_types_casting' => true, + 'native_function_casing' => true, + 'native_function_invocation' => true, + 'no_alias_functions' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => ['use' => 'print'], + 'no_null_property_initialization' => true, + 'no_short_bool_cast' => true, + 'no_short_echo_tag' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_curly_braces' => true, + 'no_unneeded_final_method' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public_static', + 'property_protected_static', + 'property_private_static', + 'property_public', + 'property_protected', + 'property_private', + 'method_public_static', + 'construct', + 'destruct', + 'magic', + 'phpunit', + 'method_public', + 'method_protected', + 'method_private', + 'method_protected_static', + 'method_private_static', + ], + ], + 'ordered_imports' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_align' => true, + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_types' => true, + 'phpdoc_types_order' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'self_accessor' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => true, + 'single_blank_line_at_eof' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'ternary_to_null_coalescing' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'visibility_required' => true, + 'void_return' => true, + 'whitespace_after_comma_in_array' => true, + ] + ) + ->setFinder( + PhpCsFixer\Finder::create() + ->files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') + ->notName('*.phpt') + ); diff --git a/vendor/phpunit/php-file-iterator/.travis.yml b/vendor/phpunit/php-file-iterator/.travis.yml new file mode 100644 index 0000000..16b399c --- /dev/null +++ b/vendor/phpunit/php-file-iterator/.travis.yml @@ -0,0 +1,32 @@ +language: php + +sudo: false + +php: + - 7.1 + - 7.2 + - master + +env: + matrix: + - DEPENDENCIES="high" + - DEPENDENCIES="low" + global: + - DEFAULT_COMPOSER_FLAGS="--no-interaction --no-ansi --no-progress --no-suggest" + +before_install: + - composer self-update + - composer clear-cache + +install: + - if [[ "$DEPENDENCIES" = 'high' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS; fi + - if [[ "$DEPENDENCIES" = 'low' ]]; then travis_retry composer update $DEFAULT_COMPOSER_FLAGS --prefer-lowest; fi + +script: + - ./vendor/bin/phpunit --coverage-clover=coverage.xml + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false diff --git a/vendor/phpunit/php-file-iterator/ChangeLog.md b/vendor/phpunit/php-file-iterator/ChangeLog.md new file mode 100644 index 0000000..f4a0801 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/ChangeLog.md @@ -0,0 +1,70 @@ +# Change Log + +All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [2.0.2] - 2018-09-13 + +### Fixed + +* Fixed [#48](https://github.com/sebastianbergmann/php-file-iterator/issues/48): Excluding an array that contains false ends up excluding the current working directory + +## [2.0.1] - 2018-06-11 + +### Fixed + +* Fixed [#46](https://github.com/sebastianbergmann/php-file-iterator/issues/46): Regression with hidden parent directory + +## [2.0.0] - 2018-05-28 + +### Fixed + +* Fixed [#30](https://github.com/sebastianbergmann/php-file-iterator/issues/30): Exclude is not considered if it is a parent of the base path + +### Changed + +* This component now uses namespaces + +### Removed + +* This component is no longer supported on PHP 5.3, PHP 5.4, PHP 5.5, PHP 5.6, and PHP 7.0 + +## [1.4.5] - 2017-11-27 + +### Fixed + +* Fixed [#37](https://github.com/sebastianbergmann/php-file-iterator/issues/37): Regression caused by fix for [#30](https://github.com/sebastianbergmann/php-file-iterator/issues/30) + +## [1.4.4] - 2017-11-27 + +### Fixed + +* Fixed [#30](https://github.com/sebastianbergmann/php-file-iterator/issues/30): Exclude is not considered if it is a parent of the base path + +## [1.4.3] - 2017-11-25 + +### Fixed + +* Fixed [#34](https://github.com/sebastianbergmann/php-file-iterator/issues/34): Factory should use canonical directory names + +## [1.4.2] - 2016-11-26 + +No changes + +## [1.4.1] - 2015-07-26 + +No changes + +## 1.4.0 - 2015-04-02 + +### Added + +* [Added support for wildcards (glob) in exclude](https://github.com/sebastianbergmann/php-file-iterator/pull/23) + +[2.0.2]: https://github.com/sebastianbergmann/php-file-iterator/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/sebastianbergmann/php-file-iterator/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4...master +[1.4.5]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.4...1.4.5 +[1.4.4]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.3...1.4.4 +[1.4.3]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.2...1.4.3 +[1.4.2]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.1...1.4.2 +[1.4.1]: https://github.com/sebastianbergmann/php-file-iterator/compare/1.4.0...1.4.1 diff --git a/vendor/phpunit/php-file-iterator/LICENSE b/vendor/phpunit/php-file-iterator/LICENSE new file mode 100644 index 0000000..87c3b51 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/LICENSE @@ -0,0 +1,33 @@ +php-file-iterator + +Copyright (c) 2009-2018, Sebastian Bergmann . +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/php-file-iterator/README.md b/vendor/phpunit/php-file-iterator/README.md new file mode 100644 index 0000000..3cbfdaa --- /dev/null +++ b/vendor/phpunit/php-file-iterator/README.md @@ -0,0 +1,14 @@ +[![Build Status](https://travis-ci.org/sebastianbergmann/php-file-iterator.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-file-iterator) + +# php-file-iterator + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phpunit/php-file-iterator + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phpunit/php-file-iterator + diff --git a/vendor/phpunit/php-file-iterator/composer.json b/vendor/phpunit/php-file-iterator/composer.json new file mode 100644 index 0000000..002e511 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/composer.json @@ -0,0 +1,37 @@ +{ + "name": "phpunit/php-file-iterator", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "type": "library", + "keywords": [ + "iterator", + "filesystem" + ], + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + } +} diff --git a/vendor/phpunit/php-file-iterator/phpunit.xml b/vendor/phpunit/php-file-iterator/phpunit.xml new file mode 100644 index 0000000..3e12be4 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/phpunit.xml @@ -0,0 +1,21 @@ + + + + + tests + + + + + + src + + + diff --git a/vendor/phpunit/php-file-iterator/src/Facade.php b/vendor/phpunit/php-file-iterator/src/Facade.php new file mode 100644 index 0000000..2456e16 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/src/Facade.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\FileIterator; + +class Facade +{ + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * @param bool $commonPath + * + * @return array + */ + public function getFilesAsArray($paths, $suffixes = '', $prefixes = '', array $exclude = [], bool $commonPath = false): array + { + if (\is_string($paths)) { + $paths = [$paths]; + } + + $factory = new Factory; + + $iterator = $factory->getFileIterator($paths, $suffixes, $prefixes, $exclude); + + $files = []; + + foreach ($iterator as $file) { + $file = $file->getRealPath(); + + if ($file) { + $files[] = $file; + } + } + + foreach ($paths as $path) { + if (\is_file($path)) { + $files[] = \realpath($path); + } + } + + $files = \array_unique($files); + \sort($files); + + if ($commonPath) { + return [ + 'commonPath' => $this->getCommonPath($files), + 'files' => $files + ]; + } + + return $files; + } + + protected function getCommonPath(array $files): string + { + $count = \count($files); + + if ($count === 0) { + return ''; + } + + if ($count === 1) { + return \dirname($files[0]) . DIRECTORY_SEPARATOR; + } + + $_files = []; + + foreach ($files as $file) { + $_files[] = $_fileParts = \explode(DIRECTORY_SEPARATOR, $file); + + if (empty($_fileParts[0])) { + $_fileParts[0] = DIRECTORY_SEPARATOR; + } + } + + $common = ''; + $done = false; + $j = 0; + $count--; + + while (!$done) { + for ($i = 0; $i < $count; $i++) { + if ($_files[$i][$j] != $_files[$i + 1][$j]) { + $done = true; + + break; + } + } + + if (!$done) { + $common .= $_files[0][$j]; + + if ($j > 0) { + $common .= DIRECTORY_SEPARATOR; + } + } + + $j++; + } + + return DIRECTORY_SEPARATOR . $common; + } +} diff --git a/vendor/phpunit/php-file-iterator/src/Factory.php b/vendor/phpunit/php-file-iterator/src/Factory.php new file mode 100644 index 0000000..02e2f38 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/src/Factory.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\FileIterator; + +class Factory +{ + /** + * @param array|string $paths + * @param array|string $suffixes + * @param array|string $prefixes + * @param array $exclude + * + * @return \AppendIterator + */ + public function getFileIterator($paths, $suffixes = '', $prefixes = '', array $exclude = []): \AppendIterator + { + if (\is_string($paths)) { + $paths = [$paths]; + } + + $paths = $this->getPathsAfterResolvingWildcards($paths); + $exclude = $this->getPathsAfterResolvingWildcards($exclude); + + if (\is_string($prefixes)) { + if ($prefixes !== '') { + $prefixes = [$prefixes]; + } else { + $prefixes = []; + } + } + + if (\is_string($suffixes)) { + if ($suffixes !== '') { + $suffixes = [$suffixes]; + } else { + $suffixes = []; + } + } + + $iterator = new \AppendIterator; + + foreach ($paths as $path) { + if (\is_dir($path)) { + $iterator->append( + new Iterator( + $path, + new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::FOLLOW_SYMLINKS | \RecursiveDirectoryIterator::SKIP_DOTS) + ), + $suffixes, + $prefixes, + $exclude + ) + ); + } + } + + return $iterator; + } + + protected function getPathsAfterResolvingWildcards(array $paths): array + { + $_paths = []; + + foreach ($paths as $path) { + if ($locals = \glob($path, GLOB_ONLYDIR)) { + $_paths = \array_merge($_paths, \array_map('\realpath', $locals)); + } else { + $_paths[] = \realpath($path); + } + } + + return \array_filter($_paths); + } +} diff --git a/vendor/phpunit/php-file-iterator/src/Iterator.php b/vendor/phpunit/php-file-iterator/src/Iterator.php new file mode 100644 index 0000000..84882d4 --- /dev/null +++ b/vendor/phpunit/php-file-iterator/src/Iterator.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace SebastianBergmann\FileIterator; + +class Iterator extends \FilterIterator +{ + const PREFIX = 0; + const SUFFIX = 1; + + /** + * @var string + */ + private $basePath; + + /** + * @var array + */ + private $suffixes = []; + + /** + * @var array + */ + private $prefixes = []; + + /** + * @var array + */ + private $exclude = []; + + /** + * @param string $basePath + * @param \Iterator $iterator + * @param array $suffixes + * @param array $prefixes + * @param array $exclude + */ + public function __construct(string $basePath, \Iterator $iterator, array $suffixes = [], array $prefixes = [], array $exclude = []) + { + $this->basePath = \realpath($basePath); + $this->prefixes = $prefixes; + $this->suffixes = $suffixes; + $this->exclude = \array_filter(\array_map('realpath', $exclude)); + + parent::__construct($iterator); + } + + public function accept() + { + $current = $this->getInnerIterator()->current(); + $filename = $current->getFilename(); + $realPath = $current->getRealPath(); + + return $this->acceptPath($realPath) && + $this->acceptPrefix($filename) && + $this->acceptSuffix($filename); + } + + private function acceptPath(string $path): bool + { + // Filter files in hidden directories by checking path that is relative to the base path. + if (\preg_match('=/\.[^/]*/=', \str_replace($this->basePath, '', $path))) { + return false; + } + + foreach ($this->exclude as $exclude) { + if (\strpos($path, $exclude) === 0) { + return false; + } + } + + return true; + } + + private function acceptPrefix(string $filename): bool + { + return $this->acceptSubString($filename, $this->prefixes, self::PREFIX); + } + + private function acceptSuffix(string $filename): bool + { + return $this->acceptSubString($filename, $this->suffixes, self::SUFFIX); + } + + private function acceptSubString(string $filename, array $subStrings, int $type): bool + { + if (empty($subStrings)) { + return true; + } + + $matched = false; + + foreach ($subStrings as $string) { + if (($type === self::PREFIX && \strpos($filename, $string) === 0) || + ($type === self::SUFFIX && + \substr($filename, -1 * \strlen($string)) === $string)) { + $matched = true; + + break; + } + } + + return $matched; + } +} diff --git a/vendor/phpunit/php-file-iterator/tests/FactoryTest.php b/vendor/phpunit/php-file-iterator/tests/FactoryTest.php new file mode 100644 index 0000000..ba4bdbf --- /dev/null +++ b/vendor/phpunit/php-file-iterator/tests/FactoryTest.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\FileIterator; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \SebastianBergmann\FileIterator\Factory + */ +class FactoryTest extends TestCase +{ + /** + * @var string + */ + private $root; + + /** + * @var Factory + */ + private $factory; + + protected function setUp(): void + { + $this->root = __DIR__; + $this->factory = new Factory; + } + + public function testFindFilesInTestDirectory(): void + { + $iterator = $this->factory->getFileIterator($this->root, 'Test.php'); + $files = \iterator_to_array($iterator); + + $this->assertGreaterThanOrEqual(1, \count($files)); + } + + public function testFindFilesWithExcludedNonExistingSubdirectory(): void + { + $iterator = $this->factory->getFileIterator($this->root, 'Test.php', '', [$this->root . '/nonExistingDir']); + $files = \iterator_to_array($iterator); + + $this->assertGreaterThanOrEqual(1, \count($files)); + } +} diff --git a/vendor/phpunit/php-text-template/.gitattributes b/vendor/phpunit/php-text-template/.gitattributes new file mode 100644 index 0000000..461090b --- /dev/null +++ b/vendor/phpunit/php-text-template/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/vendor/phpunit/php-text-template/.gitignore b/vendor/phpunit/php-text-template/.gitignore new file mode 100644 index 0000000..c599212 --- /dev/null +++ b/vendor/phpunit/php-text-template/.gitignore @@ -0,0 +1,5 @@ +/composer.lock +/composer.phar +/.idea +/vendor + diff --git a/vendor/phpunit/php-text-template/LICENSE b/vendor/phpunit/php-text-template/LICENSE new file mode 100644 index 0000000..9f9a32d --- /dev/null +++ b/vendor/phpunit/php-text-template/LICENSE @@ -0,0 +1,33 @@ +Text_Template + +Copyright (c) 2009-2015, Sebastian Bergmann . +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/php-text-template/README.md b/vendor/phpunit/php-text-template/README.md new file mode 100644 index 0000000..ec8f593 --- /dev/null +++ b/vendor/phpunit/php-text-template/README.md @@ -0,0 +1,14 @@ +# Text_Template + +## Installation + +## Installation + +To add this package as a local, per-project dependency to your project, simply add a dependency on `phpunit/php-text-template` to your project's `composer.json` file. Here is a minimal example of a `composer.json` file that just defines a dependency on Text_Template: + + { + "require": { + "phpunit/php-text-template": "~1.2" + } + } + diff --git a/vendor/phpunit/php-text-template/composer.json b/vendor/phpunit/php-text-template/composer.json new file mode 100644 index 0000000..a5779c8 --- /dev/null +++ b/vendor/phpunit/php-text-template/composer.json @@ -0,0 +1,29 @@ +{ + "name": "phpunit/php-text-template", + "description": "Simple template engine.", + "type": "library", + "keywords": [ + "template" + ], + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues" + }, + "require": { + "php": ">=5.3.3" + }, + "autoload": { + "classmap": [ + "src/" + ] + } +} + diff --git a/vendor/phpunit/php-text-template/src/Template.php b/vendor/phpunit/php-text-template/src/Template.php new file mode 100644 index 0000000..9eb39ad --- /dev/null +++ b/vendor/phpunit/php-text-template/src/Template.php @@ -0,0 +1,135 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A simple template engine. + * + * @since Class available since Release 1.0.0 + */ +class Text_Template +{ + /** + * @var string + */ + protected $template = ''; + + /** + * @var string + */ + protected $openDelimiter = '{'; + + /** + * @var string + */ + protected $closeDelimiter = '}'; + + /** + * @var array + */ + protected $values = array(); + + /** + * Constructor. + * + * @param string $file + * @throws InvalidArgumentException + */ + public function __construct($file = '', $openDelimiter = '{', $closeDelimiter = '}') + { + $this->setFile($file); + $this->openDelimiter = $openDelimiter; + $this->closeDelimiter = $closeDelimiter; + } + + /** + * Sets the template file. + * + * @param string $file + * @throws InvalidArgumentException + */ + public function setFile($file) + { + $distFile = $file . '.dist'; + + if (file_exists($file)) { + $this->template = file_get_contents($file); + } + + else if (file_exists($distFile)) { + $this->template = file_get_contents($distFile); + } + + else { + throw new InvalidArgumentException( + 'Template file could not be loaded.' + ); + } + } + + /** + * Sets one or more template variables. + * + * @param array $values + * @param bool $merge + */ + public function setVar(array $values, $merge = TRUE) + { + if (!$merge || empty($this->values)) { + $this->values = $values; + } else { + $this->values = array_merge($this->values, $values); + } + } + + /** + * Renders the template and returns the result. + * + * @return string + */ + public function render() + { + $keys = array(); + + foreach ($this->values as $key => $value) { + $keys[] = $this->openDelimiter . $key . $this->closeDelimiter; + } + + return str_replace($keys, $this->values, $this->template); + } + + /** + * Renders the template and writes the result to a file. + * + * @param string $target + */ + public function renderTo($target) + { + $fp = @fopen($target, 'wt'); + + if ($fp) { + fwrite($fp, $this->render()); + fclose($fp); + } else { + $error = error_get_last(); + + throw new RuntimeException( + sprintf( + 'Could not write to %s: %s', + $target, + substr( + $error['message'], + strpos($error['message'], ':') + 2 + ) + ) + ); + } + } +} + diff --git a/vendor/phpunit/php-timer/.gitattributes b/vendor/phpunit/php-timer/.gitattributes new file mode 100644 index 0000000..461090b --- /dev/null +++ b/vendor/phpunit/php-timer/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/vendor/phpunit/php-timer/.github/FUNDING.yml b/vendor/phpunit/php-timer/.github/FUNDING.yml new file mode 100644 index 0000000..b19ea81 --- /dev/null +++ b/vendor/phpunit/php-timer/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: s_bergmann diff --git a/vendor/phpunit/php-timer/.github/stale.yml b/vendor/phpunit/php-timer/.github/stale.yml new file mode 100644 index 0000000..4eadca3 --- /dev/null +++ b/vendor/phpunit/php-timer/.github/stale.yml @@ -0,0 +1,40 @@ +# Configuration for probot-stale - https://github.com/probot/stale + +# Number of days of inactivity before an Issue or Pull Request becomes stale +daysUntilStale: 60 + +# Number of days of inactivity before a stale Issue or Pull Request is closed. +# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale. +daysUntilClose: 7 + +# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable +exemptLabels: + - enhancement + +# Set to true to ignore issues in a project (defaults to false) +exemptProjects: false + +# Set to true to ignore issues in a milestone (defaults to false) +exemptMilestones: false + +# Label to use when marking as stale +staleLabel: stale + +# Comment to post when marking as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had activity within the last 60 days. It will be closed after 7 days if no further activity occurs. Thank you for your contributions. + +# Comment to post when removing the stale label. +# unmarkComment: > +# Your comment here. + +# Comment to post when closing a stale Issue or Pull Request. +closeComment: > + This issue has been automatically closed because it has not had activity since it was marked as stale. Thank you for your contributions. + +# Limit the number of actions per hour, from 1-30. Default is 30 +limitPerRun: 30 + +# Limit to only `issues` or `pulls` +only: issues + diff --git a/vendor/phpunit/php-timer/.gitignore b/vendor/phpunit/php-timer/.gitignore new file mode 100644 index 0000000..953d2a2 --- /dev/null +++ b/vendor/phpunit/php-timer/.gitignore @@ -0,0 +1,5 @@ +/.idea +/.php_cs.cache +/vendor +/composer.lock + diff --git a/vendor/phpunit/php-timer/.php_cs.dist b/vendor/phpunit/php-timer/.php_cs.dist new file mode 100644 index 0000000..c442264 --- /dev/null +++ b/vendor/phpunit/php-timer/.php_cs.dist @@ -0,0 +1,197 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +EOF; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules( + [ + 'align_multiline_comment' => true, + 'array_indentation' => true, + 'array_syntax' => ['syntax' => 'short'], + 'binary_operator_spaces' => [ + 'operators' => [ + '=' => 'align', + '=>' => 'align', + ], + ], + 'blank_line_after_namespace' => true, + 'blank_line_before_statement' => [ + 'statements' => [ + 'break', + 'continue', + 'declare', + 'do', + 'for', + 'foreach', + 'if', + 'include', + 'include_once', + 'require', + 'require_once', + 'return', + 'switch', + 'throw', + 'try', + 'while', + 'yield', + ], + ], + 'braces' => true, + 'cast_spaces' => true, + 'class_attributes_separation' => ['elements' => ['const', 'method', 'property']], + 'combine_consecutive_issets' => true, + 'combine_consecutive_unsets' => true, + 'compact_nullable_typehint' => true, + 'concat_space' => ['spacing' => 'one'], + 'declare_equal_normalize' => ['space' => 'none'], + 'declare_strict_types' => true, + 'dir_constant' => true, + 'elseif' => true, + 'encoding' => true, + 'full_opening_tag' => true, + 'function_declaration' => true, + 'header_comment' => ['header' => $header, 'separate' => 'none'], + 'indentation_type' => true, + 'is_null' => true, + 'line_ending' => true, + 'list_syntax' => ['syntax' => 'short'], + 'logical_operators' => true, + 'lowercase_cast' => true, + 'lowercase_constants' => true, + 'lowercase_keywords' => true, + 'lowercase_static_reference' => true, + 'magic_constant_casing' => true, + 'method_argument_space' => ['ensure_fully_multiline' => true], + 'modernize_types_casting' => true, + 'multiline_comment_opening_closing' => true, + 'multiline_whitespace_before_semicolons' => true, + 'native_constant_invocation' => true, + 'native_function_casing' => true, + 'native_function_invocation' => true, + 'new_with_braces' => false, + 'no_alias_functions' => true, + 'no_alternative_syntax' => true, + 'no_blank_lines_after_class_opening' => true, + 'no_blank_lines_after_phpdoc' => true, + 'no_blank_lines_before_namespace' => true, + 'no_closing_tag' => true, + 'no_empty_comment' => true, + 'no_empty_phpdoc' => true, + 'no_empty_statement' => true, + 'no_extra_blank_lines' => true, + 'no_homoglyph_names' => true, + 'no_leading_import_slash' => true, + 'no_leading_namespace_whitespace' => true, + 'no_mixed_echo_print' => ['use' => 'print'], + 'no_multiline_whitespace_around_double_arrow' => true, + 'no_null_property_initialization' => true, + 'no_php4_constructor' => true, + 'no_short_bool_cast' => true, + 'no_short_echo_tag' => true, + 'no_singleline_whitespace_before_semicolons' => true, + 'no_spaces_after_function_name' => true, + 'no_spaces_inside_parenthesis' => true, + 'no_superfluous_elseif' => true, + 'no_superfluous_phpdoc_tags' => true, + 'no_trailing_comma_in_list_call' => true, + 'no_trailing_comma_in_singleline_array' => true, + 'no_trailing_whitespace' => true, + 'no_trailing_whitespace_in_comment' => true, + 'no_unneeded_control_parentheses' => true, + 'no_unneeded_curly_braces' => true, + 'no_unneeded_final_method' => true, + 'no_unreachable_default_argument_value' => true, + 'no_unset_on_property' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'no_whitespace_before_comma_in_array' => true, + 'no_whitespace_in_blank_line' => true, + 'non_printable_character' => true, + 'normalize_index_brace' => true, + 'object_operator_without_whitespace' => true, + 'ordered_class_elements' => [ + 'order' => [ + 'use_trait', + 'constant_public', + 'constant_protected', + 'constant_private', + 'property_public_static', + 'property_protected_static', + 'property_private_static', + 'property_public', + 'property_protected', + 'property_private', + 'method_public_static', + 'construct', + 'destruct', + 'magic', + 'phpunit', + 'method_public', + 'method_protected', + 'method_private', + 'method_protected_static', + 'method_private_static', + ], + ], + 'ordered_imports' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'phpdoc_align' => true, + 'phpdoc_annotation_without_dot' => true, + 'phpdoc_indent' => true, + 'phpdoc_no_access' => true, + 'phpdoc_no_empty_return' => true, + 'phpdoc_no_package' => true, + 'phpdoc_order' => true, + 'phpdoc_return_self_reference' => true, + 'phpdoc_scalar' => true, + 'phpdoc_separation' => true, + 'phpdoc_single_line_var_spacing' => true, + 'phpdoc_to_comment' => true, + 'phpdoc_trim' => true, + 'phpdoc_trim_consecutive_blank_line_separation' => true, + 'phpdoc_types' => ['groups' => ['simple', 'meta']], + 'phpdoc_types_order' => true, + 'phpdoc_var_without_name' => true, + 'pow_to_exponentiation' => true, + 'protected_to_private' => true, + 'return_assignment' => true, + 'return_type_declaration' => ['space_before' => 'none'], + 'self_accessor' => true, + 'semicolon_after_instruction' => true, + 'set_type_to_cast' => true, + 'short_scalar_cast' => true, + 'simplified_null_return' => true, + 'single_blank_line_at_eof' => true, + 'single_import_per_statement' => true, + 'single_line_after_imports' => true, + 'single_quote' => true, + 'standardize_not_equals' => true, + 'ternary_to_null_coalescing' => true, + 'trailing_comma_in_multiline_array' => true, + 'trim_array_spaces' => true, + 'unary_operator_spaces' => true, + 'visibility_required' => [ + 'elements' => [ + 'const', + 'method', + 'property', + ], + ], + 'void_return' => true, + 'whitespace_after_comma_in_array' => true, + ] + ) + ->setFinder( + PhpCsFixer\Finder::create() + ->files() + ->in(__DIR__ . '/src') + ->in(__DIR__ . '/tests') + ); diff --git a/vendor/phpunit/php-timer/.travis.yml b/vendor/phpunit/php-timer/.travis.yml new file mode 100644 index 0000000..a217292 --- /dev/null +++ b/vendor/phpunit/php-timer/.travis.yml @@ -0,0 +1,23 @@ +language: php + +php: + - 7.1 + - 7.2 + - 7.3 + - 7.4snapshot + +before_install: + - composer self-update + - composer clear-cache + +install: + - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest + +script: + - ./vendor/bin/phpunit --coverage-clover=coverage.xml + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false diff --git a/vendor/phpunit/php-timer/ChangeLog.md b/vendor/phpunit/php-timer/ChangeLog.md new file mode 100644 index 0000000..6ebc9fe --- /dev/null +++ b/vendor/phpunit/php-timer/ChangeLog.md @@ -0,0 +1,36 @@ +# ChangeLog + +All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [2.1.2] - 2019-06-07 + +### Fixed + +* Fixed [#21](https://github.com/sebastianbergmann/php-timer/pull/3352): Formatting of memory consumption does not work on 32bit systems + +## [2.1.1] - 2019-02-20 + +### Changed + +* Improved formatting of memory consumption for `resourceUsage()` + +## [2.1.0] - 2019-02-20 + +### Changed + +* Improved formatting of memory consumption for `resourceUsage()` + +## [2.0.0] - 2018-02-01 + +### Changed + +* This component now uses namespaces + +### Removed + +* This component is no longer supported on PHP 5.3, PHP 5.4, PHP 5.5, PHP 5.6, and PHP 7.0 + +[2.1.2]: https://github.com/sebastianbergmann/diff/compare/2.1.1...2.1.2 +[2.1.1]: https://github.com/sebastianbergmann/diff/compare/2.1.0...2.1.1 +[2.1.0]: https://github.com/sebastianbergmann/diff/compare/2.0.0...2.1.0 +[2.0.0]: https://github.com/sebastianbergmann/diff/compare/1.0.9...2.0.0 diff --git a/vendor/phpunit/php-timer/LICENSE b/vendor/phpunit/php-timer/LICENSE new file mode 100644 index 0000000..a4eb944 --- /dev/null +++ b/vendor/phpunit/php-timer/LICENSE @@ -0,0 +1,33 @@ +phpunit/php-timer + +Copyright (c) 2010-2019, Sebastian Bergmann . +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/php-timer/README.md b/vendor/phpunit/php-timer/README.md new file mode 100644 index 0000000..61725c2 --- /dev/null +++ b/vendor/phpunit/php-timer/README.md @@ -0,0 +1,49 @@ +[![Build Status](https://travis-ci.org/sebastianbergmann/php-timer.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-timer) + +# phpunit/php-timer + +Utility class for timing things, factored out of PHPUnit into a stand-alone component. + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phpunit/php-timer + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phpunit/php-timer + +## Usage + +### Basic Timing + +```php +use SebastianBergmann\Timer\Timer; + +Timer::start(); + +// ... + +$time = Timer::stop(); +var_dump($time); + +print Timer::secondsToTimeString($time); +``` + +The code above yields the output below: + + double(1.0967254638672E-5) + 0 ms + +### Resource Consumption Since PHP Startup + +```php +use SebastianBergmann\Timer\Timer; + +print Timer::resourceUsage(); +``` + +The code above yields the output below: + + Time: 0 ms, Memory: 0.50MB diff --git a/vendor/phpunit/php-timer/build.xml b/vendor/phpunit/php-timer/build.xml new file mode 100644 index 0000000..b8d3256 --- /dev/null +++ b/vendor/phpunit/php-timer/build.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-timer/composer.json b/vendor/phpunit/php-timer/composer.json new file mode 100644 index 0000000..d400ad7 --- /dev/null +++ b/vendor/phpunit/php-timer/composer.json @@ -0,0 +1,42 @@ +{ + "name": "phpunit/php-timer", + "description": "Utility class for timing", + "type": "library", + "keywords": [ + "timer" + ], + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues" + }, + "prefer-stable": true, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + } +} + diff --git a/vendor/phpunit/php-timer/phpunit.xml b/vendor/phpunit/php-timer/phpunit.xml new file mode 100644 index 0000000..28a95de --- /dev/null +++ b/vendor/phpunit/php-timer/phpunit.xml @@ -0,0 +1,19 @@ + + + + tests + + + + + src + + + diff --git a/vendor/phpunit/php-timer/src/Exception.php b/vendor/phpunit/php-timer/src/Exception.php new file mode 100644 index 0000000..7f9a26b --- /dev/null +++ b/vendor/phpunit/php-timer/src/Exception.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Timer; + +interface Exception +{ +} diff --git a/vendor/phpunit/php-timer/src/RuntimeException.php b/vendor/phpunit/php-timer/src/RuntimeException.php new file mode 100644 index 0000000..aff06fa --- /dev/null +++ b/vendor/phpunit/php-timer/src/RuntimeException.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Timer; + +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/phpunit/php-timer/src/Timer.php b/vendor/phpunit/php-timer/src/Timer.php new file mode 100644 index 0000000..378ff72 --- /dev/null +++ b/vendor/phpunit/php-timer/src/Timer.php @@ -0,0 +1,100 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Timer; + +final class Timer +{ + /** + * @var int[] + */ + private static $sizes = [ + 'GB' => 1073741824, + 'MB' => 1048576, + 'KB' => 1024, + ]; + + /** + * @var int[] + */ + private static $times = [ + 'hour' => 3600000, + 'minute' => 60000, + 'second' => 1000, + ]; + + /** + * @var float[] + */ + private static $startTimes = []; + + public static function start(): void + { + self::$startTimes[] = \microtime(true); + } + + public static function stop(): float + { + return \microtime(true) - \array_pop(self::$startTimes); + } + + public static function bytesToString(float $bytes): string + { + foreach (self::$sizes as $unit => $value) { + if ($bytes >= $value) { + return \sprintf('%.2f %s', $bytes >= 1024 ? $bytes / $value : $bytes, $unit); + } + } + + return $bytes . ' byte' . ((int) $bytes !== 1 ? 's' : ''); + } + + public static function secondsToTimeString(float $time): string + { + $ms = \round($time * 1000); + + foreach (self::$times as $unit => $value) { + if ($ms >= $value) { + $time = \floor($ms / $value * 100.0) / 100.0; + + return $time . ' ' . ($time == 1 ? $unit : $unit . 's'); + } + } + + return $ms . ' ms'; + } + + /** + * @throws RuntimeException + */ + public static function timeSinceStartOfRequest(): string + { + if (isset($_SERVER['REQUEST_TIME_FLOAT'])) { + $startOfRequest = $_SERVER['REQUEST_TIME_FLOAT']; + } elseif (isset($_SERVER['REQUEST_TIME'])) { + $startOfRequest = $_SERVER['REQUEST_TIME']; + } else { + throw new RuntimeException('Cannot determine time at which the request started'); + } + + return self::secondsToTimeString(\microtime(true) - $startOfRequest); + } + + /** + * @throws RuntimeException + */ + public static function resourceUsage(): string + { + return \sprintf( + 'Time: %s, Memory: %s', + self::timeSinceStartOfRequest(), + self::bytesToString(\memory_get_peak_usage(true)) + ); + } +} diff --git a/vendor/phpunit/php-timer/tests/TimerTest.php b/vendor/phpunit/php-timer/tests/TimerTest.php new file mode 100644 index 0000000..93cc474 --- /dev/null +++ b/vendor/phpunit/php-timer/tests/TimerTest.php @@ -0,0 +1,134 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace SebastianBergmann\Timer; + +use PHPUnit\Framework\TestCase; + +/** + * @covers \SebastianBergmann\Timer\Timer + */ +final class TimerTest extends TestCase +{ + public function testCanBeStartedAndStopped(): void + { + $this->assertIsFloat(Timer::stop()); + } + + public function testCanFormatTimeSinceStartOfRequest(): void + { + $this->assertStringMatchesFormat('%f %s', Timer::timeSinceStartOfRequest()); + } + + /** + * @backupGlobals enabled + */ + public function testCanFormatSinceStartOfRequestWhenRequestTimeIsNotAvailableAsFloat(): void + { + if (isset($_SERVER['REQUEST_TIME_FLOAT'])) { + unset($_SERVER['REQUEST_TIME_FLOAT']); + } + + $this->assertStringMatchesFormat('%f %s', Timer::timeSinceStartOfRequest()); + } + + /** + * @backupGlobals enabled + */ + public function testCannotFormatTimeSinceStartOfRequestWhenRequestTimeIsNotAvailable(): void + { + if (isset($_SERVER['REQUEST_TIME_FLOAT'])) { + unset($_SERVER['REQUEST_TIME_FLOAT']); + } + + if (isset($_SERVER['REQUEST_TIME'])) { + unset($_SERVER['REQUEST_TIME']); + } + + $this->expectException(RuntimeException::class); + + Timer::timeSinceStartOfRequest(); + } + + public function testCanFormatResourceUsage(): void + { + $this->assertStringMatchesFormat('Time: %s, Memory: %f %s', Timer::resourceUsage()); + } + + /** + * @dataProvider secondsProvider + */ + public function testCanFormatSecondsAsString(string $string, float $seconds): void + { + $this->assertEquals($string, Timer::secondsToTimeString($seconds)); + } + + public function secondsProvider(): array + { + return [ + ['0 ms', 0], + ['1 ms', .001], + ['10 ms', .01], + ['100 ms', .1], + ['999 ms', .999], + ['1 second', .9999], + ['1 second', 1], + ['2 seconds', 2], + ['59.9 seconds', 59.9], + ['59.99 seconds', 59.99], + ['59.99 seconds', 59.999], + ['1 minute', 59.9999], + ['59 seconds', 59.001], + ['59.01 seconds', 59.01], + ['1 minute', 60], + ['1.01 minutes', 61], + ['2 minutes', 120], + ['2.01 minutes', 121], + ['59.99 minutes', 3599.9], + ['59.99 minutes', 3599.99], + ['59.99 minutes', 3599.999], + ['1 hour', 3599.9999], + ['59.98 minutes', 3599.001], + ['59.98 minutes', 3599.01], + ['1 hour', 3600], + ['1 hour', 3601], + ['1 hour', 3601.9], + ['1 hour', 3601.99], + ['1 hour', 3601.999], + ['1 hour', 3601.9999], + ['1.01 hours', 3659.9999], + ['1.01 hours', 3659.001], + ['1.01 hours', 3659.01], + ['2 hours', 7199.9999], + ]; + } + + /** + * @dataProvider bytesProvider + */ + public function testCanFormatBytesAsString(string $string, float $bytes): void + { + $this->assertEquals($string, Timer::bytesToString($bytes)); + } + + public function bytesProvider(): array + { + return [ + ['0 bytes', 0], + ['1 byte', 1], + ['1023 bytes', 1023], + ['1.00 KB', 1024], + ['1.50 KB', 1.5 * 1024], + ['2.00 MB', 2 * 1048576], + ['2.50 MB', 2.5 * 1048576], + ['3.00 GB', 3 * 1073741824], + ['3.50 GB', 3.5 * 1073741824], + ]; + } +} diff --git a/vendor/phpunit/php-token-stream/.gitattributes b/vendor/phpunit/php-token-stream/.gitattributes new file mode 100644 index 0000000..461090b --- /dev/null +++ b/vendor/phpunit/php-token-stream/.gitattributes @@ -0,0 +1 @@ +*.php diff=php diff --git a/vendor/phpunit/php-token-stream/.github/FUNDING.yml b/vendor/phpunit/php-token-stream/.github/FUNDING.yml new file mode 100644 index 0000000..b19ea81 --- /dev/null +++ b/vendor/phpunit/php-token-stream/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: s_bergmann diff --git a/vendor/phpunit/php-token-stream/.gitignore b/vendor/phpunit/php-token-stream/.gitignore new file mode 100644 index 0000000..77aae3d --- /dev/null +++ b/vendor/phpunit/php-token-stream/.gitignore @@ -0,0 +1,3 @@ +/.idea +/composer.lock +/vendor diff --git a/vendor/phpunit/php-token-stream/.travis.yml b/vendor/phpunit/php-token-stream/.travis.yml new file mode 100644 index 0000000..4e8056d --- /dev/null +++ b/vendor/phpunit/php-token-stream/.travis.yml @@ -0,0 +1,26 @@ +language: php + +php: + - 7.1 + - 7.2 + - 7.3 + - 7.4snapshot + +sudo: false + +before_install: + - composer self-update + - composer clear-cache + +install: + - travis_retry composer update --no-interaction --no-ansi --no-progress --no-suggest + +script: + - ./vendor/bin/phpunit --coverage-clover=coverage.xml + +after_success: + - bash <(curl -s https://codecov.io/bash) + +notifications: + email: false + diff --git a/vendor/phpunit/php-token-stream/ChangeLog.md b/vendor/phpunit/php-token-stream/ChangeLog.md new file mode 100644 index 0000000..884fd1f --- /dev/null +++ b/vendor/phpunit/php-token-stream/ChangeLog.md @@ -0,0 +1,57 @@ +# Change Log + +All notable changes to `sebastianbergmann/php-token-stream` are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles. + +## [3.1.1] - 2019-09-17 + +### Fixed + +* Fixed [#84](https://github.com/sebastianbergmann/php-token-stream/issues/84): Methods named `class` are not handled correctly + +## [3.1.0] - 2019-07-25 + +### Added + +* Added support for `FN` and `COALESCE_EQUAL` tokens introduced in PHP 7.4 + +## [3.0.2] - 2019-07-08 + +### Changed + +* Implemented [#82](https://github.com/sebastianbergmann/php-token-stream/issues/82): Make sure this component works when its classes are prefixed using php-scoper + +## [3.0.1] - 2018-10-30 + +### Fixed + +* Fixed [#78](https://github.com/sebastianbergmann/php-token-stream/pull/78): `getEndTokenId()` does not handle string-dollar (`"${var}"`) interpolation + +## [3.0.0] - 2018-02-01 + +### Removed + +* Implemented [#71](https://github.com/sebastianbergmann/php-token-stream/issues/71): Remove code specific to Hack language constructs +* Implemented [#72](https://github.com/sebastianbergmann/php-token-stream/issues/72): Drop support for PHP 7.0 + +## [2.0.2] - 2017-11-27 + +### Fixed + +* Fixed [#69](https://github.com/sebastianbergmann/php-token-stream/issues/69): `PHP_Token_USE_FUNCTION` does not serialize correctly + +## [2.0.1] - 2017-08-20 + +### Fixed + +* Fixed [#68](https://github.com/sebastianbergmann/php-token-stream/issues/68): Method with name `empty` wrongly recognized as anonymous function + +## [2.0.0] - 2017-08-03 + +[3.1.1]: https://github.com/sebastianbergmann/php-token-stream/compare/3.1.0...3.1.1 +[3.1.0]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.2...3.1.0 +[3.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.1...3.0.2 +[3.0.1]: https://github.com/sebastianbergmann/php-token-stream/compare/3.0.0...3.0.1 +[3.0.0]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0...3.0.0 +[2.0.2]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0.1...2.0.2 +[2.0.1]: https://github.com/sebastianbergmann/php-token-stream/compare/2.0.0...2.0.1 +[2.0.0]: https://github.com/sebastianbergmann/php-token-stream/compare/1.4.11...2.0.0 diff --git a/vendor/phpunit/php-token-stream/LICENSE b/vendor/phpunit/php-token-stream/LICENSE new file mode 100644 index 0000000..2cad5be --- /dev/null +++ b/vendor/phpunit/php-token-stream/LICENSE @@ -0,0 +1,33 @@ +php-token-stream + +Copyright (c) 2009-2019, Sebastian Bergmann . +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/php-token-stream/README.md b/vendor/phpunit/php-token-stream/README.md new file mode 100644 index 0000000..149b7e2 --- /dev/null +++ b/vendor/phpunit/php-token-stream/README.md @@ -0,0 +1,14 @@ +[![Build Status](https://travis-ci.org/sebastianbergmann/php-token-stream.svg?branch=master)](https://travis-ci.org/sebastianbergmann/php-token-stream) + +# php-token-stream + +## Installation + +You can add this library as a local, per-project dependency to your project using [Composer](https://getcomposer.org/): + + composer require phpunit/php-token-stream + +If you only need this library during development, for instance to run your project's test suite, then you should add it as a development-time dependency: + + composer require --dev phpunit/php-token-stream + diff --git a/vendor/phpunit/php-token-stream/build.xml b/vendor/phpunit/php-token-stream/build.xml new file mode 100644 index 0000000..0da8056 --- /dev/null +++ b/vendor/phpunit/php-token-stream/build.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/php-token-stream/composer.json b/vendor/phpunit/php-token-stream/composer.json new file mode 100644 index 0000000..f50e937 --- /dev/null +++ b/vendor/phpunit/php-token-stream/composer.json @@ -0,0 +1,39 @@ +{ + "name": "phpunit/php-token-stream", + "description": "Wrapper around PHP's tokenizer extension.", + "type": "library", + "keywords": ["tokenizer"], + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues" + }, + "prefer-stable": true, + "require": { + "php": "^7.1", + "ext-tokenizer": "*" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "config": { + "optimize-autoloader": true, + "sort-packages": true + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + } +} diff --git a/vendor/phpunit/php-token-stream/phpunit.xml b/vendor/phpunit/php-token-stream/phpunit.xml new file mode 100644 index 0000000..8f159fb --- /dev/null +++ b/vendor/phpunit/php-token-stream/phpunit.xml @@ -0,0 +1,21 @@ + + + + + tests + + + + + + src + + + diff --git a/vendor/phpunit/php-token-stream/src/Token.php b/vendor/phpunit/php-token-stream/src/Token.php new file mode 100644 index 0000000..65fdb06 --- /dev/null +++ b/vendor/phpunit/php-token-stream/src/Token.php @@ -0,0 +1,1361 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A PHP token. + */ +abstract class PHP_Token +{ + /** + * @var string + */ + protected $text; + + /** + * @var int + */ + protected $line; + + /** + * @var PHP_Token_Stream + */ + protected $tokenStream; + + /** + * @var int + */ + protected $id; + + /** + * @param string $text + * @param int $line + * @param PHP_Token_Stream $tokenStream + * @param int $id + */ + public function __construct($text, $line, PHP_Token_Stream $tokenStream, $id) + { + $this->text = $text; + $this->line = $line; + $this->tokenStream = $tokenStream; + $this->id = $id; + } + + /** + * @return string + */ + public function __toString() + { + return $this->text; + } + + /** + * @return int + */ + public function getLine() + { + return $this->line; + } + + /** + * @return int + */ + public function getId() + { + return $this->id; + } +} + +abstract class PHP_TokenWithScope extends PHP_Token +{ + /** + * @var int + */ + protected $endTokenId; + + /** + * Get the docblock for this token + * + * This method will fetch the docblock belonging to the current token. The + * docblock must be placed on the line directly above the token to be + * recognized. + * + * @return string|null Returns the docblock as a string if found + */ + public function getDocblock() + { + $tokens = $this->tokenStream->tokens(); + $currentLineNumber = $tokens[$this->id]->getLine(); + $prevLineNumber = $currentLineNumber - 1; + + for ($i = $this->id - 1; $i; $i--) { + if (!isset($tokens[$i])) { + return; + } + + if ($tokens[$i] instanceof PHP_Token_FUNCTION || + $tokens[$i] instanceof PHP_Token_CLASS || + $tokens[$i] instanceof PHP_Token_TRAIT) { + // Some other trait, class or function, no docblock can be + // used for the current token + break; + } + + $line = $tokens[$i]->getLine(); + + if ($line == $currentLineNumber || + ($line == $prevLineNumber && + $tokens[$i] instanceof PHP_Token_WHITESPACE)) { + continue; + } + + if ($line < $currentLineNumber && + !$tokens[$i] instanceof PHP_Token_DOC_COMMENT) { + break; + } + + return (string) $tokens[$i]; + } + } + + /** + * @return int + */ + public function getEndTokenId() + { + $block = 0; + $i = $this->id; + $tokens = $this->tokenStream->tokens(); + + while ($this->endTokenId === null && isset($tokens[$i])) { + if ($tokens[$i] instanceof PHP_Token_OPEN_CURLY || + $tokens[$i] instanceof PHP_Token_DOLLAR_OPEN_CURLY_BRACES || + $tokens[$i] instanceof PHP_Token_CURLY_OPEN) { + $block++; + } elseif ($tokens[$i] instanceof PHP_Token_CLOSE_CURLY) { + $block--; + + if ($block === 0) { + $this->endTokenId = $i; + } + } elseif (($this instanceof PHP_Token_FUNCTION || + $this instanceof PHP_Token_NAMESPACE) && + $tokens[$i] instanceof PHP_Token_SEMICOLON) { + if ($block === 0) { + $this->endTokenId = $i; + } + } + + $i++; + } + + if ($this->endTokenId === null) { + $this->endTokenId = $this->id; + } + + return $this->endTokenId; + } + + /** + * @return int + */ + public function getEndLine() + { + return $this->tokenStream[$this->getEndTokenId()]->getLine(); + } +} + +abstract class PHP_TokenWithScopeAndVisibility extends PHP_TokenWithScope +{ + /** + * @return string + */ + public function getVisibility() + { + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_PRIVATE || + $tokens[$i] instanceof PHP_Token_PROTECTED || + $tokens[$i] instanceof PHP_Token_PUBLIC)) { + return strtolower( + str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i])) + ); + } + if (isset($tokens[$i]) && + !($tokens[$i] instanceof PHP_Token_STATIC || + $tokens[$i] instanceof PHP_Token_FINAL || + $tokens[$i] instanceof PHP_Token_ABSTRACT)) { + // no keywords; stop visibility search + break; + } + } + } + + /** + * @return string + */ + public function getKeywords() + { + $keywords = []; + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id - 2; $i > $this->id - 7; $i -= 2) { + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_PRIVATE || + $tokens[$i] instanceof PHP_Token_PROTECTED || + $tokens[$i] instanceof PHP_Token_PUBLIC)) { + continue; + } + + if (isset($tokens[$i]) && + ($tokens[$i] instanceof PHP_Token_STATIC || + $tokens[$i] instanceof PHP_Token_FINAL || + $tokens[$i] instanceof PHP_Token_ABSTRACT)) { + $keywords[] = strtolower( + str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$i])) + ); + } + } + + return implode(',', $keywords); + } +} + +abstract class PHP_Token_Includes extends PHP_Token +{ + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $type; + + /** + * @return string + */ + public function getName() + { + if ($this->name === null) { + $this->process(); + } + + return $this->name; + } + + /** + * @return string + */ + public function getType() + { + if ($this->type === null) { + $this->process(); + } + + return $this->type; + } + + private function process() + { + $tokens = $this->tokenStream->tokens(); + + if ($tokens[$this->id + 2] instanceof PHP_Token_CONSTANT_ENCAPSED_STRING) { + $this->name = trim($tokens[$this->id + 2], "'\""); + $this->type = strtolower( + str_replace('PHP_Token_', '', PHP_Token_Util::getClass($tokens[$this->id])) + ); + } + } +} + +class PHP_Token_FUNCTION extends PHP_TokenWithScopeAndVisibility +{ + /** + * @var array + */ + protected $arguments; + + /** + * @var int + */ + protected $ccn; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $signature; + + /** + * @var bool + */ + private $anonymous = false; + + /** + * @return array + */ + public function getArguments() + { + if ($this->arguments !== null) { + return $this->arguments; + } + + $this->arguments = []; + $tokens = $this->tokenStream->tokens(); + $typeDeclaration = null; + + // Search for first token inside brackets + $i = $this->id + 2; + + while (!$tokens[$i - 1] instanceof PHP_Token_OPEN_BRACKET) { + $i++; + } + + while (!$tokens[$i] instanceof PHP_Token_CLOSE_BRACKET) { + if ($tokens[$i] instanceof PHP_Token_STRING) { + $typeDeclaration = (string) $tokens[$i]; + } elseif ($tokens[$i] instanceof PHP_Token_VARIABLE) { + $this->arguments[(string) $tokens[$i]] = $typeDeclaration; + $typeDeclaration = null; + } + + $i++; + } + + return $this->arguments; + } + + /** + * @return string + */ + public function getName() + { + if ($this->name !== null) { + return $this->name; + } + + $tokens = $this->tokenStream->tokens(); + + $i = $this->id + 1; + + if ($tokens[$i] instanceof PHP_Token_WHITESPACE) { + $i++; + } + + if ($tokens[$i] instanceof PHP_Token_AMPERSAND) { + $i++; + } + + if ($tokens[$i + 1] instanceof PHP_Token_OPEN_BRACKET) { + $this->name = (string) $tokens[$i]; + } elseif ($tokens[$i + 1] instanceof PHP_Token_WHITESPACE && $tokens[$i + 2] instanceof PHP_Token_OPEN_BRACKET) { + $this->name = (string) $tokens[$i]; + } else { + $this->anonymous = true; + + $this->name = sprintf( + 'anonymousFunction:%s#%s', + $this->getLine(), + $this->getId() + ); + } + + if (!$this->isAnonymous()) { + for ($i = $this->id; $i; --$i) { + if ($tokens[$i] instanceof PHP_Token_NAMESPACE) { + $this->name = $tokens[$i]->getName() . '\\' . $this->name; + + break; + } + + if ($tokens[$i] instanceof PHP_Token_INTERFACE) { + break; + } + } + } + + return $this->name; + } + + /** + * @return int + */ + public function getCCN() + { + if ($this->ccn !== null) { + return $this->ccn; + } + + $this->ccn = 1; + $end = $this->getEndTokenId(); + $tokens = $this->tokenStream->tokens(); + + for ($i = $this->id; $i <= $end; $i++) { + switch (PHP_Token_Util::getClass($tokens[$i])) { + case 'PHP_Token_IF': + case 'PHP_Token_ELSEIF': + case 'PHP_Token_FOR': + case 'PHP_Token_FOREACH': + case 'PHP_Token_WHILE': + case 'PHP_Token_CASE': + case 'PHP_Token_CATCH': + case 'PHP_Token_BOOLEAN_AND': + case 'PHP_Token_LOGICAL_AND': + case 'PHP_Token_BOOLEAN_OR': + case 'PHP_Token_LOGICAL_OR': + case 'PHP_Token_QUESTION_MARK': + $this->ccn++; + break; + } + } + + return $this->ccn; + } + + /** + * @return string + */ + public function getSignature() + { + if ($this->signature !== null) { + return $this->signature; + } + + if ($this->isAnonymous()) { + $this->signature = 'anonymousFunction'; + $i = $this->id + 1; + } else { + $this->signature = ''; + $i = $this->id + 2; + } + + $tokens = $this->tokenStream->tokens(); + + while (isset($tokens[$i]) && + !$tokens[$i] instanceof PHP_Token_OPEN_CURLY && + !$tokens[$i] instanceof PHP_Token_SEMICOLON) { + $this->signature .= $tokens[$i++]; + } + + $this->signature = trim($this->signature); + + return $this->signature; + } + + /** + * @return bool + */ + public function isAnonymous() + { + return $this->anonymous; + } +} + +class PHP_Token_INTERFACE extends PHP_TokenWithScopeAndVisibility +{ + /** + * @var array + */ + protected $interfaces; + + /** + * @return string + */ + public function getName() + { + return (string) $this->tokenStream[$this->id + 2]; + } + + /** + * @return bool + */ + public function hasParent() + { + return $this->tokenStream[$this->id + 4] instanceof PHP_Token_EXTENDS; + } + + /** + * @return array + */ + public function getPackage() + { + $className = $this->getName(); + $docComment = $this->getDocblock(); + + $result = [ + 'namespace' => '', + 'fullPackage' => '', + 'category' => '', + 'package' => '', + 'subpackage' => '' + ]; + + for ($i = $this->id; $i; --$i) { + if ($this->tokenStream[$i] instanceof PHP_Token_NAMESPACE) { + $result['namespace'] = $this->tokenStream[$i]->getName(); + break; + } + } + + if (preg_match('/@category[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['category'] = $matches[1]; + } + + if (preg_match('/@package[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['package'] = $matches[1]; + $result['fullPackage'] = $matches[1]; + } + + if (preg_match('/@subpackage[\s]+([\.\w]+)/', $docComment, $matches)) { + $result['subpackage'] = $matches[1]; + $result['fullPackage'] .= '.' . $matches[1]; + } + + if (empty($result['fullPackage'])) { + $result['fullPackage'] = $this->arrayToName( + explode('_', str_replace('\\', '_', $className)), + '.' + ); + } + + return $result; + } + + /** + * @param array $parts + * @param string $join + * + * @return string + */ + protected function arrayToName(array $parts, $join = '\\') + { + $result = ''; + + if (count($parts) > 1) { + array_pop($parts); + + $result = implode($join, $parts); + } + + return $result; + } + + /** + * @return bool|string + */ + public function getParent() + { + if (!$this->hasParent()) { + return false; + } + + $i = $this->id + 6; + $tokens = $this->tokenStream->tokens(); + $className = (string) $tokens[$i]; + + while (isset($tokens[$i + 1]) && + !$tokens[$i + 1] instanceof PHP_Token_WHITESPACE) { + $className .= (string) $tokens[++$i]; + } + + return $className; + } + + /** + * @return bool + */ + public function hasInterfaces() + { + return (isset($this->tokenStream[$this->id + 4]) && + $this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) || + (isset($this->tokenStream[$this->id + 8]) && + $this->tokenStream[$this->id + 8] instanceof PHP_Token_IMPLEMENTS); + } + + /** + * @return array|bool + */ + public function getInterfaces() + { + if ($this->interfaces !== null) { + return $this->interfaces; + } + + if (!$this->hasInterfaces()) { + return ($this->interfaces = false); + } + + if ($this->tokenStream[$this->id + 4] instanceof PHP_Token_IMPLEMENTS) { + $i = $this->id + 3; + } else { + $i = $this->id + 7; + } + + $tokens = $this->tokenStream->tokens(); + + while (!$tokens[$i + 1] instanceof PHP_Token_OPEN_CURLY) { + $i++; + + if ($tokens[$i] instanceof PHP_Token_STRING) { + $this->interfaces[] = (string) $tokens[$i]; + } + } + + return $this->interfaces; + } +} + +class PHP_Token_ABSTRACT extends PHP_Token +{ +} + +class PHP_Token_AMPERSAND extends PHP_Token +{ +} + +class PHP_Token_AND_EQUAL extends PHP_Token +{ +} + +class PHP_Token_ARRAY extends PHP_Token +{ +} + +class PHP_Token_ARRAY_CAST extends PHP_Token +{ +} + +class PHP_Token_AS extends PHP_Token +{ +} + +class PHP_Token_AT extends PHP_Token +{ +} + +class PHP_Token_BACKTICK extends PHP_Token +{ +} + +class PHP_Token_BAD_CHARACTER extends PHP_Token +{ +} + +class PHP_Token_BOOLEAN_AND extends PHP_Token +{ +} + +class PHP_Token_BOOLEAN_OR extends PHP_Token +{ +} + +class PHP_Token_BOOL_CAST extends PHP_Token +{ +} + +class PHP_Token_BREAK extends PHP_Token +{ +} + +class PHP_Token_CARET extends PHP_Token +{ +} + +class PHP_Token_CASE extends PHP_Token +{ +} + +class PHP_Token_CATCH extends PHP_Token +{ +} + +class PHP_Token_CHARACTER extends PHP_Token +{ +} + +class PHP_Token_CLASS extends PHP_Token_INTERFACE +{ + /** + * @var bool + */ + private $anonymous = false; + + /** + * @var string + */ + private $name; + + /** + * @return string + */ + public function getName() + { + if ($this->name !== null) { + return $this->name; + } + + $next = $this->tokenStream[$this->id + 1]; + + if ($next instanceof PHP_Token_WHITESPACE) { + $next = $this->tokenStream[$this->id + 2]; + } + + if ($next instanceof PHP_Token_STRING) { + $this->name =(string) $next; + + return $this->name; + } + + if ($next instanceof PHP_Token_OPEN_CURLY || + $next instanceof PHP_Token_EXTENDS || + $next instanceof PHP_Token_IMPLEMENTS) { + + $this->name = sprintf( + 'AnonymousClass:%s#%s', + $this->getLine(), + $this->getId() + ); + + $this->anonymous = true; + + return $this->name; + } + } + + public function isAnonymous() + { + return $this->anonymous; + } +} + +class PHP_Token_CLASS_C extends PHP_Token +{ +} + +class PHP_Token_CLASS_NAME_CONSTANT extends PHP_Token +{ +} + +class PHP_Token_CLONE extends PHP_Token +{ +} + +class PHP_Token_CLOSE_BRACKET extends PHP_Token +{ +} + +class PHP_Token_CLOSE_CURLY extends PHP_Token +{ +} + +class PHP_Token_CLOSE_SQUARE extends PHP_Token +{ +} + +class PHP_Token_CLOSE_TAG extends PHP_Token +{ +} + +class PHP_Token_COLON extends PHP_Token +{ +} + +class PHP_Token_COMMA extends PHP_Token +{ +} + +class PHP_Token_COMMENT extends PHP_Token +{ +} + +class PHP_Token_CONCAT_EQUAL extends PHP_Token +{ +} + +class PHP_Token_CONST extends PHP_Token +{ +} + +class PHP_Token_CONSTANT_ENCAPSED_STRING extends PHP_Token +{ +} + +class PHP_Token_CONTINUE extends PHP_Token +{ +} + +class PHP_Token_CURLY_OPEN extends PHP_Token +{ +} + +class PHP_Token_DEC extends PHP_Token +{ +} + +class PHP_Token_DECLARE extends PHP_Token +{ +} + +class PHP_Token_DEFAULT extends PHP_Token +{ +} + +class PHP_Token_DIV extends PHP_Token +{ +} + +class PHP_Token_DIV_EQUAL extends PHP_Token +{ +} + +class PHP_Token_DNUMBER extends PHP_Token +{ +} + +class PHP_Token_DO extends PHP_Token +{ +} + +class PHP_Token_DOC_COMMENT extends PHP_Token +{ +} + +class PHP_Token_DOLLAR extends PHP_Token +{ +} + +class PHP_Token_DOLLAR_OPEN_CURLY_BRACES extends PHP_Token +{ +} + +class PHP_Token_DOT extends PHP_Token +{ +} + +class PHP_Token_DOUBLE_ARROW extends PHP_Token +{ +} + +class PHP_Token_DOUBLE_CAST extends PHP_Token +{ +} + +class PHP_Token_DOUBLE_COLON extends PHP_Token +{ +} + +class PHP_Token_DOUBLE_QUOTES extends PHP_Token +{ +} + +class PHP_Token_ECHO extends PHP_Token +{ +} + +class PHP_Token_ELSE extends PHP_Token +{ +} + +class PHP_Token_ELSEIF extends PHP_Token +{ +} + +class PHP_Token_EMPTY extends PHP_Token +{ +} + +class PHP_Token_ENCAPSED_AND_WHITESPACE extends PHP_Token +{ +} + +class PHP_Token_ENDDECLARE extends PHP_Token +{ +} + +class PHP_Token_ENDFOR extends PHP_Token +{ +} + +class PHP_Token_ENDFOREACH extends PHP_Token +{ +} + +class PHP_Token_ENDIF extends PHP_Token +{ +} + +class PHP_Token_ENDSWITCH extends PHP_Token +{ +} + +class PHP_Token_ENDWHILE extends PHP_Token +{ +} + +class PHP_Token_END_HEREDOC extends PHP_Token +{ +} + +class PHP_Token_EQUAL extends PHP_Token +{ +} + +class PHP_Token_EVAL extends PHP_Token +{ +} + +class PHP_Token_EXCLAMATION_MARK extends PHP_Token +{ +} + +class PHP_Token_EXIT extends PHP_Token +{ +} + +class PHP_Token_EXTENDS extends PHP_Token +{ +} + +class PHP_Token_FILE extends PHP_Token +{ +} + +class PHP_Token_FINAL extends PHP_Token +{ +} + +class PHP_Token_FOR extends PHP_Token +{ +} + +class PHP_Token_FOREACH extends PHP_Token +{ +} + +class PHP_Token_FUNC_C extends PHP_Token +{ +} + +class PHP_Token_GLOBAL extends PHP_Token +{ +} + +class PHP_Token_GT extends PHP_Token +{ +} + +class PHP_Token_IF extends PHP_Token +{ +} + +class PHP_Token_IMPLEMENTS extends PHP_Token +{ +} + +class PHP_Token_INC extends PHP_Token +{ +} + +class PHP_Token_INCLUDE extends PHP_Token_Includes +{ +} + +class PHP_Token_INCLUDE_ONCE extends PHP_Token_Includes +{ +} + +class PHP_Token_INLINE_HTML extends PHP_Token +{ +} + +class PHP_Token_INSTANCEOF extends PHP_Token +{ +} + +class PHP_Token_INT_CAST extends PHP_Token +{ +} + +class PHP_Token_ISSET extends PHP_Token +{ +} + +class PHP_Token_IS_EQUAL extends PHP_Token +{ +} + +class PHP_Token_IS_GREATER_OR_EQUAL extends PHP_Token +{ +} + +class PHP_Token_IS_IDENTICAL extends PHP_Token +{ +} + +class PHP_Token_IS_NOT_EQUAL extends PHP_Token +{ +} + +class PHP_Token_IS_NOT_IDENTICAL extends PHP_Token +{ +} + +class PHP_Token_IS_SMALLER_OR_EQUAL extends PHP_Token +{ +} + +class PHP_Token_LINE extends PHP_Token +{ +} + +class PHP_Token_LIST extends PHP_Token +{ +} + +class PHP_Token_LNUMBER extends PHP_Token +{ +} + +class PHP_Token_LOGICAL_AND extends PHP_Token +{ +} + +class PHP_Token_LOGICAL_OR extends PHP_Token +{ +} + +class PHP_Token_LOGICAL_XOR extends PHP_Token +{ +} + +class PHP_Token_LT extends PHP_Token +{ +} + +class PHP_Token_METHOD_C extends PHP_Token +{ +} + +class PHP_Token_MINUS extends PHP_Token +{ +} + +class PHP_Token_MINUS_EQUAL extends PHP_Token +{ +} + +class PHP_Token_MOD_EQUAL extends PHP_Token +{ +} + +class PHP_Token_MULT extends PHP_Token +{ +} + +class PHP_Token_MUL_EQUAL extends PHP_Token +{ +} + +class PHP_Token_NEW extends PHP_Token +{ +} + +class PHP_Token_NUM_STRING extends PHP_Token +{ +} + +class PHP_Token_OBJECT_CAST extends PHP_Token +{ +} + +class PHP_Token_OBJECT_OPERATOR extends PHP_Token +{ +} + +class PHP_Token_OPEN_BRACKET extends PHP_Token +{ +} + +class PHP_Token_OPEN_CURLY extends PHP_Token +{ +} + +class PHP_Token_OPEN_SQUARE extends PHP_Token +{ +} + +class PHP_Token_OPEN_TAG extends PHP_Token +{ +} + +class PHP_Token_OPEN_TAG_WITH_ECHO extends PHP_Token +{ +} + +class PHP_Token_OR_EQUAL extends PHP_Token +{ +} + +class PHP_Token_PAAMAYIM_NEKUDOTAYIM extends PHP_Token +{ +} + +class PHP_Token_PERCENT extends PHP_Token +{ +} + +class PHP_Token_PIPE extends PHP_Token +{ +} + +class PHP_Token_PLUS extends PHP_Token +{ +} + +class PHP_Token_PLUS_EQUAL extends PHP_Token +{ +} + +class PHP_Token_PRINT extends PHP_Token +{ +} + +class PHP_Token_PRIVATE extends PHP_Token +{ +} + +class PHP_Token_PROTECTED extends PHP_Token +{ +} + +class PHP_Token_PUBLIC extends PHP_Token +{ +} + +class PHP_Token_QUESTION_MARK extends PHP_Token +{ +} + +class PHP_Token_REQUIRE extends PHP_Token_Includes +{ +} + +class PHP_Token_REQUIRE_ONCE extends PHP_Token_Includes +{ +} + +class PHP_Token_RETURN extends PHP_Token +{ +} + +class PHP_Token_SEMICOLON extends PHP_Token +{ +} + +class PHP_Token_SL extends PHP_Token +{ +} + +class PHP_Token_SL_EQUAL extends PHP_Token +{ +} + +class PHP_Token_SR extends PHP_Token +{ +} + +class PHP_Token_SR_EQUAL extends PHP_Token +{ +} + +class PHP_Token_START_HEREDOC extends PHP_Token +{ +} + +class PHP_Token_STATIC extends PHP_Token +{ +} + +class PHP_Token_STRING extends PHP_Token +{ +} + +class PHP_Token_STRING_CAST extends PHP_Token +{ +} + +class PHP_Token_STRING_VARNAME extends PHP_Token +{ +} + +class PHP_Token_SWITCH extends PHP_Token +{ +} + +class PHP_Token_THROW extends PHP_Token +{ +} + +class PHP_Token_TILDE extends PHP_Token +{ +} + +class PHP_Token_TRY extends PHP_Token +{ +} + +class PHP_Token_UNSET extends PHP_Token +{ +} + +class PHP_Token_UNSET_CAST extends PHP_Token +{ +} + +class PHP_Token_USE extends PHP_Token +{ +} + +class PHP_Token_USE_FUNCTION extends PHP_Token +{ +} + +class PHP_Token_VAR extends PHP_Token +{ +} + +class PHP_Token_VARIABLE extends PHP_Token +{ +} + +class PHP_Token_WHILE extends PHP_Token +{ +} + +class PHP_Token_WHITESPACE extends PHP_Token +{ +} + +class PHP_Token_XOR_EQUAL extends PHP_Token +{ +} + +// Tokens introduced in PHP 5.1 +class PHP_Token_HALT_COMPILER extends PHP_Token +{ +} + +// Tokens introduced in PHP 5.3 +class PHP_Token_DIR extends PHP_Token +{ +} + +class PHP_Token_GOTO extends PHP_Token +{ +} + +class PHP_Token_NAMESPACE extends PHP_TokenWithScope +{ + /** + * @return string + */ + public function getName() + { + $tokens = $this->tokenStream->tokens(); + $namespace = (string) $tokens[$this->id + 2]; + + for ($i = $this->id + 3;; $i += 2) { + if (isset($tokens[$i]) && + $tokens[$i] instanceof PHP_Token_NS_SEPARATOR) { + $namespace .= '\\' . $tokens[$i + 1]; + } else { + break; + } + } + + return $namespace; + } +} + +class PHP_Token_NS_C extends PHP_Token +{ +} + +class PHP_Token_NS_SEPARATOR extends PHP_Token +{ +} + +// Tokens introduced in PHP 5.4 +class PHP_Token_CALLABLE extends PHP_Token +{ +} + +class PHP_Token_INSTEADOF extends PHP_Token +{ +} + +class PHP_Token_TRAIT extends PHP_Token_INTERFACE +{ +} + +class PHP_Token_TRAIT_C extends PHP_Token +{ +} + +// Tokens introduced in PHP 5.5 +class PHP_Token_FINALLY extends PHP_Token +{ +} + +class PHP_Token_YIELD extends PHP_Token +{ +} + +// Tokens introduced in PHP 5.6 +class PHP_Token_ELLIPSIS extends PHP_Token +{ +} + +class PHP_Token_POW extends PHP_Token +{ +} + +class PHP_Token_POW_EQUAL extends PHP_Token +{ +} + +// Tokens introduced in PHP 7.0 +class PHP_Token_COALESCE extends PHP_Token +{ +} + +class PHP_Token_SPACESHIP extends PHP_Token +{ +} + +class PHP_Token_YIELD_FROM extends PHP_Token +{ +} + +// Tokens introduced in PHP 7.4 +class PHP_Token_COALESCE_EQUAL extends PHP_Token +{ +} + +class PHP_Token_FN extends PHP_Token +{ +} diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream.php b/vendor/phpunit/php-token-stream/src/Token/Stream.php new file mode 100644 index 0000000..40549b9 --- /dev/null +++ b/vendor/phpunit/php-token-stream/src/Token/Stream.php @@ -0,0 +1,609 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A stream of PHP tokens. + */ +class PHP_Token_Stream implements ArrayAccess, Countable, SeekableIterator +{ + /** + * @var array + */ + protected static $customTokens = [ + '(' => 'PHP_Token_OPEN_BRACKET', + ')' => 'PHP_Token_CLOSE_BRACKET', + '[' => 'PHP_Token_OPEN_SQUARE', + ']' => 'PHP_Token_CLOSE_SQUARE', + '{' => 'PHP_Token_OPEN_CURLY', + '}' => 'PHP_Token_CLOSE_CURLY', + ';' => 'PHP_Token_SEMICOLON', + '.' => 'PHP_Token_DOT', + ',' => 'PHP_Token_COMMA', + '=' => 'PHP_Token_EQUAL', + '<' => 'PHP_Token_LT', + '>' => 'PHP_Token_GT', + '+' => 'PHP_Token_PLUS', + '-' => 'PHP_Token_MINUS', + '*' => 'PHP_Token_MULT', + '/' => 'PHP_Token_DIV', + '?' => 'PHP_Token_QUESTION_MARK', + '!' => 'PHP_Token_EXCLAMATION_MARK', + ':' => 'PHP_Token_COLON', + '"' => 'PHP_Token_DOUBLE_QUOTES', + '@' => 'PHP_Token_AT', + '&' => 'PHP_Token_AMPERSAND', + '%' => 'PHP_Token_PERCENT', + '|' => 'PHP_Token_PIPE', + '$' => 'PHP_Token_DOLLAR', + '^' => 'PHP_Token_CARET', + '~' => 'PHP_Token_TILDE', + '`' => 'PHP_Token_BACKTICK' + ]; + + /** + * @var string + */ + protected $filename; + + /** + * @var array + */ + protected $tokens = []; + + /** + * @var int + */ + protected $position = 0; + + /** + * @var array + */ + protected $linesOfCode = ['loc' => 0, 'cloc' => 0, 'ncloc' => 0]; + + /** + * @var array + */ + protected $classes; + + /** + * @var array + */ + protected $functions; + + /** + * @var array + */ + protected $includes; + + /** + * @var array + */ + protected $interfaces; + + /** + * @var array + */ + protected $traits; + + /** + * @var array + */ + protected $lineToFunctionMap = []; + + /** + * Constructor. + * + * @param string $sourceCode + */ + public function __construct($sourceCode) + { + if (is_file($sourceCode)) { + $this->filename = $sourceCode; + $sourceCode = file_get_contents($sourceCode); + } + + $this->scan($sourceCode); + } + + /** + * Destructor. + */ + public function __destruct() + { + $this->tokens = []; + } + + /** + * @return string + */ + public function __toString() + { + $buffer = ''; + + foreach ($this as $token) { + $buffer .= $token; + } + + return $buffer; + } + + /** + * @return string + */ + public function getFilename() + { + return $this->filename; + } + + /** + * Scans the source for sequences of characters and converts them into a + * stream of tokens. + * + * @param string $sourceCode + */ + protected function scan($sourceCode) + { + $id = 0; + $line = 1; + $tokens = token_get_all($sourceCode); + $numTokens = count($tokens); + + $lastNonWhitespaceTokenWasDoubleColon = false; + + for ($i = 0; $i < $numTokens; ++$i) { + $token = $tokens[$i]; + $skip = 0; + + if (is_array($token)) { + $name = substr(token_name($token[0]), 2); + $text = $token[1]; + + if ($lastNonWhitespaceTokenWasDoubleColon && $name == 'CLASS') { + $name = 'CLASS_NAME_CONSTANT'; + } elseif ($name == 'USE' && isset($tokens[$i + 2][0]) && $tokens[$i + 2][0] == T_FUNCTION) { + $name = 'USE_FUNCTION'; + $text .= $tokens[$i + 1][1] . $tokens[$i + 2][1]; + $skip = 2; + } + + $tokenClass = 'PHP_Token_' . $name; + } else { + $text = $token; + $tokenClass = self::$customTokens[$token]; + } + + $this->tokens[] = new $tokenClass($text, $line, $this, $id++); + $lines = substr_count($text, "\n"); + $line += $lines; + + if ($tokenClass == 'PHP_Token_HALT_COMPILER') { + break; + } elseif ($tokenClass == 'PHP_Token_COMMENT' || + $tokenClass == 'PHP_Token_DOC_COMMENT') { + $this->linesOfCode['cloc'] += $lines + 1; + } + + if ($name == 'DOUBLE_COLON') { + $lastNonWhitespaceTokenWasDoubleColon = true; + } elseif ($name != 'WHITESPACE') { + $lastNonWhitespaceTokenWasDoubleColon = false; + } + + $i += $skip; + } + + $this->linesOfCode['loc'] = substr_count($sourceCode, "\n"); + $this->linesOfCode['ncloc'] = $this->linesOfCode['loc'] - + $this->linesOfCode['cloc']; + } + + /** + * @return int + */ + public function count() + { + return count($this->tokens); + } + + /** + * @return PHP_Token[] + */ + public function tokens() + { + return $this->tokens; + } + + /** + * @return array + */ + public function getClasses() + { + if ($this->classes !== null) { + return $this->classes; + } + + $this->parse(); + + return $this->classes; + } + + /** + * @return array + */ + public function getFunctions() + { + if ($this->functions !== null) { + return $this->functions; + } + + $this->parse(); + + return $this->functions; + } + + /** + * @return array + */ + public function getInterfaces() + { + if ($this->interfaces !== null) { + return $this->interfaces; + } + + $this->parse(); + + return $this->interfaces; + } + + /** + * @return array + */ + public function getTraits() + { + if ($this->traits !== null) { + return $this->traits; + } + + $this->parse(); + + return $this->traits; + } + + /** + * Gets the names of all files that have been included + * using include(), include_once(), require() or require_once(). + * + * Parameter $categorize set to TRUE causing this function to return a + * multi-dimensional array with categories in the keys of the first dimension + * and constants and their values in the second dimension. + * + * Parameter $category allow to filter following specific inclusion type + * + * @param bool $categorize OPTIONAL + * @param string $category OPTIONAL Either 'require_once', 'require', + * 'include_once', 'include'. + * + * @return array + */ + public function getIncludes($categorize = false, $category = null) + { + if ($this->includes === null) { + $this->includes = [ + 'require_once' => [], + 'require' => [], + 'include_once' => [], + 'include' => [] + ]; + + foreach ($this->tokens as $token) { + switch (PHP_Token_Util::getClass($token)) { + case 'PHP_Token_REQUIRE_ONCE': + case 'PHP_Token_REQUIRE': + case 'PHP_Token_INCLUDE_ONCE': + case 'PHP_Token_INCLUDE': + $this->includes[$token->getType()][] = $token->getName(); + break; + } + } + } + + if (isset($this->includes[$category])) { + $includes = $this->includes[$category]; + } elseif ($categorize === false) { + $includes = array_merge( + $this->includes['require_once'], + $this->includes['require'], + $this->includes['include_once'], + $this->includes['include'] + ); + } else { + $includes = $this->includes; + } + + return $includes; + } + + /** + * Returns the name of the function or method a line belongs to. + * + * @return string or null if the line is not in a function or method + */ + public function getFunctionForLine($line) + { + $this->parse(); + + if (isset($this->lineToFunctionMap[$line])) { + return $this->lineToFunctionMap[$line]; + } + } + + protected function parse() + { + $this->interfaces = []; + $this->classes = []; + $this->traits = []; + $this->functions = []; + $class = []; + $classEndLine = []; + $trait = false; + $traitEndLine = false; + $interface = false; + $interfaceEndLine = false; + + foreach ($this->tokens as $token) { + switch (PHP_Token_Util::getClass($token)) { + case 'PHP_Token_HALT_COMPILER': + return; + + case 'PHP_Token_INTERFACE': + $interface = $token->getName(); + $interfaceEndLine = $token->getEndLine(); + + $this->interfaces[$interface] = [ + 'methods' => [], + 'parent' => $token->getParent(), + 'keywords' => $token->getKeywords(), + 'docblock' => $token->getDocblock(), + 'startLine' => $token->getLine(), + 'endLine' => $interfaceEndLine, + 'package' => $token->getPackage(), + 'file' => $this->filename + ]; + break; + + case 'PHP_Token_CLASS': + case 'PHP_Token_TRAIT': + $tmp = [ + 'methods' => [], + 'parent' => $token->getParent(), + 'interfaces'=> $token->getInterfaces(), + 'keywords' => $token->getKeywords(), + 'docblock' => $token->getDocblock(), + 'startLine' => $token->getLine(), + 'endLine' => $token->getEndLine(), + 'package' => $token->getPackage(), + 'file' => $this->filename + ]; + + if ($token->getName() !== null) { + if ($token instanceof PHP_Token_CLASS) { + $class[] = $token->getName(); + $classEndLine[] = $token->getEndLine(); + + $this->classes[$class[count($class) - 1]] = $tmp; + } else { + $trait = $token->getName(); + $traitEndLine = $token->getEndLine(); + $this->traits[$trait] = $tmp; + } + } + break; + + case 'PHP_Token_FUNCTION': + $name = $token->getName(); + $tmp = [ + 'docblock' => $token->getDocblock(), + 'keywords' => $token->getKeywords(), + 'visibility'=> $token->getVisibility(), + 'signature' => $token->getSignature(), + 'startLine' => $token->getLine(), + 'endLine' => $token->getEndLine(), + 'ccn' => $token->getCCN(), + 'file' => $this->filename + ]; + + if (empty($class) && + $trait === false && + $interface === false) { + $this->functions[$name] = $tmp; + + $this->addFunctionToMap( + $name, + $tmp['startLine'], + $tmp['endLine'] + ); + } elseif (!empty($class)) { + $this->classes[$class[count($class) - 1]]['methods'][$name] = $tmp; + + $this->addFunctionToMap( + $class[count($class) - 1] . '::' . $name, + $tmp['startLine'], + $tmp['endLine'] + ); + } elseif ($trait !== false) { + $this->traits[$trait]['methods'][$name] = $tmp; + + $this->addFunctionToMap( + $trait . '::' . $name, + $tmp['startLine'], + $tmp['endLine'] + ); + } else { + $this->interfaces[$interface]['methods'][$name] = $tmp; + } + break; + + case 'PHP_Token_CLOSE_CURLY': + if (!empty($classEndLine) && + $classEndLine[count($classEndLine) - 1] == $token->getLine()) { + array_pop($classEndLine); + array_pop($class); + } elseif ($traitEndLine !== false && + $traitEndLine == $token->getLine()) { + $trait = false; + $traitEndLine = false; + } elseif ($interfaceEndLine !== false && + $interfaceEndLine == $token->getLine()) { + $interface = false; + $interfaceEndLine = false; + } + break; + } + } + } + + /** + * @return array + */ + public function getLinesOfCode() + { + return $this->linesOfCode; + } + + /** + */ + public function rewind() + { + $this->position = 0; + } + + /** + * @return bool + */ + public function valid() + { + return isset($this->tokens[$this->position]); + } + + /** + * @return int + */ + public function key() + { + return $this->position; + } + + /** + * @return PHP_Token + */ + public function current() + { + return $this->tokens[$this->position]; + } + + /** + */ + public function next() + { + $this->position++; + } + + /** + * @param int $offset + * + * @return bool + */ + public function offsetExists($offset) + { + return isset($this->tokens[$offset]); + } + + /** + * @param int $offset + * + * @return mixed + * + * @throws OutOfBoundsException + */ + public function offsetGet($offset) + { + if (!$this->offsetExists($offset)) { + throw new OutOfBoundsException( + sprintf( + 'No token at position "%s"', + $offset + ) + ); + } + + return $this->tokens[$offset]; + } + + /** + * @param int $offset + * @param mixed $value + */ + public function offsetSet($offset, $value) + { + $this->tokens[$offset] = $value; + } + + /** + * @param int $offset + * + * @throws OutOfBoundsException + */ + public function offsetUnset($offset) + { + if (!$this->offsetExists($offset)) { + throw new OutOfBoundsException( + sprintf( + 'No token at position "%s"', + $offset + ) + ); + } + + unset($this->tokens[$offset]); + } + + /** + * Seek to an absolute position. + * + * @param int $position + * + * @throws OutOfBoundsException + */ + public function seek($position) + { + $this->position = $position; + + if (!$this->valid()) { + throw new OutOfBoundsException( + sprintf( + 'No token at position "%s"', + $this->position + ) + ); + } + } + + /** + * @param string $name + * @param int $startLine + * @param int $endLine + */ + private function addFunctionToMap($name, $startLine, $endLine) + { + for ($line = $startLine; $line <= $endLine; $line++) { + $this->lineToFunctionMap[$line] = $name; + } + } +} diff --git a/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php b/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php new file mode 100644 index 0000000..9d69393 --- /dev/null +++ b/vendor/phpunit/php-token-stream/src/Token/Stream/CachingFactory.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +/** + * A caching factory for token stream objects. + */ +class PHP_Token_Stream_CachingFactory +{ + /** + * @var array + */ + protected static $cache = []; + + /** + * @param string $filename + * + * @return PHP_Token_Stream + */ + public static function get($filename) + { + if (!isset(self::$cache[$filename])) { + self::$cache[$filename] = new PHP_Token_Stream($filename); + } + + return self::$cache[$filename]; + } + + /** + * @param string $filename + */ + public static function clear($filename = null) + { + if (is_string($filename)) { + unset(self::$cache[$filename]); + } else { + self::$cache = []; + } + } +} diff --git a/vendor/phpunit/php-token-stream/src/Token/Util.php b/vendor/phpunit/php-token-stream/src/Token/Util.php new file mode 100644 index 0000000..4d82f1a --- /dev/null +++ b/vendor/phpunit/php-token-stream/src/Token/Util.php @@ -0,0 +1,19 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +final class PHP_Token_Util +{ + public static function getClass($object): string + { + $parts = explode('\\', get_class($object)); + + return array_pop($parts); + } +} \ No newline at end of file diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php new file mode 100644 index 0000000..05eca32 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/ClassTest.php @@ -0,0 +1,152 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_ClassTest extends TestCase +{ + /** + * @var PHP_Token_CLASS + */ + private $class; + + /** + * @var PHP_Token_FUNCTION + */ + private $function; + + protected function setUp() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source2.php') as $token) { + if ($token instanceof PHP_Token_CLASS) { + $this->class = $token; + } + + if ($token instanceof PHP_Token_FUNCTION) { + $this->function = $token; + break; + } + } + } + + public function testGetClassKeywords() + { + $this->assertEquals('abstract', $this->class->getKeywords()); + } + + public function testGetFunctionKeywords() + { + $this->assertEquals('abstract,static', $this->function->getKeywords()); + } + + public function testGetFunctionVisibility() + { + $this->assertEquals('public', $this->function->getVisibility()); + } + + public function testIssue19() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'issue19.php') as $token) { + if ($token instanceof PHP_Token_CLASS) { + $this->assertFalse($token->hasInterfaces()); + } + } + } + + public function testIssue30() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'issue30.php'); + $this->assertCount(1, $ts->getClasses()); + } + + public function testAnonymousClassesAreHandledCorrectly() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class.php'); + + $classes = $ts->getClasses(); + + $this->assertEquals( + [ + 'class_with_method_that_declares_anonymous_class', + 'AnonymousClass:9#31', + 'AnonymousClass:10#55', + 'AnonymousClass:11#75', + 'AnonymousClass:12#91', + 'AnonymousClass:13#107' + ], + array_keys($classes) + ); + } + + /** + * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/52 + */ + public function testAnonymousClassesAreHandledCorrectly2() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_that_declares_anonymous_class2.php'); + + $classes = $ts->getClasses(); + + $this->assertEquals(['Test', 'AnonymousClass:4#23'], array_keys($classes)); + $this->assertEquals(['methodOne', 'methodTwo'], array_keys($classes['Test']['methods'])); + + $this->assertEmpty($ts->getFunctions()); + } + + public function testImportedFunctionsAreHandledCorrectly() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'classUsesNamespacedFunction.php'); + + $this->assertEmpty($ts->getFunctions()); + $this->assertCount(1, $ts->getClasses()); + } + + /** + * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/543 + */ + public function testClassWithMultipleAnonymousClassesAndFunctionsIsHandledCorrectly() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_multiple_anonymous_classes_and_functions.php'); + + $classes = $ts->getClasses(); + + $this->assertArrayHasKey('class_with_multiple_anonymous_classes_and_functions', $classes); + $this->assertArrayHasKey('AnonymousClass:6#23', $classes); + $this->assertArrayHasKey('AnonymousClass:12#53', $classes); + $this->assertArrayHasKey('m', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']); + $this->assertArrayHasKey('anonymousFunction:18#81', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']); + $this->assertArrayHasKey('anonymousFunction:22#108', $classes['class_with_multiple_anonymous_classes_and_functions']['methods']); + } + + /** + * @ticket https://github.com/sebastianbergmann/php-token-stream/issues/68 + */ + public function testClassWithMethodNamedEmptyIsHandledCorrectly() + { + $classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'class_with_method_named_empty.php'))->getClasses(); + + $this->assertArrayHasKey('class_with_method_named_empty', $classes); + $this->assertArrayHasKey('empty', $classes['class_with_method_named_empty']['methods']); + } + + /** + * @ticket https://github.com/sebastianbergmann/php-code-coverage/issues/424 + */ + public function testAnonymousFunctionDoesNotAffectStartAndEndLineOfMethod() + { + $classes = (new PHP_Token_Stream(TEST_FILES_PATH . 'php-code-coverage-issue-424.php'))->getClasses(); + + $this->assertSame(5, $classes['Example']['methods']['even']['startLine']); + $this->assertSame(12, $classes['Example']['methods']['even']['endLine']); + + $this->assertSame(7, $classes['Example']['methods']['anonymousFunction:7#28']['startLine']); + $this->assertSame(9, $classes['Example']['methods']['anonymousFunction:7#28']['endLine']); + } +} diff --git a/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php b/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php new file mode 100644 index 0000000..4e893d8 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/ClosureTest.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_ClosureTest extends TestCase +{ + /** + * @var PHP_Token_FUNCTION[] + */ + private $functions; + + protected function setUp() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'closure.php') as $token) { + if ($token instanceof PHP_Token_FUNCTION) { + $this->functions[] = $token; + } + } + } + + public function testGetArguments() + { + $this->assertEquals(['$foo' => null, '$bar' => null], $this->functions[0]->getArguments()); + $this->assertEquals(['$foo' => 'Foo', '$bar' => null], $this->functions[1]->getArguments()); + $this->assertEquals(['$foo' => null, '$bar' => null, '$baz' => null], $this->functions[2]->getArguments()); + $this->assertEquals(['$foo' => 'Foo', '$bar' => null, '$baz' => null], $this->functions[3]->getArguments()); + $this->assertEquals([], $this->functions[4]->getArguments()); + $this->assertEquals([], $this->functions[5]->getArguments()); + } + + public function testGetName() + { + $this->assertEquals('anonymousFunction:2#5', $this->functions[0]->getName()); + $this->assertEquals('anonymousFunction:3#27', $this->functions[1]->getName()); + $this->assertEquals('anonymousFunction:4#51', $this->functions[2]->getName()); + $this->assertEquals('anonymousFunction:5#71', $this->functions[3]->getName()); + $this->assertEquals('anonymousFunction:6#93', $this->functions[4]->getName()); + $this->assertEquals('anonymousFunction:7#106', $this->functions[5]->getName()); + } + + public function testGetLine() + { + $this->assertEquals(2, $this->functions[0]->getLine()); + $this->assertEquals(3, $this->functions[1]->getLine()); + $this->assertEquals(4, $this->functions[2]->getLine()); + $this->assertEquals(5, $this->functions[3]->getLine()); + } + + public function testGetEndLine() + { + $this->assertEquals(2, $this->functions[0]->getLine()); + $this->assertEquals(3, $this->functions[1]->getLine()); + $this->assertEquals(4, $this->functions[2]->getLine()); + $this->assertEquals(5, $this->functions[3]->getLine()); + } +} diff --git a/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php b/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php new file mode 100644 index 0000000..c88454b --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/FunctionTest.php @@ -0,0 +1,124 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_FunctionTest extends TestCase +{ + /** + * @var PHP_Token_FUNCTION[] + */ + private $functions; + + protected function setUp() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'source.php') as $token) { + if ($token instanceof PHP_Token_FUNCTION) { + $this->functions[] = $token; + } + } + } + + public function testGetArguments() + { + $this->assertEquals([], $this->functions[0]->getArguments()); + + $this->assertEquals( + ['$baz' => 'Baz'], $this->functions[1]->getArguments() + ); + + $this->assertEquals( + ['$foobar' => 'Foobar'], $this->functions[2]->getArguments() + ); + + $this->assertEquals( + ['$barfoo' => 'Barfoo'], $this->functions[3]->getArguments() + ); + + $this->assertEquals([], $this->functions[4]->getArguments()); + + $this->assertEquals(['$x' => null, '$y' => null], $this->functions[5]->getArguments()); + } + + public function testGetName() + { + $this->assertEquals('foo', $this->functions[0]->getName()); + $this->assertEquals('bar', $this->functions[1]->getName()); + $this->assertEquals('foobar', $this->functions[2]->getName()); + $this->assertEquals('barfoo', $this->functions[3]->getName()); + $this->assertEquals('baz', $this->functions[4]->getName()); + } + + public function testGetLine() + { + $this->assertEquals(5, $this->functions[0]->getLine()); + $this->assertEquals(10, $this->functions[1]->getLine()); + $this->assertEquals(17, $this->functions[2]->getLine()); + $this->assertEquals(21, $this->functions[3]->getLine()); + $this->assertEquals(29, $this->functions[4]->getLine()); + $this->assertEquals(37, $this->functions[6]->getLine()); + } + + public function testGetEndLine() + { + $this->assertEquals(5, $this->functions[0]->getEndLine()); + $this->assertEquals(12, $this->functions[1]->getEndLine()); + $this->assertEquals(19, $this->functions[2]->getEndLine()); + $this->assertEquals(23, $this->functions[3]->getEndLine()); + $this->assertEquals(31, $this->functions[4]->getEndLine()); + $this->assertEquals(41, $this->functions[6]->getEndLine()); + } + + public function testGetDocblock() + { + $this->assertNull($this->functions[0]->getDocblock()); + + $this->assertEquals( + "/**\n * @param Baz \$baz\n */", + $this->functions[1]->getDocblock() + ); + + $this->assertEquals( + "/**\n * @param Foobar \$foobar\n */", + $this->functions[2]->getDocblock() + ); + + $this->assertNull($this->functions[3]->getDocblock()); + $this->assertNull($this->functions[4]->getDocblock()); + } + + public function testSignature() + { + $tokens = new PHP_Token_Stream(TEST_FILES_PATH . 'source5.php'); + $functions = $tokens->getFunctions(); + $classes = $tokens->getClasses(); + $interfaces = $tokens->getInterfaces(); + + $this->assertEquals( + 'foo($a, array $b, array $c = array())', + $functions['foo']['signature'] + ); + + $this->assertEquals( + 'm($a, array $b, array $c = array())', + $classes['c']['methods']['m']['signature'] + ); + + $this->assertEquals( + 'm($a, array $b, array $c = array())', + $classes['a']['methods']['m']['signature'] + ); + + $this->assertEquals( + 'm($a, array $b, array $c = array())', + $interfaces['i']['methods']['m']['signature'] + ); + } +} diff --git a/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php b/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php new file mode 100644 index 0000000..7f83a73 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/IncludeTest.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_IncludeTest extends TestCase +{ + /** + * @var PHP_Token_Stream + */ + private $ts; + + protected function setUp() + { + $this->ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source3.php'); + } + + public function testGetIncludes() + { + $this->assertSame( + ['test4.php', 'test3.php', 'test2.php', 'test1.php'], + $this->ts->getIncludes() + ); + } + + public function testGetIncludesCategorized() + { + $this->assertSame( + [ + 'require_once' => ['test4.php'], + 'require' => ['test3.php'], + 'include_once' => ['test2.php'], + 'include' => ['test1.php'] + ], + $this->ts->getIncludes(true) + ); + } + + public function testGetIncludesCategory() + { + $this->assertSame( + ['test4.php'], + $this->ts->getIncludes(true, 'require_once') + ); + } +} diff --git a/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php new file mode 100644 index 0000000..c61ec38 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/InterfaceTest.php @@ -0,0 +1,169 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_InterfaceTest extends TestCase +{ + /** + * @var PHP_Token_CLASS + */ + private $class; + + /** + * @var PHP_Token_INTERFACE[] + */ + private $interfaces; + + protected function setUp() + { + $ts = new PHP_Token_Stream(TEST_FILES_PATH . 'source4.php'); + $i = 0; + + foreach ($ts as $token) { + if ($token instanceof PHP_Token_CLASS) { + $this->class = $token; + } elseif ($token instanceof PHP_Token_INTERFACE) { + $this->interfaces[$i] = $token; + $i++; + } + } + } + + public function testGetName() + { + $this->assertEquals( + 'iTemplate', $this->interfaces[0]->getName() + ); + } + + public function testGetParentNotExists() + { + $this->assertFalse( + $this->interfaces[0]->getParent() + ); + } + + public function testHasParentNotExists() + { + $this->assertFalse( + $this->interfaces[0]->hasParent() + ); + } + + public function testGetParentExists() + { + $this->assertEquals( + 'a', $this->interfaces[2]->getParent() + ); + } + + public function testHasParentExists() + { + $this->assertTrue( + $this->interfaces[2]->hasParent() + ); + } + + public function testGetInterfacesExists() + { + $this->assertEquals( + ['b'], + $this->class->getInterfaces() + ); + } + + public function testHasInterfacesExists() + { + $this->assertTrue( + $this->class->hasInterfaces() + ); + } + + public function testGetPackageNamespace() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) { + if ($token instanceof PHP_Token_INTERFACE) { + $package = $token->getPackage(); + $this->assertSame('Foo\\Bar', $package['namespace']); + } + } + } + + public function provideFilesWithClassesWithinMultipleNamespaces() + { + return [ + [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingBraces.php'], + [TEST_FILES_PATH . 'multipleNamespacesWithOneClassUsingNonBraceSyntax.php'], + ]; + } + + /** + * @dataProvider provideFilesWithClassesWithinMultipleNamespaces + */ + public function testGetPackageNamespaceForFileWithMultipleNamespaces($filepath) + { + $tokenStream = new PHP_Token_Stream($filepath); + $firstClassFound = false; + + foreach ($tokenStream as $token) { + if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) { + $package = $token->getPackage(); + $this->assertSame('TestClassInBar', $token->getName()); + $this->assertSame('Foo\\Bar', $package['namespace']); + $firstClassFound = true; + continue; + } + // Secound class + if ($token instanceof PHP_Token_INTERFACE) { + $package = $token->getPackage(); + $this->assertSame('TestClassInBaz', $token->getName()); + $this->assertSame('Foo\\Baz', $package['namespace']); + + return; + } + } + $this->fail('Searching for 2 classes failed'); + } + + public function testGetPackageNamespaceIsEmptyForInterfacesThatAreNotWithinNamespaces() + { + foreach ($this->interfaces as $token) { + $package = $token->getPackage(); + $this->assertSame('', $package['namespace']); + } + } + + public function testGetPackageNamespaceWhenExtentingFromNamespaceClass() + { + $tokenStream = new PHP_Token_Stream(TEST_FILES_PATH . 'classExtendsNamespacedClass.php'); + $firstClassFound = false; + + foreach ($tokenStream as $token) { + if ($firstClassFound === false && $token instanceof PHP_Token_INTERFACE) { + $package = $token->getPackage(); + $this->assertSame('Baz', $token->getName()); + $this->assertSame('Foo\\Bar', $package['namespace']); + $firstClassFound = true; + continue; + } + + if ($token instanceof PHP_Token_INTERFACE) { + $package = $token->getPackage(); + $this->assertSame('Extender', $token->getName()); + $this->assertSame('Other\\Space', $package['namespace']); + + return; + } + } + + $this->fail('Searching for 2 classes failed'); + } +} diff --git a/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php b/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php new file mode 100644 index 0000000..97a9224 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/Token/NamespaceTest.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +use PHPUnit\Framework\TestCase; + +class PHP_Token_NamespaceTest extends TestCase +{ + public function testGetName() + { + $tokenStream = new PHP_Token_Stream( + TEST_FILES_PATH . 'classInNamespace.php' + ); + + foreach ($tokenStream as $token) { + if ($token instanceof PHP_Token_NAMESPACE) { + $this->assertSame('Foo\\Bar', $token->getName()); + } + } + } + + public function testGetStartLineWithUnscopedNamespace() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) { + if ($token instanceof PHP_Token_NAMESPACE) { + $this->assertSame(2, $token->getLine()); + } + } + } + + public function testGetEndLineWithUnscopedNamespace() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInNamespace.php') as $token) { + if ($token instanceof PHP_Token_NAMESPACE) { + $this->assertSame(2, $token->getEndLine()); + } + } + } + public function testGetStartLineWithScopedNamespace() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) { + if ($token instanceof PHP_Token_NAMESPACE) { + $this->assertSame(2, $token->getLine()); + } + } + } + + public function testGetEndLineWithScopedNamespace() + { + foreach (new PHP_Token_Stream(TEST_FILES_PATH . 'classInScopedNamespace.php') as $token) { + if ($token instanceof PHP_Token_NAMESPACE) { + $this->assertSame(8, $token->getEndLine()); + } + } + } +} diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php b/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php new file mode 100644 index 0000000..560eec9 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/_fixture/classExtendsNamespacedClass.php @@ -0,0 +1,10 @@ +method_in_anonymous_class(); + } + + public function methodTwo() { + return false; + } +} diff --git a/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php new file mode 100644 index 0000000..3267ba5 --- /dev/null +++ b/vendor/phpunit/php-token-stream/tests/_fixture/class_with_multiple_anonymous_classes_and_functions.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +require __DIR__ . '/../vendor/autoload.php'; + +define( + 'TEST_FILES_PATH', + __DIR__ . DIRECTORY_SEPARATOR . '_fixture' . DIRECTORY_SEPARATOR +); diff --git a/vendor/phpunit/phpunit/.gitattributes b/vendor/phpunit/phpunit/.gitattributes new file mode 100644 index 0000000..4f4f5d4 --- /dev/null +++ b/vendor/phpunit/phpunit/.gitattributes @@ -0,0 +1,14 @@ +/.docker export-ignore +/.editorconfig export-ignore +/.github export-ignore +/.psalm export-ignore +/.php_cs.dist export-ignore +/build export-ignore +/build.xml export-ignore +/phive.xml export-ignore +/phpunit.xml export-ignore +/tests export-ignore +/tools export-ignore +/tools/* binary + +*.php diff=php diff --git a/vendor/phpunit/phpunit/.gitignore b/vendor/phpunit/phpunit/.gitignore new file mode 100644 index 0000000..a16a652 --- /dev/null +++ b/vendor/phpunit/phpunit/.gitignore @@ -0,0 +1,30 @@ +# PhpStorm +/.idea + +# Composer +/vendor +/composer.lock + +# Apache Ant +/.ant_targets + +# Build artifacts and temporary files +/build/artifacts +/build/tmp + +# PHP-CS-Fixer +/.php_cs +/.php_cs.cache + +# Psalm +/.psalm/cache + +# PHPUnit +.phpunit.result.cache + +# Temporary files generated by PHPT test runner +/tests/end-to-end/*.diff +/tests/end-to-end/*.exp +/tests/end-to-end/*.log +/tests/end-to-end/*.out +/tests/end-to-end/*.php diff --git a/vendor/phpunit/phpunit/.phive/phars.xml b/vendor/phpunit/phpunit/.phive/phars.xml new file mode 100644 index 0000000..f2036d0 --- /dev/null +++ b/vendor/phpunit/phpunit/.phive/phars.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/.phpstorm.meta.php b/vendor/phpunit/phpunit/.phpstorm.meta.php new file mode 100644 index 0000000..5e4c4c2 --- /dev/null +++ b/vendor/phpunit/phpunit/.phpstorm.meta.php @@ -0,0 +1,45 @@ +. +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 Sebastian Bergmann nor the names of his + 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. diff --git a/vendor/phpunit/phpunit/README.md b/vendor/phpunit/phpunit/README.md new file mode 100644 index 0000000..edf80e4 --- /dev/null +++ b/vendor/phpunit/phpunit/README.md @@ -0,0 +1,41 @@ +# PHPUnit + +PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks. + +[![Latest Stable Version](https://img.shields.io/packagist/v/phpunit/phpunit.svg?style=flat-square)](https://packagist.org/packages/phpunit/phpunit) +[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%207.2-8892BF.svg?style=flat-square)](https://php.net/) +[![CI Status](https://github.com/sebastianbergmann/phpunit/workflows/CI/badge.svg?branch=8.5&event=push)](https://phpunit.de/build-status.html) +[![Type Coverage](https://shepherd.dev/github/sebastianbergmann/phpunit/coverage.svg)](https://shepherd.dev/github/sebastianbergmann/phpunit) + +## Installation + +We distribute a [PHP Archive (PHAR)](https://php.net/phar) that has all required (as well as some optional) dependencies of PHPUnit 8.5 bundled in a single file: + +```bash +$ wget https://phar.phpunit.de/phpunit-8.5.phar + +$ php phpunit-8.5.phar --version +``` + +Alternatively, you may use [Composer](https://getcomposer.org/) to download and install PHPUnit as well as its dependencies. Please refer to the "[Getting Started](https://phpunit.de/getting-started-with-phpunit.html)" guide for details on how to install PHPUnit. + +## Contribute + +Please refer to [CONTRIBUTING.md](https://github.com/sebastianbergmann/phpunit/blob/master/.github/CONTRIBUTING.md) for information on how to contribute to PHPUnit and its related projects. + +## List of Contributors + +Thanks to everyone who has contributed to PHPUnit! You can find a detailed list of contributors on every PHPUnit related package on GitHub. This list shows only the major components: + +* [PHPUnit](https://github.com/sebastianbergmann/phpunit/graphs/contributors) +* [php-code-coverage](https://github.com/sebastianbergmann/php-code-coverage/graphs/contributors) + +A very special thanks to everyone who has contributed to the documentation and helps maintain the translations: + +* [English](https://github.com/sebastianbergmann/phpunit-documentation-english/graphs/contributors) +* [Spanish](https://github.com/sebastianbergmann/phpunit-documentation-spanish/graphs/contributors) +* [French](https://github.com/sebastianbergmann/phpunit-documentation-french/graphs/contributors) +* [Japanese](https://github.com/sebastianbergmann/phpunit-documentation-japanese/graphs/contributors) +* [Brazilian Portuguese](https://github.com/sebastianbergmann/phpunit-documentation-brazilian-portuguese/graphs/contributors) +* [Simplified Chinese](https://github.com/sebastianbergmann/phpunit-documentation-chinese/graphs/contributors) + diff --git a/vendor/phpunit/phpunit/composer.json b/vendor/phpunit/phpunit/composer.json new file mode 100644 index 0000000..305fe7a --- /dev/null +++ b/vendor/phpunit/phpunit/composer.json @@ -0,0 +1,89 @@ +{ + "name": "phpunit/phpunit", + "description": "The PHP Unit Testing framework.", + "type": "library", + "keywords": [ + "phpunit", + "xunit", + "testing" + ], + "homepage": "https://phpunit.de/", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues" + }, + "prefer-stable": true, + "require": { + "php": "^7.2", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "doctrine/instantiator": "^1.2.0", + "myclabs/deep-copy": "^1.9.1", + "phar-io/manifest": "^1.0.3", + "phar-io/version": "^2.0.1", + "phpspec/prophecy": "^1.8.1", + "phpunit/php-code-coverage": "^7.0.7", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.2", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.2", + "sebastian/exporter": "^3.1.1", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" + }, + "require-dev": { + "ext-PDO": "*" + }, + "config": { + "platform": { + "php": "7.2.0" + }, + "optimize-autoloader": true, + "sort-packages": true + }, + "suggest": { + "phpunit/php-invoker": "^2.0.0", + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "autoload": { + "classmap": [ + "src/" + ] + }, + "autoload-dev": { + "classmap": [ + "tests/" + ], + "files": [ + "src/Framework/Assert/Functions.php", + "tests/_files/CoverageNamespacedFunctionTest.php", + "tests/_files/CoveredFunction.php", + "tests/_files/NamespaceCoveredFunction.php" + ] + }, + "extra": { + "branch-alias": { + "dev-master": "8.5-dev" + } + } +} diff --git a/vendor/phpunit/phpunit/phpunit b/vendor/phpunit/phpunit/phpunit new file mode 100644 index 0000000..d8393f8 --- /dev/null +++ b/vendor/phpunit/phpunit/phpunit @@ -0,0 +1,61 @@ +#!/usr/bin/env php + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +if (version_compare('7.2.0', PHP_VERSION, '>')) { + fwrite( + STDERR, + sprintf( + 'This version of PHPUnit is supported on PHP 7.2, PHP 7.3, and PHP 7.4.' . PHP_EOL . + 'You are using PHP %s (%s).' . PHP_EOL, + PHP_VERSION, + PHP_BINARY + ) + ); + + die(1); +} + +if (!ini_get('date.timezone')) { + ini_set('date.timezone', 'UTC'); +} + +foreach (array(__DIR__ . '/../../autoload.php', __DIR__ . '/../vendor/autoload.php', __DIR__ . '/vendor/autoload.php') as $file) { + if (file_exists($file)) { + define('PHPUNIT_COMPOSER_INSTALL', $file); + + break; + } +} + +unset($file); + +if (!defined('PHPUNIT_COMPOSER_INSTALL')) { + fwrite( + STDERR, + 'You need to set up the project dependencies using Composer:' . PHP_EOL . PHP_EOL . + ' composer install' . PHP_EOL . PHP_EOL . + 'You can learn all about Composer on https://getcomposer.org/.' . PHP_EOL + ); + + die(1); +} + +$options = getopt('', array('prepend:')); + +if (isset($options['prepend'])) { + require $options['prepend']; +} + +unset($options); + +require PHPUNIT_COMPOSER_INSTALL; + +PHPUnit\TextUI\Command::main(); diff --git a/vendor/phpunit/phpunit/phpunit.xsd b/vendor/phpunit/phpunit/phpunit.xsd new file mode 100644 index 0000000..29cfcf2 --- /dev/null +++ b/vendor/phpunit/phpunit/phpunit.xsd @@ -0,0 +1,317 @@ + + + + + This Schema file defines the rules by which the XML configuration file of PHPUnit 8.5 may be structured. + + + + + + Root Element + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + The main type specifying the document structure + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/vendor/phpunit/phpunit/src/Exception.php b/vendor/phpunit/phpunit/src/Exception.php new file mode 100644 index 0000000..075a315 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Exception extends \Throwable +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Assert.php b/vendor/phpunit/phpunit/src/Framework/Assert.php new file mode 100644 index 0000000..fb776d5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Assert.php @@ -0,0 +1,3556 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use ArrayAccess; +use Countable; +use DOMDocument; +use DOMElement; +use PHPUnit\Framework\Constraint\ArrayHasKey; +use PHPUnit\Framework\Constraint\ArraySubset; +use PHPUnit\Framework\Constraint\Attribute; +use PHPUnit\Framework\Constraint\Callback; +use PHPUnit\Framework\Constraint\ClassHasAttribute; +use PHPUnit\Framework\Constraint\ClassHasStaticAttribute; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\Constraint\Count; +use PHPUnit\Framework\Constraint\DirectoryExists; +use PHPUnit\Framework\Constraint\FileExists; +use PHPUnit\Framework\Constraint\GreaterThan; +use PHPUnit\Framework\Constraint\IsAnything; +use PHPUnit\Framework\Constraint\IsEmpty; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\Constraint\IsFalse; +use PHPUnit\Framework\Constraint\IsFinite; +use PHPUnit\Framework\Constraint\IsIdentical; +use PHPUnit\Framework\Constraint\IsInfinite; +use PHPUnit\Framework\Constraint\IsInstanceOf; +use PHPUnit\Framework\Constraint\IsJson; +use PHPUnit\Framework\Constraint\IsNan; +use PHPUnit\Framework\Constraint\IsNull; +use PHPUnit\Framework\Constraint\IsReadable; +use PHPUnit\Framework\Constraint\IsTrue; +use PHPUnit\Framework\Constraint\IsType; +use PHPUnit\Framework\Constraint\IsWritable; +use PHPUnit\Framework\Constraint\JsonMatches; +use PHPUnit\Framework\Constraint\LessThan; +use PHPUnit\Framework\Constraint\LogicalAnd; +use PHPUnit\Framework\Constraint\LogicalNot; +use PHPUnit\Framework\Constraint\LogicalOr; +use PHPUnit\Framework\Constraint\LogicalXor; +use PHPUnit\Framework\Constraint\ObjectHasAttribute; +use PHPUnit\Framework\Constraint\RegularExpression; +use PHPUnit\Framework\Constraint\SameSize; +use PHPUnit\Framework\Constraint\StringContains; +use PHPUnit\Framework\Constraint\StringEndsWith; +use PHPUnit\Framework\Constraint\StringMatchesFormatDescription; +use PHPUnit\Framework\Constraint\StringStartsWith; +use PHPUnit\Framework\Constraint\TraversableContains; +use PHPUnit\Framework\Constraint\TraversableContainsEqual; +use PHPUnit\Framework\Constraint\TraversableContainsIdentical; +use PHPUnit\Framework\Constraint\TraversableContainsOnly; +use PHPUnit\Util\Type; +use PHPUnit\Util\Xml; +use ReflectionObject; +use Traversable; + +/** + * A set of assertion methods. + */ +abstract class Assert +{ + /** + * @var int + */ + private static $count = 0; + + /** + * Asserts that an array has a specified key. + * + * @param int|string $key + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertArrayHasKey($key, $array, string $message = ''): void + { + if (!(\is_int($key) || \is_string($key))) { + throw InvalidArgumentException::create( + 1, + 'integer or string' + ); + } + + if (!(\is_array($array) || $array instanceof ArrayAccess)) { + throw InvalidArgumentException::create( + 2, + 'array or ArrayAccess' + ); + } + + $constraint = new ArrayHasKey($key); + + static::assertThat($array, $constraint, $message); + } + + /** + * Asserts that an array has a specified subset. + * + * @param array|ArrayAccess $subset + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @codeCoverageIgnore + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3494 + */ + public static function assertArraySubset($subset, $array, bool $checkForObjectIdentity = false, string $message = ''): void + { + self::createWarning('assertArraySubset() is deprecated and will be removed in PHPUnit 9.'); + + if (!(\is_array($subset) || $subset instanceof ArrayAccess)) { + throw InvalidArgumentException::create( + 1, + 'array or ArrayAccess' + ); + } + + if (!(\is_array($array) || $array instanceof ArrayAccess)) { + throw InvalidArgumentException::create( + 2, + 'array or ArrayAccess' + ); + } + + $constraint = new ArraySubset($subset, $checkForObjectIdentity); + + static::assertThat($array, $constraint, $message); + } + + /** + * Asserts that an array does not have a specified key. + * + * @param int|string $key + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertArrayNotHasKey($key, $array, string $message = ''): void + { + if (!(\is_int($key) || \is_string($key))) { + throw InvalidArgumentException::create( + 1, + 'integer or string' + ); + } + + if (!(\is_array($array) || $array instanceof ArrayAccess)) { + throw InvalidArgumentException::create( + 2, + 'array or ArrayAccess' + ); + } + + $constraint = new LogicalNot( + new ArrayHasKey($key) + ); + + static::assertThat($array, $constraint, $message); + } + + /** + * Asserts that a haystack contains a needle. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertContains($needle, $haystack, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void + { + // @codeCoverageIgnoreStart + if (\is_string($haystack)) { + self::createWarning('Using assertContains() with string haystacks is deprecated and will not be supported in PHPUnit 9. Refactor your test to use assertStringContainsString() or assertStringContainsStringIgnoringCase() instead.'); + } + + if (!$checkForObjectIdentity) { + self::createWarning('The optional $checkForObjectIdentity parameter of assertContains() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertContainsEquals() instead.'); + } + + if ($checkForNonObjectIdentity) { + self::createWarning('The optional $checkForNonObjectIdentity parameter of assertContains() is deprecated and will be removed in PHPUnit 9.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertContains() is deprecated and will be removed in PHPUnit 9.'); + } + // @codeCoverageIgnoreEnd + + if (\is_array($haystack) || + (\is_object($haystack) && $haystack instanceof Traversable)) { + $constraint = new TraversableContains( + $needle, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } elseif (\is_string($haystack)) { + if (!\is_string($needle)) { + throw InvalidArgumentException::create( + 1, + 'string' + ); + } + + $constraint = new StringContains( + $needle, + $ignoreCase + ); + } else { + throw InvalidArgumentException::create( + 2, + 'array, traversable or string' + ); + } + + static::assertThat($haystack, $constraint, $message); + } + + public static function assertContainsEquals($needle, iterable $haystack, string $message = ''): void + { + $constraint = new TraversableContainsEqual($needle); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains a needle. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeContains($needle, string $haystackAttributeName, $haystackClassOrObject, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void + { + self::createWarning('assertAttributeContains() is deprecated and will be removed in PHPUnit 9.'); + + static::assertContains( + $needle, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } + + /** + * Asserts that a haystack does not contain a needle. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertNotContains($needle, $haystack, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void + { + // @codeCoverageIgnoreStart + if (\is_string($haystack)) { + self::createWarning('Using assertNotContains() with string haystacks is deprecated and will not be supported in PHPUnit 9. Refactor your test to use assertStringNotContainsString() or assertStringNotContainsStringIgnoringCase() instead.'); + } + + if (!$checkForObjectIdentity) { + self::createWarning('The optional $checkForObjectIdentity parameter of assertNotContains() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertNotContainsEquals() instead.'); + } + + if ($checkForNonObjectIdentity) { + self::createWarning('The optional $checkForNonObjectIdentity parameter of assertNotContains() is deprecated and will be removed in PHPUnit 9.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertNotContains() is deprecated and will be removed in PHPUnit 9.'); + } + // @codeCoverageIgnoreEnd + + if (\is_array($haystack) || + (\is_object($haystack) && $haystack instanceof Traversable)) { + $constraint = new LogicalNot( + new TraversableContains( + $needle, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ) + ); + } elseif (\is_string($haystack)) { + if (!\is_string($needle)) { + throw InvalidArgumentException::create( + 1, + 'string' + ); + } + + $constraint = new LogicalNot( + new StringContains( + $needle, + $ignoreCase + ) + ); + } else { + throw InvalidArgumentException::create( + 2, + 'array, traversable or string' + ); + } + + static::assertThat($haystack, $constraint, $message); + } + + public static function assertNotContainsEquals($needle, iterable $haystack, string $message = ''): void + { + $constraint = new LogicalNot(new TraversableContainsEqual($needle)); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain a needle. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotContains($needle, string $haystackAttributeName, $haystackClassOrObject, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void + { + self::createWarning('assertAttributeNotContains() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotContains( + $needle, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message, + $ignoreCase, + $checkForObjectIdentity, + $checkForNonObjectIdentity + ); + } + + /** + * Asserts that a haystack contains only values of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void + { + if ($isNativeType === null) { + $isNativeType = Type::isType($type); + } + + static::assertThat( + $haystack, + new TraversableContainsOnly( + $type, + $isNativeType + ), + $message + ); + } + + /** + * Asserts that a haystack contains only instances of a given class name. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void + { + static::assertThat( + $haystack, + new TraversableContainsOnly( + $className, + false + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains only values of a given type. + * + * @param object|string $haystackClassOrObject + * @param bool $isNativeType + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeContainsOnly(string $type, string $haystackAttributeName, $haystackClassOrObject, ?bool $isNativeType = null, string $message = ''): void + { + self::createWarning('assertAttributeContainsOnly() is deprecated and will be removed in PHPUnit 9.'); + + static::assertContainsOnly( + $type, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts that a haystack does not contain only values of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void + { + if ($isNativeType === null) { + $isNativeType = Type::isType($type); + } + + static::assertThat( + $haystack, + new LogicalNot( + new TraversableContainsOnly( + $type, + $isNativeType + ) + ), + $message + ); + } + + /** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain only values of a given + * type. + * + * @param object|string $haystackClassOrObject + * @param bool $isNativeType + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotContainsOnly(string $type, string $haystackAttributeName, $haystackClassOrObject, ?bool $isNativeType = null, string $message = ''): void + { + self::createWarning('assertAttributeNotContainsOnly() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotContainsOnly( + $type, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $isNativeType, + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param Countable|iterable $haystack + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertCount(int $expectedCount, $haystack, string $message = ''): void + { + if (!$haystack instanceof Countable && !\is_iterable($haystack)) { + throw InvalidArgumentException::create(2, 'countable or iterable'); + } + + static::assertThat( + $haystack, + new Count($expectedCount), + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeCount(int $expectedCount, string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeCount() is deprecated and will be removed in PHPUnit 9.'); + + static::assertCount( + $expectedCount, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param Countable|iterable $haystack + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertNotCount(int $expectedCount, $haystack, string $message = ''): void + { + if (!$haystack instanceof Countable && !\is_iterable($haystack)) { + throw InvalidArgumentException::create(2, 'countable or iterable'); + } + + $constraint = new LogicalNot( + new Count($expectedCount) + ); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotCount(int $expectedCount, string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeNotCount() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotCount( + $expectedCount, + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that two variables are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertEquals($expected, $actual, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($delta !== 0.0) { + self::createWarning('The optional $delta parameter of assertEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertEqualsWithDelta() instead.'); + } + + if ($maxDepth !== 10) { + self::createWarning('The optional $maxDepth parameter of assertEquals() is deprecated and will be removed in PHPUnit 9.'); + } + + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertEqualsCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertEqualsIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + $constraint = new IsEqual( + $expected, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are equal (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void + { + $constraint = new IsEqual( + $expected, + 0.0, + 10, + true, + false + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are equal (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void + { + $constraint = new IsEqual( + $expected, + 0.0, + 10, + false, + true + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are equal (with delta). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void + { + $constraint = new IsEqual( + $expected, + $delta + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is equal to an attribute of an object. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeEquals($expected, string $actualAttributeName, $actualClassOrObject, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void + { + self::createWarning('assertAttributeEquals() is deprecated and will be removed in PHPUnit 9.'); + + static::assertEquals( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that two variables are not equal. + * + * @param float $delta + * @param int $maxDepth + * @param bool $canonicalize + * @param bool $ignoreCase + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotEquals($expected, $actual, string $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($delta !== 0.0) { + self::createWarning('The optional $delta parameter of assertNotEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertNotEqualsWithDelta() instead.'); + } + + if ($maxDepth !== 10) { + self::createWarning('The optional $maxDepth parameter of assertNotEquals() is deprecated and will be removed in PHPUnit 9.'); + } + + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertNotEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertNotEqualsCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertNotEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertNotEqualsIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + $constraint = new LogicalNot( + new IsEqual( + $expected, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ) + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are not equal (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void + { + $constraint = new LogicalNot( + new IsEqual( + $expected, + 0.0, + 10, + true, + false + ) + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are not equal (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void + { + $constraint = new LogicalNot( + new IsEqual( + $expected, + 0.0, + 10, + false, + true + ) + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that two variables are not equal (with delta). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void + { + $constraint = new LogicalNot( + new IsEqual( + $expected, + $delta + ) + ); + + static::assertThat($actual, $constraint, $message); + } + + /** + * Asserts that a variable is not equal to an attribute of an object. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotEquals($expected, string $actualAttributeName, $actualClassOrObject, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void + { + self::createWarning('assertAttributeNotEquals() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotEquals( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ); + } + + /** + * Asserts that a variable is empty. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert empty $actual + */ + public static function assertEmpty($actual, string $message = ''): void + { + static::assertThat($actual, static::isEmpty(), $message); + } + + /** + * Asserts that a static attribute of a class or an attribute of an object + * is empty. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeEmpty(string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeEmpty() is deprecated and will be removed in PHPUnit 9.'); + + static::assertEmpty( + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that a variable is not empty. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !empty $actual + */ + public static function assertNotEmpty($actual, string $message = ''): void + { + static::assertThat($actual, static::logicalNot(static::isEmpty()), $message); + } + + /** + * Asserts that a static attribute of a class or an attribute of an object + * is not empty. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotEmpty(string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeNotEmpty() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotEmpty( + static::readAttribute($haystackClassOrObject, $haystackAttributeName), + $message + ); + } + + /** + * Asserts that a value is greater than another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertGreaterThan($expected, $actual, string $message = ''): void + { + static::assertThat($actual, static::greaterThan($expected), $message); + } + + /** + * Asserts that an attribute is greater than another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeGreaterThan($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeGreaterThan() is deprecated and will be removed in PHPUnit 9.'); + + static::assertGreaterThan( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is greater than or equal to another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void + { + static::assertThat( + $actual, + static::greaterThanOrEqual($expected), + $message + ); + } + + /** + * Asserts that an attribute is greater than or equal to another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeGreaterThanOrEqual($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeGreaterThanOrEqual() is deprecated and will be removed in PHPUnit 9.'); + + static::assertGreaterThanOrEqual( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertLessThan($expected, $actual, string $message = ''): void + { + static::assertThat($actual, static::lessThan($expected), $message); + } + + /** + * Asserts that an attribute is smaller than another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeLessThan($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeLessThan() is deprecated and will be removed in PHPUnit 9.'); + + static::assertLessThan( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a value is smaller than or equal to another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertLessThanOrEqual($expected, $actual, string $message = ''): void + { + static::assertThat($actual, static::lessThanOrEqual($expected), $message); + } + + /** + * Asserts that an attribute is smaller than or equal to another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeLessThanOrEqual($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeLessThanOrEqual() is deprecated and will be removed in PHPUnit 9.'); + + static::assertLessThanOrEqual( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that the contents of one file is equal to the contents of another + * file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileEquals(string $expected, string $actual, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertFileEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertFileEqualsCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertFileEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertFileEqualsIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + $canonicalize, + $ignoreCase + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of one file is equal to the contents of another + * file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void + { + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + true + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of one file is equal to the contents of another + * file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void + { + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + false, + true + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of + * another file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotEquals(string $expected, string $actual, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertFileNotEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertFileNotEqualsCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertFileNotEquals() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertFileNotEqualsIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + $canonicalize, + $ignoreCase + ) + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of another + * file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void + { + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + true + ) + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of one file is not equal to the contents of another + * file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void + { + static::assertFileExists($expected, $message); + static::assertFileExists($actual, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expected), + 0.0, + 10, + false, + true + ) + ); + + static::assertThat(\file_get_contents($actual), $constraint, $message); + } + + /** + * Asserts that the contents of a string is equal + * to the contents of a file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertStringEqualsFile() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertStringEqualsFileCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertStringEqualsFile() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertStringEqualsFileIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + static::assertFileExists($expectedFile, $message); + + $constraint = new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + $canonicalize, + $ignoreCase + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that the contents of a string is equal + * to the contents of a file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + + $constraint = new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + true + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that the contents of a string is equal + * to the contents of a file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + + $constraint = new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + false, + true + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that the contents of a string is not equal + * to the contents of a file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void + { + // @codeCoverageIgnoreStart + if ($canonicalize) { + self::createWarning('The optional $canonicalize parameter of assertStringNotEqualsFile() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertStringNotEqualsFileCanonicalizing() instead.'); + } + + if ($ignoreCase) { + self::createWarning('The optional $ignoreCase parameter of assertStringNotEqualsFile() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertStringNotEqualsFileIgnoringCase() instead.'); + } + // @codeCoverageIgnoreEnd + + static::assertFileExists($expectedFile, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + $canonicalize, + $ignoreCase + ) + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that the contents of a string is not equal + * to the contents of a file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + true + ) + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that the contents of a string is not equal + * to the contents of a file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + + $constraint = new LogicalNot( + new IsEqual( + \file_get_contents($expectedFile), + 0.0, + 10, + false, + true + ) + ); + + static::assertThat($actualString, $constraint, $message); + } + + /** + * Asserts that a file/dir is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertIsReadable(string $filename, string $message = ''): void + { + static::assertThat($filename, new IsReadable, $message); + } + + /** + * Asserts that a file/dir exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotIsReadable(string $filename, string $message = ''): void + { + static::assertThat($filename, new LogicalNot(new IsReadable), $message); + } + + /** + * Asserts that a file/dir exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertIsWritable(string $filename, string $message = ''): void + { + static::assertThat($filename, new IsWritable, $message); + } + + /** + * Asserts that a file/dir exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotIsWritable(string $filename, string $message = ''): void + { + static::assertThat($filename, new LogicalNot(new IsWritable), $message); + } + + /** + * Asserts that a directory exists. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryExists(string $directory, string $message = ''): void + { + static::assertThat($directory, new DirectoryExists, $message); + } + + /** + * Asserts that a directory does not exist. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryNotExists(string $directory, string $message = ''): void + { + static::assertThat($directory, new LogicalNot(new DirectoryExists), $message); + } + + /** + * Asserts that a directory exists and is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryIsReadable(string $directory, string $message = ''): void + { + self::assertDirectoryExists($directory, $message); + self::assertIsReadable($directory, $message); + } + + /** + * Asserts that a directory exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryNotIsReadable(string $directory, string $message = ''): void + { + self::assertDirectoryExists($directory, $message); + self::assertNotIsReadable($directory, $message); + } + + /** + * Asserts that a directory exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryIsWritable(string $directory, string $message = ''): void + { + self::assertDirectoryExists($directory, $message); + self::assertIsWritable($directory, $message); + } + + /** + * Asserts that a directory exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertDirectoryNotIsWritable(string $directory, string $message = ''): void + { + self::assertDirectoryExists($directory, $message); + self::assertNotIsWritable($directory, $message); + } + + /** + * Asserts that a file exists. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileExists(string $filename, string $message = ''): void + { + static::assertThat($filename, new FileExists, $message); + } + + /** + * Asserts that a file does not exist. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotExists(string $filename, string $message = ''): void + { + static::assertThat($filename, new LogicalNot(new FileExists), $message); + } + + /** + * Asserts that a file exists and is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileIsReadable(string $file, string $message = ''): void + { + self::assertFileExists($file, $message); + self::assertIsReadable($file, $message); + } + + /** + * Asserts that a file exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotIsReadable(string $file, string $message = ''): void + { + self::assertFileExists($file, $message); + self::assertNotIsReadable($file, $message); + } + + /** + * Asserts that a file exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileIsWritable(string $file, string $message = ''): void + { + self::assertFileExists($file, $message); + self::assertIsWritable($file, $message); + } + + /** + * Asserts that a file exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFileNotIsWritable(string $file, string $message = ''): void + { + self::assertFileExists($file, $message); + self::assertNotIsWritable($file, $message); + } + + /** + * Asserts that a condition is true. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert true $condition + */ + public static function assertTrue($condition, string $message = ''): void + { + static::assertThat($condition, static::isTrue(), $message); + } + + /** + * Asserts that a condition is not true. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !true $condition + */ + public static function assertNotTrue($condition, string $message = ''): void + { + static::assertThat($condition, static::logicalNot(static::isTrue()), $message); + } + + /** + * Asserts that a condition is false. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert false $condition + */ + public static function assertFalse($condition, string $message = ''): void + { + static::assertThat($condition, static::isFalse(), $message); + } + + /** + * Asserts that a condition is not false. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !false $condition + */ + public static function assertNotFalse($condition, string $message = ''): void + { + static::assertThat($condition, static::logicalNot(static::isFalse()), $message); + } + + /** + * Asserts that a variable is null. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert null $actual + */ + public static function assertNull($actual, string $message = ''): void + { + static::assertThat($actual, static::isNull(), $message); + } + + /** + * Asserts that a variable is not null. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !null $actual + */ + public static function assertNotNull($actual, string $message = ''): void + { + static::assertThat($actual, static::logicalNot(static::isNull()), $message); + } + + /** + * Asserts that a variable is finite. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertFinite($actual, string $message = ''): void + { + static::assertThat($actual, static::isFinite(), $message); + } + + /** + * Asserts that a variable is infinite. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertInfinite($actual, string $message = ''): void + { + static::assertThat($actual, static::isInfinite(), $message); + } + + /** + * Asserts that a variable is nan. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNan($actual, string $message = ''): void + { + static::assertThat($actual, static::isNan(), $message); + } + + /** + * Asserts that a class has a specified attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void + { + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\class_exists($className)) { + throw InvalidArgumentException::create(2, 'class name'); + } + + static::assertThat($className, new ClassHasAttribute($attributeName), $message); + } + + /** + * Asserts that a class does not have a specified attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void + { + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\class_exists($className)) { + throw InvalidArgumentException::create(2, 'class name'); + } + + static::assertThat( + $className, + new LogicalNot( + new ClassHasAttribute($attributeName) + ), + $message + ); + } + + /** + * Asserts that a class has a specified static attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void + { + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\class_exists($className)) { + throw InvalidArgumentException::create(2, 'class name'); + } + + static::assertThat( + $className, + new ClassHasStaticAttribute($attributeName), + $message + ); + } + + /** + * Asserts that a class does not have a specified static attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void + { + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\class_exists($className)) { + throw InvalidArgumentException::create(2, 'class name'); + } + + static::assertThat( + $className, + new LogicalNot( + new ClassHasStaticAttribute($attributeName) + ), + $message + ); + } + + /** + * Asserts that an object has a specified attribute. + * + * @param object $object + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertObjectHasAttribute(string $attributeName, $object, string $message = ''): void + { + if (!self::isValidObjectAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\is_object($object)) { + throw InvalidArgumentException::create(2, 'object'); + } + + static::assertThat( + $object, + new ObjectHasAttribute($attributeName), + $message + ); + } + + /** + * Asserts that an object does not have a specified attribute. + * + * @param object $object + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertObjectNotHasAttribute(string $attributeName, $object, string $message = ''): void + { + if (!self::isValidObjectAttributeName($attributeName)) { + throw InvalidArgumentException::create(1, 'valid attribute name'); + } + + if (!\is_object($object)) { + throw InvalidArgumentException::create(2, 'object'); + } + + static::assertThat( + $object, + new LogicalNot( + new ObjectHasAttribute($attributeName) + ), + $message + ); + } + + /** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-template ExpectedType + * @psalm-param ExpectedType $expected + * @psalm-assert =ExpectedType $actual + */ + public static function assertSame($expected, $actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsIdentical($expected), + $message + ); + } + + /** + * Asserts that a variable and an attribute of an object have the same type + * and value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeSame($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeSame() is deprecated and will be removed in PHPUnit 9.'); + + static::assertSame( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that two variables do not have the same type and value. + * Used on objects, it asserts that two variables do not reference + * the same object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotSame($expected, $actual, string $message = ''): void + { + if (\is_bool($expected) && \is_bool($actual)) { + static::assertNotEquals($expected, $actual, $message); + } + + static::assertThat( + $actual, + new LogicalNot( + new IsIdentical($expected) + ), + $message + ); + } + + /** + * Asserts that a variable and an attribute of an object do not have the + * same type and value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotSame($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void + { + self::createWarning('assertAttributeNotSame() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotSame( + $expected, + static::readAttribute($actualClassOrObject, $actualAttributeName), + $message + ); + } + + /** + * Asserts that a variable is of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @psalm-template ExpectedType of object + * @psalm-param class-string $expected + * @psalm-assert ExpectedType $actual + */ + public static function assertInstanceOf(string $expected, $actual, string $message = ''): void + { + if (!\class_exists($expected) && !\interface_exists($expected)) { + throw InvalidArgumentException::create(1, 'class or interface name'); + } + + static::assertThat( + $actual, + new IsInstanceOf($expected), + $message + ); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @psalm-param class-string $expected + */ + public static function assertAttributeInstanceOf(string $expected, string $attributeName, $classOrObject, string $message = ''): void + { + self::createWarning('assertAttributeInstanceOf() is deprecated and will be removed in PHPUnit 9.'); + + static::assertInstanceOf( + $expected, + static::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is not of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @psalm-template ExpectedType of object + * @psalm-param class-string $expected + * @psalm-assert !ExpectedType $actual + */ + public static function assertNotInstanceOf(string $expected, $actual, string $message = ''): void + { + if (!\class_exists($expected) && !\interface_exists($expected)) { + throw InvalidArgumentException::create(1, 'class or interface name'); + } + + static::assertThat( + $actual, + new LogicalNot( + new IsInstanceOf($expected) + ), + $message + ); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @psalm-param class-string $expected + */ + public static function assertAttributeNotInstanceOf(string $expected, string $attributeName, $classOrObject, string $message = ''): void + { + self::createWarning('assertAttributeNotInstanceOf() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotInstanceOf( + $expected, + static::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3369 + * @codeCoverageIgnore + */ + public static function assertInternalType(string $expected, $actual, string $message = ''): void + { + self::createWarning('assertInternalType() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertIsArray(), assertIsBool(), assertIsFloat(), assertIsInt(), assertIsNumeric(), assertIsObject(), assertIsResource(), assertIsString(), assertIsScalar(), assertIsCallable(), or assertIsIterable() instead.'); + + static::assertThat( + $actual, + new IsType($expected), + $message + ); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeInternalType(string $expected, string $attributeName, $classOrObject, string $message = ''): void + { + self::createWarning('assertAttributeInternalType() is deprecated and will be removed in PHPUnit 9.'); + + static::assertInternalType( + $expected, + static::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a variable is of type array. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert array $actual + */ + public static function assertIsArray($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_ARRAY), + $message + ); + } + + /** + * Asserts that a variable is of type bool. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert bool $actual + */ + public static function assertIsBool($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_BOOL), + $message + ); + } + + /** + * Asserts that a variable is of type float. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert float $actual + */ + public static function assertIsFloat($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_FLOAT), + $message + ); + } + + /** + * Asserts that a variable is of type int. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert int $actual + */ + public static function assertIsInt($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_INT), + $message + ); + } + + /** + * Asserts that a variable is of type numeric. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert numeric $actual + */ + public static function assertIsNumeric($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_NUMERIC), + $message + ); + } + + /** + * Asserts that a variable is of type object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert object $actual + */ + public static function assertIsObject($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_OBJECT), + $message + ); + } + + /** + * Asserts that a variable is of type resource. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert resource $actual + */ + public static function assertIsResource($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_RESOURCE), + $message + ); + } + + /** + * Asserts that a variable is of type string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert string $actual + */ + public static function assertIsString($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_STRING), + $message + ); + } + + /** + * Asserts that a variable is of type scalar. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert scalar $actual + */ + public static function assertIsScalar($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_SCALAR), + $message + ); + } + + /** + * Asserts that a variable is of type callable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert callable $actual + */ + public static function assertIsCallable($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_CALLABLE), + $message + ); + } + + /** + * Asserts that a variable is of type iterable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert iterable $actual + */ + public static function assertIsIterable($actual, string $message = ''): void + { + static::assertThat( + $actual, + new IsType(IsType::TYPE_ITERABLE), + $message + ); + } + + /** + * Asserts that a variable is not of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3369 + * @codeCoverageIgnore + */ + public static function assertNotInternalType(string $expected, $actual, string $message = ''): void + { + self::createWarning('assertNotInternalType() is deprecated and will be removed in PHPUnit 9. Refactor your test to use assertIsNotArray(), assertIsNotBool(), assertIsNotFloat(), assertIsNotInt(), assertIsNotNumeric(), assertIsNotObject(), assertIsNotResource(), assertIsNotString(), assertIsNotScalar(), assertIsNotCallable(), or assertIsNotIterable() instead.'); + + static::assertThat( + $actual, + new LogicalNot( + new IsType($expected) + ), + $message + ); + } + + /** + * Asserts that a variable is not of type array. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !array $actual + */ + public static function assertIsNotArray($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_ARRAY)), + $message + ); + } + + /** + * Asserts that a variable is not of type bool. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !bool $actual + */ + public static function assertIsNotBool($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_BOOL)), + $message + ); + } + + /** + * Asserts that a variable is not of type float. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !float $actual + */ + public static function assertIsNotFloat($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_FLOAT)), + $message + ); + } + + /** + * Asserts that a variable is not of type int. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !int $actual + */ + public static function assertIsNotInt($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_INT)), + $message + ); + } + + /** + * Asserts that a variable is not of type numeric. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !numeric $actual + */ + public static function assertIsNotNumeric($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_NUMERIC)), + $message + ); + } + + /** + * Asserts that a variable is not of type object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !object $actual + */ + public static function assertIsNotObject($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_OBJECT)), + $message + ); + } + + /** + * Asserts that a variable is not of type resource. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !resource $actual + */ + public static function assertIsNotResource($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_RESOURCE)), + $message + ); + } + + /** + * Asserts that a variable is not of type string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !string $actual + */ + public static function assertIsNotString($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_STRING)), + $message + ); + } + + /** + * Asserts that a variable is not of type scalar. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !scalar $actual + */ + public static function assertIsNotScalar($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_SCALAR)), + $message + ); + } + + /** + * Asserts that a variable is not of type callable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !callable $actual + */ + public static function assertIsNotCallable($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_CALLABLE)), + $message + ); + } + + /** + * Asserts that a variable is not of type iterable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !iterable $actual + */ + public static function assertIsNotIterable($actual, string $message = ''): void + { + static::assertThat( + $actual, + new LogicalNot(new IsType(IsType::TYPE_ITERABLE)), + $message + ); + } + + /** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function assertAttributeNotInternalType(string $expected, string $attributeName, $classOrObject, string $message = ''): void + { + self::createWarning('assertAttributeNotInternalType() is deprecated and will be removed in PHPUnit 9.'); + + static::assertNotInternalType( + $expected, + static::readAttribute($classOrObject, $attributeName), + $message + ); + } + + /** + * Asserts that a string matches a given regular expression. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertRegExp(string $pattern, string $string, string $message = ''): void + { + static::assertThat($string, new RegularExpression($pattern), $message); + } + + /** + * Asserts that a string does not match a given regular expression. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertNotRegExp(string $pattern, string $string, string $message = ''): void + { + static::assertThat( + $string, + new LogicalNot( + new RegularExpression($pattern) + ), + $message + ); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is the same. + * + * @param Countable|iterable $expected + * @param Countable|iterable $actual + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertSameSize($expected, $actual, string $message = ''): void + { + if (!$expected instanceof Countable && !\is_iterable($expected)) { + throw InvalidArgumentException::create(1, 'countable or iterable'); + } + + if (!$actual instanceof Countable && !\is_iterable($actual)) { + throw InvalidArgumentException::create(2, 'countable or iterable'); + } + + static::assertThat( + $actual, + new SameSize($expected), + $message + ); + } + + /** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is not the same. + * + * @param Countable|iterable $expected + * @param Countable|iterable $actual + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertNotSameSize($expected, $actual, string $message = ''): void + { + if (!$expected instanceof Countable && !\is_iterable($expected)) { + throw InvalidArgumentException::create(1, 'countable or iterable'); + } + + if (!$actual instanceof Countable && !\is_iterable($actual)) { + throw InvalidArgumentException::create(2, 'countable or iterable'); + } + + static::assertThat( + $actual, + new LogicalNot( + new SameSize($expected) + ), + $message + ); + } + + /** + * Asserts that a string matches a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringMatchesFormat(string $format, string $string, string $message = ''): void + { + static::assertThat($string, new StringMatchesFormatDescription($format), $message); + } + + /** + * Asserts that a string does not match a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void + { + static::assertThat( + $string, + new LogicalNot( + new StringMatchesFormatDescription($format) + ), + $message + ); + } + + /** + * Asserts that a string matches a given format file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void + { + static::assertFileExists($formatFile, $message); + + static::assertThat( + $string, + new StringMatchesFormatDescription( + \file_get_contents($formatFile) + ), + $message + ); + } + + /** + * Asserts that a string does not match a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void + { + static::assertFileExists($formatFile, $message); + + static::assertThat( + $string, + new LogicalNot( + new StringMatchesFormatDescription( + \file_get_contents($formatFile) + ) + ), + $message + ); + } + + /** + * Asserts that a string starts with a given prefix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringStartsWith(string $prefix, string $string, string $message = ''): void + { + static::assertThat($string, new StringStartsWith($prefix), $message); + } + + /** + * Asserts that a string starts not with a given prefix. + * + * @param string $prefix + * @param string $string + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringStartsNotWith($prefix, $string, string $message = ''): void + { + static::assertThat( + $string, + new LogicalNot( + new StringStartsWith($prefix) + ), + $message + ); + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringContainsString(string $needle, string $haystack, string $message = ''): void + { + $constraint = new StringContains($needle, false); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void + { + $constraint = new StringContains($needle, true); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void + { + $constraint = new LogicalNot(new StringContains($needle)); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void + { + $constraint = new LogicalNot(new StringContains($needle, true)); + + static::assertThat($haystack, $constraint, $message); + } + + /** + * Asserts that a string ends with a given suffix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringEndsWith(string $suffix, string $string, string $message = ''): void + { + static::assertThat($string, new StringEndsWith($suffix), $message); + } + + /** + * Asserts that a string ends not with a given suffix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void + { + static::assertThat( + $string, + new LogicalNot( + new StringEndsWith($suffix) + ), + $message + ); + } + + /** + * Asserts that two XML files are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void + { + $expected = Xml::loadFile($expectedFile); + $actual = Xml::loadFile($actualFile); + + static::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML files are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void + { + $expected = Xml::loadFile($expectedFile); + $actual = Xml::loadFile($actualFile); + + static::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void + { + $expected = Xml::loadFile($expectedFile); + $actual = Xml::load($actualXml); + + static::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void + { + $expected = Xml::loadFile($expectedFile); + $actual = Xml::load($actualXml); + + static::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are equal. + * + * @param DOMDocument|string $expectedXml + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = ''): void + { + $expected = Xml::load($expectedXml); + $actual = Xml::load($actualXml); + + static::assertEquals($expected, $actual, $message); + } + + /** + * Asserts that two XML documents are not equal. + * + * @param DOMDocument|string $expectedXml + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public static function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void + { + $expected = Xml::load($expectedXml); + $actual = Xml::load($actualXml); + + static::assertNotEquals($expected, $actual, $message); + } + + /** + * Asserts that a hierarchy of DOMElements matches. + * + * @throws AssertionFailedError + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, bool $checkAttributes = false, string $message = ''): void + { + $expectedElement = Xml::import($expectedElement); + $actualElement = Xml::import($actualElement); + + static::assertSame( + $expectedElement->tagName, + $actualElement->tagName, + $message + ); + + if ($checkAttributes) { + static::assertSame( + $expectedElement->attributes->length, + $actualElement->attributes->length, + \sprintf( + '%s%sNumber of attributes on node "%s" does not match', + $message, + !empty($message) ? "\n" : '', + $expectedElement->tagName + ) + ); + + for ($i = 0; $i < $expectedElement->attributes->length; $i++) { + $expectedAttribute = $expectedElement->attributes->item($i); + $actualAttribute = $actualElement->attributes->getNamedItem($expectedAttribute->name); + + \assert($expectedAttribute instanceof \DOMAttr); + + if (!$actualAttribute) { + static::fail( + \sprintf( + '%s%sCould not find attribute "%s" on node "%s"', + $message, + !empty($message) ? "\n" : '', + $expectedAttribute->name, + $expectedElement->tagName + ) + ); + } + } + } + + Xml::removeCharacterDataNodes($expectedElement); + Xml::removeCharacterDataNodes($actualElement); + + static::assertSame( + $expectedElement->childNodes->length, + $actualElement->childNodes->length, + \sprintf( + '%s%sNumber of child nodes of "%s" differs', + $message, + !empty($message) ? "\n" : '', + $expectedElement->tagName + ) + ); + + for ($i = 0; $i < $expectedElement->childNodes->length; $i++) { + static::assertEqualXMLStructure( + $expectedElement->childNodes->item($i), + $actualElement->childNodes->item($i), + $checkAttributes, + $message + ); + } + } + + /** + * Evaluates a PHPUnit\Framework\Constraint matcher object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertThat($value, Constraint $constraint, string $message = ''): void + { + self::$count += \count($constraint); + + $constraint->evaluate($value, $message); + } + + /** + * Asserts that a string is a valid JSON string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJson(string $actualJson, string $message = ''): void + { + static::assertThat($actualJson, static::isJson(), $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void + { + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + static::assertThat($actualJson, new JsonMatches($expectedJson), $message); + } + + /** + * Asserts that two given JSON encoded objects or arrays are not equal. + * + * @param string $expectedJson + * @param string $actualJson + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = ''): void + { + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + static::assertThat( + $actualJson, + new LogicalNot( + new JsonMatches($expectedJson) + ), + $message + ); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + $expectedJson = \file_get_contents($expectedFile); + + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + static::assertThat($actualJson, new JsonMatches($expectedJson), $message); + } + + /** + * Asserts that the generated JSON encoded object and the content of the given file are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + $expectedJson = \file_get_contents($expectedFile); + + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + static::assertThat( + $actualJson, + new LogicalNot( + new JsonMatches($expectedJson) + ), + $message + ); + } + + /** + * Asserts that two JSON files are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + static::assertFileExists($actualFile, $message); + + $actualJson = \file_get_contents($actualFile); + $expectedJson = \file_get_contents($expectedFile); + + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + $constraintExpected = new JsonMatches( + $expectedJson + ); + + $constraintActual = new JsonMatches($actualJson); + + static::assertThat($expectedJson, $constraintActual, $message); + static::assertThat($actualJson, $constraintExpected, $message); + } + + /** + * Asserts that two JSON files are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void + { + static::assertFileExists($expectedFile, $message); + static::assertFileExists($actualFile, $message); + + $actualJson = \file_get_contents($actualFile); + $expectedJson = \file_get_contents($expectedFile); + + static::assertJson($expectedJson, $message); + static::assertJson($actualJson, $message); + + $constraintExpected = new JsonMatches( + $expectedJson + ); + + $constraintActual = new JsonMatches($actualJson); + + static::assertThat($expectedJson, new LogicalNot($constraintActual), $message); + static::assertThat($actualJson, new LogicalNot($constraintExpected), $message); + } + + /** + * @throws Exception + */ + public static function logicalAnd(): LogicalAnd + { + $constraints = \func_get_args(); + + $constraint = new LogicalAnd; + $constraint->setConstraints($constraints); + + return $constraint; + } + + public static function logicalOr(): LogicalOr + { + $constraints = \func_get_args(); + + $constraint = new LogicalOr; + $constraint->setConstraints($constraints); + + return $constraint; + } + + public static function logicalNot(Constraint $constraint): LogicalNot + { + return new LogicalNot($constraint); + } + + public static function logicalXor(): LogicalXor + { + $constraints = \func_get_args(); + + $constraint = new LogicalXor; + $constraint->setConstraints($constraints); + + return $constraint; + } + + public static function anything(): IsAnything + { + return new IsAnything; + } + + public static function isTrue(): IsTrue + { + return new IsTrue; + } + + public static function callback(callable $callback): Callback + { + return new Callback($callback); + } + + public static function isFalse(): IsFalse + { + return new IsFalse; + } + + public static function isJson(): IsJson + { + return new IsJson; + } + + public static function isNull(): IsNull + { + return new IsNull; + } + + public static function isFinite(): IsFinite + { + return new IsFinite; + } + + public static function isInfinite(): IsInfinite + { + return new IsInfinite; + } + + public static function isNan(): IsNan + { + return new IsNan; + } + + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function attribute(Constraint $constraint, string $attributeName): Attribute + { + self::createWarning('attribute() is deprecated and will be removed in PHPUnit 9.'); + + return new Attribute($constraint, $attributeName); + } + + /** + * @deprecated Use containsEqual() or containsIdentical() instead + */ + public static function contains($value, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): TraversableContains + { + return new TraversableContains($value, $checkForObjectIdentity, $checkForNonObjectIdentity); + } + + public static function containsEqual($value): TraversableContainsEqual + { + return new TraversableContainsEqual($value); + } + + public static function containsIdentical($value): TraversableContainsIdentical + { + return new TraversableContainsIdentical($value); + } + + public static function containsOnly(string $type): TraversableContainsOnly + { + return new TraversableContainsOnly($type); + } + + public static function containsOnlyInstancesOf(string $className): TraversableContainsOnly + { + return new TraversableContainsOnly($className, false); + } + + /** + * @param int|string $key + */ + public static function arrayHasKey($key): ArrayHasKey + { + return new ArrayHasKey($key); + } + + public static function equalTo($value, float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): IsEqual + { + return new IsEqual($value, $delta, $maxDepth, $canonicalize, $ignoreCase); + } + + /** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function attributeEqualTo(string $attributeName, $value, float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): Attribute + { + self::createWarning('attributeEqualTo() is deprecated and will be removed in PHPUnit 9.'); + + return static::attribute( + static::equalTo( + $value, + $delta, + $maxDepth, + $canonicalize, + $ignoreCase + ), + $attributeName + ); + } + + public static function isEmpty(): IsEmpty + { + return new IsEmpty; + } + + public static function isWritable(): IsWritable + { + return new IsWritable; + } + + public static function isReadable(): IsReadable + { + return new IsReadable; + } + + public static function directoryExists(): DirectoryExists + { + return new DirectoryExists; + } + + public static function fileExists(): FileExists + { + return new FileExists; + } + + public static function greaterThan($value): GreaterThan + { + return new GreaterThan($value); + } + + public static function greaterThanOrEqual($value): LogicalOr + { + return static::logicalOr( + new IsEqual($value), + new GreaterThan($value) + ); + } + + public static function classHasAttribute(string $attributeName): ClassHasAttribute + { + return new ClassHasAttribute($attributeName); + } + + public static function classHasStaticAttribute(string $attributeName): ClassHasStaticAttribute + { + return new ClassHasStaticAttribute($attributeName); + } + + public static function objectHasAttribute($attributeName): ObjectHasAttribute + { + return new ObjectHasAttribute($attributeName); + } + + public static function identicalTo($value): IsIdentical + { + return new IsIdentical($value); + } + + public static function isInstanceOf(string $className): IsInstanceOf + { + return new IsInstanceOf($className); + } + + public static function isType(string $type): IsType + { + return new IsType($type); + } + + public static function lessThan($value): LessThan + { + return new LessThan($value); + } + + public static function lessThanOrEqual($value): LogicalOr + { + return static::logicalOr( + new IsEqual($value), + new LessThan($value) + ); + } + + public static function matchesRegularExpression(string $pattern): RegularExpression + { + return new RegularExpression($pattern); + } + + public static function matches(string $string): StringMatchesFormatDescription + { + return new StringMatchesFormatDescription($string); + } + + public static function stringStartsWith($prefix): StringStartsWith + { + return new StringStartsWith($prefix); + } + + public static function stringContains(string $string, bool $case = true): StringContains + { + return new StringContains($string, $case); + } + + public static function stringEndsWith(string $suffix): StringEndsWith + { + return new StringEndsWith($suffix); + } + + public static function countOf(int $count): Count + { + return new Count($count); + } + + /** + * Fails a test with the given message. + * + * @throws AssertionFailedError + * + * @psalm-return never-return + */ + public static function fail(string $message = ''): void + { + self::$count++; + + throw new AssertionFailedError($message); + } + + /** + * Returns the value of an attribute of a class or an object. + * This also works for attributes that are declared protected or private. + * + * @param object|string $classOrObject + * + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function readAttribute($classOrObject, string $attributeName) + { + self::createWarning('readAttribute() is deprecated and will be removed in PHPUnit 9.'); + + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(2, 'valid attribute name'); + } + + if (\is_string($classOrObject)) { + if (!\class_exists($classOrObject)) { + throw InvalidArgumentException::create( + 1, + 'class name' + ); + } + + return static::getStaticAttribute( + $classOrObject, + $attributeName + ); + } + + if (\is_object($classOrObject)) { + return static::getObjectAttribute( + $classOrObject, + $attributeName + ); + } + + throw InvalidArgumentException::create( + 1, + 'class name or object' + ); + } + + /** + * Returns the value of a static attribute. + * This also works for attributes that are declared protected or private. + * + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function getStaticAttribute(string $className, string $attributeName) + { + self::createWarning('getStaticAttribute() is deprecated and will be removed in PHPUnit 9.'); + + if (!\class_exists($className)) { + throw InvalidArgumentException::create(1, 'class name'); + } + + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(2, 'valid attribute name'); + } + + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + while ($class) { + $attributes = $class->getStaticProperties(); + + if (\array_key_exists($attributeName, $attributes)) { + return $attributes[$attributeName]; + } + + $class = $class->getParentClass(); + } + + throw new Exception( + \sprintf( + 'Attribute "%s" not found in class.', + $attributeName + ) + ); + } + + /** + * Returns the value of an object's attribute. + * This also works for attributes that are declared protected or private. + * + * @param object $object + * + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ + public static function getObjectAttribute($object, string $attributeName) + { + self::createWarning('getObjectAttribute() is deprecated and will be removed in PHPUnit 9.'); + + if (!\is_object($object)) { + throw InvalidArgumentException::create(1, 'object'); + } + + if (!self::isValidClassAttributeName($attributeName)) { + throw InvalidArgumentException::create(2, 'valid attribute name'); + } + + $reflector = new ReflectionObject($object); + + do { + try { + $attribute = $reflector->getProperty($attributeName); + + if (!$attribute || $attribute->isPublic()) { + return $object->$attributeName; + } + + $attribute->setAccessible(true); + $value = $attribute->getValue($object); + $attribute->setAccessible(false); + + return $value; + } catch (\ReflectionException $e) { + } + } while ($reflector = $reflector->getParentClass()); + + throw new Exception( + \sprintf( + 'Attribute "%s" not found in object.', + $attributeName + ) + ); + } + + /** + * Mark the test as incomplete. + * + * @throws IncompleteTestError + * + * @psalm-return never-return + */ + public static function markTestIncomplete(string $message = ''): void + { + throw new IncompleteTestError($message); + } + + /** + * Mark the test as skipped. + * + * @throws SkippedTestError + * @throws SyntheticSkippedError + * + * @psalm-return never-return + */ + public static function markTestSkipped(string $message = ''): void + { + if ($hint = self::detectLocationHint($message)) { + $trace = \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS); + \array_unshift($trace, $hint); + + throw new SyntheticSkippedError($hint['message'], 0, $hint['file'], (int) $hint['line'], $trace); + } + + throw new SkippedTestError($message); + } + + /** + * Return the current assertion count. + */ + public static function getCount(): int + { + return self::$count; + } + + /** + * Reset the assertion counter. + */ + public static function resetCount(): void + { + self::$count = 0; + } + + private static function detectLocationHint(string $message): ?array + { + $hint = null; + $lines = \preg_split('/\r\n|\r|\n/', $message); + + while (\strpos($lines[0], '__OFFSET') !== false) { + $offset = \explode('=', \array_shift($lines)); + + if ($offset[0] === '__OFFSET_FILE') { + $hint['file'] = $offset[1]; + } + + if ($offset[0] === '__OFFSET_LINE') { + $hint['line'] = $offset[1]; + } + } + + if ($hint) { + $hint['message'] = \implode(\PHP_EOL, $lines); + } + + return $hint; + } + + private static function isValidObjectAttributeName(string $attributeName): bool + { + return (bool) \preg_match('/[^\x00-\x1f\x7f-\x9f]+/', $attributeName); + } + + private static function isValidClassAttributeName(string $attributeName): bool + { + return (bool) \preg_match('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/', $attributeName); + } + + /** + * @codeCoverageIgnore + */ + private static function createWarning(string $warning): void + { + foreach (\debug_backtrace() as $step) { + if (isset($step['object']) && $step['object'] instanceof TestCase) { + \assert($step['object'] instanceof TestCase); + + $step['object']->addWarning($warning); + + break; + } + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php new file mode 100644 index 0000000..0eb101a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Assert/Functions.php @@ -0,0 +1,2597 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Constraint\ArrayHasKey; +use PHPUnit\Framework\Constraint\Attribute; +use PHPUnit\Framework\Constraint\Callback; +use PHPUnit\Framework\Constraint\ClassHasAttribute; +use PHPUnit\Framework\Constraint\ClassHasStaticAttribute; +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\Constraint\Count; +use PHPUnit\Framework\Constraint\DirectoryExists; +use PHPUnit\Framework\Constraint\FileExists; +use PHPUnit\Framework\Constraint\GreaterThan; +use PHPUnit\Framework\Constraint\IsAnything; +use PHPUnit\Framework\Constraint\IsEmpty; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\Constraint\IsFalse; +use PHPUnit\Framework\Constraint\IsFinite; +use PHPUnit\Framework\Constraint\IsIdentical; +use PHPUnit\Framework\Constraint\IsInfinite; +use PHPUnit\Framework\Constraint\IsInstanceOf; +use PHPUnit\Framework\Constraint\IsJson; +use PHPUnit\Framework\Constraint\IsNan; +use PHPUnit\Framework\Constraint\IsNull; +use PHPUnit\Framework\Constraint\IsReadable; +use PHPUnit\Framework\Constraint\IsTrue; +use PHPUnit\Framework\Constraint\IsType; +use PHPUnit\Framework\Constraint\IsWritable; +use PHPUnit\Framework\Constraint\LessThan; +use PHPUnit\Framework\Constraint\LogicalAnd; +use PHPUnit\Framework\Constraint\LogicalNot; +use PHPUnit\Framework\Constraint\LogicalOr; +use PHPUnit\Framework\Constraint\LogicalXor; +use PHPUnit\Framework\Constraint\ObjectHasAttribute; +use PHPUnit\Framework\Constraint\RegularExpression; +use PHPUnit\Framework\Constraint\StringContains; +use PHPUnit\Framework\Constraint\StringEndsWith; +use PHPUnit\Framework\Constraint\StringMatchesFormatDescription; +use PHPUnit\Framework\Constraint\StringStartsWith; +use PHPUnit\Framework\Constraint\TraversableContains; +use PHPUnit\Framework\Constraint\TraversableContainsEqual; +use PHPUnit\Framework\Constraint\TraversableContainsIdentical; +use PHPUnit\Framework\Constraint\TraversableContainsOnly; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtIndex as InvokedAtIndexMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher; +use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub; +use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub; +use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub; +use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub; +use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub; +use PHPUnit\Framework\MockObject\Stub\ReturnStub; +use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub; + +/** + * Asserts that an array has a specified key. + * + * @param int|string $key + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertArrayHasKey + */ +function assertArrayHasKey($key, $array, string $message = ''): void +{ + Assert::assertArrayHasKey(...\func_get_args()); +} + +/** + * Asserts that an array has a specified subset. + * + * @param array|ArrayAccess $subset + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @codeCoverageIgnore + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3494 + * @see Assert::assertArraySubset + */ +function assertArraySubset($subset, $array, bool $checkForObjectIdentity = false, string $message = ''): void +{ + Assert::assertArraySubset(...\func_get_args()); +} + +/** + * Asserts that an array does not have a specified key. + * + * @param int|string $key + * @param array|ArrayAccess $array + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertArrayNotHasKey + */ +function assertArrayNotHasKey($key, $array, string $message = ''): void +{ + Assert::assertArrayNotHasKey(...\func_get_args()); +} + +/** + * Asserts that a haystack contains a needle. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertContains + */ +function assertContains($needle, $haystack, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void +{ + Assert::assertContains(...\func_get_args()); +} + +function assertContainsEquals($needle, iterable $haystack, string $message = ''): void +{ + Assert::assertContainsEquals(...\func_get_args()); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains a needle. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeContains + */ +function assertAttributeContains($needle, string $haystackAttributeName, $haystackClassOrObject, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void +{ + Assert::assertAttributeContains(...\func_get_args()); +} + +/** + * Asserts that a haystack does not contain a needle. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertNotContains + */ +function assertNotContains($needle, $haystack, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void +{ + Assert::assertNotContains(...\func_get_args()); +} + +function assertNotContainsEquals($needle, iterable $haystack, string $message = ''): void +{ + Assert::assertNotContainsEquals(...\func_get_args()); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain a needle. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotContains + */ +function assertAttributeNotContains($needle, string $haystackAttributeName, $haystackClassOrObject, string $message = '', bool $ignoreCase = false, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): void +{ + Assert::assertAttributeNotContains(...\func_get_args()); +} + +/** + * Asserts that a haystack contains only values of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertContainsOnly + */ +function assertContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void +{ + Assert::assertContainsOnly(...\func_get_args()); +} + +/** + * Asserts that a haystack contains only instances of a given class name. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertContainsOnlyInstancesOf + */ +function assertContainsOnlyInstancesOf(string $className, iterable $haystack, string $message = ''): void +{ + Assert::assertContainsOnlyInstancesOf(...\func_get_args()); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object contains only values of a given type. + * + * @param object|string $haystackClassOrObject + * @param bool $isNativeType + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeContainsOnly + */ +function assertAttributeContainsOnly(string $type, string $haystackAttributeName, $haystackClassOrObject, ?bool $isNativeType = null, string $message = ''): void +{ + Assert::assertAttributeContainsOnly(...\func_get_args()); +} + +/** + * Asserts that a haystack does not contain only values of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotContainsOnly + */ +function assertNotContainsOnly(string $type, iterable $haystack, ?bool $isNativeType = null, string $message = ''): void +{ + Assert::assertNotContainsOnly(...\func_get_args()); +} + +/** + * Asserts that a haystack that is stored in a static attribute of a class + * or an attribute of an object does not contain only values of a given + * type. + * + * @param object|string $haystackClassOrObject + * @param bool $isNativeType + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotContainsOnly + */ +function assertAttributeNotContainsOnly(string $type, string $haystackAttributeName, $haystackClassOrObject, ?bool $isNativeType = null, string $message = ''): void +{ + Assert::assertAttributeNotContainsOnly(...\func_get_args()); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param Countable|iterable $haystack + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertCount + */ +function assertCount(int $expectedCount, $haystack, string $message = ''): void +{ + Assert::assertCount(...\func_get_args()); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeCount + */ +function assertAttributeCount(int $expectedCount, string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void +{ + Assert::assertAttributeCount(...\func_get_args()); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable. + * + * @param Countable|iterable $haystack + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertNotCount + */ +function assertNotCount(int $expectedCount, $haystack, string $message = ''): void +{ + Assert::assertNotCount(...\func_get_args()); +} + +/** + * Asserts the number of elements of an array, Countable or Traversable + * that is stored in an attribute. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotCount + */ +function assertAttributeNotCount(int $expectedCount, string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void +{ + Assert::assertAttributeNotCount(...\func_get_args()); +} + +/** + * Asserts that two variables are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertEquals + */ +function assertEquals($expected, $actual, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertEquals(...\func_get_args()); +} + +/** + * Asserts that two variables are equal (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertEqualsCanonicalizing + */ +function assertEqualsCanonicalizing($expected, $actual, string $message = ''): void +{ + Assert::assertEqualsCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that two variables are equal (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertEqualsIgnoringCase + */ +function assertEqualsIgnoringCase($expected, $actual, string $message = ''): void +{ + Assert::assertEqualsIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that two variables are equal (with delta). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertEqualsWithDelta + */ +function assertEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void +{ + Assert::assertEqualsWithDelta(...\func_get_args()); +} + +/** + * Asserts that a variable is equal to an attribute of an object. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeEquals + */ +function assertAttributeEquals($expected, string $actualAttributeName, $actualClassOrObject, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertAttributeEquals(...\func_get_args()); +} + +/** + * Asserts that two variables are not equal. + * + * @param float $delta + * @param int $maxDepth + * @param bool $canonicalize + * @param bool $ignoreCase + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotEquals + */ +function assertNotEquals($expected, $actual, string $message = '', $delta = 0.0, $maxDepth = 10, $canonicalize = false, $ignoreCase = false): void +{ + Assert::assertNotEquals(...\func_get_args()); +} + +/** + * Asserts that two variables are not equal (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotEqualsCanonicalizing + */ +function assertNotEqualsCanonicalizing($expected, $actual, string $message = ''): void +{ + Assert::assertNotEqualsCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that two variables are not equal (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotEqualsIgnoringCase + */ +function assertNotEqualsIgnoringCase($expected, $actual, string $message = ''): void +{ + Assert::assertNotEqualsIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that two variables are not equal (with delta). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotEqualsWithDelta + */ +function assertNotEqualsWithDelta($expected, $actual, float $delta, string $message = ''): void +{ + Assert::assertNotEqualsWithDelta(...\func_get_args()); +} + +/** + * Asserts that a variable is not equal to an attribute of an object. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotEquals + */ +function assertAttributeNotEquals($expected, string $actualAttributeName, $actualClassOrObject, string $message = '', float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertAttributeNotEquals(...\func_get_args()); +} + +/** + * Asserts that a variable is empty. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert empty $actual + * + * @see Assert::assertEmpty + */ +function assertEmpty($actual, string $message = ''): void +{ + Assert::assertEmpty(...\func_get_args()); +} + +/** + * Asserts that a static attribute of a class or an attribute of an object + * is empty. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeEmpty + */ +function assertAttributeEmpty(string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void +{ + Assert::assertAttributeEmpty(...\func_get_args()); +} + +/** + * Asserts that a variable is not empty. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !empty $actual + * + * @see Assert::assertNotEmpty + */ +function assertNotEmpty($actual, string $message = ''): void +{ + Assert::assertNotEmpty(...\func_get_args()); +} + +/** + * Asserts that a static attribute of a class or an attribute of an object + * is not empty. + * + * @param object|string $haystackClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotEmpty + */ +function assertAttributeNotEmpty(string $haystackAttributeName, $haystackClassOrObject, string $message = ''): void +{ + Assert::assertAttributeNotEmpty(...\func_get_args()); +} + +/** + * Asserts that a value is greater than another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertGreaterThan + */ +function assertGreaterThan($expected, $actual, string $message = ''): void +{ + Assert::assertGreaterThan(...\func_get_args()); +} + +/** + * Asserts that an attribute is greater than another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeGreaterThan + */ +function assertAttributeGreaterThan($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeGreaterThan(...\func_get_args()); +} + +/** + * Asserts that a value is greater than or equal to another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertGreaterThanOrEqual + */ +function assertGreaterThanOrEqual($expected, $actual, string $message = ''): void +{ + Assert::assertGreaterThanOrEqual(...\func_get_args()); +} + +/** + * Asserts that an attribute is greater than or equal to another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeGreaterThanOrEqual + */ +function assertAttributeGreaterThanOrEqual($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeGreaterThanOrEqual(...\func_get_args()); +} + +/** + * Asserts that a value is smaller than another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertLessThan + */ +function assertLessThan($expected, $actual, string $message = ''): void +{ + Assert::assertLessThan(...\func_get_args()); +} + +/** + * Asserts that an attribute is smaller than another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeLessThan + */ +function assertAttributeLessThan($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeLessThan(...\func_get_args()); +} + +/** + * Asserts that a value is smaller than or equal to another value. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertLessThanOrEqual + */ +function assertLessThanOrEqual($expected, $actual, string $message = ''): void +{ + Assert::assertLessThanOrEqual(...\func_get_args()); +} + +/** + * Asserts that an attribute is smaller than or equal to another value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeLessThanOrEqual + */ +function assertAttributeLessThanOrEqual($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeLessThanOrEqual(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is equal to the contents of another + * file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileEquals + */ +function assertFileEquals(string $expected, string $actual, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertFileEquals(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is equal to the contents of another + * file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileEqualsCanonicalizing + */ +function assertFileEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void +{ + Assert::assertFileEqualsCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is equal to the contents of another + * file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileEqualsIgnoringCase + */ +function assertFileEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void +{ + Assert::assertFileEqualsIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is not equal to the contents of + * another file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotEquals + */ +function assertFileNotEquals(string $expected, string $actual, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertFileNotEquals(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is not equal to the contents of another + * file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotEqualsCanonicalizing + */ +function assertFileNotEqualsCanonicalizing(string $expected, string $actual, string $message = ''): void +{ + Assert::assertFileNotEqualsCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that the contents of one file is not equal to the contents of another + * file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotEqualsIgnoringCase + */ +function assertFileNotEqualsIgnoringCase(string $expected, string $actual, string $message = ''): void +{ + Assert::assertFileNotEqualsIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is equal + * to the contents of a file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringEqualsFile + */ +function assertStringEqualsFile(string $expectedFile, string $actualString, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertStringEqualsFile(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is equal + * to the contents of a file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringEqualsFileCanonicalizing + */ +function assertStringEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void +{ + Assert::assertStringEqualsFileCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is equal + * to the contents of a file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringEqualsFileIgnoringCase + */ +function assertStringEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void +{ + Assert::assertStringEqualsFileIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is not equal + * to the contents of a file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotEqualsFile + */ +function assertStringNotEqualsFile(string $expectedFile, string $actualString, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void +{ + Assert::assertStringNotEqualsFile(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is not equal + * to the contents of a file (canonicalizing). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotEqualsFileCanonicalizing + */ +function assertStringNotEqualsFileCanonicalizing(string $expectedFile, string $actualString, string $message = ''): void +{ + Assert::assertStringNotEqualsFileCanonicalizing(...\func_get_args()); +} + +/** + * Asserts that the contents of a string is not equal + * to the contents of a file (ignoring case). + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotEqualsFileIgnoringCase + */ +function assertStringNotEqualsFileIgnoringCase(string $expectedFile, string $actualString, string $message = ''): void +{ + Assert::assertStringNotEqualsFileIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that a file/dir is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertIsReadable + */ +function assertIsReadable(string $filename, string $message = ''): void +{ + Assert::assertIsReadable(...\func_get_args()); +} + +/** + * Asserts that a file/dir exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotIsReadable + */ +function assertNotIsReadable(string $filename, string $message = ''): void +{ + Assert::assertNotIsReadable(...\func_get_args()); +} + +/** + * Asserts that a file/dir exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertIsWritable + */ +function assertIsWritable(string $filename, string $message = ''): void +{ + Assert::assertIsWritable(...\func_get_args()); +} + +/** + * Asserts that a file/dir exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotIsWritable + */ +function assertNotIsWritable(string $filename, string $message = ''): void +{ + Assert::assertNotIsWritable(...\func_get_args()); +} + +/** + * Asserts that a directory exists. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryExists + */ +function assertDirectoryExists(string $directory, string $message = ''): void +{ + Assert::assertDirectoryExists(...\func_get_args()); +} + +/** + * Asserts that a directory does not exist. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryNotExists + */ +function assertDirectoryNotExists(string $directory, string $message = ''): void +{ + Assert::assertDirectoryNotExists(...\func_get_args()); +} + +/** + * Asserts that a directory exists and is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryIsReadable + */ +function assertDirectoryIsReadable(string $directory, string $message = ''): void +{ + Assert::assertDirectoryIsReadable(...\func_get_args()); +} + +/** + * Asserts that a directory exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryNotIsReadable + */ +function assertDirectoryNotIsReadable(string $directory, string $message = ''): void +{ + Assert::assertDirectoryNotIsReadable(...\func_get_args()); +} + +/** + * Asserts that a directory exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryIsWritable + */ +function assertDirectoryIsWritable(string $directory, string $message = ''): void +{ + Assert::assertDirectoryIsWritable(...\func_get_args()); +} + +/** + * Asserts that a directory exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertDirectoryNotIsWritable + */ +function assertDirectoryNotIsWritable(string $directory, string $message = ''): void +{ + Assert::assertDirectoryNotIsWritable(...\func_get_args()); +} + +/** + * Asserts that a file exists. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileExists + */ +function assertFileExists(string $filename, string $message = ''): void +{ + Assert::assertFileExists(...\func_get_args()); +} + +/** + * Asserts that a file does not exist. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotExists + */ +function assertFileNotExists(string $filename, string $message = ''): void +{ + Assert::assertFileNotExists(...\func_get_args()); +} + +/** + * Asserts that a file exists and is readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileIsReadable + */ +function assertFileIsReadable(string $file, string $message = ''): void +{ + Assert::assertFileIsReadable(...\func_get_args()); +} + +/** + * Asserts that a file exists and is not readable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotIsReadable + */ +function assertFileNotIsReadable(string $file, string $message = ''): void +{ + Assert::assertFileNotIsReadable(...\func_get_args()); +} + +/** + * Asserts that a file exists and is writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileIsWritable + */ +function assertFileIsWritable(string $file, string $message = ''): void +{ + Assert::assertFileIsWritable(...\func_get_args()); +} + +/** + * Asserts that a file exists and is not writable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFileNotIsWritable + */ +function assertFileNotIsWritable(string $file, string $message = ''): void +{ + Assert::assertFileNotIsWritable(...\func_get_args()); +} + +/** + * Asserts that a condition is true. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert true $condition + * + * @see Assert::assertTrue + */ +function assertTrue($condition, string $message = ''): void +{ + Assert::assertTrue(...\func_get_args()); +} + +/** + * Asserts that a condition is not true. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !true $condition + * + * @see Assert::assertNotTrue + */ +function assertNotTrue($condition, string $message = ''): void +{ + Assert::assertNotTrue(...\func_get_args()); +} + +/** + * Asserts that a condition is false. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert false $condition + * + * @see Assert::assertFalse + */ +function assertFalse($condition, string $message = ''): void +{ + Assert::assertFalse(...\func_get_args()); +} + +/** + * Asserts that a condition is not false. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !false $condition + * + * @see Assert::assertNotFalse + */ +function assertNotFalse($condition, string $message = ''): void +{ + Assert::assertNotFalse(...\func_get_args()); +} + +/** + * Asserts that a variable is null. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert null $actual + * + * @see Assert::assertNull + */ +function assertNull($actual, string $message = ''): void +{ + Assert::assertNull(...\func_get_args()); +} + +/** + * Asserts that a variable is not null. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !null $actual + * + * @see Assert::assertNotNull + */ +function assertNotNull($actual, string $message = ''): void +{ + Assert::assertNotNull(...\func_get_args()); +} + +/** + * Asserts that a variable is finite. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertFinite + */ +function assertFinite($actual, string $message = ''): void +{ + Assert::assertFinite(...\func_get_args()); +} + +/** + * Asserts that a variable is infinite. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertInfinite + */ +function assertInfinite($actual, string $message = ''): void +{ + Assert::assertInfinite(...\func_get_args()); +} + +/** + * Asserts that a variable is nan. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNan + */ +function assertNan($actual, string $message = ''): void +{ + Assert::assertNan(...\func_get_args()); +} + +/** + * Asserts that a class has a specified attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertClassHasAttribute + */ +function assertClassHasAttribute(string $attributeName, string $className, string $message = ''): void +{ + Assert::assertClassHasAttribute(...\func_get_args()); +} + +/** + * Asserts that a class does not have a specified attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertClassNotHasAttribute + */ +function assertClassNotHasAttribute(string $attributeName, string $className, string $message = ''): void +{ + Assert::assertClassNotHasAttribute(...\func_get_args()); +} + +/** + * Asserts that a class has a specified static attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertClassHasStaticAttribute + */ +function assertClassHasStaticAttribute(string $attributeName, string $className, string $message = ''): void +{ + Assert::assertClassHasStaticAttribute(...\func_get_args()); +} + +/** + * Asserts that a class does not have a specified static attribute. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertClassNotHasStaticAttribute + */ +function assertClassNotHasStaticAttribute(string $attributeName, string $className, string $message = ''): void +{ + Assert::assertClassNotHasStaticAttribute(...\func_get_args()); +} + +/** + * Asserts that an object has a specified attribute. + * + * @param object $object + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertObjectHasAttribute + */ +function assertObjectHasAttribute(string $attributeName, $object, string $message = ''): void +{ + Assert::assertObjectHasAttribute(...\func_get_args()); +} + +/** + * Asserts that an object does not have a specified attribute. + * + * @param object $object + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertObjectNotHasAttribute + */ +function assertObjectNotHasAttribute(string $attributeName, $object, string $message = ''): void +{ + Assert::assertObjectNotHasAttribute(...\func_get_args()); +} + +/** + * Asserts that two variables have the same type and value. + * Used on objects, it asserts that two variables reference + * the same object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-template ExpectedType + * @psalm-param ExpectedType $expected + * @psalm-assert =ExpectedType $actual + * + * @see Assert::assertSame + */ +function assertSame($expected, $actual, string $message = ''): void +{ + Assert::assertSame(...\func_get_args()); +} + +/** + * Asserts that a variable and an attribute of an object have the same type + * and value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeSame + */ +function assertAttributeSame($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeSame(...\func_get_args()); +} + +/** + * Asserts that two variables do not have the same type and value. + * Used on objects, it asserts that two variables do not reference + * the same object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotSame + */ +function assertNotSame($expected, $actual, string $message = ''): void +{ + Assert::assertNotSame(...\func_get_args()); +} + +/** + * Asserts that a variable and an attribute of an object do not have the + * same type and value. + * + * @param object|string $actualClassOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotSame + */ +function assertAttributeNotSame($expected, string $actualAttributeName, $actualClassOrObject, string $message = ''): void +{ + Assert::assertAttributeNotSame(...\func_get_args()); +} + +/** + * Asserts that a variable is of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @psalm-template ExpectedType of object + * @psalm-param class-string $expected + * @psalm-assert ExpectedType $actual + * + * @see Assert::assertInstanceOf + */ +function assertInstanceOf(string $expected, $actual, string $message = ''): void +{ + Assert::assertInstanceOf(...\func_get_args()); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @psalm-param class-string $expected + * + * @see Assert::assertAttributeInstanceOf + */ +function assertAttributeInstanceOf(string $expected, string $attributeName, $classOrObject, string $message = ''): void +{ + Assert::assertAttributeInstanceOf(...\func_get_args()); +} + +/** + * Asserts that a variable is not of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @psalm-template ExpectedType of object + * @psalm-param class-string $expected + * @psalm-assert !ExpectedType $actual + * + * @see Assert::assertNotInstanceOf + */ +function assertNotInstanceOf(string $expected, $actual, string $message = ''): void +{ + Assert::assertNotInstanceOf(...\func_get_args()); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @psalm-param class-string $expected + * + * @see Assert::assertAttributeNotInstanceOf + */ +function assertAttributeNotInstanceOf(string $expected, string $attributeName, $classOrObject, string $message = ''): void +{ + Assert::assertAttributeNotInstanceOf(...\func_get_args()); +} + +/** + * Asserts that a variable is of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3369 + * @codeCoverageIgnore + * + * @see Assert::assertInternalType + */ +function assertInternalType(string $expected, $actual, string $message = ''): void +{ + Assert::assertInternalType(...\func_get_args()); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeInternalType + */ +function assertAttributeInternalType(string $expected, string $attributeName, $classOrObject, string $message = ''): void +{ + Assert::assertAttributeInternalType(...\func_get_args()); +} + +/** + * Asserts that a variable is of type array. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert array $actual + * + * @see Assert::assertIsArray + */ +function assertIsArray($actual, string $message = ''): void +{ + Assert::assertIsArray(...\func_get_args()); +} + +/** + * Asserts that a variable is of type bool. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert bool $actual + * + * @see Assert::assertIsBool + */ +function assertIsBool($actual, string $message = ''): void +{ + Assert::assertIsBool(...\func_get_args()); +} + +/** + * Asserts that a variable is of type float. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert float $actual + * + * @see Assert::assertIsFloat + */ +function assertIsFloat($actual, string $message = ''): void +{ + Assert::assertIsFloat(...\func_get_args()); +} + +/** + * Asserts that a variable is of type int. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert int $actual + * + * @see Assert::assertIsInt + */ +function assertIsInt($actual, string $message = ''): void +{ + Assert::assertIsInt(...\func_get_args()); +} + +/** + * Asserts that a variable is of type numeric. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert numeric $actual + * + * @see Assert::assertIsNumeric + */ +function assertIsNumeric($actual, string $message = ''): void +{ + Assert::assertIsNumeric(...\func_get_args()); +} + +/** + * Asserts that a variable is of type object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert object $actual + * + * @see Assert::assertIsObject + */ +function assertIsObject($actual, string $message = ''): void +{ + Assert::assertIsObject(...\func_get_args()); +} + +/** + * Asserts that a variable is of type resource. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert resource $actual + * + * @see Assert::assertIsResource + */ +function assertIsResource($actual, string $message = ''): void +{ + Assert::assertIsResource(...\func_get_args()); +} + +/** + * Asserts that a variable is of type string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert string $actual + * + * @see Assert::assertIsString + */ +function assertIsString($actual, string $message = ''): void +{ + Assert::assertIsString(...\func_get_args()); +} + +/** + * Asserts that a variable is of type scalar. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert scalar $actual + * + * @see Assert::assertIsScalar + */ +function assertIsScalar($actual, string $message = ''): void +{ + Assert::assertIsScalar(...\func_get_args()); +} + +/** + * Asserts that a variable is of type callable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert callable $actual + * + * @see Assert::assertIsCallable + */ +function assertIsCallable($actual, string $message = ''): void +{ + Assert::assertIsCallable(...\func_get_args()); +} + +/** + * Asserts that a variable is of type iterable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert iterable $actual + * + * @see Assert::assertIsIterable + */ +function assertIsIterable($actual, string $message = ''): void +{ + Assert::assertIsIterable(...\func_get_args()); +} + +/** + * Asserts that a variable is not of a given type. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3369 + * @codeCoverageIgnore + * + * @see Assert::assertNotInternalType + */ +function assertNotInternalType(string $expected, $actual, string $message = ''): void +{ + Assert::assertNotInternalType(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type array. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !array $actual + * + * @see Assert::assertIsNotArray + */ +function assertIsNotArray($actual, string $message = ''): void +{ + Assert::assertIsNotArray(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type bool. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !bool $actual + * + * @see Assert::assertIsNotBool + */ +function assertIsNotBool($actual, string $message = ''): void +{ + Assert::assertIsNotBool(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type float. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !float $actual + * + * @see Assert::assertIsNotFloat + */ +function assertIsNotFloat($actual, string $message = ''): void +{ + Assert::assertIsNotFloat(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type int. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !int $actual + * + * @see Assert::assertIsNotInt + */ +function assertIsNotInt($actual, string $message = ''): void +{ + Assert::assertIsNotInt(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type numeric. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !numeric $actual + * + * @see Assert::assertIsNotNumeric + */ +function assertIsNotNumeric($actual, string $message = ''): void +{ + Assert::assertIsNotNumeric(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !object $actual + * + * @see Assert::assertIsNotObject + */ +function assertIsNotObject($actual, string $message = ''): void +{ + Assert::assertIsNotObject(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type resource. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !resource $actual + * + * @see Assert::assertIsNotResource + */ +function assertIsNotResource($actual, string $message = ''): void +{ + Assert::assertIsNotResource(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !string $actual + * + * @see Assert::assertIsNotString + */ +function assertIsNotString($actual, string $message = ''): void +{ + Assert::assertIsNotString(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type scalar. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !scalar $actual + * + * @see Assert::assertIsNotScalar + */ +function assertIsNotScalar($actual, string $message = ''): void +{ + Assert::assertIsNotScalar(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type callable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !callable $actual + * + * @see Assert::assertIsNotCallable + */ +function assertIsNotCallable($actual, string $message = ''): void +{ + Assert::assertIsNotCallable(...\func_get_args()); +} + +/** + * Asserts that a variable is not of type iterable. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-assert !iterable $actual + * + * @see Assert::assertIsNotIterable + */ +function assertIsNotIterable($actual, string $message = ''): void +{ + Assert::assertIsNotIterable(...\func_get_args()); +} + +/** + * Asserts that an attribute is of a given type. + * + * @param object|string $classOrObject + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + * + * @see Assert::assertAttributeNotInternalType + */ +function assertAttributeNotInternalType(string $expected, string $attributeName, $classOrObject, string $message = ''): void +{ + Assert::assertAttributeNotInternalType(...\func_get_args()); +} + +/** + * Asserts that a string matches a given regular expression. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertRegExp + */ +function assertRegExp(string $pattern, string $string, string $message = ''): void +{ + Assert::assertRegExp(...\func_get_args()); +} + +/** + * Asserts that a string does not match a given regular expression. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertNotRegExp + */ +function assertNotRegExp(string $pattern, string $string, string $message = ''): void +{ + Assert::assertNotRegExp(...\func_get_args()); +} + +/** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is the same. + * + * @param Countable|iterable $expected + * @param Countable|iterable $actual + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertSameSize + */ +function assertSameSize($expected, $actual, string $message = ''): void +{ + Assert::assertSameSize(...\func_get_args()); +} + +/** + * Assert that the size of two arrays (or `Countable` or `Traversable` objects) + * is not the same. + * + * @param Countable|iterable $expected + * @param Countable|iterable $actual + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertNotSameSize + */ +function assertNotSameSize($expected, $actual, string $message = ''): void +{ + Assert::assertNotSameSize(...\func_get_args()); +} + +/** + * Asserts that a string matches a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringMatchesFormat + */ +function assertStringMatchesFormat(string $format, string $string, string $message = ''): void +{ + Assert::assertStringMatchesFormat(...\func_get_args()); +} + +/** + * Asserts that a string does not match a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotMatchesFormat + */ +function assertStringNotMatchesFormat(string $format, string $string, string $message = ''): void +{ + Assert::assertStringNotMatchesFormat(...\func_get_args()); +} + +/** + * Asserts that a string matches a given format file. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringMatchesFormatFile + */ +function assertStringMatchesFormatFile(string $formatFile, string $string, string $message = ''): void +{ + Assert::assertStringMatchesFormatFile(...\func_get_args()); +} + +/** + * Asserts that a string does not match a given format string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotMatchesFormatFile + */ +function assertStringNotMatchesFormatFile(string $formatFile, string $string, string $message = ''): void +{ + Assert::assertStringNotMatchesFormatFile(...\func_get_args()); +} + +/** + * Asserts that a string starts with a given prefix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringStartsWith + */ +function assertStringStartsWith(string $prefix, string $string, string $message = ''): void +{ + Assert::assertStringStartsWith(...\func_get_args()); +} + +/** + * Asserts that a string starts not with a given prefix. + * + * @param string $prefix + * @param string $string + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringStartsNotWith + */ +function assertStringStartsNotWith($prefix, $string, string $message = ''): void +{ + Assert::assertStringStartsNotWith(...\func_get_args()); +} + +/** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringContainsString + */ +function assertStringContainsString(string $needle, string $haystack, string $message = ''): void +{ + Assert::assertStringContainsString(...\func_get_args()); +} + +/** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringContainsStringIgnoringCase + */ +function assertStringContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void +{ + Assert::assertStringContainsStringIgnoringCase(...\func_get_args()); +} + +/** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotContainsString + */ +function assertStringNotContainsString(string $needle, string $haystack, string $message = ''): void +{ + Assert::assertStringNotContainsString(...\func_get_args()); +} + +/** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringNotContainsStringIgnoringCase + */ +function assertStringNotContainsStringIgnoringCase(string $needle, string $haystack, string $message = ''): void +{ + Assert::assertStringNotContainsStringIgnoringCase(...\func_get_args()); +} + +/** + * Asserts that a string ends with a given suffix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringEndsWith + */ +function assertStringEndsWith(string $suffix, string $string, string $message = ''): void +{ + Assert::assertStringEndsWith(...\func_get_args()); +} + +/** + * Asserts that a string ends not with a given suffix. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertStringEndsNotWith + */ +function assertStringEndsNotWith(string $suffix, string $string, string $message = ''): void +{ + Assert::assertStringEndsNotWith(...\func_get_args()); +} + +/** + * Asserts that two XML files are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlFileEqualsXmlFile + */ +function assertXmlFileEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void +{ + Assert::assertXmlFileEqualsXmlFile(...\func_get_args()); +} + +/** + * Asserts that two XML files are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlFileNotEqualsXmlFile + */ +function assertXmlFileNotEqualsXmlFile(string $expectedFile, string $actualFile, string $message = ''): void +{ + Assert::assertXmlFileNotEqualsXmlFile(...\func_get_args()); +} + +/** + * Asserts that two XML documents are equal. + * + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlStringEqualsXmlFile + */ +function assertXmlStringEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void +{ + Assert::assertXmlStringEqualsXmlFile(...\func_get_args()); +} + +/** + * Asserts that two XML documents are not equal. + * + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlStringNotEqualsXmlFile + */ +function assertXmlStringNotEqualsXmlFile(string $expectedFile, $actualXml, string $message = ''): void +{ + Assert::assertXmlStringNotEqualsXmlFile(...\func_get_args()); +} + +/** + * Asserts that two XML documents are equal. + * + * @param DOMDocument|string $expectedXml + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlStringEqualsXmlString + */ +function assertXmlStringEqualsXmlString($expectedXml, $actualXml, string $message = ''): void +{ + Assert::assertXmlStringEqualsXmlString(...\func_get_args()); +} + +/** + * Asserts that two XML documents are not equal. + * + * @param DOMDocument|string $expectedXml + * @param DOMDocument|string $actualXml + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + * + * @see Assert::assertXmlStringNotEqualsXmlString + */ +function assertXmlStringNotEqualsXmlString($expectedXml, $actualXml, string $message = ''): void +{ + Assert::assertXmlStringNotEqualsXmlString(...\func_get_args()); +} + +/** + * Asserts that a hierarchy of DOMElements matches. + * + * @throws AssertionFailedError + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertEqualXMLStructure + */ +function assertEqualXMLStructure(DOMElement $expectedElement, DOMElement $actualElement, bool $checkAttributes = false, string $message = ''): void +{ + Assert::assertEqualXMLStructure(...\func_get_args()); +} + +/** + * Evaluates a PHPUnit\Framework\Constraint matcher object. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertThat + */ +function assertThat($value, Constraint $constraint, string $message = ''): void +{ + Assert::assertThat(...\func_get_args()); +} + +/** + * Asserts that a string is a valid JSON string. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJson + */ +function assertJson(string $actualJson, string $message = ''): void +{ + Assert::assertJson(...\func_get_args()); +} + +/** + * Asserts that two given JSON encoded objects or arrays are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonStringEqualsJsonString + */ +function assertJsonStringEqualsJsonString(string $expectedJson, string $actualJson, string $message = ''): void +{ + Assert::assertJsonStringEqualsJsonString(...\func_get_args()); +} + +/** + * Asserts that two given JSON encoded objects or arrays are not equal. + * + * @param string $expectedJson + * @param string $actualJson + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonStringNotEqualsJsonString + */ +function assertJsonStringNotEqualsJsonString($expectedJson, $actualJson, string $message = ''): void +{ + Assert::assertJsonStringNotEqualsJsonString(...\func_get_args()); +} + +/** + * Asserts that the generated JSON encoded object and the content of the given file are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonStringEqualsJsonFile + */ +function assertJsonStringEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void +{ + Assert::assertJsonStringEqualsJsonFile(...\func_get_args()); +} + +/** + * Asserts that the generated JSON encoded object and the content of the given file are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonStringNotEqualsJsonFile + */ +function assertJsonStringNotEqualsJsonFile(string $expectedFile, string $actualJson, string $message = ''): void +{ + Assert::assertJsonStringNotEqualsJsonFile(...\func_get_args()); +} + +/** + * Asserts that two JSON files are equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonFileEqualsJsonFile + */ +function assertJsonFileEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void +{ + Assert::assertJsonFileEqualsJsonFile(...\func_get_args()); +} + +/** + * Asserts that two JSON files are not equal. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @see Assert::assertJsonFileNotEqualsJsonFile + */ +function assertJsonFileNotEqualsJsonFile(string $expectedFile, string $actualFile, string $message = ''): void +{ + Assert::assertJsonFileNotEqualsJsonFile(...\func_get_args()); +} + +function logicalAnd(): LogicalAnd +{ + return Assert::logicalAnd(...\func_get_args()); +} + +function logicalOr(): LogicalOr +{ + return Assert::logicalOr(...\func_get_args()); +} + +function logicalNot(Constraint $constraint): LogicalNot +{ + return Assert::logicalNot(...\func_get_args()); +} + +function logicalXor(): LogicalXor +{ + return Assert::logicalXor(...\func_get_args()); +} + +function anything(): IsAnything +{ + return Assert::anything(...\func_get_args()); +} + +function isTrue(): IsTrue +{ + return Assert::isTrue(...\func_get_args()); +} + +function callback(callable $callback): Callback +{ + return Assert::callback(...\func_get_args()); +} + +function isFalse(): IsFalse +{ + return Assert::isFalse(...\func_get_args()); +} + +function isJson(): IsJson +{ + return Assert::isJson(...\func_get_args()); +} + +function isNull(): IsNull +{ + return Assert::isNull(...\func_get_args()); +} + +function isFinite(): IsFinite +{ + return Assert::isFinite(...\func_get_args()); +} + +function isInfinite(): IsInfinite +{ + return Assert::isInfinite(...\func_get_args()); +} + +function isNan(): IsNan +{ + return Assert::isNan(...\func_get_args()); +} + +function attribute(Constraint $constraint, string $attributeName): Attribute +{ + return Assert::attribute(...\func_get_args()); +} + +function contains($value, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false): TraversableContains +{ + return Assert::contains(...\func_get_args()); +} + +function containsEqual($value): TraversableContainsEqual +{ + return Assert::containsEqual(...\func_get_args()); +} + +function containsIdentical($value): TraversableContainsIdentical +{ + return Assert::containsIdentical(...\func_get_args()); +} + +function containsOnly(string $type): TraversableContainsOnly +{ + return Assert::containsOnly(...\func_get_args()); +} + +function containsOnlyInstancesOf(string $className): TraversableContainsOnly +{ + return Assert::containsOnlyInstancesOf(...\func_get_args()); +} + +function arrayHasKey($key): ArrayHasKey +{ + return Assert::arrayHasKey(...\func_get_args()); +} + +function equalTo($value, float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): IsEqual +{ + return Assert::equalTo(...\func_get_args()); +} + +function attributeEqualTo(string $attributeName, $value, float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false): Attribute +{ + return Assert::attributeEqualTo(...\func_get_args()); +} + +function isEmpty(): IsEmpty +{ + return Assert::isEmpty(...\func_get_args()); +} + +function isWritable(): IsWritable +{ + return Assert::isWritable(...\func_get_args()); +} + +function isReadable(): IsReadable +{ + return Assert::isReadable(...\func_get_args()); +} + +function directoryExists(): DirectoryExists +{ + return Assert::directoryExists(...\func_get_args()); +} + +function fileExists(): FileExists +{ + return Assert::fileExists(...\func_get_args()); +} + +function greaterThan($value): GreaterThan +{ + return Assert::greaterThan(...\func_get_args()); +} + +function greaterThanOrEqual($value): LogicalOr +{ + return Assert::greaterThanOrEqual(...\func_get_args()); +} + +function classHasAttribute(string $attributeName): ClassHasAttribute +{ + return Assert::classHasAttribute(...\func_get_args()); +} + +function classHasStaticAttribute(string $attributeName): ClassHasStaticAttribute +{ + return Assert::classHasStaticAttribute(...\func_get_args()); +} + +function objectHasAttribute($attributeName): ObjectHasAttribute +{ + return Assert::objectHasAttribute(...\func_get_args()); +} + +function identicalTo($value): IsIdentical +{ + return Assert::identicalTo(...\func_get_args()); +} + +function isInstanceOf(string $className): IsInstanceOf +{ + return Assert::isInstanceOf(...\func_get_args()); +} + +function isType(string $type): IsType +{ + return Assert::isType(...\func_get_args()); +} + +function lessThan($value): LessThan +{ + return Assert::lessThan(...\func_get_args()); +} + +function lessThanOrEqual($value): LogicalOr +{ + return Assert::lessThanOrEqual(...\func_get_args()); +} + +function matchesRegularExpression(string $pattern): RegularExpression +{ + return Assert::matchesRegularExpression(...\func_get_args()); +} + +function matches(string $string): StringMatchesFormatDescription +{ + return Assert::matches(...\func_get_args()); +} + +function stringStartsWith($prefix): StringStartsWith +{ + return Assert::stringStartsWith(...\func_get_args()); +} + +function stringContains(string $string, bool $case = true): StringContains +{ + return Assert::stringContains(...\func_get_args()); +} + +function stringEndsWith(string $suffix): StringEndsWith +{ + return Assert::stringEndsWith(...\func_get_args()); +} + +function countOf(int $count): Count +{ + return Assert::countOf(...\func_get_args()); +} + +/** + * Returns a matcher that matches when the method is executed + * zero or more times. + */ +function any(): AnyInvokedCountMatcher +{ + return new AnyInvokedCountMatcher; +} + +/** + * Returns a matcher that matches when the method is never executed. + */ +function never(): InvokedCountMatcher +{ + return new InvokedCountMatcher(0); +} + +/** + * Returns a matcher that matches when the method is executed + * at least N times. + */ +function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher +{ + return new InvokedAtLeastCountMatcher( + $requiredInvocations + ); +} + +/** + * Returns a matcher that matches when the method is executed at least once. + */ +function atLeastOnce(): InvokedAtLeastOnceMatcher +{ + return new InvokedAtLeastOnceMatcher; +} + +/** + * Returns a matcher that matches when the method is executed exactly once. + */ +function once(): InvokedCountMatcher +{ + return new InvokedCountMatcher(1); +} + +/** + * Returns a matcher that matches when the method is executed + * exactly $count times. + */ +function exactly(int $count): InvokedCountMatcher +{ + return new InvokedCountMatcher($count); +} + +/** + * Returns a matcher that matches when the method is executed + * at most N times. + */ +function atMost(int $allowedInvocations): InvokedAtMostCountMatcher +{ + return new InvokedAtMostCountMatcher($allowedInvocations); +} + +/** + * Returns a matcher that matches when the method is executed + * at the given index. + */ +function at(int $index): InvokedAtIndexMatcher +{ + return new InvokedAtIndexMatcher($index); +} + +function returnValue($value): ReturnStub +{ + return new ReturnStub($value); +} + +function returnValueMap(array $valueMap): ReturnValueMapStub +{ + return new ReturnValueMapStub($valueMap); +} + +function returnArgument(int $argumentIndex): ReturnArgumentStub +{ + return new ReturnArgumentStub($argumentIndex); +} + +function returnCallback($callback): ReturnCallbackStub +{ + return new ReturnCallbackStub($callback); +} + +/** + * Returns the current object. + * + * This method is useful when mocking a fluent interface. + */ +function returnSelf(): ReturnSelfStub +{ + return new ReturnSelfStub; +} + +function throwException(Throwable $exception): ExceptionStub +{ + return new ExceptionStub($exception); +} + +function onConsecutiveCalls(): ConsecutiveCallsStub +{ + $args = \func_get_args(); + + return new ConsecutiveCallsStub($args); +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php new file mode 100644 index 0000000..eab5a49 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ArrayHasKey.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use ArrayAccess; + +/** + * Constraint that asserts that the array it is evaluated for has a given key. + * + * Uses array_key_exists() to check if the key is found in the input array, if + * not found the evaluation fails. + * + * The array key is passed in the constructor. + */ +final class ArrayHasKey extends Constraint +{ + /** + * @var int|string + */ + private $key; + + /** + * @param int|string $key + */ + public function __construct($key) + { + $this->key = $key; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return 'has the key ' . $this->exporter()->export($this->key); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if (\is_array($other)) { + return \array_key_exists($this->key, $other); + } + + if ($other instanceof ArrayAccess) { + return $other->offsetExists($this->key); + } + + return false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return 'an array ' . $this->toString(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php new file mode 100644 index 0000000..a60c261 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ArraySubset.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Constraint that asserts that the array it is evaluated for has a specified subset. + * + * Uses array_replace_recursive() to check if a key value subset is part of the + * subject array. + * + * @codeCoverageIgnore + * + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3494 + */ +final class ArraySubset extends Constraint +{ + /** + * @var iterable + */ + private $subset; + + /** + * @var bool + */ + private $strict; + + public function __construct(iterable $subset, bool $strict = false) + { + $this->strict = $strict; + $this->subset = $subset; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + //type cast $other & $this->subset as an array to allow + //support in standard array functions. + $other = $this->toArray($other); + $this->subset = $this->toArray($this->subset); + + $patched = \array_replace_recursive($other, $this->subset); + + if ($this->strict) { + $result = $other === $patched; + } else { + $result = $other == $patched; + } + + if ($returnResult) { + return $result; + } + + if (!$result) { + $f = new ComparisonFailure( + $patched, + $other, + \var_export($patched, true), + \var_export($other, true) + ); + + $this->fail($other, $description, $f); + } + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return 'has the subset ' . $this->exporter()->export($this->subset); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return 'an array ' . $this->toString(); + } + + private function toArray(iterable $other): array + { + if (\is_array($other)) { + return $other; + } + + if ($other instanceof \ArrayObject) { + return $other->getArrayCopy(); + } + + if ($other instanceof \Traversable) { + return \iterator_to_array($other); + } + + // Keep BC even if we know that array would not be the expected one + return (array) $other; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php new file mode 100644 index 0000000..36b0532 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Attribute.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\ExpectationFailedException; + +/** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ +final class Attribute extends Composite +{ + /** + * @var string + */ + private $attributeName; + + public function __construct(Constraint $constraint, string $attributeName) + { + parent::__construct($constraint); + + $this->attributeName = $attributeName; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \PHPUnit\Framework\Exception + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + return parent::evaluate( + Assert::readAttribute( + $other, + $this->attributeName + ), + $description, + $returnResult + ); + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'attribute "' . $this->attributeName . '" ' . $this->innerConstraint()->toString(); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return $this->toString(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php new file mode 100644 index 0000000..f537d09 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Callback.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that evaluates against a specified closure. + */ +final class Callback extends Constraint +{ + /** + * @var callable + */ + private $callback; + + public function __construct(callable $callback) + { + $this->callback = $callback; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is accepted by specified callback'; + } + + /** + * Evaluates the constraint for parameter $value. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \call_user_func($this->callback, $other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php new file mode 100644 index 0000000..2a3fd8c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasAttribute.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\Exception; + +/** + * Constraint that asserts that the class it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + */ +class ClassHasAttribute extends Constraint +{ + /** + * @var string + */ + private $attributeName; + + public function __construct(string $attributeName) + { + $this->attributeName = $attributeName; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'has attribute "%s"', + $this->attributeName + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + try { + return (new \ReflectionClass($other))->hasProperty($this->attributeName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + '%sclass "%s" %s', + \is_object($other) ? 'object of ' : '', + \is_object($other) ? \get_class($other) : $other, + $this->toString() + ); + } + + protected function attributeName(): string + { + return $this->attributeName; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php new file mode 100644 index 0000000..8afe692 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ClassHasStaticAttribute.php @@ -0,0 +1,59 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\Exception; + +/** + * Constraint that asserts that the class it is evaluated for has a given + * static attribute. + * + * The attribute name is passed in the constructor. + */ +final class ClassHasStaticAttribute extends ClassHasAttribute +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'has static attribute "%s"', + $this->attributeName() + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + try { + $class = new \ReflectionClass($other); + + if ($class->hasProperty($this->attributeName())) { + return $class->getProperty($this->attributeName())->isStatic(); + } + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + return false; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php new file mode 100644 index 0000000..ffb8ff9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Composite.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * @deprecated https://github.com/sebastianbergmann/phpunit/issues/3338 + * @codeCoverageIgnore + */ +abstract class Composite extends Constraint +{ + /** + * @var Constraint + */ + private $innerConstraint; + + public function __construct(Constraint $innerConstraint) + { + $this->innerConstraint = $innerConstraint; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + try { + return $this->innerConstraint->evaluate( + $other, + $description, + $returnResult + ); + } catch (ExpectationFailedException $e) { + $this->fail($other, $description, $e->getComparisonFailure()); + } + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + return \count($this->innerConstraint); + } + + protected function innerConstraint(): Constraint + { + return $this->innerConstraint; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php new file mode 100644 index 0000000..de8de05 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Constraint.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use Countable; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\SelfDescribing; +use SebastianBergmann\Comparator\ComparisonFailure; +use SebastianBergmann\Exporter\Exporter; + +/** + * Abstract base class for constraints which can be applied to any value. + */ +abstract class Constraint implements Countable, SelfDescribing +{ + /** + * @var Exporter + */ + private $exporter; + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = false; + + if ($this->matches($other)) { + $success = true; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + return 1; + } + + protected function exporter(): Exporter + { + if ($this->exporter === null) { + $this->exporter = new Exporter; + } + + return $this->exporter; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * This method can be overridden to implement the evaluation algorithm. + * + * @param mixed $other value or object to evaluate + * @codeCoverageIgnore + */ + protected function matches($other): bool + { + return false; + } + + /** + * Throws an exception for the given compared value and test description + * + * @param mixed $other evaluated value or object + * @param string $description Additional information about the test + * @param ComparisonFailure $comparisonFailure + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-return never-return + */ + protected function fail($other, $description, ComparisonFailure $comparisonFailure = null): void + { + $failureDescription = \sprintf( + 'Failed asserting that %s.', + $this->failureDescription($other) + ); + + $additionalFailureDescription = $this->additionalFailureDescription($other); + + if ($additionalFailureDescription) { + $failureDescription .= "\n" . $additionalFailureDescription; + } + + if (!empty($description)) { + $failureDescription = $description . "\n" . $failureDescription; + } + + throw new ExpectationFailedException( + $failureDescription, + $comparisonFailure + ); + } + + /** + * Return additional failure description where needed + * + * The function can be overridden to provide additional failure + * information like a diff + * + * @param mixed $other evaluated value or object + */ + protected function additionalFailureDescription($other): string + { + return ''; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * To provide additional failure information additionalFailureDescription + * can be used. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return $this->exporter()->export($other) . ' ' . $this->toString(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php new file mode 100644 index 0000000..dfb60eb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Count.php @@ -0,0 +1,123 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use Countable; +use Generator; +use Iterator; +use IteratorAggregate; +use Traversable; + +class Count extends Constraint +{ + /** + * @var int + */ + private $expectedCount; + + public function __construct(int $expected) + { + $this->expectedCount = $expected; + } + + public function toString(): string + { + return \sprintf( + 'count matches %d', + $this->expectedCount + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + */ + protected function matches($other): bool + { + return $this->expectedCount === $this->getCountOf($other); + } + + /** + * @param iterable $other + */ + protected function getCountOf($other): ?int + { + if ($other instanceof Countable || \is_array($other)) { + return \count($other); + } + + if ($other instanceof \EmptyIterator) { + return 0; + } + + if ($other instanceof Traversable) { + while ($other instanceof IteratorAggregate) { + $other = $other->getIterator(); + } + + $iterator = $other; + + if ($iterator instanceof Generator) { + return $this->getCountOfGenerator($iterator); + } + + if (!$iterator instanceof Iterator) { + return \iterator_count($iterator); + } + + $key = $iterator->key(); + $count = \iterator_count($iterator); + + // Manually rewind $iterator to previous key, since iterator_count + // moves pointer. + if ($key !== null) { + $iterator->rewind(); + + while ($iterator->valid() && $key !== $iterator->key()) { + $iterator->next(); + } + } + + return $count; + } + + return null; + } + + /** + * Returns the total number of iterations from a generator. + * This will fully exhaust the generator. + */ + protected function getCountOfGenerator(Generator $generator): int + { + for ($count = 0; $generator->valid(); $generator->next()) { + ++$count; + } + + return $count; + } + + /** + * Returns the description of the failure. + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + 'actual size %d matches expected size %d', + $this->getCountOf($other), + $this->expectedCount + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php new file mode 100644 index 0000000..fe7ead8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/DirectoryExists.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that checks if the directory(name) that it is evaluated for exists. + * + * The file path to check is passed as $other in evaluate(). + */ +final class DirectoryExists extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'directory exists'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_dir($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + 'directory "%s" exists', + $other + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php new file mode 100644 index 0000000..6a77c1d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/Exception.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Util\Filter; +use Throwable; + +final class Exception extends Constraint +{ + /** + * @var string + */ + private $className; + + public function __construct(string $className) + { + $this->className = $className; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'exception of type "%s"', + $this->className + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $other instanceof $this->className; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + if ($other !== null) { + $message = ''; + + if ($other instanceof Throwable) { + $message = '. Message was: "' . $other->getMessage() . '" at' + . "\n" . Filter::getFilteredStacktrace($other); + } + + return \sprintf( + 'exception of type "%s" matches expected exception "%s"%s', + \get_class($other), + $this->className, + $message + ); + } + + return \sprintf( + 'exception of type "%s" is thrown', + $this->className + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php new file mode 100644 index 0000000..d664f5e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionCode.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +final class ExceptionCode extends Constraint +{ + /** + * @var int|string + */ + private $expectedCode; + + /** + * @param int|string $expected + */ + public function __construct($expected) + { + $this->expectedCode = $expected; + } + + public function toString(): string + { + return 'exception code is '; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param \Throwable $other + */ + protected function matches($other): bool + { + return (string) $other->getCode() === (string) $this->expectedCode; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s is equal to expected exception code %s', + $this->exporter()->export($other->getCode()), + $this->exporter()->export($this->expectedCode) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php new file mode 100644 index 0000000..18b7a1d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessage.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +final class ExceptionMessage extends Constraint +{ + /** + * @var string + */ + private $expectedMessage; + + public function __construct(string $expected) + { + $this->expectedMessage = $expected; + } + + public function toString(): string + { + if ($this->expectedMessage === '') { + return 'exception message is empty'; + } + + return 'exception message contains '; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param \Throwable $other + */ + protected function matches($other): bool + { + if ($this->expectedMessage === '') { + return $other->getMessage() === ''; + } + + return \strpos((string) $other->getMessage(), $this->expectedMessage) !== false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + if ($this->expectedMessage === '') { + return \sprintf( + "exception message is empty but is '%s'", + $other->getMessage() + ); + } + + return \sprintf( + "exception message '%s' contains '%s'", + $other->getMessage(), + $this->expectedMessage + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php new file mode 100644 index 0000000..747353d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ExceptionMessageRegularExpression.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Util\RegularExpression as RegularExpressionUtil; + +final class ExceptionMessageRegularExpression extends Constraint +{ + /** + * @var string + */ + private $expectedMessageRegExp; + + public function __construct(string $expected) + { + $this->expectedMessageRegExp = $expected; + } + + public function toString(): string + { + return 'exception message matches '; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param \PHPUnit\Framework\Exception $other + * + * @throws \Exception + * @throws \PHPUnit\Framework\Exception + */ + protected function matches($other): bool + { + $match = RegularExpressionUtil::safeMatch($this->expectedMessageRegExp, $other->getMessage()); + + if ($match === false) { + throw new \PHPUnit\Framework\Exception( + "Invalid expected exception message regex given: '{$this->expectedMessageRegExp}'" + ); + } + + return $match === 1; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + "exception message '%s' matches '%s'", + $other->getMessage(), + $this->expectedMessageRegExp + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php b/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php new file mode 100644 index 0000000..b62f9fa --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/FileExists.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that checks if the file(name) that it is evaluated for exists. + * + * The file path to check is passed as $other in evaluate(). + */ +final class FileExists extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'file exists'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \file_exists($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + 'file "%s" exists', + $other + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php new file mode 100644 index 0000000..b007615 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/GreaterThan.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the value it is evaluated for is greater + * than a given value. + */ +final class GreaterThan extends Constraint +{ + /** + * @var float|int + */ + private $value; + + /** + * @param float|int $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return 'is greater than ' . $this->exporter()->export($this->value); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $this->value < $other; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php new file mode 100644 index 0000000..f1a9e7d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsAnything.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Constraint that accepts any input value. + */ +final class IsAnything extends Constraint +{ + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + return $returnResult ? true : null; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is anything'; + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + return 0; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php new file mode 100644 index 0000000..26db5b4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEmpty.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use Countable; + +/** + * Constraint that checks whether a variable is empty(). + */ +final class IsEmpty extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is empty'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ($other instanceof \EmptyIterator) { + return true; + } + + if ($other instanceof Countable) { + return \count($other) === 0; + } + + return empty($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + $type = \gettype($other); + + return \sprintf( + '%s %s %s', + \strpos($type, 'a') === 0 || \strpos($type, 'o') === 0 ? 'an' : 'a', + $type, + $this->toString() + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php new file mode 100644 index 0000000..3306de7 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsEqual.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; +use SebastianBergmann\Comparator\ComparisonFailure; +use SebastianBergmann\Comparator\Factory as ComparatorFactory; + +/** + * Constraint that checks if one value is equal to another. + * + * Equality is checked with PHP's == operator, the operator is explained in + * detail at {@url https://php.net/manual/en/types.comparisons.php}. + * Two values are equal if they have the same value disregarding type. + * + * The expected value is passed in the constructor. + */ +final class IsEqual extends Constraint +{ + /** + * @var mixed + */ + private $value; + + /** + * @var float + */ + private $delta; + + /** + * @var bool + */ + private $canonicalize; + + /** + * @var bool + */ + private $ignoreCase; + + public function __construct($value, float $delta = 0.0, int $maxDepth = 10, bool $canonicalize = false, bool $ignoreCase = false) + { + $this->value = $value; + $this->delta = $delta; + $this->canonicalize = $canonicalize; + $this->ignoreCase = $ignoreCase; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + // If $this->value and $other are identical, they are also equal. + // This is the most common path and will allow us to skip + // initialization of all the comparators. + if ($this->value === $other) { + return true; + } + + $comparatorFactory = ComparatorFactory::getInstance(); + + try { + $comparator = $comparatorFactory->getComparatorFor( + $this->value, + $other + ); + + $comparator->assertEquals( + $this->value, + $other, + $this->delta, + $this->canonicalize, + $this->ignoreCase + ); + } catch (ComparisonFailure $f) { + if ($returnResult) { + return false; + } + + throw new ExpectationFailedException( + \trim($description . "\n" . $f->getMessage()), + $f + ); + } + + return true; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + $delta = ''; + + if (\is_string($this->value)) { + if (\strpos($this->value, "\n") !== false) { + return 'is equal to '; + } + + return \sprintf( + "is equal to '%s'", + $this->value + ); + } + + if ($this->delta != 0) { + $delta = \sprintf( + ' with delta <%F>', + $this->delta + ); + } + + return \sprintf( + 'is equal to %s%s', + $this->exporter()->export($this->value), + $delta + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php new file mode 100644 index 0000000..8b11e0a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFalse.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts false. + */ +final class IsFalse extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is false'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $other === false; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php new file mode 100644 index 0000000..b36f765 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsFinite.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts finite. + */ +final class IsFinite extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is finite'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_finite($other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php new file mode 100644 index 0000000..df3daba --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsIdentical.php @@ -0,0 +1,138 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Constraint that asserts that one value is identical to another. + * + * Identical check is performed with PHP's === operator, the operator is + * explained in detail at + * {@url https://php.net/manual/en/types.comparisons.php}. + * Two values are identical if they have the same value and are of the same + * type. + * + * The expected value is passed in the constructor. + */ +final class IsIdentical extends Constraint +{ + /** + * @var float + */ + private const EPSILON = 0.0000000001; + + /** + * @var mixed + */ + private $value; + + public function __construct($value) + { + $this->value = $value; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + if (\is_float($this->value) && \is_float($other) && + !\is_infinite($this->value) && !\is_infinite($other) && + !\is_nan($this->value) && !\is_nan($other)) { + $success = \abs($this->value - $other) < self::EPSILON; + } else { + $success = $this->value === $other; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $f = null; + + // if both values are strings, make sure a diff is generated + if (\is_string($this->value) && \is_string($other)) { + $f = new ComparisonFailure( + $this->value, + $other, + \sprintf("'%s'", $this->value), + \sprintf("'%s'", $other) + ); + } + + // if both values are array, make sure a diff is generated + if (\is_array($this->value) && \is_array($other)) { + $f = new ComparisonFailure( + $this->value, + $other, + $this->exporter()->export($this->value), + $this->exporter()->export($other) + ); + } + + $this->fail($other, $description, $f); + } + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + if (\is_object($this->value)) { + return 'is identical to an object of class "' . + \get_class($this->value) . '"'; + } + + return 'is identical to ' . $this->exporter()->export($this->value); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + if (\is_object($this->value) && \is_object($other)) { + return 'two variables reference the same object'; + } + + if (\is_string($this->value) && \is_string($other)) { + return 'two strings are identical'; + } + + if (\is_array($this->value) && \is_array($other)) { + return 'two arrays are identical'; + } + + return parent::failureDescription($other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php new file mode 100644 index 0000000..03b991c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInfinite.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts infinite. + */ +final class IsInfinite extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is infinite'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_infinite($other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php new file mode 100644 index 0000000..1e86461 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsInstanceOf.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the object it is evaluated for is an instance + * of a given class. + * + * The expected class name is passed in the constructor. + */ +final class IsInstanceOf extends Constraint +{ + /** + * @var string + */ + private $className; + + public function __construct(string $className) + { + $this->className = $className; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'is instance of %s "%s"', + $this->getType(), + $this->className + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $other instanceof $this->className; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s is an instance of %s "%s"', + $this->exporter()->shortenedExport($other), + $this->getType(), + $this->className + ); + } + + private function getType(): string + { + try { + $reflection = new \ReflectionClass($this->className); + + if ($reflection->isInterface()) { + return 'interface'; + } + } catch (\ReflectionException $e) { + } + + return 'class'; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php new file mode 100644 index 0000000..7231628 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsJson.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that a string is valid JSON. + */ +final class IsJson extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is valid JSON'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ($other === '') { + return false; + } + + \json_decode($other); + + if (\json_last_error()) { + return false; + } + + return true; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + if ($other === '') { + return 'an empty string is valid JSON'; + } + + \json_decode($other); + $error = JsonMatchesErrorMessageProvider::determineJsonError( + (string) \json_last_error() + ); + + return \sprintf( + '%s is valid JSON (%s)', + $this->exporter()->shortenedExport($other), + $error + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php new file mode 100644 index 0000000..cc45631 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNan.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts nan. + */ +final class IsNan extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is nan'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_nan($other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php new file mode 100644 index 0000000..1538138 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsNull.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts null. + */ +final class IsNull extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is null'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $other === null; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php new file mode 100644 index 0000000..c9d56ef --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsReadable.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that checks if the file/dir(name) that it is evaluated for is readable. + * + * The file path to check is passed as $other in evaluate(). + */ +final class IsReadable extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is readable'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_readable($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + '"%s" is readable', + $other + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php new file mode 100644 index 0000000..7948c8f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsTrue.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that accepts true. + */ +final class IsTrue extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is true'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $other === true; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php new file mode 100644 index 0000000..03654f4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsType.php @@ -0,0 +1,199 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the value it is evaluated for is of a + * specified type. + * + * The expected value is passed in the constructor. + */ +final class IsType extends Constraint +{ + /** + * @var string + */ + public const TYPE_ARRAY = 'array'; + + /** + * @var string + */ + public const TYPE_BOOL = 'bool'; + + /** + * @var string + */ + public const TYPE_FLOAT = 'float'; + + /** + * @var string + */ + public const TYPE_INT = 'int'; + + /** + * @var string + */ + public const TYPE_NULL = 'null'; + + /** + * @var string + */ + public const TYPE_NUMERIC = 'numeric'; + + /** + * @var string + */ + public const TYPE_OBJECT = 'object'; + + /** + * @var string + */ + public const TYPE_RESOURCE = 'resource'; + + /** + * @var string + */ + public const TYPE_STRING = 'string'; + + /** + * @var string + */ + public const TYPE_SCALAR = 'scalar'; + + /** + * @var string + */ + public const TYPE_CALLABLE = 'callable'; + + /** + * @var string + */ + public const TYPE_ITERABLE = 'iterable'; + + /** + * @var array + */ + private const KNOWN_TYPES = [ + 'array' => true, + 'boolean' => true, + 'bool' => true, + 'double' => true, + 'float' => true, + 'integer' => true, + 'int' => true, + 'null' => true, + 'numeric' => true, + 'object' => true, + 'real' => true, + 'resource' => true, + 'string' => true, + 'scalar' => true, + 'callable' => true, + 'iterable' => true, + ]; + + /** + * @var string + */ + private $type; + + /** + * @throws \PHPUnit\Framework\Exception + */ + public function __construct(string $type) + { + if (!isset(self::KNOWN_TYPES[$type])) { + throw new \PHPUnit\Framework\Exception( + \sprintf( + 'Type specified for PHPUnit\Framework\Constraint\IsType <%s> ' . + 'is not a valid type.', + $type + ) + ); + } + + $this->type = $type; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'is of type "%s"', + $this->type + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + switch ($this->type) { + case 'numeric': + return \is_numeric($other); + + case 'integer': + case 'int': + return \is_int($other); + + case 'double': + case 'float': + case 'real': + return \is_float($other); + + case 'string': + return \is_string($other); + + case 'boolean': + case 'bool': + return \is_bool($other); + + case 'null': + return null === $other; + + case 'array': + return \is_array($other); + + case 'object': + return \is_object($other); + + case 'resource': + if (\is_resource($other)) { + return true; + } + + try { + $resource = @\get_resource_type($other); + + if (\is_string($resource)) { + return true; + } + } catch (\TypeError $e) { + } + + return false; + + case 'scalar': + return \is_scalar($other); + + case 'callable': + return \is_callable($other); + + case 'iterable': + return \is_iterable($other); + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php b/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php new file mode 100644 index 0000000..95d3185 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/IsWritable.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that checks if the file/dir(name) that it is evaluated for is writable. + * + * The file path to check is passed as $other in evaluate(). + */ +final class IsWritable extends Constraint +{ + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'is writable'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \is_writable($other); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + */ + protected function failureDescription($other): string + { + return \sprintf( + '"%s" is writable', + $other + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php new file mode 100644 index 0000000..0a4f6c2 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatches.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Util\Json; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Asserts whether or not two JSON objects are equal. + */ +final class JsonMatches extends Constraint +{ + /** + * @var string + */ + private $value; + + public function __construct(string $value) + { + $this->value = $value; + } + + /** + * Returns a string representation of the object. + */ + public function toString(): string + { + return \sprintf( + 'matches JSON string "%s"', + $this->value + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * This method can be overridden to implement the evaluation algorithm. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + [$error, $recodedOther] = Json::canonicalize($other); + + if ($error) { + return false; + } + + [$error, $recodedValue] = Json::canonicalize($this->value); + + if ($error) { + return false; + } + + return $recodedOther == $recodedValue; + } + + /** + * Throws an exception for the given compared value and test description + * + * @param mixed $other evaluated value or object + * @param string $description Additional information about the test + * @param ComparisonFailure $comparisonFailure + * + * @throws ExpectationFailedException + * @throws \PHPUnit\Framework\Exception + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @psalm-return never-return + */ + protected function fail($other, $description, ComparisonFailure $comparisonFailure = null): void + { + if ($comparisonFailure === null) { + [$error, $recodedOther] = Json::canonicalize($other); + + if ($error) { + parent::fail($other, $description); + } + + [$error, $recodedValue] = Json::canonicalize($this->value); + + if ($error) { + parent::fail($other, $description); + } + + $comparisonFailure = new ComparisonFailure( + \json_decode($this->value), + \json_decode($other), + Json::prettify($recodedValue), + Json::prettify($recodedOther), + false, + 'Failed asserting that two json values are equal.' + ); + } + + parent::fail($other, $description, $comparisonFailure); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php new file mode 100644 index 0000000..ac1b624 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/JsonMatchesErrorMessageProvider.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Provides human readable messages for each JSON error. + */ +final class JsonMatchesErrorMessageProvider +{ + /** + * Translates JSON error to a human readable string. + */ + public static function determineJsonError(string $error, string $prefix = ''): ?string + { + switch ($error) { + case \JSON_ERROR_NONE: + return null; + case \JSON_ERROR_DEPTH: + return $prefix . 'Maximum stack depth exceeded'; + case \JSON_ERROR_STATE_MISMATCH: + return $prefix . 'Underflow or the modes mismatch'; + case \JSON_ERROR_CTRL_CHAR: + return $prefix . 'Unexpected control character found'; + case \JSON_ERROR_SYNTAX: + return $prefix . 'Syntax error, malformed JSON'; + case \JSON_ERROR_UTF8: + return $prefix . 'Malformed UTF-8 characters, possibly incorrectly encoded'; + default: + return $prefix . 'Unknown error'; + } + } + + /** + * Translates a given type to a human readable message prefix. + */ + public static function translateTypeToPrefix(string $type): string + { + switch (\strtolower($type)) { + case 'expected': + $prefix = 'Expected value JSON decode error - '; + + break; + case 'actual': + $prefix = 'Actual value JSON decode error - '; + + break; + default: + $prefix = ''; + + break; + } + + return $prefix; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php new file mode 100644 index 0000000..781c817 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LessThan.php @@ -0,0 +1,51 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the value it is evaluated for is less than + * a given value. + */ +final class LessThan extends Constraint +{ + /** + * @var float|int + */ + private $value; + + /** + * @param float|int $value + */ + public function __construct($value) + { + $this->value = $value; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return 'is less than ' . $this->exporter()->export($this->value); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return $this->value > $other; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php new file mode 100644 index 0000000..0e9a94b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalAnd.php @@ -0,0 +1,119 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Logical AND. + */ +final class LogicalAnd extends Constraint +{ + /** + * @var Constraint[] + */ + private $constraints = []; + + public static function fromConstraints(Constraint ...$constraints): self + { + $constraint = new self; + + $constraint->constraints = \array_values($constraints); + + return $constraint; + } + + /** + * @param Constraint[] $constraints + * + * @throws \PHPUnit\Framework\Exception + */ + public function setConstraints(array $constraints): void + { + $this->constraints = []; + + foreach ($constraints as $constraint) { + if (!($constraint instanceof Constraint)) { + throw new \PHPUnit\Framework\Exception( + 'All parameters to ' . __CLASS__ . + ' must be a constraint object.' + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = true; + + foreach ($this->constraints as $constraint) { + if (!$constraint->evaluate($other, $description, true)) { + $success = false; + + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' and '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += \count($constraint); + } + + return $count; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php new file mode 100644 index 0000000..0822863 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalNot.php @@ -0,0 +1,165 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Logical NOT. + */ +final class LogicalNot extends Constraint +{ + /** + * @var Constraint + */ + private $constraint; + + public static function negate(string $string): string + { + $positives = [ + 'contains ', + 'exists', + 'has ', + 'is ', + 'are ', + 'matches ', + 'starts with ', + 'ends with ', + 'reference ', + 'not not ', + ]; + + $negatives = [ + 'does not contain ', + 'does not exist', + 'does not have ', + 'is not ', + 'are not ', + 'does not match ', + 'starts not with ', + 'ends not with ', + 'don\'t reference ', + 'not ', + ]; + + \preg_match('/(\'[\w\W]*\')([\w\W]*)("[\w\W]*")/i', $string, $matches); + + if (\count($matches) > 0) { + $nonInput = $matches[2]; + + $negatedString = \str_replace( + $nonInput, + \str_replace( + $positives, + $negatives, + $nonInput + ), + $string + ); + } else { + $negatedString = \str_replace( + $positives, + $negatives, + $string + ); + } + + return $negatedString; + } + + /** + * @param Constraint|mixed $constraint + */ + public function __construct($constraint) + { + if (!($constraint instanceof Constraint)) { + $constraint = new IsEqual($constraint); + } + + $this->constraint = $constraint; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = !$this->constraint->evaluate($other, $description, true); + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + switch (\get_class($this->constraint)) { + case LogicalAnd::class: + case self::class: + case LogicalOr::class: + return 'not( ' . $this->constraint->toString() . ' )'; + + default: + return self::negate( + $this->constraint->toString() + ); + } + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + return \count($this->constraint); + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + switch (\get_class($this->constraint)) { + case LogicalAnd::class: + case self::class: + case LogicalOr::class: + return 'not( ' . $this->constraint->failureDescription($other) . ' )'; + + default: + return self::negate( + $this->constraint->failureDescription($other) + ); + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php new file mode 100644 index 0000000..0362d39 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalOr.php @@ -0,0 +1,116 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Logical OR. + */ +final class LogicalOr extends Constraint +{ + /** + * @var Constraint[] + */ + private $constraints = []; + + public static function fromConstraints(Constraint ...$constraints): self + { + $constraint = new self; + + $constraint->constraints = \array_values($constraints); + + return $constraint; + } + + /** + * @param Constraint[] $constraints + */ + public function setConstraints(array $constraints): void + { + $this->constraints = []; + + foreach ($constraints as $constraint) { + if (!($constraint instanceof Constraint)) { + $constraint = new IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = false; + + foreach ($this->constraints as $constraint) { + if ($constraint->evaluate($other, $description, true)) { + $success = true; + + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' or '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += \count($constraint); + } + + return $count; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php new file mode 100644 index 0000000..de7f871 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/LogicalXor.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Logical XOR. + */ +final class LogicalXor extends Constraint +{ + /** + * @var Constraint[] + */ + private $constraints = []; + + public static function fromConstraints(Constraint ...$constraints): self + { + $constraint = new self; + + $constraint->constraints = \array_values($constraints); + + return $constraint; + } + + /** + * @param Constraint[] $constraints + */ + public function setConstraints(array $constraints): void + { + $this->constraints = []; + + foreach ($constraints as $constraint) { + if (!($constraint instanceof Constraint)) { + $constraint = new IsEqual( + $constraint + ); + } + + $this->constraints[] = $constraint; + } + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = true; + $lastResult = null; + + foreach ($this->constraints as $constraint) { + $result = $constraint->evaluate($other, $description, true); + + if ($result === $lastResult) { + $success = false; + + break; + } + + $lastResult = $result; + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + $text = ''; + + foreach ($this->constraints as $key => $constraint) { + if ($key > 0) { + $text .= ' xor '; + } + + $text .= $constraint->toString(); + } + + return $text; + } + + /** + * Counts the number of constraint elements. + */ + public function count(): int + { + $count = 0; + + foreach ($this->constraints as $constraint) { + $count += \count($constraint); + } + + return $count; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php b/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php new file mode 100644 index 0000000..8543c22 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/ObjectHasAttribute.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use ReflectionObject; + +/** + * Constraint that asserts that the object it is evaluated for has a given + * attribute. + * + * The attribute name is passed in the constructor. + */ +final class ObjectHasAttribute extends ClassHasAttribute +{ + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return (new ReflectionObject($other))->hasProperty($this->attributeName()); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php b/vendor/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php new file mode 100644 index 0000000..178b637 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/RegularExpression.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the string it is evaluated for matches + * a regular expression. + * + * Checks a given value using the Perl Compatible Regular Expression extension + * in PHP. The pattern is matched by executing preg_match(). + * + * The pattern string passed in the constructor. + */ +class RegularExpression extends Constraint +{ + /** + * @var string + */ + private $pattern; + + public function __construct(string $pattern) + { + $this->pattern = $pattern; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return \sprintf( + 'matches PCRE pattern "%s"', + $this->pattern + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \preg_match($this->pattern, $other) > 0; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php b/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php new file mode 100644 index 0000000..c6b8703 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/SameSize.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +final class SameSize extends Count +{ + public function __construct(iterable $expected) + { + parent::__construct($this->getCountOf($expected)); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php new file mode 100644 index 0000000..791fccc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringContains.php @@ -0,0 +1,74 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the string it is evaluated for contains + * a given string. + * + * Uses mb_strpos() to find the position of the string in the input, if not + * found the evaluation fails. + * + * The sub-string is passed in the constructor. + */ +final class StringContains extends Constraint +{ + /** + * @var string + */ + private $string; + + /** + * @var bool + */ + private $ignoreCase; + + public function __construct(string $string, bool $ignoreCase = false) + { + $this->string = $string; + $this->ignoreCase = $ignoreCase; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + if ($this->ignoreCase) { + $string = \mb_strtolower($this->string); + } else { + $string = $this->string; + } + + return \sprintf( + 'contains "%s"', + $string + ); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ('' === $this->string) { + return true; + } + + if ($this->ignoreCase) { + return \mb_stripos($other, $this->string) !== false; + } + + return \mb_strpos($other, $this->string) !== false; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php new file mode 100644 index 0000000..c4c3c14 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringEndsWith.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +/** + * Constraint that asserts that the string it is evaluated for ends with a given + * suffix. + */ +final class StringEndsWith extends Constraint +{ + /** + * @var string + */ + private $suffix; + + public function __construct(string $suffix) + { + $this->suffix = $suffix; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'ends with "' . $this->suffix . '"'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \substr($other, 0 - \strlen($this->suffix)) === $this->suffix; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php new file mode 100644 index 0000000..ab7e622 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringMatchesFormatDescription.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use SebastianBergmann\Diff\Differ; + +/** + * ... + */ +final class StringMatchesFormatDescription extends RegularExpression +{ + /** + * @var string + */ + private $string; + + public function __construct(string $string) + { + parent::__construct( + $this->createPatternFromFormat( + $this->convertNewlines($string) + ) + ); + + $this->string = $string; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return parent::matches( + $this->convertNewlines($other) + ); + } + + protected function failureDescription($other): string + { + return 'string matches format description'; + } + + protected function additionalFailureDescription($other): string + { + $from = \explode("\n", $this->string); + $to = \explode("\n", $this->convertNewlines($other)); + + foreach ($from as $index => $line) { + if (isset($to[$index]) && $line !== $to[$index]) { + $line = $this->createPatternFromFormat($line); + + if (\preg_match($line, $to[$index]) > 0) { + $from[$index] = $to[$index]; + } + } + } + + $this->string = \implode("\n", $from); + $other = \implode("\n", $to); + + return (new Differ("--- Expected\n+++ Actual\n"))->diff($this->string, $other); + } + + private function createPatternFromFormat(string $string): string + { + $string = \strtr( + \preg_quote($string, '/'), + [ + '%%' => '%', + '%e' => '\\' . \DIRECTORY_SEPARATOR, + '%s' => '[^\r\n]+', + '%S' => '[^\r\n]*', + '%a' => '.+', + '%A' => '.*', + '%w' => '\s*', + '%i' => '[+-]?\d+', + '%d' => '\d+', + '%x' => '[0-9a-fA-F]+', + '%f' => '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', + '%c' => '.', + ] + ); + + return '/^' . $string . '$/s'; + } + + private function convertNewlines($text): string + { + return \preg_replace('/\r\n/', "\n", $text); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php b/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php new file mode 100644 index 0000000..27c100a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/StringStartsWith.php @@ -0,0 +1,52 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\InvalidArgumentException; + +/** + * Constraint that asserts that the string it is evaluated for begins with a + * given prefix. + */ +final class StringStartsWith extends Constraint +{ + /** + * @var string + */ + private $prefix; + + public function __construct(string $prefix) + { + if (\strlen($prefix) === 0) { + throw InvalidArgumentException::create(1, 'non-empty string'); + } + + $this->prefix = $prefix; + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'starts with "' . $this->prefix . '"'; + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + return \strpos((string) $other, $this->prefix) === 0; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php new file mode 100644 index 0000000..be66317 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContains.php @@ -0,0 +1,115 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use SplObjectStorage; + +/** + * Constraint that asserts that the Traversable it is applied to contains + * a given value. + * + * @deprecated Use TraversableContainsEqual or TraversableContainsIdentical instead + */ +final class TraversableContains extends Constraint +{ + /** + * @var bool + */ + private $checkForObjectIdentity; + + /** + * @var bool + */ + private $checkForNonObjectIdentity; + + /** + * @var mixed + */ + private $value; + + public function __construct($value, bool $checkForObjectIdentity = true, bool $checkForNonObjectIdentity = false) + { + $this->checkForObjectIdentity = $checkForObjectIdentity; + $this->checkForNonObjectIdentity = $checkForNonObjectIdentity; + $this->value = $value; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + if (\is_string($this->value) && \strpos($this->value, "\n") !== false) { + return 'contains "' . $this->value . '"'; + } + + return 'contains ' . $this->exporter()->export($this->value); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ($other instanceof SplObjectStorage) { + return $other->contains($this->value); + } + + if (\is_object($this->value)) { + foreach ($other as $element) { + if ($this->checkForObjectIdentity && $element === $this->value) { + return true; + } + + /* @noinspection TypeUnsafeComparisonInspection */ + if (!$this->checkForObjectIdentity && $element == $this->value) { + return true; + } + } + } else { + foreach ($other as $element) { + if ($this->checkForNonObjectIdentity && $element === $this->value) { + return true; + } + + /* @noinspection TypeUnsafeComparisonInspection */ + if (!$this->checkForNonObjectIdentity && $element == $this->value) { + return true; + } + } + } + + return false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s %s', + \is_array($other) ? 'an array' : 'a traversable', + $this->toString() + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php new file mode 100644 index 0000000..495795e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsEqual.php @@ -0,0 +1,84 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use SplObjectStorage; + +/** + * Constraint that asserts that the Traversable it is applied to contains + * a given value (using non-strict comparison). + */ +final class TraversableContainsEqual extends Constraint +{ + /** + * @var mixed + */ + private $value; + + public function __construct($value) + { + $this->value = $value; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + if (\is_string($this->value) && \strpos($this->value, "\n") !== false) { + return 'contains "' . $this->value . '"'; + } + + return 'contains ' . $this->exporter()->export($this->value); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ($other instanceof SplObjectStorage) { + return $other->contains($this->value); + } + + foreach ($other as $element) { + /* @noinspection TypeUnsafeComparisonInspection */ + if ($this->value == $element) { + return true; + } + } + + return false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s %s', + \is_array($other) ? 'an array' : 'a traversable', + $this->toString() + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php new file mode 100644 index 0000000..aead4b1 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsIdentical.php @@ -0,0 +1,83 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use SplObjectStorage; + +/** + * Constraint that asserts that the Traversable it is applied to contains + * a given value (using strict comparison). + */ +final class TraversableContainsIdentical extends Constraint +{ + /** + * @var mixed + */ + private $value; + + public function __construct($value) + { + $this->value = $value; + } + + /** + * Returns a string representation of the constraint. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + if (\is_string($this->value) && \strpos($this->value, "\n") !== false) { + return 'contains "' . $this->value . '"'; + } + + return 'contains ' . $this->exporter()->export($this->value); + } + + /** + * Evaluates the constraint for parameter $other. Returns true if the + * constraint is met, false otherwise. + * + * @param mixed $other value or object to evaluate + */ + protected function matches($other): bool + { + if ($other instanceof SplObjectStorage) { + return $other->contains($this->value); + } + + foreach ($other as $element) { + if ($this->value === $element) { + return true; + } + } + + return false; + } + + /** + * Returns the description of the failure + * + * The beginning of failure messages is "Failed asserting that" in most + * cases. This method should return the second part of that sentence. + * + * @param mixed $other evaluated value or object + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function failureDescription($other): string + { + return \sprintf( + '%s %s', + \is_array($other) ? 'an array' : 'a traversable', + $this->toString() + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php new file mode 100644 index 0000000..2191ae6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Constraint/TraversableContainsOnly.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Constraint; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * Constraint that asserts that the Traversable it is applied to contains + * only values of a given type. + */ +final class TraversableContainsOnly extends Constraint +{ + /** + * @var Constraint + */ + private $constraint; + + /** + * @var string + */ + private $type; + + /** + * @throws \PHPUnit\Framework\Exception + */ + public function __construct(string $type, bool $isNativeType = true) + { + if ($isNativeType) { + $this->constraint = new IsType($type); + } else { + $this->constraint = new IsInstanceOf( + $type + ); + } + + $this->type = $type; + } + + /** + * Evaluates the constraint for parameter $other + * + * If $returnResult is set to false (the default), an exception is thrown + * in case of a failure. null is returned otherwise. + * + * If $returnResult is true, the result of the evaluation is returned as + * a boolean value instead: true in case of success, false in case of a + * failure. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function evaluate($other, string $description = '', bool $returnResult = false) + { + $success = true; + + foreach ($other as $item) { + if (!$this->constraint->evaluate($item, '', true)) { + $success = false; + + break; + } + } + + if ($returnResult) { + return $success; + } + + if (!$success) { + $this->fail($other, $description); + } + } + + /** + * Returns a string representation of the constraint. + */ + public function toString(): string + { + return 'contains only values of type "' . $this->type . '"'; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php b/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php new file mode 100644 index 0000000..a65dc34 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/DataProviderTestSuite.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Util\Test as TestUtil; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class DataProviderTestSuite extends TestSuite +{ + /** + * @var string[] + */ + private $dependencies = []; + + /** + * @param string[] $dependencies + */ + public function setDependencies(array $dependencies): void + { + $this->dependencies = $dependencies; + + foreach ($this->tests as $test) { + if (!$test instanceof TestCase) { + continue; + } + + $test->setDependencies($dependencies); + } + } + + public function getDependencies(): array + { + return $this->dependencies; + } + + public function hasDependencies(): bool + { + return \count($this->dependencies) > 0; + } + + /** + * Returns the size of the each test created using the data provider(s) + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function getSize(): int + { + [$className, $methodName] = \explode('::', $this->getName()); + + return TestUtil::getSize($className, $methodName); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php new file mode 100644 index 0000000..607c965 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Error/Deprecated.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Error; + +final class Deprecated extends Error +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Error.php b/vendor/phpunit/phpunit/src/Framework/Error/Error.php new file mode 100644 index 0000000..61e80f8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Error/Error.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Error; + +use PHPUnit\Framework\Exception; + +class Error extends Exception +{ + public function __construct(string $message, int $code, string $file, int $line, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->file = $file; + $this->line = $line; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Notice.php b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php new file mode 100644 index 0000000..4a3d01d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Error/Notice.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Error; + +final class Notice extends Error +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Error/Warning.php b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php new file mode 100644 index 0000000..d49f991 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Error/Warning.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\Error; + +final class Warning extends Error +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php new file mode 100644 index 0000000..0ba2528 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/AssertionFailedError.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class AssertionFailedError extends Exception implements SelfDescribing +{ + /** + * Wrapper for getMessage() which is declared as final. + */ + public function toString(): string + { + return $this->getMessage(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php b/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php new file mode 100644 index 0000000..36b0723 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/CodeCoverageException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class CodeCoverageException extends Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php b/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php new file mode 100644 index 0000000..78f89bc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/CoveredCodeNotExecutedException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class CoveredCodeNotExecutedException extends RiskyTestError +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php b/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php new file mode 100644 index 0000000..838c736 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/Exception.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Util\Filter; + +/** + * Base class for all PHPUnit Framework exceptions. + * + * Ensures that exceptions thrown during a test run do not leave stray + * references behind. + * + * Every Exception contains a stack trace. Each stack frame contains the 'args' + * of the called function. The function arguments can contain references to + * instantiated objects. The references prevent the objects from being + * destructed (until test results are eventually printed), so memory cannot be + * freed up. + * + * With enabled process isolation, test results are serialized in the child + * process and unserialized in the parent process. The stack trace of Exceptions + * may contain objects that cannot be serialized or unserialized (e.g., PDO + * connections). Unserializing user-space objects from the child process into + * the parent would break the intended encapsulation of process isolation. + * + * @see http://fabien.potencier.org/article/9/php-serialization-stack-traces-and-exceptions + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class Exception extends \RuntimeException implements \PHPUnit\Exception +{ + /** + * @var array + */ + protected $serializableTrace; + + public function __construct($message = '', $code = 0, \Throwable $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->serializableTrace = $this->getTrace(); + + foreach (\array_keys($this->serializableTrace) as $key) { + unset($this->serializableTrace[$key]['args']); + } + } + + public function __toString(): string + { + $string = TestFailure::exceptionToString($this); + + if ($trace = Filter::getFilteredStacktrace($this)) { + $string .= "\n" . $trace; + } + + return $string; + } + + public function __sleep(): array + { + return \array_keys(\get_object_vars($this)); + } + + /** + * Returns the serializable trace (without 'args'). + */ + public function getSerializableTrace(): array + { + return $this->serializableTrace; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php b/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php new file mode 100644 index 0000000..f7d7a9c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/ExpectationFailedException.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * Exception for expectations which failed their check. + * + * The exception contains the error message and optionally a + * SebastianBergmann\Comparator\ComparisonFailure which is used to + * generate diff output of the failed expectations. + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExpectationFailedException extends AssertionFailedError +{ + /** + * @var ComparisonFailure + */ + protected $comparisonFailure; + + public function __construct(string $message, ComparisonFailure $comparisonFailure = null, \Exception $previous = null) + { + $this->comparisonFailure = $comparisonFailure; + + parent::__construct($message, 0, $previous); + } + + public function getComparisonFailure(): ?ComparisonFailure + { + return $this->comparisonFailure; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php new file mode 100644 index 0000000..65f9c8b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/IncompleteTestError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class IncompleteTestError extends AssertionFailedError implements IncompleteTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php new file mode 100644 index 0000000..48249ad --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidArgumentException.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidArgumentException extends Exception +{ + public static function create(int $argument, string $type): self + { + $stack = \debug_backtrace(); + + return new self( + \sprintf( + 'Argument #%d of %s::%s() must be %s %s', + $argument, + $stack[1]['class'], + $stack[1]['function'], + \in_array(\lcfirst($type)[0], ['a', 'e', 'i', 'o', 'u']) ? 'an' : 'a', + $type + ) + ); + } + + private function __construct(string $message = '', int $code = 0, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php new file mode 100644 index 0000000..ebf2994 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidCoversTargetException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidCoversTargetException extends CodeCoverageException +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php new file mode 100644 index 0000000..7e2ef24 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/InvalidDataProviderException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidDataProviderException extends Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php b/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php new file mode 100644 index 0000000..567a6c4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/MissingCoversAnnotationException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MissingCoversAnnotationException extends RiskyTestError +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php b/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php new file mode 100644 index 0000000..7ef4153 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/NoChildTestSuiteException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class NoChildTestSuiteException extends Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php b/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php new file mode 100644 index 0000000..1c8b37e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/OutputError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class OutputError extends AssertionFailedError +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php new file mode 100644 index 0000000..1712613 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/PHPTAssertionFailedError.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class PHPTAssertionFailedError extends SyntheticError +{ + /** + * @var string + */ + private $diff; + + public function __construct(string $message, int $code, string $file, int $line, array $trace, string $diff) + { + parent::__construct($message, $code, $file, $line, $trace); + $this->diff = $diff; + } + + public function getDiff(): string + { + return $this->diff; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php new file mode 100644 index 0000000..a66552c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/RiskyTestError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class RiskyTestError extends AssertionFailedError +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php new file mode 100644 index 0000000..7d553dc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SkippedTestError extends AssertionFailedError implements SkippedTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php new file mode 100644 index 0000000..5448508 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/SkippedTestSuiteError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SkippedTestSuiteError extends AssertionFailedError implements SkippedTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php new file mode 100644 index 0000000..c3124ba --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticError.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class SyntheticError extends AssertionFailedError +{ + /** + * The synthetic file. + * + * @var string + */ + protected $syntheticFile = ''; + + /** + * The synthetic line number. + * + * @var int + */ + protected $syntheticLine = 0; + + /** + * The synthetic trace. + * + * @var array + */ + protected $syntheticTrace = []; + + public function __construct(string $message, int $code, string $file, int $line, array $trace) + { + parent::__construct($message, $code); + + $this->syntheticFile = $file; + $this->syntheticLine = $line; + $this->syntheticTrace = $trace; + } + + public function getSyntheticFile(): string + { + return $this->syntheticFile; + } + + public function getSyntheticLine(): int + { + return $this->syntheticLine; + } + + public function getSyntheticTrace(): array + { + return $this->syntheticTrace; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php new file mode 100644 index 0000000..f6e155d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/SyntheticSkippedError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SyntheticSkippedError extends SyntheticError implements SkippedTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php b/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php new file mode 100644 index 0000000..fcd1d82 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/UnintentionallyCoveredCodeError.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class UnintentionallyCoveredCodeError extends RiskyTestError +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php b/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php new file mode 100644 index 0000000..35e9449 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Exception/Warning.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Warning extends Exception implements SelfDescribing +{ + /** + * Wrapper for getMessage() which is declared as final. + */ + public function toString(): string + { + return $this->getMessage(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php new file mode 100644 index 0000000..14d422f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/ExceptionWrapper.php @@ -0,0 +1,117 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Util\Filter; +use Throwable; + +/** + * Wraps Exceptions thrown by code under test. + * + * Re-instantiates Exceptions thrown by user-space code to retain their original + * class names, properties, and stack traces (but without arguments). + * + * Unlike PHPUnit\Framework_\Exception, the complete stack of previous Exceptions + * is processed. + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExceptionWrapper extends Exception +{ + /** + * @var string + */ + protected $className; + + /** + * @var null|ExceptionWrapper + */ + protected $previous; + + public function __construct(Throwable $t) + { + // PDOException::getCode() is a string. + // @see https://php.net/manual/en/class.pdoexception.php#95812 + parent::__construct($t->getMessage(), (int) $t->getCode()); + $this->setOriginalException($t); + } + + public function __toString(): string + { + $string = TestFailure::exceptionToString($this); + + if ($trace = Filter::getFilteredStacktrace($this)) { + $string .= "\n" . $trace; + } + + if ($this->previous) { + $string .= "\nCaused by\n" . $this->previous; + } + + return $string; + } + + public function getClassName(): string + { + return $this->className; + } + + public function getPreviousWrapped(): ?self + { + return $this->previous; + } + + public function setClassName(string $className): void + { + $this->className = $className; + } + + public function setOriginalException(\Throwable $t): void + { + $this->originalException($t); + + $this->className = \get_class($t); + $this->file = $t->getFile(); + $this->line = $t->getLine(); + + $this->serializableTrace = $t->getTrace(); + + foreach (\array_keys($this->serializableTrace) as $key) { + unset($this->serializableTrace[$key]['args']); + } + + if ($t->getPrevious()) { + $this->previous = new self($t->getPrevious()); + } + } + + public function getOriginalException(): ?Throwable + { + return $this->originalException(); + } + + /** + * Method to contain static originalException to exclude it from stacktrace to prevent the stacktrace contents, + * which can be quite big, from being garbage-collected, thus blocking memory until shutdown. + * Approach works both for var_dump() and var_export() and print_r() + */ + private function originalException(Throwable $exceptionToStore = null): ?Throwable + { + static $originalExceptions; + + $instanceId = \spl_object_hash($this); + + if ($exceptionToStore) { + $originalExceptions[$instanceId] = $exceptionToStore; + } + + return $originalExceptions[$instanceId] ?? null; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php new file mode 100644 index 0000000..268957c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTest.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface IncompleteTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php new file mode 100644 index 0000000..e656248 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/IncompleteTestCase.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class IncompleteTestCase extends TestCase +{ + /** + * @var bool + */ + protected $backupGlobals = false; + + /** + * @var bool + */ + protected $backupStaticAttributes = false; + + /** + * @var bool + */ + protected $runTestInSeparateProcess = false; + + /** + * @var bool + */ + protected $useErrorHandler = false; + + /** + * @var string + */ + private $message; + + public function __construct(string $className, string $methodName, string $message = '') + { + parent::__construct($className . '::' . $methodName); + + $this->message = $message; + } + + public function getMessage(): string + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return $this->getName(); + } + + /** + * @throws Exception + */ + protected function runTest(): void + { + $this->markTestIncomplete($this->message); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php b/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php new file mode 100644 index 0000000..feb9cc9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/InvalidParameterGroupException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidParameterGroupException extends Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php new file mode 100644 index 0000000..e2f0a28 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Api.php @@ -0,0 +1,97 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\MockObject\Builder\InvocationMocker as InvocationMockerBuilder; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; + +/** + * @internal This trait is not covered by the backward compatibility promise for PHPUnit + */ +trait Api +{ + /** + * @var ConfigurableMethod[] + */ + private static $__phpunit_configurableMethods; + + /** + * @var object + */ + private $__phpunit_originalObject; + + /** + * @var bool + */ + private $__phpunit_returnValueGeneration = true; + + /** + * @var InvocationHandler + */ + private $__phpunit_invocationMocker; + + /** @noinspection MagicMethodsValidityInspection */ + public static function __phpunit_initConfigurableMethods(ConfigurableMethod ...$configurableMethods): void + { + if (isset(static::$__phpunit_configurableMethods)) { + throw new ConfigurableMethodsAlreadyInitializedException( + 'Configurable methods is already initialized and can not be reinitialized' + ); + } + + static::$__phpunit_configurableMethods = $configurableMethods; + } + + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_setOriginalObject($originalObject): void + { + $this->__phpunit_originalObject = $originalObject; + } + + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void + { + $this->__phpunit_returnValueGeneration = $returnValueGeneration; + } + + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_getInvocationHandler(): InvocationHandler + { + if ($this->__phpunit_invocationMocker === null) { + $this->__phpunit_invocationMocker = new InvocationHandler( + static::$__phpunit_configurableMethods, + $this->__phpunit_returnValueGeneration + ); + } + + return $this->__phpunit_invocationMocker; + } + + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_hasMatchers(): bool + { + return $this->__phpunit_getInvocationHandler()->hasMatchers(); + } + + /** @noinspection MagicMethodsValidityInspection */ + public function __phpunit_verify(bool $unsetInvocationMocker = true): void + { + $this->__phpunit_getInvocationHandler()->verify(); + + if ($unsetInvocationMocker) { + $this->__phpunit_invocationMocker = null; + } + } + + public function expects(InvocationOrder $matcher): InvocationMockerBuilder + { + return $this->__phpunit_getInvocationHandler()->expects($matcher); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php new file mode 100644 index 0000000..77d1770 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/Method.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount; + +/** + * @internal This trait is not covered by the backward compatibility promise for PHPUnit + */ +trait Method +{ + public function method() + { + $expects = $this->expects(new AnyInvokedCount); + + return \call_user_func_array( + [$expects, 'method'], + \func_get_args() + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php new file mode 100644 index 0000000..91e35f9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/MockedCloneMethod.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This trait is not covered by the backward compatibility promise for PHPUnit + */ +trait MockedCloneMethod +{ + public function __clone() + { + $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php new file mode 100644 index 0000000..3f493d2 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Api/UnmockedCloneMethod.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This trait is not covered by the backward compatibility promise for PHPUnit + */ +trait UnmockedCloneMethod +{ + public function __clone() + { + $this->__phpunit_invocationMocker = clone $this->__phpunit_getInvocationHandler(); + + parent::__clone(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php new file mode 100644 index 0000000..a68bfad --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Identity.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Identity +{ + /** + * Sets the identification of the expectation to $id. + * + * @note The identifier is unique per mock object. + * + * @param string $id unique identification of expectation + */ + public function id($id); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php new file mode 100644 index 0000000..76c08f0 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationMocker.php @@ -0,0 +1,293 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\MockObject\ConfigurableMethod; +use PHPUnit\Framework\MockObject\IncompatibleReturnValueException; +use PHPUnit\Framework\MockObject\InvocationHandler; +use PHPUnit\Framework\MockObject\Matcher; +use PHPUnit\Framework\MockObject\Rule; +use PHPUnit\Framework\MockObject\RuntimeException; +use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls; +use PHPUnit\Framework\MockObject\Stub\Exception; +use PHPUnit\Framework\MockObject\Stub\ReturnArgument; +use PHPUnit\Framework\MockObject\Stub\ReturnCallback; +use PHPUnit\Framework\MockObject\Stub\ReturnReference; +use PHPUnit\Framework\MockObject\Stub\ReturnSelf; +use PHPUnit\Framework\MockObject\Stub\ReturnStub; +use PHPUnit\Framework\MockObject\Stub\ReturnValueMap; +use PHPUnit\Framework\MockObject\Stub\Stub; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvocationMocker implements InvocationStubber, MethodNameMatch +{ + /** + * @var InvocationHandler + */ + private $invocationHandler; + + /** + * @var Matcher + */ + private $matcher; + + /** + * @var ConfigurableMethod[] + */ + private $configurableMethods; + + public function __construct(InvocationHandler $handler, Matcher $matcher, ConfigurableMethod ...$configurableMethods) + { + $this->invocationHandler = $handler; + $this->matcher = $matcher; + $this->configurableMethods = $configurableMethods; + } + + /** + * @return $this + */ + public function id($id): self + { + $this->invocationHandler->registerMatcher($id, $this->matcher); + + return $this; + } + + /** + * @return $this + */ + public function will(Stub $stub): Identity + { + $this->matcher->setStub($stub); + + return $this; + } + + public function willReturn($value, ...$nextValues): self + { + if (\count($nextValues) === 0) { + $this->ensureTypeOfReturnValues([$value]); + + $stub = $value instanceof Stub ? $value : new ReturnStub($value); + } else { + $values = \array_merge([$value], $nextValues); + + $this->ensureTypeOfReturnValues($values); + + $stub = new ConsecutiveCalls($values); + } + + return $this->will($stub); + } + + /** {@inheritDoc} */ + public function willReturnReference(&$reference): self + { + $stub = new ReturnReference($reference); + + return $this->will($stub); + } + + public function willReturnMap(array $valueMap): self + { + $stub = new ReturnValueMap($valueMap); + + return $this->will($stub); + } + + public function willReturnArgument($argumentIndex): self + { + $stub = new ReturnArgument($argumentIndex); + + return $this->will($stub); + } + + /** {@inheritDoc} */ + public function willReturnCallback($callback): self + { + $stub = new ReturnCallback($callback); + + return $this->will($stub); + } + + public function willReturnSelf(): self + { + $stub = new ReturnSelf; + + return $this->will($stub); + } + + public function willReturnOnConsecutiveCalls(...$values): self + { + $stub = new ConsecutiveCalls($values); + + return $this->will($stub); + } + + public function willThrowException(\Throwable $exception): self + { + $stub = new Exception($exception); + + return $this->will($stub); + } + + /** + * @return $this + */ + public function after($id): self + { + $this->matcher->setAfterMatchBuilderId($id); + + return $this; + } + + /** + * @throws RuntimeException + * + * @return $this + */ + public function with(...$arguments): self + { + $this->canDefineParameters(); + + $this->matcher->setParametersRule(new Rule\Parameters($arguments)); + + return $this; + } + + /** + * @param array ...$arguments + * + * @throws RuntimeException + * + * @return $this + */ + public function withConsecutive(...$arguments): self + { + $this->canDefineParameters(); + + $this->matcher->setParametersRule(new Rule\ConsecutiveParameters($arguments)); + + return $this; + } + + /** + * @throws RuntimeException + * + * @return $this + */ + public function withAnyParameters(): self + { + $this->canDefineParameters(); + + $this->matcher->setParametersRule(new Rule\AnyParameters); + + return $this; + } + + /** + * @param Constraint|string $constraint + * + * @throws RuntimeException + * + * @return $this + */ + public function method($constraint): self + { + if ($this->matcher->hasMethodNameRule()) { + throw new RuntimeException( + 'Rule for method name is already defined, cannot redefine' + ); + } + + $configurableMethodNames = \array_map( + static function (ConfigurableMethod $configurable) { + return \strtolower($configurable->getName()); + }, + $this->configurableMethods + ); + + if (\is_string($constraint) && !\in_array(\strtolower($constraint), $configurableMethodNames, true)) { + throw new RuntimeException( + \sprintf( + 'Trying to configure method "%s" which cannot be configured because it does not exist, has not been specified, is final, or is static', + $constraint + ) + ); + } + + $this->matcher->setMethodNameRule(new Rule\MethodName($constraint)); + + return $this; + } + + /** + * Validate that a parameters rule can be defined, throw exceptions otherwise. + * + * @throws RuntimeException + */ + private function canDefineParameters(): void + { + if (!$this->matcher->hasMethodNameRule()) { + throw new RuntimeException( + 'Rule for method name is not defined, cannot define rule for parameters ' . + 'without one' + ); + } + + if ($this->matcher->hasParametersRule()) { + throw new RuntimeException( + 'Rule for parameters is already defined, cannot redefine' + ); + } + } + + private function getConfiguredMethod(): ?ConfigurableMethod + { + $configuredMethod = null; + + foreach ($this->configurableMethods as $configurableMethod) { + if ($this->matcher->getMethodNameRule()->matchesName($configurableMethod->getName())) { + if ($configuredMethod !== null) { + return null; + } + + $configuredMethod = $configurableMethod; + } + } + + return $configuredMethod; + } + + private function ensureTypeOfReturnValues(array $values): void + { + $configuredMethod = $this->getConfiguredMethod(); + + if ($configuredMethod === null) { + return; + } + + foreach ($values as $value) { + if (!$configuredMethod->mayReturn($value)) { + throw new IncompatibleReturnValueException( + \sprintf( + 'Method %s may not return value of type %s, its return declaration is "%s"', + $configuredMethod->getName(), + \is_object($value) ? \get_class($value) : \gettype($value), + $configuredMethod->getReturnTypeDeclaration() + ) + ); + } + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php new file mode 100644 index 0000000..cb2e0ac --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/InvocationStubber.php @@ -0,0 +1,61 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +use PHPUnit\Framework\MockObject\Stub\Stub; + +interface InvocationStubber +{ + public function will(Stub $stub): Identity; + + /** @return self */ + public function willReturn($value, ...$nextValues)/*: self */; + + /** + * @param mixed $reference + * + * @return self + */ + public function willReturnReference(&$reference)/*: self */; + + /** + * @param array> $valueMap + * + * @return self + */ + public function willReturnMap(array $valueMap)/*: self */; + + /** + * @param int $argumentIndex + * + * @return self + */ + public function willReturnArgument($argumentIndex)/*: self */; + + /** + * @param callable $callback + * + * @return self + */ + public function willReturnCallback($callback)/*: self */; + + /** @return self */ + public function willReturnSelf()/*: self */; + + /** + * @param mixed $values + * + * @return self + */ + public function willReturnOnConsecutiveCalls(...$values)/*: self */; + + /** @return self */ + public function willThrowException(\Throwable $exception)/*: self */; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php new file mode 100644 index 0000000..d343eac --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Match.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Match extends Stub +{ + /** + * Defines the expectation which must occur before the current is valid. + * + * @param string $id the identification of the expectation that should + * occur before this one + * + * @return Stub + */ + public function after($id); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php new file mode 100644 index 0000000..f4b1150 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/MethodNameMatch.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface MethodNameMatch extends ParametersMatch +{ + /** + * Adds a new method name match and returns the parameter match object for + * further matching possibilities. + * + * @param \PHPUnit\Framework\Constraint\Constraint $name Constraint for matching method, if a string is passed it will use the PHPUnit_Framework_Constraint_IsEqual + * + * @return ParametersMatch + */ + public function method($name); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php new file mode 100644 index 0000000..ae16d79 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/ParametersMatch.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface ParametersMatch extends Match +{ + /** + * Sets the parameters to match for, each parameter to this function will + * be part of match. To perform specific matches or constraints create a + * new PHPUnit\Framework\Constraint\Constraint and use it for the parameter. + * If the parameter value is not a constraint it will use the + * PHPUnit\Framework\Constraint\IsEqual for the value. + * + * Some examples: + * + * // match first parameter with value 2 + * $b->with(2); + * // match first parameter with value 'smock' and second identical to 42 + * $b->with('smock', new PHPUnit\Framework\Constraint\IsEqual(42)); + * + * + * @return ParametersMatch + */ + public function with(...$arguments); + + /** + * Sets a rule which allows any kind of parameters. + * + * Some examples: + * + * // match any number of parameters + * $b->withAnyParameters(); + * + * + * @return ParametersMatch + */ + public function withAnyParameters(); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php new file mode 100644 index 0000000..d7cb78f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Builder/Stub.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Builder; + +use PHPUnit\Framework\MockObject\Stub\Stub as BaseStub; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Stub extends Identity +{ + /** + * Stubs the matching method with the stub object $stub. Any invocations of + * the matched method will now be handled by the stub instead. + */ + public function will(BaseStub $stub): Identity; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php new file mode 100644 index 0000000..f65983d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/ConfigurableMethod.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use SebastianBergmann\Type\Type; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConfigurableMethod +{ + /** + * @var string + */ + private $name; + + /** + * @var Type + */ + private $returnType; + + public function __construct(string $name, Type $returnType) + { + $this->name = $name; + $this->returnType = $returnType; + } + + public function getName(): string + { + return $this->name; + } + + public function mayReturn($value): bool + { + if ($value === null && $this->returnType->allowsNull()) { + return true; + } + + return $this->returnType->isAssignable(Type::fromValue($value, false)); + } + + public function getReturnTypeDeclaration(): string + { + return $this->returnType->getReturnTypeDeclaration(); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php new file mode 100644 index 0000000..7e655e2 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/BadMethodCallException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class BadMethodCallException extends \BadMethodCallException implements Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php new file mode 100644 index 0000000..d12ac99 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ConfigurableMethodsAlreadyInitializedException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConfigurableMethodsAlreadyInitializedException extends \PHPUnit\Framework\Exception implements Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php new file mode 100644 index 0000000..7307fba --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Exception extends \Throwable +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php new file mode 100644 index 0000000..f1ceb1d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/IncompatibleReturnValueException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class IncompatibleReturnValueException extends \PHPUnit\Framework\Exception implements Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php new file mode 100644 index 0000000..33b6a5b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/RuntimeException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RuntimeException extends \RuntimeException implements Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php new file mode 100644 index 0000000..01aae5d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator.php @@ -0,0 +1,1050 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use Doctrine\Instantiator\Exception\ExceptionInterface as InstantiatorException; +use Doctrine\Instantiator\Instantiator; +use PHPUnit\Framework\InvalidArgumentException; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Generator +{ + /** + * @var array + */ + private const BLACKLISTED_METHOD_NAMES = [ + '__CLASS__' => true, + '__DIR__' => true, + '__FILE__' => true, + '__FUNCTION__' => true, + '__LINE__' => true, + '__METHOD__' => true, + '__NAMESPACE__' => true, + '__TRAIT__' => true, + '__clone' => true, + '__halt_compiler' => true, + ]; + + /** + * @var array + */ + private static $cache = []; + + /** + * @var \Text_Template[] + */ + private static $templates = []; + + /** + * Returns a mock object for the specified class. + * + * @param string|string[] $type + * @param null|array $methods + * + * @throws RuntimeException + */ + public function getMock($type, $methods = [], array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false, object $proxyTarget = null, bool $allowMockingUnknownTypes = true, bool $returnValueGeneration = true): MockObject + { + if (!\is_array($type) && !\is_string($type)) { + throw InvalidArgumentException::create(1, 'array or string'); + } + + if (!\is_array($methods) && null !== $methods) { + throw InvalidArgumentException::create(2, 'array'); + } + + if ($type === 'Traversable' || $type === '\\Traversable') { + $type = 'Iterator'; + } + + if (\is_array($type)) { + $type = \array_unique( + \array_map( + static function ($type) { + if ($type === 'Traversable' || + $type === '\\Traversable' || + $type === '\\Iterator') { + return 'Iterator'; + } + + return $type; + }, + $type + ) + ); + } + + if (!$allowMockingUnknownTypes) { + if (\is_array($type)) { + foreach ($type as $_type) { + if (!\class_exists($_type, $callAutoload) && + !\interface_exists($_type, $callAutoload)) { + throw new RuntimeException( + \sprintf( + 'Cannot stub or mock class or interface "%s" which does not exist', + $_type + ) + ); + } + } + } elseif (!\class_exists($type, $callAutoload) && !\interface_exists($type, $callAutoload)) { + throw new RuntimeException( + \sprintf( + 'Cannot stub or mock class or interface "%s" which does not exist', + $type + ) + ); + } + } + + if (null !== $methods) { + foreach ($methods as $method) { + if (!\preg_match('~[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*~', (string) $method)) { + throw new RuntimeException( + \sprintf( + 'Cannot stub or mock method with invalid name "%s"', + $method + ) + ); + } + } + + if ($methods !== \array_unique($methods)) { + throw new RuntimeException( + \sprintf( + 'Cannot stub or mock using a method list that contains duplicates: "%s" (duplicate: "%s")', + \implode(', ', $methods), + \implode(', ', \array_unique(\array_diff_assoc($methods, \array_unique($methods)))) + ) + ); + } + } + + if ($mockClassName !== '' && \class_exists($mockClassName, false)) { + try { + $reflector = new \ReflectionClass($mockClassName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$reflector->implementsInterface(MockObject::class)) { + throw new RuntimeException( + \sprintf( + 'Class "%s" already exists.', + $mockClassName + ) + ); + } + } + + if (!$callOriginalConstructor && $callOriginalMethods) { + throw new RuntimeException( + 'Proxying to original methods requires invoking the original constructor' + ); + } + + $mock = $this->generate( + $type, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + + return $this->getObject( + $mock, + $type, + $callOriginalConstructor, + $callAutoload, + $arguments, + $callOriginalMethods, + $proxyTarget, + $returnValueGeneration + ); + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods to mock can be specified with + * the $mockedMethods parameter + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string $originalClassName + * @psalm-return MockObject&RealInstanceType + * + * @throws RuntimeException + */ + public function getMockForAbstractClass(string $originalClassName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = null, bool $cloneArguments = true): MockObject + { + if (\class_exists($originalClassName, $callAutoload) || + \interface_exists($originalClassName, $callAutoload)) { + try { + $reflector = new \ReflectionClass($originalClassName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methods = $mockedMethods; + + foreach ($reflector->getMethods() as $method) { + if ($method->isAbstract() && !\in_array($method->getName(), $methods ?? [], true)) { + $methods[] = $method->getName(); + } + } + + if (empty($methods)) { + $methods = null; + } + + return $this->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + } + + throw new RuntimeException( + \sprintf('Class "%s" does not exist.', $originalClassName) + ); + } + + /** + * Returns a mock object for the specified trait with all abstract methods + * of the trait mocked. Concrete methods to mock can be specified with the + * `$mockedMethods` parameter. + * + * @throws RuntimeException + */ + public function getMockForTrait(string $traitName, array $arguments = [], string $mockClassName = '', bool $callOriginalConstructor = true, bool $callOriginalClone = true, bool $callAutoload = true, array $mockedMethods = null, bool $cloneArguments = true): MockObject + { + if (!\trait_exists($traitName, $callAutoload)) { + throw new RuntimeException( + \sprintf( + 'Trait "%s" does not exist.', + $traitName + ) + ); + } + + $className = $this->generateClassName( + $traitName, + '', + 'Trait_' + ); + + $classTemplate = $this->getTemplate('trait_class.tpl'); + + $classTemplate->setVar( + [ + 'prologue' => 'abstract ', + 'class_name' => $className['className'], + 'trait_name' => $traitName, + ] + ); + + $mockTrait = new MockTrait($classTemplate->render(), $className['className']); + $mockTrait->generate(); + + return $this->getMockForAbstractClass($className['className'], $arguments, $mockClassName, $callOriginalConstructor, $callOriginalClone, $callAutoload, $mockedMethods, $cloneArguments); + } + + /** + * Returns an object for the specified trait. + * + * @throws RuntimeException + */ + public function getObjectForTrait(string $traitName, string $traitClassName = '', bool $callAutoload = true, bool $callOriginalConstructor = false, array $arguments = []): object + { + if (!\trait_exists($traitName, $callAutoload)) { + throw new RuntimeException( + \sprintf( + 'Trait "%s" does not exist.', + $traitName + ) + ); + } + + $className = $this->generateClassName( + $traitName, + $traitClassName, + 'Trait_' + ); + + $classTemplate = $this->getTemplate('trait_class.tpl'); + + $classTemplate->setVar( + [ + 'prologue' => '', + 'class_name' => $className['className'], + 'trait_name' => $traitName, + ] + ); + + return $this->getObject( + new MockTrait( + $classTemplate->render(), + $className['className'] + ), + '', + $callOriginalConstructor, + $callAutoload, + $arguments + ); + } + + public function generate($type, array $methods = null, string $mockClassName = '', bool $callOriginalClone = true, bool $callAutoload = true, bool $cloneArguments = true, bool $callOriginalMethods = false): MockClass + { + if (\is_array($type)) { + \sort($type); + } + + if ($mockClassName !== '') { + return $this->generateMock( + $type, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + } + + $key = \md5( + \is_array($type) ? \implode('_', $type) : $type . + \serialize($methods) . + \serialize($callOriginalClone) . + \serialize($cloneArguments) . + \serialize($callOriginalMethods) + ); + + if (!isset(self::$cache[$key])) { + self::$cache[$key] = $this->generateMock( + $type, + $methods, + $mockClassName, + $callOriginalClone, + $callAutoload, + $cloneArguments, + $callOriginalMethods + ); + } + + return self::$cache[$key]; + } + + /** + * @throws RuntimeException + */ + public function generateClassFromWsdl(string $wsdlFile, string $className, array $methods = [], array $options = []): string + { + if (!\extension_loaded('soap')) { + throw new RuntimeException( + 'The SOAP extension is required to generate a mock object from WSDL.' + ); + } + + $options = \array_merge($options, ['cache_wsdl' => \WSDL_CACHE_NONE]); + + try { + $client = new \SoapClient($wsdlFile, $options); + $_methods = \array_unique($client->__getFunctions()); + unset($client); + } catch (\SoapFault $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + + \sort($_methods); + + $methodTemplate = $this->getTemplate('wsdl_method.tpl'); + $methodsBuffer = ''; + + foreach ($_methods as $method) { + \preg_match_all('/[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(/', $method, $matches, \PREG_OFFSET_CAPTURE); + $lastFunction = \array_pop($matches[0]); + $nameStart = $lastFunction[1]; + $nameEnd = $nameStart + \strlen($lastFunction[0]) - 1; + $name = \str_replace('(', '', $lastFunction[0]); + + if (empty($methods) || \in_array($name, $methods, true)) { + $args = \explode( + ',', + \str_replace(')', '', \substr($method, $nameEnd + 1)) + ); + + foreach (\range(0, \count($args) - 1) as $i) { + $args[$i] = \substr($args[$i], \strpos($args[$i], '$')); + } + + $methodTemplate->setVar( + [ + 'method_name' => $name, + 'arguments' => \implode(', ', $args), + ] + ); + + $methodsBuffer .= $methodTemplate->render(); + } + } + + $optionsBuffer = '['; + + foreach ($options as $key => $value) { + $optionsBuffer .= $key . ' => ' . $value; + } + + $optionsBuffer .= ']'; + + $classTemplate = $this->getTemplate('wsdl_class.tpl'); + $namespace = ''; + + if (\strpos($className, '\\') !== false) { + $parts = \explode('\\', $className); + $className = \array_pop($parts); + $namespace = 'namespace ' . \implode('\\', $parts) . ';' . "\n\n"; + } + + $classTemplate->setVar( + [ + 'namespace' => $namespace, + 'class_name' => $className, + 'wsdl' => $wsdlFile, + 'options' => $optionsBuffer, + 'methods' => $methodsBuffer, + ] + ); + + return $classTemplate->render(); + } + + /** + * @throws RuntimeException + * + * @return string[] + */ + public function getClassMethods(string $className): array + { + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methods = []; + + foreach ($class->getMethods() as $method) { + if ($method->isPublic() || $method->isAbstract()) { + $methods[] = $method->getName(); + } + } + + return $methods; + } + + /** + * @throws RuntimeException + * + * @return MockMethod[] + */ + public function mockClassMethods(string $className, bool $callOriginalMethods, bool $cloneArguments): array + { + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methods = []; + + foreach ($class->getMethods() as $method) { + if (($method->isPublic() || $method->isAbstract()) && $this->canMockMethod($method)) { + $methods[] = MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments); + } + } + + return $methods; + } + + /** + * @throws RuntimeException + * + * @return MockMethod[] + */ + public function mockInterfaceMethods(string $interfaceName, bool $cloneArguments): array + { + try { + $class = new \ReflectionClass($interfaceName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methods = []; + + foreach ($class->getMethods() as $method) { + $methods[] = MockMethod::fromReflection($method, false, $cloneArguments); + } + + return $methods; + } + + /** + * @psalm-param class-string $interfaceName + * + * @return \ReflectionMethod[] + */ + private function userDefinedInterfaceMethods(string $interfaceName): array + { + try { + // @codeCoverageIgnoreStart + $interface = new \ReflectionClass($interfaceName); + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methods = []; + + foreach ($interface->getMethods() as $method) { + if (!$method->isUserDefined()) { + continue; + } + + $methods[] = $method; + } + + return $methods; + } + + private function getObject(MockType $mockClass, $type = '', bool $callOriginalConstructor = false, bool $callAutoload = false, array $arguments = [], bool $callOriginalMethods = false, object $proxyTarget = null, bool $returnValueGeneration = true) + { + $className = $mockClass->generate(); + + if ($callOriginalConstructor) { + if (\count($arguments) === 0) { + $object = new $className; + } else { + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $object = $class->newInstanceArgs($arguments); + } + } else { + try { + $object = (new Instantiator)->instantiate($className); + } catch (InstantiatorException $exception) { + throw new RuntimeException($exception->getMessage()); + } + } + + if ($callOriginalMethods) { + if (!\is_object($proxyTarget)) { + if (\count($arguments) === 0) { + $proxyTarget = new $type; + } else { + try { + $class = new \ReflectionClass($type); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $proxyTarget = $class->newInstanceArgs($arguments); + } + } + + $object->__phpunit_setOriginalObject($proxyTarget); + } + + if ($object instanceof MockObject) { + $object->__phpunit_setReturnValueGeneration($returnValueGeneration); + } + + return $object; + } + + /** + * @param array|string $type + * + * @throws RuntimeException + */ + private function generateMock($type, ?array $explicitMethods, string $mockClassName, bool $callOriginalClone, bool $callAutoload, bool $cloneArguments, bool $callOriginalMethods): MockClass + { + $classTemplate = $this->getTemplate('mocked_class.tpl'); + $additionalInterfaces = []; + $mockedCloneMethod = false; + $unmockedCloneMethod = false; + $isClass = false; + $isInterface = false; + $class = null; + $mockMethods = new MockMethodSet; + + if (\is_array($type)) { + $interfaceMethods = []; + + foreach ($type as $_type) { + if (!\interface_exists($_type, $callAutoload)) { + throw new RuntimeException( + \sprintf( + 'Interface "%s" does not exist.', + $_type + ) + ); + } + + $additionalInterfaces[] = $_type; + + try { + $typeClass = new \ReflectionClass($_type); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + foreach ($this->getClassMethods($_type) as $method) { + if (\in_array($method, $interfaceMethods, true)) { + throw new RuntimeException( + \sprintf( + 'Duplicate method "%s" not allowed.', + $method + ) + ); + } + + try { + $methodReflection = $typeClass->getMethod($method); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($this->canMockMethod($methodReflection)) { + $mockMethods->addMethods( + MockMethod::fromReflection($methodReflection, $callOriginalMethods, $cloneArguments) + ); + + $interfaceMethods[] = $method; + } + } + } + + unset($interfaceMethods); + } + + $mockClassName = $this->generateClassName( + $type, + $mockClassName, + 'Mock_' + ); + + if (\class_exists($mockClassName['fullClassName'], $callAutoload)) { + $isClass = true; + } elseif (\interface_exists($mockClassName['fullClassName'], $callAutoload)) { + $isInterface = true; + } + + if (!$isClass && !$isInterface) { + $prologue = 'class ' . $mockClassName['originalClassName'] . "\n{\n}\n\n"; + + if (!empty($mockClassName['namespaceName'])) { + $prologue = 'namespace ' . $mockClassName['namespaceName'] . + " {\n\n" . $prologue . "}\n\n" . + "namespace {\n\n"; + + $epilogue = "\n\n}"; + } + + $mockedCloneMethod = true; + } else { + try { + $class = new \ReflectionClass($mockClassName['fullClassName']); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($class->isFinal()) { + throw new RuntimeException( + \sprintf( + 'Class "%s" is declared "final" and cannot be mocked.', + $mockClassName['fullClassName'] + ) + ); + } + + // @see https://github.com/sebastianbergmann/phpunit/issues/2995 + if ($isInterface && $class->implementsInterface(\Throwable::class)) { + $actualClassName = \Exception::class; + $additionalInterfaces[] = $class->getName(); + $isInterface = false; + + try { + $class = new \ReflectionClass($actualClassName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + foreach ($this->userDefinedInterfaceMethods($mockClassName['fullClassName']) as $method) { + $methodName = $method->getName(); + + if ($class->hasMethod($methodName)) { + try { + $classMethod = $class->getMethod($methodName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$this->canMockMethod($classMethod)) { + continue; + } + } + + $mockMethods->addMethods( + MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments) + ); + } + + $mockClassName = $this->generateClassName( + $actualClassName, + $mockClassName['className'], + 'Mock_' + ); + } + + // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/103 + if ($isInterface && $class->implementsInterface(\Traversable::class) && + !$class->implementsInterface(\Iterator::class) && + !$class->implementsInterface(\IteratorAggregate::class)) { + $additionalInterfaces[] = \Iterator::class; + + $mockMethods->addMethods( + ...$this->mockClassMethods(\Iterator::class, $callOriginalMethods, $cloneArguments) + ); + } + + if ($class->hasMethod('__clone')) { + try { + $cloneMethod = $class->getMethod('__clone'); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$cloneMethod->isFinal()) { + if ($callOriginalClone && !$isInterface) { + $unmockedCloneMethod = true; + } else { + $mockedCloneMethod = true; + } + } + } else { + $mockedCloneMethod = true; + } + } + + if ($isClass && $explicitMethods === []) { + $mockMethods->addMethods( + ...$this->mockClassMethods($mockClassName['fullClassName'], $callOriginalMethods, $cloneArguments) + ); + } + + if ($isInterface && ($explicitMethods === [] || $explicitMethods === null)) { + $mockMethods->addMethods( + ...$this->mockInterfaceMethods($mockClassName['fullClassName'], $cloneArguments) + ); + } + + if (\is_array($explicitMethods)) { + foreach ($explicitMethods as $methodName) { + if ($class !== null && $class->hasMethod($methodName)) { + try { + $method = $class->getMethod($methodName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($this->canMockMethod($method)) { + $mockMethods->addMethods( + MockMethod::fromReflection($method, $callOriginalMethods, $cloneArguments) + ); + } + } else { + $mockMethods->addMethods( + MockMethod::fromName( + $mockClassName['fullClassName'], + $methodName, + $cloneArguments + ) + ); + } + } + } + + $mockedMethods = ''; + $configurable = []; + + foreach ($mockMethods->asArray() as $mockMethod) { + $mockedMethods .= $mockMethod->generateCode(); + $configurable[] = new ConfigurableMethod($mockMethod->getName(), $mockMethod->getReturnType()); + } + + $method = ''; + + if (!$mockMethods->hasMethod('method') && (!isset($class) || !$class->hasMethod('method'))) { + $method = \PHP_EOL . ' use \PHPUnit\Framework\MockObject\Method;'; + } + + $cloneTrait = ''; + + if ($mockedCloneMethod) { + $cloneTrait = \PHP_EOL . ' use \PHPUnit\Framework\MockObject\MockedCloneMethod;'; + } + + if ($unmockedCloneMethod) { + $cloneTrait = \PHP_EOL . ' use \PHPUnit\Framework\MockObject\UnmockedCloneMethod;'; + } + + $classTemplate->setVar( + [ + 'prologue' => $prologue ?? '', + 'epilogue' => $epilogue ?? '', + 'class_declaration' => $this->generateMockClassDeclaration( + $mockClassName, + $isInterface, + $additionalInterfaces + ), + 'clone' => $cloneTrait, + 'mock_class_name' => $mockClassName['className'], + 'mocked_methods' => $mockedMethods, + 'method' => $method, + ] + ); + + return new MockClass( + $classTemplate->render(), + $mockClassName['className'], + $configurable + ); + } + + /** + * @param array|string $type + */ + private function generateClassName($type, string $className, string $prefix): array + { + if (\is_array($type)) { + $type = \implode('_', $type); + } + + if ($type[0] === '\\') { + $type = \substr($type, 1); + } + + $classNameParts = \explode('\\', $type); + + if (\count($classNameParts) > 1) { + $type = \array_pop($classNameParts); + $namespaceName = \implode('\\', $classNameParts); + $fullClassName = $namespaceName . '\\' . $type; + } else { + $namespaceName = ''; + $fullClassName = $type; + } + + if ($className === '') { + do { + $className = $prefix . $type . '_' . + \substr(\md5((string) \mt_rand()), 0, 8); + } while (\class_exists($className, false)); + } + + return [ + 'className' => $className, + 'originalClassName' => $type, + 'fullClassName' => $fullClassName, + 'namespaceName' => $namespaceName, + ]; + } + + private function generateMockClassDeclaration(array $mockClassName, bool $isInterface, array $additionalInterfaces = []): string + { + $buffer = 'class '; + + $additionalInterfaces[] = MockObject::class; + $interfaces = \implode(', ', $additionalInterfaces); + + if ($isInterface) { + $buffer .= \sprintf( + '%s implements %s', + $mockClassName['className'], + $interfaces + ); + + if (!\in_array($mockClassName['originalClassName'], $additionalInterfaces, true)) { + $buffer .= ', '; + + if (!empty($mockClassName['namespaceName'])) { + $buffer .= $mockClassName['namespaceName'] . '\\'; + } + + $buffer .= $mockClassName['originalClassName']; + } + } else { + $buffer .= \sprintf( + '%s extends %s%s implements %s', + $mockClassName['className'], + !empty($mockClassName['namespaceName']) ? $mockClassName['namespaceName'] . '\\' : '', + $mockClassName['originalClassName'], + $interfaces + ); + } + + return $buffer; + } + + private function canMockMethod(\ReflectionMethod $method): bool + { + return !($this->isConstructor($method) || $method->isFinal() || $method->isPrivate() || $this->isMethodNameBlacklisted($method->getName())); + } + + private function isMethodNameBlacklisted(string $name): bool + { + return isset(self::BLACKLISTED_METHOD_NAMES[$name]); + } + + private function getTemplate(string $template): \Text_Template + { + $filename = __DIR__ . \DIRECTORY_SEPARATOR . 'Generator' . \DIRECTORY_SEPARATOR . $template; + + if (!isset(self::$templates[$filename])) { + self::$templates[$filename] = new \Text_Template($filename); + } + + return self::$templates[$filename]; + } + + /** + * @see https://github.com/sebastianbergmann/phpunit/issues/4139#issuecomment-605409765 + */ + private function isConstructor(\ReflectionMethod $method): bool + { + $methodName = \strtolower($method->getName()); + + if ($methodName === '__construct') { + return true; + } + + if (\PHP_MAJOR_VERSION >= 8) { + return false; + } + + $className = \strtolower($method->getDeclaringClass()->getName()); + + return $methodName === $className; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl new file mode 100644 index 0000000..5bf06f5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/deprecation.tpl @@ -0,0 +1,2 @@ + + @trigger_error({deprecation}, E_USER_DEPRECATED); diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl new file mode 100644 index 0000000..593119f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_class.tpl @@ -0,0 +1,6 @@ +declare(strict_types=1); + +{prologue}{class_declaration} +{ + use \PHPUnit\Framework\MockObject\Api;{method}{clone} +{mocked_methods}}{epilogue} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl new file mode 100644 index 0000000..32304f3 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method.tpl @@ -0,0 +1,22 @@ + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + {{deprecation} + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $__phpunit_result = $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_declaration}', $this, {clone_arguments} + ) + ); + + return $__phpunit_result; + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl new file mode 100644 index 0000000..6ea6f45 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_void.tpl @@ -0,0 +1,20 @@ + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + {{deprecation} + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_declaration}', $this, {clone_arguments} + ) + ); + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl new file mode 100644 index 0000000..5e5cf23 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_static_method.tpl @@ -0,0 +1,5 @@ + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + { + throw new \PHPUnit\Framework\MockObject\BadMethodCallException('Static method "{method_name}" cannot be invoked on mock object'); + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl new file mode 100644 index 0000000..6f699be --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method.tpl @@ -0,0 +1,22 @@ + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + { + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_declaration}', $this, {clone_arguments}, true + ) + ); + + return call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments); + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl new file mode 100644 index 0000000..b2f963d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_void.tpl @@ -0,0 +1,22 @@ + + {modifier} function {reference}{method_name}({arguments_decl}){return_declaration} + { + $__phpunit_arguments = [{arguments_call}]; + $__phpunit_count = func_num_args(); + + if ($__phpunit_count > {arguments_count}) { + $__phpunit_arguments_tmp = func_get_args(); + + for ($__phpunit_i = {arguments_count}; $__phpunit_i < $__phpunit_count; $__phpunit_i++) { + $__phpunit_arguments[] = $__phpunit_arguments_tmp[$__phpunit_i]; + } + } + + $this->__phpunit_getInvocationHandler()->invoke( + new \PHPUnit\Framework\MockObject\Invocation( + '{class_name}', '{method_name}', $__phpunit_arguments, '{return_declaration}', $this, {clone_arguments}, true + ) + ); + + call_user_func_array(array($this->__phpunit_originalObject, "{method_name}"), $__phpunit_arguments); + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl new file mode 100644 index 0000000..a8fe470 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/trait_class.tpl @@ -0,0 +1,6 @@ +declare(strict_types=1); + +{prologue}class {class_name} +{ + use {trait_name}; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl new file mode 100644 index 0000000..b3100b4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_class.tpl @@ -0,0 +1,9 @@ +declare(strict_types=1); + +{namespace}class {class_name} extends \SoapClient +{ + public function __construct($wsdl, array $options) + { + parent::__construct('{wsdl}', $options); + } +{methods}} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl new file mode 100644 index 0000000..bb16e76 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/wsdl_method.tpl @@ -0,0 +1,4 @@ + + public function {method_name}({arguments}) + { + } diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php new file mode 100644 index 0000000..228cf0d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Invocation.php @@ -0,0 +1,190 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Util\Type; +use SebastianBergmann\Exporter\Exporter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Invocation implements SelfDescribing +{ + /** + * @var string + */ + private $className; + + /** + * @var string + */ + private $methodName; + + /** + * @var array + */ + private $parameters; + + /** + * @var string + */ + private $returnType; + + /** + * @var bool + */ + private $isReturnTypeNullable = false; + + /** + * @var bool + */ + private $proxiedCall; + + /** + * @var object + */ + private $object; + + public function __construct(string $className, string $methodName, array $parameters, string $returnType, object $object, bool $cloneObjects = false, bool $proxiedCall = false) + { + $this->className = $className; + $this->methodName = $methodName; + $this->parameters = $parameters; + $this->object = $object; + $this->proxiedCall = $proxiedCall; + + $returnType = \ltrim($returnType, ': '); + + if (\strtolower($methodName) === '__tostring') { + $returnType = 'string'; + } + + if (\strpos($returnType, '?') === 0) { + $returnType = \substr($returnType, 1); + $this->isReturnTypeNullable = true; + } + + $this->returnType = $returnType; + + if (!$cloneObjects) { + return; + } + + foreach ($this->parameters as $key => $value) { + if (\is_object($value)) { + $this->parameters[$key] = $this->cloneObject($value); + } + } + } + + public function getClassName(): string + { + return $this->className; + } + + public function getMethodName(): string + { + return $this->methodName; + } + + public function getParameters(): array + { + return $this->parameters; + } + + /** + * @throws RuntimeException + * + * @return mixed Mocked return value + */ + public function generateReturnValue() + { + if ($this->isReturnTypeNullable || $this->proxiedCall) { + return; + } + + switch (\strtolower($this->returnType)) { + case '': + case 'void': + return; + + case 'string': + return ''; + + case 'float': + return 0.0; + + case 'int': + return 0; + + case 'bool': + return false; + + case 'array': + return []; + + case 'object': + return new \stdClass; + + case 'callable': + case 'closure': + return function (): void { + }; + + case 'traversable': + case 'generator': + case 'iterable': + $generator = static function () { + yield; + }; + + return $generator(); + + default: + $generator = new Generator; + + return $generator->getMock($this->returnType, [], [], '', false); + } + } + + public function toString(): string + { + $exporter = new Exporter; + + return \sprintf( + '%s::%s(%s)%s', + $this->className, + $this->methodName, + \implode( + ', ', + \array_map( + [$exporter, 'shortenedExport'], + $this->parameters + ) + ), + $this->returnType ? \sprintf(': %s', $this->returnType) : '' + ); + } + + public function getObject(): object + { + return $this->object; + } + + private function cloneObject(object $original): object + { + if (Type::isCloneable($original)) { + return clone $original; + } + + return $original; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php b/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php new file mode 100644 index 0000000..cd1ea0d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/InvocationHandler.php @@ -0,0 +1,194 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use Exception; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Builder\InvocationMocker; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvocationHandler +{ + /** + * @var Matcher[] + */ + private $matchers = []; + + /** + * @var Matcher[] + */ + private $matcherMap = []; + + /** + * @var ConfigurableMethod[] + */ + private $configurableMethods; + + /** + * @var bool + */ + private $returnValueGeneration; + + /** + * @var \Throwable + */ + private $deferredError; + + public function __construct(array $configurableMethods, bool $returnValueGeneration) + { + $this->configurableMethods = $configurableMethods; + $this->returnValueGeneration = $returnValueGeneration; + } + + public function hasMatchers(): bool + { + foreach ($this->matchers as $matcher) { + if ($matcher->hasMatchers()) { + return true; + } + } + + return false; + } + + /** + * Looks up the match builder with identification $id and returns it. + * + * @param string $id The identification of the match builder + */ + public function lookupMatcher(string $id): ?Matcher + { + if (isset($this->matcherMap[$id])) { + return $this->matcherMap[$id]; + } + + return null; + } + + /** + * Registers a matcher with the identification $id. The matcher can later be + * looked up using lookupMatcher() to figure out if it has been invoked. + * + * @param string $id The identification of the matcher + * @param Matcher $matcher The builder which is being registered + * + * @throws RuntimeException + */ + public function registerMatcher(string $id, Matcher $matcher): void + { + if (isset($this->matcherMap[$id])) { + throw new RuntimeException( + 'Matcher with id <' . $id . '> is already registered.' + ); + } + + $this->matcherMap[$id] = $matcher; + } + + public function expects(InvocationOrder $rule): InvocationMocker + { + $matcher = new Matcher($rule); + $this->addMatcher($matcher); + + return new InvocationMocker( + $this, + $matcher, + ...$this->configurableMethods + ); + } + + /** + * @throws Exception + * + * @return mixed|void + */ + public function invoke(Invocation $invocation) + { + $exception = null; + $hasReturnValue = false; + $returnValue = null; + + foreach ($this->matchers as $match) { + try { + if ($match->matches($invocation)) { + $value = $match->invoked($invocation); + + if (!$hasReturnValue) { + $returnValue = $value; + $hasReturnValue = true; + } + } + } catch (Exception $e) { + $exception = $e; + } + } + + if ($exception !== null) { + throw $exception; + } + + if ($hasReturnValue) { + return $returnValue; + } + + if (!$this->returnValueGeneration) { + $exception = new ExpectationFailedException( + \sprintf( + 'Return value inference disabled and no expectation set up for %s::%s()', + $invocation->getClassName(), + $invocation->getMethodName() + ) + ); + + if (\strtolower($invocation->getMethodName()) === '__tostring') { + $this->deferredError = $exception; + + return ''; + } + + throw $exception; + } + + return $invocation->generateReturnValue(); + } + + public function matches(Invocation $invocation): bool + { + foreach ($this->matchers as $matcher) { + if (!$matcher->matches($invocation)) { + return false; + } + } + + return true; + } + + /** + * @throws \PHPUnit\Framework\ExpectationFailedException + */ + public function verify(): void + { + foreach ($this->matchers as $matcher) { + $matcher->verify(); + } + + if ($this->deferredError) { + throw $this->deferredError; + } + } + + private function addMatcher(Matcher $matcher): void + { + $this->matchers[] = $matcher; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php new file mode 100644 index 0000000..6179eeb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Matcher.php @@ -0,0 +1,274 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount; +use PHPUnit\Framework\MockObject\Rule\AnyParameters; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; +use PHPUnit\Framework\MockObject\Rule\InvokedCount; +use PHPUnit\Framework\MockObject\Rule\MethodName; +use PHPUnit\Framework\MockObject\Rule\ParametersRule; +use PHPUnit\Framework\MockObject\Stub\Stub; +use PHPUnit\Framework\TestFailure; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Matcher +{ + /** + * @var InvocationOrder + */ + private $invocationRule; + + /** + * @var mixed + */ + private $afterMatchBuilderId; + + /** + * @var bool + */ + private $afterMatchBuilderIsInvoked = false; + + /** + * @var MethodName + */ + private $methodNameRule; + + /** + * @var ParametersRule + */ + private $parametersRule; + + /** + * @var Stub + */ + private $stub; + + public function __construct(InvocationOrder $rule) + { + $this->invocationRule = $rule; + } + + public function hasMatchers(): bool + { + return !$this->invocationRule instanceof AnyInvokedCount; + } + + public function hasMethodNameRule(): bool + { + return $this->methodNameRule !== null; + } + + public function getMethodNameRule(): MethodName + { + return $this->methodNameRule; + } + + public function setMethodNameRule(MethodName $rule): void + { + $this->methodNameRule = $rule; + } + + public function hasParametersRule(): bool + { + return $this->parametersRule !== null; + } + + public function setParametersRule(ParametersRule $rule): void + { + $this->parametersRule = $rule; + } + + public function setStub(Stub $stub): void + { + $this->stub = $stub; + } + + public function setAfterMatchBuilderId(string $id): void + { + $this->afterMatchBuilderId = $id; + } + + /** + * @throws \Exception + * @throws RuntimeException + * @throws ExpectationFailedException + */ + public function invoked(Invocation $invocation) + { + if ($this->methodNameRule === null) { + throw new RuntimeException('No method rule is set'); + } + + if ($this->afterMatchBuilderId !== null) { + $matcher = $invocation->getObject() + ->__phpunit_getInvocationHandler() + ->lookupMatcher($this->afterMatchBuilderId); + + if (!$matcher) { + throw new RuntimeException( + \sprintf( + 'No builder found for match builder identification <%s>', + $this->afterMatchBuilderId + ) + ); + } + \assert($matcher instanceof self); + + if ($matcher->invocationRule->hasBeenInvoked()) { + $this->afterMatchBuilderIsInvoked = true; + } + } + + $this->invocationRule->invoked($invocation); + + try { + if ($this->parametersRule !== null) { + $this->parametersRule->apply($invocation); + } + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException( + \sprintf( + "Expectation failed for %s when %s\n%s", + $this->methodNameRule->toString(), + $this->invocationRule->toString(), + $e->getMessage() + ), + $e->getComparisonFailure() + ); + } + + if ($this->stub) { + return $this->stub->invoke($invocation); + } + + return $invocation->generateReturnValue(); + } + + /** + * @throws RuntimeException + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function matches(Invocation $invocation): bool + { + if ($this->afterMatchBuilderId !== null) { + $matcher = $invocation->getObject() + ->__phpunit_getInvocationHandler() + ->lookupMatcher($this->afterMatchBuilderId); + + if (!$matcher) { + throw new RuntimeException( + \sprintf( + 'No builder found for match builder identification <%s>', + $this->afterMatchBuilderId + ) + ); + } + \assert($matcher instanceof self); + + if (!$matcher->invocationRule->hasBeenInvoked()) { + return false; + } + } + + if ($this->methodNameRule === null) { + throw new RuntimeException('No method rule is set'); + } + + if (!$this->invocationRule->matches($invocation)) { + return false; + } + + try { + if (!$this->methodNameRule->matches($invocation)) { + return false; + } + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException( + \sprintf( + "Expectation failed for %s when %s\n%s", + $this->methodNameRule->toString(), + $this->invocationRule->toString(), + $e->getMessage() + ), + $e->getComparisonFailure() + ); + } + + return true; + } + + /** + * @throws RuntimeException + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function verify(): void + { + if ($this->methodNameRule === null) { + throw new RuntimeException('No method rule is set'); + } + + try { + $this->invocationRule->verify(); + + if ($this->parametersRule === null) { + $this->parametersRule = new AnyParameters; + } + + $invocationIsAny = $this->invocationRule instanceof AnyInvokedCount; + $invocationIsNever = $this->invocationRule instanceof InvokedCount && $this->invocationRule->isNever(); + + if (!$invocationIsAny && !$invocationIsNever) { + $this->parametersRule->verify(); + } + } catch (ExpectationFailedException $e) { + throw new ExpectationFailedException( + \sprintf( + "Expectation failed for %s when %s.\n%s", + $this->methodNameRule->toString(), + $this->invocationRule->toString(), + TestFailure::exceptionToString($e) + ) + ); + } + } + + public function toString(): string + { + $list = []; + + if ($this->invocationRule !== null) { + $list[] = $this->invocationRule->toString(); + } + + if ($this->methodNameRule !== null) { + $list[] = 'where ' . $this->methodNameRule->toString(); + } + + if ($this->parametersRule !== null) { + $list[] = 'and ' . $this->parametersRule->toString(); + } + + if ($this->afterMatchBuilderId !== null) { + $list[] = 'after ' . $this->afterMatchBuilderId; + } + + if ($this->stub !== null) { + $list[] = 'will ' . $this->stub->toString(); + } + + return \implode(' ', $list); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php new file mode 100644 index 0000000..18e5772 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MethodNameConstraint.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\Constraint\Constraint; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MethodNameConstraint extends Constraint +{ + /** + * @var string + */ + private $methodName; + + public function __construct(string $methodName) + { + $this->methodName = $methodName; + } + + public function toString(): string + { + return \sprintf( + 'is "%s"', + $this->methodName + ); + } + + protected function matches($other): bool + { + if (!\is_string($other)) { + return false; + } + + return \strtolower($this->methodName) === \strtolower($other); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php new file mode 100644 index 0000000..3eeb36a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockBuilder.php @@ -0,0 +1,506 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\TestCase; + +/** + * @psalm-template MockedType + */ +final class MockBuilder +{ + /** + * @var TestCase + */ + private $testCase; + + /** + * @var string + */ + private $type; + + /** + * @var null|string[] + */ + private $methods = []; + + /** + * @var bool + */ + private $emptyMethodsArray = false; + + /** + * @var string + */ + private $mockClassName = ''; + + /** + * @var array + */ + private $constructorArgs = []; + + /** + * @var bool + */ + private $originalConstructor = true; + + /** + * @var bool + */ + private $originalClone = true; + + /** + * @var bool + */ + private $autoload = true; + + /** + * @var bool + */ + private $cloneArguments = false; + + /** + * @var bool + */ + private $callOriginalMethods = false; + + /** + * @var ?object + */ + private $proxyTarget; + + /** + * @var bool + */ + private $allowMockingUnknownTypes = true; + + /** + * @var bool + */ + private $returnValueGeneration = true; + + /** + * @var Generator + */ + private $generator; + + /** + * @param string|string[] $type + * + * @psalm-param class-string|string|string[] $type + */ + public function __construct(TestCase $testCase, $type) + { + $this->testCase = $testCase; + $this->type = $type; + $this->generator = new Generator; + } + + /** + * Creates a mock object using a fluent interface. + * + * @throws RuntimeException + * + * @psalm-return MockObject&MockedType + */ + public function getMock(): MockObject + { + $object = $this->generator->getMock( + $this->type, + !$this->emptyMethodsArray ? $this->methods : null, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->cloneArguments, + $this->callOriginalMethods, + $this->proxyTarget, + $this->allowMockingUnknownTypes, + $this->returnValueGeneration + ); + + $this->testCase->registerMockObject($object); + + return $object; + } + + /** + * Creates a mock object for an abstract class using a fluent interface. + * + * @throws \PHPUnit\Framework\Exception + * @throws RuntimeException + * + * @psalm-return MockObject&MockedType + */ + public function getMockForAbstractClass(): MockObject + { + $object = $this->generator->getMockForAbstractClass( + $this->type, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->methods, + $this->cloneArguments + ); + + $this->testCase->registerMockObject($object); + + return $object; + } + + /** + * Creates a mock object for a trait using a fluent interface. + * + * @throws \PHPUnit\Framework\Exception + * @throws RuntimeException + * + * @psalm-return MockObject&MockedType + */ + public function getMockForTrait(): MockObject + { + $object = $this->generator->getMockForTrait( + $this->type, + $this->constructorArgs, + $this->mockClassName, + $this->originalConstructor, + $this->originalClone, + $this->autoload, + $this->methods, + $this->cloneArguments + ); + + $this->testCase->registerMockObject($object); + + return $object; + } + + /** + * Specifies the subset of methods to mock. Default is to mock none of them. + * + * @deprecated https://github.com/sebastianbergmann/phpunit/pull/3687 + * + * @return $this + */ + public function setMethods(?array $methods = null): self + { + if ($methods === null) { + $this->methods = $methods; + } else { + $this->methods = \array_merge($this->methods ?? [], $methods); + } + + return $this; + } + + /** + * Specifies the subset of methods to mock, requiring each to exist in the class + * + * @param string[] $methods + * + * @throws RuntimeException + * + * @return $this + */ + public function onlyMethods(array $methods): self + { + if (empty($methods)) { + $this->emptyMethodsArray = true; + + return $this; + } + + try { + $reflector = new \ReflectionClass($this->type); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + foreach ($methods as $method) { + if (!$reflector->hasMethod($method)) { + throw new RuntimeException( + \sprintf( + 'Trying to set mock method "%s" with onlyMethods, but it does not exist in class "%s". Use addMethods() for methods that don\'t exist in the class.', + $method, + $this->type + ) + ); + } + } + + $this->methods = \array_merge($this->methods ?? [], $methods); + + return $this; + } + + /** + * Specifies methods that don't exist in the class which you want to mock + * + * @param string[] $methods + * + * @throws RuntimeException + * + * @return $this + */ + public function addMethods(array $methods): self + { + if (empty($methods)) { + $this->emptyMethodsArray = true; + + return $this; + } + + try { + $reflector = new \ReflectionClass($this->type); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + foreach ($methods as $method) { + if ($reflector->hasMethod($method)) { + throw new RuntimeException( + \sprintf( + 'Trying to set mock method "%s" with addMethods(), but it exists in class "%s". Use onlyMethods() for methods that exist in the class.', + $method, + $this->type + ) + ); + } + } + + $this->methods = \array_merge($this->methods ?? [], $methods); + + return $this; + } + + /** + * Specifies the subset of methods to not mock. Default is to mock all of them. + */ + public function setMethodsExcept(array $methods = []): self + { + return $this->setMethods( + \array_diff( + $this->generator->getClassMethods($this->type), + $methods + ) + ); + } + + /** + * Specifies the arguments for the constructor. + * + * @return $this + */ + public function setConstructorArgs(array $args): self + { + $this->constructorArgs = $args; + + return $this; + } + + /** + * Specifies the name for the mock class. + * + * @return $this + */ + public function setMockClassName(string $name): self + { + $this->mockClassName = $name; + + return $this; + } + + /** + * Disables the invocation of the original constructor. + * + * @return $this + */ + public function disableOriginalConstructor(): self + { + $this->originalConstructor = false; + + return $this; + } + + /** + * Enables the invocation of the original constructor. + * + * @return $this + */ + public function enableOriginalConstructor(): self + { + $this->originalConstructor = true; + + return $this; + } + + /** + * Disables the invocation of the original clone constructor. + * + * @return $this + */ + public function disableOriginalClone(): self + { + $this->originalClone = false; + + return $this; + } + + /** + * Enables the invocation of the original clone constructor. + * + * @return $this + */ + public function enableOriginalClone(): self + { + $this->originalClone = true; + + return $this; + } + + /** + * Disables the use of class autoloading while creating the mock object. + * + * @return $this + */ + public function disableAutoload(): self + { + $this->autoload = false; + + return $this; + } + + /** + * Enables the use of class autoloading while creating the mock object. + * + * @return $this + */ + public function enableAutoload(): self + { + $this->autoload = true; + + return $this; + } + + /** + * Disables the cloning of arguments passed to mocked methods. + * + * @return $this + */ + public function disableArgumentCloning(): self + { + $this->cloneArguments = false; + + return $this; + } + + /** + * Enables the cloning of arguments passed to mocked methods. + * + * @return $this + */ + public function enableArgumentCloning(): self + { + $this->cloneArguments = true; + + return $this; + } + + /** + * Enables the invocation of the original methods. + * + * @return $this + */ + public function enableProxyingToOriginalMethods(): self + { + $this->callOriginalMethods = true; + + return $this; + } + + /** + * Disables the invocation of the original methods. + * + * @return $this + */ + public function disableProxyingToOriginalMethods(): self + { + $this->callOriginalMethods = false; + $this->proxyTarget = null; + + return $this; + } + + /** + * Sets the proxy target. + * + * @return $this + */ + public function setProxyTarget(object $object): self + { + $this->proxyTarget = $object; + + return $this; + } + + /** + * @return $this + */ + public function allowMockingUnknownTypes(): self + { + $this->allowMockingUnknownTypes = true; + + return $this; + } + + /** + * @return $this + */ + public function disallowMockingUnknownTypes(): self + { + $this->allowMockingUnknownTypes = false; + + return $this; + } + + /** + * @return $this + */ + public function enableAutoReturnValueGeneration(): self + { + $this->returnValueGeneration = true; + + return $this; + } + + /** + * @return $this + */ + public function disableAutoReturnValueGeneration(): self + { + $this->returnValueGeneration = false; + + return $this; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php new file mode 100644 index 0000000..938db87 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockClass.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MockClass implements MockType +{ + /** + * @var string + */ + private $classCode; + + /** + * @var string + */ + private $mockName; + + /** + * @var ConfigurableMethod[] + */ + private $configurableMethods; + + public function __construct(string $classCode, string $mockName, array $configurableMethods) + { + $this->classCode = $classCode; + $this->mockName = $mockName; + $this->configurableMethods = $configurableMethods; + } + + public function generate(): string + { + if (!\class_exists($this->mockName, false)) { + eval($this->classCode); + + \call_user_func( + [ + $this->mockName, + '__phpunit_initConfigurableMethods', + ], + ...$this->configurableMethods + ); + } + + return $this->mockName; + } + + public function getClassCode(): string + { + return $this->classCode; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php new file mode 100644 index 0000000..85b7516 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethod.php @@ -0,0 +1,372 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use SebastianBergmann\Type\ObjectType; +use SebastianBergmann\Type\Type; +use SebastianBergmann\Type\UnknownType; +use SebastianBergmann\Type\VoidType; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MockMethod +{ + /** + * @var \Text_Template[] + */ + private static $templates = []; + + /** + * @var string + */ + private $className; + + /** + * @var string + */ + private $methodName; + + /** + * @var bool + */ + private $cloneArguments; + + /** + * @var string string + */ + private $modifier; + + /** + * @var string + */ + private $argumentsForDeclaration; + + /** + * @var string + */ + private $argumentsForCall; + + /** + * @var Type + */ + private $returnType; + + /** + * @var string + */ + private $reference; + + /** + * @var bool + */ + private $callOriginalMethod; + + /** + * @var bool + */ + private $static; + + /** + * @var ?string + */ + private $deprecation; + + /** + * @var bool + */ + private $allowsReturnNull; + + /** + * @throws RuntimeException + */ + public static function fromReflection(\ReflectionMethod $method, bool $callOriginalMethod, bool $cloneArguments): self + { + if ($method->isPrivate()) { + $modifier = 'private'; + } elseif ($method->isProtected()) { + $modifier = 'protected'; + } else { + $modifier = 'public'; + } + + if ($method->isStatic()) { + $modifier .= ' static'; + } + + if ($method->returnsReference()) { + $reference = '&'; + } else { + $reference = ''; + } + + $docComment = $method->getDocComment(); + + if (\is_string($docComment) && + \preg_match('#\*[ \t]*+@deprecated[ \t]*+(.*?)\r?+\n[ \t]*+\*(?:[ \t]*+@|/$)#s', $docComment, $deprecation)) { + $deprecation = \trim(\preg_replace('#[ \t]*\r?\n[ \t]*+\*[ \t]*+#', ' ', $deprecation[1])); + } else { + $deprecation = null; + } + + return new self( + $method->getDeclaringClass()->getName(), + $method->getName(), + $cloneArguments, + $modifier, + self::getMethodParameters($method), + self::getMethodParameters($method, true), + self::deriveReturnType($method), + $reference, + $callOriginalMethod, + $method->isStatic(), + $deprecation, + $method->hasReturnType() && $method->getReturnType()->allowsNull() + ); + } + + public static function fromName(string $fullClassName, string $methodName, bool $cloneArguments): self + { + return new self( + $fullClassName, + $methodName, + $cloneArguments, + 'public', + '', + '', + new UnknownType, + '', + false, + false, + null, + false + ); + } + + public function __construct(string $className, string $methodName, bool $cloneArguments, string $modifier, string $argumentsForDeclaration, string $argumentsForCall, Type $returnType, string $reference, bool $callOriginalMethod, bool $static, ?string $deprecation, bool $allowsReturnNull) + { + $this->className = $className; + $this->methodName = $methodName; + $this->cloneArguments = $cloneArguments; + $this->modifier = $modifier; + $this->argumentsForDeclaration = $argumentsForDeclaration; + $this->argumentsForCall = $argumentsForCall; + $this->returnType = $returnType; + $this->reference = $reference; + $this->callOriginalMethod = $callOriginalMethod; + $this->static = $static; + $this->deprecation = $deprecation; + $this->allowsReturnNull = $allowsReturnNull; + } + + public function getName(): string + { + return $this->methodName; + } + + /** + * @throws RuntimeException + */ + public function generateCode(): string + { + if ($this->static) { + $templateFile = 'mocked_static_method.tpl'; + } elseif ($this->returnType instanceof VoidType) { + $templateFile = \sprintf( + '%s_method_void.tpl', + $this->callOriginalMethod ? 'proxied' : 'mocked' + ); + } else { + $templateFile = \sprintf( + '%s_method.tpl', + $this->callOriginalMethod ? 'proxied' : 'mocked' + ); + } + + $deprecation = $this->deprecation; + + if (null !== $this->deprecation) { + $deprecation = "The $this->className::$this->methodName method is deprecated ($this->deprecation)."; + $deprecationTemplate = $this->getTemplate('deprecation.tpl'); + + $deprecationTemplate->setVar([ + 'deprecation' => \var_export($deprecation, true), + ]); + + $deprecation = $deprecationTemplate->render(); + } + + $template = $this->getTemplate($templateFile); + + $template->setVar( + [ + 'arguments_decl' => $this->argumentsForDeclaration, + 'arguments_call' => $this->argumentsForCall, + 'return_declaration' => $this->returnType->getReturnTypeDeclaration(), + 'arguments_count' => !empty($this->argumentsForCall) ? \substr_count($this->argumentsForCall, ',') + 1 : 0, + 'class_name' => $this->className, + 'method_name' => $this->methodName, + 'modifier' => $this->modifier, + 'reference' => $this->reference, + 'clone_arguments' => $this->cloneArguments ? 'true' : 'false', + 'deprecation' => $deprecation, + ] + ); + + return $template->render(); + } + + public function getReturnType(): Type + { + return $this->returnType; + } + + private function getTemplate(string $template): \Text_Template + { + $filename = __DIR__ . \DIRECTORY_SEPARATOR . 'Generator' . \DIRECTORY_SEPARATOR . $template; + + if (!isset(self::$templates[$filename])) { + self::$templates[$filename] = new \Text_Template($filename); + } + + return self::$templates[$filename]; + } + + /** + * Returns the parameters of a function or method. + * + * @throws RuntimeException + */ + private static function getMethodParameters(\ReflectionMethod $method, bool $forCall = false): string + { + $parameters = []; + + foreach ($method->getParameters() as $i => $parameter) { + $name = '$' . $parameter->getName(); + + /* Note: PHP extensions may use empty names for reference arguments + * or "..." for methods taking a variable number of arguments. + */ + if ($name === '$' || $name === '$...') { + $name = '$arg' . $i; + } + + if ($parameter->isVariadic()) { + if ($forCall) { + continue; + } + + $name = '...' . $name; + } + + $nullable = ''; + $default = ''; + $reference = ''; + $typeDeclaration = ''; + + if (!$forCall) { + if ($parameter->hasType() && $parameter->allowsNull()) { + $nullable = '?'; + } + + if ($parameter->hasType()) { + $type = $parameter->getType(); + + if ($type instanceof \ReflectionNamedType && $type->getName() !== 'self') { + $typeDeclaration = $type->getName() . ' '; + } else { + try { + $class = $parameter->getClass(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + \sprintf( + 'Cannot mock %s::%s() because a class or ' . + 'interface used in the signature is not loaded', + $method->getDeclaringClass()->getName(), + $method->getName() + ), + 0, + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($class !== null) { + $typeDeclaration = $class->getName() . ' '; + } + } + } + + if (!$parameter->isVariadic()) { + if ($parameter->isDefaultValueAvailable()) { + try { + $value = \var_export($parameter->getDefaultValue(), true); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new RuntimeException( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $default = ' = ' . $value; + } elseif ($parameter->isOptional()) { + $default = ' = null'; + } + } + } + + if ($parameter->isPassedByReference()) { + $reference = '&'; + } + + $parameters[] = $nullable . $typeDeclaration . $reference . $name . $default; + } + + return \implode(', ', $parameters); + } + + private static function deriveReturnType(\ReflectionMethod $method): Type + { + $returnType = $method->getReturnType(); + + if ($returnType === null) { + return new UnknownType(); + } + + // @see https://bugs.php.net/bug.php?id=70722 + if ($returnType->getName() === 'self') { + return ObjectType::fromName($method->getDeclaringClass()->getName(), $returnType->allowsNull()); + } + + // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/406 + if ($returnType->getName() === 'parent') { + $parentClass = $method->getDeclaringClass()->getParentClass(); + + if ($parentClass === false) { + throw new RuntimeException( + \sprintf( + 'Cannot mock %s::%s because "parent" return type declaration is used but %s does not have a parent class', + $method->getDeclaringClass()->getName(), + $method->getName(), + $method->getDeclaringClass()->getName() + ) + ); + } + + return ObjectType::fromName($parentClass->getName(), $returnType->allowsNull()); + } + + return Type::fromName($returnType->getName(), $returnType->allowsNull()); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php new file mode 100644 index 0000000..939437e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockMethodSet.php @@ -0,0 +1,41 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MockMethodSet +{ + /** + * @var MockMethod[] + */ + private $methods = []; + + public function addMethods(MockMethod ...$methods): void + { + foreach ($methods as $method) { + $this->methods[\strtolower($method->getName())] = $method; + } + } + + /** + * @return MockMethod[] + */ + public function asArray(): array + { + return \array_values($this->methods); + } + + public function hasMethod(string $methodName): bool + { + return \array_key_exists(\strtolower($methodName), $this->methods); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php new file mode 100644 index 0000000..4db11e1 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockObject.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\MockObject\Builder\InvocationMocker as BuilderInvocationMocker; +use PHPUnit\Framework\MockObject\Rule\InvocationOrder; + +/** + * @method BuilderInvocationMocker method($constraint) + */ +interface MockObject extends Stub +{ + public function __phpunit_setOriginalObject($originalObject): void; + + public function __phpunit_verify(bool $unsetInvocationMocker = true): void; + + public function expects(InvocationOrder $invocationRule): BuilderInvocationMocker; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php new file mode 100644 index 0000000..3ced889 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockTrait.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MockTrait implements MockType +{ + /** + * @var string + */ + private $classCode; + + /** + * @var string + */ + private $mockName; + + public function __construct(string $classCode, string $mockName) + { + $this->classCode = $classCode; + $this->mockName = $mockName; + } + + public function generate(): string + { + if (!\class_exists($this->mockName, false)) { + eval($this->classCode); + } + + return $this->mockName; + } + + public function getClassCode(): string + { + return $this->classCode; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php b/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php new file mode 100644 index 0000000..b35ac30 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/MockType.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface MockType +{ + public function generate(): string; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php new file mode 100644 index 0000000..f93e568 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyInvokedCount.php @@ -0,0 +1,36 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class AnyInvokedCount extends InvocationOrder +{ + public function toString(): string + { + return 'invoked zero or more times'; + } + + public function verify(): void + { + } + + public function matches(BaseInvocation $invocation): bool + { + return true; + } + + protected function invokedDo(BaseInvocation $invocation): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php new file mode 100644 index 0000000..61de788 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/AnyParameters.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class AnyParameters implements ParametersRule +{ + public function toString(): string + { + return 'with any parameters'; + } + + public function apply(BaseInvocation $invocation): void + { + } + + public function verify(): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php new file mode 100644 index 0000000..3a1f528 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ConsecutiveParameters.php @@ -0,0 +1,132 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\InvalidParameterGroupException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConsecutiveParameters implements ParametersRule +{ + /** + * @var array + */ + private $parameterGroups = []; + + /** + * @var array + */ + private $invocations = []; + + /** + * @throws \PHPUnit\Framework\Exception + */ + public function __construct(array $parameterGroups) + { + foreach ($parameterGroups as $index => $parameters) { + if (!\is_iterable($parameters)) { + throw new InvalidParameterGroupException( + \sprintf( + 'Parameter group #%d must be an array or Traversable, got %s', + $index, + \gettype($parameters) + ) + ); + } + + foreach ($parameters as $parameter) { + if (!$parameter instanceof Constraint) { + $parameter = new IsEqual($parameter); + } + + $this->parameterGroups[$index][] = $parameter; + } + } + } + + public function toString(): string + { + return 'with consecutive parameters'; + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function apply(BaseInvocation $invocation): void + { + $this->invocations[] = $invocation; + $callIndex = \count($this->invocations) - 1; + + $this->verifyInvocation($invocation, $callIndex); + } + + /** + * @throws \PHPUnit\Framework\ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function verify(): void + { + foreach ($this->invocations as $callIndex => $invocation) { + $this->verifyInvocation($invocation, $callIndex); + } + } + + /** + * Verify a single invocation + * + * @param int $callIndex + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function verifyInvocation(BaseInvocation $invocation, $callIndex): void + { + if (!isset($this->parameterGroups[$callIndex])) { + // no parameter assertion for this call index + return; + } + + if ($invocation === null) { + throw new ExpectationFailedException( + 'Mocked method does not exist.' + ); + } + + $parameters = $this->parameterGroups[$callIndex]; + + if (\count($invocation->getParameters()) < \count($parameters)) { + throw new ExpectationFailedException( + \sprintf( + 'Parameter count for invocation %s is too low.', + $invocation->toString() + ) + ); + } + + foreach ($parameters as $i => $parameter) { + $parameter->evaluate( + $invocation->getParameters()[$i], + \sprintf( + 'Parameter %s for invocation #%d %s does not match expected ' . + 'value.', + $i, + $callIndex, + $invocation->toString() + ) + ); + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php new file mode 100644 index 0000000..1df95e5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvocationOrder.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; +use PHPUnit\Framework\MockObject\Verifiable; +use PHPUnit\Framework\SelfDescribing; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +abstract class InvocationOrder implements SelfDescribing, Verifiable +{ + /** + * @var BaseInvocation[] + */ + private $invocations = []; + + public function getInvocationCount(): int + { + return \count($this->invocations); + } + + public function hasBeenInvoked(): bool + { + return \count($this->invocations) > 0; + } + + final public function invoked(BaseInvocation $invocation) + { + $this->invocations[] = $invocation; + + return $this->invokedDo($invocation); + } + + abstract public function matches(BaseInvocation $invocation): bool; + + abstract protected function invokedDo(BaseInvocation $invocation); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php new file mode 100644 index 0000000..070ffee --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtIndex.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class InvokedAtIndex extends InvocationOrder +{ + /** + * @var int + */ + private $sequenceIndex; + + /** + * @var int + */ + private $currentIndex = -1; + + /** + * @param int $sequenceIndex + */ + public function __construct($sequenceIndex) + { + $this->sequenceIndex = $sequenceIndex; + } + + public function toString(): string + { + return 'invoked at sequence index ' . $this->sequenceIndex; + } + + public function matches(BaseInvocation $invocation): bool + { + $this->currentIndex++; + + return $this->currentIndex == $this->sequenceIndex; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void + { + if ($this->currentIndex < $this->sequenceIndex) { + throw new ExpectationFailedException( + \sprintf( + 'The expected invocation at index %s was never reached.', + $this->sequenceIndex + ) + ); + } + } + + protected function invokedDo(BaseInvocation $invocation): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php new file mode 100644 index 0000000..a84aa65 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastCount.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvokedAtLeastCount extends InvocationOrder +{ + /** + * @var int + */ + private $requiredInvocations; + + /** + * @param int $requiredInvocations + */ + public function __construct($requiredInvocations) + { + $this->requiredInvocations = $requiredInvocations; + } + + public function toString(): string + { + return 'invoked at least ' . $this->requiredInvocations . ' times'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void + { + $count = $this->getInvocationCount(); + + if ($count < $this->requiredInvocations) { + throw new ExpectationFailedException( + 'Expected invocation at least ' . $this->requiredInvocations . + ' times but it occurred ' . $count . ' time(s).' + ); + } + } + + public function matches(BaseInvocation $invocation): bool + { + return true; + } + + protected function invokedDo(BaseInvocation $invocation): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php new file mode 100644 index 0000000..d0ad1f8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtLeastOnce.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvokedAtLeastOnce extends InvocationOrder +{ + public function toString(): string + { + return 'invoked at least once'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void + { + $count = $this->getInvocationCount(); + + if ($count < 1) { + throw new ExpectationFailedException( + 'Expected invocation at least once but it never occurred.' + ); + } + } + + public function matches(BaseInvocation $invocation): bool + { + return true; + } + + protected function invokedDo(BaseInvocation $invocation): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php new file mode 100644 index 0000000..c3b815a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedAtMostCount.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvokedAtMostCount extends InvocationOrder +{ + /** + * @var int + */ + private $allowedInvocations; + + /** + * @param int $allowedInvocations + */ + public function __construct($allowedInvocations) + { + $this->allowedInvocations = $allowedInvocations; + } + + public function toString(): string + { + return 'invoked at most ' . $this->allowedInvocations . ' times'; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void + { + $count = $this->getInvocationCount(); + + if ($count > $this->allowedInvocations) { + throw new ExpectationFailedException( + 'Expected invocation at most ' . $this->allowedInvocations . + ' times but it occurred ' . $count . ' time(s).' + ); + } + } + + public function matches(BaseInvocation $invocation): bool + { + return true; + } + + protected function invokedDo(BaseInvocation $invocation): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php new file mode 100644 index 0000000..37beffc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/InvokedCount.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvokedCount extends InvocationOrder +{ + /** + * @var int + */ + private $expectedCount; + + /** + * @param int $expectedCount + */ + public function __construct($expectedCount) + { + $this->expectedCount = $expectedCount; + } + + public function isNever(): bool + { + return $this->expectedCount === 0; + } + + public function toString(): string + { + return 'invoked ' . $this->expectedCount . ' time(s)'; + } + + public function matches(BaseInvocation $invocation): bool + { + return true; + } + + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void + { + $count = $this->getInvocationCount(); + + if ($count !== $this->expectedCount) { + throw new ExpectationFailedException( + \sprintf( + 'Method was expected to be called %d times, ' . + 'actually called %d times.', + $this->expectedCount, + $count + ) + ); + } + } + + /** + * @throws ExpectationFailedException + */ + protected function invokedDo(BaseInvocation $invocation): void + { + $count = $this->getInvocationCount(); + + if ($count > $this->expectedCount) { + $message = $invocation->toString() . ' '; + + switch ($this->expectedCount) { + case 0: + $message .= 'was not expected to be called.'; + + break; + + case 1: + $message .= 'was not expected to be called more than once.'; + + break; + + default: + $message .= \sprintf( + 'was not expected to be called more than %d times.', + $this->expectedCount + ); + } + + throw new ExpectationFailedException($message); + } + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php new file mode 100644 index 0000000..efca2ba --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/MethodName.php @@ -0,0 +1,63 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\InvalidArgumentException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; +use PHPUnit\Framework\MockObject\MethodNameConstraint; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class MethodName +{ + /** + * @var Constraint + */ + private $constraint; + + /** + * @param Constraint|string $constraint + * + * @throws InvalidArgumentException + */ + public function __construct($constraint) + { + if (\is_string($constraint)) { + $constraint = new MethodNameConstraint($constraint); + } + + if (!$constraint instanceof Constraint) { + throw InvalidArgumentException::create(1, 'PHPUnit\Framework\Constraint\Constraint object or string'); + } + + $this->constraint = $constraint; + } + + public function toString(): string + { + return 'method name ' . $this->constraint->toString(); + } + + /** + * @throws \PHPUnit\Framework\ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function matches(BaseInvocation $invocation): bool + { + return $this->matchesName($invocation->getMethodName()); + } + + public function matchesName(string $methodName): bool + { + return $this->constraint->evaluate($methodName, '', true); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php new file mode 100644 index 0000000..2fa58c6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/Parameters.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\Constraint\Constraint; +use PHPUnit\Framework\Constraint\IsAnything; +use PHPUnit\Framework\Constraint\IsEqual; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Parameters implements ParametersRule +{ + /** + * @var Constraint[] + */ + private $parameters = []; + + /** + * @var BaseInvocation + */ + private $invocation; + + /** + * @var bool|ExpectationFailedException + */ + private $parameterVerificationResult; + + /** + * @throws \PHPUnit\Framework\Exception + */ + public function __construct(array $parameters) + { + foreach ($parameters as $parameter) { + if (!($parameter instanceof Constraint)) { + $parameter = new IsEqual( + $parameter + ); + } + + $this->parameters[] = $parameter; + } + } + + public function toString(): string + { + $text = 'with parameter'; + + foreach ($this->parameters as $index => $parameter) { + if ($index > 0) { + $text .= ' and'; + } + + $text .= ' ' . $index . ' ' . $parameter->toString(); + } + + return $text; + } + + /** + * @throws \Exception + */ + public function apply(BaseInvocation $invocation): void + { + $this->invocation = $invocation; + $this->parameterVerificationResult = null; + + try { + $this->parameterVerificationResult = $this->doVerify(); + } catch (ExpectationFailedException $e) { + $this->parameterVerificationResult = $e; + + throw $this->parameterVerificationResult; + } + } + + /** + * Checks if the invocation $invocation matches the current rules. If it + * does the rule will get the invoked() method called which should check + * if an expectation is met. + * + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function verify(): void + { + $this->doVerify(); + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function doVerify(): bool + { + if (isset($this->parameterVerificationResult)) { + return $this->guardAgainstDuplicateEvaluationOfParameterConstraints(); + } + + if ($this->invocation === null) { + throw new ExpectationFailedException('Mocked method does not exist.'); + } + + if (\count($this->invocation->getParameters()) < \count($this->parameters)) { + $message = 'Parameter count for invocation %s is too low.'; + + // The user called `->with($this->anything())`, but may have meant + // `->withAnyParameters()`. + // + // @see https://github.com/sebastianbergmann/phpunit-mock-objects/issues/199 + if (\count($this->parameters) === 1 && + \get_class($this->parameters[0]) === IsAnything::class) { + $message .= "\nTo allow 0 or more parameters with any value, omit ->with() or use ->withAnyParameters() instead."; + } + + throw new ExpectationFailedException( + \sprintf($message, $this->invocation->toString()) + ); + } + + foreach ($this->parameters as $i => $parameter) { + $parameter->evaluate( + $this->invocation->getParameters()[$i], + \sprintf( + 'Parameter %s for invocation %s does not match expected ' . + 'value.', + $i, + $this->invocation->toString() + ) + ); + } + + return true; + } + + /** + * @throws ExpectationFailedException + */ + private function guardAgainstDuplicateEvaluationOfParameterConstraints(): bool + { + if ($this->parameterVerificationResult instanceof ExpectationFailedException) { + throw $this->parameterVerificationResult; + } + + return (bool) $this->parameterVerificationResult; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php new file mode 100644 index 0000000..0c9f191 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Rule/ParametersRule.php @@ -0,0 +1,25 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Rule; + +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\MockObject\Invocation as BaseInvocation; +use PHPUnit\Framework\MockObject\Verifiable; +use PHPUnit\Framework\SelfDescribing; + +interface ParametersRule extends SelfDescribing, Verifiable +{ + /** + * @throws ExpectationFailedException if the invocation violates the rule + */ + public function apply(BaseInvocation $invocation): void; + + public function verify(): void; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php new file mode 100644 index 0000000..f7358af --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub.php @@ -0,0 +1,24 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\MockObject\Builder\InvocationStubber; + +/** + * @method InvocationStubber method($constraint) + */ +interface Stub +{ + public function __phpunit_getInvocationHandler(): InvocationHandler; + + public function __phpunit_hasMatchers(): bool; + + public function __phpunit_setReturnValueGeneration(bool $returnValueGeneration): void; +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php new file mode 100644 index 0000000..d1d7bdb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ConsecutiveCalls.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use SebastianBergmann\Exporter\Exporter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConsecutiveCalls implements Stub +{ + /** + * @var array + */ + private $stack; + + /** + * @var mixed + */ + private $value; + + public function __construct(array $stack) + { + $this->stack = $stack; + } + + public function invoke(Invocation $invocation) + { + $this->value = \array_shift($this->stack); + + if ($this->value instanceof Stub) { + $this->value = $this->value->invoke($invocation); + } + + return $this->value; + } + + public function toString(): string + { + $exporter = new Exporter; + + return \sprintf( + 'return user-specified value %s', + $exporter->export($this->value) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php new file mode 100644 index 0000000..11913c6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Exception.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use SebastianBergmann\Exporter\Exporter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Exception implements Stub +{ + private $exception; + + public function __construct(\Throwable $exception) + { + $this->exception = $exception; + } + + /** + * @throws \Throwable + */ + public function invoke(Invocation $invocation): void + { + throw $this->exception; + } + + public function toString(): string + { + $exporter = new Exporter; + + return \sprintf( + 'raise user-specified exception %s', + $exporter->export($this->exception) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php new file mode 100644 index 0000000..bf0af3f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnArgument.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnArgument implements Stub +{ + /** + * @var int + */ + private $argumentIndex; + + public function __construct($argumentIndex) + { + $this->argumentIndex = $argumentIndex; + } + + public function invoke(Invocation $invocation) + { + if (isset($invocation->getParameters()[$this->argumentIndex])) { + return $invocation->getParameters()[$this->argumentIndex]; + } + } + + public function toString(): string + { + return \sprintf('return argument #%d', $this->argumentIndex); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php new file mode 100644 index 0000000..aa6dffb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnCallback.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnCallback implements Stub +{ + private $callback; + + public function __construct($callback) + { + $this->callback = $callback; + } + + public function invoke(Invocation $invocation) + { + return \call_user_func_array($this->callback, $invocation->getParameters()); + } + + public function toString(): string + { + if (\is_array($this->callback)) { + if (\is_object($this->callback[0])) { + $class = \get_class($this->callback[0]); + $type = '->'; + } else { + $class = $this->callback[0]; + $type = '::'; + } + + return \sprintf( + 'return result of user defined callback %s%s%s() with the ' . + 'passed arguments', + $class, + $type, + $this->callback[1] + ); + } + + return 'return result of user defined callback ' . $this->callback . + ' with the passed arguments'; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php new file mode 100644 index 0000000..0dd9476 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnReference.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use SebastianBergmann\Exporter\Exporter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnReference implements Stub +{ + /** + * @var mixed + */ + private $reference; + + public function __construct(&$reference) + { + $this->reference = &$reference; + } + + public function invoke(Invocation $invocation) + { + return $this->reference; + } + + public function toString(): string + { + $exporter = new Exporter; + + return \sprintf( + 'return user-specified reference %s', + $exporter->export($this->reference) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php new file mode 100644 index 0000000..6d2137b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnSelf.php @@ -0,0 +1,32 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use PHPUnit\Framework\MockObject\RuntimeException; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnSelf implements Stub +{ + /** + * @throws RuntimeException + */ + public function invoke(Invocation $invocation) + { + return $invocation->getObject(); + } + + public function toString(): string + { + return 'return the current object'; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php new file mode 100644 index 0000000..caaf4bc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnStub.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use SebastianBergmann\Exporter\Exporter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnStub implements Stub +{ + /** + * @var mixed + */ + private $value; + + public function __construct($value) + { + $this->value = $value; + } + + public function invoke(Invocation $invocation) + { + return $this->value; + } + + public function toString(): string + { + $exporter = new Exporter; + + return \sprintf( + 'return user-specified value %s', + $exporter->export($this->value) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php new file mode 100644 index 0000000..b44035a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/ReturnValueMap.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ReturnValueMap implements Stub +{ + /** + * @var array + */ + private $valueMap; + + public function __construct(array $valueMap) + { + $this->valueMap = $valueMap; + } + + public function invoke(Invocation $invocation) + { + $parameterCount = \count($invocation->getParameters()); + + foreach ($this->valueMap as $map) { + if (!\is_array($map) || $parameterCount !== (\count($map) - 1)) { + continue; + } + + $return = \array_pop($map); + + if ($invocation->getParameters() === $map) { + return $return; + } + } + } + + public function toString(): string + { + return 'return value from a map'; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php new file mode 100644 index 0000000..15cfce5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Stub/Stub.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject\Stub; + +use PHPUnit\Framework\MockObject\Invocation; +use PHPUnit\Framework\SelfDescribing; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Stub extends SelfDescribing +{ + /** + * Fakes the processing of the invocation $invocation by returning a + * specific value. + * + * @param Invocation $invocation The invocation which was mocked and matched by the current method and argument matchers + */ + public function invoke(Invocation $invocation); +} diff --git a/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php b/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php new file mode 100644 index 0000000..8c9a82c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/MockObject/Verifiable.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework\MockObject; + +use PHPUnit\Framework\ExpectationFailedException; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface Verifiable +{ + /** + * Verifies that the current expectation is valid. If everything is OK the + * code should just return, if not it must throw an exception. + * + * @throws ExpectationFailedException + */ + public function verify(): void; +} diff --git a/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php new file mode 100644 index 0000000..73034f6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/SelfDescribing.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface SelfDescribing +{ + /** + * Returns a string representation of the object. + */ + public function toString(): string; +} diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTest.php b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php new file mode 100644 index 0000000..c5ac84e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/SkippedTest.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface SkippedTest +{ +} diff --git a/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php new file mode 100644 index 0000000..b88dca3 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/SkippedTestCase.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class SkippedTestCase extends TestCase +{ + /** + * @var bool + */ + protected $backupGlobals = false; + + /** + * @var bool + */ + protected $backupStaticAttributes = false; + + /** + * @var bool + */ + protected $runTestInSeparateProcess = false; + + /** + * @var bool + */ + protected $useErrorHandler = false; + + /** + * @var string + */ + private $message; + + public function __construct(string $className, string $methodName, string $message = '') + { + parent::__construct($className . '::' . $methodName); + + $this->message = $message; + } + + public function getMessage(): string + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function toString(): string + { + return $this->getName(); + } + + /** + * @throws Exception + */ + protected function runTest(): void + { + $this->markTestSkipped($this->message); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/Test.php b/vendor/phpunit/phpunit/src/Framework/Test.php new file mode 100644 index 0000000..7740afc --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/Test.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use Countable; + +/** + * A Test can be run and collect its results. + */ +interface Test extends Countable +{ + /** + * Runs a test and collects its result in a TestResult instance. + */ + public function run(TestResult $result = null): TestResult; +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestBuilder.php b/vendor/phpunit/phpunit/src/Framework/TestBuilder.php new file mode 100644 index 0000000..a4b9ab5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestBuilder.php @@ -0,0 +1,232 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Util\Filter; +use PHPUnit\Util\InvalidDataSetException; +use PHPUnit\Util\Test as TestUtil; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestBuilder +{ + public function build(\ReflectionClass $theClass, string $methodName): Test + { + $className = $theClass->getName(); + + if (!$theClass->isInstantiable()) { + return new WarningTestCase( + \sprintf('Cannot instantiate class "%s".', $className) + ); + } + + $backupSettings = TestUtil::getBackupSettings( + $className, + $methodName + ); + + $preserveGlobalState = TestUtil::getPreserveGlobalStateSettings( + $className, + $methodName + ); + + $runTestInSeparateProcess = TestUtil::getProcessIsolationSettings( + $className, + $methodName + ); + + $runClassInSeparateProcess = TestUtil::getClassProcessIsolationSettings( + $className, + $methodName + ); + + $constructor = $theClass->getConstructor(); + + if ($constructor === null) { + throw new Exception('No valid test provided.'); + } + + $parameters = $constructor->getParameters(); + + // TestCase() or TestCase($name) + if (\count($parameters) < 2) { + $test = $this->buildTestWithoutData($className); + } // TestCase($name, $data) + else { + try { + $data = TestUtil::getProvidedData( + $className, + $methodName + ); + } catch (IncompleteTestError $e) { + $message = \sprintf( + "Test for %s::%s marked incomplete by data provider\n%s", + $className, + $methodName, + $this->throwableToString($e) + ); + + $data = new IncompleteTestCase($className, $methodName, $message); + } catch (SkippedTestError $e) { + $message = \sprintf( + "Test for %s::%s skipped by data provider\n%s", + $className, + $methodName, + $this->throwableToString($e) + ); + + $data = new SkippedTestCase($className, $methodName, $message); + } catch (\Throwable $t) { + $message = \sprintf( + "The data provider specified for %s::%s is invalid.\n%s", + $className, + $methodName, + $this->throwableToString($t) + ); + + $data = new WarningTestCase($message); + } + + // Test method with @dataProvider. + if (isset($data)) { + $test = $this->buildDataProviderTestSuite( + $methodName, + $className, + $data, + $runTestInSeparateProcess, + $preserveGlobalState, + $runClassInSeparateProcess, + $backupSettings + ); + } else { + $test = $this->buildTestWithoutData($className); + } + } + + if ($test instanceof TestCase) { + $test->setName($methodName); + $this->configureTestCase( + $test, + $runTestInSeparateProcess, + $preserveGlobalState, + $runClassInSeparateProcess, + $backupSettings + ); + } + + return $test; + } + + /** @psalm-param class-string $className */ + private function buildTestWithoutData(string $className) + { + return new $className; + } + + /** @psalm-param class-string $className */ + private function buildDataProviderTestSuite( + string $methodName, + string $className, + $data, + bool $runTestInSeparateProcess, + ?bool $preserveGlobalState, + bool $runClassInSeparateProcess, + array $backupSettings + ): DataProviderTestSuite { + $dataProviderTestSuite = new DataProviderTestSuite( + $className . '::' . $methodName + ); + + $groups = TestUtil::getGroups($className, $methodName); + + if ($data instanceof WarningTestCase || + $data instanceof SkippedTestCase || + $data instanceof IncompleteTestCase) { + $dataProviderTestSuite->addTest($data, $groups); + } else { + foreach ($data as $_dataName => $_data) { + $_test = new $className($methodName, $_data, $_dataName); + + \assert($_test instanceof TestCase); + + $this->configureTestCase( + $_test, + $runTestInSeparateProcess, + $preserveGlobalState, + $runClassInSeparateProcess, + $backupSettings + ); + + $dataProviderTestSuite->addTest($_test, $groups); + } + } + + return $dataProviderTestSuite; + } + + private function configureTestCase( + TestCase $test, + bool $runTestInSeparateProcess, + ?bool $preserveGlobalState, + bool $runClassInSeparateProcess, + array $backupSettings + ): void { + if ($runTestInSeparateProcess) { + $test->setRunTestInSeparateProcess(true); + + if ($preserveGlobalState !== null) { + $test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($runClassInSeparateProcess) { + $test->setRunClassInSeparateProcess(true); + + if ($preserveGlobalState !== null) { + $test->setPreserveGlobalState($preserveGlobalState); + } + } + + if ($backupSettings['backupGlobals'] !== null) { + $test->setBackupGlobals($backupSettings['backupGlobals']); + } + + if ($backupSettings['backupStaticAttributes'] !== null) { + $test->setBackupStaticAttributes( + $backupSettings['backupStaticAttributes'] + ); + } + } + + private function throwableToString(\Throwable $t): string + { + $message = $t->getMessage(); + + if (empty(\trim($message))) { + $message = ''; + } + + if ($t instanceof InvalidDataSetException) { + return \sprintf( + "%s\n%s", + $message, + Filter::getFilteredStacktrace($t) + ); + } + + return \sprintf( + "%s: %s\n%s", + \get_class($t), + $message, + Filter::getFilteredStacktrace($t) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestCase.php b/vendor/phpunit/phpunit/src/Framework/TestCase.php new file mode 100644 index 0000000..2c8f17d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestCase.php @@ -0,0 +1,2526 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use DeepCopy\DeepCopy; +use PHPUnit\Framework\Constraint\Exception as ExceptionConstraint; +use PHPUnit\Framework\Constraint\ExceptionCode; +use PHPUnit\Framework\Constraint\ExceptionMessage; +use PHPUnit\Framework\Constraint\ExceptionMessageRegularExpression; +use PHPUnit\Framework\Error\Deprecated; +use PHPUnit\Framework\Error\Error; +use PHPUnit\Framework\Error\Notice; +use PHPUnit\Framework\Error\Warning as WarningError; +use PHPUnit\Framework\MockObject\Generator as MockGenerator; +use PHPUnit\Framework\MockObject\MockBuilder; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\MockObject\Rule\AnyInvokedCount as AnyInvokedCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtIndex as InvokedAtIndexMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastCount as InvokedAtLeastCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtLeastOnce as InvokedAtLeastOnceMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedAtMostCount as InvokedAtMostCountMatcher; +use PHPUnit\Framework\MockObject\Rule\InvokedCount as InvokedCountMatcher; +use PHPUnit\Framework\MockObject\Stub; +use PHPUnit\Framework\MockObject\Stub\ConsecutiveCalls as ConsecutiveCallsStub; +use PHPUnit\Framework\MockObject\Stub\Exception as ExceptionStub; +use PHPUnit\Framework\MockObject\Stub\ReturnArgument as ReturnArgumentStub; +use PHPUnit\Framework\MockObject\Stub\ReturnCallback as ReturnCallbackStub; +use PHPUnit\Framework\MockObject\Stub\ReturnSelf as ReturnSelfStub; +use PHPUnit\Framework\MockObject\Stub\ReturnStub; +use PHPUnit\Framework\MockObject\Stub\ReturnValueMap as ReturnValueMapStub; +use PHPUnit\Runner\BaseTestRunner; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\Util\Exception as UtilException; +use PHPUnit\Util\GlobalState; +use PHPUnit\Util\PHP\AbstractPhpProcess; +use PHPUnit\Util\Test as TestUtil; +use PHPUnit\Util\Type; +use Prophecy\Exception\Prediction\PredictionException; +use Prophecy\Prophecy\MethodProphecy; +use Prophecy\Prophecy\ObjectProphecy; +use Prophecy\Prophet; +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Comparator\Factory as ComparatorFactory; +use SebastianBergmann\Diff\Differ; +use SebastianBergmann\Exporter\Exporter; +use SebastianBergmann\GlobalState\Blacklist; +use SebastianBergmann\GlobalState\Restorer; +use SebastianBergmann\GlobalState\Snapshot; +use SebastianBergmann\ObjectEnumerator\Enumerator; + +abstract class TestCase extends Assert implements SelfDescribing, Test +{ + private const LOCALE_CATEGORIES = [\LC_ALL, \LC_COLLATE, \LC_CTYPE, \LC_MONETARY, \LC_NUMERIC, \LC_TIME]; + + /** + * @var ?bool + */ + protected $backupGlobals; + + /** + * @var string[] + */ + protected $backupGlobalsBlacklist = []; + + /** + * @var bool + */ + protected $backupStaticAttributes; + + /** + * @var array> + */ + protected $backupStaticAttributesBlacklist = []; + + /** + * @var bool + */ + protected $runTestInSeparateProcess; + + /** + * @var bool + */ + protected $preserveGlobalState = true; + + /** + * @var bool + */ + private $runClassInSeparateProcess; + + /** + * @var bool + */ + private $inIsolation = false; + + /** + * @var array + */ + private $data; + + /** + * @var string + */ + private $dataName; + + /** + * @var null|string + */ + private $expectedException; + + /** + * @var null|string + */ + private $expectedExceptionMessage; + + /** + * @var null|string + */ + private $expectedExceptionMessageRegExp; + + /** + * @var null|int|string + */ + private $expectedExceptionCode; + + /** + * @var string + */ + private $name = ''; + + /** + * @var string[] + */ + private $dependencies = []; + + /** + * @var array + */ + private $dependencyInput = []; + + /** + * @var array + */ + private $iniSettings = []; + + /** + * @var array + */ + private $locale = []; + + /** + * @var MockObject[] + */ + private $mockObjects = []; + + /** + * @var MockGenerator + */ + private $mockObjectGenerator; + + /** + * @var int + */ + private $status = BaseTestRunner::STATUS_UNKNOWN; + + /** + * @var string + */ + private $statusMessage = ''; + + /** + * @var int + */ + private $numAssertions = 0; + + /** + * @var TestResult + */ + private $result; + + /** + * @var mixed + */ + private $testResult; + + /** + * @var string + */ + private $output = ''; + + /** + * @var string + */ + private $outputExpectedRegex; + + /** + * @var string + */ + private $outputExpectedString; + + /** + * @var mixed + */ + private $outputCallback = false; + + /** + * @var bool + */ + private $outputBufferingActive = false; + + /** + * @var int + */ + private $outputBufferingLevel; + + /** + * @var bool + */ + private $outputRetrievedForAssertion = false; + + /** + * @var Snapshot + */ + private $snapshot; + + /** + * @var \Prophecy\Prophet + */ + private $prophet; + + /** + * @var bool + */ + private $beStrictAboutChangesToGlobalState = false; + + /** + * @var bool + */ + private $registerMockObjectsFromTestArgumentsRecursively = false; + + /** + * @var string[] + */ + private $warnings = []; + + /** + * @var string[] + */ + private $groups = []; + + /** + * @var bool + */ + private $doesNotPerformAssertions = false; + + /** + * @var Comparator[] + */ + private $customComparators = []; + + /** + * @var string[] + */ + private $doubledTypes = []; + + /** + * @var bool + */ + private $deprecatedExpectExceptionMessageRegExpUsed = false; + + /** + * Returns a matcher that matches when the method is executed + * zero or more times. + */ + public static function any(): AnyInvokedCountMatcher + { + return new AnyInvokedCountMatcher; + } + + /** + * Returns a matcher that matches when the method is never executed. + */ + public static function never(): InvokedCountMatcher + { + return new InvokedCountMatcher(0); + } + + /** + * Returns a matcher that matches when the method is executed + * at least N times. + */ + public static function atLeast(int $requiredInvocations): InvokedAtLeastCountMatcher + { + return new InvokedAtLeastCountMatcher( + $requiredInvocations + ); + } + + /** + * Returns a matcher that matches when the method is executed at least once. + */ + public static function atLeastOnce(): InvokedAtLeastOnceMatcher + { + return new InvokedAtLeastOnceMatcher; + } + + /** + * Returns a matcher that matches when the method is executed exactly once. + */ + public static function once(): InvokedCountMatcher + { + return new InvokedCountMatcher(1); + } + + /** + * Returns a matcher that matches when the method is executed + * exactly $count times. + */ + public static function exactly(int $count): InvokedCountMatcher + { + return new InvokedCountMatcher($count); + } + + /** + * Returns a matcher that matches when the method is executed + * at most N times. + */ + public static function atMost(int $allowedInvocations): InvokedAtMostCountMatcher + { + return new InvokedAtMostCountMatcher($allowedInvocations); + } + + /** + * Returns a matcher that matches when the method is executed + * at the given index. + */ + public static function at(int $index): InvokedAtIndexMatcher + { + return new InvokedAtIndexMatcher($index); + } + + public static function returnValue($value): ReturnStub + { + return new ReturnStub($value); + } + + public static function returnValueMap(array $valueMap): ReturnValueMapStub + { + return new ReturnValueMapStub($valueMap); + } + + public static function returnArgument(int $argumentIndex): ReturnArgumentStub + { + return new ReturnArgumentStub($argumentIndex); + } + + public static function returnCallback($callback): ReturnCallbackStub + { + return new ReturnCallbackStub($callback); + } + + /** + * Returns the current object. + * + * This method is useful when mocking a fluent interface. + */ + public static function returnSelf(): ReturnSelfStub + { + return new ReturnSelfStub; + } + + public static function throwException(\Throwable $exception): ExceptionStub + { + return new ExceptionStub($exception); + } + + public static function onConsecutiveCalls(...$args): ConsecutiveCallsStub + { + return new ConsecutiveCallsStub($args); + } + + /** + * @param string $name + * @param string $dataName + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function __construct($name = null, array $data = [], $dataName = '') + { + if ($name !== null) { + $this->setName($name); + } + + $this->data = $data; + $this->dataName = $dataName; + } + + /** + * This method is called before the first test of this test class is run. + */ + public static function setUpBeforeClass(): void + { + } + + /** + * This method is called after the last test of this test class is run. + */ + public static function tearDownAfterClass(): void + { + } + + /** + * This method is called before each test. + */ + protected function setUp(): void + { + } + + /** + * This method is called after each test. + */ + protected function tearDown(): void + { + } + + /** + * Returns a string representation of the test case. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + public function toString(): string + { + try { + $class = new \ReflectionClass($this); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $buffer = \sprintf( + '%s::%s', + $class->name, + $this->getName(false) + ); + + return $buffer . $this->getDataSetAsString(); + } + + public function count(): int + { + return 1; + } + + public function getActualOutputForAssertion(): string + { + $this->outputRetrievedForAssertion = true; + + return $this->getActualOutput(); + } + + public function expectOutputRegex(string $expectedRegex): void + { + $this->outputExpectedRegex = $expectedRegex; + } + + public function expectOutputString(string $expectedString): void + { + $this->outputExpectedString = $expectedString; + } + + /** + * @psalm-param class-string<\Throwable> $exception + */ + public function expectException(string $exception): void + { + $this->expectedException = $exception; + } + + /** + * @param int|string $code + */ + public function expectExceptionCode($code): void + { + $this->expectedExceptionCode = $code; + } + + public function expectExceptionMessage(string $message): void + { + $this->expectedExceptionMessage = $message; + } + + public function expectExceptionMessageMatches(string $regularExpression): void + { + $this->expectedExceptionMessageRegExp = $regularExpression; + } + + /** + * @deprecated Use expectExceptionMessageMatches() instead + */ + public function expectExceptionMessageRegExp(string $regularExpression): void + { + $this->deprecatedExpectExceptionMessageRegExpUsed = true; + + $this->expectExceptionMessageMatches($regularExpression); + } + + /** + * Sets up an expectation for an exception to be raised by the code under test. + * Information for expected exception class, expected exception message, and + * expected exception code are retrieved from a given Exception object. + */ + public function expectExceptionObject(\Exception $exception): void + { + $this->expectException(\get_class($exception)); + $this->expectExceptionMessage($exception->getMessage()); + $this->expectExceptionCode($exception->getCode()); + } + + public function expectNotToPerformAssertions(): void + { + $this->doesNotPerformAssertions = true; + } + + public function expectDeprecation(): void + { + $this->expectException(Deprecated::class); + } + + public function expectDeprecationMessage(string $message): void + { + $this->expectExceptionMessage($message); + } + + public function expectDeprecationMessageMatches(string $regularExpression): void + { + $this->expectExceptionMessageMatches($regularExpression); + } + + public function expectNotice(): void + { + $this->expectException(Notice::class); + } + + public function expectNoticeMessage(string $message): void + { + $this->expectExceptionMessage($message); + } + + public function expectNoticeMessageMatches(string $regularExpression): void + { + $this->expectExceptionMessageMatches($regularExpression); + } + + public function expectWarning(): void + { + $this->expectException(WarningError::class); + } + + public function expectWarningMessage(string $message): void + { + $this->expectExceptionMessage($message); + } + + public function expectWarningMessageMatches(string $regularExpression): void + { + $this->expectExceptionMessageMatches($regularExpression); + } + + public function expectError(): void + { + $this->expectException(Error::class); + } + + public function expectErrorMessage(string $message): void + { + $this->expectExceptionMessage($message); + } + + public function expectErrorMessageMatches(string $regularExpression): void + { + $this->expectExceptionMessageMatches($regularExpression); + } + + public function getStatus(): int + { + return $this->status; + } + + public function markAsRisky(): void + { + $this->status = BaseTestRunner::STATUS_RISKY; + } + + public function getStatusMessage(): string + { + return $this->statusMessage; + } + + public function hasFailed(): bool + { + $status = $this->getStatus(); + + return $status === BaseTestRunner::STATUS_FAILURE || $status === BaseTestRunner::STATUS_ERROR; + } + + /** + * Runs the test case and collects the results in a TestResult object. + * If no TestResult object is passed a new one will be created. + * + * @throws CodeCoverageException + * @throws UtilException + * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException + * @throws \SebastianBergmann\CodeCoverage\RuntimeException + * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function run(TestResult $result = null): TestResult + { + if ($result === null) { + $result = $this->createResult(); + } + + if (!$this instanceof WarningTestCase) { + $this->setTestResultObject($result); + } + + if (!$this instanceof WarningTestCase && + !$this instanceof SkippedTestCase && + !$this->handleDependencies()) { + return $result; + } + + if ($this->runInSeparateProcess()) { + $runEntireClass = $this->runClassInSeparateProcess && !$this->runTestInSeparateProcess; + + try { + $class = new \ReflectionClass($this); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($runEntireClass) { + $template = new \Text_Template( + __DIR__ . '/../Util/PHP/Template/TestCaseClass.tpl' + ); + } else { + $template = new \Text_Template( + __DIR__ . '/../Util/PHP/Template/TestCaseMethod.tpl' + ); + } + + if ($this->preserveGlobalState) { + $constants = GlobalState::getConstantsAsString(); + $globals = GlobalState::getGlobalsAsString(); + $includedFiles = GlobalState::getIncludedFilesAsString(); + $iniSettings = GlobalState::getIniSettingsAsString(); + } else { + $constants = ''; + + if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . \var_export($GLOBALS['__PHPUNIT_BOOTSTRAP'], true) . ";\n"; + } else { + $globals = ''; + } + + $includedFiles = ''; + $iniSettings = ''; + } + + $coverage = $result->getCollectCodeCoverageInformation() ? 'true' : 'false'; + $isStrictAboutTestsThatDoNotTestAnything = $result->isStrictAboutTestsThatDoNotTestAnything() ? 'true' : 'false'; + $isStrictAboutOutputDuringTests = $result->isStrictAboutOutputDuringTests() ? 'true' : 'false'; + $enforcesTimeLimit = $result->enforcesTimeLimit() ? 'true' : 'false'; + $isStrictAboutTodoAnnotatedTests = $result->isStrictAboutTodoAnnotatedTests() ? 'true' : 'false'; + $isStrictAboutResourceUsageDuringSmallTests = $result->isStrictAboutResourceUsageDuringSmallTests() ? 'true' : 'false'; + + if (\defined('PHPUNIT_COMPOSER_INSTALL')) { + $composerAutoload = \var_export(PHPUNIT_COMPOSER_INSTALL, true); + } else { + $composerAutoload = '\'\''; + } + + if (\defined('__PHPUNIT_PHAR__')) { + $phar = \var_export(__PHPUNIT_PHAR__, true); + } else { + $phar = '\'\''; + } + + if ($result->getCodeCoverage()) { + $codeCoverageFilter = $result->getCodeCoverage()->filter(); + } else { + $codeCoverageFilter = null; + } + + $data = \var_export(\serialize($this->data), true); + $dataName = \var_export($this->dataName, true); + $dependencyInput = \var_export(\serialize($this->dependencyInput), true); + $includePath = \var_export(\get_include_path(), true); + $codeCoverageFilter = \var_export(\serialize($codeCoverageFilter), true); + // must do these fixes because TestCaseMethod.tpl has unserialize('{data}') in it, and we can't break BC + // the lines above used to use addcslashes() rather than var_export(), which breaks null byte escape sequences + $data = "'." . $data . ".'"; + $dataName = "'.(" . $dataName . ").'"; + $dependencyInput = "'." . $dependencyInput . ".'"; + $includePath = "'." . $includePath . ".'"; + $codeCoverageFilter = "'." . $codeCoverageFilter . ".'"; + + $configurationFilePath = $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] ?? ''; + + $var = [ + 'composerAutoload' => $composerAutoload, + 'phar' => $phar, + 'filename' => $class->getFileName(), + 'className' => $class->getName(), + 'collectCodeCoverageInformation' => $coverage, + 'data' => $data, + 'dataName' => $dataName, + 'dependencyInput' => $dependencyInput, + 'constants' => $constants, + 'globals' => $globals, + 'include_path' => $includePath, + 'included_files' => $includedFiles, + 'iniSettings' => $iniSettings, + 'isStrictAboutTestsThatDoNotTestAnything' => $isStrictAboutTestsThatDoNotTestAnything, + 'isStrictAboutOutputDuringTests' => $isStrictAboutOutputDuringTests, + 'enforcesTimeLimit' => $enforcesTimeLimit, + 'isStrictAboutTodoAnnotatedTests' => $isStrictAboutTodoAnnotatedTests, + 'isStrictAboutResourceUsageDuringSmallTests' => $isStrictAboutResourceUsageDuringSmallTests, + 'codeCoverageFilter' => $codeCoverageFilter, + 'configurationFilePath' => $configurationFilePath, + 'name' => $this->getName(false), + ]; + + if (!$runEntireClass) { + $var['methodName'] = $this->name; + } + + $template->setVar($var); + + $php = AbstractPhpProcess::factory(); + $php->runTestJob($template->render(), $this, $result); + } else { + $result->run($this); + } + + $this->result = null; + + return $result; + } + + /** + * Returns a builder object to create mock objects using a fluent interface. + * + * @param string|string[] $className + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string[] $className + * @psalm-return MockBuilder + */ + public function getMockBuilder($className): MockBuilder + { + if (!\is_string($className)) { + $this->addWarning('Passing an array of interface names to getMockBuilder() for creating a test double that implements multiple interfaces is deprecated and will no longer be supported in PHPUnit 9.'); + } + + $this->recordDoubledType($className); + + return new MockBuilder($this, $className); + } + + public function registerComparator(Comparator $comparator): void + { + ComparatorFactory::getInstance()->register($comparator); + + $this->customComparators[] = $comparator; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + * + * @deprecated Invoking this method has no effect; it will be removed in PHPUnit 9 + */ + public function setUseErrorHandler(bool $useErrorHandler): void + { + } + + /** + * @return string[] + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function doubledTypes(): array + { + return \array_unique($this->doubledTypes); + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getGroups(): array + { + return $this->groups; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setGroups(array $groups): void + { + $this->groups = $groups; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getAnnotations(): array + { + return TestUtil::parseTestMethodAnnotations( + \get_class($this), + $this->name + ); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getName(bool $withDataSet = true): string + { + if ($withDataSet) { + return $this->name . $this->getDataSetAsString(false); + } + + return $this->name; + } + + /** + * Returns the size of the test. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getSize(): int + { + return TestUtil::getSize( + \get_class($this), + $this->getName(false) + ); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function hasSize(): bool + { + return $this->getSize() !== TestUtil::UNKNOWN; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function isSmall(): bool + { + return $this->getSize() === TestUtil::SMALL; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function isMedium(): bool + { + return $this->getSize() === TestUtil::MEDIUM; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function isLarge(): bool + { + return $this->getSize() === TestUtil::LARGE; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getActualOutput(): string + { + if (!$this->outputBufferingActive) { + return $this->output; + } + + return (string) \ob_get_contents(); + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function hasOutput(): bool + { + if ($this->output === '') { + return false; + } + + if ($this->hasExpectationOnOutput()) { + return false; + } + + return true; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function doesNotPerformAssertions(): bool + { + return $this->doesNotPerformAssertions; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function hasExpectationOnOutput(): bool + { + return \is_string($this->outputExpectedString) || \is_string($this->outputExpectedRegex) || $this->outputRetrievedForAssertion; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getExpectedException(): ?string + { + return $this->expectedException; + } + + /** + * @return null|int|string + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getExpectedExceptionCode() + { + return $this->expectedExceptionCode; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getExpectedExceptionMessage(): ?string + { + return $this->expectedExceptionMessage; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getExpectedExceptionMessageRegExp(): ?string + { + return $this->expectedExceptionMessageRegExp; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setRegisterMockObjectsFromTestArgumentsRecursively(bool $flag): void + { + $this->registerMockObjectsFromTestArgumentsRecursively = $flag; + } + + /** + * @throws \Throwable + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function runBare(): void + { + $this->numAssertions = 0; + + $this->snapshotGlobalState(); + $this->startOutputBuffering(); + \clearstatcache(); + $currentWorkingDirectory = \getcwd(); + + $hookMethods = TestUtil::getHookMethods(\get_class($this)); + + $hasMetRequirements = false; + + try { + $this->checkRequirements(); + $hasMetRequirements = true; + + if ($this->inIsolation) { + foreach ($hookMethods['beforeClass'] as $method) { + $this->$method(); + } + } + + $this->setExpectedExceptionFromAnnotation(); + $this->setDoesNotPerformAssertionsFromAnnotation(); + + foreach ($hookMethods['before'] as $method) { + $this->$method(); + } + + $this->assertPreConditions(); + $this->testResult = $this->runTest(); + $this->verifyMockObjects(); + $this->assertPostConditions(); + + if (!empty($this->warnings)) { + throw new Warning( + \implode( + "\n", + \array_unique($this->warnings) + ) + ); + } + + $this->status = BaseTestRunner::STATUS_PASSED; + } catch (IncompleteTest $e) { + $this->status = BaseTestRunner::STATUS_INCOMPLETE; + $this->statusMessage = $e->getMessage(); + } catch (SkippedTest $e) { + $this->status = BaseTestRunner::STATUS_SKIPPED; + $this->statusMessage = $e->getMessage(); + } catch (Warning $e) { + $this->status = BaseTestRunner::STATUS_WARNING; + $this->statusMessage = $e->getMessage(); + } catch (AssertionFailedError $e) { + $this->status = BaseTestRunner::STATUS_FAILURE; + $this->statusMessage = $e->getMessage(); + } catch (PredictionException $e) { + $this->status = BaseTestRunner::STATUS_FAILURE; + $this->statusMessage = $e->getMessage(); + } catch (\Throwable $_e) { + $e = $_e; + $this->status = BaseTestRunner::STATUS_ERROR; + $this->statusMessage = $_e->getMessage(); + } + + $this->mockObjects = []; + $this->prophet = null; + + // Tear down the fixture. An exception raised in tearDown() will be + // caught and passed on when no exception was raised before. + try { + if ($hasMetRequirements) { + foreach ($hookMethods['after'] as $method) { + $this->$method(); + } + + if ($this->inIsolation) { + foreach ($hookMethods['afterClass'] as $method) { + $this->$method(); + } + } + } + } catch (\Throwable $_e) { + $e = $e ?? $_e; + } + + try { + $this->stopOutputBuffering(); + } catch (RiskyTestError $_e) { + $e = $e ?? $_e; + } + + if (isset($_e)) { + $this->status = BaseTestRunner::STATUS_ERROR; + $this->statusMessage = $_e->getMessage(); + } + + \clearstatcache(); + + if ($currentWorkingDirectory !== \getcwd()) { + \chdir($currentWorkingDirectory); + } + + $this->restoreGlobalState(); + $this->unregisterCustomComparators(); + $this->cleanupIniSettings(); + $this->cleanupLocaleSettings(); + \libxml_clear_errors(); + + // Perform assertion on output. + if (!isset($e)) { + try { + if ($this->outputExpectedRegex !== null) { + $this->assertRegExp($this->outputExpectedRegex, $this->output); + } elseif ($this->outputExpectedString !== null) { + $this->assertEquals($this->outputExpectedString, $this->output); + } + } catch (\Throwable $_e) { + $e = $_e; + } + } + + // Workaround for missing "finally". + if (isset($e)) { + if ($e instanceof PredictionException) { + $e = new AssertionFailedError($e->getMessage()); + } + + $this->onNotSuccessfulTest($e); + } + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * @param string[] $dependencies + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setDependencies(array $dependencies): void + { + $this->dependencies = $dependencies; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getDependencies(): array + { + return $this->dependencies; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function hasDependencies(): bool + { + return \count($this->dependencies) > 0; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setDependencyInput(array $dependencyInput): void + { + $this->dependencyInput = $dependencyInput; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getDependencyInput(): array + { + return $this->dependencyInput; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setBeStrictAboutChangesToGlobalState(?bool $beStrictAboutChangesToGlobalState): void + { + $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setBackupGlobals(?bool $backupGlobals): void + { + if ($this->backupGlobals === null && $backupGlobals !== null) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setBackupStaticAttributes(?bool $backupStaticAttributes): void + { + if ($this->backupStaticAttributes === null && $backupStaticAttributes !== null) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void + { + if ($this->runTestInSeparateProcess === null) { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setRunClassInSeparateProcess(bool $runClassInSeparateProcess): void + { + if ($this->runClassInSeparateProcess === null) { + $this->runClassInSeparateProcess = $runClassInSeparateProcess; + } + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setPreserveGlobalState(bool $preserveGlobalState): void + { + $this->preserveGlobalState = $preserveGlobalState; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setInIsolation(bool $inIsolation): void + { + $this->inIsolation = $inIsolation; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function isInIsolation(): bool + { + return $this->inIsolation; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getResult() + { + return $this->testResult; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setResult($result): void + { + $this->testResult = $result; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setOutputCallback(callable $callback): void + { + $this->outputCallback = $callback; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getTestResultObject(): ?TestResult + { + return $this->result; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function setTestResultObject(TestResult $result): void + { + $this->result = $result; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function registerMockObject(MockObject $mockObject): void + { + $this->mockObjects[] = $mockObject; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function addToAssertionCount(int $count): void + { + $this->numAssertions += $count; + } + + /** + * Returns the number of assertions performed by this test. + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getNumAssertions(): int + { + return $this->numAssertions; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function usesDataProvider(): bool + { + return !empty($this->data); + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function dataDescription(): string + { + return \is_string($this->dataName) ? $this->dataName : ''; + } + + /** + * @return int|string + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function dataName() + { + return $this->dataName; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getDataSetAsString(bool $includeData = true): string + { + $buffer = ''; + + if (!empty($this->data)) { + if (\is_int($this->dataName)) { + $buffer .= \sprintf(' with data set #%d', $this->dataName); + } else { + $buffer .= \sprintf(' with data set "%s"', $this->dataName); + } + + $exporter = new Exporter; + + if ($includeData) { + $buffer .= \sprintf(' (%s)', $exporter->shortenedRecursiveExport($this->data)); + } + } + + return $buffer; + } + + /** + * Gets the data set of a TestCase. + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function getProvidedData(): array + { + return $this->data; + } + + /** + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + public function addWarning(string $warning): void + { + $this->warnings[] = $warning; + } + + /** + * Override to run the test and assert its state. + * + * @throws AssertionFailedError + * @throws Exception + * @throws ExpectationFailedException + * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException + * @throws \Throwable + */ + protected function runTest() + { + if (\trim($this->name) === '') { + throw new Exception( + 'PHPUnit\Framework\TestCase::$name must be a non-blank string.' + ); + } + + $testArguments = \array_merge($this->data, $this->dependencyInput); + + $this->registerMockObjectsFromTestArguments($testArguments); + + try { + $testResult = $this->{$this->name}(...\array_values($testArguments)); + } catch (\Throwable $exception) { + if (!$this->checkExceptionExpectations($exception)) { + throw $exception; + } + + if ($this->expectedException !== null) { + $this->assertThat( + $exception, + new ExceptionConstraint( + $this->expectedException + ) + ); + } + + if ($this->expectedExceptionMessage !== null) { + $this->assertThat( + $exception, + new ExceptionMessage( + $this->expectedExceptionMessage + ) + ); + } + + if ($this->expectedExceptionMessageRegExp !== null) { + $this->assertThat( + $exception, + new ExceptionMessageRegularExpression( + $this->expectedExceptionMessageRegExp + ) + ); + } + + if ($this->expectedExceptionCode !== null) { + $this->assertThat( + $exception, + new ExceptionCode( + $this->expectedExceptionCode + ) + ); + } + + if ($this->deprecatedExpectExceptionMessageRegExpUsed) { + $this->addWarning('expectExceptionMessageRegExp() is deprecated in PHPUnit 8 and will be removed in PHPUnit 9.'); + } + + return; + } + + if ($this->expectedException !== null) { + $this->assertThat( + null, + new ExceptionConstraint( + $this->expectedException + ) + ); + } elseif ($this->expectedExceptionMessage !== null) { + $this->numAssertions++; + + throw new AssertionFailedError( + \sprintf( + 'Failed asserting that exception with message "%s" is thrown', + $this->expectedExceptionMessage + ) + ); + } elseif ($this->expectedExceptionMessageRegExp !== null) { + $this->numAssertions++; + + throw new AssertionFailedError( + \sprintf( + 'Failed asserting that exception with message matching "%s" is thrown', + $this->expectedExceptionMessageRegExp + ) + ); + } elseif ($this->expectedExceptionCode !== null) { + $this->numAssertions++; + + throw new AssertionFailedError( + \sprintf( + 'Failed asserting that exception with code "%s" is thrown', + $this->expectedExceptionCode + ) + ); + } + + return $testResult; + } + + /** + * This method is a wrapper for the ini_set() function that automatically + * resets the modified php.ini setting to its original value after the + * test is run. + * + * @throws Exception + */ + protected function iniSet(string $varName, string $newValue): void + { + $currentValue = \ini_set($varName, $newValue); + + if ($currentValue !== false) { + $this->iniSettings[$varName] = $currentValue; + } else { + throw new Exception( + \sprintf( + 'INI setting "%s" could not be set to "%s".', + $varName, + $newValue + ) + ); + } + } + + /** + * This method is a wrapper for the setlocale() function that automatically + * resets the locale to its original value after the test is run. + * + * @throws Exception + */ + protected function setLocale(...$args): void + { + if (\count($args) < 2) { + throw new Exception; + } + + [$category, $locale] = $args; + + if (\defined('LC_MESSAGES')) { + $categories[] = \LC_MESSAGES; + } + + if (!\in_array($category, self::LOCALE_CATEGORIES, true)) { + throw new Exception; + } + + if (!\is_array($locale) && !\is_string($locale)) { + throw new Exception; + } + + $this->locale[$category] = \setlocale($category, 0); + + $result = \setlocale(...$args); + + if ($result === false) { + throw new Exception( + 'The locale functionality is not implemented on your platform, ' . + 'the specified locale does not exist or the category name is ' . + 'invalid.' + ); + } + } + + /** + * Makes configurable stub for the specified class. + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string $originalClassName + * @psalm-return Stub&RealInstanceType + */ + protected function createStub(string $originalClassName): Stub + { + return $this->createMock($originalClassName); + } + + /** + * Returns a mock object for the specified class. + * + * @param string|string[] $originalClassName + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string[] $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function createMock($originalClassName): MockObject + { + if (!\is_string($originalClassName)) { + $this->addWarning('Passing an array of interface names to createMock() for creating a test double that implements multiple interfaces is deprecated and will no longer be supported in PHPUnit 9.'); + } + + return $this->getMockBuilder($originalClassName) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->disallowMockingUnknownTypes() + ->getMock(); + } + + /** + * Returns a configured mock object for the specified class. + * + * @param string|string[] $originalClassName + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string[] $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function createConfiguredMock($originalClassName, array $configuration): MockObject + { + $o = $this->createMock($originalClassName); + + foreach ($configuration as $method => $return) { + $o->method($method)->willReturn($return); + } + + return $o; + } + + /** + * Returns a partial mock object for the specified class. + * + * @param string|string[] $originalClassName + * @param string[] $methods + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string[] $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function createPartialMock($originalClassName, array $methods): MockObject + { + if (!\is_string($originalClassName)) { + $this->addWarning('Passing an array of interface names to createPartialMock() for creating a test double that implements multiple interfaces is deprecated and will no longer be supported in PHPUnit 9.'); + } + + $class_names = \is_array($originalClassName) ? $originalClassName : [$originalClassName]; + + foreach ($class_names as $class_name) { + $reflection = new \ReflectionClass($class_name); + + $mockedMethodsThatDontExist = \array_filter( + $methods, + static function (string $method) use ($reflection) { + return !$reflection->hasMethod($method); + } + ); + + if ($mockedMethodsThatDontExist) { + $this->addWarning( + \sprintf( + 'createPartialMock called with method(s) %s that do not exist in %s. This will not be allowed in future versions of PHPUnit.', + \implode(', ', $mockedMethodsThatDontExist), + $class_name + ) + ); + } + } + + return $this->getMockBuilder($originalClassName) + ->disableOriginalConstructor() + ->disableOriginalClone() + ->disableArgumentCloning() + ->disallowMockingUnknownTypes() + ->setMethods(empty($methods) ? null : $methods) + ->getMock(); + } + + /** + * Returns a test proxy for the specified class. + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function createTestProxy(string $originalClassName, array $constructorArguments = []): MockObject + { + return $this->getMockBuilder($originalClassName) + ->setConstructorArgs($constructorArguments) + ->enableProxyingToOriginalMethods() + ->getMock(); + } + + /** + * Mocks the specified class and returns the name of the mocked class. + * + * @param string $originalClassName + * @param array $methods + * @param string $mockClassName + * @param bool $callOriginalConstructor + * @param bool $callOriginalClone + * @param bool $callAutoload + * @param bool $cloneArguments + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string $originalClassName + * @psalm-return class-string + */ + protected function getMockClass($originalClassName, $methods = [], array $arguments = [], $mockClassName = '', $callOriginalConstructor = false, $callOriginalClone = true, $callAutoload = true, $cloneArguments = false): string + { + $this->recordDoubledType($originalClassName); + + $mock = $this->getMockObjectGenerator()->getMock( + $originalClassName, + $methods, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $cloneArguments + ); + + return \get_class($mock); + } + + /** + * Returns a mock object for the specified abstract class with all abstract + * methods of the class mocked. Concrete methods are not mocked by default. + * To mock concrete methods, use the 7th parameter ($mockedMethods). + * + * @param string $originalClassName + * @param string $mockClassName + * @param bool $callOriginalConstructor + * @param bool $callOriginalClone + * @param bool $callAutoload + * @param array $mockedMethods + * @param bool $cloneArguments + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function getMockForAbstractClass($originalClassName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = false): MockObject + { + $this->recordDoubledType($originalClassName); + + $mockObject = $this->getMockObjectGenerator()->getMockForAbstractClass( + $originalClassName, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $mockedMethods, + $cloneArguments + ); + + $this->registerMockObject($mockObject); + + return $mockObject; + } + + /** + * Returns a mock object based on the given WSDL file. + * + * @param string $wsdlFile + * @param string $originalClassName + * @param string $mockClassName + * @param bool $callOriginalConstructor + * @param array $options An array of options passed to SOAPClient::_construct + * + * @psalm-template RealInstanceType of object + * @psalm-param class-string|string $originalClassName + * @psalm-return MockObject&RealInstanceType + */ + protected function getMockFromWsdl($wsdlFile, $originalClassName = '', $mockClassName = '', array $methods = [], $callOriginalConstructor = true, array $options = []): MockObject + { + $this->recordDoubledType('SoapClient'); + + if ($originalClassName === '') { + $fileName = \pathinfo(\basename(\parse_url($wsdlFile, \PHP_URL_PATH)), \PATHINFO_FILENAME); + $originalClassName = \preg_replace('/\W/', '', $fileName); + } + + if (!\class_exists($originalClassName)) { + eval( + $this->getMockObjectGenerator()->generateClassFromWsdl( + $wsdlFile, + $originalClassName, + $methods, + $options + ) + ); + } + + $mockObject = $this->getMockObjectGenerator()->getMock( + $originalClassName, + $methods, + ['', $options], + $mockClassName, + $callOriginalConstructor, + false, + false + ); + + $this->registerMockObject($mockObject); + + return $mockObject; + } + + /** + * Returns a mock object for the specified trait with all abstract methods + * of the trait mocked. Concrete methods to mock can be specified with the + * `$mockedMethods` parameter. + * + * @param string $traitName + * @param string $mockClassName + * @param bool $callOriginalConstructor + * @param bool $callOriginalClone + * @param bool $callAutoload + * @param array $mockedMethods + * @param bool $cloneArguments + */ + protected function getMockForTrait($traitName, array $arguments = [], $mockClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true, $mockedMethods = [], $cloneArguments = false): MockObject + { + $this->recordDoubledType($traitName); + + $mockObject = $this->getMockObjectGenerator()->getMockForTrait( + $traitName, + $arguments, + $mockClassName, + $callOriginalConstructor, + $callOriginalClone, + $callAutoload, + $mockedMethods, + $cloneArguments + ); + + $this->registerMockObject($mockObject); + + return $mockObject; + } + + /** + * Returns an object for the specified trait. + * + * @param string $traitName + * @param string $traitClassName + * @param bool $callOriginalConstructor + * @param bool $callOriginalClone + * @param bool $callAutoload + * + * @return object + */ + protected function getObjectForTrait($traitName, array $arguments = [], $traitClassName = '', $callOriginalConstructor = true, $callOriginalClone = true, $callAutoload = true)/*: object*/ + { + $this->recordDoubledType($traitName); + + return $this->getMockObjectGenerator()->getObjectForTrait( + $traitName, + $traitClassName, + $callAutoload, + $callOriginalConstructor, + $arguments + ); + } + + /** + * @param null|string $classOrInterface + * + * @throws \Prophecy\Exception\Doubler\ClassNotFoundException + * @throws \Prophecy\Exception\Doubler\DoubleException + * @throws \Prophecy\Exception\Doubler\InterfaceNotFoundException + * + * @psalm-param class-string|null $classOrInterface + */ + protected function prophesize($classOrInterface = null): ObjectProphecy + { + if (\is_string($classOrInterface)) { + $this->recordDoubledType($classOrInterface); + } + + return $this->getProphet()->prophesize($classOrInterface); + } + + /** + * Creates a default TestResult object. + * + * @internal This method is not covered by the backward compatibility promise for PHPUnit + */ + protected function createResult(): TestResult + { + return new TestResult; + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called between setUp() and test. + */ + protected function assertPreConditions(): void + { + } + + /** + * Performs assertions shared by all tests of a test case. + * + * This method is called between test and tearDown(). + */ + protected function assertPostConditions(): void + { + } + + /** + * This method is called when a test method did not execute successfully. + * + * @throws \Throwable + */ + protected function onNotSuccessfulTest(\Throwable $t): void + { + throw $t; + } + + private function setExpectedExceptionFromAnnotation(): void + { + if ($this->name === null) { + return; + } + + try { + $expectedException = TestUtil::getExpectedException( + \get_class($this), + $this->name + ); + + if ($expectedException !== false) { + $this->addWarning('The @expectedException, @expectedExceptionCode, @expectedExceptionMessage, and @expectedExceptionMessageRegExp annotations are deprecated. They will be removed in PHPUnit 9. Refactor your test to use expectException(), expectExceptionCode(), expectExceptionMessage(), or expectExceptionMessageMatches() instead.'); + + $this->expectException($expectedException['class']); + + if ($expectedException['code'] !== null) { + $this->expectExceptionCode($expectedException['code']); + } + + if ($expectedException['message'] !== '') { + $this->expectExceptionMessage($expectedException['message']); + } elseif ($expectedException['message_regex'] !== '') { + $this->expectExceptionMessageMatches($expectedException['message_regex']); + } + } + } catch (UtilException $e) { + } + } + + /** + * @throws Warning + * @throws SkippedTestError + * @throws SyntheticSkippedError + */ + private function checkRequirements(): void + { + if (!$this->name || !\method_exists($this, $this->name)) { + return; + } + + $missingRequirements = TestUtil::getMissingRequirements( + \get_class($this), + $this->name + ); + + if (!empty($missingRequirements)) { + $this->markTestSkipped(\implode(\PHP_EOL, $missingRequirements)); + } + } + + /** + * @throws \Throwable + */ + private function verifyMockObjects(): void + { + foreach ($this->mockObjects as $mockObject) { + if ($mockObject->__phpunit_hasMatchers()) { + $this->numAssertions++; + } + + $mockObject->__phpunit_verify( + $this->shouldInvocationMockerBeReset($mockObject) + ); + } + + if ($this->prophet !== null) { + try { + $this->prophet->checkPredictions(); + } finally { + foreach ($this->prophet->getProphecies() as $objectProphecy) { + foreach ($objectProphecy->getMethodProphecies() as $methodProphecies) { + foreach ($methodProphecies as $methodProphecy) { + \assert($methodProphecy instanceof MethodProphecy); + + $this->numAssertions += \count($methodProphecy->getCheckedPredictions()); + } + } + } + } + } + } + + private function handleDependencies(): bool + { + if (!empty($this->dependencies) && !$this->inIsolation) { + $className = \get_class($this); + $passed = $this->result->passed(); + $passedKeys = \array_keys($passed); + + foreach ($passedKeys as $key => $value) { + $pos = \strpos($value, ' with data set'); + + if ($pos !== false) { + $passedKeys[$key] = \substr($value, 0, $pos); + } + } + + $passedKeys = \array_flip(\array_unique($passedKeys)); + + foreach ($this->dependencies as $dependency) { + $deepClone = false; + $shallowClone = false; + + if (empty($dependency)) { + $this->markSkippedForNotSpecifyingDependency(); + + return false; + } + + if (\strpos($dependency, 'clone ') === 0) { + $deepClone = true; + $dependency = \substr($dependency, \strlen('clone ')); + } elseif (\strpos($dependency, '!clone ') === 0) { + $deepClone = false; + $dependency = \substr($dependency, \strlen('!clone ')); + } + + if (\strpos($dependency, 'shallowClone ') === 0) { + $shallowClone = true; + $dependency = \substr($dependency, \strlen('shallowClone ')); + } elseif (\strpos($dependency, '!shallowClone ') === 0) { + $shallowClone = false; + $dependency = \substr($dependency, \strlen('!shallowClone ')); + } + + if (\strpos($dependency, '::') === false) { + $dependency = $className . '::' . $dependency; + } + + if (!isset($passedKeys[$dependency])) { + if (!$this->isCallableTestMethod($dependency)) { + $this->warnAboutDependencyThatDoesNotExist($dependency); + } else { + $this->markSkippedForMissingDependency($dependency); + } + + return false; + } + + if (isset($passed[$dependency])) { + if ($passed[$dependency]['size'] !== TestUtil::UNKNOWN && + $this->getSize() !== TestUtil::UNKNOWN && + $passed[$dependency]['size'] > $this->getSize()) { + $this->result->addError( + $this, + new SkippedTestError( + 'This test depends on a test that is larger than itself.' + ), + 0 + ); + + return false; + } + + if ($deepClone) { + $deepCopy = new DeepCopy; + $deepCopy->skipUncloneable(false); + + $this->dependencyInput[$dependency] = $deepCopy->copy($passed[$dependency]['result']); + } elseif ($shallowClone) { + $this->dependencyInput[$dependency] = clone $passed[$dependency]['result']; + } else { + $this->dependencyInput[$dependency] = $passed[$dependency]['result']; + } + } else { + $this->dependencyInput[$dependency] = null; + } + } + } + + return true; + } + + private function markSkippedForNotSpecifyingDependency(): void + { + $this->status = BaseTestRunner::STATUS_SKIPPED; + + $this->result->startTest($this); + + $this->result->addError( + $this, + new SkippedTestError( + \sprintf('This method has an invalid @depends annotation.') + ), + 0 + ); + + $this->result->endTest($this, 0); + } + + private function markSkippedForMissingDependency(string $dependency): void + { + $this->status = BaseTestRunner::STATUS_SKIPPED; + + $this->result->startTest($this); + + $this->result->addError( + $this, + new SkippedTestError( + \sprintf( + 'This test depends on "%s" to pass.', + $dependency + ) + ), + 0 + ); + + $this->result->endTest($this, 0); + } + + private function warnAboutDependencyThatDoesNotExist(string $dependency): void + { + $this->status = BaseTestRunner::STATUS_WARNING; + + $this->result->startTest($this); + + $this->result->addWarning( + $this, + new Warning( + \sprintf( + 'This test depends on "%s" which does not exist.', + $dependency + ) + ), + 0 + ); + + $this->result->endTest($this, 0); + } + + /** + * Get the mock object generator, creating it if it doesn't exist. + */ + private function getMockObjectGenerator(): MockGenerator + { + if ($this->mockObjectGenerator === null) { + $this->mockObjectGenerator = new MockGenerator; + } + + return $this->mockObjectGenerator; + } + + private function startOutputBuffering(): void + { + \ob_start(); + + $this->outputBufferingActive = true; + $this->outputBufferingLevel = \ob_get_level(); + } + + /** + * @throws RiskyTestError + */ + private function stopOutputBuffering(): void + { + if (\ob_get_level() !== $this->outputBufferingLevel) { + while (\ob_get_level() >= $this->outputBufferingLevel) { + \ob_end_clean(); + } + + throw new RiskyTestError( + 'Test code or tested code did not (only) close its own output buffers' + ); + } + + $this->output = \ob_get_contents(); + + if ($this->outputCallback !== false) { + $this->output = (string) \call_user_func($this->outputCallback, $this->output); + } + + \ob_end_clean(); + + $this->outputBufferingActive = false; + $this->outputBufferingLevel = \ob_get_level(); + } + + private function snapshotGlobalState(): void + { + if ($this->runTestInSeparateProcess || $this->inIsolation || + (!$this->backupGlobals && !$this->backupStaticAttributes)) { + return; + } + + $this->snapshot = $this->createGlobalStateSnapshot($this->backupGlobals === true); + } + + /** + * @throws RiskyTestError + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function restoreGlobalState(): void + { + if (!$this->snapshot instanceof Snapshot) { + return; + } + + if ($this->beStrictAboutChangesToGlobalState) { + try { + $this->compareGlobalStateSnapshots( + $this->snapshot, + $this->createGlobalStateSnapshot($this->backupGlobals === true) + ); + } catch (RiskyTestError $rte) { + // Intentionally left empty + } + } + + $restorer = new Restorer; + + if ($this->backupGlobals) { + $restorer->restoreGlobalVariables($this->snapshot); + } + + if ($this->backupStaticAttributes) { + $restorer->restoreStaticAttributes($this->snapshot); + } + + $this->snapshot = null; + + if (isset($rte)) { + throw $rte; + } + } + + private function createGlobalStateSnapshot(bool $backupGlobals): Snapshot + { + $blacklist = new Blacklist; + + foreach ($this->backupGlobalsBlacklist as $globalVariable) { + $blacklist->addGlobalVariable($globalVariable); + } + + if (!\defined('PHPUNIT_TESTSUITE')) { + $blacklist->addClassNamePrefix('PHPUnit'); + $blacklist->addClassNamePrefix('SebastianBergmann\CodeCoverage'); + $blacklist->addClassNamePrefix('SebastianBergmann\FileIterator'); + $blacklist->addClassNamePrefix('SebastianBergmann\Invoker'); + $blacklist->addClassNamePrefix('SebastianBergmann\Timer'); + $blacklist->addClassNamePrefix('PHP_Token'); + $blacklist->addClassNamePrefix('Symfony'); + $blacklist->addClassNamePrefix('Text_Template'); + $blacklist->addClassNamePrefix('Doctrine\Instantiator'); + $blacklist->addClassNamePrefix('Prophecy'); + + foreach ($this->backupStaticAttributesBlacklist as $class => $attributes) { + foreach ($attributes as $attribute) { + $blacklist->addStaticAttribute($class, $attribute); + } + } + } + + return new Snapshot( + $blacklist, + $backupGlobals, + (bool) $this->backupStaticAttributes, + false, + false, + false, + false, + false, + false, + false + ); + } + + /** + * @throws RiskyTestError + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function compareGlobalStateSnapshots(Snapshot $before, Snapshot $after): void + { + $backupGlobals = $this->backupGlobals === null || $this->backupGlobals; + + if ($backupGlobals) { + $this->compareGlobalStateSnapshotPart( + $before->globalVariables(), + $after->globalVariables(), + "--- Global variables before the test\n+++ Global variables after the test\n" + ); + + $this->compareGlobalStateSnapshotPart( + $before->superGlobalVariables(), + $after->superGlobalVariables(), + "--- Super-global variables before the test\n+++ Super-global variables after the test\n" + ); + } + + if ($this->backupStaticAttributes) { + $this->compareGlobalStateSnapshotPart( + $before->staticAttributes(), + $after->staticAttributes(), + "--- Static attributes before the test\n+++ Static attributes after the test\n" + ); + } + } + + /** + * @throws RiskyTestError + */ + private function compareGlobalStateSnapshotPart(array $before, array $after, string $header): void + { + if ($before != $after) { + $differ = new Differ($header); + $exporter = new Exporter; + + $diff = $differ->diff( + $exporter->export($before), + $exporter->export($after) + ); + + throw new RiskyTestError( + $diff + ); + } + } + + private function getProphet(): Prophet + { + if ($this->prophet === null) { + $this->prophet = new Prophet; + } + + return $this->prophet; + } + + /** + * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException + */ + private function shouldInvocationMockerBeReset(MockObject $mock): bool + { + $enumerator = new Enumerator; + + foreach ($enumerator->enumerate($this->dependencyInput) as $object) { + if ($mock === $object) { + return false; + } + } + + if (!\is_array($this->testResult) && !\is_object($this->testResult)) { + return true; + } + + return !\in_array($mock, $enumerator->enumerate($this->testResult), true); + } + + /** + * @throws \SebastianBergmann\ObjectEnumerator\InvalidArgumentException + * @throws \SebastianBergmann\ObjectReflector\InvalidArgumentException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function registerMockObjectsFromTestArguments(array $testArguments, array &$visited = []): void + { + if ($this->registerMockObjectsFromTestArgumentsRecursively) { + foreach ((new Enumerator)->enumerate($testArguments) as $object) { + if ($object instanceof MockObject) { + $this->registerMockObject($object); + } + } + } else { + foreach ($testArguments as $testArgument) { + if ($testArgument instanceof MockObject) { + if (Type::isCloneable($testArgument)) { + $testArgument = clone $testArgument; + } + + $this->registerMockObject($testArgument); + } elseif (\is_array($testArgument) && !\in_array($testArgument, $visited, true)) { + $visited[] = $testArgument; + + $this->registerMockObjectsFromTestArguments( + $testArgument, + $visited + ); + } + } + } + } + + private function setDoesNotPerformAssertionsFromAnnotation(): void + { + $annotations = $this->getAnnotations(); + + if (isset($annotations['method']['doesNotPerformAssertions'])) { + $this->doesNotPerformAssertions = true; + } + } + + private function unregisterCustomComparators(): void + { + $factory = ComparatorFactory::getInstance(); + + foreach ($this->customComparators as $comparator) { + $factory->unregister($comparator); + } + + $this->customComparators = []; + } + + private function cleanupIniSettings(): void + { + foreach ($this->iniSettings as $varName => $oldValue) { + \ini_set($varName, $oldValue); + } + + $this->iniSettings = []; + } + + private function cleanupLocaleSettings(): void + { + foreach ($this->locale as $category => $locale) { + \setlocale($category, $locale); + } + + $this->locale = []; + } + + /** + * @throws Exception + */ + private function checkExceptionExpectations(\Throwable $throwable): bool + { + $result = false; + + if ($this->expectedException !== null || $this->expectedExceptionCode !== null || $this->expectedExceptionMessage !== null || $this->expectedExceptionMessageRegExp !== null) { + $result = true; + } + + if ($throwable instanceof Exception) { + $result = false; + } + + if (\is_string($this->expectedException)) { + try { + $reflector = new \ReflectionClass($this->expectedException); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($this->expectedException === 'PHPUnit\Framework\Exception' || + $this->expectedException === '\PHPUnit\Framework\Exception' || + $reflector->isSubclassOf(Exception::class)) { + $result = true; + } + } + + return $result; + } + + private function runInSeparateProcess(): bool + { + return ($this->runTestInSeparateProcess || $this->runClassInSeparateProcess) && + !$this->inIsolation && !$this instanceof PhptTestCase; + } + + /** + * @param string|string[] $originalClassName + */ + private function recordDoubledType($originalClassName): void + { + if (\is_string($originalClassName)) { + $this->doubledTypes[] = $originalClassName; + } + + if (\is_array($originalClassName)) { + foreach ($originalClassName as $_originalClassName) { + if (\is_string($_originalClassName)) { + $this->doubledTypes[] = $_originalClassName; + } + } + } + } + + private function isCallableTestMethod(string $dependency): bool + { + [$className, $methodName] = \explode('::', $dependency); + + if (!\class_exists($className)) { + return false; + } + + try { + $class = new \ReflectionClass($className); + } catch (\ReflectionException $e) { + return false; + } + + if (!$class->isSubclassOf(__CLASS__)) { + return false; + } + + if (!$class->hasMethod($methodName)) { + return false; + } + + try { + $method = $class->getMethod($methodName); + } catch (\ReflectionException $e) { + return false; + } + + return TestUtil::isTestMethod($method); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestFailure.php b/vendor/phpunit/phpunit/src/Framework/TestFailure.php new file mode 100644 index 0000000..6fe25f5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestFailure.php @@ -0,0 +1,154 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Framework\Error\Error; +use Throwable; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestFailure +{ + /** + * @var null|Test + */ + private $failedTest; + + /** + * @var Throwable + */ + private $thrownException; + + /** + * @var string + */ + private $testName; + + /** + * Returns a description for an exception. + */ + public static function exceptionToString(Throwable $e): string + { + if ($e instanceof SelfDescribing) { + $buffer = $e->toString(); + + if ($e instanceof ExpectationFailedException && $e->getComparisonFailure()) { + $buffer .= $e->getComparisonFailure()->getDiff(); + } + + if ($e instanceof PHPTAssertionFailedError) { + $buffer .= $e->getDiff(); + } + + if (!empty($buffer)) { + $buffer = \trim($buffer) . "\n"; + } + + return $buffer; + } + + if ($e instanceof Error) { + return $e->getMessage() . "\n"; + } + + if ($e instanceof ExceptionWrapper) { + return $e->getClassName() . ': ' . $e->getMessage() . "\n"; + } + + return \get_class($e) . ': ' . $e->getMessage() . "\n"; + } + + /** + * Constructs a TestFailure with the given test and exception. + * + * @param Throwable $t + */ + public function __construct(Test $failedTest, $t) + { + if ($failedTest instanceof SelfDescribing) { + $this->testName = $failedTest->toString(); + } else { + $this->testName = \get_class($failedTest); + } + + if (!$failedTest instanceof TestCase || !$failedTest->isInIsolation()) { + $this->failedTest = $failedTest; + } + + $this->thrownException = $t; + } + + /** + * Returns a short description of the failure. + */ + public function toString(): string + { + return \sprintf( + '%s: %s', + $this->testName, + $this->thrownException->getMessage() + ); + } + + /** + * Returns a description for the thrown exception. + */ + public function getExceptionAsString(): string + { + return self::exceptionToString($this->thrownException); + } + + /** + * Returns the name of the failing test (including data set, if any). + */ + public function getTestName(): string + { + return $this->testName; + } + + /** + * Returns the failing test. + * + * Note: The test object is not set when the test is executed in process + * isolation. + * + * @see Exception + */ + public function failedTest(): ?Test + { + return $this->failedTest; + } + + /** + * Gets the thrown exception. + */ + public function thrownException(): Throwable + { + return $this->thrownException; + } + + /** + * Returns the exception's message. + */ + public function exceptionMessage(): string + { + return $this->thrownException()->getMessage(); + } + + /** + * Returns true if the thrown exception + * is of type AssertionFailedError. + */ + public function isFailure(): bool + { + return $this->thrownException() instanceof AssertionFailedError; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestListener.php b/vendor/phpunit/phpunit/src/Framework/TestListener.php new file mode 100644 index 0000000..0390151 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestListener.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @deprecated Use the `TestHook` interfaces instead + */ +interface TestListener +{ + /** + * An error occurred. + * + * @deprecated Use `AfterTestErrorHook::executeAfterTestError` instead + */ + public function addError(Test $test, \Throwable $t, float $time): void; + + /** + * A warning occurred. + * + * @deprecated Use `AfterTestWarningHook::executeAfterTestWarning` instead + */ + public function addWarning(Test $test, Warning $e, float $time): void; + + /** + * A failure occurred. + * + * @deprecated Use `AfterTestFailureHook::executeAfterTestFailure` instead + */ + public function addFailure(Test $test, AssertionFailedError $e, float $time): void; + + /** + * Incomplete test. + * + * @deprecated Use `AfterIncompleteTestHook::executeAfterIncompleteTest` instead + */ + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void; + + /** + * Risky test. + * + * @deprecated Use `AfterRiskyTestHook::executeAfterRiskyTest` instead + */ + public function addRiskyTest(Test $test, \Throwable $t, float $time): void; + + /** + * Skipped test. + * + * @deprecated Use `AfterSkippedTestHook::executeAfterSkippedTest` instead + */ + public function addSkippedTest(Test $test, \Throwable $t, float $time): void; + + /** + * A test suite started. + */ + public function startTestSuite(TestSuite $suite): void; + + /** + * A test suite ended. + */ + public function endTestSuite(TestSuite $suite): void; + + /** + * A test started. + * + * @deprecated Use `BeforeTestHook::executeBeforeTest` instead + */ + public function startTest(Test $test): void; + + /** + * A test ended. + * + * @deprecated Use `AfterTestHook::executeAfterTest` instead + */ + public function endTest(Test $test, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php b/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php new file mode 100644 index 0000000..9c080af --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestListenerDefaultImplementation.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @deprecated The `TestListener` interface is deprecated + */ +trait TestListenerDefaultImplementation +{ + public function addError(Test $test, \Throwable $t, float $time): void + { + } + + public function addWarning(Test $test, Warning $e, float $time): void + { + } + + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + } + + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void + { + } + + public function addRiskyTest(Test $test, \Throwable $t, float $time): void + { + } + + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + } + + public function startTestSuite(TestSuite $suite): void + { + } + + public function endTestSuite(TestSuite $suite): void + { + } + + public function startTest(Test $test): void + { + } + + public function endTest(Test $test, float $time): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestResult.php b/vendor/phpunit/phpunit/src/Framework/TestResult.php new file mode 100644 index 0000000..2aea26a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestResult.php @@ -0,0 +1,1220 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use AssertionError; +use Countable; +use Error; +use PHPUnit\Framework\MockObject\Exception as MockObjectException; +use PHPUnit\Util\Blacklist; +use PHPUnit\Util\ErrorHandler; +use PHPUnit\Util\Printer; +use PHPUnit\Util\Test as TestUtil; +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException as OriginalCoveredCodeNotExecutedException; +use SebastianBergmann\CodeCoverage\Exception as OriginalCodeCoverageException; +use SebastianBergmann\CodeCoverage\MissingCoversAnnotationException as OriginalMissingCoversAnnotationException; +use SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException; +use SebastianBergmann\Invoker\Invoker; +use SebastianBergmann\Invoker\TimeoutException; +use SebastianBergmann\ResourceOperations\ResourceOperations; +use SebastianBergmann\Timer\Timer; +use Throwable; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestResult implements Countable +{ + /** + * @var array + */ + private $passed = []; + + /** + * @var TestFailure[] + */ + private $errors = []; + + /** + * @var TestFailure[] + */ + private $failures = []; + + /** + * @var TestFailure[] + */ + private $warnings = []; + + /** + * @var TestFailure[] + */ + private $notImplemented = []; + + /** + * @var TestFailure[] + */ + private $risky = []; + + /** + * @var TestFailure[] + */ + private $skipped = []; + + /** + * @deprecated Use the `TestHook` interfaces instead + * + * @var TestListener[] + */ + private $listeners = []; + + /** + * @var int + */ + private $runTests = 0; + + /** + * @var float + */ + private $time = 0; + + /** + * @var TestSuite + */ + private $topTestSuite; + + /** + * Code Coverage information. + * + * @var CodeCoverage + */ + private $codeCoverage; + + /** + * @var bool + */ + private $convertDeprecationsToExceptions = true; + + /** + * @var bool + */ + private $convertErrorsToExceptions = true; + + /** + * @var bool + */ + private $convertNoticesToExceptions = true; + + /** + * @var bool + */ + private $convertWarningsToExceptions = true; + + /** + * @var bool + */ + private $stop = false; + + /** + * @var bool + */ + private $stopOnError = false; + + /** + * @var bool + */ + private $stopOnFailure = false; + + /** + * @var bool + */ + private $stopOnWarning = false; + + /** + * @var bool + */ + private $beStrictAboutTestsThatDoNotTestAnything = true; + + /** + * @var bool + */ + private $beStrictAboutOutputDuringTests = false; + + /** + * @var bool + */ + private $beStrictAboutTodoAnnotatedTests = false; + + /** + * @var bool + */ + private $beStrictAboutResourceUsageDuringSmallTests = false; + + /** + * @var bool + */ + private $enforceTimeLimit = false; + + /** + * @var int + */ + private $timeoutForSmallTests = 1; + + /** + * @var int + */ + private $timeoutForMediumTests = 10; + + /** + * @var int + */ + private $timeoutForLargeTests = 60; + + /** + * @var bool + */ + private $stopOnRisky = false; + + /** + * @var bool + */ + private $stopOnIncomplete = false; + + /** + * @var bool + */ + private $stopOnSkipped = false; + + /** + * @var bool + */ + private $lastTestFailed = false; + + /** + * @var int + */ + private $defaultTimeLimit = 0; + + /** + * @var bool + */ + private $stopOnDefect = false; + + /** + * @var bool + */ + private $registerMockObjectsFromTestArgumentsRecursively = false; + + /** + * @deprecated Use the `TestHook` interfaces instead + * + * @codeCoverageIgnore + * + * Registers a TestListener. + */ + public function addListener(TestListener $listener): void + { + $this->listeners[] = $listener; + } + + /** + * @deprecated Use the `TestHook` interfaces instead + * + * @codeCoverageIgnore + * + * Unregisters a TestListener. + */ + public function removeListener(TestListener $listener): void + { + foreach ($this->listeners as $key => $_listener) { + if ($listener === $_listener) { + unset($this->listeners[$key]); + } + } + } + + /** + * @deprecated Use the `TestHook` interfaces instead + * + * @codeCoverageIgnore + * + * Flushes all flushable TestListeners. + */ + public function flushListeners(): void + { + foreach ($this->listeners as $listener) { + if ($listener instanceof Printer) { + $listener->flush(); + } + } + } + + /** + * Adds an error to the list of errors. + */ + public function addError(Test $test, Throwable $t, float $time): void + { + if ($t instanceof RiskyTestError) { + $this->risky[] = new TestFailure($test, $t); + $notifyMethod = 'addRiskyTest'; + + if ($test instanceof TestCase) { + $test->markAsRisky(); + } + + if ($this->stopOnRisky || $this->stopOnDefect) { + $this->stop(); + } + } elseif ($t instanceof IncompleteTest) { + $this->notImplemented[] = new TestFailure($test, $t); + $notifyMethod = 'addIncompleteTest'; + + if ($this->stopOnIncomplete) { + $this->stop(); + } + } elseif ($t instanceof SkippedTest) { + $this->skipped[] = new TestFailure($test, $t); + $notifyMethod = 'addSkippedTest'; + + if ($this->stopOnSkipped) { + $this->stop(); + } + } else { + $this->errors[] = new TestFailure($test, $t); + $notifyMethod = 'addError'; + + if ($this->stopOnError || $this->stopOnFailure) { + $this->stop(); + } + } + + // @see https://github.com/sebastianbergmann/phpunit/issues/1953 + if ($t instanceof Error) { + $t = new ExceptionWrapper($t); + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $t, $time); + } + + $this->lastTestFailed = true; + $this->time += $time; + } + + /** + * Adds a warning to the list of warnings. + * The passed in exception caused the warning. + */ + public function addWarning(Test $test, Warning $e, float $time): void + { + if ($this->stopOnWarning || $this->stopOnDefect) { + $this->stop(); + } + + $this->warnings[] = new TestFailure($test, $e); + + foreach ($this->listeners as $listener) { + $listener->addWarning($test, $e, $time); + } + + $this->time += $time; + } + + /** + * Adds a failure to the list of failures. + * The passed in exception caused the failure. + */ + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + if ($e instanceof RiskyTestError || $e instanceof OutputError) { + $this->risky[] = new TestFailure($test, $e); + $notifyMethod = 'addRiskyTest'; + + if ($test instanceof TestCase) { + $test->markAsRisky(); + } + + if ($this->stopOnRisky || $this->stopOnDefect) { + $this->stop(); + } + } elseif ($e instanceof IncompleteTest) { + $this->notImplemented[] = new TestFailure($test, $e); + $notifyMethod = 'addIncompleteTest'; + + if ($this->stopOnIncomplete) { + $this->stop(); + } + } elseif ($e instanceof SkippedTest) { + $this->skipped[] = new TestFailure($test, $e); + $notifyMethod = 'addSkippedTest'; + + if ($this->stopOnSkipped) { + $this->stop(); + } + } else { + $this->failures[] = new TestFailure($test, $e); + $notifyMethod = 'addFailure'; + + if ($this->stopOnFailure || $this->stopOnDefect) { + $this->stop(); + } + } + + foreach ($this->listeners as $listener) { + $listener->$notifyMethod($test, $e, $time); + } + + $this->lastTestFailed = true; + $this->time += $time; + } + + /** + * Informs the result that a test suite will be started. + */ + public function startTestSuite(TestSuite $suite): void + { + if ($this->topTestSuite === null) { + $this->topTestSuite = $suite; + } + + foreach ($this->listeners as $listener) { + $listener->startTestSuite($suite); + } + } + + /** + * Informs the result that a test suite was completed. + */ + public function endTestSuite(TestSuite $suite): void + { + foreach ($this->listeners as $listener) { + $listener->endTestSuite($suite); + } + } + + /** + * Informs the result that a test will be started. + */ + public function startTest(Test $test): void + { + $this->lastTestFailed = false; + $this->runTests += \count($test); + + foreach ($this->listeners as $listener) { + $listener->startTest($test); + } + } + + /** + * Informs the result that a test was completed. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function endTest(Test $test, float $time): void + { + foreach ($this->listeners as $listener) { + $listener->endTest($test, $time); + } + + if (!$this->lastTestFailed && $test instanceof TestCase) { + $class = \get_class($test); + $key = $class . '::' . $test->getName(); + + $this->passed[$key] = [ + 'result' => $test->getResult(), + 'size' => \PHPUnit\Util\Test::getSize( + $class, + $test->getName(false) + ), + ]; + + $this->time += $time; + } + } + + /** + * Returns true if no risky test occurred. + */ + public function allHarmless(): bool + { + return $this->riskyCount() == 0; + } + + /** + * Gets the number of risky tests. + */ + public function riskyCount(): int + { + return \count($this->risky); + } + + /** + * Returns true if no incomplete test occurred. + */ + public function allCompletelyImplemented(): bool + { + return $this->notImplementedCount() == 0; + } + + /** + * Gets the number of incomplete tests. + */ + public function notImplementedCount(): int + { + return \count($this->notImplemented); + } + + /** + * Returns an array of TestFailure objects for the risky tests + * + * @return TestFailure[] + */ + public function risky(): array + { + return $this->risky; + } + + /** + * Returns an array of TestFailure objects for the incomplete tests + * + * @return TestFailure[] + */ + public function notImplemented(): array + { + return $this->notImplemented; + } + + /** + * Returns true if no test has been skipped. + */ + public function noneSkipped(): bool + { + return $this->skippedCount() == 0; + } + + /** + * Gets the number of skipped tests. + */ + public function skippedCount(): int + { + return \count($this->skipped); + } + + /** + * Returns an array of TestFailure objects for the skipped tests + * + * @return TestFailure[] + */ + public function skipped(): array + { + return $this->skipped; + } + + /** + * Gets the number of detected errors. + */ + public function errorCount(): int + { + return \count($this->errors); + } + + /** + * Returns an array of TestFailure objects for the errors + * + * @return TestFailure[] + */ + public function errors(): array + { + return $this->errors; + } + + /** + * Gets the number of detected failures. + */ + public function failureCount(): int + { + return \count($this->failures); + } + + /** + * Returns an array of TestFailure objects for the failures + * + * @return TestFailure[] + */ + public function failures(): array + { + return $this->failures; + } + + /** + * Gets the number of detected warnings. + */ + public function warningCount(): int + { + return \count($this->warnings); + } + + /** + * Returns an array of TestFailure objects for the warnings + * + * @return TestFailure[] + */ + public function warnings(): array + { + return $this->warnings; + } + + /** + * Returns the names of the tests that have passed. + */ + public function passed(): array + { + return $this->passed; + } + + /** + * Returns the (top) test suite. + */ + public function topTestSuite(): TestSuite + { + return $this->topTestSuite; + } + + /** + * Returns whether code coverage information should be collected. + */ + public function getCollectCodeCoverageInformation(): bool + { + return $this->codeCoverage !== null; + } + + /** + * Runs a TestCase. + * + * @throws CodeCoverageException + * @throws OriginalCoveredCodeNotExecutedException + * @throws OriginalMissingCoversAnnotationException + * @throws UnintentionallyCoveredCodeException + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + * @throws \SebastianBergmann\CodeCoverage\RuntimeException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function run(Test $test): void + { + Assert::resetCount(); + + if ($test instanceof TestCase) { + $test->setRegisterMockObjectsFromTestArgumentsRecursively( + $this->registerMockObjectsFromTestArgumentsRecursively + ); + + $isAnyCoverageRequired = TestUtil::requiresCodeCoverageDataCollection($test); + } + + $error = false; + $failure = false; + $warning = false; + $incomplete = false; + $risky = false; + $skipped = false; + + $this->startTest($test); + + if ($this->convertDeprecationsToExceptions || $this->convertErrorsToExceptions || $this->convertNoticesToExceptions || $this->convertWarningsToExceptions) { + $errorHandler = new ErrorHandler( + $this->convertDeprecationsToExceptions, + $this->convertErrorsToExceptions, + $this->convertNoticesToExceptions, + $this->convertWarningsToExceptions + ); + + $errorHandler->register(); + } + + $collectCodeCoverage = $this->codeCoverage !== null && + !$test instanceof WarningTestCase && + $isAnyCoverageRequired; + + if ($collectCodeCoverage) { + $this->codeCoverage->start($test); + } + + $monitorFunctions = $this->beStrictAboutResourceUsageDuringSmallTests && + !$test instanceof WarningTestCase && + $test->getSize() == \PHPUnit\Util\Test::SMALL && + \function_exists('xdebug_start_function_monitor'); + + if ($monitorFunctions) { + /* @noinspection ForgottenDebugOutputInspection */ + \xdebug_start_function_monitor(ResourceOperations::getFunctions()); + } + + Timer::start(); + + try { + if (!$test instanceof WarningTestCase && + $this->enforceTimeLimit && + ($this->defaultTimeLimit || $test->getSize() != \PHPUnit\Util\Test::UNKNOWN) && + \extension_loaded('pcntl') && \class_exists(Invoker::class)) { + switch ($test->getSize()) { + case \PHPUnit\Util\Test::SMALL: + $_timeout = $this->timeoutForSmallTests; + + break; + + case \PHPUnit\Util\Test::MEDIUM: + $_timeout = $this->timeoutForMediumTests; + + break; + + case \PHPUnit\Util\Test::LARGE: + $_timeout = $this->timeoutForLargeTests; + + break; + + case \PHPUnit\Util\Test::UNKNOWN: + $_timeout = $this->defaultTimeLimit; + + break; + } + + $invoker = new Invoker; + $invoker->invoke([$test, 'runBare'], [], $_timeout); + } else { + $test->runBare(); + } + } catch (TimeoutException $e) { + $this->addFailure( + $test, + new RiskyTestError( + $e->getMessage() + ), + $_timeout + ); + + $risky = true; + } catch (MockObjectException $e) { + $e = new Warning( + $e->getMessage() + ); + + $warning = true; + } catch (AssertionFailedError $e) { + $failure = true; + + if ($e instanceof RiskyTestError) { + $risky = true; + } elseif ($e instanceof IncompleteTestError) { + $incomplete = true; + } elseif ($e instanceof SkippedTestError) { + $skipped = true; + } + } catch (AssertionError $e) { + $test->addToAssertionCount(1); + + $failure = true; + $frame = $e->getTrace()[0]; + + $e = new AssertionFailedError( + \sprintf( + '%s in %s:%s', + $e->getMessage(), + $frame['file'], + $frame['line'] + ) + ); + } catch (Warning $e) { + $warning = true; + } catch (Exception $e) { + $error = true; + } catch (Throwable $e) { + $e = new ExceptionWrapper($e); + $error = true; + } + + $time = Timer::stop(); + $test->addToAssertionCount(Assert::getCount()); + + if ($monitorFunctions) { + $blacklist = new Blacklist; + + /** @noinspection ForgottenDebugOutputInspection */ + $functions = \xdebug_get_monitored_functions(); + + /* @noinspection ForgottenDebugOutputInspection */ + \xdebug_stop_function_monitor(); + + foreach ($functions as $function) { + if (!$blacklist->isBlacklisted($function['filename'])) { + $this->addFailure( + $test, + new RiskyTestError( + \sprintf( + '%s() used in %s:%s', + $function['function'], + $function['filename'], + $function['lineno'] + ) + ), + $time + ); + } + } + } + + if ($this->beStrictAboutTestsThatDoNotTestAnything && + $test->getNumAssertions() == 0) { + $risky = true; + } + + if ($collectCodeCoverage) { + $append = !$risky && !$incomplete && !$skipped; + $linesToBeCovered = []; + $linesToBeUsed = []; + + if ($append && $test instanceof TestCase) { + try { + $linesToBeCovered = \PHPUnit\Util\Test::getLinesToBeCovered( + \get_class($test), + $test->getName(false) + ); + + $linesToBeUsed = \PHPUnit\Util\Test::getLinesToBeUsed( + \get_class($test), + $test->getName(false) + ); + } catch (InvalidCoversTargetException $cce) { + $this->addWarning( + $test, + new Warning( + $cce->getMessage() + ), + $time + ); + } + } + + try { + $this->codeCoverage->stop( + $append, + $linesToBeCovered, + $linesToBeUsed + ); + } catch (UnintentionallyCoveredCodeException $cce) { + $this->addFailure( + $test, + new UnintentionallyCoveredCodeError( + 'This test executed code that is not listed as code to be covered or used:' . + \PHP_EOL . $cce->getMessage() + ), + $time + ); + } catch (OriginalCoveredCodeNotExecutedException $cce) { + $this->addFailure( + $test, + new CoveredCodeNotExecutedException( + 'This test did not execute all the code that is listed as code to be covered:' . + \PHP_EOL . $cce->getMessage() + ), + $time + ); + } catch (OriginalMissingCoversAnnotationException $cce) { + if ($linesToBeCovered !== false) { + $this->addFailure( + $test, + new MissingCoversAnnotationException( + 'This test does not have a @covers annotation but is expected to have one' + ), + $time + ); + } + } catch (OriginalCodeCoverageException $cce) { + $error = true; + + $e = $e ?? $cce; + } + } + + if (isset($errorHandler)) { + $errorHandler->unregister(); + + unset($errorHandler); + } + + if ($error) { + $this->addError($test, $e, $time); + } elseif ($failure) { + $this->addFailure($test, $e, $time); + } elseif ($warning) { + $this->addWarning($test, $e, $time); + } elseif ($this->beStrictAboutTestsThatDoNotTestAnything && + !$test->doesNotPerformAssertions() && + $test->getNumAssertions() == 0) { + try { + $reflected = new \ReflectionClass($test); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $name = $test->getName(false); + + if ($name && $reflected->hasMethod($name)) { + try { + $reflected = $reflected->getMethod($name); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + $this->addFailure( + $test, + new RiskyTestError( + \sprintf( + "This test did not perform any assertions\n\n%s:%d", + $reflected->getFileName(), + $reflected->getStartLine() + ) + ), + $time + ); + } elseif ($this->beStrictAboutTestsThatDoNotTestAnything && + $test->doesNotPerformAssertions() && + $test->getNumAssertions() > 0) { + $this->addFailure( + $test, + new RiskyTestError( + \sprintf( + 'This test is annotated with "@doesNotPerformAssertions" but performed %d assertions', + $test->getNumAssertions() + ) + ), + $time + ); + } elseif ($this->beStrictAboutOutputDuringTests && $test->hasOutput()) { + $this->addFailure( + $test, + new OutputError( + \sprintf( + 'This test printed output: %s', + $test->getActualOutput() + ) + ), + $time + ); + } elseif ($this->beStrictAboutTodoAnnotatedTests && $test instanceof TestCase) { + $annotations = $test->getAnnotations(); + + if (isset($annotations['method']['todo'])) { + $this->addFailure( + $test, + new RiskyTestError( + 'Test method is annotated with @todo' + ), + $time + ); + } + } + + $this->endTest($test, $time); + } + + /** + * Gets the number of run tests. + */ + public function count(): int + { + return $this->runTests; + } + + /** + * Checks whether the test run should stop. + */ + public function shouldStop(): bool + { + return $this->stop; + } + + /** + * Marks that the test run should stop. + */ + public function stop(): void + { + $this->stop = true; + } + + /** + * Returns the code coverage object. + */ + public function getCodeCoverage(): ?CodeCoverage + { + return $this->codeCoverage; + } + + /** + * Sets the code coverage object. + */ + public function setCodeCoverage(CodeCoverage $codeCoverage): void + { + $this->codeCoverage = $codeCoverage; + } + + /** + * Enables or disables the deprecation-to-exception conversion. + */ + public function convertDeprecationsToExceptions(bool $flag): void + { + $this->convertDeprecationsToExceptions = $flag; + } + + /** + * Returns the deprecation-to-exception conversion setting. + */ + public function getConvertDeprecationsToExceptions(): bool + { + return $this->convertDeprecationsToExceptions; + } + + /** + * Enables or disables the error-to-exception conversion. + */ + public function convertErrorsToExceptions(bool $flag): void + { + $this->convertErrorsToExceptions = $flag; + } + + /** + * Returns the error-to-exception conversion setting. + */ + public function getConvertErrorsToExceptions(): bool + { + return $this->convertErrorsToExceptions; + } + + /** + * Enables or disables the notice-to-exception conversion. + */ + public function convertNoticesToExceptions(bool $flag): void + { + $this->convertNoticesToExceptions = $flag; + } + + /** + * Returns the notice-to-exception conversion setting. + */ + public function getConvertNoticesToExceptions(): bool + { + return $this->convertNoticesToExceptions; + } + + /** + * Enables or disables the warning-to-exception conversion. + */ + public function convertWarningsToExceptions(bool $flag): void + { + $this->convertWarningsToExceptions = $flag; + } + + /** + * Returns the warning-to-exception conversion setting. + */ + public function getConvertWarningsToExceptions(): bool + { + return $this->convertWarningsToExceptions; + } + + /** + * Enables or disables the stopping when an error occurs. + */ + public function stopOnError(bool $flag): void + { + $this->stopOnError = $flag; + } + + /** + * Enables or disables the stopping when a failure occurs. + */ + public function stopOnFailure(bool $flag): void + { + $this->stopOnFailure = $flag; + } + + /** + * Enables or disables the stopping when a warning occurs. + */ + public function stopOnWarning(bool $flag): void + { + $this->stopOnWarning = $flag; + } + + public function beStrictAboutTestsThatDoNotTestAnything(bool $flag): void + { + $this->beStrictAboutTestsThatDoNotTestAnything = $flag; + } + + public function isStrictAboutTestsThatDoNotTestAnything(): bool + { + return $this->beStrictAboutTestsThatDoNotTestAnything; + } + + public function beStrictAboutOutputDuringTests(bool $flag): void + { + $this->beStrictAboutOutputDuringTests = $flag; + } + + public function isStrictAboutOutputDuringTests(): bool + { + return $this->beStrictAboutOutputDuringTests; + } + + public function beStrictAboutResourceUsageDuringSmallTests(bool $flag): void + { + $this->beStrictAboutResourceUsageDuringSmallTests = $flag; + } + + public function isStrictAboutResourceUsageDuringSmallTests(): bool + { + return $this->beStrictAboutResourceUsageDuringSmallTests; + } + + public function enforceTimeLimit(bool $flag): void + { + $this->enforceTimeLimit = $flag; + } + + public function enforcesTimeLimit(): bool + { + return $this->enforceTimeLimit; + } + + public function beStrictAboutTodoAnnotatedTests(bool $flag): void + { + $this->beStrictAboutTodoAnnotatedTests = $flag; + } + + public function isStrictAboutTodoAnnotatedTests(): bool + { + return $this->beStrictAboutTodoAnnotatedTests; + } + + /** + * Enables or disables the stopping for risky tests. + */ + public function stopOnRisky(bool $flag): void + { + $this->stopOnRisky = $flag; + } + + /** + * Enables or disables the stopping for incomplete tests. + */ + public function stopOnIncomplete(bool $flag): void + { + $this->stopOnIncomplete = $flag; + } + + /** + * Enables or disables the stopping for skipped tests. + */ + public function stopOnSkipped(bool $flag): void + { + $this->stopOnSkipped = $flag; + } + + /** + * Enables or disables the stopping for defects: error, failure, warning + */ + public function stopOnDefect(bool $flag): void + { + $this->stopOnDefect = $flag; + } + + /** + * Returns the time spent running the tests. + */ + public function time(): float + { + return $this->time; + } + + /** + * Returns whether the entire test was successful or not. + */ + public function wasSuccessful(): bool + { + return $this->wasSuccessfulIgnoringWarnings() && empty($this->warnings); + } + + public function wasSuccessfulIgnoringWarnings(): bool + { + return empty($this->errors) && empty($this->failures); + } + + public function wasSuccessfulAndNoTestIsRiskyOrSkippedOrIncomplete(): bool + { + return $this->wasSuccessful() && $this->allHarmless() && $this->allCompletelyImplemented() && $this->noneSkipped(); + } + + /** + * Sets the default timeout for tests + */ + public function setDefaultTimeLimit(int $timeout): void + { + $this->defaultTimeLimit = $timeout; + } + + /** + * Sets the timeout for small tests. + */ + public function setTimeoutForSmallTests(int $timeout): void + { + $this->timeoutForSmallTests = $timeout; + } + + /** + * Sets the timeout for medium tests. + */ + public function setTimeoutForMediumTests(int $timeout): void + { + $this->timeoutForMediumTests = $timeout; + } + + /** + * Sets the timeout for large tests. + */ + public function setTimeoutForLargeTests(int $timeout): void + { + $this->timeoutForLargeTests = $timeout; + } + + /** + * Returns the set timeout for large tests. + */ + public function getTimeoutForLargeTests(): int + { + return $this->timeoutForLargeTests; + } + + public function setRegisterMockObjectsFromTestArgumentsRecursively(bool $flag): void + { + $this->registerMockObjectsFromTestArgumentsRecursively = $flag; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuite.php b/vendor/phpunit/phpunit/src/Framework/TestSuite.php new file mode 100644 index 0000000..fb0c4e5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestSuite.php @@ -0,0 +1,780 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +use PHPUnit\Runner\BaseTestRunner; +use PHPUnit\Runner\Filter\Factory; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\Util\FileLoader; +use PHPUnit\Util\Test as TestUtil; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class TestSuite implements \IteratorAggregate, SelfDescribing, Test +{ + /** + * Enable or disable the backup and restoration of the $GLOBALS array. + * + * @var bool + */ + protected $backupGlobals; + + /** + * Enable or disable the backup and restoration of static attributes. + * + * @var bool + */ + protected $backupStaticAttributes; + + /** + * @var bool + */ + protected $runTestInSeparateProcess = false; + + /** + * The name of the test suite. + * + * @var string + */ + protected $name = ''; + + /** + * The test groups of the test suite. + * + * @var array + */ + protected $groups = []; + + /** + * The tests in the test suite. + * + * @var Test[] + */ + protected $tests = []; + + /** + * The number of tests in the test suite. + * + * @var int + */ + protected $numTests = -1; + + /** + * @var bool + */ + protected $testCase = false; + + /** + * @var string[] + */ + protected $foundClasses = []; + + /** + * Last count of tests in this suite. + * + * @var null|int + */ + private $cachedNumTests; + + /** + * @var bool + */ + private $beStrictAboutChangesToGlobalState; + + /** + * @var Factory + */ + private $iteratorFilter; + + /** + * @var string[] + */ + private $declaredClasses; + + /** + * Constructs a new TestSuite: + * + * - PHPUnit\Framework\TestSuite() constructs an empty TestSuite. + * + * - PHPUnit\Framework\TestSuite(ReflectionClass) constructs a + * TestSuite from the given class. + * + * - PHPUnit\Framework\TestSuite(ReflectionClass, String) + * constructs a TestSuite from the given class with the given + * name. + * + * - PHPUnit\Framework\TestSuite(String) either constructs a + * TestSuite from the given class (if the passed string is the + * name of an existing class) or constructs an empty TestSuite + * with the given name. + * + * @param \ReflectionClass|string $theClass + * + * @throws Exception + */ + public function __construct($theClass = '', string $name = '') + { + if (!\is_string($theClass) && !$theClass instanceof \ReflectionClass) { + throw InvalidArgumentException::create( + 1, + 'ReflectionClass object or string' + ); + } + + $this->declaredClasses = \get_declared_classes(); + + if (!$theClass instanceof \ReflectionClass) { + if (\class_exists($theClass, true)) { + if ($name === '') { + $name = $theClass; + } + + try { + $theClass = new \ReflectionClass($theClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } else { + $this->setName($theClass); + + return; + } + } + + if (!$theClass->isSubclassOf(TestCase::class)) { + $this->setName((string) $theClass); + + return; + } + + if ($name !== '') { + $this->setName($name); + } else { + $this->setName($theClass->getName()); + } + + $constructor = $theClass->getConstructor(); + + if ($constructor !== null && + !$constructor->isPublic()) { + $this->addTest( + new WarningTestCase( + \sprintf( + 'Class "%s" has no public constructor.', + $theClass->getName() + ) + ) + ); + + return; + } + + foreach ($theClass->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() === Assert::class) { + continue; + } + + if ($method->getDeclaringClass()->getName() === TestCase::class) { + continue; + } + + $this->addTestMethod($theClass, $method); + } + + if (empty($this->tests)) { + $this->addTest( + new WarningTestCase( + \sprintf( + 'No tests found in class "%s".', + $theClass->getName() + ) + ) + ); + } + + $this->testCase = true; + } + + /** + * Returns a string representation of the test suite. + */ + public function toString(): string + { + return $this->getName(); + } + + /** + * Adds a test to the suite. + * + * @param array $groups + */ + public function addTest(Test $test, $groups = []): void + { + try { + $class = new \ReflectionClass($test); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$class->isAbstract()) { + $this->tests[] = $test; + $this->numTests = -1; + + if ($test instanceof self && empty($groups)) { + $groups = $test->getGroups(); + } + + if (empty($groups)) { + $groups = ['default']; + } + + foreach ($groups as $group) { + if (!isset($this->groups[$group])) { + $this->groups[$group] = [$test]; + } else { + $this->groups[$group][] = $test; + } + } + + if ($test instanceof TestCase) { + $test->setGroups($groups); + } + } + } + + /** + * Adds the tests from the given class to the suite. + * + * @param object|string $testClass + * + * @throws Exception + */ + public function addTestSuite($testClass): void + { + if (!(\is_object($testClass) || (\is_string($testClass) && \class_exists($testClass)))) { + throw InvalidArgumentException::create( + 1, + 'class name or object' + ); + } + + if (!\is_object($testClass)) { + try { + $testClass = new \ReflectionClass($testClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + if ($testClass instanceof self) { + $this->addTest($testClass); + } elseif ($testClass instanceof \ReflectionClass) { + $suiteMethod = false; + + if (!$testClass->isAbstract() && $testClass->hasMethod(BaseTestRunner::SUITE_METHODNAME)) { + try { + $method = $testClass->getMethod( + BaseTestRunner::SUITE_METHODNAME + ); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($method->isStatic()) { + $this->addTest( + $method->invoke(null, $testClass->getName()) + ); + + $suiteMethod = true; + } + } + + if (!$suiteMethod && !$testClass->isAbstract() && $testClass->isSubclassOf(TestCase::class)) { + $this->addTest(new self($testClass)); + } + } else { + throw new Exception; + } + } + + /** + * Wraps both addTest() and addTestSuite + * as well as the separate import statements for the user's convenience. + * + * If the named file cannot be read or there are no new tests that can be + * added, a PHPUnit\Framework\WarningTestCase will be created instead, + * leaving the current test run untouched. + * + * @throws Exception + */ + public function addTestFile(string $filename): void + { + if (\file_exists($filename) && \substr($filename, -5) === '.phpt') { + $this->addTest( + new PhptTestCase($filename) + ); + + return; + } + + // The given file may contain further stub classes in addition to the + // test class itself. Figure out the actual test class. + $filename = FileLoader::checkAndLoad($filename); + $newClasses = \array_diff(\get_declared_classes(), $this->declaredClasses); + + // The diff is empty in case a parent class (with test methods) is added + // AFTER a child class that inherited from it. To account for that case, + // accumulate all discovered classes, so the parent class may be found in + // a later invocation. + if (!empty($newClasses)) { + // On the assumption that test classes are defined first in files, + // process discovered classes in approximate LIFO order, so as to + // avoid unnecessary reflection. + $this->foundClasses = \array_merge($newClasses, $this->foundClasses); + $this->declaredClasses = \get_declared_classes(); + } + + // The test class's name must match the filename, either in full, or as + // a PEAR/PSR-0 prefixed short name ('NameSpace_ShortName'), or as a + // PSR-1 local short name ('NameSpace\ShortName'). The comparison must be + // anchored to prevent false-positive matches (e.g., 'OtherShortName'). + $shortName = \basename($filename, '.php'); + $shortNameRegEx = '/(?:^|_|\\\\)' . \preg_quote($shortName, '/') . '$/'; + + foreach ($this->foundClasses as $i => $className) { + if (\preg_match($shortNameRegEx, $className)) { + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($class->getFileName() == $filename) { + $newClasses = [$className]; + unset($this->foundClasses[$i]); + + break; + } + } + } + + foreach ($newClasses as $className) { + try { + $class = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (\dirname($class->getFileName()) === __DIR__) { + continue; + } + + if (!$class->isAbstract()) { + if ($class->hasMethod(BaseTestRunner::SUITE_METHODNAME)) { + try { + $method = $class->getMethod( + BaseTestRunner::SUITE_METHODNAME + ); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($method->isStatic()) { + $this->addTest($method->invoke(null, $className)); + } + } elseif ($class->implementsInterface(Test::class)) { + $this->addTestSuite($class); + } + } + } + + $this->numTests = -1; + } + + /** + * Wrapper for addTestFile() that adds multiple test files. + * + * @throws Exception + */ + public function addTestFiles(iterable $fileNames): void + { + foreach ($fileNames as $filename) { + $this->addTestFile((string) $filename); + } + } + + /** + * Counts the number of test cases that will be run by this test. + */ + public function count(bool $preferCache = false): int + { + if ($preferCache && $this->cachedNumTests !== null) { + return $this->cachedNumTests; + } + + $numTests = 0; + + foreach ($this as $test) { + $numTests += \count($test); + } + + $this->cachedNumTests = $numTests; + + return $numTests; + } + + /** + * Returns the name of the suite. + */ + public function getName(): string + { + return $this->name; + } + + /** + * Returns the test groups of the suite. + */ + public function getGroups(): array + { + return \array_keys($this->groups); + } + + public function getGroupDetails(): array + { + return $this->groups; + } + + /** + * Set tests groups of the test case + */ + public function setGroupDetails(array $groups): void + { + $this->groups = $groups; + } + + /** + * Runs the tests and collects their result in a TestResult. + * + * @throws \PHPUnit\Framework\CodeCoverageException + * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException + * @throws \SebastianBergmann\CodeCoverage\RuntimeException + * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Warning + */ + public function run(TestResult $result = null): TestResult + { + if ($result === null) { + $result = $this->createResult(); + } + + if (\count($this) === 0) { + return $result; + } + + /** @psalm-var class-string $className */ + $className = $this->name; + $hookMethods = TestUtil::getHookMethods($className); + + $result->startTestSuite($this); + + try { + foreach ($hookMethods['beforeClass'] as $beforeClassMethod) { + if ($this->testCase && + \class_exists($this->name, false) && + \method_exists($this->name, $beforeClassMethod)) { + if ($missingRequirements = TestUtil::getMissingRequirements($this->name, $beforeClassMethod)) { + $this->markTestSuiteSkipped(\implode(\PHP_EOL, $missingRequirements)); + } + + \call_user_func([$this->name, $beforeClassMethod]); + } + } + } catch (SkippedTestSuiteError $error) { + foreach ($this->tests() as $test) { + $result->startTest($test); + $result->addFailure($test, $error, 0); + $result->endTest($test, 0); + } + + $result->endTestSuite($this); + + return $result; + } catch (\Throwable $t) { + $errorAdded = false; + + foreach ($this->tests() as $test) { + if ($result->shouldStop()) { + break; + } + + $result->startTest($test); + + if (!$errorAdded) { + $result->addError($test, $t, 0); + + $errorAdded = true; + } else { + $result->addFailure( + $test, + new SkippedTestError('Test skipped because of an error in hook method'), + 0 + ); + } + + $result->endTest($test, 0); + } + + $result->endTestSuite($this); + + return $result; + } + + foreach ($this as $test) { + if ($result->shouldStop()) { + break; + } + + if ($test instanceof TestCase || $test instanceof self) { + $test->setBeStrictAboutChangesToGlobalState($this->beStrictAboutChangesToGlobalState); + $test->setBackupGlobals($this->backupGlobals); + $test->setBackupStaticAttributes($this->backupStaticAttributes); + $test->setRunTestInSeparateProcess($this->runTestInSeparateProcess); + } + + $test->run($result); + } + + try { + foreach ($hookMethods['afterClass'] as $afterClassMethod) { + if ($this->testCase && + \class_exists($this->name, false) && + \method_exists($this->name, $afterClassMethod)) { + \call_user_func([$this->name, $afterClassMethod]); + } + } + } catch (\Throwable $t) { + $message = "Exception in {$this->name}::$afterClassMethod" . \PHP_EOL . $t->getMessage(); + $error = new SyntheticError($message, 0, $t->getFile(), $t->getLine(), $t->getTrace()); + + $placeholderTest = clone $test; + $placeholderTest->setName($afterClassMethod); + + $result->startTest($placeholderTest); + $result->addFailure($placeholderTest, $error, 0); + $result->endTest($placeholderTest, 0); + } + + $result->endTestSuite($this); + + return $result; + } + + public function setRunTestInSeparateProcess(bool $runTestInSeparateProcess): void + { + $this->runTestInSeparateProcess = $runTestInSeparateProcess; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * Returns the test at the given index. + * + * @return false|Test + */ + public function testAt(int $index) + { + return $this->tests[$index] ?? false; + } + + /** + * Returns the tests as an enumeration. + * + * @return Test[] + */ + public function tests(): array + { + return $this->tests; + } + + /** + * Set tests of the test suite + * + * @param Test[] $tests + */ + public function setTests(array $tests): void + { + $this->tests = $tests; + } + + /** + * Mark the test suite as skipped. + * + * @param string $message + * + * @throws SkippedTestSuiteError + * + * @psalm-return never-return + */ + public function markTestSuiteSkipped($message = ''): void + { + throw new SkippedTestSuiteError($message); + } + + /** + * @param bool $beStrictAboutChangesToGlobalState + */ + public function setBeStrictAboutChangesToGlobalState($beStrictAboutChangesToGlobalState): void + { + if (null === $this->beStrictAboutChangesToGlobalState && \is_bool($beStrictAboutChangesToGlobalState)) { + $this->beStrictAboutChangesToGlobalState = $beStrictAboutChangesToGlobalState; + } + } + + /** + * @param bool $backupGlobals + */ + public function setBackupGlobals($backupGlobals): void + { + if (null === $this->backupGlobals && \is_bool($backupGlobals)) { + $this->backupGlobals = $backupGlobals; + } + } + + /** + * @param bool $backupStaticAttributes + */ + public function setBackupStaticAttributes($backupStaticAttributes): void + { + if (null === $this->backupStaticAttributes && \is_bool($backupStaticAttributes)) { + $this->backupStaticAttributes = $backupStaticAttributes; + } + } + + /** + * Returns an iterator for this test suite. + */ + public function getIterator(): \Iterator + { + $iterator = new TestSuiteIterator($this); + + if ($this->iteratorFilter !== null) { + $iterator = $this->iteratorFilter->factory($iterator, $this); + } + + return $iterator; + } + + public function injectFilter(Factory $filter): void + { + $this->iteratorFilter = $filter; + + foreach ($this as $test) { + if ($test instanceof self) { + $test->injectFilter($filter); + } + } + } + + /** + * Creates a default TestResult object. + */ + protected function createResult(): TestResult + { + return new TestResult; + } + + /** + * @throws Exception + */ + protected function addTestMethod(\ReflectionClass $class, \ReflectionMethod $method): void + { + if (!TestUtil::isTestMethod($method)) { + return; + } + + $methodName = $method->getName(); + + if (!$method->isPublic()) { + $this->addTest( + new WarningTestCase( + \sprintf( + 'Test method "%s" in test class "%s" is not public.', + $methodName, + $class->getName() + ) + ) + ); + + return; + } + + $test = (new TestBuilder)->build($class, $methodName); + + if ($test instanceof TestCase || $test instanceof DataProviderTestSuite) { + $test->setDependencies( + TestUtil::getDependencies($class->getName(), $methodName) + ); + } + + $this->addTest( + $test, + TestUtil::getGroups($class->getName(), $methodName) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php new file mode 100644 index 0000000..804048a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/TestSuiteIterator.php @@ -0,0 +1,79 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestSuiteIterator implements \RecursiveIterator +{ + /** + * @var int + */ + private $position = 0; + + /** + * @var Test[] + */ + private $tests; + + public function __construct(TestSuite $testSuite) + { + $this->tests = $testSuite->tests(); + } + + public function rewind(): void + { + $this->position = 0; + } + + public function valid(): bool + { + return $this->position < \count($this->tests); + } + + public function key(): int + { + return $this->position; + } + + public function current(): Test + { + return $this->tests[$this->position]; + } + + public function next(): void + { + $this->position++; + } + + /** + * @throws NoChildTestSuiteException + */ + public function getChildren(): self + { + if (!$this->hasChildren()) { + throw new NoChildTestSuiteException( + 'The current item is not a TestSuite instance and therefore does not have any children.' + ); + } + + $current = $this->current(); + + \assert($current instanceof TestSuite); + + return new self($current); + } + + public function hasChildren(): bool + { + return $this->valid() && $this->current() instanceof TestSuite; + } +} diff --git a/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php new file mode 100644 index 0000000..8070c01 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Framework/WarningTestCase.php @@ -0,0 +1,73 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Framework; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class WarningTestCase extends TestCase +{ + /** + * @var bool + */ + protected $backupGlobals = false; + + /** + * @var bool + */ + protected $backupStaticAttributes = false; + + /** + * @var bool + */ + protected $runTestInSeparateProcess = false; + + /** + * @var bool + */ + protected $useErrorHandler = false; + + /** + * @var string + */ + private $message; + + /** + * @param string $message + */ + public function __construct($message = '') + { + $this->message = $message; + parent::__construct('Warning'); + } + + public function getMessage(): string + { + return $this->message; + } + + /** + * Returns a string representation of the test case. + */ + public function toString(): string + { + return 'Warning'; + } + + /** + * @throws Exception + * + * @psalm-return never-return + */ + protected function runTest(): void + { + throw new Warning($this->message); + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php b/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php new file mode 100644 index 0000000..c302dad --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/BaseTestRunner.php @@ -0,0 +1,156 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestSuite; +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +abstract class BaseTestRunner +{ + /** + * @var int + */ + public const STATUS_UNKNOWN = -1; + + /** + * @var int + */ + public const STATUS_PASSED = 0; + + /** + * @var int + */ + public const STATUS_SKIPPED = 1; + + /** + * @var int + */ + public const STATUS_INCOMPLETE = 2; + + /** + * @var int + */ + public const STATUS_FAILURE = 3; + + /** + * @var int + */ + public const STATUS_ERROR = 4; + + /** + * @var int + */ + public const STATUS_RISKY = 5; + + /** + * @var int + */ + public const STATUS_WARNING = 6; + + /** + * @var string + */ + public const SUITE_METHODNAME = 'suite'; + + /** + * Returns the loader to be used. + */ + public function getLoader(): TestSuiteLoader + { + return new StandardTestSuiteLoader; + } + + /** + * Returns the Test corresponding to the given suite. + * This is a template method, subclasses override + * the runFailed() and clearStatus() methods. + * + * @param string|string[] $suffixes + * + * @throws Exception + */ + public function getTest(string $suiteClassName, string $suiteClassFile = '', $suffixes = ''): ?Test + { + if (empty($suiteClassFile) && \is_dir($suiteClassName) && !\is_file($suiteClassName . '.php')) { + /** @var string[] $files */ + $files = (new FileIteratorFacade)->getFilesAsArray( + $suiteClassName, + $suffixes + ); + + $suite = new TestSuite($suiteClassName); + $suite->addTestFiles($files); + + return $suite; + } + + try { + $testClass = $this->loadSuiteClass( + $suiteClassName, + $suiteClassFile + ); + } catch (Exception $e) { + $this->runFailed($e->getMessage()); + + return null; + } + + try { + $suiteMethod = $testClass->getMethod(self::SUITE_METHODNAME); + + if (!$suiteMethod->isStatic()) { + $this->runFailed( + 'suite() method must be static.' + ); + + return null; + } + + $test = $suiteMethod->invoke(null, $testClass->getName()); + } catch (\ReflectionException $e) { + try { + $test = new TestSuite($testClass); + } catch (Exception $e) { + $test = new TestSuite; + $test->setName($suiteClassName); + } + } + + $this->clearStatus(); + + return $test; + } + + /** + * Returns the loaded ReflectionClass for a suite name. + */ + protected function loadSuiteClass(string $suiteClassName, string $suiteClassFile = ''): \ReflectionClass + { + return $this->getLoader()->load($suiteClassName, $suiteClassFile); + } + + /** + * Clears the status message. + */ + protected function clearStatus(): void + { + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + */ + abstract protected function runFailed(string $message): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/DefaultTestResultCache.php b/vendor/phpunit/phpunit/src/Runner/DefaultTestResultCache.php new file mode 100644 index 0000000..a56ceab --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/DefaultTestResultCache.php @@ -0,0 +1,217 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Util\ErrorHandler; +use PHPUnit\Util\Filesystem; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class DefaultTestResultCache implements \Serializable, TestResultCache +{ + /** + * @var string + */ + public const DEFAULT_RESULT_CACHE_FILENAME = '.phpunit.result.cache'; + + /** + * Provide extra protection against incomplete or corrupt caches + * + * @var int[] + */ + private const ALLOWED_CACHE_TEST_STATUSES = [ + BaseTestRunner::STATUS_SKIPPED, + BaseTestRunner::STATUS_INCOMPLETE, + BaseTestRunner::STATUS_FAILURE, + BaseTestRunner::STATUS_ERROR, + BaseTestRunner::STATUS_RISKY, + BaseTestRunner::STATUS_WARNING, + ]; + + /** + * Path and filename for result cache file + * + * @var string + */ + private $cacheFilename; + + /** + * The list of defective tests + * + * + * // Mark a test skipped + * $this->defects[$testName] = BaseTestRunner::TEST_SKIPPED; + * + * + * @var array + */ + private $defects = []; + + /** + * The list of execution duration of suites and tests (in seconds) + * + * + * // Record running time for test + * $this->times[$testName] = 1.234; + * + * + * @var array + */ + private $times = []; + + public function __construct(?string $filepath = null) + { + if ($filepath !== null && \is_dir($filepath)) { + // cache path provided, use default cache filename in that location + $filepath .= \DIRECTORY_SEPARATOR . self::DEFAULT_RESULT_CACHE_FILENAME; + } + + $this->cacheFilename = $filepath ?? $_ENV['PHPUNIT_RESULT_CACHE'] ?? self::DEFAULT_RESULT_CACHE_FILENAME; + } + + /** + * @throws Exception + */ + public function persist(): void + { + $this->saveToFile(); + } + + /** + * @throws Exception + */ + public function saveToFile(): void + { + if (\defined('PHPUNIT_TESTSUITE_RESULTCACHE')) { + return; + } + + if (!Filesystem::createDirectory(\dirname($this->cacheFilename))) { + throw new Exception( + \sprintf( + 'Cannot create directory "%s" for result cache file', + $this->cacheFilename + ) + ); + } + + \file_put_contents( + $this->cacheFilename, + \serialize($this) + ); + } + + public function setState(string $testName, int $state): void + { + if ($state !== BaseTestRunner::STATUS_PASSED) { + $this->defects[$testName] = $state; + } + } + + public function getState(string $testName): int + { + return $this->defects[$testName] ?? BaseTestRunner::STATUS_UNKNOWN; + } + + public function setTime(string $testName, float $time): void + { + $this->times[$testName] = $time; + } + + public function getTime(string $testName): float + { + return $this->times[$testName] ?? 0.0; + } + + public function load(): void + { + $this->clear(); + + if (!\is_file($this->cacheFilename)) { + return; + } + + $cacheData = @\file_get_contents($this->cacheFilename); + + // @codeCoverageIgnoreStart + if ($cacheData === false) { + return; + } + // @codeCoverageIgnoreEnd + + $cache = ErrorHandler::invokeIgnoringWarnings( + static function () use ($cacheData) { + return @\unserialize($cacheData, ['allowed_classes' => [self::class]]); + } + ); + + if ($cache === false) { + return; + } + + if ($cache instanceof self) { + /* @var DefaultTestResultCache $cache */ + $cache->copyStateToCache($this); + } + } + + public function copyStateToCache(self $targetCache): void + { + foreach ($this->defects as $name => $state) { + $targetCache->setState($name, $state); + } + + foreach ($this->times as $name => $time) { + $targetCache->setTime($name, $time); + } + } + + public function clear(): void + { + $this->defects = []; + $this->times = []; + } + + public function serialize(): string + { + return \serialize([ + 'defects' => $this->defects, + 'times' => $this->times, + ]); + } + + /** + * @param string $serialized + */ + public function unserialize($serialized): void + { + $data = \unserialize($serialized); + + if (isset($data['times'])) { + foreach ($data['times'] as $testName => $testTime) { + \assert(\is_string($testName)); + \assert(\is_float($testTime)); + $this->times[$testName] = $testTime; + } + } + + if (isset($data['defects'])) { + foreach ($data['defects'] as $testName => $testResult) { + \assert(\is_string($testName)); + \assert(\is_int($testResult)); + + if (\in_array($testResult, self::ALLOWED_CACHE_TEST_STATUSES, true)) { + $this->defects[$testName] = $testResult; + } + } + } + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Exception.php b/vendor/phpunit/phpunit/src/Runner/Exception.php new file mode 100644 index 0000000..44705f5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Exception extends \RuntimeException implements \PHPUnit\Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php b/vendor/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php new file mode 100644 index 0000000..d8a8643 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Filter/ExcludeGroupFilterIterator.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Filter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ExcludeGroupFilterIterator extends GroupFilterIterator +{ + protected function doAccept(string $hash): bool + { + return !\in_array($hash, $this->groupTests, true); + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php b/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php new file mode 100644 index 0000000..4072ad2 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Filter/Factory.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Filter; + +use FilterIterator; +use InvalidArgumentException; +use Iterator; +use PHPUnit\Framework\TestSuite; +use ReflectionClass; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Factory +{ + /** + * @var array + */ + private $filters = []; + + /** + * @throws InvalidArgumentException + */ + public function addFilter(ReflectionClass $filter, $args): void + { + if (!$filter->isSubclassOf(\RecursiveFilterIterator::class)) { + throw new InvalidArgumentException( + \sprintf( + 'Class "%s" does not extend RecursiveFilterIterator', + $filter->name + ) + ); + } + + $this->filters[] = [$filter, $args]; + } + + public function factory(Iterator $iterator, TestSuite $suite): FilterIterator + { + foreach ($this->filters as $filter) { + [$class, $args] = $filter; + $iterator = $class->newInstance($iterator, $args, $suite); + } + + return $iterator; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php b/vendor/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php new file mode 100644 index 0000000..1d778a6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Filter/GroupFilterIterator.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Filter; + +use PHPUnit\Framework\TestSuite; +use RecursiveFilterIterator; +use RecursiveIterator; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +abstract class GroupFilterIterator extends RecursiveFilterIterator +{ + /** + * @var string[] + */ + protected $groupTests = []; + + public function __construct(RecursiveIterator $iterator, array $groups, TestSuite $suite) + { + parent::__construct($iterator); + + foreach ($suite->getGroupDetails() as $group => $tests) { + if (\in_array((string) $group, $groups, true)) { + $testHashes = \array_map( + 'spl_object_hash', + $tests + ); + + $this->groupTests = \array_merge($this->groupTests, $testHashes); + } + } + } + + public function accept(): bool + { + $test = $this->getInnerIterator()->current(); + + if ($test instanceof TestSuite) { + return true; + } + + return $this->doAccept(\spl_object_hash($test)); + } + + abstract protected function doAccept(string $hash); +} diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php b/vendor/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php new file mode 100644 index 0000000..5f004f9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Filter/IncludeGroupFilterIterator.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Filter; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class IncludeGroupFilterIterator extends GroupFilterIterator +{ + protected function doAccept(string $hash): bool + { + return \in_array($hash, $this->groupTests, true); + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php b/vendor/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php new file mode 100644 index 0000000..a26665d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Filter/NameFilterIterator.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner\Filter; + +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\WarningTestCase; +use PHPUnit\Util\RegularExpression; +use RecursiveFilterIterator; +use RecursiveIterator; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class NameFilterIterator extends RecursiveFilterIterator +{ + /** + * @var string + */ + private $filter; + + /** + * @var int + */ + private $filterMin; + + /** + * @var int + */ + private $filterMax; + + /** + * @throws \Exception + */ + public function __construct(RecursiveIterator $iterator, string $filter) + { + parent::__construct($iterator); + + $this->setFilter($filter); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function accept(): bool + { + $test = $this->getInnerIterator()->current(); + + if ($test instanceof TestSuite) { + return true; + } + + $tmp = \PHPUnit\Util\Test::describe($test); + + if ($test instanceof WarningTestCase) { + $name = $test->getMessage(); + } elseif ($tmp[0] !== '') { + $name = \implode('::', $tmp); + } else { + $name = $tmp[1]; + } + + $accepted = @\preg_match($this->filter, $name, $matches); + + if ($accepted && isset($this->filterMax)) { + $set = \end($matches); + $accepted = $set >= $this->filterMin && $set <= $this->filterMax; + } + + return (bool) $accepted; + } + + /** + * @throws \Exception + */ + private function setFilter(string $filter): void + { + if (RegularExpression::safeMatch($filter, '') === false) { + // Handles: + // * testAssertEqualsSucceeds#4 + // * testAssertEqualsSucceeds#4-8 + if (\preg_match('/^(.*?)#(\d+)(?:-(\d+))?$/', $filter, $matches)) { + if (isset($matches[3]) && $matches[2] < $matches[3]) { + $filter = \sprintf( + '%s.*with data set #(\d+)$', + $matches[1] + ); + + $this->filterMin = (int) $matches[2]; + $this->filterMax = (int) $matches[3]; + } else { + $filter = \sprintf( + '%s.*with data set #%s$', + $matches[1], + $matches[2] + ); + } + } // Handles: + // * testDetermineJsonError@JSON_ERROR_NONE + // * testDetermineJsonError@JSON.* + elseif (\preg_match('/^(.*?)@(.+)$/', $filter, $matches)) { + $filter = \sprintf( + '%s.*with data set "%s"$', + $matches[1], + $matches[2] + ); + } + + // Escape delimiters in regular expression. Do NOT use preg_quote, + // to keep magic characters. + $filter = \sprintf('/%s/i', \str_replace( + '/', + '\\/', + $filter + )); + } + + $this->filter = $filter; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php new file mode 100644 index 0000000..35ded5d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterIncompleteTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterIncompleteTestHook extends TestHook +{ + public function executeAfterIncompleteTest(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php new file mode 100644 index 0000000..7dee9f9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterLastTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterLastTestHook extends Hook +{ + public function executeAfterLastTest(): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php new file mode 100644 index 0000000..7fe9ee7 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterRiskyTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterRiskyTestHook extends TestHook +{ + public function executeAfterRiskyTest(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php new file mode 100644 index 0000000..f9253b5 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterSkippedTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterSkippedTestHook extends TestHook +{ + public function executeAfterSkippedTest(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php new file mode 100644 index 0000000..6b55cc8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterSuccessfulTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterSuccessfulTestHook extends TestHook +{ + public function executeAfterSuccessfulTest(string $test, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php new file mode 100644 index 0000000..f5c23fb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestErrorHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterTestErrorHook extends TestHook +{ + public function executeAfterTestError(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php new file mode 100644 index 0000000..9ed2939 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestFailureHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterTestFailureHook extends TestHook +{ + public function executeAfterTestFailure(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php new file mode 100644 index 0000000..7e0af80 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestHook.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterTestHook extends TestHook +{ + /** + * This hook will fire after any test, regardless of the result. + * + * For more fine grained control, have a look at the other hooks + * that extend PHPUnit\Runner\Hook. + */ + public function executeAfterTest(string $test, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php new file mode 100644 index 0000000..12de80f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/AfterTestWarningHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface AfterTestWarningHook extends TestHook +{ + public function executeAfterTestWarning(string $test, string $message, float $time): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php new file mode 100644 index 0000000..59b6666 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/BeforeFirstTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface BeforeFirstTestHook extends Hook +{ + public function executeBeforeFirstTest(): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php new file mode 100644 index 0000000..8bbf8a9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/BeforeTestHook.php @@ -0,0 +1,15 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface BeforeTestHook extends TestHook +{ + public function executeBeforeTest(string $test): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/Hook.php b/vendor/phpunit/phpunit/src/Runner/Hook/Hook.php new file mode 100644 index 0000000..546f1a3 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/Hook.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface Hook +{ +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/TestHook.php b/vendor/phpunit/phpunit/src/Runner/Hook/TestHook.php new file mode 100644 index 0000000..47c41f9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/TestHook.php @@ -0,0 +1,14 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +interface TestHook extends Hook +{ +} diff --git a/vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php b/vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php new file mode 100644 index 0000000..a4dfa4b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Hook/TestListenerAdapter.php @@ -0,0 +1,140 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; +use PHPUnit\Util\Test as TestUtil; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestListenerAdapter implements TestListener +{ + /** + * @var TestHook[] + */ + private $hooks = []; + + /** + * @var bool + */ + private $lastTestWasNotSuccessful; + + public function add(TestHook $hook): void + { + $this->hooks[] = $hook; + } + + public function startTest(Test $test): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof BeforeTestHook) { + $hook->executeBeforeTest(TestUtil::describeAsString($test)); + } + } + + $this->lastTestWasNotSuccessful = false; + } + + public function addError(Test $test, \Throwable $t, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterTestErrorHook) { + $hook->executeAfterTestError(TestUtil::describeAsString($test), $t->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function addWarning(Test $test, Warning $e, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterTestWarningHook) { + $hook->executeAfterTestWarning(TestUtil::describeAsString($test), $e->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterTestFailureHook) { + $hook->executeAfterTestFailure(TestUtil::describeAsString($test), $e->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterIncompleteTestHook) { + $hook->executeAfterIncompleteTest(TestUtil::describeAsString($test), $t->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function addRiskyTest(Test $test, \Throwable $t, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterRiskyTestHook) { + $hook->executeAfterRiskyTest(TestUtil::describeAsString($test), $t->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterSkippedTestHook) { + $hook->executeAfterSkippedTest(TestUtil::describeAsString($test), $t->getMessage(), $time); + } + } + + $this->lastTestWasNotSuccessful = true; + } + + public function endTest(Test $test, float $time): void + { + if (!$this->lastTestWasNotSuccessful) { + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterSuccessfulTestHook) { + $hook->executeAfterSuccessfulTest(TestUtil::describeAsString($test), $time); + } + } + } + + foreach ($this->hooks as $hook) { + if ($hook instanceof AfterTestHook) { + $hook->executeAfterTest(TestUtil::describeAsString($test), $time); + } + } + } + + public function startTestSuite(TestSuite $suite): void + { + } + + public function endTestSuite(TestSuite $suite): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/NullTestResultCache.php b/vendor/phpunit/phpunit/src/Runner/NullTestResultCache.php new file mode 100644 index 0000000..2aa8653 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/NullTestResultCache.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class NullTestResultCache implements TestResultCache +{ + public function setState(string $testName, int $state): void + { + } + + public function getState(string $testName): int + { + return BaseTestRunner::STATUS_UNKNOWN; + } + + public function setTime(string $testName, float $time): void + { + } + + public function getTime(string $testName): float + { + return 0; + } + + public function load(): void + { + } + + public function persist(): void + { + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/PhptTestCase.php b/vendor/phpunit/phpunit/src/Runner/PhptTestCase.php new file mode 100644 index 0000000..b94e17a --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/PhptTestCase.php @@ -0,0 +1,751 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\IncompleteTestError; +use PHPUnit\Framework\PHPTAssertionFailedError; +use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Framework\SkippedTestError; +use PHPUnit\Framework\SyntheticSkippedError; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestResult; +use PHPUnit\Util\PHP\AbstractPhpProcess; +use SebastianBergmann\Timer\Timer; +use Text_Template; +use Throwable; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class PhptTestCase implements SelfDescribing, Test +{ + /** + * @var string[] + */ + private const SETTINGS = [ + 'allow_url_fopen=1', + 'auto_append_file=', + 'auto_prepend_file=', + 'disable_functions=', + 'display_errors=1', + 'docref_ext=.html', + 'docref_root=', + 'error_append_string=', + 'error_prepend_string=', + 'error_reporting=-1', + 'html_errors=0', + 'log_errors=0', + 'magic_quotes_runtime=0', + 'open_basedir=', + 'output_buffering=Off', + 'output_handler=', + 'report_memleaks=0', + 'report_zend_debug=0', + 'safe_mode=0', + 'xdebug.default_enable=0', + ]; + + /** + * @var string + */ + private $filename; + + /** + * @var AbstractPhpProcess + */ + private $phpUtil; + + /** + * @var string + */ + private $output = ''; + + /** + * Constructs a test case with the given filename. + * + * @throws Exception + */ + public function __construct(string $filename, AbstractPhpProcess $phpUtil = null) + { + if (!\is_file($filename)) { + throw new Exception( + \sprintf( + 'File "%s" does not exist.', + $filename + ) + ); + } + + $this->filename = $filename; + $this->phpUtil = $phpUtil ?: AbstractPhpProcess::factory(); + } + + /** + * Counts the number of test cases executed by run(TestResult result). + */ + public function count(): int + { + return 1; + } + + /** + * Runs a test and collects its result in a TestResult instance. + * + * @throws Exception + * @throws \SebastianBergmann\CodeCoverage\CoveredCodeNotExecutedException + * @throws \SebastianBergmann\CodeCoverage\InvalidArgumentException + * @throws \SebastianBergmann\CodeCoverage\MissingCoversAnnotationException + * @throws \SebastianBergmann\CodeCoverage\RuntimeException + * @throws \SebastianBergmann\CodeCoverage\UnintentionallyCoveredCodeException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function run(TestResult $result = null): TestResult + { + if ($result === null) { + $result = new TestResult; + } + + try { + $sections = $this->parse(); + } catch (Exception $e) { + $result->startTest($this); + $result->addFailure($this, new SkippedTestError($e->getMessage()), 0); + $result->endTest($this, 0); + + return $result; + } + + $code = $this->render($sections['FILE']); + $xfail = false; + $settings = $this->parseIniSection(self::SETTINGS); + + $result->startTest($this); + + if (isset($sections['INI'])) { + $settings = $this->parseIniSection($sections['INI'], $settings); + } + + if (isset($sections['ENV'])) { + $env = $this->parseEnvSection($sections['ENV']); + $this->phpUtil->setEnv($env); + } + + $this->phpUtil->setUseStderrRedirection(true); + + if ($result->enforcesTimeLimit()) { + $this->phpUtil->setTimeout($result->getTimeoutForLargeTests()); + } + + $skip = $this->runSkip($sections, $result, $settings); + + if ($skip) { + return $result; + } + + if (isset($sections['XFAIL'])) { + $xfail = \trim($sections['XFAIL']); + } + + if (isset($sections['STDIN'])) { + $this->phpUtil->setStdin($sections['STDIN']); + } + + if (isset($sections['ARGS'])) { + $this->phpUtil->setArgs($sections['ARGS']); + } + + if ($result->getCollectCodeCoverageInformation()) { + $this->renderForCoverage($code); + } + + Timer::start(); + + $jobResult = $this->phpUtil->runJob($code, $this->stringifyIni($settings)); + $time = Timer::stop(); + $this->output = $jobResult['stdout'] ?? ''; + + if ($result->getCollectCodeCoverageInformation() && ($coverage = $this->cleanupForCoverage())) { + $result->getCodeCoverage()->append($coverage, $this, true, [], [], true); + } + + try { + $this->assertPhptExpectation($sections, $this->output); + } catch (AssertionFailedError $e) { + $failure = $e; + + if ($xfail !== false) { + $failure = new IncompleteTestError($xfail, 0, $e); + } elseif ($e instanceof ExpectationFailedException) { + $comparisonFailure = $e->getComparisonFailure(); + + if ($comparisonFailure) { + $diff = $comparisonFailure->getDiff(); + } else { + $diff = $e->getMessage(); + } + + $hint = $this->getLocationHintFromDiff($diff, $sections); + $trace = \array_merge($hint, \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); + $failure = new PHPTAssertionFailedError( + $e->getMessage(), + 0, + $trace[0]['file'], + $trace[0]['line'], + $trace, + $comparisonFailure ? $diff : '' + ); + } + + $result->addFailure($this, $failure, $time); + } catch (Throwable $t) { + $result->addError($this, $t, $time); + } + + if ($xfail !== false && $result->allCompletelyImplemented()) { + $result->addFailure($this, new IncompleteTestError('XFAIL section but test passes'), $time); + } + + $this->runClean($sections); + + $result->endTest($this, $time); + + return $result; + } + + /** + * Returns the name of the test case. + */ + public function getName(): string + { + return $this->toString(); + } + + /** + * Returns a string representation of the test case. + */ + public function toString(): string + { + return $this->filename; + } + + public function usesDataProvider(): bool + { + return false; + } + + public function getNumAssertions(): int + { + return 1; + } + + public function getActualOutput(): string + { + return $this->output; + } + + public function hasOutput(): bool + { + return !empty($this->output); + } + + /** + * Parse --INI-- section key value pairs and return as array. + * + * @param array|string + */ + private function parseIniSection($content, $ini = []): array + { + if (\is_string($content)) { + $content = \explode("\n", \trim($content)); + } + + foreach ($content as $setting) { + if (\strpos($setting, '=') === false) { + continue; + } + + $setting = \explode('=', $setting, 2); + $name = \trim($setting[0]); + $value = \trim($setting[1]); + + if ($name === 'extension' || $name === 'zend_extension') { + if (!isset($ini[$name])) { + $ini[$name] = []; + } + + $ini[$name][] = $value; + + continue; + } + + $ini[$name] = $value; + } + + return $ini; + } + + private function parseEnvSection(string $content): array + { + $env = []; + + foreach (\explode("\n", \trim($content)) as $e) { + $e = \explode('=', \trim($e), 2); + + if (!empty($e[0]) && isset($e[1])) { + $env[$e[0]] = $e[1]; + } + } + + return $env; + } + + /** + * @throws ExpectationFailedException + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + * @throws Exception + */ + private function assertPhptExpectation(array $sections, string $output): void + { + $assertions = [ + 'EXPECT' => 'assertEquals', + 'EXPECTF' => 'assertStringMatchesFormat', + 'EXPECTREGEX' => 'assertRegExp', + ]; + + $actual = \preg_replace('/\r\n/', "\n", \trim($output)); + + foreach ($assertions as $sectionName => $sectionAssertion) { + if (isset($sections[$sectionName])) { + $sectionContent = \preg_replace('/\r\n/', "\n", \trim($sections[$sectionName])); + $expected = $sectionName === 'EXPECTREGEX' ? "/{$sectionContent}/" : $sectionContent; + + if ($expected === null) { + throw new Exception('No PHPT expectation found'); + } + + Assert::$sectionAssertion($expected, $actual); + + return; + } + } + + throw new Exception('No PHPT assertion found'); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function runSkip(array &$sections, TestResult $result, array $settings): bool + { + if (!isset($sections['SKIPIF'])) { + return false; + } + + $skipif = $this->render($sections['SKIPIF']); + $jobResult = $this->phpUtil->runJob($skipif, $this->stringifyIni($settings)); + + if (!\strncasecmp('skip', \ltrim($jobResult['stdout']), 4)) { + $message = ''; + + if (\preg_match('/^\s*skip\s*(.+)\s*/i', $jobResult['stdout'], $skipMatch)) { + $message = \substr($skipMatch[1], 2); + } + + $hint = $this->getLocationHint($message, $sections, 'SKIPIF'); + $trace = \array_merge($hint, \debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS)); + $result->addFailure( + $this, + new SyntheticSkippedError($message, 0, $trace[0]['file'], $trace[0]['line'], $trace), + 0 + ); + $result->endTest($this, 0); + + return true; + } + + return false; + } + + private function runClean(array &$sections): void + { + $this->phpUtil->setStdin(''); + $this->phpUtil->setArgs(''); + + if (isset($sections['CLEAN'])) { + $cleanCode = $this->render($sections['CLEAN']); + + $this->phpUtil->runJob($cleanCode, self::SETTINGS); + } + } + + /** + * @throws Exception + */ + private function parse(): array + { + $sections = []; + $section = ''; + + $unsupportedSections = [ + 'CGI', + 'COOKIE', + 'DEFLATE_POST', + 'EXPECTHEADERS', + 'EXTENSIONS', + 'GET', + 'GZIP_POST', + 'HEADERS', + 'PHPDBG', + 'POST', + 'POST_RAW', + 'PUT', + 'REDIRECTTEST', + 'REQUEST', + ]; + + $lineNr = 0; + + foreach (\file($this->filename) as $line) { + $lineNr++; + + if (\preg_match('/^--([_A-Z]+)--/', $line, $result)) { + $section = $result[1]; + $sections[$section] = ''; + $sections[$section . '_offset'] = $lineNr; + + continue; + } + + if (empty($section)) { + throw new Exception('Invalid PHPT file: empty section header'); + } + + $sections[$section] .= $line; + } + + if (isset($sections['FILEEOF'])) { + $sections['FILE'] = \rtrim($sections['FILEEOF'], "\r\n"); + unset($sections['FILEEOF']); + } + + $this->parseExternal($sections); + + if (!$this->validate($sections)) { + throw new Exception('Invalid PHPT file'); + } + + foreach ($unsupportedSections as $section) { + if (isset($sections[$section])) { + throw new Exception( + "PHPUnit does not support PHPT $section sections" + ); + } + } + + return $sections; + } + + /** + * @throws Exception + */ + private function parseExternal(array &$sections): void + { + $allowSections = [ + 'FILE', + 'EXPECT', + 'EXPECTF', + 'EXPECTREGEX', + ]; + $testDirectory = \dirname($this->filename) . \DIRECTORY_SEPARATOR; + + foreach ($allowSections as $section) { + if (isset($sections[$section . '_EXTERNAL'])) { + $externalFilename = \trim($sections[$section . '_EXTERNAL']); + + if (!\is_file($testDirectory . $externalFilename) || + !\is_readable($testDirectory . $externalFilename)) { + throw new Exception( + \sprintf( + 'Could not load --%s-- %s for PHPT file', + $section . '_EXTERNAL', + $testDirectory . $externalFilename + ) + ); + } + + $sections[$section] = \file_get_contents($testDirectory . $externalFilename); + } + } + } + + private function validate(array &$sections): bool + { + $requiredSections = [ + 'FILE', + [ + 'EXPECT', + 'EXPECTF', + 'EXPECTREGEX', + ], + ]; + + foreach ($requiredSections as $section) { + if (\is_array($section)) { + $foundSection = false; + + foreach ($section as $anySection) { + if (isset($sections[$anySection])) { + $foundSection = true; + + break; + } + } + + if (!$foundSection) { + return false; + } + + continue; + } + + if (!isset($sections[$section])) { + return false; + } + } + + return true; + } + + private function render(string $code): string + { + return \str_replace( + [ + '__DIR__', + '__FILE__', + ], + [ + "'" . \dirname($this->filename) . "'", + "'" . $this->filename . "'", + ], + $code + ); + } + + private function getCoverageFiles(): array + { + $baseDir = \dirname(\realpath($this->filename)) . \DIRECTORY_SEPARATOR; + $basename = \basename($this->filename, 'phpt'); + + return [ + 'coverage' => $baseDir . $basename . 'coverage', + 'job' => $baseDir . $basename . 'php', + ]; + } + + private function renderForCoverage(string &$job): void + { + $files = $this->getCoverageFiles(); + + $template = new Text_Template( + __DIR__ . '/../Util/PHP/Template/PhptTestCase.tpl' + ); + + $composerAutoload = '\'\''; + + if (\defined('PHPUNIT_COMPOSER_INSTALL') && !\defined('PHPUNIT_TESTSUITE')) { + $composerAutoload = \var_export(PHPUNIT_COMPOSER_INSTALL, true); + } + + $phar = '\'\''; + + if (\defined('__PHPUNIT_PHAR__')) { + $phar = \var_export(__PHPUNIT_PHAR__, true); + } + + $globals = ''; + + if (!empty($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + $globals = '$GLOBALS[\'__PHPUNIT_BOOTSTRAP\'] = ' . \var_export( + $GLOBALS['__PHPUNIT_BOOTSTRAP'], + true + ) . ";\n"; + } + + $template->setVar( + [ + 'composerAutoload' => $composerAutoload, + 'phar' => $phar, + 'globals' => $globals, + 'job' => $files['job'], + 'coverageFile' => $files['coverage'], + ] + ); + + \file_put_contents($files['job'], $job); + $job = $template->render(); + } + + private function cleanupForCoverage(): array + { + $files = $this->getCoverageFiles(); + $coverage = @\unserialize(\file_get_contents($files['coverage'])); + + if ($coverage === false) { + $coverage = []; + } + + foreach ($files as $file) { + @\unlink($file); + } + + return $coverage; + } + + private function stringifyIni(array $ini): array + { + $settings = []; + + foreach ($ini as $key => $value) { + if (\is_array($value)) { + foreach ($value as $val) { + $settings[] = $key . '=' . $val; + } + + continue; + } + + $settings[] = $key . '=' . $value; + } + + return $settings; + } + + private function getLocationHintFromDiff(string $message, array $sections): array + { + $needle = ''; + $previousLine = ''; + $block = 'message'; + + foreach (\preg_split('/\r\n|\r|\n/', $message) as $line) { + $line = \trim($line); + + if ($block === 'message' && $line === '--- Expected') { + $block = 'expected'; + } + + if ($block === 'expected' && $line === '@@ @@') { + $block = 'diff'; + } + + if ($block === 'diff') { + if (\strpos($line, '+') === 0) { + $needle = $this->getCleanDiffLine($previousLine); + + break; + } + + if (\strpos($line, '-') === 0) { + $needle = $this->getCleanDiffLine($line); + + break; + } + } + + if (!empty($line)) { + $previousLine = $line; + } + } + + return $this->getLocationHint($needle, $sections); + } + + private function getCleanDiffLine(string $line): string + { + if (\preg_match('/^[\-+]([\'\"]?)(.*)\1$/', $line, $matches)) { + $line = $matches[2]; + } + + return $line; + } + + private function getLocationHint(string $needle, array $sections, ?string $sectionName = null): array + { + $needle = \trim($needle); + + if (empty($needle)) { + return [[ + 'file' => \realpath($this->filename), + 'line' => 1, + ]]; + } + + if ($sectionName) { + $search = [$sectionName]; + } else { + $search = [ + // 'FILE', + 'EXPECT', + 'EXPECTF', + 'EXPECTREGEX', + ]; + } + + foreach ($search as $section) { + if (!isset($sections[$section])) { + continue; + } + + if (isset($sections[$section . '_EXTERNAL'])) { + $externalFile = \trim($sections[$section . '_EXTERNAL']); + + return [ + [ + 'file' => \realpath(\dirname($this->filename) . \DIRECTORY_SEPARATOR . $externalFile), + 'line' => 1, + ], + [ + 'file' => \realpath($this->filename), + 'line' => ($sections[$section . '_EXTERNAL_offset'] ?? 0) + 1, + ], + ]; + } + + $sectionOffset = $sections[$section . '_offset'] ?? 0; + $offset = $sectionOffset + 1; + + foreach (\preg_split('/\r\n|\r|\n/', $sections[$section]) as $line) { + if (\strpos($line, $needle) !== false) { + return [[ + 'file' => \realpath($this->filename), + 'line' => $offset, + ]]; + } + $offset++; + } + } + + if ($sectionName) { + // String not found in specified section, show user the start of the named section + return [[ + 'file' => \realpath($this->filename), + 'line' => $sectionOffset, + ]]; + } + + // No section specified, show user start of code + return [[ + 'file' => \realpath($this->filename), + 'line' => 1, + ]]; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/ResultCacheExtension.php b/vendor/phpunit/phpunit/src/Runner/ResultCacheExtension.php new file mode 100644 index 0000000..f9a9b13 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/ResultCacheExtension.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ResultCacheExtension implements AfterIncompleteTestHook, AfterLastTestHook, AfterRiskyTestHook, AfterSkippedTestHook, AfterSuccessfulTestHook, AfterTestErrorHook, AfterTestFailureHook, AfterTestWarningHook +{ + /** + * @var TestResultCache + */ + private $cache; + + public function __construct(TestResultCache $cache) + { + $this->cache = $cache; + } + + public function flush(): void + { + $this->cache->persist(); + } + + public function executeAfterSuccessfulTest(string $test, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + } + + public function executeAfterIncompleteTest(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_INCOMPLETE); + } + + public function executeAfterRiskyTest(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_RISKY); + } + + public function executeAfterSkippedTest(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_SKIPPED); + } + + public function executeAfterTestError(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_ERROR); + } + + public function executeAfterTestFailure(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_FAILURE); + } + + public function executeAfterTestWarning(string $test, string $message, float $time): void + { + $testName = $this->getTestName($test); + + $this->cache->setTime($testName, \round($time, 3)); + $this->cache->setState($testName, BaseTestRunner::STATUS_WARNING); + } + + public function executeAfterLastTest(): void + { + $this->flush(); + } + + /** + * @param string $test A long description format of the current test + * + * @return string The test name without TestSuiteClassName:: and @dataprovider details + */ + private function getTestName(string $test): string + { + $matches = []; + + if (\preg_match('/^(?\S+::\S+)(?:(? with data set (?:#\d+|"[^"]+"))\s\()?/', $test, $matches)) { + $test = $matches['name'] . ($matches['dataname'] ?? ''); + } + + return $test; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php new file mode 100644 index 0000000..e7651a4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/StandardTestSuiteLoader.php @@ -0,0 +1,153 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Framework\TestCase; +use PHPUnit\Util\FileLoader; +use PHPUnit\Util\Filesystem; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class StandardTestSuiteLoader implements TestSuiteLoader +{ + /** + * @throws Exception + * @throws \PHPUnit\Framework\Exception + */ + public function load(string $suiteClassName, string $suiteClassFile = ''): \ReflectionClass + { + $suiteClassName = \str_replace('.php', '', $suiteClassName); + $filename = null; + + if (empty($suiteClassFile)) { + $suiteClassFile = Filesystem::classNameToFilename( + $suiteClassName + ); + } + + if (!\class_exists($suiteClassName, false)) { + $loadedClasses = \get_declared_classes(); + + $filename = FileLoader::checkAndLoad($suiteClassFile); + + $loadedClasses = \array_values( + \array_diff(\get_declared_classes(), $loadedClasses) + ); + } + + if (!empty($loadedClasses) && !\class_exists($suiteClassName, false)) { + $offset = 0 - \strlen($suiteClassName); + + foreach ($loadedClasses as $loadedClass) { + try { + $class = new \ReflectionClass($loadedClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (\substr($loadedClass, $offset) === $suiteClassName && + $class->getFileName() == $filename) { + $suiteClassName = $loadedClass; + + break; + } + } + } + + if (!empty($loadedClasses) && !\class_exists($suiteClassName, false)) { + $testCaseClass = TestCase::class; + + foreach ($loadedClasses as $loadedClass) { + try { + $class = new \ReflectionClass($loadedClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $classFile = $class->getFileName(); + + if ($class->isSubclassOf($testCaseClass) && !$class->isAbstract()) { + $suiteClassName = $loadedClass; + $testCaseClass = $loadedClass; + + if ($classFile == \realpath($suiteClassFile)) { + break; + } + } + + if ($class->hasMethod('suite')) { + try { + $method = $class->getMethod('suite'); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$method->isAbstract() && $method->isPublic() && $method->isStatic()) { + $suiteClassName = $loadedClass; + + if ($classFile == \realpath($suiteClassFile)) { + break; + } + } + } + } + } + + if (\class_exists($suiteClassName, false)) { + try { + $class = new \ReflectionClass($suiteClassName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($class->getFileName() == \realpath($suiteClassFile)) { + return $class; + } + } + + throw new Exception( + \sprintf( + "Class '%s' could not be found in '%s'.", + $suiteClassName, + $suiteClassFile + ) + ); + } + + public function reload(\ReflectionClass $aClass): \ReflectionClass + { + return $aClass; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/TestResultCache.php b/vendor/phpunit/phpunit/src/Runner/TestResultCache.php new file mode 100644 index 0000000..69e6282 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/TestResultCache.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +interface TestResultCache +{ + public function setState(string $testName, int $state): void; + + public function getState(string $testName): int; + + public function setTime(string $testName, float $time): void; + + public function getTime(string $testName): float; + + public function load(): void; + + public function persist(): void; +} diff --git a/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php b/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php new file mode 100644 index 0000000..f059688 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/TestSuiteLoader.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use ReflectionClass; + +/** + * An interface to define how a test suite should be loaded. + */ +interface TestSuiteLoader +{ + public function load(string $suiteClassName, string $suiteClassFile = ''): ReflectionClass; + + public function reload(ReflectionClass $aClass): ReflectionClass; +} diff --git a/vendor/phpunit/phpunit/src/Runner/TestSuiteSorter.php b/vendor/phpunit/phpunit/src/Runner/TestSuiteSorter.php new file mode 100644 index 0000000..c75976d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/TestSuiteSorter.php @@ -0,0 +1,434 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use PHPUnit\Framework\DataProviderTestSuite; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Util\Test as TestUtil; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestSuiteSorter +{ + /** + * @var int + */ + public const ORDER_DEFAULT = 0; + + /** + * @var int + */ + public const ORDER_RANDOMIZED = 1; + + /** + * @var int + */ + public const ORDER_REVERSED = 2; + + /** + * @var int + */ + public const ORDER_DEFECTS_FIRST = 3; + + /** + * @var int + */ + public const ORDER_DURATION = 4; + + /** + * Order tests by @size annotation 'small', 'medium', 'large' + * + * @var int + */ + public const ORDER_SIZE = 5; + + /** + * List of sorting weights for all test result codes. A higher number gives higher priority. + */ + private const DEFECT_SORT_WEIGHT = [ + BaseTestRunner::STATUS_ERROR => 6, + BaseTestRunner::STATUS_FAILURE => 5, + BaseTestRunner::STATUS_WARNING => 4, + BaseTestRunner::STATUS_INCOMPLETE => 3, + BaseTestRunner::STATUS_RISKY => 2, + BaseTestRunner::STATUS_SKIPPED => 1, + BaseTestRunner::STATUS_UNKNOWN => 0, + ]; + + private const SIZE_SORT_WEIGHT = [ + TestUtil::SMALL => 1, + TestUtil::MEDIUM => 2, + TestUtil::LARGE => 3, + TestUtil::UNKNOWN => 4, + ]; + + /** + * @var array Associative array of (string => DEFECT_SORT_WEIGHT) elements + */ + private $defectSortOrder = []; + + /** + * @var TestResultCache + */ + private $cache; + + /** + * @var string[] A list of normalized names of tests before reordering + */ + private $originalExecutionOrder = []; + + /** + * @var string[] A list of normalized names of tests affected by reordering + */ + private $executionOrder = []; + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function getTestSorterUID(Test $test): string + { + if ($test instanceof PhptTestCase) { + return $test->getName(); + } + + if ($test instanceof TestCase) { + $testName = $test->getName(true); + + if (\strpos($testName, '::') === false) { + $testName = \get_class($test) . '::' . $testName; + } + + return $testName; + } + + return $test->getName(); + } + + public function __construct(?TestResultCache $cache = null) + { + $this->cache = $cache ?? new NullTestResultCache; + } + + /** + * @throws Exception + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function reorderTestsInSuite(Test $suite, int $order, bool $resolveDependencies, int $orderDefects, bool $isRootTestSuite = true): void + { + $allowedOrders = [ + self::ORDER_DEFAULT, + self::ORDER_REVERSED, + self::ORDER_RANDOMIZED, + self::ORDER_DURATION, + self::ORDER_SIZE, + ]; + + if (!\in_array($order, $allowedOrders, true)) { + throw new Exception( + '$order must be one of TestSuiteSorter::ORDER_[DEFAULT|REVERSED|RANDOMIZED|DURATION|SIZE]' + ); + } + + $allowedOrderDefects = [ + self::ORDER_DEFAULT, + self::ORDER_DEFECTS_FIRST, + ]; + + if (!\in_array($orderDefects, $allowedOrderDefects, true)) { + throw new Exception( + '$orderDefects must be one of TestSuiteSorter::ORDER_DEFAULT, TestSuiteSorter::ORDER_DEFECTS_FIRST' + ); + } + + if ($isRootTestSuite) { + $this->originalExecutionOrder = $this->calculateTestExecutionOrder($suite); + } + + if ($suite instanceof TestSuite) { + foreach ($suite as $_suite) { + $this->reorderTestsInSuite($_suite, $order, $resolveDependencies, $orderDefects, false); + } + + if ($orderDefects === self::ORDER_DEFECTS_FIRST) { + $this->addSuiteToDefectSortOrder($suite); + } + + $this->sort($suite, $order, $resolveDependencies, $orderDefects); + } + + if ($isRootTestSuite) { + $this->executionOrder = $this->calculateTestExecutionOrder($suite); + } + } + + public function getOriginalExecutionOrder(): array + { + return $this->originalExecutionOrder; + } + + public function getExecutionOrder(): array + { + return $this->executionOrder; + } + + private function sort(TestSuite $suite, int $order, bool $resolveDependencies, int $orderDefects): void + { + if (empty($suite->tests())) { + return; + } + + if ($order === self::ORDER_REVERSED) { + $suite->setTests($this->reverse($suite->tests())); + } elseif ($order === self::ORDER_RANDOMIZED) { + $suite->setTests($this->randomize($suite->tests())); + } elseif ($order === self::ORDER_DURATION && $this->cache !== null) { + $suite->setTests($this->sortByDuration($suite->tests())); + } elseif ($order === self::ORDER_SIZE) { + $suite->setTests($this->sortBySize($suite->tests())); + } + + if ($orderDefects === self::ORDER_DEFECTS_FIRST && $this->cache !== null) { + $suite->setTests($this->sortDefectsFirst($suite->tests())); + } + + if ($resolveDependencies && !($suite instanceof DataProviderTestSuite) && $this->suiteOnlyContainsTests($suite)) { + /** @var TestCase[] $tests */ + $tests = $suite->tests(); + + $suite->setTests($this->resolveDependencies($tests)); + } + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function addSuiteToDefectSortOrder(TestSuite $suite): void + { + $max = 0; + + foreach ($suite->tests() as $test) { + $testname = self::getTestSorterUID($test); + + if (!isset($this->defectSortOrder[$testname])) { + $this->defectSortOrder[$testname] = self::DEFECT_SORT_WEIGHT[$this->cache->getState($testname)]; + $max = \max($max, $this->defectSortOrder[$testname]); + } + } + + $this->defectSortOrder[$suite->getName()] = $max; + } + + private function suiteOnlyContainsTests(TestSuite $suite): bool + { + return \array_reduce( + $suite->tests(), + static function ($carry, $test) { + return $carry && ($test instanceof TestCase || $test instanceof DataProviderTestSuite); + }, + true + ); + } + + private function reverse(array $tests): array + { + return \array_reverse($tests); + } + + private function randomize(array $tests): array + { + \shuffle($tests); + + return $tests; + } + + private function sortDefectsFirst(array $tests): array + { + \usort( + $tests, + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + function ($left, $right) { + return $this->cmpDefectPriorityAndTime($left, $right); + } + ); + + return $tests; + } + + private function sortByDuration(array $tests): array + { + \usort( + $tests, + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + function ($left, $right) { + return $this->cmpDuration($left, $right); + } + ); + + return $tests; + } + + private function sortBySize(array $tests): array + { + \usort( + $tests, + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + function ($left, $right) { + return $this->cmpSize($left, $right); + } + ); + + return $tests; + } + + /** + * Comparator callback function to sort tests for "reach failure as fast as possible": + * 1. sort tests by defect weight defined in self::DEFECT_SORT_WEIGHT + * 2. when tests are equally defective, sort the fastest to the front + * 3. do not reorder successful tests + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function cmpDefectPriorityAndTime(Test $a, Test $b): int + { + $priorityA = $this->defectSortOrder[self::getTestSorterUID($a)] ?? 0; + $priorityB = $this->defectSortOrder[self::getTestSorterUID($b)] ?? 0; + + if ($priorityB <=> $priorityA) { + // Sort defect weight descending + return $priorityB <=> $priorityA; + } + + if ($priorityA || $priorityB) { + return $this->cmpDuration($a, $b); + } + + // do not change execution order + return 0; + } + + /** + * Compares test duration for sorting tests by duration ascending. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function cmpDuration(Test $a, Test $b): int + { + return $this->cache->getTime(self::getTestSorterUID($a)) <=> $this->cache->getTime(self::getTestSorterUID($b)); + } + + /** + * Compares test size for sorting tests small->medium->large->unknown + */ + private function cmpSize(Test $a, Test $b): int + { + $sizeA = ($a instanceof TestCase || $a instanceof DataProviderTestSuite) + ? $a->getSize() + : TestUtil::UNKNOWN; + $sizeB = ($b instanceof TestCase || $b instanceof DataProviderTestSuite) + ? $b->getSize() + : TestUtil::UNKNOWN; + + return self::SIZE_SORT_WEIGHT[$sizeA] <=> self::SIZE_SORT_WEIGHT[$sizeB]; + } + + /** + * Reorder Tests within a TestCase in such a way as to resolve as many dependencies as possible. + * The algorithm will leave the tests in original running order when it can. + * For more details see the documentation for test dependencies. + * + * Short description of algorithm: + * 1. Pick the next Test from remaining tests to be checked for dependencies. + * 2. If the test has no dependencies: mark done, start again from the top + * 3. If the test has dependencies but none left to do: mark done, start again from the top + * 4. When we reach the end add any leftover tests to the end. These will be marked 'skipped' during execution. + * + * @param array $tests + * + * @return array + */ + private function resolveDependencies(array $tests): array + { + $newTestOrder = []; + $i = 0; + + do { + $todoNames = \array_map( + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + static function ($test) { + return self::getTestSorterUID($test); + }, + $tests + ); + + if (!$tests[$i]->hasDependencies() || empty(\array_intersect($this->getNormalizedDependencyNames($tests[$i]), $todoNames))) { + $newTestOrder = \array_merge($newTestOrder, \array_splice($tests, $i, 1)); + $i = 0; + } else { + $i++; + } + } while (!empty($tests) && ($i < \count($tests))); + + return \array_merge($newTestOrder, $tests); + } + + /** + * @param DataProviderTestSuite|TestCase $test + * + * @return array A list of full test names as "TestSuiteClassName::testMethodName" + */ + private function getNormalizedDependencyNames($test): array + { + if ($test instanceof DataProviderTestSuite) { + $testClass = \substr($test->getName(), 0, \strpos($test->getName(), '::')); + } else { + $testClass = \get_class($test); + } + + $names = \array_map( + static function ($name) use ($testClass) { + return \strpos($name, '::') === false ? $testClass . '::' . $name : $name; + }, + $test->getDependencies() + ); + + return $names; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function calculateTestExecutionOrder(Test $suite): array + { + $tests = []; + + if ($suite instanceof TestSuite) { + foreach ($suite->tests() as $test) { + if (!($test instanceof TestSuite)) { + $tests[] = self::getTestSorterUID($test); + } else { + $tests = \array_merge($tests, $this->calculateTestExecutionOrder($test)); + } + } + } + + return $tests; + } +} diff --git a/vendor/phpunit/phpunit/src/Runner/Version.php b/vendor/phpunit/phpunit/src/Runner/Version.php new file mode 100644 index 0000000..763c411 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Runner/Version.php @@ -0,0 +1,66 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Runner; + +use SebastianBergmann\Version as VersionId; + +final class Version +{ + /** + * @var string + */ + private static $pharVersion = ''; + + /** + * @var string + */ + private static $version = ''; + + /** + * Returns the current version of PHPUnit. + */ + public static function id(): string + { + if (self::$pharVersion !== '') { + return self::$pharVersion; + } + + if (self::$version === '') { + self::$version = (new VersionId('8.5.8', \dirname(__DIR__, 2)))->getVersion(); + } + + return self::$version; + } + + public static function series(): string + { + if (\strpos(self::id(), '-')) { + $version = \explode('-', self::id())[0]; + } else { + $version = self::id(); + } + + return \implode('.', \array_slice(\explode('.', $version), 0, 2)); + } + + public static function getVersionString(): string + { + return 'PHPUnit ' . self::id() . ' by Sebastian Bergmann and contributors.'; + } + + public static function getReleaseChannel(): string + { + if (\strpos(self::$pharVersion, '-') !== false) { + return '-nightly'; + } + + return ''; + } +} diff --git a/vendor/phpunit/phpunit/src/TextUI/Command.php b/vendor/phpunit/phpunit/src/TextUI/Command.php new file mode 100644 index 0000000..02ef34a --- /dev/null +++ b/vendor/phpunit/phpunit/src/TextUI/Command.php @@ -0,0 +1,1332 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use PharIo\Manifest\ApplicationName; +use PharIo\Manifest\Exception as ManifestException; +use PharIo\Manifest\ManifestLoader; +use PharIo\Version\Version as PharIoVersion; +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Runner\StandardTestSuiteLoader; +use PHPUnit\Runner\TestSuiteLoader; +use PHPUnit\Runner\TestSuiteSorter; +use PHPUnit\Runner\Version; +use PHPUnit\Util\Configuration; +use PHPUnit\Util\ConfigurationGenerator; +use PHPUnit\Util\FileLoader; +use PHPUnit\Util\Filesystem; +use PHPUnit\Util\Getopt; +use PHPUnit\Util\Log\TeamCity; +use PHPUnit\Util\Printer; +use PHPUnit\Util\TestDox\CliTestDoxPrinter; +use PHPUnit\Util\TextTestListRenderer; +use PHPUnit\Util\XmlTestListRenderer; +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; + +use Throwable; + +/** + * A TestRunner for the Command Line Interface (CLI) + * PHP SAPI Module. + */ +class Command +{ + /** + * @var array + */ + protected $arguments = [ + 'listGroups' => false, + 'listSuites' => false, + 'listTests' => false, + 'listTestsXml' => false, + 'loader' => null, + 'useDefaultConfiguration' => true, + 'loadedExtensions' => [], + 'notLoadedExtensions' => [], + ]; + + /** + * @var array + */ + protected $options = []; + + /** + * @var array + */ + protected $longOptions = [ + 'atleast-version=' => null, + 'prepend=' => null, + 'bootstrap=' => null, + 'cache-result' => null, + 'do-not-cache-result' => null, + 'cache-result-file=' => null, + 'check-version' => null, + 'colors==' => null, + 'columns=' => null, + 'configuration=' => null, + 'coverage-clover=' => null, + 'coverage-crap4j=' => null, + 'coverage-html=' => null, + 'coverage-php=' => null, + 'coverage-text==' => null, + 'coverage-xml=' => null, + 'debug' => null, + 'disallow-test-output' => null, + 'disallow-resource-usage' => null, + 'disallow-todo-tests' => null, + 'default-time-limit=' => null, + 'enforce-time-limit' => null, + 'exclude-group=' => null, + 'filter=' => null, + 'generate-configuration' => null, + 'globals-backup' => null, + 'group=' => null, + 'help' => null, + 'resolve-dependencies' => null, + 'ignore-dependencies' => null, + 'include-path=' => null, + 'list-groups' => null, + 'list-suites' => null, + 'list-tests' => null, + 'list-tests-xml=' => null, + 'loader=' => null, + 'log-junit=' => null, + 'log-teamcity=' => null, + 'no-configuration' => null, + 'no-coverage' => null, + 'no-logging' => null, + 'no-interaction' => null, + 'no-extensions' => null, + 'order-by=' => null, + 'printer=' => null, + 'process-isolation' => null, + 'repeat=' => null, + 'dont-report-useless-tests' => null, + 'random-order' => null, + 'random-order-seed=' => null, + 'reverse-order' => null, + 'reverse-list' => null, + 'static-backup' => null, + 'stderr' => null, + 'stop-on-defect' => null, + 'stop-on-error' => null, + 'stop-on-failure' => null, + 'stop-on-warning' => null, + 'stop-on-incomplete' => null, + 'stop-on-risky' => null, + 'stop-on-skipped' => null, + 'fail-on-warning' => null, + 'fail-on-risky' => null, + 'strict-coverage' => null, + 'disable-coverage-ignore' => null, + 'strict-global-state' => null, + 'teamcity' => null, + 'testdox' => null, + 'testdox-group=' => null, + 'testdox-exclude-group=' => null, + 'testdox-html=' => null, + 'testdox-text=' => null, + 'testdox-xml=' => null, + 'test-suffix=' => null, + 'testsuite=' => null, + 'verbose' => null, + 'version' => null, + 'whitelist=' => null, + 'dump-xdebug-filter=' => null, + ]; + + /** + * @var @psalm-var list + */ + private $warnings = []; + + /** + * @var bool + */ + private $versionStringPrinted = false; + + /** + * @throws \PHPUnit\Framework\Exception + */ + public static function main(bool $exit = true): int + { + return (new static)->run($_SERVER['argv'], $exit); + } + + /** + * @throws Exception + */ + public function run(array $argv, bool $exit = true): int + { + $this->handleArguments($argv); + + $runner = $this->createRunner(); + + if ($this->arguments['test'] instanceof Test) { + $suite = $this->arguments['test']; + } else { + $suite = $runner->getTest( + $this->arguments['test'], + $this->arguments['testFile'], + $this->arguments['testSuffixes'] + ); + } + + if ($this->arguments['listGroups']) { + return $this->handleListGroups($suite, $exit); + } + + if ($this->arguments['listSuites']) { + return $this->handleListSuites($exit); + } + + if ($this->arguments['listTests']) { + return $this->handleListTests($suite, $exit); + } + + if ($this->arguments['listTestsXml']) { + return $this->handleListTestsXml($suite, $this->arguments['listTestsXml'], $exit); + } + + unset($this->arguments['test'], $this->arguments['testFile']); + + try { + $result = $runner->doRun($suite, $this->arguments, $this->warnings, $exit); + } catch (Exception $e) { + print $e->getMessage() . \PHP_EOL; + } + + $return = TestRunner::FAILURE_EXIT; + + if (isset($result) && $result->wasSuccessful()) { + $return = TestRunner::SUCCESS_EXIT; + } elseif (!isset($result) || $result->errorCount() > 0) { + $return = TestRunner::EXCEPTION_EXIT; + } + + if ($exit) { + exit($return); + } + + return $return; + } + + /** + * Create a TestRunner, override in subclasses. + */ + protected function createRunner(): TestRunner + { + return new TestRunner($this->arguments['loader']); + } + + /** + * Handles the command-line arguments. + * + * A child class of PHPUnit\TextUI\Command can hook into the argument + * parsing by adding the switch(es) to the $longOptions array and point to a + * callback method that handles the switch(es) in the child class like this + * + * + * longOptions['my-switch'] = 'myHandler'; + * // my-secondswitch will accept a value - note the equals sign + * $this->longOptions['my-secondswitch='] = 'myOtherHandler'; + * } + * + * // --my-switch -> myHandler() + * protected function myHandler() + * { + * } + * + * // --my-secondswitch foo -> myOtherHandler('foo') + * protected function myOtherHandler ($value) + * { + * } + * + * // You will also need this - the static keyword in the + * // PHPUnit\TextUI\Command will mean that it'll be + * // PHPUnit\TextUI\Command that gets instantiated, + * // not MyCommand + * public static function main($exit = true) + * { + * $command = new static; + * + * return $command->run($_SERVER['argv'], $exit); + * } + * + * } + * + * + * @throws Exception + */ + protected function handleArguments(array $argv): void + { + try { + $this->options = Getopt::getopt( + $argv, + 'd:c:hv', + \array_keys($this->longOptions) + ); + } catch (Exception $t) { + $this->exitWithErrorMessage($t->getMessage()); + } + + foreach ($this->options[0] as $option) { + switch ($option[0]) { + case '--colors': + $this->arguments['colors'] = $option[1] ?: ResultPrinter::COLOR_AUTO; + + break; + + case '--bootstrap': + $this->arguments['bootstrap'] = $option[1]; + + break; + + case '--cache-result': + $this->arguments['cacheResult'] = true; + + break; + + case '--do-not-cache-result': + $this->arguments['cacheResult'] = false; + + break; + + case '--cache-result-file': + $this->arguments['cacheResultFile'] = $option[1]; + + break; + + case '--columns': + if (\is_numeric($option[1])) { + $this->arguments['columns'] = (int) $option[1]; + } elseif ($option[1] === 'max') { + $this->arguments['columns'] = 'max'; + } + + break; + + case 'c': + case '--configuration': + $this->arguments['configuration'] = $option[1]; + + break; + + case '--coverage-clover': + $this->arguments['coverageClover'] = $option[1]; + + break; + + case '--coverage-crap4j': + $this->arguments['coverageCrap4J'] = $option[1]; + + break; + + case '--coverage-html': + $this->arguments['coverageHtml'] = $option[1]; + + break; + + case '--coverage-php': + $this->arguments['coveragePHP'] = $option[1]; + + break; + + case '--coverage-text': + if ($option[1] === null) { + $option[1] = 'php://stdout'; + } + + $this->arguments['coverageText'] = $option[1]; + $this->arguments['coverageTextShowUncoveredFiles'] = false; + $this->arguments['coverageTextShowOnlySummary'] = false; + + break; + + case '--coverage-xml': + $this->arguments['coverageXml'] = $option[1]; + + break; + + case 'd': + $ini = \explode('=', $option[1]); + + if (isset($ini[0])) { + if (isset($ini[1])) { + \ini_set($ini[0], $ini[1]); + } else { + \ini_set($ini[0], '1'); + } + } + + break; + + case '--debug': + $this->arguments['debug'] = true; + + break; + + case 'h': + case '--help': + $this->showHelp(); + exit(TestRunner::SUCCESS_EXIT); + + break; + + case '--filter': + $this->arguments['filter'] = $option[1]; + + break; + + case '--testsuite': + $this->arguments['testsuite'] = $option[1]; + + break; + + case '--generate-configuration': + $this->printVersionString(); + + print 'Generating phpunit.xml in ' . \getcwd() . \PHP_EOL . \PHP_EOL; + + print 'Bootstrap script (relative to path shown above; default: vendor/autoload.php): '; + $bootstrapScript = \trim(\fgets(\STDIN)); + + print 'Tests directory (relative to path shown above; default: tests): '; + $testsDirectory = \trim(\fgets(\STDIN)); + + print 'Source directory (relative to path shown above; default: src): '; + $src = \trim(\fgets(\STDIN)); + + if ($bootstrapScript === '') { + $bootstrapScript = 'vendor/autoload.php'; + } + + if ($testsDirectory === '') { + $testsDirectory = 'tests'; + } + + if ($src === '') { + $src = 'src'; + } + + $generator = new ConfigurationGenerator; + + \file_put_contents( + 'phpunit.xml', + $generator->generateDefaultConfiguration( + Version::series(), + $bootstrapScript, + $testsDirectory, + $src + ) + ); + + print \PHP_EOL . 'Generated phpunit.xml in ' . \getcwd() . \PHP_EOL; + + exit(TestRunner::SUCCESS_EXIT); + + break; + + case '--group': + $this->arguments['groups'] = \explode(',', $option[1]); + + break; + + case '--exclude-group': + $this->arguments['excludeGroups'] = \explode( + ',', + $option[1] + ); + + break; + + case '--test-suffix': + $this->arguments['testSuffixes'] = \explode( + ',', + $option[1] + ); + + break; + + case '--include-path': + $includePath = $option[1]; + + break; + + case '--list-groups': + $this->arguments['listGroups'] = true; + + break; + + case '--list-suites': + $this->arguments['listSuites'] = true; + + break; + + case '--list-tests': + $this->arguments['listTests'] = true; + + break; + + case '--list-tests-xml': + $this->arguments['listTestsXml'] = $option[1]; + + break; + + case '--printer': + $this->arguments['printer'] = $option[1]; + + break; + + case '--loader': + $this->arguments['loader'] = $option[1]; + + break; + + case '--log-junit': + $this->arguments['junitLogfile'] = $option[1]; + + break; + + case '--log-teamcity': + $this->arguments['teamcityLogfile'] = $option[1]; + + break; + + case '--order-by': + $this->handleOrderByOption($option[1]); + + break; + + case '--process-isolation': + $this->arguments['processIsolation'] = true; + + break; + + case '--repeat': + $this->arguments['repeat'] = (int) $option[1]; + + break; + + case '--stderr': + $this->arguments['stderr'] = true; + + break; + + case '--stop-on-defect': + $this->arguments['stopOnDefect'] = true; + + break; + + case '--stop-on-error': + $this->arguments['stopOnError'] = true; + + break; + + case '--stop-on-failure': + $this->arguments['stopOnFailure'] = true; + + break; + + case '--stop-on-warning': + $this->arguments['stopOnWarning'] = true; + + break; + + case '--stop-on-incomplete': + $this->arguments['stopOnIncomplete'] = true; + + break; + + case '--stop-on-risky': + $this->arguments['stopOnRisky'] = true; + + break; + + case '--stop-on-skipped': + $this->arguments['stopOnSkipped'] = true; + + break; + + case '--fail-on-warning': + $this->arguments['failOnWarning'] = true; + + break; + + case '--fail-on-risky': + $this->arguments['failOnRisky'] = true; + + break; + + case '--teamcity': + $this->arguments['printer'] = TeamCity::class; + + break; + + case '--testdox': + $this->arguments['printer'] = CliTestDoxPrinter::class; + + break; + + case '--testdox-group': + $this->arguments['testdoxGroups'] = \explode( + ',', + $option[1] + ); + + break; + + case '--testdox-exclude-group': + $this->arguments['testdoxExcludeGroups'] = \explode( + ',', + $option[1] + ); + + break; + + case '--testdox-html': + $this->arguments['testdoxHTMLFile'] = $option[1]; + + break; + + case '--testdox-text': + $this->arguments['testdoxTextFile'] = $option[1]; + + break; + + case '--testdox-xml': + $this->arguments['testdoxXMLFile'] = $option[1]; + + break; + + case '--no-configuration': + $this->arguments['useDefaultConfiguration'] = false; + + break; + + case '--no-extensions': + $this->arguments['noExtensions'] = true; + + break; + + case '--no-coverage': + $this->arguments['noCoverage'] = true; + + break; + + case '--no-logging': + $this->arguments['noLogging'] = true; + + break; + + case '--no-interaction': + $this->arguments['noInteraction'] = true; + + break; + + case '--globals-backup': + $this->arguments['backupGlobals'] = true; + + break; + + case '--static-backup': + $this->arguments['backupStaticAttributes'] = true; + + break; + + case 'v': + case '--verbose': + $this->arguments['verbose'] = true; + + break; + + case '--atleast-version': + if (\version_compare(Version::id(), $option[1], '>=')) { + exit(TestRunner::SUCCESS_EXIT); + } + + exit(TestRunner::FAILURE_EXIT); + + break; + + case '--version': + $this->printVersionString(); + exit(TestRunner::SUCCESS_EXIT); + + break; + + case '--dont-report-useless-tests': + $this->arguments['reportUselessTests'] = false; + + break; + + case '--strict-coverage': + $this->arguments['strictCoverage'] = true; + + break; + + case '--disable-coverage-ignore': + $this->arguments['disableCodeCoverageIgnore'] = true; + + break; + + case '--strict-global-state': + $this->arguments['beStrictAboutChangesToGlobalState'] = true; + + break; + + case '--disallow-test-output': + $this->arguments['disallowTestOutput'] = true; + + break; + + case '--disallow-resource-usage': + $this->arguments['beStrictAboutResourceUsageDuringSmallTests'] = true; + + break; + + case '--default-time-limit': + $this->arguments['defaultTimeLimit'] = (int) $option[1]; + + break; + + case '--enforce-time-limit': + $this->arguments['enforceTimeLimit'] = true; + + break; + + case '--disallow-todo-tests': + $this->arguments['disallowTodoAnnotatedTests'] = true; + + break; + + case '--reverse-list': + $this->arguments['reverseList'] = true; + + break; + + case '--check-version': + $this->handleVersionCheck(); + + break; + + case '--whitelist': + $this->arguments['whitelist'] = $option[1]; + + break; + + case '--random-order': + $this->handleOrderByOption('random'); + + break; + + case '--random-order-seed': + $this->arguments['randomOrderSeed'] = (int) $option[1]; + + break; + + case '--resolve-dependencies': + $this->handleOrderByOption('depends'); + + break; + + case '--ignore-dependencies': + $this->handleOrderByOption('no-depends'); + + break; + + case '--reverse-order': + $this->handleOrderByOption('reverse'); + + break; + + case '--dump-xdebug-filter': + $this->arguments['xdebugFilterFile'] = $option[1]; + + break; + + default: + $optionName = \str_replace('--', '', $option[0]); + + $handler = null; + + if (isset($this->longOptions[$optionName])) { + $handler = $this->longOptions[$optionName]; + } elseif (isset($this->longOptions[$optionName . '='])) { + $handler = $this->longOptions[$optionName . '=']; + } + + if (isset($handler) && \is_callable([$this, $handler])) { + $this->$handler($option[1]); + } + } + } + + $this->handleCustomTestSuite(); + + if (!isset($this->arguments['testSuffixes'])) { + $this->arguments['testSuffixes'] = ['Test.php', '.phpt']; + } + + if (isset($this->options[1][0]) && + \substr($this->options[1][0], -5, 5) !== '.phpt' && + \substr($this->options[1][0], -4, 4) !== '.php' && + \substr($this->options[1][0], -1, 1) !== '/' && + !\is_dir($this->options[1][0])) { + $this->warnings[] = 'Invocation with class name is deprecated'; + } + + if (!isset($this->arguments['test'])) { + if (isset($this->options[1][0])) { + $this->arguments['test'] = $this->options[1][0]; + } + + if (isset($this->options[1][1])) { + $testFile = \realpath($this->options[1][1]); + + if ($testFile === false) { + $this->exitWithErrorMessage( + \sprintf( + 'Cannot open file "%s".', + $this->options[1][1] + ) + ); + } + $this->arguments['testFile'] = $testFile; + } else { + $this->arguments['testFile'] = ''; + } + + if (isset($this->arguments['test']) && + \is_file($this->arguments['test']) && + \strrpos($this->arguments['test'], '.') !== false && + \substr($this->arguments['test'], -5, 5) !== '.phpt') { + $this->arguments['testFile'] = \realpath($this->arguments['test']); + $this->arguments['test'] = \substr($this->arguments['test'], 0, \strrpos($this->arguments['test'], '.')); + } + + if (isset($this->arguments['test']) && + \is_string($this->arguments['test']) && + \substr($this->arguments['test'], -5, 5) === '.phpt') { + $suite = new TestSuite; + $suite->addTestFile($this->arguments['test']); + $this->arguments['test'] = $suite; + } + } + + if (isset($includePath)) { + \ini_set( + 'include_path', + $includePath . \PATH_SEPARATOR . \ini_get('include_path') + ); + } + + if ($this->arguments['loader'] !== null) { + $this->arguments['loader'] = $this->handleLoader($this->arguments['loader']); + } + + if (isset($this->arguments['configuration']) && + \is_dir($this->arguments['configuration'])) { + $configurationFile = $this->arguments['configuration'] . '/phpunit.xml'; + + if (\file_exists($configurationFile)) { + $this->arguments['configuration'] = \realpath( + $configurationFile + ); + } elseif (\file_exists($configurationFile . '.dist')) { + $this->arguments['configuration'] = \realpath( + $configurationFile . '.dist' + ); + } + } elseif (!isset($this->arguments['configuration']) && + $this->arguments['useDefaultConfiguration']) { + if (\file_exists('phpunit.xml')) { + $this->arguments['configuration'] = \realpath('phpunit.xml'); + } elseif (\file_exists('phpunit.xml.dist')) { + $this->arguments['configuration'] = \realpath( + 'phpunit.xml.dist' + ); + } + } + + if (isset($this->arguments['configuration'])) { + try { + $configuration = Configuration::getInstance( + $this->arguments['configuration'] + ); + } catch (Throwable $t) { + print $t->getMessage() . \PHP_EOL; + exit(TestRunner::FAILURE_EXIT); + } + + $phpunitConfiguration = $configuration->getPHPUnitConfiguration(); + + $configuration->handlePHPConfiguration(); + + /* + * Issue #1216 + */ + if (isset($this->arguments['bootstrap'])) { + $this->handleBootstrap($this->arguments['bootstrap']); + } elseif (isset($phpunitConfiguration['bootstrap'])) { + $this->handleBootstrap($phpunitConfiguration['bootstrap']); + } + + /* + * Issue #657 + */ + if (isset($phpunitConfiguration['stderr']) && !isset($this->arguments['stderr'])) { + $this->arguments['stderr'] = $phpunitConfiguration['stderr']; + } + + if (isset($phpunitConfiguration['extensionsDirectory']) && !isset($this->arguments['noExtensions']) && \extension_loaded('phar')) { + $this->handleExtensions($phpunitConfiguration['extensionsDirectory']); + } + + if (isset($phpunitConfiguration['columns']) && !isset($this->arguments['columns'])) { + $this->arguments['columns'] = $phpunitConfiguration['columns']; + } + + if (!isset($this->arguments['printer']) && isset($phpunitConfiguration['printerClass'])) { + $file = $phpunitConfiguration['printerFile'] ?? ''; + + $this->arguments['printer'] = $this->handlePrinter( + $phpunitConfiguration['printerClass'], + $file + ); + } + + if (isset($phpunitConfiguration['testSuiteLoaderClass'])) { + $file = $phpunitConfiguration['testSuiteLoaderFile'] ?? ''; + + $this->arguments['loader'] = $this->handleLoader( + $phpunitConfiguration['testSuiteLoaderClass'], + $file + ); + } + + if (!isset($this->arguments['testsuite']) && isset($phpunitConfiguration['defaultTestSuite'])) { + $this->arguments['testsuite'] = $phpunitConfiguration['defaultTestSuite']; + } + + if (!isset($this->arguments['test'])) { + $testSuite = $configuration->getTestSuiteConfiguration($this->arguments['testsuite'] ?? ''); + + if ($testSuite !== null) { + $this->arguments['test'] = $testSuite; + } + } + } elseif (isset($this->arguments['bootstrap'])) { + $this->handleBootstrap($this->arguments['bootstrap']); + } + + if (isset($this->arguments['printer']) && + \is_string($this->arguments['printer'])) { + $this->arguments['printer'] = $this->handlePrinter($this->arguments['printer']); + } + + if (!isset($this->arguments['test'])) { + $this->showHelp(); + exit(TestRunner::EXCEPTION_EXIT); + } + } + + /** + * Handles the loading of the PHPUnit\Runner\TestSuiteLoader implementation. + */ + protected function handleLoader(string $loaderClass, string $loaderFile = ''): ?TestSuiteLoader + { + if (!\class_exists($loaderClass, false)) { + if ($loaderFile == '') { + $loaderFile = Filesystem::classNameToFilename( + $loaderClass + ); + } + + $loaderFile = \stream_resolve_include_path($loaderFile); + + if ($loaderFile) { + require $loaderFile; + } + } + + if (\class_exists($loaderClass, false)) { + try { + $class = new \ReflectionClass($loaderClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if ($class->implementsInterface(TestSuiteLoader::class) && $class->isInstantiable()) { + $object = $class->newInstance(); + + \assert($object instanceof TestSuiteLoader); + + return $object; + } + } + + if ($loaderClass == StandardTestSuiteLoader::class) { + return null; + } + + $this->exitWithErrorMessage( + \sprintf( + 'Could not use "%s" as loader.', + $loaderClass + ) + ); + + return null; + } + + /** + * Handles the loading of the PHPUnit\Util\Printer implementation. + * + * @return null|Printer|string + */ + protected function handlePrinter(string $printerClass, string $printerFile = '') + { + if (!\class_exists($printerClass, false)) { + if ($printerFile == '') { + $printerFile = Filesystem::classNameToFilename( + $printerClass + ); + } + + $printerFile = \stream_resolve_include_path($printerFile); + + if ($printerFile) { + require $printerFile; + } + } + + if (!\class_exists($printerClass)) { + $this->exitWithErrorMessage( + \sprintf( + 'Could not use "%s" as printer: class does not exist', + $printerClass + ) + ); + } + + try { + $class = new \ReflectionClass($printerClass); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + // @codeCoverageIgnoreEnd + } + + if (!$class->implementsInterface(TestListener::class)) { + $this->exitWithErrorMessage( + \sprintf( + 'Could not use "%s" as printer: class does not implement %s', + $printerClass, + TestListener::class + ) + ); + } + + if (!$class->isSubclassOf(Printer::class)) { + $this->exitWithErrorMessage( + \sprintf( + 'Could not use "%s" as printer: class does not extend %s', + $printerClass, + Printer::class + ) + ); + } + + if (!$class->isInstantiable()) { + $this->exitWithErrorMessage( + \sprintf( + 'Could not use "%s" as printer: class cannot be instantiated', + $printerClass + ) + ); + } + + if ($class->isSubclassOf(ResultPrinter::class)) { + return $printerClass; + } + + $outputStream = isset($this->arguments['stderr']) ? 'php://stderr' : null; + + return $class->newInstance($outputStream); + } + + /** + * Loads a bootstrap file. + */ + protected function handleBootstrap(string $filename): void + { + try { + FileLoader::checkAndLoad($filename); + } catch (Exception $e) { + $this->exitWithErrorMessage($e->getMessage()); + } + } + + protected function handleVersionCheck(): void + { + $this->printVersionString(); + + $latestVersion = \file_get_contents('https://phar.phpunit.de/latest-version-of/phpunit'); + $isOutdated = \version_compare($latestVersion, Version::id(), '>'); + + if ($isOutdated) { + \printf( + 'You are not using the latest version of PHPUnit.' . \PHP_EOL . + 'The latest version is PHPUnit %s.' . \PHP_EOL, + $latestVersion + ); + } else { + print 'You are using the latest version of PHPUnit.' . \PHP_EOL; + } + + exit(TestRunner::SUCCESS_EXIT); + } + + /** + * Show the help message. + */ + protected function showHelp(): void + { + $this->printVersionString(); + (new Help)->writeToConsole(); + } + + /** + * Custom callback for test suite discovery. + */ + protected function handleCustomTestSuite(): void + { + } + + private function printVersionString(): void + { + if ($this->versionStringPrinted) { + return; + } + + print Version::getVersionString() . \PHP_EOL . \PHP_EOL; + + $this->versionStringPrinted = true; + } + + private function exitWithErrorMessage(string $message): void + { + $this->printVersionString(); + + print $message . \PHP_EOL; + + exit(TestRunner::FAILURE_EXIT); + } + + private function handleExtensions(string $directory): void + { + foreach ((new FileIteratorFacade)->getFilesAsArray($directory, '.phar') as $file) { + if (!\file_exists('phar://' . $file . '/manifest.xml')) { + $this->arguments['notLoadedExtensions'][] = $file . ' is not an extension for PHPUnit'; + + continue; + } + + try { + $applicationName = new ApplicationName('phpunit/phpunit'); + $version = new PharIoVersion(Version::series()); + $manifest = ManifestLoader::fromFile('phar://' . $file . '/manifest.xml'); + + if (!$manifest->isExtensionFor($applicationName)) { + $this->arguments['notLoadedExtensions'][] = $file . ' is not an extension for PHPUnit'; + + continue; + } + + if (!$manifest->isExtensionFor($applicationName, $version)) { + $this->arguments['notLoadedExtensions'][] = $file . ' is not compatible with this version of PHPUnit'; + + continue; + } + } catch (ManifestException $e) { + $this->arguments['notLoadedExtensions'][] = $file . ': ' . $e->getMessage(); + + continue; + } + + require $file; + + $this->arguments['loadedExtensions'][] = $manifest->getName() . ' ' . $manifest->getVersion()->getVersionString(); + } + } + + private function handleListGroups(TestSuite $suite, bool $exit): int + { + $this->printVersionString(); + + print 'Available test group(s):' . \PHP_EOL; + + $groups = $suite->getGroups(); + \sort($groups); + + foreach ($groups as $group) { + \printf( + ' - %s' . \PHP_EOL, + $group + ); + } + + if ($exit) { + exit(TestRunner::SUCCESS_EXIT); + } + + return TestRunner::SUCCESS_EXIT; + } + + /** + * @throws \PHPUnit\Framework\Exception + */ + private function handleListSuites(bool $exit): int + { + $this->printVersionString(); + + print 'Available test suite(s):' . \PHP_EOL; + + $configuration = Configuration::getInstance( + $this->arguments['configuration'] + ); + + foreach ($configuration->getTestSuiteNames() as $suiteName) { + \printf( + ' - %s' . \PHP_EOL, + $suiteName + ); + } + + if ($exit) { + exit(TestRunner::SUCCESS_EXIT); + } + + return TestRunner::SUCCESS_EXIT; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function handleListTests(TestSuite $suite, bool $exit): int + { + $this->printVersionString(); + + $renderer = new TextTestListRenderer; + + print $renderer->render($suite); + + if ($exit) { + exit(TestRunner::SUCCESS_EXIT); + } + + return TestRunner::SUCCESS_EXIT; + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function handleListTestsXml(TestSuite $suite, string $target, bool $exit): int + { + $this->printVersionString(); + + $renderer = new XmlTestListRenderer; + + \file_put_contents($target, $renderer->render($suite)); + + \printf( + 'Wrote list of tests that would have been run to %s' . \PHP_EOL, + $target + ); + + if ($exit) { + exit(TestRunner::SUCCESS_EXIT); + } + + return TestRunner::SUCCESS_EXIT; + } + + private function handleOrderByOption(string $value): void + { + foreach (\explode(',', $value) as $order) { + switch ($order) { + case 'default': + $this->arguments['executionOrder'] = TestSuiteSorter::ORDER_DEFAULT; + $this->arguments['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFAULT; + $this->arguments['resolveDependencies'] = true; + + break; + + case 'defects': + $this->arguments['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFECTS_FIRST; + + break; + + case 'depends': + $this->arguments['resolveDependencies'] = true; + + break; + + case 'duration': + $this->arguments['executionOrder'] = TestSuiteSorter::ORDER_DURATION; + + break; + + case 'no-depends': + $this->arguments['resolveDependencies'] = false; + + break; + + case 'random': + $this->arguments['executionOrder'] = TestSuiteSorter::ORDER_RANDOMIZED; + + break; + + case 'reverse': + $this->arguments['executionOrder'] = TestSuiteSorter::ORDER_REVERSED; + + break; + + case 'size': + $this->arguments['executionOrder'] = TestSuiteSorter::ORDER_SIZE; + + break; + + default: + $this->exitWithErrorMessage("unrecognized --order-by option: $order"); + } + } + } +} diff --git a/vendor/phpunit/phpunit/src/TextUI/Exception.php b/vendor/phpunit/phpunit/src/TextUI/Exception.php new file mode 100644 index 0000000..a660a87 --- /dev/null +++ b/vendor/phpunit/phpunit/src/TextUI/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Exception extends \RuntimeException implements \PHPUnit\Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/TextUI/Help.php b/vendor/phpunit/phpunit/src/TextUI/Help.php new file mode 100644 index 0000000..b2a5c6d --- /dev/null +++ b/vendor/phpunit/phpunit/src/TextUI/Help.php @@ -0,0 +1,246 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use PHPUnit\Util\Color; +use SebastianBergmann\Environment\Console; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Help +{ + private const LEFT_MARGIN = ' '; + + private const HELP_TEXT = [ + 'Usage' => [ + ['text' => 'phpunit [options] UnitTest [UnitTest.php]'], + ['text' => 'phpunit [options] '], + ], + 'Code Coverage Options' => [ + ['arg' => '--coverage-clover ', 'desc' => 'Generate code coverage report in Clover XML format'], + ['arg' => '--coverage-crap4j ', 'desc' => 'Generate code coverage report in Crap4J XML format'], + ['arg' => '--coverage-html ', 'desc' => 'Generate code coverage report in HTML format'], + ['arg' => '--coverage-php ', 'desc' => 'Export PHP_CodeCoverage object to file'], + ['arg' => '--coverage-text=', 'desc' => 'Generate code coverage report in text format [default: standard output]'], + ['arg' => '--coverage-xml ', 'desc' => 'Generate code coverage report in PHPUnit XML format'], + ['arg' => '--whitelist ', 'desc' => 'Whitelist for code coverage analysis'], + ['arg' => '--disable-coverage-ignore', 'desc' => 'Disable annotations for ignoring code coverage'], + ['arg' => '--no-coverage', 'desc' => 'Ignore code coverage configuration'], + ['arg' => '--dump-xdebug-filter ', 'desc' => 'Generate script to set Xdebug code coverage filter'], + ], + + 'Logging Options' => [ + ['arg' => '--log-junit ', 'desc' => 'Log test execution in JUnit XML format to file'], + ['arg' => '--log-teamcity ', 'desc' => 'Log test execution in TeamCity format to file'], + ['arg' => '--testdox-html ', 'desc' => 'Write agile documentation in HTML format to file'], + ['arg' => '--testdox-text ', 'desc' => 'Write agile documentation in Text format to file'], + ['arg' => '--testdox-xml ', 'desc' => 'Write agile documentation in XML format to file'], + ['arg' => '--reverse-list', 'desc' => 'Print defects in reverse order'], + ], + + 'Test Selection Options' => [ + ['arg' => '--filter ', 'desc' => 'Filter which tests to run'], + ['arg' => '--testsuite ', 'desc' => 'Filter which testsuite to run'], + ['arg' => '--group ', 'desc' => 'Only runs tests from the specified group(s)'], + ['arg' => '--exclude-group ', 'desc' => 'Exclude tests from the specified group(s)'], + ['arg' => '--list-groups', 'desc' => 'List available test groups'], + ['arg' => '--list-suites', 'desc' => 'List available test suites'], + ['arg' => '--list-tests', 'desc' => 'List available tests'], + ['arg' => '--list-tests-xml ', 'desc' => 'List available tests in XML format'], + ['arg' => '--test-suffix ', 'desc' => 'Only search for test in files with specified suffix(es). Default: Test.php,.phpt'], + ], + + 'Test Execution Options' => [ + ['arg' => '--dont-report-useless-tests', 'desc' => 'Do not report tests that do not test anything'], + ['arg' => '--strict-coverage', 'desc' => 'Be strict about @covers annotation usage'], + ['arg' => '--strict-global-state', 'desc' => 'Be strict about changes to global state'], + ['arg' => '--disallow-test-output', 'desc' => 'Be strict about output during tests'], + ['arg' => '--disallow-resource-usage', 'desc' => 'Be strict about resource usage during small tests'], + ['arg' => '--enforce-time-limit', 'desc' => 'Enforce time limit based on test size'], + ['arg' => '--default-time-limit=', 'desc' => 'Timeout in seconds for tests without @small, @medium or @large'], + ['arg' => '--disallow-todo-tests', 'desc' => 'Disallow @todo-annotated tests'], + ['spacer' => ''], + + ['arg' => '--process-isolation', 'desc' => 'Run each test in a separate PHP process'], + ['arg' => '--globals-backup', 'desc' => 'Backup and restore $GLOBALS for each test'], + ['arg' => '--static-backup', 'desc' => 'Backup and restore static attributes for each test'], + ['spacer' => ''], + + ['arg' => '--colors=', 'desc' => 'Use colors in output ("never", "auto" or "always")'], + ['arg' => '--columns ', 'desc' => 'Number of columns to use for progress output'], + ['arg' => '--columns max', 'desc' => 'Use maximum number of columns for progress output'], + ['arg' => '--stderr', 'desc' => 'Write to STDERR instead of STDOUT'], + ['arg' => '--stop-on-defect', 'desc' => 'Stop execution upon first not-passed test'], + ['arg' => '--stop-on-error', 'desc' => 'Stop execution upon first error'], + ['arg' => '--stop-on-failure', 'desc' => 'Stop execution upon first error or failure'], + ['arg' => '--stop-on-warning', 'desc' => 'Stop execution upon first warning'], + ['arg' => '--stop-on-risky', 'desc' => 'Stop execution upon first risky test'], + ['arg' => '--stop-on-skipped', 'desc' => 'Stop execution upon first skipped test'], + ['arg' => '--stop-on-incomplete', 'desc' => 'Stop execution upon first incomplete test'], + ['arg' => '--fail-on-warning', 'desc' => 'Treat tests with warnings as failures'], + ['arg' => '--fail-on-risky', 'desc' => 'Treat risky tests as failures'], + ['arg' => '-v|--verbose', 'desc' => 'Output more verbose information'], + ['arg' => '--debug', 'desc' => 'Display debugging information'], + ['spacer' => ''], + + ['arg' => '--loader ', 'desc' => 'TestSuiteLoader implementation to use'], + ['arg' => '--repeat ', 'desc' => 'Runs the test(s) repeatedly'], + ['arg' => '--teamcity', 'desc' => 'Report test execution progress in TeamCity format'], + ['arg' => '--testdox', 'desc' => 'Report test execution progress in TestDox format'], + ['arg' => '--testdox-group', 'desc' => 'Only include tests from the specified group(s)'], + ['arg' => '--testdox-exclude-group', 'desc' => 'Exclude tests from the specified group(s)'], + ['arg' => '--no-interaction', 'desc' => 'Disable TestDox progress animation'], + ['arg' => '--printer ', 'desc' => 'TestListener implementation to use'], + ['spacer' => ''], + + ['arg' => '--order-by=', 'desc' => 'Run tests in order: default|defects|duration|no-depends|random|reverse|size'], + ['arg' => '--random-order-seed=', 'desc' => 'Use a specific random seed for random order'], + ['arg' => '--cache-result', 'desc' => 'Write test results to cache file'], + ['arg' => '--do-not-cache-result', 'desc' => 'Do not write test results to cache file'], + ], + + 'Configuration Options' => [ + ['arg' => '--prepend ', 'desc' => 'A PHP script that is included as early as possible'], + ['arg' => '--bootstrap ', 'desc' => 'A PHP script that is included before the tests run'], + ['arg' => '-c|--configuration ', 'desc' => 'Read configuration from XML file'], + ['arg' => '--no-configuration', 'desc' => 'Ignore default configuration file (phpunit.xml)'], + ['arg' => '--no-logging', 'desc' => 'Ignore logging configuration'], + ['arg' => '--no-extensions', 'desc' => 'Do not load PHPUnit extensions'], + ['arg' => '--include-path ', 'desc' => 'Prepend PHP\'s include_path with given path(s)'], + ['arg' => '-d ', 'desc' => 'Sets a php.ini value'], + ['arg' => '--generate-configuration', 'desc' => 'Generate configuration file with suggested settings'], + ['arg' => '--cache-result-file=', 'desc' => 'Specify result cache path and filename'], + ], + + 'Miscellaneous Options' => [ + ['arg' => '-h|--help', 'desc' => 'Prints this usage information'], + ['arg' => '--version', 'desc' => 'Prints the version and exits'], + ['arg' => '--atleast-version ', 'desc' => 'Checks that version is greater than min and exits'], + ['arg' => '--check-version', 'desc' => 'Check whether PHPUnit is the latest version'], + ], + + ]; + + /** + * @var int Number of columns required to write the longest option name to the console + */ + private $maxArgLength = 0; + + /** + * @var int Number of columns left for the description field after padding and option + */ + private $maxDescLength; + + /** + * @var bool Use color highlights for sections, options and parameters + */ + private $hasColor = false; + + public function __construct(?int $width = null, ?bool $withColor = null) + { + if ($width === null) { + $width = (new Console)->getNumberOfColumns(); + } + + if ($withColor === null) { + $this->hasColor = (new Console)->hasColorSupport(); + } else { + $this->hasColor = $withColor; + } + + foreach (self::HELP_TEXT as $options) { + foreach ($options as $option) { + if (isset($option['arg'])) { + $this->maxArgLength = \max($this->maxArgLength, isset($option['arg']) ? \strlen($option['arg']) : 0); + } + } + } + + $this->maxDescLength = $width - $this->maxArgLength - 4; + } + + /** + * Write the help file to the CLI, adapting width and colors to the console + */ + public function writeToConsole(): void + { + if ($this->hasColor) { + $this->writeWithColor(); + } else { + $this->writePlaintext(); + } + } + + private function writePlaintext(): void + { + foreach (self::HELP_TEXT as $section => $options) { + print "$section:" . \PHP_EOL; + + if ($section !== 'Usage') { + print \PHP_EOL; + } + + foreach ($options as $option) { + if (isset($option['spacer'])) { + print \PHP_EOL; + } + + if (isset($option['text'])) { + print self::LEFT_MARGIN . $option['text'] . \PHP_EOL; + } + + if (isset($option['arg'])) { + $arg = \str_pad($option['arg'], $this->maxArgLength); + print self::LEFT_MARGIN . $arg . ' ' . $option['desc'] . \PHP_EOL; + } + } + + print \PHP_EOL; + } + } + + private function writeWithColor(): void + { + foreach (self::HELP_TEXT as $section => $options) { + print Color::colorize('fg-yellow', "$section:") . \PHP_EOL; + + foreach ($options as $option) { + if (isset($option['spacer'])) { + print \PHP_EOL; + } + + if (isset($option['text'])) { + print self::LEFT_MARGIN . $option['text'] . \PHP_EOL; + } + + if (isset($option['arg'])) { + $arg = Color::colorize('fg-green', \str_pad($option['arg'], $this->maxArgLength)); + $arg = \preg_replace_callback( + '/(<[^>]+>)/', + static function ($matches) { + return Color::colorize('fg-cyan', $matches[0]); + }, + $arg + ); + $desc = \explode(\PHP_EOL, \wordwrap($option['desc'], $this->maxDescLength, \PHP_EOL)); + + print self::LEFT_MARGIN . $arg . ' ' . $desc[0] . \PHP_EOL; + + for ($i = 1; $i < \count($desc); $i++) { + print \str_repeat(' ', $this->maxArgLength + 3) . $desc[$i] . \PHP_EOL; + } + } + } + + print \PHP_EOL; + } + } +} diff --git a/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php b/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php new file mode 100644 index 0000000..bbe7215 --- /dev/null +++ b/vendor/phpunit/phpunit/src/TextUI/ResultPrinter.php @@ -0,0 +1,572 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\InvalidArgumentException; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestFailure; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestResult; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\Util\Color; +use PHPUnit\Util\Printer; +use SebastianBergmann\Environment\Console; +use SebastianBergmann\Timer\Timer; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class ResultPrinter extends Printer implements TestListener +{ + public const EVENT_TEST_START = 0; + + public const EVENT_TEST_END = 1; + + public const EVENT_TESTSUITE_START = 2; + + public const EVENT_TESTSUITE_END = 3; + + public const COLOR_NEVER = 'never'; + + public const COLOR_AUTO = 'auto'; + + public const COLOR_ALWAYS = 'always'; + + public const COLOR_DEFAULT = self::COLOR_NEVER; + + private const AVAILABLE_COLORS = [self::COLOR_NEVER, self::COLOR_AUTO, self::COLOR_ALWAYS]; + + /** + * @var int + */ + protected $column = 0; + + /** + * @var int + */ + protected $maxColumn; + + /** + * @var bool + */ + protected $lastTestFailed = false; + + /** + * @var int + */ + protected $numAssertions = 0; + + /** + * @var int + */ + protected $numTests = -1; + + /** + * @var int + */ + protected $numTestsRun = 0; + + /** + * @var int + */ + protected $numTestsWidth; + + /** + * @var bool + */ + protected $colors = false; + + /** + * @var bool + */ + protected $debug = false; + + /** + * @var bool + */ + protected $verbose = false; + + /** + * @var int + */ + private $numberOfColumns; + + /** + * @var bool + */ + private $reverse; + + /** + * @var bool + */ + private $defectListPrinted = false; + + /** + * Constructor. + * + * @param null|resource|string $out + * @param int|string $numberOfColumns + * + * @throws Exception + */ + public function __construct($out = null, bool $verbose = false, string $colors = self::COLOR_DEFAULT, bool $debug = false, $numberOfColumns = 80, bool $reverse = false) + { + parent::__construct($out); + + if (!\in_array($colors, self::AVAILABLE_COLORS, true)) { + throw InvalidArgumentException::create( + 3, + \vsprintf('value from "%s", "%s" or "%s"', self::AVAILABLE_COLORS) + ); + } + + if (!\is_int($numberOfColumns) && $numberOfColumns !== 'max') { + throw InvalidArgumentException::create(5, 'integer or "max"'); + } + + $console = new Console; + $maxNumberOfColumns = $console->getNumberOfColumns(); + + if ($numberOfColumns === 'max' || ($numberOfColumns !== 80 && $numberOfColumns > $maxNumberOfColumns)) { + $numberOfColumns = $maxNumberOfColumns; + } + + $this->numberOfColumns = $numberOfColumns; + $this->verbose = $verbose; + $this->debug = $debug; + $this->reverse = $reverse; + + if ($colors === self::COLOR_AUTO && $console->hasColorSupport()) { + $this->colors = true; + } else { + $this->colors = (self::COLOR_ALWAYS === $colors); + } + } + + /** + * @throws \SebastianBergmann\Timer\RuntimeException + */ + public function printResult(TestResult $result): void + { + $this->printHeader($result); + $this->printErrors($result); + $this->printWarnings($result); + $this->printFailures($result); + $this->printRisky($result); + + if ($this->verbose) { + $this->printIncompletes($result); + $this->printSkipped($result); + } + + $this->printFooter($result); + } + + /** + * An error occurred. + */ + public function addError(Test $test, \Throwable $t, float $time): void + { + $this->writeProgressWithColor('fg-red, bold', 'E'); + $this->lastTestFailed = true; + } + + /** + * A failure occurred. + */ + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + $this->writeProgressWithColor('bg-red, fg-white', 'F'); + $this->lastTestFailed = true; + } + + /** + * A warning occurred. + */ + public function addWarning(Test $test, Warning $e, float $time): void + { + $this->writeProgressWithColor('fg-yellow, bold', 'W'); + $this->lastTestFailed = true; + } + + /** + * Incomplete test. + */ + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void + { + $this->writeProgressWithColor('fg-yellow, bold', 'I'); + $this->lastTestFailed = true; + } + + /** + * Risky test. + */ + public function addRiskyTest(Test $test, \Throwable $t, float $time): void + { + $this->writeProgressWithColor('fg-yellow, bold', 'R'); + $this->lastTestFailed = true; + } + + /** + * Skipped test. + */ + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + $this->writeProgressWithColor('fg-cyan, bold', 'S'); + $this->lastTestFailed = true; + } + + /** + * A testsuite started. + */ + public function startTestSuite(TestSuite $suite): void + { + if ($this->numTests == -1) { + $this->numTests = \count($suite); + $this->numTestsWidth = \strlen((string) $this->numTests); + $this->maxColumn = $this->numberOfColumns - \strlen(' / (XXX%)') - (2 * $this->numTestsWidth); + } + } + + /** + * A testsuite ended. + */ + public function endTestSuite(TestSuite $suite): void + { + } + + /** + * A test started. + */ + public function startTest(Test $test): void + { + if ($this->debug) { + $this->write( + \sprintf( + "Test '%s' started\n", + \PHPUnit\Util\Test::describeAsString($test) + ) + ); + } + } + + /** + * A test ended. + */ + public function endTest(Test $test, float $time): void + { + if ($this->debug) { + $this->write( + \sprintf( + "Test '%s' ended\n", + \PHPUnit\Util\Test::describeAsString($test) + ) + ); + } + + if (!$this->lastTestFailed) { + $this->writeProgress('.'); + } + + if ($test instanceof TestCase) { + $this->numAssertions += $test->getNumAssertions(); + } elseif ($test instanceof PhptTestCase) { + $this->numAssertions++; + } + + $this->lastTestFailed = false; + + if ($test instanceof TestCase && !$test->hasExpectationOnOutput()) { + $this->write($test->getActualOutput()); + } + } + + protected function printDefects(array $defects, string $type): void + { + $count = \count($defects); + + if ($count == 0) { + return; + } + + if ($this->defectListPrinted) { + $this->write("\n--\n\n"); + } + + $this->write( + \sprintf( + "There %s %d %s%s:\n", + ($count == 1) ? 'was' : 'were', + $count, + $type, + ($count == 1) ? '' : 's' + ) + ); + + $i = 1; + + if ($this->reverse) { + $defects = \array_reverse($defects); + } + + foreach ($defects as $defect) { + $this->printDefect($defect, $i++); + } + + $this->defectListPrinted = true; + } + + protected function printDefect(TestFailure $defect, int $count): void + { + $this->printDefectHeader($defect, $count); + $this->printDefectTrace($defect); + } + + protected function printDefectHeader(TestFailure $defect, int $count): void + { + $this->write( + \sprintf( + "\n%d) %s\n", + $count, + $defect->getTestName() + ) + ); + } + + protected function printDefectTrace(TestFailure $defect): void + { + $e = $defect->thrownException(); + $this->write((string) $e); + + while ($e = $e->getPrevious()) { + $this->write("\nCaused by\n" . $e); + } + } + + protected function printErrors(TestResult $result): void + { + $this->printDefects($result->errors(), 'error'); + } + + protected function printFailures(TestResult $result): void + { + $this->printDefects($result->failures(), 'failure'); + } + + protected function printWarnings(TestResult $result): void + { + $this->printDefects($result->warnings(), 'warning'); + } + + protected function printIncompletes(TestResult $result): void + { + $this->printDefects($result->notImplemented(), 'incomplete test'); + } + + protected function printRisky(TestResult $result): void + { + $this->printDefects($result->risky(), 'risky test'); + } + + protected function printSkipped(TestResult $result): void + { + $this->printDefects($result->skipped(), 'skipped test'); + } + + /** + * @throws \SebastianBergmann\Timer\RuntimeException + */ + protected function printHeader(TestResult $result): void + { + if (\count($result) > 0) { + $this->write(\PHP_EOL . \PHP_EOL . Timer::resourceUsage() . \PHP_EOL . \PHP_EOL); + } + } + + protected function printFooter(TestResult $result): void + { + if (\count($result) === 0) { + $this->writeWithColor( + 'fg-black, bg-yellow', + 'No tests executed!' + ); + + return; + } + + if ($result->wasSuccessfulAndNoTestIsRiskyOrSkippedOrIncomplete()) { + $this->writeWithColor( + 'fg-black, bg-green', + \sprintf( + 'OK (%d test%s, %d assertion%s)', + \count($result), + (\count($result) == 1) ? '' : 's', + $this->numAssertions, + ($this->numAssertions == 1) ? '' : 's' + ) + ); + + return; + } + + $color = 'fg-black, bg-yellow'; + + if ($result->wasSuccessful()) { + if ($this->verbose || !$result->allHarmless()) { + $this->write("\n"); + } + + $this->writeWithColor( + $color, + 'OK, but incomplete, skipped, or risky tests!' + ); + } else { + $this->write("\n"); + + if ($result->errorCount()) { + $color = 'fg-white, bg-red'; + + $this->writeWithColor( + $color, + 'ERRORS!' + ); + } elseif ($result->failureCount()) { + $color = 'fg-white, bg-red'; + + $this->writeWithColor( + $color, + 'FAILURES!' + ); + } elseif ($result->warningCount()) { + $color = 'fg-black, bg-yellow'; + + $this->writeWithColor( + $color, + 'WARNINGS!' + ); + } + } + + $this->writeCountString(\count($result), 'Tests', $color, true); + $this->writeCountString($this->numAssertions, 'Assertions', $color, true); + $this->writeCountString($result->errorCount(), 'Errors', $color); + $this->writeCountString($result->failureCount(), 'Failures', $color); + $this->writeCountString($result->warningCount(), 'Warnings', $color); + $this->writeCountString($result->skippedCount(), 'Skipped', $color); + $this->writeCountString($result->notImplementedCount(), 'Incomplete', $color); + $this->writeCountString($result->riskyCount(), 'Risky', $color); + $this->writeWithColor($color, '.'); + } + + protected function writeProgress(string $progress): void + { + if ($this->debug) { + return; + } + + $this->write($progress); + $this->column++; + $this->numTestsRun++; + + if ($this->column == $this->maxColumn || $this->numTestsRun == $this->numTests) { + if ($this->numTestsRun == $this->numTests) { + $this->write(\str_repeat(' ', $this->maxColumn - $this->column)); + } + + $this->write( + \sprintf( + ' %' . $this->numTestsWidth . 'd / %' . + $this->numTestsWidth . 'd (%3s%%)', + $this->numTestsRun, + $this->numTests, + \floor(($this->numTestsRun / $this->numTests) * 100) + ) + ); + + if ($this->column == $this->maxColumn) { + $this->writeNewLine(); + } + } + } + + protected function writeNewLine(): void + { + $this->column = 0; + $this->write("\n"); + } + + /** + * Formats a buffer with a specified ANSI color sequence if colors are + * enabled. + */ + protected function colorizeTextBox(string $color, string $buffer): string + { + if (!$this->colors) { + return $buffer; + } + + $lines = \preg_split('/\r\n|\r|\n/', $buffer); + $padding = \max(\array_map('\strlen', $lines)); + + $styledLines = []; + + foreach ($lines as $line) { + $styledLines[] = Color::colorize($color, \str_pad($line, $padding)); + } + + return \implode(\PHP_EOL, $styledLines); + } + + /** + * Writes a buffer out with a color sequence if colors are enabled. + */ + protected function writeWithColor(string $color, string $buffer, bool $lf = true): void + { + $this->write($this->colorizeTextBox($color, $buffer)); + + if ($lf) { + $this->write(\PHP_EOL); + } + } + + /** + * Writes progress with a color sequence if colors are enabled. + */ + protected function writeProgressWithColor(string $color, string $buffer): void + { + $buffer = $this->colorizeTextBox($color, $buffer); + $this->writeProgress($buffer); + } + + private function writeCountString(int $count, string $name, string $color, bool $always = false): void + { + static $first = true; + + if ($always || $count > 0) { + $this->writeWithColor( + $color, + \sprintf( + '%s%s: %d', + !$first ? ', ' : '', + $name, + $count + ), + false + ); + + $first = false; + } + } +} diff --git a/vendor/phpunit/phpunit/src/TextUI/TestRunner.php b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php new file mode 100644 index 0000000..ecbef74 --- /dev/null +++ b/vendor/phpunit/phpunit/src/TextUI/TestRunner.php @@ -0,0 +1,1363 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\TextUI; + +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestResult; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Runner\AfterLastTestHook; +use PHPUnit\Runner\BaseTestRunner; +use PHPUnit\Runner\BeforeFirstTestHook; +use PHPUnit\Runner\DefaultTestResultCache; +use PHPUnit\Runner\Filter\ExcludeGroupFilterIterator; +use PHPUnit\Runner\Filter\Factory; +use PHPUnit\Runner\Filter\IncludeGroupFilterIterator; +use PHPUnit\Runner\Filter\NameFilterIterator; +use PHPUnit\Runner\Hook; +use PHPUnit\Runner\NullTestResultCache; +use PHPUnit\Runner\ResultCacheExtension; +use PHPUnit\Runner\StandardTestSuiteLoader; +use PHPUnit\Runner\TestHook; +use PHPUnit\Runner\TestListenerAdapter; +use PHPUnit\Runner\TestSuiteLoader; +use PHPUnit\Runner\TestSuiteSorter; +use PHPUnit\Runner\Version; +use PHPUnit\Util\Configuration; +use PHPUnit\Util\Filesystem; +use PHPUnit\Util\Log\JUnit; +use PHPUnit\Util\Log\TeamCity; +use PHPUnit\Util\Printer; +use PHPUnit\Util\TestDox\CliTestDoxPrinter; +use PHPUnit\Util\TestDox\HtmlResultPrinter; +use PHPUnit\Util\TestDox\TextResultPrinter; +use PHPUnit\Util\TestDox\XmlResultPrinter; +use PHPUnit\Util\XdebugFilterScriptGenerator; +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeCoverage\Exception as CodeCoverageException; +use SebastianBergmann\CodeCoverage\Filter as CodeCoverageFilter; +use SebastianBergmann\CodeCoverage\Report\Clover as CloverReport; +use SebastianBergmann\CodeCoverage\Report\Crap4j as Crap4jReport; +use SebastianBergmann\CodeCoverage\Report\Html\Facade as HtmlReport; +use SebastianBergmann\CodeCoverage\Report\PHP as PhpReport; +use SebastianBergmann\CodeCoverage\Report\Text as TextReport; +use SebastianBergmann\CodeCoverage\Report\Xml\Facade as XmlReport; +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Environment\Runtime; +use SebastianBergmann\Invoker\Invoker; +use SebastianBergmann\Timer\Timer; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TestRunner extends BaseTestRunner +{ + public const SUCCESS_EXIT = 0; + + public const FAILURE_EXIT = 1; + + public const EXCEPTION_EXIT = 2; + + /** + * @var bool + */ + private static $versionStringPrinted = false; + + /** + * @var CodeCoverageFilter + */ + private $codeCoverageFilter; + + /** + * @var TestSuiteLoader + */ + private $loader; + + /** + * @psalm-var Printer&TestListener + */ + private $printer; + + /** + * @var Runtime + */ + private $runtime; + + /** + * @var bool + */ + private $messagePrinted = false; + + /** + * @var Hook[] + */ + private $extensions = []; + + public function __construct(TestSuiteLoader $loader = null, CodeCoverageFilter $filter = null) + { + if ($filter === null) { + $filter = new CodeCoverageFilter; + } + + $this->codeCoverageFilter = $filter; + $this->loader = $loader; + $this->runtime = new Runtime; + } + + /** + * @throws \PHPUnit\Runner\Exception + * @throws Exception + */ + public function doRun(Test $suite, array $arguments = [], array $warnings = [], bool $exit = true): TestResult + { + if (isset($arguments['configuration'])) { + $GLOBALS['__PHPUNIT_CONFIGURATION_FILE'] = $arguments['configuration']; + } + + $this->handleConfiguration($arguments); + + if (\is_int($arguments['columns']) && $arguments['columns'] < 16) { + $arguments['columns'] = 16; + $tooFewColumnsRequested = true; + } + + if (isset($arguments['bootstrap'])) { + $GLOBALS['__PHPUNIT_BOOTSTRAP'] = $arguments['bootstrap']; + } + + if ($suite instanceof TestCase || $suite instanceof TestSuite) { + if ($arguments['backupGlobals'] === true) { + $suite->setBackupGlobals(true); + } + + if ($arguments['backupStaticAttributes'] === true) { + $suite->setBackupStaticAttributes(true); + } + + if ($arguments['beStrictAboutChangesToGlobalState'] === true) { + $suite->setBeStrictAboutChangesToGlobalState(true); + } + } + + if ($arguments['executionOrder'] === TestSuiteSorter::ORDER_RANDOMIZED) { + \mt_srand($arguments['randomOrderSeed']); + } + + if ($arguments['cacheResult']) { + if (!isset($arguments['cacheResultFile'])) { + if (isset($arguments['configuration']) && $arguments['configuration'] instanceof Configuration) { + $cacheLocation = $arguments['configuration']->getFilename(); + } else { + $cacheLocation = $_SERVER['PHP_SELF']; + } + + $arguments['cacheResultFile'] = null; + + $cacheResultFile = \realpath($cacheLocation); + + if ($cacheResultFile !== false) { + $arguments['cacheResultFile'] = \dirname($cacheResultFile); + } + } + + $cache = new DefaultTestResultCache($arguments['cacheResultFile']); + + $this->addExtension(new ResultCacheExtension($cache)); + } + + if ($arguments['executionOrder'] !== TestSuiteSorter::ORDER_DEFAULT || $arguments['executionOrderDefects'] !== TestSuiteSorter::ORDER_DEFAULT || $arguments['resolveDependencies']) { + $cache = $cache ?? new NullTestResultCache; + + $cache->load(); + + $sorter = new TestSuiteSorter($cache); + + $sorter->reorderTestsInSuite($suite, $arguments['executionOrder'], $arguments['resolveDependencies'], $arguments['executionOrderDefects']); + $originalExecutionOrder = $sorter->getOriginalExecutionOrder(); + + unset($sorter); + } + + if (\is_int($arguments['repeat']) && $arguments['repeat'] > 0) { + $_suite = new TestSuite; + + /* @noinspection PhpUnusedLocalVariableInspection */ + foreach (\range(1, $arguments['repeat']) as $step) { + $_suite->addTest($suite); + } + + $suite = $_suite; + + unset($_suite); + } + + $result = $this->createTestResult(); + + $listener = new TestListenerAdapter; + $listenerNeeded = false; + + foreach ($this->extensions as $extension) { + if ($extension instanceof TestHook) { + $listener->add($extension); + + $listenerNeeded = true; + } + } + + if ($listenerNeeded) { + $result->addListener($listener); + } + + unset($listener, $listenerNeeded); + + if (!$arguments['convertDeprecationsToExceptions']) { + $result->convertDeprecationsToExceptions(false); + } + + if (!$arguments['convertErrorsToExceptions']) { + $result->convertErrorsToExceptions(false); + } + + if (!$arguments['convertNoticesToExceptions']) { + $result->convertNoticesToExceptions(false); + } + + if (!$arguments['convertWarningsToExceptions']) { + $result->convertWarningsToExceptions(false); + } + + if ($arguments['stopOnError']) { + $result->stopOnError(true); + } + + if ($arguments['stopOnFailure']) { + $result->stopOnFailure(true); + } + + if ($arguments['stopOnWarning']) { + $result->stopOnWarning(true); + } + + if ($arguments['stopOnIncomplete']) { + $result->stopOnIncomplete(true); + } + + if ($arguments['stopOnRisky']) { + $result->stopOnRisky(true); + } + + if ($arguments['stopOnSkipped']) { + $result->stopOnSkipped(true); + } + + if ($arguments['stopOnDefect']) { + $result->stopOnDefect(true); + } + + if ($arguments['registerMockObjectsFromTestArgumentsRecursively']) { + $result->setRegisterMockObjectsFromTestArgumentsRecursively(true); + } + + if ($this->printer === null) { + if (isset($arguments['printer'])) { + if ($arguments['printer'] instanceof Printer && $arguments['printer'] instanceof TestListener) { + $this->printer = $arguments['printer']; + } elseif (\is_string($arguments['printer']) && \class_exists($arguments['printer'], false)) { + try { + new \ReflectionClass($arguments['printer']); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (\is_subclass_of($arguments['printer'], ResultPrinter::class)) { + $this->printer = $this->createPrinter($arguments['printer'], $arguments); + } + } + } else { + $this->printer = $this->createPrinter(ResultPrinter::class, $arguments); + } + } + + if (isset($originalExecutionOrder) && $this->printer instanceof CliTestDoxPrinter) { + \assert($this->printer instanceof CliTestDoxPrinter); + + $this->printer->setOriginalExecutionOrder($originalExecutionOrder); + $this->printer->setShowProgressAnimation(!$arguments['noInteraction']); + } + + $this->printer->write( + Version::getVersionString() . "\n" + ); + + self::$versionStringPrinted = true; + + if ($arguments['verbose']) { + $this->writeMessage('Runtime', $this->runtime->getNameWithVersionAndCodeCoverageDriver()); + + if (isset($arguments['configuration'])) { + $this->writeMessage( + 'Configuration', + $arguments['configuration']->getFilename() + ); + } + + foreach ($arguments['loadedExtensions'] as $extension) { + $this->writeMessage( + 'Extension', + $extension + ); + } + + foreach ($arguments['notLoadedExtensions'] as $extension) { + $this->writeMessage( + 'Extension', + $extension + ); + } + } + + foreach ($warnings as $warning) { + $this->writeMessage('Warning', $warning); + } + + if ($arguments['executionOrder'] === TestSuiteSorter::ORDER_RANDOMIZED) { + $this->writeMessage( + 'Random seed', + (string) $arguments['randomOrderSeed'] + ); + } + + if (isset($tooFewColumnsRequested)) { + $this->writeMessage('Error', 'Less than 16 columns requested, number of columns set to 16'); + } + + if ($this->runtime->discardsComments()) { + $this->writeMessage('Warning', 'opcache.save_comments=0 set; annotations will not work'); + } + + if (isset($arguments['configuration']) && $arguments['configuration']->hasValidationErrors()) { + $this->write( + "\n Warning - The configuration file did not pass validation!\n The following problems have been detected:\n" + ); + + foreach ($arguments['configuration']->getValidationErrors() as $line => $errors) { + $this->write(\sprintf("\n Line %d:\n", $line)); + + foreach ($errors as $msg) { + $this->write(\sprintf(" - %s\n", $msg)); + } + } + + $this->write("\n Test results may not be as expected.\n\n"); + } + + if (isset($arguments['conflictBetweenPrinterClassAndTestdox'])) { + $this->writeMessage('Warning', 'Directives printerClass and testdox are mutually exclusive'); + } + + foreach ($arguments['listeners'] as $listener) { + $result->addListener($listener); + } + + $result->addListener($this->printer); + + $codeCoverageReports = 0; + + if (!isset($arguments['noLogging'])) { + if (isset($arguments['testdoxHTMLFile'])) { + $result->addListener( + new HtmlResultPrinter( + $arguments['testdoxHTMLFile'], + $arguments['testdoxGroups'], + $arguments['testdoxExcludeGroups'] + ) + ); + } + + if (isset($arguments['testdoxTextFile'])) { + $result->addListener( + new TextResultPrinter( + $arguments['testdoxTextFile'], + $arguments['testdoxGroups'], + $arguments['testdoxExcludeGroups'] + ) + ); + } + + if (isset($arguments['testdoxXMLFile'])) { + $result->addListener( + new XmlResultPrinter( + $arguments['testdoxXMLFile'] + ) + ); + } + + if (isset($arguments['teamcityLogfile'])) { + $result->addListener( + new TeamCity($arguments['teamcityLogfile']) + ); + } + + if (isset($arguments['junitLogfile'])) { + $result->addListener( + new JUnit( + $arguments['junitLogfile'], + $arguments['reportUselessTests'] + ) + ); + } + + if (isset($arguments['coverageClover'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageCrap4J'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageHtml'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coveragePHP'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageText'])) { + $codeCoverageReports++; + } + + if (isset($arguments['coverageXml'])) { + $codeCoverageReports++; + } + } + + if (isset($arguments['noCoverage'])) { + $codeCoverageReports = 0; + } + + if ($codeCoverageReports > 0 && !$this->runtime->canCollectCodeCoverage()) { + $this->writeMessage('Error', 'No code coverage driver is available'); + + $codeCoverageReports = 0; + } + + if ($codeCoverageReports > 0 || isset($arguments['xdebugFilterFile'])) { + $whitelistFromConfigurationFile = false; + $whitelistFromOption = false; + + if (isset($arguments['whitelist'])) { + $this->codeCoverageFilter->addDirectoryToWhitelist($arguments['whitelist']); + + $whitelistFromOption = true; + } + + if (isset($arguments['configuration'])) { + $filterConfiguration = $arguments['configuration']->getFilterConfiguration(); + + if (!empty($filterConfiguration['whitelist'])) { + $whitelistFromConfigurationFile = true; + } + + if (!empty($filterConfiguration['whitelist'])) { + foreach ($filterConfiguration['whitelist']['include']['directory'] as $dir) { + $this->codeCoverageFilter->addDirectoryToWhitelist( + $dir['path'], + $dir['suffix'], + $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['include']['file'] as $file) { + $this->codeCoverageFilter->addFileToWhitelist($file); + } + + foreach ($filterConfiguration['whitelist']['exclude']['directory'] as $dir) { + $this->codeCoverageFilter->removeDirectoryFromWhitelist( + $dir['path'], + $dir['suffix'], + $dir['prefix'] + ); + } + + foreach ($filterConfiguration['whitelist']['exclude']['file'] as $file) { + $this->codeCoverageFilter->removeFileFromWhitelist($file); + } + } + } + } + + if ($codeCoverageReports > 0) { + try { + $codeCoverage = new CodeCoverage( + null, + $this->codeCoverageFilter + ); + + $codeCoverage->setUnintentionallyCoveredSubclassesWhitelist( + [Comparator::class] + ); + + $codeCoverage->setCheckForUnintentionallyCoveredCode( + $arguments['strictCoverage'] + ); + + $codeCoverage->setCheckForMissingCoversAnnotation( + $arguments['strictCoverage'] + ); + + if (isset($arguments['forceCoversAnnotation'])) { + $codeCoverage->setForceCoversAnnotation( + $arguments['forceCoversAnnotation'] + ); + } + + if (isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) { + $codeCoverage->setIgnoreDeprecatedCode( + $arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'] + ); + } + + if (isset($arguments['disableCodeCoverageIgnore'])) { + $codeCoverage->setDisableIgnoredLines(true); + } + + if (!empty($filterConfiguration['whitelist'])) { + $codeCoverage->setAddUncoveredFilesFromWhitelist( + $filterConfiguration['whitelist']['addUncoveredFilesFromWhitelist'] + ); + + $codeCoverage->setProcessUncoveredFilesFromWhitelist( + $filterConfiguration['whitelist']['processUncoveredFilesFromWhitelist'] + ); + } + + if (!$this->codeCoverageFilter->hasWhitelist()) { + if (!$whitelistFromConfigurationFile && !$whitelistFromOption) { + $this->writeMessage('Error', 'No whitelist is configured, no code coverage will be generated.'); + } else { + $this->writeMessage('Error', 'Incorrect whitelist config, no code coverage will be generated.'); + } + + $codeCoverageReports = 0; + + unset($codeCoverage); + } + } catch (CodeCoverageException $e) { + $this->writeMessage('Error', $e->getMessage()); + + $codeCoverageReports = 0; + } + } + + if (isset($arguments['xdebugFilterFile'], $filterConfiguration)) { + $this->write("\n"); + + $script = (new XdebugFilterScriptGenerator)->generate($filterConfiguration['whitelist']); + + if ($arguments['xdebugFilterFile'] !== 'php://stdout' && $arguments['xdebugFilterFile'] !== 'php://stderr' && !Filesystem::createDirectory(\dirname($arguments['xdebugFilterFile']))) { + $this->write(\sprintf('Cannot write Xdebug filter script to %s ' . \PHP_EOL, $arguments['xdebugFilterFile'])); + + exit(self::EXCEPTION_EXIT); + } + + \file_put_contents($arguments['xdebugFilterFile'], $script); + + $this->write(\sprintf('Wrote Xdebug filter script to %s ' . \PHP_EOL, $arguments['xdebugFilterFile'])); + + exit(self::SUCCESS_EXIT); + } + + $this->printer->write("\n"); + + if (isset($codeCoverage)) { + $result->setCodeCoverage($codeCoverage); + + if ($codeCoverageReports > 1 && isset($arguments['cacheTokens'])) { + $codeCoverage->setCacheTokens($arguments['cacheTokens']); + } + } + + $result->beStrictAboutTestsThatDoNotTestAnything($arguments['reportUselessTests']); + $result->beStrictAboutOutputDuringTests($arguments['disallowTestOutput']); + $result->beStrictAboutTodoAnnotatedTests($arguments['disallowTodoAnnotatedTests']); + $result->beStrictAboutResourceUsageDuringSmallTests($arguments['beStrictAboutResourceUsageDuringSmallTests']); + + if ($arguments['enforceTimeLimit'] === true) { + if (!\class_exists(Invoker::class)) { + $this->writeMessage('Error', 'Package phpunit/php-invoker is required for enforcing time limits'); + } + + if (!\extension_loaded('pcntl') || \strpos(\ini_get('disable_functions'), 'pcntl') !== false) { + $this->writeMessage('Error', 'PHP extension pcntl is required for enforcing time limits'); + } + } + $result->enforceTimeLimit($arguments['enforceTimeLimit']); + $result->setDefaultTimeLimit($arguments['defaultTimeLimit']); + $result->setTimeoutForSmallTests($arguments['timeoutForSmallTests']); + $result->setTimeoutForMediumTests($arguments['timeoutForMediumTests']); + $result->setTimeoutForLargeTests($arguments['timeoutForLargeTests']); + + if ($suite instanceof TestSuite) { + $this->processSuiteFilters($suite, $arguments); + $suite->setRunTestInSeparateProcess($arguments['processIsolation']); + } + + foreach ($this->extensions as $extension) { + if ($extension instanceof BeforeFirstTestHook) { + $extension->executeBeforeFirstTest(); + } + } + + $suite->run($result); + + foreach ($this->extensions as $extension) { + if ($extension instanceof AfterLastTestHook) { + $extension->executeAfterLastTest(); + } + } + + $result->flushListeners(); + + if ($this->printer instanceof ResultPrinter) { + $this->printer->printResult($result); + } + + if (isset($codeCoverage)) { + if (isset($arguments['coverageClover'])) { + $this->codeCoverageGenerationStart('Clover XML'); + + try { + $writer = new CloverReport; + $writer->process($codeCoverage, $arguments['coverageClover']); + + $this->codeCoverageGenerationSucceeded(); + + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($e); + } + } + + if (isset($arguments['coverageCrap4J'])) { + $this->codeCoverageGenerationStart('Crap4J XML'); + + try { + $writer = new Crap4jReport($arguments['crap4jThreshold']); + $writer->process($codeCoverage, $arguments['coverageCrap4J']); + + $this->codeCoverageGenerationSucceeded(); + + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($e); + } + } + + if (isset($arguments['coverageHtml'])) { + $this->codeCoverageGenerationStart('HTML'); + + try { + $writer = new HtmlReport( + $arguments['reportLowUpperBound'], + $arguments['reportHighLowerBound'], + \sprintf( + ' and PHPUnit %s', + Version::id() + ) + ); + + $writer->process($codeCoverage, $arguments['coverageHtml']); + + $this->codeCoverageGenerationSucceeded(); + + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($e); + } + } + + if (isset($arguments['coveragePHP'])) { + $this->codeCoverageGenerationStart('PHP'); + + try { + $writer = new PhpReport; + $writer->process($codeCoverage, $arguments['coveragePHP']); + + $this->codeCoverageGenerationSucceeded(); + + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($e); + } + } + + if (isset($arguments['coverageText'])) { + if ($arguments['coverageText'] === 'php://stdout') { + $outputStream = $this->printer; + $colors = $arguments['colors'] && $arguments['colors'] !== ResultPrinter::COLOR_NEVER; + } else { + $outputStream = new Printer($arguments['coverageText']); + $colors = false; + } + + $processor = new TextReport( + $arguments['reportLowUpperBound'], + $arguments['reportHighLowerBound'], + $arguments['coverageTextShowUncoveredFiles'], + $arguments['coverageTextShowOnlySummary'] + ); + + $outputStream->write( + $processor->process($codeCoverage, $colors) + ); + } + + if (isset($arguments['coverageXml'])) { + $this->codeCoverageGenerationStart('PHPUnit XML'); + + try { + $writer = new XmlReport(Version::id()); + $writer->process($codeCoverage, $arguments['coverageXml']); + + $this->codeCoverageGenerationSucceeded(); + + unset($writer); + } catch (CodeCoverageException $e) { + $this->codeCoverageGenerationFailed($e); + } + } + } + + if ($exit) { + if ($result->wasSuccessfulIgnoringWarnings()) { + if ($arguments['failOnRisky'] && !$result->allHarmless()) { + exit(self::FAILURE_EXIT); + } + + if ($arguments['failOnWarning'] && $result->warningCount() > 0) { + exit(self::FAILURE_EXIT); + } + + exit(self::SUCCESS_EXIT); + } + + if ($result->errorCount() > 0) { + exit(self::EXCEPTION_EXIT); + } + + if ($result->failureCount() > 0) { + exit(self::FAILURE_EXIT); + } + } + + return $result; + } + + public function setPrinter(ResultPrinter $resultPrinter): void + { + $this->printer = $resultPrinter; + } + + /** + * Returns the loader to be used. + */ + public function getLoader(): TestSuiteLoader + { + if ($this->loader === null) { + $this->loader = new StandardTestSuiteLoader; + } + + return $this->loader; + } + + public function addExtension(Hook $extension): void + { + $this->extensions[] = $extension; + } + + /** + * Override to define how to handle a failed loading of + * a test suite. + */ + protected function runFailed(string $message): void + { + $this->write($message . \PHP_EOL); + + exit(self::FAILURE_EXIT); + } + + private function createTestResult(): TestResult + { + return new TestResult; + } + + private function write(string $buffer): void + { + if (\PHP_SAPI !== 'cli' && \PHP_SAPI !== 'phpdbg') { + $buffer = \htmlspecialchars($buffer); + } + + if ($this->printer !== null) { + $this->printer->write($buffer); + } else { + print $buffer; + } + } + + /** + * @throws Exception + */ + private function handleConfiguration(array &$arguments): void + { + if (isset($arguments['configuration']) && + !$arguments['configuration'] instanceof Configuration) { + $arguments['configuration'] = Configuration::getInstance( + $arguments['configuration'] + ); + } + + $arguments['debug'] = $arguments['debug'] ?? false; + $arguments['filter'] = $arguments['filter'] ?? false; + $arguments['listeners'] = $arguments['listeners'] ?? []; + + if (isset($arguments['configuration'])) { + $arguments['configuration']->handlePHPConfiguration(); + + $phpunitConfiguration = $arguments['configuration']->getPHPUnitConfiguration(); + + if (isset($phpunitConfiguration['backupGlobals']) && !isset($arguments['backupGlobals'])) { + $arguments['backupGlobals'] = $phpunitConfiguration['backupGlobals']; + } + + if (isset($phpunitConfiguration['backupStaticAttributes']) && !isset($arguments['backupStaticAttributes'])) { + $arguments['backupStaticAttributes'] = $phpunitConfiguration['backupStaticAttributes']; + } + + if (isset($phpunitConfiguration['beStrictAboutChangesToGlobalState']) && !isset($arguments['beStrictAboutChangesToGlobalState'])) { + $arguments['beStrictAboutChangesToGlobalState'] = $phpunitConfiguration['beStrictAboutChangesToGlobalState']; + } + + if (isset($phpunitConfiguration['bootstrap']) && !isset($arguments['bootstrap'])) { + $arguments['bootstrap'] = $phpunitConfiguration['bootstrap']; + } + + if (isset($phpunitConfiguration['cacheResult']) && !isset($arguments['cacheResult'])) { + $arguments['cacheResult'] = $phpunitConfiguration['cacheResult']; + } + + if (isset($phpunitConfiguration['cacheResultFile']) && !isset($arguments['cacheResultFile'])) { + $arguments['cacheResultFile'] = $phpunitConfiguration['cacheResultFile']; + } + + if (isset($phpunitConfiguration['cacheTokens']) && !isset($arguments['cacheTokens'])) { + $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens']; + } + + if (isset($phpunitConfiguration['cacheTokens']) && !isset($arguments['cacheTokens'])) { + $arguments['cacheTokens'] = $phpunitConfiguration['cacheTokens']; + } + + if (isset($phpunitConfiguration['colors']) && !isset($arguments['colors'])) { + $arguments['colors'] = $phpunitConfiguration['colors']; + } + + if (isset($phpunitConfiguration['convertDeprecationsToExceptions']) && !isset($arguments['convertDeprecationsToExceptions'])) { + $arguments['convertDeprecationsToExceptions'] = $phpunitConfiguration['convertDeprecationsToExceptions']; + } + + if (isset($phpunitConfiguration['convertErrorsToExceptions']) && !isset($arguments['convertErrorsToExceptions'])) { + $arguments['convertErrorsToExceptions'] = $phpunitConfiguration['convertErrorsToExceptions']; + } + + if (isset($phpunitConfiguration['convertNoticesToExceptions']) && !isset($arguments['convertNoticesToExceptions'])) { + $arguments['convertNoticesToExceptions'] = $phpunitConfiguration['convertNoticesToExceptions']; + } + + if (isset($phpunitConfiguration['convertWarningsToExceptions']) && !isset($arguments['convertWarningsToExceptions'])) { + $arguments['convertWarningsToExceptions'] = $phpunitConfiguration['convertWarningsToExceptions']; + } + + if (isset($phpunitConfiguration['processIsolation']) && !isset($arguments['processIsolation'])) { + $arguments['processIsolation'] = $phpunitConfiguration['processIsolation']; + } + + if (isset($phpunitConfiguration['stopOnDefect']) && !isset($arguments['stopOnDefect'])) { + $arguments['stopOnDefect'] = $phpunitConfiguration['stopOnDefect']; + } + + if (isset($phpunitConfiguration['stopOnError']) && !isset($arguments['stopOnError'])) { + $arguments['stopOnError'] = $phpunitConfiguration['stopOnError']; + } + + if (isset($phpunitConfiguration['stopOnFailure']) && !isset($arguments['stopOnFailure'])) { + $arguments['stopOnFailure'] = $phpunitConfiguration['stopOnFailure']; + } + + if (isset($phpunitConfiguration['stopOnWarning']) && !isset($arguments['stopOnWarning'])) { + $arguments['stopOnWarning'] = $phpunitConfiguration['stopOnWarning']; + } + + if (isset($phpunitConfiguration['stopOnIncomplete']) && !isset($arguments['stopOnIncomplete'])) { + $arguments['stopOnIncomplete'] = $phpunitConfiguration['stopOnIncomplete']; + } + + if (isset($phpunitConfiguration['stopOnRisky']) && !isset($arguments['stopOnRisky'])) { + $arguments['stopOnRisky'] = $phpunitConfiguration['stopOnRisky']; + } + + if (isset($phpunitConfiguration['stopOnSkipped']) && !isset($arguments['stopOnSkipped'])) { + $arguments['stopOnSkipped'] = $phpunitConfiguration['stopOnSkipped']; + } + + if (isset($phpunitConfiguration['failOnWarning']) && !isset($arguments['failOnWarning'])) { + $arguments['failOnWarning'] = $phpunitConfiguration['failOnWarning']; + } + + if (isset($phpunitConfiguration['failOnRisky']) && !isset($arguments['failOnRisky'])) { + $arguments['failOnRisky'] = $phpunitConfiguration['failOnRisky']; + } + + if (isset($phpunitConfiguration['timeoutForSmallTests']) && !isset($arguments['timeoutForSmallTests'])) { + $arguments['timeoutForSmallTests'] = $phpunitConfiguration['timeoutForSmallTests']; + } + + if (isset($phpunitConfiguration['timeoutForMediumTests']) && !isset($arguments['timeoutForMediumTests'])) { + $arguments['timeoutForMediumTests'] = $phpunitConfiguration['timeoutForMediumTests']; + } + + if (isset($phpunitConfiguration['timeoutForLargeTests']) && !isset($arguments['timeoutForLargeTests'])) { + $arguments['timeoutForLargeTests'] = $phpunitConfiguration['timeoutForLargeTests']; + } + + if (isset($phpunitConfiguration['reportUselessTests']) && !isset($arguments['reportUselessTests'])) { + $arguments['reportUselessTests'] = $phpunitConfiguration['reportUselessTests']; + } + + if (isset($phpunitConfiguration['strictCoverage']) && !isset($arguments['strictCoverage'])) { + $arguments['strictCoverage'] = $phpunitConfiguration['strictCoverage']; + } + + if (isset($phpunitConfiguration['ignoreDeprecatedCodeUnitsFromCodeCoverage']) && !isset($arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'])) { + $arguments['ignoreDeprecatedCodeUnitsFromCodeCoverage'] = $phpunitConfiguration['ignoreDeprecatedCodeUnitsFromCodeCoverage']; + } + + if (isset($phpunitConfiguration['disallowTestOutput']) && !isset($arguments['disallowTestOutput'])) { + $arguments['disallowTestOutput'] = $phpunitConfiguration['disallowTestOutput']; + } + + if (isset($phpunitConfiguration['defaultTimeLimit']) && !isset($arguments['defaultTimeLimit'])) { + $arguments['defaultTimeLimit'] = $phpunitConfiguration['defaultTimeLimit']; + } + + if (isset($phpunitConfiguration['enforceTimeLimit']) && !isset($arguments['enforceTimeLimit'])) { + $arguments['enforceTimeLimit'] = $phpunitConfiguration['enforceTimeLimit']; + } + + if (isset($phpunitConfiguration['disallowTodoAnnotatedTests']) && !isset($arguments['disallowTodoAnnotatedTests'])) { + $arguments['disallowTodoAnnotatedTests'] = $phpunitConfiguration['disallowTodoAnnotatedTests']; + } + + if (isset($phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']) && !isset($arguments['beStrictAboutResourceUsageDuringSmallTests'])) { + $arguments['beStrictAboutResourceUsageDuringSmallTests'] = $phpunitConfiguration['beStrictAboutResourceUsageDuringSmallTests']; + } + + if (isset($phpunitConfiguration['verbose']) && !isset($arguments['verbose'])) { + $arguments['verbose'] = $phpunitConfiguration['verbose']; + } + + if (isset($phpunitConfiguration['reverseDefectList']) && !isset($arguments['reverseList'])) { + $arguments['reverseList'] = $phpunitConfiguration['reverseDefectList']; + } + + if (isset($phpunitConfiguration['forceCoversAnnotation']) && !isset($arguments['forceCoversAnnotation'])) { + $arguments['forceCoversAnnotation'] = $phpunitConfiguration['forceCoversAnnotation']; + } + + if (isset($phpunitConfiguration['disableCodeCoverageIgnore']) && !isset($arguments['disableCodeCoverageIgnore'])) { + $arguments['disableCodeCoverageIgnore'] = $phpunitConfiguration['disableCodeCoverageIgnore']; + } + + if (isset($phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']) && !isset($arguments['registerMockObjectsFromTestArgumentsRecursively'])) { + $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $phpunitConfiguration['registerMockObjectsFromTestArgumentsRecursively']; + } + + if (isset($phpunitConfiguration['executionOrder']) && !isset($arguments['executionOrder'])) { + $arguments['executionOrder'] = $phpunitConfiguration['executionOrder']; + } + + if (isset($phpunitConfiguration['executionOrderDefects']) && !isset($arguments['executionOrderDefects'])) { + $arguments['executionOrderDefects'] = $phpunitConfiguration['executionOrderDefects']; + } + + if (isset($phpunitConfiguration['resolveDependencies']) && !isset($arguments['resolveDependencies'])) { + $arguments['resolveDependencies'] = $phpunitConfiguration['resolveDependencies']; + } + + if (isset($phpunitConfiguration['noInteraction']) && !isset($arguments['noInteraction'])) { + $arguments['noInteraction'] = $phpunitConfiguration['noInteraction']; + } + + if (isset($phpunitConfiguration['conflictBetweenPrinterClassAndTestdox'])) { + $arguments['conflictBetweenPrinterClassAndTestdox'] = true; + } + + $groupCliArgs = []; + + if (!empty($arguments['groups'])) { + $groupCliArgs = $arguments['groups']; + } + + $groupConfiguration = $arguments['configuration']->getGroupConfiguration(); + + if (!empty($groupConfiguration['include']) && !isset($arguments['groups'])) { + $arguments['groups'] = $groupConfiguration['include']; + } + + if (!empty($groupConfiguration['exclude']) && !isset($arguments['excludeGroups'])) { + $arguments['excludeGroups'] = \array_diff($groupConfiguration['exclude'], $groupCliArgs); + } + + foreach ($arguments['configuration']->getExtensionConfiguration() as $extension) { + if ($extension['file'] !== '' && !\class_exists($extension['class'], false)) { + require_once $extension['file']; + } + + if (!\class_exists($extension['class'])) { + throw new Exception( + \sprintf( + 'Class "%s" does not exist', + $extension['class'] + ) + ); + } + + try { + $extensionClass = new \ReflectionClass($extension['class']); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$extensionClass->implementsInterface(Hook::class)) { + throw new Exception( + \sprintf( + 'Class "%s" does not implement a PHPUnit\Runner\Hook interface', + $extension['class'] + ) + ); + } + + if (\count($extension['arguments']) === 0) { + $extensionObject = $extensionClass->newInstance(); + } else { + $extensionObject = $extensionClass->newInstanceArgs( + $extension['arguments'] + ); + } + + \assert($extensionObject instanceof Hook); + + $this->addExtension($extensionObject); + } + + foreach ($arguments['configuration']->getListenerConfiguration() as $listener) { + if ($listener['file'] !== '' && !\class_exists($listener['class'], false)) { + require_once $listener['file']; + } + + if (!\class_exists($listener['class'])) { + throw new Exception( + \sprintf( + 'Class "%s" does not exist', + $listener['class'] + ) + ); + } + + try { + $listenerClass = new \ReflectionClass($listener['class']); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + if (!$listenerClass->implementsInterface(TestListener::class)) { + throw new Exception( + \sprintf( + 'Class "%s" does not implement the PHPUnit\Framework\TestListener interface', + $listener['class'] + ) + ); + } + + if (\count($listener['arguments']) === 0) { + $listener = new $listener['class']; + } else { + $listener = $listenerClass->newInstanceArgs( + $listener['arguments'] + ); + } + + $arguments['listeners'][] = $listener; + } + + $loggingConfiguration = $arguments['configuration']->getLoggingConfiguration(); + + if (isset($loggingConfiguration['coverage-clover']) && !isset($arguments['coverageClover'])) { + $arguments['coverageClover'] = $loggingConfiguration['coverage-clover']; + } + + if (isset($loggingConfiguration['coverage-crap4j']) && !isset($arguments['coverageCrap4J'])) { + $arguments['coverageCrap4J'] = $loggingConfiguration['coverage-crap4j']; + + if (isset($loggingConfiguration['crap4jThreshold']) && !isset($arguments['crap4jThreshold'])) { + $arguments['crap4jThreshold'] = $loggingConfiguration['crap4jThreshold']; + } + } + + if (isset($loggingConfiguration['coverage-html']) && !isset($arguments['coverageHtml'])) { + if (isset($loggingConfiguration['lowUpperBound']) && !isset($arguments['reportLowUpperBound'])) { + $arguments['reportLowUpperBound'] = $loggingConfiguration['lowUpperBound']; + } + + if (isset($loggingConfiguration['highLowerBound']) && !isset($arguments['reportHighLowerBound'])) { + $arguments['reportHighLowerBound'] = $loggingConfiguration['highLowerBound']; + } + + $arguments['coverageHtml'] = $loggingConfiguration['coverage-html']; + } + + if (isset($loggingConfiguration['coverage-php']) && !isset($arguments['coveragePHP'])) { + $arguments['coveragePHP'] = $loggingConfiguration['coverage-php']; + } + + if (isset($loggingConfiguration['coverage-text']) && !isset($arguments['coverageText'])) { + $arguments['coverageText'] = $loggingConfiguration['coverage-text']; + $arguments['coverageTextShowUncoveredFiles'] = $loggingConfiguration['coverageTextShowUncoveredFiles'] ?? false; + $arguments['coverageTextShowOnlySummary'] = $loggingConfiguration['coverageTextShowOnlySummary'] ?? false; + } + + if (isset($loggingConfiguration['coverage-xml']) && !isset($arguments['coverageXml'])) { + $arguments['coverageXml'] = $loggingConfiguration['coverage-xml']; + } + + if (isset($loggingConfiguration['plain'])) { + $arguments['listeners'][] = new ResultPrinter( + $loggingConfiguration['plain'], + true + ); + } + + if (isset($loggingConfiguration['teamcity']) && !isset($arguments['teamcityLogfile'])) { + $arguments['teamcityLogfile'] = $loggingConfiguration['teamcity']; + } + + if (isset($loggingConfiguration['junit']) && !isset($arguments['junitLogfile'])) { + $arguments['junitLogfile'] = $loggingConfiguration['junit']; + } + + if (isset($loggingConfiguration['testdox-html']) && !isset($arguments['testdoxHTMLFile'])) { + $arguments['testdoxHTMLFile'] = $loggingConfiguration['testdox-html']; + } + + if (isset($loggingConfiguration['testdox-text']) && !isset($arguments['testdoxTextFile'])) { + $arguments['testdoxTextFile'] = $loggingConfiguration['testdox-text']; + } + + if (isset($loggingConfiguration['testdox-xml']) && !isset($arguments['testdoxXMLFile'])) { + $arguments['testdoxXMLFile'] = $loggingConfiguration['testdox-xml']; + } + + $testdoxGroupConfiguration = $arguments['configuration']->getTestdoxGroupConfiguration(); + + if (isset($testdoxGroupConfiguration['include']) && + !isset($arguments['testdoxGroups'])) { + $arguments['testdoxGroups'] = $testdoxGroupConfiguration['include']; + } + + if (isset($testdoxGroupConfiguration['exclude']) && + !isset($arguments['testdoxExcludeGroups'])) { + $arguments['testdoxExcludeGroups'] = $testdoxGroupConfiguration['exclude']; + } + } + + $arguments['addUncoveredFilesFromWhitelist'] = $arguments['addUncoveredFilesFromWhitelist'] ?? true; + $arguments['backupGlobals'] = $arguments['backupGlobals'] ?? null; + $arguments['backupStaticAttributes'] = $arguments['backupStaticAttributes'] ?? null; + $arguments['beStrictAboutChangesToGlobalState'] = $arguments['beStrictAboutChangesToGlobalState'] ?? null; + $arguments['beStrictAboutResourceUsageDuringSmallTests'] = $arguments['beStrictAboutResourceUsageDuringSmallTests'] ?? false; + $arguments['cacheResult'] = $arguments['cacheResult'] ?? true; + $arguments['cacheTokens'] = $arguments['cacheTokens'] ?? false; + $arguments['colors'] = $arguments['colors'] ?? ResultPrinter::COLOR_DEFAULT; + $arguments['columns'] = $arguments['columns'] ?? 80; + $arguments['convertDeprecationsToExceptions'] = $arguments['convertDeprecationsToExceptions'] ?? true; + $arguments['convertErrorsToExceptions'] = $arguments['convertErrorsToExceptions'] ?? true; + $arguments['convertNoticesToExceptions'] = $arguments['convertNoticesToExceptions'] ?? true; + $arguments['convertWarningsToExceptions'] = $arguments['convertWarningsToExceptions'] ?? true; + $arguments['crap4jThreshold'] = $arguments['crap4jThreshold'] ?? 30; + $arguments['disallowTestOutput'] = $arguments['disallowTestOutput'] ?? false; + $arguments['disallowTodoAnnotatedTests'] = $arguments['disallowTodoAnnotatedTests'] ?? false; + $arguments['defaultTimeLimit'] = $arguments['defaultTimeLimit'] ?? 0; + $arguments['enforceTimeLimit'] = $arguments['enforceTimeLimit'] ?? false; + $arguments['excludeGroups'] = $arguments['excludeGroups'] ?? []; + $arguments['executionOrder'] = $arguments['executionOrder'] ?? TestSuiteSorter::ORDER_DEFAULT; + $arguments['executionOrderDefects'] = $arguments['executionOrderDefects'] ?? TestSuiteSorter::ORDER_DEFAULT; + $arguments['failOnRisky'] = $arguments['failOnRisky'] ?? false; + $arguments['failOnWarning'] = $arguments['failOnWarning'] ?? false; + $arguments['groups'] = $arguments['groups'] ?? []; + $arguments['noInteraction'] = $arguments['noInteraction'] ?? false; + $arguments['processIsolation'] = $arguments['processIsolation'] ?? false; + $arguments['processUncoveredFilesFromWhitelist'] = $arguments['processUncoveredFilesFromWhitelist'] ?? false; + $arguments['randomOrderSeed'] = $arguments['randomOrderSeed'] ?? \time(); + $arguments['registerMockObjectsFromTestArgumentsRecursively'] = $arguments['registerMockObjectsFromTestArgumentsRecursively'] ?? false; + $arguments['repeat'] = $arguments['repeat'] ?? false; + $arguments['reportHighLowerBound'] = $arguments['reportHighLowerBound'] ?? 90; + $arguments['reportLowUpperBound'] = $arguments['reportLowUpperBound'] ?? 50; + $arguments['reportUselessTests'] = $arguments['reportUselessTests'] ?? true; + $arguments['reverseList'] = $arguments['reverseList'] ?? false; + $arguments['resolveDependencies'] = $arguments['resolveDependencies'] ?? true; + $arguments['stopOnError'] = $arguments['stopOnError'] ?? false; + $arguments['stopOnFailure'] = $arguments['stopOnFailure'] ?? false; + $arguments['stopOnIncomplete'] = $arguments['stopOnIncomplete'] ?? false; + $arguments['stopOnRisky'] = $arguments['stopOnRisky'] ?? false; + $arguments['stopOnSkipped'] = $arguments['stopOnSkipped'] ?? false; + $arguments['stopOnWarning'] = $arguments['stopOnWarning'] ?? false; + $arguments['stopOnDefect'] = $arguments['stopOnDefect'] ?? false; + $arguments['strictCoverage'] = $arguments['strictCoverage'] ?? false; + $arguments['testdoxExcludeGroups'] = $arguments['testdoxExcludeGroups'] ?? []; + $arguments['testdoxGroups'] = $arguments['testdoxGroups'] ?? []; + $arguments['timeoutForLargeTests'] = $arguments['timeoutForLargeTests'] ?? 60; + $arguments['timeoutForMediumTests'] = $arguments['timeoutForMediumTests'] ?? 10; + $arguments['timeoutForSmallTests'] = $arguments['timeoutForSmallTests'] ?? 1; + $arguments['verbose'] = $arguments['verbose'] ?? false; + } + + private function processSuiteFilters(TestSuite $suite, array $arguments): void + { + if (!$arguments['filter'] && + empty($arguments['groups']) && + empty($arguments['excludeGroups'])) { + return; + } + + $filterFactory = new Factory; + + if (!empty($arguments['excludeGroups'])) { + $filterFactory->addFilter( + new \ReflectionClass(ExcludeGroupFilterIterator::class), + $arguments['excludeGroups'] + ); + } + + if (!empty($arguments['groups'])) { + $filterFactory->addFilter( + new \ReflectionClass(IncludeGroupFilterIterator::class), + $arguments['groups'] + ); + } + + if ($arguments['filter']) { + $filterFactory->addFilter( + new \ReflectionClass(NameFilterIterator::class), + $arguments['filter'] + ); + } + + $suite->injectFilter($filterFactory); + } + + private function writeMessage(string $type, string $message): void + { + if (!$this->messagePrinted) { + $this->write("\n"); + } + + $this->write( + \sprintf( + "%-15s%s\n", + $type . ':', + $message + ) + ); + + $this->messagePrinted = true; + } + + /** + * @template T as Printer + * + * @param class-string $class + * + * @return T + */ + private function createPrinter(string $class, array $arguments): Printer + { + return new $class( + (isset($arguments['stderr']) && $arguments['stderr'] === true) ? 'php://stderr' : null, + $arguments['verbose'], + $arguments['colors'], + $arguments['debug'], + $arguments['columns'], + $arguments['reverseList'] + ); + } + + private function codeCoverageGenerationStart(string $format): void + { + $this->printer->write( + \sprintf( + "\nGenerating code coverage report in %s format ... ", + $format + ) + ); + + Timer::start(); + } + + private function codeCoverageGenerationSucceeded(): void + { + $this->printer->write( + \sprintf( + "done [%s]\n", + Timer::secondsToTimeString(Timer::stop()) + ) + ); + } + + private function codeCoverageGenerationFailed(\Exception $e): void + { + $this->printer->write( + \sprintf( + "failed [%s]\n%s\n", + Timer::secondsToTimeString(Timer::stop()), + $e->getMessage() + ) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php b/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php new file mode 100644 index 0000000..e1cc484 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Annotation/DocBlock.php @@ -0,0 +1,578 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\Annotation; + +use PharIo\Version\VersionConstraintParser; +use PHPUnit\Framework\InvalidDataProviderException; +use PHPUnit\Framework\SkippedTestError; +use PHPUnit\Framework\Warning; +use PHPUnit\Util\Exception; +use PHPUnit\Util\InvalidDataSetException; + +/** + * This is an abstraction around a PHPUnit-specific docBlock, + * allowing us to ask meaningful questions about a specific + * reflection symbol. + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class DocBlock +{ + /** + * @todo This constant should be private (it's public because of TestTest::testGetProvidedDataRegEx) + */ + public const REGEX_DATA_PROVIDER = '/@dataProvider\s+([a-zA-Z0-9._:-\\\\x7f-\xff]+)/'; + + private const REGEX_REQUIRES_VERSION = '/@requires\s+(?PPHP(?:Unit)?)\s+(?P[<>=!]{0,2})\s*(?P[\d\.-]+(dev|(RC|alpha|beta)[\d\.])?)[ \t]*\r?$/m'; + + private const REGEX_REQUIRES_VERSION_CONSTRAINT = '/@requires\s+(?PPHP(?:Unit)?)\s+(?P[\d\t \-.|~^]+)[ \t]*\r?$/m'; + + private const REGEX_REQUIRES_OS = '/@requires\s+(?POS(?:FAMILY)?)\s+(?P.+?)[ \t]*\r?$/m'; + + private const REGEX_REQUIRES_SETTING = '/@requires\s+(?Psetting)\s+(?P([^ ]+?))\s*(?P[\w\.-]+[\w\.]?)?[ \t]*\r?$/m'; + + private const REGEX_REQUIRES = '/@requires\s+(?Pfunction|extension)\s+(?P([^\s<>=!]+))\s*(?P[<>=!]{0,2})\s*(?P[\d\.-]+[\d\.]?)?[ \t]*\r?$/m'; + + private const REGEX_TEST_WITH = '/@testWith\s+/'; + + private const REGEX_EXPECTED_EXCEPTION = '(@expectedException\s+([:.\w\\\\x7f-\xff]+)(?:[\t ]+(\S*))?(?:[\t ]+(\S*))?\s*$)m'; + + /** @var string */ + private $docComment; + + /** @var bool */ + private $isMethod; + + /** @var array> pre-parsed annotations indexed by name and occurrence index */ + private $symbolAnnotations; + + /** + * @var null|array + * + * @psalm-var null|(array{ + * __OFFSET: array&array{__FILE: string}, + * setting?: array, + * extension_versions?: array + * }&array< + * string, + * string|array{version: string, operator: string}|array{constraint: string}|array + * >) + */ + private $parsedRequirements; + + /** @var int */ + private $startLine; + + /** @var int */ + private $endLine; + + /** @var string */ + private $fileName; + + /** @var string */ + private $name; + + /** + * @var string + * + * @psalm-var class-string + */ + private $className; + + public static function ofClass(\ReflectionClass $class): self + { + $className = $class->getName(); + + return new self( + (string) $class->getDocComment(), + false, + self::extractAnnotationsFromReflector($class), + $class->getStartLine(), + $class->getEndLine(), + $class->getFileName(), + $className, + $className + ); + } + + /** + * @psalm-param class-string $classNameInHierarchy + */ + public static function ofMethod(\ReflectionMethod $method, string $classNameInHierarchy): self + { + return new self( + (string) $method->getDocComment(), + true, + self::extractAnnotationsFromReflector($method), + $method->getStartLine(), + $method->getEndLine(), + $method->getFileName(), + $method->getName(), + $classNameInHierarchy + ); + } + + /** + * Note: we do not preserve an instance of the reflection object, since it cannot be safely (de-)serialized. + * + * @param array> $symbolAnnotations + * + * @psalm-param class-string $className + */ + private function __construct(string $docComment, bool $isMethod, array $symbolAnnotations, int $startLine, int $endLine, string $fileName, string $name, string $className) + { + $this->docComment = $docComment; + $this->isMethod = $isMethod; + $this->symbolAnnotations = $symbolAnnotations; + $this->startLine = $startLine; + $this->endLine = $endLine; + $this->fileName = $fileName; + $this->name = $name; + $this->className = $className; + } + + /** + * @psalm-return array{ + * __OFFSET: array&array{__FILE: string}, + * setting?: array, + * extension_versions?: array + * }&array< + * string, + * string|array{version: string, operator: string}|array{constraint: string}|array + * > + * + * @throws Warning if the requirements version constraint is not well-formed + */ + public function requirements(): array + { + if ($this->parsedRequirements !== null) { + return $this->parsedRequirements; + } + + $offset = $this->startLine; + $requires = []; + $recordedSettings = []; + $extensionVersions = []; + $recordedOffsets = [ + '__FILE' => \realpath($this->fileName), + ]; + + // Split docblock into lines and rewind offset to start of docblock + $lines = \preg_split('/\r\n|\r|\n/', $this->docComment); + $offset -= \count($lines); + + foreach ($lines as $line) { + if (\preg_match(self::REGEX_REQUIRES_OS, $line, $matches)) { + $requires[$matches['name']] = $matches['value']; + $recordedOffsets[$matches['name']] = $offset; + } + + if (\preg_match(self::REGEX_REQUIRES_VERSION, $line, $matches)) { + $requires[$matches['name']] = [ + 'version' => $matches['version'], + 'operator' => $matches['operator'], + ]; + $recordedOffsets[$matches['name']] = $offset; + } + + if (\preg_match(self::REGEX_REQUIRES_VERSION_CONSTRAINT, $line, $matches)) { + if (!empty($requires[$matches['name']])) { + $offset++; + + continue; + } + + try { + $versionConstraintParser = new VersionConstraintParser; + + $requires[$matches['name'] . '_constraint'] = [ + 'constraint' => $versionConstraintParser->parse(\trim($matches['constraint'])), + ]; + $recordedOffsets[$matches['name'] . '_constraint'] = $offset; + } catch (\PharIo\Version\Exception $e) { + /* @TODO this catch is currently not valid, see https://github.com/phar-io/version/issues/16 */ + throw new Warning($e->getMessage(), $e->getCode(), $e); + } + } + + if (\preg_match(self::REGEX_REQUIRES_SETTING, $line, $matches)) { + $recordedSettings[$matches['setting']] = $matches['value']; + $recordedOffsets['__SETTING_' . $matches['setting']] = $offset; + } + + if (\preg_match(self::REGEX_REQUIRES, $line, $matches)) { + $name = $matches['name'] . 's'; + + if (!isset($requires[$name])) { + $requires[$name] = []; + } + + $requires[$name][] = $matches['value']; + $recordedOffsets[$matches['name'] . '_' . $matches['value']] = $offset; + + if ($name === 'extensions' && !empty($matches['version'])) { + $extensionVersions[$matches['value']] = [ + 'version' => $matches['version'], + 'operator' => $matches['operator'], + ]; + } + } + + $offset++; + } + + return $this->parsedRequirements = \array_merge( + $requires, + ['__OFFSET' => $recordedOffsets], + \array_filter([ + 'setting' => $recordedSettings, + 'extension_versions' => $extensionVersions, + ]) + ); + } + + /** + * @return array|bool + * + * @psalm-return false|array{ + * class: class-string, + * code: int|string|null, + * message: string, + * message_regex: string + * } + */ + public function expectedException() + { + $docComment = (string) \substr($this->docComment, 3, -2); + + if (1 !== \preg_match(self::REGEX_EXPECTED_EXCEPTION, $docComment, $matches)) { + return false; + } + + /** @psalm-var class-string $class */ + $class = $matches[1]; + $annotations = $this->symbolAnnotations(); + $code = null; + $message = ''; + $messageRegExp = ''; + + if (isset($matches[2])) { + $message = \trim($matches[2]); + } elseif (isset($annotations['expectedExceptionMessage'])) { + $message = $this->parseAnnotationContent($annotations['expectedExceptionMessage'][0]); + } + + if (isset($annotations['expectedExceptionMessageRegExp'])) { + $messageRegExp = $this->parseAnnotationContent($annotations['expectedExceptionMessageRegExp'][0]); + } + + if (isset($matches[3])) { + $code = $matches[3]; + } elseif (isset($annotations['expectedExceptionCode'])) { + $code = $this->parseAnnotationContent($annotations['expectedExceptionCode'][0]); + } + + if (\is_numeric($code)) { + $code = (int) $code; + } elseif (\is_string($code) && \defined($code)) { + $code = (int) \constant($code); + } + + return [ + 'class' => $class, + 'code' => $code, + 'message' => $message, + 'message_regex' => $messageRegExp, + ]; + } + + /** + * Returns the provided data for a method. + * + * @throws Exception + */ + public function getProvidedData(): ?array + { + /** @noinspection SuspiciousBinaryOperationInspection */ + $data = $this->getDataFromDataProviderAnnotation($this->docComment) ?? $this->getDataFromTestWithAnnotation($this->docComment); + + if ($data === null) { + return null; + } + + if ($data === []) { + throw new SkippedTestError; + } + + foreach ($data as $key => $value) { + if (!\is_array($value)) { + throw new InvalidDataSetException( + \sprintf( + 'Data set %s is invalid.', + \is_int($key) ? '#' . $key : '"' . $key . '"' + ) + ); + } + } + + return $data; + } + + /** + * @psalm-return array + */ + public function getInlineAnnotations(): array + { + $code = \file($this->fileName); + $lineNumber = $this->startLine; + $startLine = $this->startLine - 1; + $endLine = $this->endLine - 1; + $codeLines = \array_slice($code, $startLine, $endLine - $startLine + 1); + $annotations = []; + + foreach ($codeLines as $line) { + if (\preg_match('#/\*\*?\s*@(?P[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?\*/$#m', $line, $matches)) { + $annotations[\strtolower($matches['name'])] = [ + 'line' => $lineNumber, + 'value' => $matches['value'], + ]; + } + + $lineNumber++; + } + + return $annotations; + } + + public function symbolAnnotations(): array + { + return $this->symbolAnnotations; + } + + public function isHookToBeExecutedBeforeClass(): bool + { + return $this->isMethod + && false !== \strpos($this->docComment, '@beforeClass'); + } + + public function isHookToBeExecutedAfterClass(): bool + { + return $this->isMethod + && false !== \strpos($this->docComment, '@afterClass'); + } + + public function isToBeExecutedBeforeTest(): bool + { + return 1 === \preg_match('/@before\b/', $this->docComment); + } + + public function isToBeExecutedAfterTest(): bool + { + return 1 === \preg_match('/@after\b/', $this->docComment); + } + + /** + * Parse annotation content to use constant/class constant values + * + * Constants are specified using a starting '@'. For example: @ClassName::CONST_NAME + * + * If the constant is not found the string is used as is to ensure maximum BC. + */ + private function parseAnnotationContent(string $message): string + { + if (\defined($message) && + (\strpos($message, '::') !== false && \substr_count($message, '::') + 1 === 2)) { + return \constant($message); + } + + return $message; + } + + private function getDataFromDataProviderAnnotation(string $docComment): ?array + { + $methodName = null; + $className = $this->className; + + if ($this->isMethod) { + $methodName = $this->name; + } + + if (!\preg_match_all(self::REGEX_DATA_PROVIDER, $docComment, $matches)) { + return null; + } + + $result = []; + + foreach ($matches[1] as $match) { + $dataProviderMethodNameNamespace = \explode('\\', $match); + $leaf = \explode('::', \array_pop($dataProviderMethodNameNamespace)); + $dataProviderMethodName = \array_pop($leaf); + + if (empty($dataProviderMethodNameNamespace)) { + $dataProviderMethodNameNamespace = ''; + } else { + $dataProviderMethodNameNamespace = \implode('\\', $dataProviderMethodNameNamespace) . '\\'; + } + + if (empty($leaf)) { + $dataProviderClassName = $className; + } else { + /** @psalm-var class-string $dataProviderClassName */ + $dataProviderClassName = $dataProviderMethodNameNamespace . \array_pop($leaf); + } + + try { + $dataProviderClass = new \ReflectionClass($dataProviderClassName); + + $dataProviderMethod = $dataProviderClass->getMethod( + $dataProviderMethodName + ); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + // @codeCoverageIgnoreEnd + } + + if ($dataProviderMethod->isStatic()) { + $object = null; + } else { + $object = $dataProviderClass->newInstance(); + } + + if ($dataProviderMethod->getNumberOfParameters() === 0) { + $data = $dataProviderMethod->invoke($object); + } else { + $data = $dataProviderMethod->invoke($object, $methodName); + } + + if ($data instanceof \Traversable) { + $origData = $data; + $data = []; + + foreach ($origData as $key => $value) { + if (\is_int($key)) { + $data[] = $value; + } elseif (\array_key_exists($key, $data)) { + throw new InvalidDataProviderException( + \sprintf( + 'The key "%s" has already been defined in the data provider "%s".', + $key, + $match + ) + ); + } else { + $data[$key] = $value; + } + } + } + + if (\is_array($data)) { + $result = \array_merge($result, $data); + } + } + + return $result; + } + + /** + * @throws Exception + */ + private function getDataFromTestWithAnnotation(string $docComment): ?array + { + $docComment = $this->cleanUpMultiLineAnnotation($docComment); + + if (!\preg_match(self::REGEX_TEST_WITH, $docComment, $matches, \PREG_OFFSET_CAPTURE)) { + return null; + } + + $offset = \strlen($matches[0][0]) + $matches[0][1]; + $annotationContent = \substr($docComment, $offset); + $data = []; + + foreach (\explode("\n", $annotationContent) as $candidateRow) { + $candidateRow = \trim($candidateRow); + + if ($candidateRow[0] !== '[') { + break; + } + + $dataSet = \json_decode($candidateRow, true); + + if (\json_last_error() !== \JSON_ERROR_NONE) { + throw new Exception( + 'The data set for the @testWith annotation cannot be parsed: ' . \json_last_error_msg() + ); + } + + $data[] = $dataSet; + } + + if (!$data) { + throw new Exception('The data set for the @testWith annotation cannot be parsed.'); + } + + return $data; + } + + private function cleanUpMultiLineAnnotation(string $docComment): string + { + //removing initial ' * ' for docComment + $docComment = \str_replace("\r\n", "\n", $docComment); + $docComment = \preg_replace('/' . '\n' . '\s*' . '\*' . '\s?' . '/', "\n", $docComment); + $docComment = (string) \substr($docComment, 0, -1); + + return \rtrim($docComment, "\n"); + } + + /** @return array> */ + private static function parseDocBlock(string $docBlock): array + { + // Strip away the docblock header and footer to ease parsing of one line annotations + $docBlock = (string) \substr($docBlock, 3, -2); + $annotations = []; + + if (\preg_match_all('/@(?P[A-Za-z_-]+)(?:[ \t]+(?P.*?))?[ \t]*\r?$/m', $docBlock, $matches)) { + $numMatches = \count($matches[0]); + + for ($i = 0; $i < $numMatches; ++$i) { + $annotations[$matches['name'][$i]][] = (string) $matches['value'][$i]; + } + } + + return $annotations; + } + + /** @param \ReflectionClass|\ReflectionFunctionAbstract $reflector */ + private static function extractAnnotationsFromReflector(\Reflector $reflector): array + { + $annotations = []; + + if ($reflector instanceof \ReflectionClass) { + $annotations = \array_merge( + $annotations, + ...\array_map( + function (\ReflectionClass $trait): array { + return self::parseDocBlock((string) $trait->getDocComment()); + }, + \array_values($reflector->getTraits()) + ) + ); + } + + return \array_merge( + $annotations, + self::parseDocBlock((string) $reflector->getDocComment()) + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php b/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php new file mode 100644 index 0000000..0706ba3 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Annotation/Registry.php @@ -0,0 +1,89 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\Annotation; + +use PHPUnit\Util\Exception; + +/** + * Reflection information, and therefore DocBlock information, is static within + * a single PHP process. It is therefore okay to use a Singleton registry here. + * + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Registry +{ + /** @var null|self */ + private static $instance; + + /** @var array indexed by class name */ + private $classDocBlocks = []; + + /** @var array> indexed by class name and method name */ + private $methodDocBlocks = []; + + public static function getInstance(): self + { + return self::$instance ?? self::$instance = new self; + } + + private function __construct() + { + } + + /** + * @throws Exception + * @psalm-param class-string $class + */ + public function forClassName(string $class): DocBlock + { + if (\array_key_exists($class, $this->classDocBlocks)) { + return $this->classDocBlocks[$class]; + } + + try { + $reflection = new \ReflectionClass($class); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + return $this->classDocBlocks[$class] = DocBlock::ofClass($reflection); + } + + /** + * @throws Exception + * @psalm-param class-string $classInHierarchy + */ + public function forMethod(string $classInHierarchy, string $method): DocBlock + { + if (isset($this->methodDocBlocks[$classInHierarchy][$method])) { + return $this->methodDocBlocks[$classInHierarchy][$method]; + } + + try { + $reflection = new \ReflectionMethod($classInHierarchy, $method); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + return $this->methodDocBlocks[$classInHierarchy][$method] = DocBlock::ofMethod($reflection, $classInHierarchy); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Blacklist.php b/vendor/phpunit/phpunit/src/Util/Blacklist.php new file mode 100644 index 0000000..3915cd6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Blacklist.php @@ -0,0 +1,216 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use Composer\Autoload\ClassLoader; +use DeepCopy\DeepCopy; +use Doctrine\Instantiator\Instantiator; +use PharIo\Manifest\Manifest; +use PharIo\Version\Version as PharIoVersion; +use PHP_Token; +use phpDocumentor\Reflection\DocBlock; +use phpDocumentor\Reflection\Project; +use phpDocumentor\Reflection\Type; +use PHPUnit\Framework\TestCase; +use Prophecy\Prophet; +use SebastianBergmann\CodeCoverage\CodeCoverage; +use SebastianBergmann\CodeUnitReverseLookup\Wizard; +use SebastianBergmann\Comparator\Comparator; +use SebastianBergmann\Diff\Diff; +use SebastianBergmann\Environment\Runtime; +use SebastianBergmann\Exporter\Exporter; +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; +use SebastianBergmann\GlobalState\Snapshot; +use SebastianBergmann\Invoker\Invoker; +use SebastianBergmann\ObjectEnumerator\Enumerator; +use SebastianBergmann\RecursionContext\Context; +use SebastianBergmann\ResourceOperations\ResourceOperations; +use SebastianBergmann\Timer\Timer; +use SebastianBergmann\Type\TypeName; +use SebastianBergmann\Version; +use Text_Template; +use TheSeer\Tokenizer\Tokenizer; +use Webmozart\Assert\Assert; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Blacklist +{ + /** + * @var array + */ + public static $blacklistedClassNames = [ + // composer + ClassLoader::class => 1, + + // doctrine/instantiator + Instantiator::class => 1, + + // myclabs/deepcopy + DeepCopy::class => 1, + + // phar-io/manifest + Manifest::class => 1, + + // phar-io/version + PharIoVersion::class => 1, + + // phpdocumentor/reflection-common + Project::class => 1, + + // phpdocumentor/reflection-docblock + DocBlock::class => 1, + + // phpdocumentor/type-resolver + Type::class => 1, + + // phpspec/prophecy + Prophet::class => 1, + + // phpunit/phpunit + TestCase::class => 2, + + // phpunit/php-code-coverage + CodeCoverage::class => 1, + + // phpunit/php-file-iterator + FileIteratorFacade::class => 1, + + // phpunit/php-invoker + Invoker::class => 1, + + // phpunit/php-text-template + Text_Template::class => 1, + + // phpunit/php-timer + Timer::class => 1, + + // phpunit/php-token-stream + PHP_Token::class => 1, + + // sebastian/code-unit-reverse-lookup + Wizard::class => 1, + + // sebastian/comparator + Comparator::class => 1, + + // sebastian/diff + Diff::class => 1, + + // sebastian/environment + Runtime::class => 1, + + // sebastian/exporter + Exporter::class => 1, + + // sebastian/global-state + Snapshot::class => 1, + + // sebastian/object-enumerator + Enumerator::class => 1, + + // sebastian/recursion-context + Context::class => 1, + + // sebastian/resource-operations + ResourceOperations::class => 1, + + // sebastian/type + TypeName::class => 1, + + // sebastian/version + Version::class => 1, + + // theseer/tokenizer + Tokenizer::class => 1, + + // webmozart/assert + Assert::class => 1, + ]; + + /** + * @var string[] + */ + private static $directories; + + /** + * @throws Exception + * + * @return string[] + */ + public function getBlacklistedDirectories(): array + { + $this->initialize(); + + return self::$directories; + } + + /** + * @throws Exception + */ + public function isBlacklisted(string $file): bool + { + if (\defined('PHPUNIT_TESTSUITE')) { + return false; + } + + $this->initialize(); + + foreach (self::$directories as $directory) { + if (\strpos($file, $directory) === 0) { + return true; + } + } + + return false; + } + + /** + * @throws Exception + */ + private function initialize(): void + { + if (self::$directories === null) { + self::$directories = []; + + foreach (self::$blacklistedClassNames as $className => $parent) { + if (!\class_exists($className)) { + continue; + } + + try { + $directory = (new \ReflectionClass($className))->getFileName(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + for ($i = 0; $i < $parent; $i++) { + $directory = \dirname($directory); + } + + self::$directories[] = $directory; + } + + // Hide process isolation workaround on Windows. + if (\DIRECTORY_SEPARATOR === '\\') { + // tempnam() prefix is limited to first 3 chars. + // @see https://php.net/manual/en/function.tempnam.php + self::$directories[] = \sys_get_temp_dir() . '\\PHP'; + } + } + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Color.php b/vendor/phpunit/phpunit/src/Util/Color.php new file mode 100644 index 0000000..c0611d1 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Color.php @@ -0,0 +1,143 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Color +{ + /** + * @var array + */ + private const WHITESPACE_MAP = [ + ' ' => '·', + "\t" => '⇥', + ]; + + /** + * @var array + */ + private const WHITESPACE_EOL_MAP = [ + ' ' => '·', + "\t" => '⇥', + "\n" => '↵', + "\r" => '⟵', + ]; + + /** + * @var array + */ + private static $ansiCodes = [ + 'reset' => '0', + 'bold' => '1', + 'dim' => '2', + 'dim-reset' => '22', + 'underlined' => '4', + 'fg-default' => '39', + 'fg-black' => '30', + 'fg-red' => '31', + 'fg-green' => '32', + 'fg-yellow' => '33', + 'fg-blue' => '34', + 'fg-magenta' => '35', + 'fg-cyan' => '36', + 'fg-white' => '37', + 'bg-default' => '49', + 'bg-black' => '40', + 'bg-red' => '41', + 'bg-green' => '42', + 'bg-yellow' => '43', + 'bg-blue' => '44', + 'bg-magenta' => '45', + 'bg-cyan' => '46', + 'bg-white' => '47', + ]; + + public static function colorize(string $color, string $buffer): string + { + if (\trim($buffer) === '') { + return $buffer; + } + + $codes = \array_map('\trim', \explode(',', $color)); + $styles = []; + + foreach ($codes as $code) { + if (isset(self::$ansiCodes[$code])) { + $styles[] = self::$ansiCodes[$code] ?? ''; + } + } + + if (empty($styles)) { + return $buffer; + } + + return self::optimizeColor(\sprintf("\x1b[%sm", \implode(';', $styles)) . $buffer . "\x1b[0m"); + } + + public static function colorizePath(string $path, ?string $prevPath = null, bool $colorizeFilename = false): string + { + if ($prevPath === null) { + $prevPath = ''; + } + + $path = \explode(\DIRECTORY_SEPARATOR, $path); + $prevPath = \explode(\DIRECTORY_SEPARATOR, $prevPath); + + for ($i = 0; $i < \min(\count($path), \count($prevPath)); $i++) { + if ($path[$i] == $prevPath[$i]) { + $path[$i] = self::dim($path[$i]); + } + } + + if ($colorizeFilename) { + $last = \count($path) - 1; + $path[$last] = \preg_replace_callback( + '/([\-_\.]+|phpt$)/', + static function ($matches) { + return self::dim($matches[0]); + }, + $path[$last] + ); + } + + return self::optimizeColor(\implode(self::dim(\DIRECTORY_SEPARATOR), $path)); + } + + public static function dim(string $buffer): string + { + if (\trim($buffer) === '') { + return $buffer; + } + + return "\e[2m$buffer\e[22m"; + } + + public static function visualizeWhitespace(string $buffer, bool $visualizeEOL = false): string + { + $replaceMap = $visualizeEOL ? self::WHITESPACE_EOL_MAP : self::WHITESPACE_MAP; + + return \preg_replace_callback('/\s+/', static function ($matches) use ($replaceMap) { + return self::dim(\strtr($matches[0], $replaceMap)); + }, $buffer); + } + + private static function optimizeColor(string $buffer): string + { + $patterns = [ + "/\e\\[22m\e\\[2m/" => '', + "/\e\\[([^m]*)m\e\\[([1-9][0-9;]*)m/" => "\e[$1;$2m", + "/(\e\\[[^m]*m)+(\e\\[0m)/" => '$2', + ]; + + return \preg_replace(\array_keys($patterns), \array_values($patterns), $buffer); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Configuration.php b/vendor/phpunit/phpunit/src/Util/Configuration.php new file mode 100644 index 0000000..d756af8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Configuration.php @@ -0,0 +1,1205 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use DOMElement; +use DOMXPath; +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Runner\TestSuiteSorter; +use PHPUnit\TextUI\ResultPrinter; +use PHPUnit\Util\TestDox\CliTestDoxPrinter; +use SebastianBergmann\FileIterator\Facade as FileIteratorFacade; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Configuration +{ + /** + * @var self[] + */ + private static $instances = []; + + /** + * @var \DOMDocument + */ + private $document; + + /** + * @var DOMXPath + */ + private $xpath; + + /** + * @var string + */ + private $filename; + + /** + * @var \LibXMLError[] + */ + private $errors = []; + + /** + * Returns a PHPUnit configuration object. + * + * @throws Exception + */ + public static function getInstance(string $filename): self + { + $realPath = \realpath($filename); + + if ($realPath === false) { + throw new Exception( + \sprintf( + 'Could not read "%s".', + $filename + ) + ); + } + + if (!isset(self::$instances[$realPath])) { + self::$instances[$realPath] = new self($realPath); + } + + return self::$instances[$realPath]; + } + + /** + * Loads a PHPUnit configuration file. + * + * @throws Exception + */ + private function __construct(string $filename) + { + $this->filename = $filename; + $this->document = Xml::loadFile($filename, false, true, true); + $this->xpath = new DOMXPath($this->document); + + $this->validateConfigurationAgainstSchema(); + } + + /** + * @codeCoverageIgnore + */ + private function __clone() + { + } + + public function hasValidationErrors(): bool + { + return \count($this->errors) > 0; + } + + public function getValidationErrors(): array + { + $result = []; + + foreach ($this->errors as $error) { + if (!isset($result[$error->line])) { + $result[$error->line] = []; + } + $result[$error->line][] = \trim($error->message); + } + + return $result; + } + + /** + * Returns the real path to the configuration file. + */ + public function getFilename(): string + { + return $this->filename; + } + + public function getExtensionConfiguration(): array + { + $result = []; + + foreach ($this->xpath->query('extensions/extension') as $extension) { + $result[] = $this->getElementConfigurationParameters($extension); + } + + return $result; + } + + /** + * Returns the configuration for SUT filtering. + */ + public function getFilterConfiguration(): array + { + $addUncoveredFilesFromWhitelist = true; + $processUncoveredFilesFromWhitelist = false; + $includeDirectory = []; + $includeFile = []; + $excludeDirectory = []; + $excludeFile = []; + + $tmp = $this->xpath->query('filter/whitelist'); + + if ($tmp->length === 1) { + if ($tmp->item(0)->hasAttribute('addUncoveredFilesFromWhitelist')) { + $addUncoveredFilesFromWhitelist = $this->getBoolean( + (string) $tmp->item(0)->getAttribute( + 'addUncoveredFilesFromWhitelist' + ), + true + ); + } + + if ($tmp->item(0)->hasAttribute('processUncoveredFilesFromWhitelist')) { + $processUncoveredFilesFromWhitelist = $this->getBoolean( + (string) $tmp->item(0)->getAttribute( + 'processUncoveredFilesFromWhitelist' + ), + false + ); + } + + $includeDirectory = $this->readFilterDirectories( + 'filter/whitelist/directory' + ); + + $includeFile = $this->readFilterFiles( + 'filter/whitelist/file' + ); + + $excludeDirectory = $this->readFilterDirectories( + 'filter/whitelist/exclude/directory' + ); + + $excludeFile = $this->readFilterFiles( + 'filter/whitelist/exclude/file' + ); + } + + return [ + 'whitelist' => [ + 'addUncoveredFilesFromWhitelist' => $addUncoveredFilesFromWhitelist, + 'processUncoveredFilesFromWhitelist' => $processUncoveredFilesFromWhitelist, + 'include' => [ + 'directory' => $includeDirectory, + 'file' => $includeFile, + ], + 'exclude' => [ + 'directory' => $excludeDirectory, + 'file' => $excludeFile, + ], + ], + ]; + } + + /** + * Returns the configuration for groups. + */ + public function getGroupConfiguration(): array + { + return $this->parseGroupConfiguration('groups'); + } + + /** + * Returns the configuration for testdox groups. + */ + public function getTestdoxGroupConfiguration(): array + { + return $this->parseGroupConfiguration('testdoxGroups'); + } + + /** + * Returns the configuration for listeners. + */ + public function getListenerConfiguration(): array + { + $result = []; + + foreach ($this->xpath->query('listeners/listener') as $listener) { + $result[] = $this->getElementConfigurationParameters($listener); + } + + return $result; + } + + /** + * Returns the logging configuration. + */ + public function getLoggingConfiguration(): array + { + $result = []; + + foreach ($this->xpath->query('logging/log') as $log) { + \assert($log instanceof DOMElement); + + $type = (string) $log->getAttribute('type'); + $target = (string) $log->getAttribute('target'); + + if (!$target) { + continue; + } + + $target = $this->toAbsolutePath($target); + + if ($type === 'coverage-html') { + if ($log->hasAttribute('lowUpperBound')) { + $result['lowUpperBound'] = $this->getInteger( + (string) $log->getAttribute('lowUpperBound'), + 50 + ); + } + + if ($log->hasAttribute('highLowerBound')) { + $result['highLowerBound'] = $this->getInteger( + (string) $log->getAttribute('highLowerBound'), + 90 + ); + } + } elseif ($type === 'coverage-crap4j') { + if ($log->hasAttribute('threshold')) { + $result['crap4jThreshold'] = $this->getInteger( + (string) $log->getAttribute('threshold'), + 30 + ); + } + } elseif ($type === 'coverage-text') { + if ($log->hasAttribute('showUncoveredFiles')) { + $result['coverageTextShowUncoveredFiles'] = $this->getBoolean( + (string) $log->getAttribute('showUncoveredFiles'), + false + ); + } + + if ($log->hasAttribute('showOnlySummary')) { + $result['coverageTextShowOnlySummary'] = $this->getBoolean( + (string) $log->getAttribute('showOnlySummary'), + false + ); + } + } + + $result[$type] = $target; + } + + return $result; + } + + /** + * Returns the PHP configuration. + */ + public function getPHPConfiguration(): array + { + $result = [ + 'include_path' => [], + 'ini' => [], + 'const' => [], + 'var' => [], + 'env' => [], + 'post' => [], + 'get' => [], + 'cookie' => [], + 'server' => [], + 'files' => [], + 'request' => [], + ]; + + foreach ($this->xpath->query('php/includePath') as $includePath) { + $path = (string) $includePath->textContent; + + if ($path) { + $result['include_path'][] = $this->toAbsolutePath($path); + } + } + + foreach ($this->xpath->query('php/ini') as $ini) { + \assert($ini instanceof DOMElement); + + $name = (string) $ini->getAttribute('name'); + $value = (string) $ini->getAttribute('value'); + + $result['ini'][$name]['value'] = $value; + } + + foreach ($this->xpath->query('php/const') as $const) { + \assert($const instanceof DOMElement); + + $name = (string) $const->getAttribute('name'); + $value = (string) $const->getAttribute('value'); + + $result['const'][$name]['value'] = $this->getBoolean($value, $value); + } + + foreach (['var', 'env', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) { + foreach ($this->xpath->query('php/' . $array) as $var) { + \assert($var instanceof DOMElement); + + $name = (string) $var->getAttribute('name'); + $value = (string) $var->getAttribute('value'); + $verbatim = false; + + if ($var->hasAttribute('verbatim')) { + $verbatim = $this->getBoolean($var->getAttribute('verbatim'), false); + $result[$array][$name]['verbatim'] = $verbatim; + } + + if ($var->hasAttribute('force')) { + $force = $this->getBoolean($var->getAttribute('force'), false); + $result[$array][$name]['force'] = $force; + } + + if (!$verbatim) { + $value = $this->getBoolean($value, $value); + } + + $result[$array][$name]['value'] = $value; + } + } + + return $result; + } + + /** + * Handles the PHP configuration. + */ + public function handlePHPConfiguration(): void + { + $configuration = $this->getPHPConfiguration(); + + if (!empty($configuration['include_path'])) { + \ini_set( + 'include_path', + \implode(\PATH_SEPARATOR, $configuration['include_path']) . + \PATH_SEPARATOR . + \ini_get('include_path') + ); + } + + foreach ($configuration['ini'] as $name => $data) { + $value = $data['value']; + + if (\defined($value)) { + $value = (string) \constant($value); + } + + \ini_set($name, $value); + } + + foreach ($configuration['const'] as $name => $data) { + $value = $data['value']; + + if (!\defined($name)) { + \define($name, $value); + } + } + + foreach (['var', 'post', 'get', 'cookie', 'server', 'files', 'request'] as $array) { + /* + * @see https://github.com/sebastianbergmann/phpunit/issues/277 + */ + switch ($array) { + case 'var': + $target = &$GLOBALS; + + break; + + case 'server': + $target = &$_SERVER; + + break; + + default: + $target = &$GLOBALS['_' . \strtoupper($array)]; + + break; + } + + foreach ($configuration[$array] as $name => $data) { + $target[$name] = $data['value']; + } + } + + foreach ($configuration['env'] as $name => $data) { + $value = $data['value']; + $force = $data['force'] ?? false; + + if ($force || \getenv($name) === false) { + \putenv("{$name}={$value}"); + } + + $value = \getenv($name); + + if (!isset($_ENV[$name])) { + $_ENV[$name] = $value; + } + + if ($force) { + $_ENV[$name] = $value; + } + } + } + + /** + * Returns the PHPUnit configuration. + */ + public function getPHPUnitConfiguration(): array + { + $result = []; + $root = $this->document->documentElement; + + if ($root->hasAttribute('cacheTokens')) { + $result['cacheTokens'] = $this->getBoolean( + (string) $root->getAttribute('cacheTokens'), + false + ); + } + + if ($root->hasAttribute('columns')) { + $columns = (string) $root->getAttribute('columns'); + + if ($columns === 'max') { + $result['columns'] = 'max'; + } else { + $result['columns'] = $this->getInteger($columns, 80); + } + } + + if ($root->hasAttribute('colors')) { + /* only allow boolean for compatibility with previous versions + 'always' only allowed from command line */ + if ($this->getBoolean($root->getAttribute('colors'), false)) { + $result['colors'] = ResultPrinter::COLOR_AUTO; + } else { + $result['colors'] = ResultPrinter::COLOR_NEVER; + } + } + + /* + * @see https://github.com/sebastianbergmann/phpunit/issues/657 + */ + if ($root->hasAttribute('stderr')) { + $result['stderr'] = $this->getBoolean( + (string) $root->getAttribute('stderr'), + false + ); + } + + if ($root->hasAttribute('backupGlobals')) { + $result['backupGlobals'] = $this->getBoolean( + (string) $root->getAttribute('backupGlobals'), + false + ); + } + + if ($root->hasAttribute('backupStaticAttributes')) { + $result['backupStaticAttributes'] = $this->getBoolean( + (string) $root->getAttribute('backupStaticAttributes'), + false + ); + } + + if ($root->getAttribute('bootstrap')) { + $result['bootstrap'] = $this->toAbsolutePath( + (string) $root->getAttribute('bootstrap') + ); + } + + if ($root->hasAttribute('convertDeprecationsToExceptions')) { + $result['convertDeprecationsToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertDeprecationsToExceptions'), + true + ); + } + + if ($root->hasAttribute('convertErrorsToExceptions')) { + $result['convertErrorsToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertErrorsToExceptions'), + true + ); + } + + if ($root->hasAttribute('convertNoticesToExceptions')) { + $result['convertNoticesToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertNoticesToExceptions'), + true + ); + } + + if ($root->hasAttribute('convertWarningsToExceptions')) { + $result['convertWarningsToExceptions'] = $this->getBoolean( + (string) $root->getAttribute('convertWarningsToExceptions'), + true + ); + } + + if ($root->hasAttribute('forceCoversAnnotation')) { + $result['forceCoversAnnotation'] = $this->getBoolean( + (string) $root->getAttribute('forceCoversAnnotation'), + false + ); + } + + if ($root->hasAttribute('disableCodeCoverageIgnore')) { + $result['disableCodeCoverageIgnore'] = $this->getBoolean( + (string) $root->getAttribute('disableCodeCoverageIgnore'), + false + ); + } + + if ($root->hasAttribute('processIsolation')) { + $result['processIsolation'] = $this->getBoolean( + (string) $root->getAttribute('processIsolation'), + false + ); + } + + if ($root->hasAttribute('stopOnDefect')) { + $result['stopOnDefect'] = $this->getBoolean( + (string) $root->getAttribute('stopOnDefect'), + false + ); + } + + if ($root->hasAttribute('stopOnError')) { + $result['stopOnError'] = $this->getBoolean( + (string) $root->getAttribute('stopOnError'), + false + ); + } + + if ($root->hasAttribute('stopOnFailure')) { + $result['stopOnFailure'] = $this->getBoolean( + (string) $root->getAttribute('stopOnFailure'), + false + ); + } + + if ($root->hasAttribute('stopOnWarning')) { + $result['stopOnWarning'] = $this->getBoolean( + (string) $root->getAttribute('stopOnWarning'), + false + ); + } + + if ($root->hasAttribute('stopOnIncomplete')) { + $result['stopOnIncomplete'] = $this->getBoolean( + (string) $root->getAttribute('stopOnIncomplete'), + false + ); + } + + if ($root->hasAttribute('stopOnRisky')) { + $result['stopOnRisky'] = $this->getBoolean( + (string) $root->getAttribute('stopOnRisky'), + false + ); + } + + if ($root->hasAttribute('stopOnSkipped')) { + $result['stopOnSkipped'] = $this->getBoolean( + (string) $root->getAttribute('stopOnSkipped'), + false + ); + } + + if ($root->hasAttribute('failOnWarning')) { + $result['failOnWarning'] = $this->getBoolean( + (string) $root->getAttribute('failOnWarning'), + false + ); + } + + if ($root->hasAttribute('failOnRisky')) { + $result['failOnRisky'] = $this->getBoolean( + (string) $root->getAttribute('failOnRisky'), + false + ); + } + + if ($root->hasAttribute('testSuiteLoaderClass')) { + $result['testSuiteLoaderClass'] = (string) $root->getAttribute( + 'testSuiteLoaderClass' + ); + } + + if ($root->hasAttribute('defaultTestSuite')) { + $result['defaultTestSuite'] = (string) $root->getAttribute( + 'defaultTestSuite' + ); + } + + if ($root->getAttribute('testSuiteLoaderFile')) { + $result['testSuiteLoaderFile'] = $this->toAbsolutePath( + (string) $root->getAttribute('testSuiteLoaderFile') + ); + } + + if ($root->hasAttribute('printerClass')) { + $result['printerClass'] = (string) $root->getAttribute( + 'printerClass' + ); + } + + if ($root->getAttribute('printerFile')) { + $result['printerFile'] = $this->toAbsolutePath( + (string) $root->getAttribute('printerFile') + ); + } + + if ($root->hasAttribute('beStrictAboutChangesToGlobalState')) { + $result['beStrictAboutChangesToGlobalState'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutChangesToGlobalState'), + false + ); + } + + if ($root->hasAttribute('beStrictAboutOutputDuringTests')) { + $result['disallowTestOutput'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutOutputDuringTests'), + false + ); + } + + if ($root->hasAttribute('beStrictAboutResourceUsageDuringSmallTests')) { + $result['beStrictAboutResourceUsageDuringSmallTests'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutResourceUsageDuringSmallTests'), + false + ); + } + + if ($root->hasAttribute('beStrictAboutTestsThatDoNotTestAnything')) { + $result['reportUselessTests'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutTestsThatDoNotTestAnything'), + true + ); + } + + if ($root->hasAttribute('beStrictAboutTodoAnnotatedTests')) { + $result['disallowTodoAnnotatedTests'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutTodoAnnotatedTests'), + false + ); + } + + if ($root->hasAttribute('beStrictAboutCoversAnnotation')) { + $result['strictCoverage'] = $this->getBoolean( + (string) $root->getAttribute('beStrictAboutCoversAnnotation'), + false + ); + } + + if ($root->hasAttribute('defaultTimeLimit')) { + $result['defaultTimeLimit'] = $this->getInteger( + (string) $root->getAttribute('defaultTimeLimit'), + 1 + ); + } + + if ($root->hasAttribute('enforceTimeLimit')) { + $result['enforceTimeLimit'] = $this->getBoolean( + (string) $root->getAttribute('enforceTimeLimit'), + false + ); + } + + if ($root->hasAttribute('ignoreDeprecatedCodeUnitsFromCodeCoverage')) { + $result['ignoreDeprecatedCodeUnitsFromCodeCoverage'] = $this->getBoolean( + (string) $root->getAttribute('ignoreDeprecatedCodeUnitsFromCodeCoverage'), + false + ); + } + + if ($root->hasAttribute('timeoutForSmallTests')) { + $result['timeoutForSmallTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForSmallTests'), + 1 + ); + } + + if ($root->hasAttribute('timeoutForMediumTests')) { + $result['timeoutForMediumTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForMediumTests'), + 10 + ); + } + + if ($root->hasAttribute('timeoutForLargeTests')) { + $result['timeoutForLargeTests'] = $this->getInteger( + (string) $root->getAttribute('timeoutForLargeTests'), + 60 + ); + } + + if ($root->hasAttribute('reverseDefectList')) { + $result['reverseDefectList'] = $this->getBoolean( + (string) $root->getAttribute('reverseDefectList'), + false + ); + } + + if ($root->hasAttribute('verbose')) { + $result['verbose'] = $this->getBoolean( + (string) $root->getAttribute('verbose'), + false + ); + } + + if ($root->hasAttribute('testdox')) { + $testdox = $this->getBoolean( + (string) $root->getAttribute('testdox'), + false + ); + + if ($testdox) { + if (isset($result['printerClass'])) { + $result['conflictBetweenPrinterClassAndTestdox'] = true; + } else { + $result['printerClass'] = CliTestDoxPrinter::class; + } + } + } + + if ($root->hasAttribute('registerMockObjectsFromTestArgumentsRecursively')) { + $result['registerMockObjectsFromTestArgumentsRecursively'] = $this->getBoolean( + (string) $root->getAttribute('registerMockObjectsFromTestArgumentsRecursively'), + false + ); + } + + if ($root->hasAttribute('extensionsDirectory')) { + $result['extensionsDirectory'] = $this->toAbsolutePath( + (string) $root->getAttribute( + 'extensionsDirectory' + ) + ); + } + + if ($root->hasAttribute('cacheResult')) { + $result['cacheResult'] = $this->getBoolean( + (string) $root->getAttribute('cacheResult'), + true + ); + } + + if ($root->hasAttribute('cacheResultFile')) { + $result['cacheResultFile'] = $this->toAbsolutePath( + (string) $root->getAttribute('cacheResultFile') + ); + } + + if ($root->hasAttribute('executionOrder')) { + foreach (\explode(',', $root->getAttribute('executionOrder')) as $order) { + switch ($order) { + case 'default': + $result['executionOrder'] = TestSuiteSorter::ORDER_DEFAULT; + $result['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFAULT; + $result['resolveDependencies'] = false; + + break; + + case 'defects': + $result['executionOrderDefects'] = TestSuiteSorter::ORDER_DEFECTS_FIRST; + + break; + + case 'depends': + $result['resolveDependencies'] = true; + + break; + + case 'duration': + $result['executionOrder'] = TestSuiteSorter::ORDER_DURATION; + + break; + + case 'no-depends': + $result['resolveDependencies'] = false; + + break; + + case 'random': + $result['executionOrder'] = TestSuiteSorter::ORDER_RANDOMIZED; + + break; + + case 'reverse': + $result['executionOrder'] = TestSuiteSorter::ORDER_REVERSED; + + break; + + case 'size': + $result['executionOrder'] = TestSuiteSorter::ORDER_SIZE; + + break; + } + } + } + + if ($root->hasAttribute('resolveDependencies')) { + $result['resolveDependencies'] = $this->getBoolean( + (string) $root->getAttribute('resolveDependencies'), + false + ); + } + + if ($root->hasAttribute('noInteraction')) { + $result['noInteraction'] = $this->getBoolean( + (string) $root->getAttribute('noInteraction'), + false + ); + } + + return $result; + } + + /** + * Returns the test suite configuration. + * + * @throws Exception + */ + public function getTestSuiteConfiguration(string $testSuiteFilter = ''): TestSuite + { + $testSuiteNodes = $this->xpath->query('testsuites/testsuite'); + + if ($testSuiteNodes->length === 0) { + $testSuiteNodes = $this->xpath->query('testsuite'); + } + + if ($testSuiteNodes->length === 1) { + return $this->getTestSuite($testSuiteNodes->item(0), $testSuiteFilter); + } + + $suite = new TestSuite; + + foreach ($testSuiteNodes as $testSuiteNode) { + $suite->addTestSuite( + $this->getTestSuite($testSuiteNode, $testSuiteFilter) + ); + } + + return $suite; + } + + /** + * Returns the test suite names from the configuration. + */ + public function getTestSuiteNames(): array + { + $names = []; + + foreach ($this->xpath->query('*/testsuite') as $node) { + /* @var DOMElement $node */ + $names[] = $node->getAttribute('name'); + } + + return $names; + } + + private function validateConfigurationAgainstSchema(): void + { + $original = \libxml_use_internal_errors(true); + $xsdFilename = __DIR__ . '/../../phpunit.xsd'; + + if (\defined('__PHPUNIT_PHAR_ROOT__')) { + $xsdFilename = __PHPUNIT_PHAR_ROOT__ . '/phpunit.xsd'; + } + + $this->document->schemaValidate($xsdFilename); + $this->errors = \libxml_get_errors(); + \libxml_clear_errors(); + \libxml_use_internal_errors($original); + } + + /** + * Collects and returns the configuration arguments from the PHPUnit + * XML configuration + */ + private function getConfigurationArguments(\DOMNodeList $nodes): array + { + $arguments = []; + + if ($nodes->length === 0) { + return $arguments; + } + + foreach ($nodes as $node) { + if (!$node instanceof DOMElement) { + continue; + } + + if ($node->tagName !== 'arguments') { + continue; + } + + foreach ($node->childNodes as $argument) { + if (!$argument instanceof DOMElement) { + continue; + } + + if ($argument->tagName === 'file' || $argument->tagName === 'directory') { + $arguments[] = $this->toAbsolutePath((string) $argument->textContent); + } else { + $arguments[] = Xml::xmlToVariable($argument); + } + } + } + + return $arguments; + } + + /** + * @throws \PHPUnit\Framework\Exception + */ + private function getTestSuite(DOMElement $testSuiteNode, string $testSuiteFilter = ''): TestSuite + { + if ($testSuiteNode->hasAttribute('name')) { + $suite = new TestSuite( + (string) $testSuiteNode->getAttribute('name') + ); + } else { + $suite = new TestSuite; + } + + $exclude = []; + + foreach ($testSuiteNode->getElementsByTagName('exclude') as $excludeNode) { + $excludeFile = (string) $excludeNode->textContent; + + if ($excludeFile) { + $exclude[] = $this->toAbsolutePath($excludeFile); + } + } + + $fileIteratorFacade = new FileIteratorFacade; + $testSuiteFilter = $testSuiteFilter ? \explode(',', $testSuiteFilter) : []; + + foreach ($testSuiteNode->getElementsByTagName('directory') as $directoryNode) { + \assert($directoryNode instanceof DOMElement); + + if (!empty($testSuiteFilter) && !\in_array($directoryNode->parentNode->getAttribute('name'), $testSuiteFilter)) { + continue; + } + + $directory = (string) $directoryNode->textContent; + + if (empty($directory)) { + continue; + } + + if (!$this->satisfiesPhpVersion($directoryNode)) { + continue; + } + + $files = $fileIteratorFacade->getFilesAsArray( + $this->toAbsolutePath($directory), + $directoryNode->hasAttribute('suffix') ? (string) $directoryNode->getAttribute('suffix') : 'Test.php', + $directoryNode->hasAttribute('prefix') ? (string) $directoryNode->getAttribute('prefix') : '', + $exclude + ); + + $suite->addTestFiles($files); + } + + foreach ($testSuiteNode->getElementsByTagName('file') as $fileNode) { + \assert($fileNode instanceof DOMElement); + + if (!empty($testSuiteFilter) && !\in_array($fileNode->parentNode->getAttribute('name'), $testSuiteFilter)) { + continue; + } + + $file = (string) $fileNode->textContent; + + if (empty($file)) { + continue; + } + + $file = $fileIteratorFacade->getFilesAsArray( + $this->toAbsolutePath($file) + ); + + if (!isset($file[0])) { + continue; + } + + $file = $file[0]; + + if (!$this->satisfiesPhpVersion($fileNode)) { + continue; + } + + $suite->addTestFile($file); + } + + return $suite; + } + + private function satisfiesPhpVersion(DOMElement $node): bool + { + $phpVersion = \PHP_VERSION; + $phpVersionOperator = '>='; + + if ($node->hasAttribute('phpVersion')) { + $phpVersion = (string) $node->getAttribute('phpVersion'); + } + + if ($node->hasAttribute('phpVersionOperator')) { + $phpVersionOperator = (string) $node->getAttribute('phpVersionOperator'); + } + + return \version_compare(\PHP_VERSION, $phpVersion, (new VersionComparisonOperator($phpVersionOperator))->asString()); + } + + /** + * if $value is 'false' or 'true', this returns the value that $value represents. + * Otherwise, returns $default, which may be a string in rare cases. + * See PHPUnit\Util\ConfigurationTest::testPHPConfigurationIsReadCorrectly + * + * @param bool|string $default + * + * @return bool|string + */ + private function getBoolean(string $value, $default) + { + if (\strtolower($value) === 'false') { + return false; + } + + if (\strtolower($value) === 'true') { + return true; + } + + return $default; + } + + private function getInteger(string $value, int $default): int + { + if (\is_numeric($value)) { + return (int) $value; + } + + return $default; + } + + private function readFilterDirectories(string $query): array + { + $directories = []; + + foreach ($this->xpath->query($query) as $directoryNode) { + \assert($directoryNode instanceof DOMElement); + + $directoryPath = (string) $directoryNode->textContent; + + if (!$directoryPath) { + continue; + } + + $directories[] = [ + 'path' => $this->toAbsolutePath($directoryPath), + 'prefix' => $directoryNode->hasAttribute('prefix') ? (string) $directoryNode->getAttribute('prefix') : '', + 'suffix' => $directoryNode->hasAttribute('suffix') ? (string) $directoryNode->getAttribute('suffix') : '.php', + 'group' => $directoryNode->hasAttribute('group') ? (string) $directoryNode->getAttribute('group') : 'DEFAULT', + ]; + } + + return $directories; + } + + /** + * @return string[] + */ + private function readFilterFiles(string $query): array + { + $files = []; + + foreach ($this->xpath->query($query) as $file) { + $filePath = (string) $file->textContent; + + if ($filePath) { + $files[] = $this->toAbsolutePath($filePath); + } + } + + return $files; + } + + private function toAbsolutePath(string $path, bool $useIncludePath = false): string + { + $path = \trim($path); + + if (\strpos($path, '/') === 0) { + return $path; + } + + // Matches the following on Windows: + // - \\NetworkComputer\Path + // - \\.\D: + // - \\.\c: + // - C:\Windows + // - C:\windows + // - C:/windows + // - c:/windows + if (\defined('PHP_WINDOWS_VERSION_BUILD') && + ($path[0] === '\\' || (\strlen($path) >= 3 && \preg_match('#^[A-Z]\:[/\\\]#i', \substr($path, 0, 3))))) { + return $path; + } + + if (\strpos($path, '://') !== false) { + return $path; + } + + $file = \dirname($this->filename) . \DIRECTORY_SEPARATOR . $path; + + if ($useIncludePath && !\file_exists($file)) { + $includePathFile = \stream_resolve_include_path($path); + + if ($includePathFile) { + $file = $includePathFile; + } + } + + return $file; + } + + private function parseGroupConfiguration(string $root): array + { + $groups = [ + 'include' => [], + 'exclude' => [], + ]; + + foreach ($this->xpath->query($root . '/include/group') as $group) { + $groups['include'][] = (string) $group->textContent; + } + + foreach ($this->xpath->query($root . '/exclude/group') as $group) { + $groups['exclude'][] = (string) $group->textContent; + } + + return $groups; + } + + private function getElementConfigurationParameters(DOMElement $element): array + { + $class = (string) $element->getAttribute('class'); + $file = ''; + $arguments = $this->getConfigurationArguments($element->childNodes); + + if ($element->getAttribute('file')) { + $file = $this->toAbsolutePath( + (string) $element->getAttribute('file'), + true + ); + } + + return [ + 'class' => $class, + 'file' => $file, + 'arguments' => $arguments, + ]; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php b/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php new file mode 100644 index 0000000..f2727fa --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/ConfigurationGenerator.php @@ -0,0 +1,64 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ConfigurationGenerator +{ + /** + * @var string + */ + private const TEMPLATE = << + + + + {tests_directory} + + + + + + {src_directory} + + + + +EOT; + + public function generateDefaultConfiguration(string $phpunitVersion, string $bootstrapScript, string $testsDirectory, string $srcDirectory): string + { + return \str_replace( + [ + '{phpunit_version}', + '{bootstrap_script}', + '{tests_directory}', + '{src_directory}', + ], + [ + $phpunitVersion, + $bootstrapScript, + $testsDirectory, + $srcDirectory, + ], + self::TEMPLATE + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/ErrorHandler.php b/vendor/phpunit/phpunit/src/Util/ErrorHandler.php new file mode 100644 index 0000000..99e3ae2 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/ErrorHandler.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Error\Deprecated; +use PHPUnit\Framework\Error\Error; +use PHPUnit\Framework\Error\Notice; +use PHPUnit\Framework\Error\Warning; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class ErrorHandler +{ + /** + * @var bool + */ + private $convertDeprecationsToExceptions; + + /** + * @var bool + */ + private $convertErrorsToExceptions; + + /** + * @var bool + */ + private $convertNoticesToExceptions; + + /** + * @var bool + */ + private $convertWarningsToExceptions; + + /** + * @var bool + */ + private $registered = false; + + public static function invokeIgnoringWarnings(callable $callable) + { + \set_error_handler( + static function ($errorNumber, $errorString) { + if ($errorNumber === \E_WARNING) { + return; + } + + return false; + } + ); + + $result = $callable(); + + \restore_error_handler(); + + return $result; + } + + public function __construct(bool $convertDeprecationsToExceptions, bool $convertErrorsToExceptions, bool $convertNoticesToExceptions, bool $convertWarningsToExceptions) + { + $this->convertDeprecationsToExceptions = $convertDeprecationsToExceptions; + $this->convertErrorsToExceptions = $convertErrorsToExceptions; + $this->convertNoticesToExceptions = $convertNoticesToExceptions; + $this->convertWarningsToExceptions = $convertWarningsToExceptions; + } + + public function __invoke(int $errorNumber, string $errorString, string $errorFile, int $errorLine): bool + { + /* + * Do not raise an exception when the error suppression operator (@) was used. + * + * @see https://github.com/sebastianbergmann/phpunit/issues/3739 + */ + if (!($errorNumber & \error_reporting())) { + return false; + } + + switch ($errorNumber) { + case \E_NOTICE: + case \E_USER_NOTICE: + case \E_STRICT: + if (!$this->convertNoticesToExceptions) { + return false; + } + + throw new Notice($errorString, $errorNumber, $errorFile, $errorLine); + + case \E_WARNING: + case \E_USER_WARNING: + if (!$this->convertWarningsToExceptions) { + return false; + } + + throw new Warning($errorString, $errorNumber, $errorFile, $errorLine); + + case \E_DEPRECATED: + case \E_USER_DEPRECATED: + if (!$this->convertDeprecationsToExceptions) { + return false; + } + + throw new Deprecated($errorString, $errorNumber, $errorFile, $errorLine); + + default: + if (!$this->convertErrorsToExceptions) { + return false; + } + + throw new Error($errorString, $errorNumber, $errorFile, $errorLine); + } + } + + public function register(): void + { + if ($this->registered) { + return; + } + + $oldErrorHandler = \set_error_handler($this); + + if ($oldErrorHandler !== null) { + \restore_error_handler(); + + return; + } + + $this->registered = true; + } + + public function unregister(): void + { + if (!$this->registered) { + return; + } + + \restore_error_handler(); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Exception.php b/vendor/phpunit/phpunit/src/Util/Exception.php new file mode 100644 index 0000000..da452f4 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Exception.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Exception extends \RuntimeException implements \PHPUnit\Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Util/FileLoader.php b/vendor/phpunit/phpunit/src/Util/FileLoader.php new file mode 100644 index 0000000..2c5f7ca --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/FileLoader.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class FileLoader +{ + /** + * Checks if a PHP sourcecode file is readable. The sourcecode file is loaded through the load() method. + * + * As a fallback, PHP looks in the directory of the file executing the stream_resolve_include_path function. + * We do not want to load the Test.php file here, so skip it if it found that. + * PHP prioritizes the include_path setting, so if the current directory is in there, it will first look in the + * current working directory. + * + * @throws Exception + */ + public static function checkAndLoad(string $filename): string + { + $includePathFilename = \stream_resolve_include_path($filename); + + if (!$includePathFilename) { + throw new Exception( + \sprintf('Cannot open file "%s".' . "\n", $filename) + ); + } + + $localFile = __DIR__ . \DIRECTORY_SEPARATOR . $filename; + + if ($includePathFilename === $localFile || !self::isReadable($includePathFilename)) { + throw new Exception( + \sprintf('Cannot open file "%s".' . "\n", $filename) + ); + } + + self::load($includePathFilename); + + return $includePathFilename; + } + + /** + * Loads a PHP sourcefile. + */ + public static function load(string $filename): void + { + $oldVariableNames = \array_keys(\get_defined_vars()); + + include_once $filename; + + $newVariables = \get_defined_vars(); + + foreach (\array_diff(\array_keys($newVariables), $oldVariableNames) as $variableName) { + if ($variableName !== 'oldVariableNames') { + $GLOBALS[$variableName] = $newVariables[$variableName]; + } + } + } + + /** + * @see https://github.com/sebastianbergmann/phpunit/pull/2751 + */ + private static function isReadable(string $filename): bool + { + return @\fopen($filename, 'r') !== false; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Filesystem.php b/vendor/phpunit/phpunit/src/Util/Filesystem.php new file mode 100644 index 0000000..8207a4f --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Filesystem.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Filesystem +{ + /** + * Maps class names to source file names: + * - PEAR CS: Foo_Bar_Baz -> Foo/Bar/Baz.php + * - Namespace: Foo\Bar\Baz -> Foo/Bar/Baz.php + */ + public static function classNameToFilename(string $className): string + { + return \str_replace( + ['_', '\\'], + \DIRECTORY_SEPARATOR, + $className + ) . '.php'; + } + + public static function createDirectory(string $directory): bool + { + return !(!\is_dir($directory) && !@\mkdir($directory, 0777, true) && !\is_dir($directory)); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Filter.php b/vendor/phpunit/phpunit/src/Util/Filter.php new file mode 100644 index 0000000..d1a8ec6 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Filter.php @@ -0,0 +1,107 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\SyntheticError; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Filter +{ + /** + * @throws Exception + */ + public static function getFilteredStacktrace(\Throwable $t): string + { + $filteredStacktrace = ''; + + if ($t instanceof SyntheticError) { + $eTrace = $t->getSyntheticTrace(); + $eFile = $t->getSyntheticFile(); + $eLine = $t->getSyntheticLine(); + } elseif ($t instanceof Exception) { + $eTrace = $t->getSerializableTrace(); + $eFile = $t->getFile(); + $eLine = $t->getLine(); + } else { + if ($t->getPrevious()) { + $t = $t->getPrevious(); + } + + $eTrace = $t->getTrace(); + $eFile = $t->getFile(); + $eLine = $t->getLine(); + } + + if (!self::frameExists($eTrace, $eFile, $eLine)) { + \array_unshift( + $eTrace, + ['file' => $eFile, 'line' => $eLine] + ); + } + + $prefix = \defined('__PHPUNIT_PHAR_ROOT__') ? __PHPUNIT_PHAR_ROOT__ : false; + $blacklist = new Blacklist; + + foreach ($eTrace as $frame) { + if (self::shouldPrintFrame($frame, $prefix, $blacklist)) { + $filteredStacktrace .= \sprintf( + "%s:%s\n", + $frame['file'], + $frame['line'] ?? '?' + ); + } + } + + return $filteredStacktrace; + } + + private static function shouldPrintFrame($frame, $prefix, Blacklist $blacklist): bool + { + if (!isset($frame['file'])) { + return false; + } + + $file = $frame['file']; + $fileIsNotPrefixed = $prefix === false || \strpos($file, $prefix) !== 0; + + // @see https://github.com/sebastianbergmann/phpunit/issues/4033 + if (isset($GLOBALS['_SERVER']['SCRIPT_NAME'])) { + $script = \realpath($GLOBALS['_SERVER']['SCRIPT_NAME']); + } else { + $script = ''; + } + + return \is_file($file) && + self::fileIsBlacklisted($file, $blacklist) && + $fileIsNotPrefixed && + $file !== $script; + } + + private static function fileIsBlacklisted($file, Blacklist $blacklist): bool + { + return (empty($GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST']) || + !\in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST'], true)) && + !$blacklist->isBlacklisted($file); + } + + private static function frameExists(array $trace, string $file, int $line): bool + { + foreach ($trace as $frame) { + if (isset($frame['file'], $frame['line']) && $frame['file'] === $file && $frame['line'] === $line) { + return true; + } + } + + return false; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Getopt.php b/vendor/phpunit/phpunit/src/Util/Getopt.php new file mode 100644 index 0000000..e361383 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Getopt.php @@ -0,0 +1,181 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Getopt +{ + /** + * @throws Exception + */ + public static function getopt(array $args, string $short_options, array $long_options = null): array + { + if (empty($args)) { + return [[], []]; + } + + $opts = []; + $non_opts = []; + + if ($long_options) { + \sort($long_options); + } + + if (isset($args[0][0]) && $args[0][0] !== '-') { + \array_shift($args); + } + + \reset($args); + + $args = \array_map('trim', $args); + + /* @noinspection ComparisonOperandsOrderInspection */ + while (false !== $arg = \current($args)) { + $i = \key($args); + \next($args); + + if ($arg === '') { + continue; + } + + if ($arg === '--') { + $non_opts = \array_merge($non_opts, \array_slice($args, $i + 1)); + + break; + } + + if ($arg[0] !== '-' || (\strlen($arg) > 1 && $arg[1] === '-' && !$long_options)) { + $non_opts[] = $args[$i]; + + continue; + } + + if (\strlen($arg) > 1 && $arg[1] === '-') { + self::parseLongOption( + \substr($arg, 2), + $long_options, + $opts, + $args + ); + } else { + self::parseShortOption( + \substr($arg, 1), + $short_options, + $opts, + $args + ); + } + } + + return [$opts, $non_opts]; + } + + /** + * @throws Exception + */ + private static function parseShortOption(string $arg, string $short_options, array &$opts, array &$args): void + { + $argLen = \strlen($arg); + + for ($i = 0; $i < $argLen; $i++) { + $opt = $arg[$i]; + $opt_arg = null; + + if ($arg[$i] === ':' || ($spec = \strstr($short_options, $opt)) === false) { + throw new Exception( + "unrecognized option -- $opt" + ); + } + + if (\strlen($spec) > 1 && $spec[1] === ':') { + if ($i + 1 < $argLen) { + $opts[] = [$opt, \substr($arg, $i + 1)]; + + break; + } + + if (!(\strlen($spec) > 2 && $spec[2] === ':')) { + /* @noinspection ComparisonOperandsOrderInspection */ + if (false === $opt_arg = \current($args)) { + throw new Exception( + "option requires an argument -- $opt" + ); + } + + \next($args); + } + } + + $opts[] = [$opt, $opt_arg]; + } + } + + /** + * @throws Exception + */ + private static function parseLongOption(string $arg, array $long_options, array &$opts, array &$args): void + { + $count = \count($long_options); + $list = \explode('=', $arg); + $opt = $list[0]; + $opt_arg = null; + + if (\count($list) > 1) { + $opt_arg = $list[1]; + } + + $opt_len = \strlen($opt); + + foreach ($long_options as $i => $long_opt) { + $opt_start = \substr($long_opt, 0, $opt_len); + + if ($opt_start !== $opt) { + continue; + } + + $opt_rest = \substr($long_opt, $opt_len); + + if ($opt_rest !== '' && $i + 1 < $count && $opt[0] !== '=' && \strpos($long_options[$i + 1], $opt) === 0) { + throw new Exception( + "option --$opt is ambiguous" + ); + } + + if (\substr($long_opt, -1) === '=') { + /* @noinspection StrlenInEmptyStringCheckContextInspection */ + if (\substr($long_opt, -2) !== '==' && !\strlen((string) $opt_arg)) { + /* @noinspection ComparisonOperandsOrderInspection */ + if (false === $opt_arg = \current($args)) { + throw new Exception( + "option --$opt requires an argument" + ); + } + + \next($args); + } + } elseif ($opt_arg) { + throw new Exception( + "option --$opt doesn't allow an argument" + ); + } + + $full_option = '--' . \preg_replace('/={1,2}$/', '', $long_opt); + $opts[] = [$full_option, $opt_arg]; + + return; + } + + throw new Exception("unrecognized option --$opt"); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/GlobalState.php b/vendor/phpunit/phpunit/src/Util/GlobalState.php new file mode 100644 index 0000000..4a8dadb --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/GlobalState.php @@ -0,0 +1,179 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use Closure; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class GlobalState +{ + /** + * @var string[] + */ + private const SUPER_GLOBAL_ARRAYS = [ + '_ENV', + '_POST', + '_GET', + '_COOKIE', + '_SERVER', + '_FILES', + '_REQUEST', + ]; + + /** + * @throws Exception + */ + public static function getIncludedFilesAsString(): string + { + return static::processIncludedFilesAsString(\get_included_files()); + } + + /** + * @param string[] $files + * + * @throws Exception + */ + public static function processIncludedFilesAsString(array $files): string + { + $blacklist = new Blacklist; + $prefix = false; + $result = ''; + + if (\defined('__PHPUNIT_PHAR__')) { + $prefix = 'phar://' . __PHPUNIT_PHAR__ . '/'; + } + + for ($i = \count($files) - 1; $i > 0; $i--) { + $file = $files[$i]; + + if (!empty($GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST']) && + \in_array($file, $GLOBALS['__PHPUNIT_ISOLATION_BLACKLIST'])) { + continue; + } + + if ($prefix !== false && \strpos($file, $prefix) === 0) { + continue; + } + + // Skip virtual file system protocols + if (\preg_match('/^(vfs|phpvfs[a-z0-9]+):/', $file)) { + continue; + } + + if (!$blacklist->isBlacklisted($file) && \is_file($file)) { + $result = 'require_once \'' . $file . "';\n" . $result; + } + } + + return $result; + } + + public static function getIniSettingsAsString(): string + { + $result = ''; + + foreach (\ini_get_all(null, false) as $key => $value) { + $result .= \sprintf( + '@ini_set(%s, %s);' . "\n", + self::exportVariable($key), + self::exportVariable((string) $value) + ); + } + + return $result; + } + + public static function getConstantsAsString(): string + { + $constants = \get_defined_constants(true); + $result = ''; + + if (isset($constants['user'])) { + foreach ($constants['user'] as $name => $value) { + $result .= \sprintf( + 'if (!defined(\'%s\')) define(\'%s\', %s);' . "\n", + $name, + $name, + self::exportVariable($value) + ); + } + } + + return $result; + } + + public static function getGlobalsAsString(): string + { + $result = ''; + + foreach (self::SUPER_GLOBAL_ARRAYS as $superGlobalArray) { + if (isset($GLOBALS[$superGlobalArray]) && \is_array($GLOBALS[$superGlobalArray])) { + foreach (\array_keys($GLOBALS[$superGlobalArray]) as $key) { + if ($GLOBALS[$superGlobalArray][$key] instanceof Closure) { + continue; + } + + $result .= \sprintf( + '$GLOBALS[\'%s\'][\'%s\'] = %s;' . "\n", + $superGlobalArray, + $key, + self::exportVariable($GLOBALS[$superGlobalArray][$key]) + ); + } + } + } + + $blacklist = self::SUPER_GLOBAL_ARRAYS; + $blacklist[] = 'GLOBALS'; + + foreach (\array_keys($GLOBALS) as $key) { + if (!$GLOBALS[$key] instanceof Closure && !\in_array($key, $blacklist, true)) { + $result .= \sprintf( + '$GLOBALS[\'%s\'] = %s;' . "\n", + $key, + self::exportVariable($GLOBALS[$key]) + ); + } + } + + return $result; + } + + private static function exportVariable($variable): string + { + if (\is_scalar($variable) || $variable === null || + (\is_array($variable) && self::arrayOnlyContainsScalars($variable))) { + return \var_export($variable, true); + } + + return 'unserialize(' . \var_export(\serialize($variable), true) . ')'; + } + + private static function arrayOnlyContainsScalars(array $array): bool + { + $result = true; + + foreach ($array as $element) { + if (\is_array($element)) { + $result = self::arrayOnlyContainsScalars($element); + } elseif (!\is_scalar($element) && $element !== null) { + $result = false; + } + + if (!$result) { + break; + } + } + + return $result; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/InvalidDataSetException.php b/vendor/phpunit/phpunit/src/Util/InvalidDataSetException.php new file mode 100644 index 0000000..228f066 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/InvalidDataSetException.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class InvalidDataSetException extends \RuntimeException implements \PHPUnit\Exception +{ +} diff --git a/vendor/phpunit/phpunit/src/Util/Json.php b/vendor/phpunit/phpunit/src/Util/Json.php new file mode 100644 index 0000000..8e7c82c --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Json.php @@ -0,0 +1,86 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Json +{ + /** + * Prettify json string + * + * @throws \PHPUnit\Framework\Exception + */ + public static function prettify(string $json): string + { + $decodedJson = \json_decode($json, false); + + if (\json_last_error()) { + throw new Exception( + 'Cannot prettify invalid json' + ); + } + + return \json_encode($decodedJson, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE); + } + + /* + * To allow comparison of JSON strings, first process them into a consistent + * format so that they can be compared as strings. + * @return array ($error, $canonicalized_json) The $error parameter is used + * to indicate an error decoding the json. This is used to avoid ambiguity + * with JSON strings consisting entirely of 'null' or 'false'. + */ + public static function canonicalize(string $json): array + { + $decodedJson = \json_decode($json); + + if (\json_last_error()) { + return [true, null]; + } + + self::recursiveSort($decodedJson); + + $reencodedJson = \json_encode($decodedJson); + + return [false, $reencodedJson]; + } + + /* + * JSON object keys are unordered while PHP array keys are ordered. + * Sort all array keys to ensure both the expected and actual values have + * their keys in the same order. + */ + private static function recursiveSort(&$json): void + { + if (!\is_array($json)) { + // If the object is not empty, change it to an associative array + // so we can sort the keys (and we will still re-encode it + // correctly, since PHP encodes associative arrays as JSON objects.) + // But EMPTY objects MUST remain empty objects. (Otherwise we will + // re-encode it as a JSON array rather than a JSON object.) + // See #2919. + if (\is_object($json) && \count((array) $json) > 0) { + $json = (array) $json; + } else { + return; + } + } + + \ksort($json); + + foreach ($json as $key => &$value) { + self::recursiveSort($value); + } + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Log/JUnit.php b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php new file mode 100644 index 0000000..4d152a3 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Log/JUnit.php @@ -0,0 +1,422 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\Log; + +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ExceptionWrapper; +use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestFailure; +use PHPUnit\Framework\TestListener; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; +use PHPUnit\Util\Exception; +use PHPUnit\Util\Filter; +use PHPUnit\Util\Printer; +use PHPUnit\Util\Xml; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class JUnit extends Printer implements TestListener +{ + /** + * @var \DOMDocument + */ + private $document; + + /** + * @var \DOMElement + */ + private $root; + + /** + * @var bool + */ + private $reportRiskyTests = false; + + /** + * @var \DOMElement[] + */ + private $testSuites = []; + + /** + * @var int[] + */ + private $testSuiteTests = [0]; + + /** + * @var int[] + */ + private $testSuiteAssertions = [0]; + + /** + * @var int[] + */ + private $testSuiteErrors = [0]; + + /** + * @var int[] + */ + private $testSuiteWarnings = [0]; + + /** + * @var int[] + */ + private $testSuiteFailures = [0]; + + /** + * @var int[] + */ + private $testSuiteSkipped = [0]; + + /** + * @var int[] + */ + private $testSuiteTimes = [0]; + + /** + * @var int + */ + private $testSuiteLevel = 0; + + /** + * @var \DOMElement + */ + private $currentTestCase; + + /** + * @param null|mixed $out + */ + public function __construct($out = null, bool $reportRiskyTests = false) + { + $this->document = new \DOMDocument('1.0', 'UTF-8'); + $this->document->formatOutput = true; + + $this->root = $this->document->createElement('testsuites'); + $this->document->appendChild($this->root); + + parent::__construct($out); + + $this->reportRiskyTests = $reportRiskyTests; + } + + /** + * Flush buffer and close output. + */ + public function flush(): void + { + $this->write($this->getXML()); + + parent::flush(); + } + + /** + * An error occurred. + */ + public function addError(Test $test, \Throwable $t, float $time): void + { + $this->doAddFault($test, $t, $time, 'error'); + $this->testSuiteErrors[$this->testSuiteLevel]++; + } + + /** + * A warning occurred. + */ + public function addWarning(Test $test, Warning $e, float $time): void + { + $this->doAddFault($test, $e, $time, 'warning'); + $this->testSuiteWarnings[$this->testSuiteLevel]++; + } + + /** + * A failure occurred. + */ + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + $this->doAddFault($test, $e, $time, 'failure'); + $this->testSuiteFailures[$this->testSuiteLevel]++; + } + + /** + * Incomplete test. + */ + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void + { + $this->doAddSkipped(); + } + + /** + * Risky test. + */ + public function addRiskyTest(Test $test, \Throwable $t, float $time): void + { + if (!$this->reportRiskyTests || $this->currentTestCase === null) { + return; + } + + $error = $this->document->createElement( + 'error', + Xml::prepareString( + "Risky Test\n" . + Filter::getFilteredStacktrace($t) + ) + ); + + $error->setAttribute('type', \get_class($t)); + + $this->currentTestCase->appendChild($error); + + $this->testSuiteErrors[$this->testSuiteLevel]++; + } + + /** + * Skipped test. + */ + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + $this->doAddSkipped(); + } + + /** + * A testsuite started. + */ + public function startTestSuite(TestSuite $suite): void + { + $testSuite = $this->document->createElement('testsuite'); + $testSuite->setAttribute('name', $suite->getName()); + + if (\class_exists($suite->getName(), false)) { + try { + $class = new \ReflectionClass($suite->getName()); + + $testSuite->setAttribute('file', $class->getFileName()); + } catch (\ReflectionException $e) { + } + } + + if ($this->testSuiteLevel > 0) { + $this->testSuites[$this->testSuiteLevel]->appendChild($testSuite); + } else { + $this->root->appendChild($testSuite); + } + + $this->testSuiteLevel++; + $this->testSuites[$this->testSuiteLevel] = $testSuite; + $this->testSuiteTests[$this->testSuiteLevel] = 0; + $this->testSuiteAssertions[$this->testSuiteLevel] = 0; + $this->testSuiteErrors[$this->testSuiteLevel] = 0; + $this->testSuiteWarnings[$this->testSuiteLevel] = 0; + $this->testSuiteFailures[$this->testSuiteLevel] = 0; + $this->testSuiteSkipped[$this->testSuiteLevel] = 0; + $this->testSuiteTimes[$this->testSuiteLevel] = 0; + } + + /** + * A testsuite ended. + */ + public function endTestSuite(TestSuite $suite): void + { + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'tests', + (string) $this->testSuiteTests[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'assertions', + (string) $this->testSuiteAssertions[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'errors', + (string) $this->testSuiteErrors[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'warnings', + (string) $this->testSuiteWarnings[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'failures', + (string) $this->testSuiteFailures[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'skipped', + (string) $this->testSuiteSkipped[$this->testSuiteLevel] + ); + + $this->testSuites[$this->testSuiteLevel]->setAttribute( + 'time', + \sprintf('%F', $this->testSuiteTimes[$this->testSuiteLevel]) + ); + + if ($this->testSuiteLevel > 1) { + $this->testSuiteTests[$this->testSuiteLevel - 1] += $this->testSuiteTests[$this->testSuiteLevel]; + $this->testSuiteAssertions[$this->testSuiteLevel - 1] += $this->testSuiteAssertions[$this->testSuiteLevel]; + $this->testSuiteErrors[$this->testSuiteLevel - 1] += $this->testSuiteErrors[$this->testSuiteLevel]; + $this->testSuiteWarnings[$this->testSuiteLevel - 1] += $this->testSuiteWarnings[$this->testSuiteLevel]; + $this->testSuiteFailures[$this->testSuiteLevel - 1] += $this->testSuiteFailures[$this->testSuiteLevel]; + $this->testSuiteSkipped[$this->testSuiteLevel - 1] += $this->testSuiteSkipped[$this->testSuiteLevel]; + $this->testSuiteTimes[$this->testSuiteLevel - 1] += $this->testSuiteTimes[$this->testSuiteLevel]; + } + + $this->testSuiteLevel--; + } + + /** + * A test started. + */ + public function startTest(Test $test): void + { + $usesDataprovider = false; + + if (\method_exists($test, 'usesDataProvider')) { + $usesDataprovider = $test->usesDataProvider(); + } + + $testCase = $this->document->createElement('testcase'); + $testCase->setAttribute('name', $test->getName()); + + try { + $class = new \ReflectionClass($test); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $methodName = $test->getName(!$usesDataprovider); + + if ($class->hasMethod($methodName)) { + try { + $method = $class->getMethod($methodName); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $testCase->setAttribute('class', $class->getName()); + $testCase->setAttribute('classname', \str_replace('\\', '.', $class->getName())); + $testCase->setAttribute('file', $class->getFileName()); + $testCase->setAttribute('line', (string) $method->getStartLine()); + } + + $this->currentTestCase = $testCase; + } + + /** + * A test ended. + */ + public function endTest(Test $test, float $time): void + { + $numAssertions = 0; + + if (\method_exists($test, 'getNumAssertions')) { + $numAssertions = $test->getNumAssertions(); + } + + $this->testSuiteAssertions[$this->testSuiteLevel] += $numAssertions; + + $this->currentTestCase->setAttribute( + 'assertions', + (string) $numAssertions + ); + + $this->currentTestCase->setAttribute( + 'time', + \sprintf('%F', $time) + ); + + $this->testSuites[$this->testSuiteLevel]->appendChild( + $this->currentTestCase + ); + + $this->testSuiteTests[$this->testSuiteLevel]++; + $this->testSuiteTimes[$this->testSuiteLevel] += $time; + + $testOutput = ''; + + if (\method_exists($test, 'hasOutput') && \method_exists($test, 'getActualOutput')) { + $testOutput = $test->hasOutput() ? $test->getActualOutput() : ''; + } + + if (!empty($testOutput)) { + $systemOut = $this->document->createElement( + 'system-out', + Xml::prepareString($testOutput) + ); + + $this->currentTestCase->appendChild($systemOut); + } + + $this->currentTestCase = null; + } + + /** + * Returns the XML as a string. + */ + public function getXML(): string + { + return $this->document->saveXML(); + } + + private function doAddFault(Test $test, \Throwable $t, float $time, $type): void + { + if ($this->currentTestCase === null) { + return; + } + + if ($test instanceof SelfDescribing) { + $buffer = $test->toString() . "\n"; + } else { + $buffer = ''; + } + + $buffer .= TestFailure::exceptionToString($t) . "\n" . + Filter::getFilteredStacktrace($t); + + $fault = $this->document->createElement( + $type, + Xml::prepareString($buffer) + ); + + if ($t instanceof ExceptionWrapper) { + $fault->setAttribute('type', $t->getClassName()); + } else { + $fault->setAttribute('type', \get_class($t)); + } + + $this->currentTestCase->appendChild($fault); + } + + private function doAddSkipped(): void + { + if ($this->currentTestCase === null) { + return; + } + + $skipped = $this->document->createElement('skipped'); + + $this->currentTestCase->appendChild($skipped); + + $this->testSuiteSkipped[$this->testSuiteLevel]++; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php new file mode 100644 index 0000000..ccfb81b --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Log/TeamCity.php @@ -0,0 +1,378 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\Log; + +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\ExceptionWrapper; +use PHPUnit\Framework\ExpectationFailedException; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestFailure; +use PHPUnit\Framework\TestResult; +use PHPUnit\Framework\TestSuite; +use PHPUnit\Framework\Warning; +use PHPUnit\TextUI\ResultPrinter; +use PHPUnit\Util\Exception; +use PHPUnit\Util\Filter; +use SebastianBergmann\Comparator\ComparisonFailure; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class TeamCity extends ResultPrinter +{ + /** + * @var bool + */ + private $isSummaryTestCountPrinted = false; + + /** + * @var string + */ + private $startedTestName; + + /** + * @var false|int + */ + private $flowId; + + /** + * @throws \SebastianBergmann\Timer\RuntimeException + */ + public function printResult(TestResult $result): void + { + $this->printHeader($result); + $this->printFooter($result); + } + + /** + * An error occurred. + */ + public function addError(Test $test, \Throwable $t, float $time): void + { + $this->printEvent( + 'testFailed', + [ + 'name' => $test->getName(), + 'message' => self::getMessage($t), + 'details' => self::getDetails($t), + 'duration' => self::toMilliseconds($time), + ] + ); + } + + /** + * A warning occurred. + */ + public function addWarning(Test $test, Warning $e, float $time): void + { + $this->printEvent( + 'testFailed', + [ + 'name' => $test->getName(), + 'message' => self::getMessage($e), + 'details' => self::getDetails($e), + 'duration' => self::toMilliseconds($time), + ] + ); + } + + /** + * A failure occurred. + */ + public function addFailure(Test $test, AssertionFailedError $e, float $time): void + { + $parameters = [ + 'name' => $test->getName(), + 'message' => self::getMessage($e), + 'details' => self::getDetails($e), + 'duration' => self::toMilliseconds($time), + ]; + + if ($e instanceof ExpectationFailedException) { + $comparisonFailure = $e->getComparisonFailure(); + + if ($comparisonFailure instanceof ComparisonFailure) { + $expectedString = $comparisonFailure->getExpectedAsString(); + + if ($expectedString === null || empty($expectedString)) { + $expectedString = self::getPrimitiveValueAsString($comparisonFailure->getExpected()); + } + + $actualString = $comparisonFailure->getActualAsString(); + + if ($actualString === null || empty($actualString)) { + $actualString = self::getPrimitiveValueAsString($comparisonFailure->getActual()); + } + + if ($actualString !== null && $expectedString !== null) { + $parameters['type'] = 'comparisonFailure'; + $parameters['actual'] = $actualString; + $parameters['expected'] = $expectedString; + } + } + } + + $this->printEvent('testFailed', $parameters); + } + + /** + * Incomplete test. + */ + public function addIncompleteTest(Test $test, \Throwable $t, float $time): void + { + $this->printIgnoredTest($test->getName(), $t, $time); + } + + /** + * Risky test. + */ + public function addRiskyTest(Test $test, \Throwable $t, float $time): void + { + $this->addError($test, $t, $time); + } + + /** + * Skipped test. + */ + public function addSkippedTest(Test $test, \Throwable $t, float $time): void + { + $testName = $test->getName(); + + if ($this->startedTestName !== $testName) { + $this->startTest($test); + $this->printIgnoredTest($testName, $t, $time); + $this->endTest($test, $time); + } else { + $this->printIgnoredTest($testName, $t, $time); + } + } + + public function printIgnoredTest($testName, \Throwable $t, float $time): void + { + $this->printEvent( + 'testIgnored', + [ + 'name' => $testName, + 'message' => self::getMessage($t), + 'details' => self::getDetails($t), + 'duration' => self::toMilliseconds($time), + ] + ); + } + + /** + * A testsuite started. + */ + public function startTestSuite(TestSuite $suite): void + { + if (\stripos(\ini_get('disable_functions'), 'getmypid') === false) { + $this->flowId = \getmypid(); + } else { + $this->flowId = false; + } + + if (!$this->isSummaryTestCountPrinted) { + $this->isSummaryTestCountPrinted = true; + + $this->printEvent( + 'testCount', + ['count' => \count($suite)] + ); + } + + $suiteName = $suite->getName(); + + if (empty($suiteName)) { + return; + } + + $parameters = ['name' => $suiteName]; + + if (\class_exists($suiteName, false)) { + $fileName = self::getFileName($suiteName); + $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName"; + } else { + $split = \explode('::', $suiteName); + + if (\count($split) === 2 && \class_exists($split[0]) && \method_exists($split[0], $split[1])) { + $fileName = self::getFileName($split[0]); + $parameters['locationHint'] = "php_qn://$fileName::\\$suiteName"; + $parameters['name'] = $split[1]; + } + } + + $this->printEvent('testSuiteStarted', $parameters); + } + + /** + * A testsuite ended. + */ + public function endTestSuite(TestSuite $suite): void + { + $suiteName = $suite->getName(); + + if (empty($suiteName)) { + return; + } + + $parameters = ['name' => $suiteName]; + + if (!\class_exists($suiteName, false)) { + $split = \explode('::', $suiteName); + + if (\count($split) === 2 && \class_exists($split[0]) && \method_exists($split[0], $split[1])) { + $parameters['name'] = $split[1]; + } + } + + $this->printEvent('testSuiteFinished', $parameters); + } + + /** + * A test started. + */ + public function startTest(Test $test): void + { + $testName = $test->getName(); + $this->startedTestName = $testName; + $params = ['name' => $testName]; + + if ($test instanceof TestCase) { + $className = \get_class($test); + $fileName = self::getFileName($className); + $params['locationHint'] = "php_qn://$fileName::\\$className::$testName"; + } + + $this->printEvent('testStarted', $params); + } + + /** + * A test ended. + */ + public function endTest(Test $test, float $time): void + { + parent::endTest($test, $time); + + $this->printEvent( + 'testFinished', + [ + 'name' => $test->getName(), + 'duration' => self::toMilliseconds($time), + ] + ); + } + + protected function writeProgress(string $progress): void + { + } + + private function printEvent(string $eventName, array $params = []): void + { + $this->write("\n##teamcity[$eventName"); + + if ($this->flowId) { + $params['flowId'] = $this->flowId; + } + + foreach ($params as $key => $value) { + $escapedValue = self::escapeValue((string) $value); + $this->write(" $key='$escapedValue'"); + } + + $this->write("]\n"); + } + + private static function getMessage(\Throwable $t): string + { + $message = ''; + + if ($t instanceof ExceptionWrapper) { + if ($t->getClassName() !== '') { + $message .= $t->getClassName(); + } + + if ($message !== '' && $t->getMessage() !== '') { + $message .= ' : '; + } + } + + return $message . $t->getMessage(); + } + + private static function getDetails(\Throwable $t): string + { + $stackTrace = Filter::getFilteredStacktrace($t); + $previous = $t instanceof ExceptionWrapper ? $t->getPreviousWrapped() : $t->getPrevious(); + + while ($previous) { + $stackTrace .= "\nCaused by\n" . + TestFailure::exceptionToString($previous) . "\n" . + Filter::getFilteredStacktrace($previous); + + $previous = $previous instanceof ExceptionWrapper ? + $previous->getPreviousWrapped() : $previous->getPrevious(); + } + + return ' ' . \str_replace("\n", "\n ", $stackTrace); + } + + private static function getPrimitiveValueAsString($value): ?string + { + if ($value === null) { + return 'null'; + } + + if (\is_bool($value)) { + return $value ? 'true' : 'false'; + } + + if (\is_scalar($value)) { + return \print_r($value, true); + } + + return null; + } + + private static function escapeValue(string $text): string + { + return \str_replace( + ['|', "'", "\n", "\r", ']', '['], + ['||', "|'", '|n', '|r', '|]', '|['], + $text + ); + } + + /** + * @param string $className + */ + private static function getFileName($className): string + { + try { + return (new \ReflectionClass($className))->getFileName(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + + /** + * @param float $time microseconds + */ + private static function toMilliseconds(float $time): int + { + return (int) \round($time * 1000); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php b/vendor/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php new file mode 100644 index 0000000..90978a8 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/AbstractPhpProcess.php @@ -0,0 +1,399 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\PHP; + +use __PHP_Incomplete_Class; +use ErrorException; +use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Exception; +use PHPUnit\Framework\SyntheticError; +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestFailure; +use PHPUnit\Framework\TestResult; +use SebastianBergmann\Environment\Runtime; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +abstract class AbstractPhpProcess +{ + /** + * @var Runtime + */ + protected $runtime; + + /** + * @var bool + */ + protected $stderrRedirection = false; + + /** + * @var string + */ + protected $stdin = ''; + + /** + * @var string + */ + protected $args = ''; + + /** + * @var array + */ + protected $env = []; + + /** + * @var int + */ + protected $timeout = 0; + + public static function factory(): self + { + if (\DIRECTORY_SEPARATOR === '\\') { + return new WindowsPhpProcess; + } + + return new DefaultPhpProcess; + } + + public function __construct() + { + $this->runtime = new Runtime; + } + + /** + * Defines if should use STDERR redirection or not. + * + * Then $stderrRedirection is TRUE, STDERR is redirected to STDOUT. + */ + public function setUseStderrRedirection(bool $stderrRedirection): void + { + $this->stderrRedirection = $stderrRedirection; + } + + /** + * Returns TRUE if uses STDERR redirection or FALSE if not. + */ + public function useStderrRedirection(): bool + { + return $this->stderrRedirection; + } + + /** + * Sets the input string to be sent via STDIN + */ + public function setStdin(string $stdin): void + { + $this->stdin = $stdin; + } + + /** + * Returns the input string to be sent via STDIN + */ + public function getStdin(): string + { + return $this->stdin; + } + + /** + * Sets the string of arguments to pass to the php job + */ + public function setArgs(string $args): void + { + $this->args = $args; + } + + /** + * Returns the string of arguments to pass to the php job + */ + public function getArgs(): string + { + return $this->args; + } + + /** + * Sets the array of environment variables to start the child process with + * + * @param array $env + */ + public function setEnv(array $env): void + { + $this->env = $env; + } + + /** + * Returns the array of environment variables to start the child process with + */ + public function getEnv(): array + { + return $this->env; + } + + /** + * Sets the amount of seconds to wait before timing out + */ + public function setTimeout(int $timeout): void + { + $this->timeout = $timeout; + } + + /** + * Returns the amount of seconds to wait before timing out + */ + public function getTimeout(): int + { + return $this->timeout; + } + + /** + * Runs a single test in a separate PHP process. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public function runTestJob(string $job, Test $test, TestResult $result): void + { + $result->startTest($test); + + $_result = $this->runJob($job); + + $this->processChildResult( + $test, + $result, + $_result['stdout'], + $_result['stderr'] + ); + } + + /** + * Returns the command based into the configurations. + */ + public function getCommand(array $settings, string $file = null): string + { + $command = $this->runtime->getBinary(); + + if ($this->runtime->hasPCOV()) { + $settings = \array_merge( + $settings, + $this->runtime->getCurrentSettings( + \array_keys(\ini_get_all('pcov')) + ) + ); + } elseif ($this->runtime->hasXdebug()) { + $settings = \array_merge( + $settings, + $this->runtime->getCurrentSettings( + \array_keys(\ini_get_all('xdebug')) + ) + ); + } + + $command .= $this->settingsToParameters($settings); + + if (\PHP_SAPI === 'phpdbg') { + $command .= ' -qrr'; + + if (!$file) { + $command .= 's='; + } + } + + if ($file) { + $command .= ' ' . \escapeshellarg($file); + } + + if ($this->args) { + if (!$file) { + $command .= ' --'; + } + $command .= ' ' . $this->args; + } + + if ($this->stderrRedirection) { + $command .= ' 2>&1'; + } + + return $command; + } + + /** + * Runs a single job (PHP code) using a separate PHP process. + */ + abstract public function runJob(string $job, array $settings = []): array; + + protected function settingsToParameters(array $settings): string + { + $buffer = ''; + + foreach ($settings as $setting) { + $buffer .= ' -d ' . \escapeshellarg($setting); + } + + return $buffer; + } + + /** + * Processes the TestResult object from an isolated process. + * + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + private function processChildResult(Test $test, TestResult $result, string $stdout, string $stderr): void + { + $time = 0; + + if (!empty($stderr)) { + $result->addError( + $test, + new Exception(\trim($stderr)), + $time + ); + } else { + \set_error_handler( + /** + * @throws ErrorException + */ + static function ($errno, $errstr, $errfile, $errline): void { + throw new ErrorException($errstr, $errno, $errno, $errfile, $errline); + } + ); + + try { + if (\strpos($stdout, "#!/usr/bin/env php\n") === 0) { + $stdout = \substr($stdout, 19); + } + + $childResult = \unserialize(\str_replace("#!/usr/bin/env php\n", '', $stdout)); + \restore_error_handler(); + + if ($childResult === false) { + $result->addFailure( + $test, + new AssertionFailedError('Test was run in child process and ended unexpectedly'), + $time + ); + } + } catch (ErrorException $e) { + \restore_error_handler(); + $childResult = false; + + $result->addError( + $test, + new Exception(\trim($stdout), 0, $e), + $time + ); + } + + if ($childResult !== false) { + if (!empty($childResult['output'])) { + $output = $childResult['output']; + } + + /* @var TestCase $test */ + + $test->setResult($childResult['testResult']); + $test->addToAssertionCount($childResult['numAssertions']); + + $childResult = $childResult['result']; + \assert($childResult instanceof TestResult); + + if ($result->getCollectCodeCoverageInformation()) { + $result->getCodeCoverage()->merge( + $childResult->getCodeCoverage() + ); + } + + $time = $childResult->time(); + $notImplemented = $childResult->notImplemented(); + $risky = $childResult->risky(); + $skipped = $childResult->skipped(); + $errors = $childResult->errors(); + $warnings = $childResult->warnings(); + $failures = $childResult->failures(); + + if (!empty($notImplemented)) { + $result->addError( + $test, + $this->getException($notImplemented[0]), + $time + ); + } elseif (!empty($risky)) { + $result->addError( + $test, + $this->getException($risky[0]), + $time + ); + } elseif (!empty($skipped)) { + $result->addError( + $test, + $this->getException($skipped[0]), + $time + ); + } elseif (!empty($errors)) { + $result->addError( + $test, + $this->getException($errors[0]), + $time + ); + } elseif (!empty($warnings)) { + $result->addWarning( + $test, + $this->getException($warnings[0]), + $time + ); + } elseif (!empty($failures)) { + $result->addFailure( + $test, + $this->getException($failures[0]), + $time + ); + } + } + } + + $result->endTest($test, $time); + + if (!empty($output)) { + print $output; + } + } + + /** + * Gets the thrown exception from a PHPUnit\Framework\TestFailure. + * + * @see https://github.com/sebastianbergmann/phpunit/issues/74 + */ + private function getException(TestFailure $error): Exception + { + $exception = $error->thrownException(); + + if ($exception instanceof __PHP_Incomplete_Class) { + $exceptionArray = []; + + foreach ((array) $exception as $key => $value) { + $key = \substr($key, \strrpos($key, "\0") + 1); + $exceptionArray[$key] = $value; + } + + $exception = new SyntheticError( + \sprintf( + '%s: %s', + $exceptionArray['_PHP_Incomplete_Class_Name'], + $exceptionArray['message'] + ), + $exceptionArray['code'], + $exceptionArray['file'], + $exceptionArray['line'], + $exceptionArray['trace'] + ); + } + + return $exception; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php b/vendor/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php new file mode 100644 index 0000000..1d47eaf --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/DefaultPhpProcess.php @@ -0,0 +1,216 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\PHP; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class DefaultPhpProcess extends AbstractPhpProcess +{ + /** + * @var string + */ + protected $tempFile; + + /** + * Runs a single job (PHP code) using a separate PHP process. + * + * @throws Exception + */ + public function runJob(string $job, array $settings = []): array + { + if ($this->stdin || $this->useTemporaryFile()) { + if (!($this->tempFile = \tempnam(\sys_get_temp_dir(), 'PHPUnit')) || + \file_put_contents($this->tempFile, $job) === false) { + throw new Exception( + 'Unable to write temporary file' + ); + } + + $job = $this->stdin; + } + + return $this->runProcess($job, $settings); + } + + /** + * Returns an array of file handles to be used in place of pipes + */ + protected function getHandles(): array + { + return []; + } + + /** + * Handles creating the child process and returning the STDOUT and STDERR + * + * @throws Exception + */ + protected function runProcess(string $job, array $settings): array + { + $handles = $this->getHandles(); + + $env = null; + + if ($this->env) { + $env = $_SERVER ?? []; + unset($env['argv'], $env['argc']); + $env = \array_merge($env, $this->env); + + foreach ($env as $envKey => $envVar) { + if (\is_array($envVar)) { + unset($env[$envKey]); + } + } + } + + $pipeSpec = [ + 0 => $handles[0] ?? ['pipe', 'r'], + 1 => $handles[1] ?? ['pipe', 'w'], + 2 => $handles[2] ?? ['pipe', 'w'], + ]; + + $process = \proc_open( + $this->getCommand($settings, $this->tempFile), + $pipeSpec, + $pipes, + null, + $env + ); + + if (!\is_resource($process)) { + throw new Exception( + 'Unable to spawn worker process' + ); + } + + if ($job) { + $this->process($pipes[0], $job); + } + + \fclose($pipes[0]); + + $stderr = $stdout = ''; + + if ($this->timeout) { + unset($pipes[0]); + + while (true) { + $r = $pipes; + $w = null; + $e = null; + + $n = @\stream_select($r, $w, $e, $this->timeout); + + if ($n === false) { + break; + } + + if ($n === 0) { + \proc_terminate($process, 9); + + throw new Exception( + \sprintf( + 'Job execution aborted after %d seconds', + $this->timeout + ) + ); + } + + if ($n > 0) { + foreach ($r as $pipe) { + $pipeOffset = 0; + + foreach ($pipes as $i => $origPipe) { + if ($pipe === $origPipe) { + $pipeOffset = $i; + + break; + } + } + + if (!$pipeOffset) { + break; + } + + $line = \fread($pipe, 8192); + + if ($line === '' || $line === false) { + \fclose($pipes[$pipeOffset]); + + unset($pipes[$pipeOffset]); + } elseif ($pipeOffset === 1) { + $stdout .= $line; + } else { + $stderr .= $line; + } + } + + if (empty($pipes)) { + break; + } + } + } + } else { + if (isset($pipes[1])) { + $stdout = \stream_get_contents($pipes[1]); + + \fclose($pipes[1]); + } + + if (isset($pipes[2])) { + $stderr = \stream_get_contents($pipes[2]); + + \fclose($pipes[2]); + } + } + + if (isset($handles[1])) { + \rewind($handles[1]); + + $stdout = \stream_get_contents($handles[1]); + + \fclose($handles[1]); + } + + if (isset($handles[2])) { + \rewind($handles[2]); + + $stderr = \stream_get_contents($handles[2]); + + \fclose($handles[2]); + } + + \proc_close($process); + + $this->cleanup(); + + return ['stdout' => $stdout, 'stderr' => $stderr]; + } + + protected function process($pipe, string $job): void + { + \fwrite($pipe, $job); + } + + protected function cleanup(): void + { + if ($this->tempFile) { + \unlink($this->tempFile); + } + } + + protected function useTemporaryFile(): bool + { + return false; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Template/PhptTestCase.tpl b/vendor/phpunit/phpunit/src/Util/PHP/Template/PhptTestCase.tpl new file mode 100644 index 0000000..14c3e7e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/Template/PhptTestCase.tpl @@ -0,0 +1,40 @@ +start(__FILE__); +} + +register_shutdown_function(function() use ($coverage) { + $output = null; + if ($coverage) { + $output = $coverage->stop(); + } + file_put_contents('{coverageFile}', serialize($output)); +}); + +ob_end_clean(); + +require '{job}'; diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseClass.tpl b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseClass.tpl new file mode 100644 index 0000000..c25f63d --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseClass.tpl @@ -0,0 +1,108 @@ +setCodeCoverage( + new CodeCoverage( + null, + unserialize('{codeCoverageFilter}') + ) + ); + } + + $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything}); + $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests}); + $result->enforceTimeLimit({enforcesTimeLimit}); + $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests}); + $result->beStrictAboutResourceUsageDuringSmallTests({isStrictAboutResourceUsageDuringSmallTests}); + + $test = new {className}('{name}', unserialize('{data}'), '{dataName}'); + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(TRUE); + + ob_end_clean(); + $test->run($result); + $output = ''; + if (!$test->hasExpectationOnOutput()) { + $output = $test->getActualOutput(); + } + + ini_set('xdebug.scream', '0'); + @rewind(STDOUT); /* @ as not every STDOUT target stream is rewindable */ + if ($stdout = stream_get_contents(STDOUT)) { + $output = $stdout . $output; + $streamMetaData = stream_get_meta_data(STDOUT); + if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) { + @ftruncate(STDOUT, 0); + @rewind(STDOUT); + } + } + + print serialize( + [ + 'testResult' => $test->getResult(), + 'numAssertions' => $test->getNumAssertions(), + 'result' => $result, + 'output' => $output + ] + ); +} + +$configurationFilePath = '{configurationFilePath}'; + +if ('' !== $configurationFilePath) { + $configuration = PHPUnit\Util\Configuration::getInstance($configurationFilePath); + $configuration->handlePHPConfiguration(); + unset($configuration); +} + +function __phpunit_error_handler($errno, $errstr, $errfile, $errline) +{ + return true; +} + +set_error_handler('__phpunit_error_handler'); + +{constants} +{included_files} +{globals} + +restore_error_handler(); + +if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + require_once $GLOBALS['__PHPUNIT_BOOTSTRAP']; + unset($GLOBALS['__PHPUNIT_BOOTSTRAP']); +} + +__phpunit_run_isolated_test(); diff --git a/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl new file mode 100644 index 0000000..68357ee --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/Template/TestCaseMethod.tpl @@ -0,0 +1,111 @@ +setCodeCoverage( + new CodeCoverage( + null, + unserialize('{codeCoverageFilter}') + ) + ); + } + + $result->beStrictAboutTestsThatDoNotTestAnything({isStrictAboutTestsThatDoNotTestAnything}); + $result->beStrictAboutOutputDuringTests({isStrictAboutOutputDuringTests}); + $result->enforceTimeLimit({enforcesTimeLimit}); + $result->beStrictAboutTodoAnnotatedTests({isStrictAboutTodoAnnotatedTests}); + $result->beStrictAboutResourceUsageDuringSmallTests({isStrictAboutResourceUsageDuringSmallTests}); + + $test = new {className}('{methodName}', unserialize('{data}'), '{dataName}'); + \assert($test instanceof TestCase); + + $test->setDependencyInput(unserialize('{dependencyInput}')); + $test->setInIsolation(true); + + ob_end_clean(); + $test->run($result); + $output = ''; + if (!$test->hasExpectationOnOutput()) { + $output = $test->getActualOutput(); + } + + ini_set('xdebug.scream', '0'); + @rewind(STDOUT); /* @ as not every STDOUT target stream is rewindable */ + if ($stdout = stream_get_contents(STDOUT)) { + $output = $stdout . $output; + $streamMetaData = stream_get_meta_data(STDOUT); + if (!empty($streamMetaData['stream_type']) && 'STDIO' === $streamMetaData['stream_type']) { + @ftruncate(STDOUT, 0); + @rewind(STDOUT); + } + } + + print serialize( + [ + 'testResult' => $test->getResult(), + 'numAssertions' => $test->getNumAssertions(), + 'result' => $result, + 'output' => $output + ] + ); +} + +$configurationFilePath = '{configurationFilePath}'; + +if ('' !== $configurationFilePath) { + $configuration = PHPUnit\Util\Configuration::getInstance($configurationFilePath); + $configuration->handlePHPConfiguration(); + unset($configuration); +} + +function __phpunit_error_handler($errno, $errstr, $errfile, $errline) +{ + return true; +} + +set_error_handler('__phpunit_error_handler'); + +{constants} +{included_files} +{globals} + +restore_error_handler(); + +if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + require_once $GLOBALS['__PHPUNIT_BOOTSTRAP']; + unset($GLOBALS['__PHPUNIT_BOOTSTRAP']); +} + +__phpunit_run_isolated_test(); diff --git a/vendor/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php b/vendor/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php new file mode 100644 index 0000000..844a372 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/PHP/WindowsPhpProcess.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\PHP; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + * + * @see https://bugs.php.net/bug.php?id=51800 + */ +final class WindowsPhpProcess extends DefaultPhpProcess +{ + public function getCommand(array $settings, string $file = null): string + { + return '"' . parent::getCommand($settings, $file) . '"'; + } + + /** + * @throws Exception + */ + protected function getHandles(): array + { + if (false === $stdout_handle = \tmpfile()) { + throw new Exception( + 'A temporary file could not be created; verify that your TEMP environment variable is writable' + ); + } + + return [ + 1 => $stdout_handle, + ]; + } + + protected function useTemporaryFile(): bool + { + return true; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Printer.php b/vendor/phpunit/phpunit/src/Util/Printer.php new file mode 100644 index 0000000..65abb4e --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Printer.php @@ -0,0 +1,145 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Exception; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class Printer +{ + /** + * If true, flush output after every write. + * + * @var bool + */ + protected $autoFlush = false; + + /** + * @psalm-var resource|closed-resource + */ + protected $out; + + /** + * @var string + */ + protected $outTarget; + + /** + * Constructor. + * + * @param null|resource|string $out + * + * @throws Exception + */ + public function __construct($out = null) + { + if ($out === null) { + return; + } + + if (\is_string($out) === false) { + $this->out = $out; + + return; + } + + if (\strpos($out, 'socket://') === 0) { + $out = \explode(':', \str_replace('socket://', '', $out)); + + if (\count($out) !== 2) { + throw new Exception; + } + + $this->out = \fsockopen($out[0], $out[1]); + } else { + if (\strpos($out, 'php://') === false && !Filesystem::createDirectory(\dirname($out))) { + throw new Exception(\sprintf('Directory "%s" was not created', \dirname($out))); + } + + $this->out = \fopen($out, 'wt'); + } + + $this->outTarget = $out; + } + + /** + * Flush buffer and close output if it's not to a PHP stream + */ + public function flush(): void + { + if ($this->out && \strncmp($this->outTarget, 'php://', 6) !== 0) { + \assert(\is_resource($this->out)); + + \fclose($this->out); + } + } + + /** + * Performs a safe, incremental flush. + * + * Do not confuse this function with the flush() function of this class, + * since the flush() function may close the file being written to, rendering + * the current object no longer usable. + */ + public function incrementalFlush(): void + { + if ($this->out) { + \assert(\is_resource($this->out)); + + \fflush($this->out); + } else { + \flush(); + } + } + + public function write(string $buffer): void + { + if ($this->out) { + \assert(\is_resource($this->out)); + + \fwrite($this->out, $buffer); + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } else { + if (\PHP_SAPI !== 'cli' && \PHP_SAPI !== 'phpdbg') { + $buffer = \htmlspecialchars($buffer, \ENT_SUBSTITUTE); + } + + print $buffer; + + if ($this->autoFlush) { + $this->incrementalFlush(); + } + } + } + + /** + * Check auto-flush mode. + */ + public function getAutoFlush(): bool + { + return $this->autoFlush; + } + + /** + * Set auto-flushing mode. + * + * If set, *incremental* flushes will be done after each write. This should + * not be confused with the different effects of this class' flush() method. + */ + public function setAutoFlush(bool $autoFlush): void + { + $this->autoFlush = $autoFlush; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/RegularExpression.php b/vendor/phpunit/phpunit/src/Util/RegularExpression.php new file mode 100644 index 0000000..97e33c9 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/RegularExpression.php @@ -0,0 +1,28 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class RegularExpression +{ + /** + * @return false|int + */ + public static function safeMatch(string $pattern, string $subject, ?array $matches = null, int $flags = 0, int $offset = 0) + { + return ErrorHandler::invokeIgnoringWarnings( + static function () use ($pattern, $subject, $matches, $flags, $offset) { + return \preg_match($pattern, $subject, $matches, $flags, $offset); + } + ); + } +} diff --git a/vendor/phpunit/phpunit/src/Util/Test.php b/vendor/phpunit/phpunit/src/Util/Test.php new file mode 100644 index 0000000..9b15e50 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/Test.php @@ -0,0 +1,894 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util; + +use PHPUnit\Framework\Assert; +use PHPUnit\Framework\CodeCoverageException; +use PHPUnit\Framework\InvalidCoversTargetException; +use PHPUnit\Framework\SelfDescribing; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\Warning; +use PHPUnit\Runner\Version; +use PHPUnit\Util\Annotation\Registry; +use SebastianBergmann\Environment\OperatingSystem; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class Test +{ + /** + * @var int + */ + public const UNKNOWN = -1; + + /** + * @var int + */ + public const SMALL = 0; + + /** + * @var int + */ + public const MEDIUM = 1; + + /** + * @var int + */ + public const LARGE = 2; + + /** + * @var array + */ + private static $hookMethods = []; + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + public static function describe(\PHPUnit\Framework\Test $test): array + { + if ($test instanceof TestCase) { + return [\get_class($test), $test->getName()]; + } + + if ($test instanceof SelfDescribing) { + return ['', $test->toString()]; + } + + return ['', \get_class($test)]; + } + + public static function describeAsString(\PHPUnit\Framework\Test $test): string + { + if ($test instanceof SelfDescribing) { + return $test->toString(); + } + + return \get_class($test); + } + + /** + * @throws CodeCoverageException + * + * @return array|bool + * @psalm-param class-string $className + */ + public static function getLinesToBeCovered(string $className, string $methodName) + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + if (!self::shouldCoversAnnotationBeUsed($annotations)) { + return false; + } + + return self::getLinesToBeCoveredOrUsed($className, $methodName, 'covers'); + } + + /** + * Returns lines of code specified with the @uses annotation. + * + * @throws CodeCoverageException + * @psalm-param class-string $className + */ + public static function getLinesToBeUsed(string $className, string $methodName): array + { + return self::getLinesToBeCoveredOrUsed($className, $methodName, 'uses'); + } + + public static function requiresCodeCoverageDataCollection(TestCase $test): bool + { + $annotations = $test->getAnnotations(); + + // If there is no @covers annotation but a @coversNothing annotation on + // the test method then code coverage data does not need to be collected + if (isset($annotations['method']['coversNothing'])) { + return false; + } + + // If there is at least one @covers annotation then + // code coverage data needs to be collected + if (isset($annotations['method']['covers'])) { + return true; + } + + // If there is no @covers annotation but a @coversNothing annotation + // then code coverage data does not need to be collected + if (isset($annotations['class']['coversNothing'])) { + return false; + } + + // If there is no @coversNothing annotation then + // code coverage data may be collected + return true; + } + + /** + * @throws Exception + * @psalm-param class-string $className + */ + public static function getRequirements(string $className, string $methodName): array + { + return self::mergeArraysRecursively( + Registry::getInstance()->forClassName($className)->requirements(), + Registry::getInstance()->forMethod($className, $methodName)->requirements() + ); + } + + /** + * Returns the missing requirements for a test. + * + * @throws Exception + * @throws Warning + * @psalm-param class-string $className + */ + public static function getMissingRequirements(string $className, string $methodName): array + { + $required = static::getRequirements($className, $methodName); + $missing = []; + $hint = null; + + if (!empty($required['PHP'])) { + $operator = new VersionComparisonOperator(empty($required['PHP']['operator']) ? '>=' : $required['PHP']['operator']); + + if (!\version_compare(\PHP_VERSION, $required['PHP']['version'], $operator->asString())) { + $missing[] = \sprintf('PHP %s %s is required.', $operator->asString(), $required['PHP']['version']); + $hint = 'PHP'; + } + } elseif (!empty($required['PHP_constraint'])) { + $version = new \PharIo\Version\Version(self::sanitizeVersionNumber(\PHP_VERSION)); + + if (!$required['PHP_constraint']['constraint']->complies($version)) { + $missing[] = \sprintf( + 'PHP version does not match the required constraint %s.', + $required['PHP_constraint']['constraint']->asString() + ); + + $hint = 'PHP_constraint'; + } + } + + if (!empty($required['PHPUnit'])) { + $phpunitVersion = Version::id(); + + $operator = new VersionComparisonOperator(empty($required['PHPUnit']['operator']) ? '>=' : $required['PHPUnit']['operator']); + + if (!\version_compare($phpunitVersion, $required['PHPUnit']['version'], $operator->asString())) { + $missing[] = \sprintf('PHPUnit %s %s is required.', $operator->asString(), $required['PHPUnit']['version']); + $hint = $hint ?? 'PHPUnit'; + } + } elseif (!empty($required['PHPUnit_constraint'])) { + $phpunitVersion = new \PharIo\Version\Version(self::sanitizeVersionNumber(Version::id())); + + if (!$required['PHPUnit_constraint']['constraint']->complies($phpunitVersion)) { + $missing[] = \sprintf( + 'PHPUnit version does not match the required constraint %s.', + $required['PHPUnit_constraint']['constraint']->asString() + ); + + $hint = $hint ?? 'PHPUnit_constraint'; + } + } + + if (!empty($required['OSFAMILY']) && $required['OSFAMILY'] !== (new OperatingSystem)->getFamily()) { + $missing[] = \sprintf('Operating system %s is required.', $required['OSFAMILY']); + $hint = $hint ?? 'OSFAMILY'; + } + + if (!empty($required['OS'])) { + $requiredOsPattern = \sprintf('/%s/i', \addcslashes($required['OS'], '/')); + + if (!\preg_match($requiredOsPattern, \PHP_OS)) { + $missing[] = \sprintf('Operating system matching %s is required.', $requiredOsPattern); + $hint = $hint ?? 'OS'; + } + } + + if (!empty($required['functions'])) { + foreach ($required['functions'] as $function) { + $pieces = \explode('::', $function); + + if (\count($pieces) === 2 && \class_exists($pieces[0]) && \method_exists($pieces[0], $pieces[1])) { + continue; + } + + if (\function_exists($function)) { + continue; + } + + $missing[] = \sprintf('Function %s is required.', $function); + $hint = $hint ?? 'function_' . $function; + } + } + + if (!empty($required['setting'])) { + foreach ($required['setting'] as $setting => $value) { + if (\ini_get($setting) !== $value) { + $missing[] = \sprintf('Setting "%s" must be "%s".', $setting, $value); + $hint = $hint ?? '__SETTING_' . $setting; + } + } + } + + if (!empty($required['extensions'])) { + foreach ($required['extensions'] as $extension) { + if (isset($required['extension_versions'][$extension])) { + continue; + } + + if (!\extension_loaded($extension)) { + $missing[] = \sprintf('Extension %s is required.', $extension); + $hint = $hint ?? 'extension_' . $extension; + } + } + } + + if (!empty($required['extension_versions'])) { + foreach ($required['extension_versions'] as $extension => $req) { + $actualVersion = \phpversion($extension); + + $operator = new VersionComparisonOperator(empty($req['operator']) ? '>=' : $req['operator']); + + if ($actualVersion === false || !\version_compare($actualVersion, $req['version'], $operator->asString())) { + $missing[] = \sprintf('Extension %s %s %s is required.', $extension, $operator->asString(), $req['version']); + $hint = $hint ?? 'extension_' . $extension; + } + } + } + + if ($hint && isset($required['__OFFSET'])) { + \array_unshift($missing, '__OFFSET_FILE=' . $required['__OFFSET']['__FILE']); + \array_unshift($missing, '__OFFSET_LINE=' . ($required['__OFFSET'][$hint] ?? 1)); + } + + return $missing; + } + + /** + * Returns the expected exception for a test. + * + * @return array|false + * + * @deprecated + * @codeCoverageIgnore + * @psalm-param class-string $className + */ + public static function getExpectedException(string $className, string $methodName) + { + return Registry::getInstance()->forMethod($className, $methodName)->expectedException(); + } + + /** + * Returns the provided data for a method. + * + * @throws Exception + * @psalm-param class-string $className + */ + public static function getProvidedData(string $className, string $methodName): ?array + { + return Registry::getInstance()->forMethod($className, $methodName)->getProvidedData(); + } + + /** + * @psalm-param class-string $className + */ + public static function parseTestMethodAnnotations(string $className, ?string $methodName = ''): array + { + $registry = Registry::getInstance(); + + if ($methodName !== null) { + try { + return [ + 'method' => $registry->forMethod($className, $methodName)->symbolAnnotations(), + 'class' => $registry->forClassName($className)->symbolAnnotations(), + ]; + } catch (Exception $methodNotFound) { + // ignored + } + } + + return [ + 'method' => null, + 'class' => $registry->forClassName($className)->symbolAnnotations(), + ]; + } + + /** + * @psalm-param class-string $className + */ + public static function getInlineAnnotations(string $className, string $methodName): array + { + return Registry::getInstance()->forMethod($className, $methodName)->getInlineAnnotations(); + } + + /** @psalm-param class-string $className */ + public static function getBackupSettings(string $className, string $methodName): array + { + return [ + 'backupGlobals' => self::getBooleanAnnotationSetting( + $className, + $methodName, + 'backupGlobals' + ), + 'backupStaticAttributes' => self::getBooleanAnnotationSetting( + $className, + $methodName, + 'backupStaticAttributes' + ), + ]; + } + + /** @psalm-param class-string $className */ + public static function getDependencies(string $className, string $methodName): array + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $dependencies = $annotations['class']['depends'] ?? []; + + if (isset($annotations['method']['depends'])) { + $dependencies = \array_merge( + $dependencies, + $annotations['method']['depends'] + ); + } + + return \array_unique($dependencies); + } + + /** @psalm-param class-string $className */ + public static function getGroups(string $className, ?string $methodName = ''): array + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $groups = []; + + if (isset($annotations['method']['author'])) { + $groups[] = $annotations['method']['author']; + } elseif (isset($annotations['class']['author'])) { + $groups[] = $annotations['class']['author']; + } + + if (isset($annotations['class']['group'])) { + $groups[] = $annotations['class']['group']; + } + + if (isset($annotations['method']['group'])) { + $groups[] = $annotations['method']['group']; + } + + if (isset($annotations['class']['ticket'])) { + $groups[] = $annotations['class']['ticket']; + } + + if (isset($annotations['method']['ticket'])) { + $groups[] = $annotations['method']['ticket']; + } + + foreach (['method', 'class'] as $element) { + foreach (['small', 'medium', 'large'] as $size) { + if (isset($annotations[$element][$size])) { + $groups[] = [$size]; + + break 2; + } + } + } + + return \array_unique(\array_merge([], ...$groups)); + } + + /** @psalm-param class-string $className */ + public static function getSize(string $className, ?string $methodName): int + { + $groups = \array_flip(self::getGroups($className, $methodName)); + + if (isset($groups['large'])) { + return self::LARGE; + } + + if (isset($groups['medium'])) { + return self::MEDIUM; + } + + if (isset($groups['small'])) { + return self::SMALL; + } + + return self::UNKNOWN; + } + + /** @psalm-param class-string $className */ + public static function getProcessIsolationSettings(string $className, string $methodName): bool + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + return isset($annotations['class']['runTestsInSeparateProcesses']) || isset($annotations['method']['runInSeparateProcess']); + } + + /** @psalm-param class-string $className */ + public static function getClassProcessIsolationSettings(string $className, string $methodName): bool + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + return isset($annotations['class']['runClassInSeparateProcess']); + } + + /** @psalm-param class-string $className */ + public static function getPreserveGlobalStateSettings(string $className, string $methodName): ?bool + { + return self::getBooleanAnnotationSetting( + $className, + $methodName, + 'preserveGlobalState' + ); + } + + /** @psalm-param class-string $className */ + public static function getHookMethods(string $className): array + { + if (!\class_exists($className, false)) { + return self::emptyHookMethodsArray(); + } + + if (!isset(self::$hookMethods[$className])) { + self::$hookMethods[$className] = self::emptyHookMethodsArray(); + + try { + foreach ((new \ReflectionClass($className))->getMethods() as $method) { + if ($method->getDeclaringClass()->getName() === Assert::class) { + continue; + } + + if ($method->getDeclaringClass()->getName() === TestCase::class) { + continue; + } + + $docBlock = Registry::getInstance()->forMethod($className, $method->getName()); + + if ($method->isStatic()) { + if ($docBlock->isHookToBeExecutedBeforeClass()) { + \array_unshift( + self::$hookMethods[$className]['beforeClass'], + $method->getName() + ); + } + + if ($docBlock->isHookToBeExecutedAfterClass()) { + self::$hookMethods[$className]['afterClass'][] = $method->getName(); + } + } + + if ($docBlock->isToBeExecutedBeforeTest()) { + \array_unshift( + self::$hookMethods[$className]['before'], + $method->getName() + ); + } + + if ($docBlock->isToBeExecutedAfterTest()) { + self::$hookMethods[$className]['after'][] = $method->getName(); + } + } + } catch (\ReflectionException $e) { + } + } + + return self::$hookMethods[$className]; + } + + public static function isTestMethod(\ReflectionMethod $method): bool + { + if (\strpos($method->getName(), 'test') === 0) { + return true; + } + + return \array_key_exists( + 'test', + Registry::getInstance()->forMethod( + $method->getDeclaringClass()->getName(), + $method->getName() + ) + ->symbolAnnotations() + ); + } + + /** + * @throws CodeCoverageException + * @psalm-param class-string $className + */ + private static function getLinesToBeCoveredOrUsed(string $className, string $methodName, string $mode): array + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + $classShortcut = null; + + if (!empty($annotations['class'][$mode . 'DefaultClass'])) { + if (\count($annotations['class'][$mode . 'DefaultClass']) > 1) { + throw new CodeCoverageException( + \sprintf( + 'More than one @%sClass annotation in class or interface "%s".', + $mode, + $className + ) + ); + } + + $classShortcut = $annotations['class'][$mode . 'DefaultClass'][0]; + } + + $list = $annotations['class'][$mode] ?? []; + + if (isset($annotations['method'][$mode])) { + $list = \array_merge($list, $annotations['method'][$mode]); + } + + $codeList = []; + + foreach (\array_unique($list) as $element) { + if ($classShortcut && \strncmp($element, '::', 2) === 0) { + $element = $classShortcut . $element; + } + + $element = \preg_replace('/[\s()]+$/', '', $element); + $element = \explode(' ', $element); + $element = $element[0]; + + if ($mode === 'covers' && \interface_exists($element)) { + throw new InvalidCoversTargetException( + \sprintf( + 'Trying to @cover interface "%s".', + $element + ) + ); + } + + $codeList[] = self::resolveElementToReflectionObjects($element); + } + + return self::resolveReflectionObjectsToLines(\array_merge([], ...$codeList)); + } + + private static function emptyHookMethodsArray(): array + { + return [ + 'beforeClass' => ['setUpBeforeClass'], + 'before' => ['setUp'], + 'after' => ['tearDown'], + 'afterClass' => ['tearDownAfterClass'], + ]; + } + + /** @psalm-param class-string $className */ + private static function getBooleanAnnotationSetting(string $className, ?string $methodName, string $settingName): ?bool + { + $annotations = self::parseTestMethodAnnotations( + $className, + $methodName + ); + + if (isset($annotations['method'][$settingName])) { + if ($annotations['method'][$settingName][0] === 'enabled') { + return true; + } + + if ($annotations['method'][$settingName][0] === 'disabled') { + return false; + } + } + + if (isset($annotations['class'][$settingName])) { + if ($annotations['class'][$settingName][0] === 'enabled') { + return true; + } + + if ($annotations['class'][$settingName][0] === 'disabled') { + return false; + } + } + + return null; + } + + /** + * @throws InvalidCoversTargetException + */ + private static function resolveElementToReflectionObjects(string $element): array + { + $codeToCoverList = []; + + if (\function_exists($element) && \strpos($element, '\\') !== false) { + try { + $codeToCoverList[] = new \ReflectionFunction($element); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } elseif (\strpos($element, '::') !== false) { + [$className, $methodName] = \explode('::', $element); + + if (isset($methodName[0]) && $methodName[0] === '<') { + $classes = [$className]; + + foreach ($classes as $className) { + if (!\class_exists($className) && + !\interface_exists($className) && + !\trait_exists($className)) { + throw new InvalidCoversTargetException( + \sprintf( + 'Trying to @cover or @use not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + try { + $methods = (new \ReflectionClass($className))->getMethods(); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + + $inverse = isset($methodName[1]) && $methodName[1] === '!'; + $visibility = 'isPublic'; + + if (\strpos($methodName, 'protected')) { + $visibility = 'isProtected'; + } elseif (\strpos($methodName, 'private')) { + $visibility = 'isPrivate'; + } + + foreach ($methods as $method) { + if ($inverse && !$method->$visibility()) { + $codeToCoverList[] = $method; + } elseif (!$inverse && $method->$visibility()) { + $codeToCoverList[] = $method; + } + } + } + } else { + $classes = [$className]; + + foreach ($classes as $className) { + if ($className === '' && \function_exists($methodName)) { + try { + $codeToCoverList[] = new \ReflectionFunction( + $methodName + ); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } else { + if (!((\class_exists($className) || \interface_exists($className) || \trait_exists($className)) && + \method_exists($className, $methodName))) { + throw new InvalidCoversTargetException( + \sprintf( + 'Trying to @cover or @use not existing method "%s::%s".', + $className, + $methodName + ) + ); + } + + try { + $codeToCoverList[] = new \ReflectionMethod( + $className, + $methodName + ); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + } + } + } else { + $extended = false; + + if (\strpos($element, '') !== false) { + $element = \str_replace('', '', $element); + $extended = true; + } + + $classes = [$element]; + + if ($extended) { + $classes = \array_merge( + $classes, + \class_implements($element), + \class_parents($element) + ); + } + + foreach ($classes as $className) { + if (!\class_exists($className) && + !\interface_exists($className) && + !\trait_exists($className)) { + throw new InvalidCoversTargetException( + \sprintf( + 'Trying to @cover or @use not existing class or ' . + 'interface "%s".', + $className + ) + ); + } + + try { + $codeToCoverList[] = new \ReflectionClass($className); + // @codeCoverageIgnoreStart + } catch (\ReflectionException $e) { + throw new Exception( + $e->getMessage(), + (int) $e->getCode(), + $e + ); + } + // @codeCoverageIgnoreEnd + } + } + + return $codeToCoverList; + } + + private static function resolveReflectionObjectsToLines(array $reflectors): array + { + $result = []; + + foreach ($reflectors as $reflector) { + if ($reflector instanceof \ReflectionClass) { + foreach ($reflector->getTraits() as $trait) { + $reflectors[] = $trait; + } + } + } + + foreach ($reflectors as $reflector) { + $filename = $reflector->getFileName(); + + if (!isset($result[$filename])) { + $result[$filename] = []; + } + + $result[$filename] = \array_merge( + $result[$filename], + \range($reflector->getStartLine(), $reflector->getEndLine()) + ); + } + + foreach ($result as $filename => $lineNumbers) { + $result[$filename] = \array_keys(\array_flip($lineNumbers)); + } + + return $result; + } + + /** + * Trims any extensions from version string that follows after + * the .[.] format + */ + private static function sanitizeVersionNumber(string $version) + { + return \preg_replace( + '/^(\d+\.\d+(?:.\d+)?).*$/', + '$1', + $version + ); + } + + private static function shouldCoversAnnotationBeUsed(array $annotations): bool + { + if (isset($annotations['method']['coversNothing'])) { + return false; + } + + if (isset($annotations['method']['covers'])) { + return true; + } + + if (isset($annotations['class']['coversNothing'])) { + return false; + } + + return true; + } + + /** + * Merge two arrays together. + * + * If an integer key exists in both arrays and preserveNumericKeys is false, the value + * from the second array will be appended to the first array. If both values are arrays, they + * are merged together, else the value of the second array overwrites the one of the first array. + * + * This implementation is copied from https://github.com/zendframework/zend-stdlib/blob/76b653c5e99b40eccf5966e3122c90615134ae46/src/ArrayUtils.php + * + * Zend Framework (http://framework.zend.com/) + * + * @link http://github.com/zendframework/zf2 for the canonical source repository + * + * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) + * @license http://framework.zend.com/license/new-bsd New BSD License + */ + private static function mergeArraysRecursively(array $a, array $b): array + { + foreach ($b as $key => $value) { + if (\array_key_exists($key, $a)) { + if (\is_int($key)) { + $a[] = $value; + } elseif (\is_array($value) && \is_array($a[$key])) { + $a[$key] = self::mergeArraysRecursively($a[$key], $value); + } else { + $a[$key] = $value; + } + } else { + $a[$key] = $value; + } + } + + return $a; + } +} diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php b/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php new file mode 100644 index 0000000..b76d223 --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/TestDox/CliTestDoxPrinter.php @@ -0,0 +1,352 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\TestDox; + +use PHPUnit\Framework\Test; +use PHPUnit\Framework\TestCase; +use PHPUnit\Framework\TestResult; +use PHPUnit\Runner\BaseTestRunner; +use PHPUnit\Runner\PhptTestCase; +use PHPUnit\Util\Color; +use SebastianBergmann\Timer\Timer; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +class CliTestDoxPrinter extends TestDoxPrinter +{ + /** + * The default Testdox left margin for messages is a vertical line + */ + private const PREFIX_SIMPLE = [ + 'default' => '│', + 'start' => '│', + 'message' => '│', + 'diff' => '│', + 'trace' => '│', + 'last' => '│', + ]; + + /** + * Colored Testdox use box-drawing for a more textured map of the message + */ + private const PREFIX_DECORATED = [ + 'default' => '│', + 'start' => 'â”', + 'message' => '├', + 'diff' => '┊', + 'trace' => '╵', + 'last' => 'â”´', + ]; + + private const SPINNER_ICONS = [ + " \e[36mâ—\e[0m running tests", + " \e[36mâ—“\e[0m running tests", + " \e[36mâ—‘\e[0m running tests", + " \e[36mâ—’\e[0m running tests", + ]; + + private const STATUS_STYLES = [ + BaseTestRunner::STATUS_PASSED => [ + 'symbol' => '✔', + 'color' => 'fg-green', + ], + BaseTestRunner::STATUS_ERROR => [ + 'symbol' => '✘', + 'color' => 'fg-yellow', + 'message' => 'bg-yellow,fg-black', + ], + BaseTestRunner::STATUS_FAILURE => [ + 'symbol' => '✘', + 'color' => 'fg-red', + 'message' => 'bg-red,fg-white', + ], + BaseTestRunner::STATUS_SKIPPED => [ + 'symbol' => '↩', + 'color' => 'fg-cyan', + 'message' => 'fg-cyan', + ], + BaseTestRunner::STATUS_RISKY => [ + 'symbol' => '☢', + 'color' => 'fg-yellow', + 'message' => 'fg-yellow', + ], + BaseTestRunner::STATUS_INCOMPLETE => [ + 'symbol' => '∅', + 'color' => 'fg-yellow', + 'message' => 'fg-yellow', + ], + BaseTestRunner::STATUS_WARNING => [ + 'symbol' => 'âš ', + 'color' => 'fg-yellow', + 'message' => 'fg-yellow', + ], + BaseTestRunner::STATUS_UNKNOWN => [ + 'symbol' => '?', + 'color' => 'fg-blue', + 'message' => 'fg-white,bg-blue', + ], + ]; + + /** + * @var int[] + */ + private $nonSuccessfulTestResults = []; + + /** + * @throws \SebastianBergmann\Timer\RuntimeException + */ + public function printResult(TestResult $result): void + { + $this->printHeader($result); + + $this->printNonSuccessfulTestsSummary($result->count()); + + $this->printFooter($result); + } + + /** + * @throws \SebastianBergmann\Timer\RuntimeException + */ + protected function printHeader(TestResult $result): void + { + $this->write("\n" . Timer::resourceUsage() . "\n\n"); + } + + protected function formatClassName(Test $test): string + { + if ($test instanceof TestCase) { + return $this->prettifier->prettifyTestClass(\get_class($test)); + } + + return \get_class($test); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function registerTestResult(Test $test, ?\Throwable $t, int $status, float $time, bool $verbose): void + { + if ($status !== BaseTestRunner::STATUS_PASSED) { + $this->nonSuccessfulTestResults[] = $this->testIndex; + } + + parent::registerTestResult($test, $t, $status, $time, $verbose); + } + + /** + * @throws \SebastianBergmann\RecursionContext\InvalidArgumentException + */ + protected function formatTestName(Test $test): string + { + if ($test instanceof TestCase) { + return $this->prettifier->prettifyTestCase($test); + } + + return parent::formatTestName($test); + } + + protected function writeTestResult(array $prevResult, array $result): void + { + // spacer line for new suite headers and after verbose messages + if ($prevResult['testName'] !== '' && + (!empty($prevResult['message']) || $prevResult['className'] !== $result['className'])) { + $this->write(\PHP_EOL); + } + + // suite header + if ($prevResult['className'] !== $result['className']) { + $this->write($this->colorizeTextBox('underlined', $result['className']) . \PHP_EOL); + } + + // test result line + if ($this->colors && $result['className'] === PhptTestCase::class) { + $testName = Color::colorizePath($result['testName'], $prevResult['testName'], true); + } else { + $testName = $result['testMethod']; + } + + $style = self::STATUS_STYLES[$result['status']]; + $line = \sprintf( + ' %s %s%s' . \PHP_EOL, + $this->colorizeTextBox($style['color'], $style['symbol']), + $testName, + $this->verbose ? ' ' . $this->formatRuntime($result['time'], $style['color']) : '' + ); + + $this->write($line); + + // additional information when verbose + $this->write($result['message']); + } + + protected function formatThrowable(\Throwable $t, ?int $status = null): string + { + return \trim(\PHPUnit\Framework\TestFailure::exceptionToString($t)); + } + + protected function colorizeMessageAndDiff(string $style, string $buffer): array + { + $lines = $buffer ? \array_map('\rtrim', \explode(\PHP_EOL, $buffer)) : []; + $message = []; + $diff = []; + $insideDiff = false; + + foreach ($lines as $line) { + if ($line === '--- Expected') { + $insideDiff = true; + } + + if (!$insideDiff) { + $message[] = $line; + } else { + if (\strpos($line, '-') === 0) { + $line = Color::colorize('fg-red', Color::visualizeWhitespace($line, true)); + } elseif (\strpos($line, '+') === 0) { + $line = Color::colorize('fg-green', Color::visualizeWhitespace($line, true)); + } elseif ($line === '@@ @@') { + $line = Color::colorize('fg-cyan', $line); + } + $diff[] = $line; + } + } + $diff = \implode(\PHP_EOL, $diff); + + if (!empty($message)) { + $message = $this->colorizeTextBox($style, \implode(\PHP_EOL, $message)); + } + + return [$message, $diff]; + } + + protected function formatStacktrace(\Throwable $t): string + { + $trace = \PHPUnit\Util\Filter::getFilteredStacktrace($t); + + if (!$this->colors) { + return $trace; + } + + $lines = []; + $prevPath = ''; + + foreach (\explode(\PHP_EOL, $trace) as $line) { + if (\preg_match('/^(.*):(\d+)$/', $line, $matches)) { + $lines[] = Color::colorizePath($matches[1], $prevPath) . + Color::dim(':') . + Color::colorize('fg-blue', $matches[2]) . + "\n"; + $prevPath = $matches[1]; + } else { + $lines[] = $line; + $prevPath = ''; + } + } + + return \implode('', $lines); + } + + protected function formatTestResultMessage(\Throwable $t, array $result, ?string $prefix = null): string + { + $message = $this->formatThrowable($t, $result['status']); + $diff = ''; + + if (!($this->verbose || $result['verbose'])) { + return ''; + } + + if ($message && $this->colors) { + $style = self::STATUS_STYLES[$result['status']]['message'] ?? ''; + [$message, $diff] = $this->colorizeMessageAndDiff($style, $message); + } + + if ($prefix === null || !$this->colors) { + $prefix = self::PREFIX_SIMPLE; + } + + if ($this->colors) { + $color = self::STATUS_STYLES[$result['status']]['color'] ?? ''; + $prefix = \array_map(static function ($p) use ($color) { + return Color::colorize($color, $p); + }, self::PREFIX_DECORATED); + } + + $trace = $this->formatStacktrace($t); + $out = $this->prefixLines($prefix['start'], \PHP_EOL) . \PHP_EOL; + + if ($message) { + $out .= $this->prefixLines($prefix['message'], $message . \PHP_EOL) . \PHP_EOL; + } + + if ($diff) { + $out .= $this->prefixLines($prefix['diff'], $diff . \PHP_EOL) . \PHP_EOL; + } + + if ($trace) { + if ($message || $diff) { + $out .= $this->prefixLines($prefix['default'], \PHP_EOL) . \PHP_EOL; + } + $out .= $this->prefixLines($prefix['trace'], $trace . \PHP_EOL) . \PHP_EOL; + } + $out .= $this->prefixLines($prefix['last'], \PHP_EOL) . \PHP_EOL; + + return $out; + } + + protected function drawSpinner(): void + { + if ($this->colors) { + $id = $this->spinState % \count(self::SPINNER_ICONS); + $this->write(self::SPINNER_ICONS[$id]); + } + } + + protected function undrawSpinner(): void + { + if ($this->colors) { + $id = $this->spinState % \count(self::SPINNER_ICONS); + $this->write("\e[1K\e[" . \strlen(self::SPINNER_ICONS[$id]) . 'D'); + } + } + + private function formatRuntime(float $time, string $color = ''): string + { + if (!$this->colors) { + return \sprintf('[%.2f ms]', $time * 1000); + } + + if ($time > 1) { + $color = 'fg-magenta'; + } + + return Color::colorize($color, ' ' . (int) \ceil($time * 1000) . ' ' . Color::dim('ms')); + } + + private function printNonSuccessfulTestsSummary(int $numberOfExecutedTests): void + { + if (empty($this->nonSuccessfulTestResults)) { + return; + } + + if ((\count($this->nonSuccessfulTestResults) / $numberOfExecutedTests) >= 0.7) { + return; + } + + $this->write("Summary of non-successful tests:\n\n"); + + $prevResult = $this->getEmptyTestResult(); + + foreach ($this->nonSuccessfulTestResults as $testIndex) { + $result = $this->testResults[$testIndex]; + $this->writeTestResult($prevResult, $result); + $prevResult = $result; + } + } +} diff --git a/vendor/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php b/vendor/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php new file mode 100644 index 0000000..1beb8be --- /dev/null +++ b/vendor/phpunit/phpunit/src/Util/TestDox/HtmlResultPrinter.php @@ -0,0 +1,131 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +namespace PHPUnit\Util\TestDox; + +/** + * @internal This class is not covered by the backward compatibility promise for PHPUnit + */ +final class HtmlResultPrinter extends ResultPrinter +{ + /** + * @var string + */ + private const PAGE_HEADER = << + + + + Test Documentation + + + +EOT; + + /** + * @var string + */ + private const CLASS_HEADER = <<%s +

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�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%0D`P|=8@u+UQ%=z7R+43L4Zl8#;T;K1r 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≤GWXA<}4NfYWI^m11sQ58*e$_lfk}0Xc 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

9nyP&)%1+Th)t@ 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%0DpUJh6t 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%0DLs-B8qbLv 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ℌ*IIa96aU~;z(a&l-;O~SwKYI>8=rHgfLY=eO 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�f zQtCH<=0f%RFa^5ICEWq0)KnkMpgGr|*xS!d_3~KnuD)&B z;N!mAlS^{%dh5jM)D(~RP_U0@IqwpaP2u1#aB_s%GrEB_woO@A{_f_IqWgwMM6HkZg`$_) zfSV?Edxu3jSu0xANiY6e*^QQg>dU4nO5draNcUe*d85BJ0xyW?V>uM(rctXQJuGNY z4ieH&xjz}y$o8y7trW$(= zvE4&IKabTIJHnQ_eT(N`o2N{=b#mr3HmnexVj`kH{Yun}(v zvLS(epuBBCPi!F1Xv*fGv?}@EP!JnU^=-*WG55BZeXL(!MHw)BM`Gf%X{=0G%knA5 z*!#cMP!%s5U%^ZG1U5tt13DGZa__)ny)&ON`RUW1nXIpdFw;*LTu}Tg7XkK#Fh-h28 z_RCi|;=tMcAHfRoBHGFJtNs7tMQ)O$Hgnxr|KDtM#=Jirj#mfJ+AT?Ac#(Qz5IUHVkVl?}^yX00x)aY~oIG80_W@V5pdCTwfH zY-p=eY_MZ5zGD&pZu**$dOhjz>5!`vF%pb#q~=Lh?VJ5#U+!dWsxmBhzB24S=;5Y= zpr;zjDRLJZ3eq0=#EL4`J+1K(Di0F-w1HxudwBVlnXfn^`OVpsaAW{5FC=y*QC9xttrSl(F-e24`CZ_A+dn+B` z{Kr<~npE)iuFzy$D@VB6txmtCD|W6}+ON(%Yf9TrqdK)sv7#L$PVG0$aZEDQi(bii zDz`rSn>AIF9LJPle2f^iFSnfwPjqL9iCm%h2p)hx;EP9_t3Az9Qnp>6UFF$Xe#gIh zmzHX`8Vjzz!#X)8urhJvR%_r2{}l=ugCaGJGL7x-zwLn-g@b8spj%F}bbUh-a{=T9?S-rp{= zH9O@k)q*9|PU1kn+AiuDaO})LZ3S>=d5n)PaI~{J8+hzmxcFW^0Vlwdo_AkKH{e)< z!yB0E5*+0-4EPiY$J!O(&};RCqzAhQP#SX_3GV=<|5PvU_(S&e@+MjVrg!j6G3qv+ zRWQk=4LtiW@3tz`f#6TahrvXDhrP=G%*VG5mLrZu8qd;&zjDiF_vn(K)- zQYG9!?{D=ZyOXW&fD^Ig0oh6X222m*WpTfAvk!@@f5;eQn5UTUqTAu?=SI`G<{PfekZ(W z{NXR)myjaxhra~B6K>$o`^(Zro#iSYbYhXwed3vD&z6eaoKdA@wm zSJMl@i^dOXpTjR9h4A;6ctB^7_?>W9{AZo?Yt7h2$2a-(pGDu5kV5#kYTXH*mo0`o zN53oFiT{GzW^)tZKP2@hRQpRkDDj_gUj?{5NJ4-IJzmcxuddYL?3#KIaO~07;o21) z&O;-g7*;@UAK6ZCg7^nbbOW8f$F zRf793H{jefPuFwJqSU1J+5jS4k(l5hVk1 z09-2pIP{+&Xvd9GPpEupt&+1mdS9fdcq;s@icA`FZrc0p?B^ zF>r3gjHEI#3O4%{fKy?6<;j2hqA|UqJFTs6x$FJ7oAdP!OEtcLt?^evx;*vx^(PWEhIXiW=u?2 zFE*iei)ibVNS2&uIu%^eBP6Vh<5FBqXrA5|FuuJ@H2Z&^|NW5s{)Oxlk|#?;$N)TH z%&DPzl03DR@LlO=jtpKjKiNqhGGV{g){M0rs_~lc=L-KIJA7W~1 z-e|yG@f&c{B(cL>gWm_<9NFfRFh)1T)hU$O#b`;J9Vv%t=4+4fp`Ek&X%wmXt%2H; z(#59ri>tl4T<6KZd@%2m6=FkamRa^pO7ki;ucTOev&?Yr+1+CuB1F}DZ1}c9RQaCl zwRt<&P2bfdz^BUFT}N-cfj}dT-;x$BQ0ip^5v$WA;h;$kgUk|1HqhDz4&+lHUitrL z{8*UxkwsHIf%hsZ#N8s`HG)6FzO~ZwEGz9NwBo=SHgQFn>~S*k;bfT7;hX%BsE*DB zV=|hEB@=ZN`*JdFVVkufEvqVCyS0JlcrT5k?bz*yM+tHol&bfgz z^GsPog@XmHk4^chX;M_l)}ek?KV@+aK6HGqxt2ddr&Oz)HA>gPypJ>=qSOC-{X6=1 z27iR_KS(((%sXv<-F!v%_n}%E_!;1YTV?`o^S>l@D3s%AzD^7P9DM}36>4g#eVeZn z1cxrWz{zfO)8f%*hDv#lF{OxDlqWkAOmP37o`XLz=8V9i~3hCulJ9sc`=eNGx0_I2#4gSfRF85_h&;)--zwt?-hf;?S{YX zgd=ieV!7{V&?k!r#SMHSRZDbYY)pdqQVjN7z~ zyru?3+hYD=3hS}JQw%l_TT!w0;f9S(%u&*esDQ;zxhH(+06lhY!+1o?fEt2n>cY+? z%Ez=zYNULk4jpoQaP5*K%(Yo`s8TE@uFT9PjZ2u}`pf#vp8S@9rxaNt5^+j`Zij4k z9nY)P8}kA@f9ZJ2SIEZ$8C6pc@~P&Puo@%sx)5q=SG3|*6InN6pP$HRuBt=p6i_RljlYxV)%(^^dg@~L@`foGJn zPMr?zG+?8hFr5y->^jVajt}`%NynJNWdXBm5>`+a`I_~*#uk(X>=HAftc2y4^;OUE zE#^m{VO&93DT_xaD`EL%o2cLOK}cC|(Z&}p3z%Jp<(FM*Dy>Xb9^iWmDPLGue%rDU z{jaUG6BF{fvSW}t;7S1Cc1=Q{pRY@~!#m@?mWTP}C!%~8$PsXq2b{`*5(6&%pl<3H zz%#K3d*cGv?Tu-*@Zgjm-bv4-Jorz*54aLQa09;+F8dkq8}|3?WK|(cAXa6i z)@Q@j_0M+07UY>Sx=TFUdL(|e8R*gRhq~ei9RBZ%_|+c> z{v!TDa2@~i^QT~CjVT)RKR-VU#=QTCE;nO-6U>K_JoD#gYmE7m6JB_JW2X5Z+TFk_ zbEW8wPA&(2bWb`kArhIYtw@JN>((hYI?EA*ELk|mW>XJ0uGyw;yR~B*)`<5V*!par zj`vuF3me4_(e(7{d6_5MEScGrd7VZAh^P{t-n?#&1*36qR{Dh38b#OJaC&V2j1}VE z40dwmjosTOHdp-p$}m%HTb_x*(97|S_>$*6h#VX$N=}InLMkQ@MnA^jg|wDEn-1-= zvf=hdO&=a%L4R}_I%VeYoTEpwdR>@1e_%KEPl#7>Pb8AZF~{imMtP>ly3I0L#6~ew zR7?Ye%bay#t|@oX6~>J{tPXlf zcCs$zUC0`BNf}*Md~~>00&tQwAfRodYvUS7Yd@eE?y-{zdll;8q&EZJK_gl0& zrbl(glG|K1NZopBXop~fOxf8Qm z8SoNiN?=X6XNj1;pKM(H;pm?mRw!Gy-ACyG!5c)+diB>#8dW{1a??TeB8o>8sZSmE zM3k;j;k)tu5_%quuNs|a8sqKR2?zHorG%9X`P4NFp z(kKXda5#ZDs`-LG6%v8P6C!Yo5G~lNEOX9USFQ1KbamyMnKb`r?cVEMpd22HT^N?_ zVa`MS#pSsQ*M^5*P?#2rS^2a8w+HGUip^Bc`VZ`I(K)f!wPL72z7BrpD{*jTh^hkw`YX4O_>@qmUJ5>60W`3yhC$_ z1ln-v)~`G;XT*?FrOK8q8&xhPu|kE!lrk}8%T}rr9Z)gPbQ#OI(!W!;sAXji78%XM z;O=AARNbwE(?x@QtdEUv7*nHD(>=d@goF$Wzn(eh{VBcd)jT}TOlH};_@Alm29>Vq zAJ+qU7P}(qv-1E??3cf@-3O|F?L*=Q#c6hGG$dOS5JD?79Ehu+P9ifw@UpAZ6j+mPYsJ? zylE>QG-%emW8wtXjVVZ)U2Wp<-eVIQJEyo!)rG^E#iLZYK-@Ukc2HTn$5{6gp=E;n zyvtOo_^Q3!vn>t%{1}f&KTg5Ziq!+G_WIr5Q$8@}#7@1&S^!xwxwAzQ|NQ!dpX_Js zAu0{O3x_5tU<}Fxv$g<|IJCrOd&V12vbEBrty0Ffm>o@H%)1pM!p#6HzmK%)Mhl8*Nf|HM{e5>~$2kgF8! zUl90|flwLyR9`V#ci=$M-+8d54Ji(;4U+nc@8*tt0y3{jKO!1|Ik_Vbs}#v8cIQ1% zhDAjsvCh{>S^?d6`Rz=R$3EwqnTRdpV>$PKQ_wN@Sm1nB%^I=d}nV{nSZk+p- zN(>7vL40Fu&AX&_0gXPU@@O3w0?5`U#3M(Q^cu-;l${Qff5TexKcj-oHjmP!d?GZp zM2+fpQ7>iy(RV1wt;d*?cPE5eQv0qSSu3UDk5scclxns{g!z}=(=EMrOxsOKaq}Cr ztyjV;j+t!e5|S2eC}^=7ck+-|>#U75h1^&A(Wlvk#HCZKO+?l2?J6u6lBHhD^&i+<8?8mjx#0$y8)97u>p$?r$bN6&xa)-0fpq)F+rq!H zQM^ss`}Q=Jlb?(D5y25}D}bA1Jd59e{tS`&BjZ?@?-+T3NgAXW3Gse5oQ*D!1mJea ziiR$Jq=cKQbuCk&es`v^OdjoDroKnhn;8x3`V6>RrP`UR{aMY@2_=JyMMfvbvGvw~ z)AL(}qUS`Fimt=F;tqa12c{O}K`-PQ5BgC#nO|C;Bp_B!)gs%qkE*Anl}ceWk}-Ue z9VXq;Z8MMUi5+Pb!+bgO3Ygix8dAK4JgMu~W!$ef7x&AX{aTCW$;D#EROAB#qsrC@ z4;bffiBVaT8Wn7%tQ8_6qWwy;w|q5bs`|yjeTh}qwIA9ihM7ES1vY9h1bMxV){3uL zMXMKKjj3rd=tdvJS`<#h#8BLdwtXhVNbQ9Ulu8^+YK3i;I)N1aC-Xz6=P?V~t*xGQ zm8oOeZ$R>@SsU7q5xG}qt=3NQ3Vw~-bnVrsLUMA2M!mYWY0ONYX3uABQ~Qp|!ot~@ zzNu~5{OnH=QFtY>a@B@n&Zve}D<{4JVd}91wHsf8cE$P-^qk@s!F&nyJkFTA8E!{P zvQ%(fv_T?7SR;_s-Vbu6ulmd_k$)E1^SjPH+`<+OT=A%Dha`W?fiv#4yMFW7@#XK^ zceL+a(_AUsUN$@;Iwooy*IKrDJ+b`yDrFg~ma?*H%RE!3-fuN&jk{Y*h9#%6C1vcv zjD<&pRq&&`N1@Aw)^KDzL$2XakHnl?#rR4q>_n!NA4qfhObJLAZ3MuKqYeJy&Q{QBv$sVQRn#4C-%2=OvN#QlO4eD6m*HWQs-EYdUh<;DzcIrK) zep#RB(ovy4u^zE)dQ@s06n$W2o@viw#m81Yxa64KL@Vs8>pEHppQEp%VZWBXjwT`K zkIr?p|Ht|h+70>Wv=~bXxgOxo$^*{>*`9!#?S|Xo{#LYG+Q0Ae{w;(DZin9*?vJ>OQdfNbRi`>1mwgn=Sb249Zk=)|vk&kcPP|kf zWn(}(m*;W1#QT+d7sb#QaO+C|!;)jCt$!Z9F+A4Bo&l_9$BUob_F4Mkla)^6x~n+E zS6ePt$KX_%MP4)koiTf1YjrqHGSv}k-De*^`&fNkwti|CoWyz5`SjS#!!6r&ORAdM zzb@-%=_?=C6<<`S(6m<74y$?`IaRu>I9az|i?oUviPd^cZdG{+GM4qCen+`k%x$oD z&_Z`SxibydCLkHMRZ;SITXA=*W8PMAm$$XDS)U^P^0bj`kr+Huo0z+YoyY5-`gGns zb)NPM)+2pnHdUV#T4<*mMT`%WoKV^tX=orx_Neu;snZU`wO%o9(gCqC^8_2e^7Sp7 zXKfM-_6+6ya7mQfw_$?;{57$PtK(AA+cD<1cINx*X3yC3&XhHNXmil4rfPpu4r9%o z1-Ub2K<+<^TMqK5C59_*@{{8n(Z@}vvF<^4YZa&c;K*Q$(?x!PP!!cFcfTjY3^V)b zWo*UH_rpEPrsDeXJAxdxTv}p>d)vyRZM+x>b9aC9XF5^i|_mq4(W^3@!WOyL_#q zN5PBoon@#q6Z~LD3{Duy8zJZdEG6@cFC1}S;4%P_gS;F$SoN96%2WG*fBn7-x{F-q zsHVE$Us_KqzvKoZ+sP2Nkp5A6ZDlmloLxXdFtn~_S_a+N2swMf0}O$uiW!fIo7Kn| z8~652j)_zQeW9r-bR$IsbjGIy-4Rw1J6^_J5;t*4_RUM<#$95OtQw2FG|n-7M0N~- zzlf7D*(X`G5!t*Vs}_@ud&q8H8b97y4xhwL$LiSZ5lE3)T^6byn|(^07?JIi8G8i& z6@9)yl4j-cUA71G;uh$ICd()VsfLB=MR?3f#}YpLqyyI#Ap_m5n~rOa%Qx8_`5t66 z4mixz1A^#y0ei$w9CdgdW#y4{cH(WvEIgI%?S2>di$jhH?n;om0wEsdf$TfvHa?%@ z=qeKMQ%~feirVZuksyKWJU)!d#Y;wA=2pPrCUFpjP8{@p{=4|%d`F`;G_RICJMWXv zZ$~sE?s28xR-e;a&eQVBC>EdlI*Ui@J^7bfRo#MwXlPetUE7D7?-S@B^<8KCTF^Hz z(wX8hjf=7+nv!v@AgToSkKpmiG0!!)(sf*i4&yp-d()zyh@eK9n~C_<7G3jJlLbJS*-H3Gm+vo82K4F?^z6CFDeyuvkP3c9OLte+N{ zA+jK$W*O=n@xz4NV71Xa7NN^i{l_R9q-&WPlare(yWB&3aNL#>B)rfiZH$y5`cR6r z$`*H|YiKSSJz!ZZ>j6%=A9#RzvL5i?c>52KE79Wv#}>!d54eZpuMfZz^bxe}L;D3_ z)Wuj>hT+x^-3vqpG;EG3XHiEf{90_Js>0vs1G)D{*|KQR5Idj;2JpM-vTP7bF`jn3T z;z2h(GQ@*OhsdjEfuvd%H61~NQz9qpD2rXT#IgFV^>43G{SJvsj;rW1eBK<96+EM5 zi`l`13uAaXqO+$BxdKN4?2$ zRa{cUl;GJdTF%h*OGyMS=$9W*&`&QU&nz!;khZEkZ-d(xuz>=82W(m!sarIb8kR?4 zv2a0{QcBtwPscW-B=`wG{*GjMm3huDFX`aeA_d{cv%GEeSEo$PBK$@< z8{vJSwB(>rIf=&wpZu<7=`@ST=jtX}v+}Y2Kk6ool2cb2C7&Wv$A=P5T8xs<)lITD zI6_$)WV6oOOx*uZPrD1`55(@3(@GTyWkyN{*voLG&-(HniVae^KS^MqSP_I%cD! z3okCbI;98=lKQO{=Gl-R^*EF;cqR@DmvgQ6MT|x8EGd*)t4p=0x?SY`Z*{xMn=m@% zty5V<-7fM*d86j%$~`CVmy~nX<>bbY_lxo&2+{VO{RXtK9A79$bQB?*7v!zuFPay$ zo!$dw%M>bENGGT+dp-sDhVuVbw_d{eMv--c&UODs-gf{-QKgU1o0;8B&u+?YdUmtf z-H?RT-E`6jJ%IEUr1vHmFbIMo0@4-atYFDm5IZR60ivL1!H(ytr(!$HaUOanD%pMf zzxQTmXSOAqWGTPm`$zR!XeZfM<514bxnDY+*V-&~GF22b-#W9f4NtAKpTM=%75B=lY^E!BM{X?{_rj0O?LcF zi}Ri0^PNxhfo~^QxON%Uq{~saQeOymhQf{+9K@am=+_VZ zIM{vYvo~=Df^F)*Wt$u=w_U@Q!v>BO*s7S=mdt-+f0{k-fZ4D)B%8#*qsTshiiha) zVxR^$17-*z#fBh1Yci1Cw3TEZu{gd5g0El)3$xKe|KuPANn?;{HjaEyTg=G1A7bUn zkbTh2oU(EQ{yYAwV;XAxy>C@j-`@|B--pn%BMZljDbx)rm@=h67*NZhw-?-D%6w_d z-%hfp9JedkCS?nc>$dlxUWFNoC~JP@n6GO177oH~6%4>q*LQ3N{|--l)hn-}1Hcgu*>%7@>>W+__|zB;@M#OXv!%r`zoiAW?%%KYprtLjr3KKK4D+O0 z@Jx0x+!rSFw;|j>D_w`9S`A$ofNMi4UhsaCVg{IF?79zOxSn(fi9?(Gat7v z;r@2izM0^*1#&;Pu!|hE_J6W3J1PMtA_Iah3c&zPgdm|!vbV(=#lP{Set0UvP3Q-79a@dP$0zrnGwg@A zzrG(F7Nt%xChRMcx=x)Hx4&c3>Fs1~i7Vt~wt?3du z$Z3*%9bI;3vnogX!|aV~$2YhB_CEC9m2JU0{^r}hI)Q|}cQ+{#M?KIov8g!AHgeSM!zzY; zx8YE6R^hzTM7TE& z=uNkoCACGs!9WQ%tz`eIp6r7)Jy-3A&HY-JtX^{!@bRBugOaE5pSI0E$nCZNj(=^* zPD#mbL7|+=KKda4aocBq+H?Q2e1`o7dDF&KOM7E&%@|Vi0~KD^#*PoE`YT& z?>cT|87RMa=2pjtcq|n%7OHHRL154G+$o_{RM&AKWx*XkOm^DXC}htz}9a6?Jp}kI+Y&)bjuI z?n%Zu0meB1=0w84qS4t(6E(Fkq%>rq+)8@(fl`2ma74#|7T{QJN@7An;^WV7=)itZ zG_3=lX?`1p;j?cqeHw4v&#phnvJ+UYmHqcOU!UoBzcP+A;=|85&f(|4!kqiNA`{ox zAD#_+N%W)q2Dsu&09QIl`#X2)CPt>D6!zBu`$Ei%7Uoi%r7L{N#3u%~Oq|%#_*4@b z`Pdjx)_Y-_i~O;Vj&d~Vlh&RetAr??zg5B9!9ZU+qq>eFz|6n!j0QL@k0u6$lOF~dDJ4WM|{Dh+I zho0r1Z(&zy=B#>iWioE>}ohnDG!#B)PfbW;k|FqE#A-ee0*m`Ia-TX;-)8`95eP1f9FFJ zkga-U+v|$ETgpps?b~9{4A7gymsf*xpSx9rj5HM-!gZuh21zsqfWBSJ;`0uV%OlG@mFfKp|!+zXY0|a zO{n*|HdNO%&Hf^{?0U5O`lYPBl`BrkyB<%y9xwznS_q>a0(jDbP3!?xR`SM`z#Gnn zmZEUevMbox1q6lLD|V{{0U7i1vUfiMLp-?t#zbAHGAc}EKfa$`c#F`L(y>$!5z?!& zg)KTTvcD?96sx5l$c8LpwGrz2NUdm^yZJKdgdVd zIQ+7@eAH9i$+j~uDEhVSKlS6)O~;f~?y=^0Px30IatArA0iJb(k+ITE!1((#Y|>;@SHxhmO#z0rf(3ks5=;smlc zIZp|cv2S;$Fb;D+hPhISFZju=&=u4+P_Gj@naWN9l$19CUf;Y)VF3`j%bRozK3Ef7 zOBjvdo#-(Oj3X5Mm1N?vAgZ*2!P((dpEXflepf3nIIpt0X#| z=crN#qXtS{uw@gcI`%6=&RwNQu-`KS^+OG_VGK<$hW>O6$q*reAB}{Fi5M4M0fbDX z$gbDXltXTvz?{!TQe^sxvPJL$H7o_2|X+h2DX_NnJpZ4+f zq%rlhLC}^u?nK0e-oK+y-25j#IYX3wQJffB3)jUh2yuV{9?~F~Cme z$s{NUM+W{6FMaot-SX16#~jb2Lx&Ed<%bU6gg?SN4j;lBM6CyZ?HupmSv&NWXYH_I zFj)ntfWDpZ7VzImgkd87HXWT2p=7r85l0gQgnt89Cgyf1&%xlz|A>FQ9bG9rv<2UV zX5eziEcksFdX>^P5qypqc&3uX`U)ruwIHJjyf?C#p9cD*$d!F6GP0o%A2`mvbOY|u zf8wOO-hO*=b!4PtKY9(#TbW{bYB8s1X)8H2a9~SeSd?O%{TaeHO@PNWbi9#-ZwU19 z@V~(Zq0yNa98bT1-{&J8PqRbXK4ynF-k^j0uEoB+1(3=>z7nvnv?xAME6HjaI6ed; zyqO+@o`7SLYiUxPf%9hZJjpk~u|+)Qzo5r}IpKc(4SEcoiSvHQ)xh=H;(5hcdLHs^ zaDFYraJ$H{ZXP+Nd68c9JcI(m^OTF}ah`bWd>{Bi!g-Z2o&xdM`TRn9?93s+`ynzD zu6M!*c|ACui9aAY1~^aGHPCz-L*Hkk=biCBoG+orfG@>ddS2*hO5);U^tens@5E<0 zJtlD{%5Jg2ZsaBH^KQRdcL1{p7`@{JxC3lhxc=^9|#-|5UvN_jN+HW@j!Y^{3qHU zg&8Cs3;j}^Mvz)JhPPf_%VRmA4W3<*Mm< zP`HX6iWk+&h+FCLwDbQ^^dS7r3G%TI_-T@|0FDLuNQdK5gr1xrALD>uvXq%{EXW7! zugLvO_>CJ#pEnMV=3xyU96RL$?x+0BQTYIQ{oZ-MARqUh|A>8+KHnuDieB`1D19D4 z!M{(RC&Qhw2cq!+$@HLS3(V`*nYqGs<^uTCf{)^l!GAak87}C%iE43v!?58E z4a0{$$gj`He*|_JeD0Ba)_?{+lAqDG9KJyV@D{uP?SMk(X0!t@u&epsV`AGvW2sND z2L|^u%@an!n26&K3kPf@e2zD;OCV2Q0^4)LmX?s-8`<`33rRQf-}GT734#4ngUQd$x1V9To$&ergB9JKZ@A%svxWkTb4P?%x03UFCdiFsS_s8_~ z-}a9|Kh+d0SWv+JFp=xu;=tT#eC5AJKRK>|W7l%?*bv7Dx)qMc<1J%Q&oO4gzpLT> zM#YcLd>q&iNOlTAqmYEu#am!PgiMBzOgv#}SVTrMhDGcZR@;#WTZ;tTX^Y0s89`3={l85WH0zeO|^~gdZ>1FWX0SA_y#<7 zTT)VwMQF;jyhKMDYv&A(f_Tb*pxr56sQ)hb$>4W_(|H&xUqI*WA^dX3ySSRoaSS7K z2ryp+6GpTLlL~qyeWi#2zR`g-wm{ae4B|J?uFh!@*)*#`4-4K)plpE(Dnnu-kX{qP zGs#;!;Veyb%>h#3Ci6m1ZrF&D0Q=D>Y14+=?*hU741bD0yo+12Ah&lzuKl~|Myu7x zHrR~QryHLxt?OM@y0)ymzOEF0@Lw8o=P$_Rl6&l3efX7^kF4I?Bm407&%XNVv+akm z8ucA!fI8;5489uoO;n@5s}p;`xMj42;R<0lr6rXcX!Zp2S)}z7fB{)nl62IVGq^gSCH@vw{EDoo25-WDCbUEq zKua9zM#~$~_GArf--*Q3;Z*0xluC5~Ns>w`EJ)ouT8j@$C)| zk%jCaYCr{H!Ge+`hGD)zdZ4O6tx3|EGZT_DYWS2eAR#eE{rm0WYuIC%x}+GjTAiZH zG?7!}8pp$)FDL7QgfVMjR;B>r5b%@`eVNw~yuK#MYo&ZlAy4^w>B}(2nCNItvd%<4 z!AO#I=R(ARq8hb2IiY_-Vk|vDF43r2jarkU>+ifep?|>-vfv;eD%pj|bC$ zyoGq-ZXvUTS;ky@;jpLhiGMeF4n9)xuYi638Y0M;{@R!5d+D1{7w*ZfkhQSe-5h2$ zb0f2!+2kg<5(9IT{eJ8iL#9 zs!Y}DE#fBcukf1#oyrvutpm-4G@2xK)IcrhIrs=NE$Tk+uNKI*vriI%Wp6iiEMx2mx#l1mOrz$fw<{$+ zM@k6Lv2B&?6B&Cw^b;INc21LNXxZpx=1Fe$y}tG`P`(hY_}13|UvAex`2-Z-*Hz;T zdRA_ua{bt-PGP_$(sE-iGgKY%pHH-O!IlS(sxBLNZyU9MSlhBwxTMo>88+l@G3iAlWFAgVM55RA@I7I2dm$(>| z3dq3-li3U6UyNqvfq!uua|d$|bDuxz(Z)q)4-#G?zrzlr@Tk!BaT>`o)J4qhPoGN@M4fMNvXGsv<3 z*UPnn9HAJ;iLrl~Wm-NZIpJwzv>p6 zyXtZUjC!c*5@j|HDj=(w5zg#OGXr^PnSVgplM+KnzfiPG4zE}Cg2jgn0YT=kK79A@c^g zEu!OzW>lk4A4zv#{-``>L*^C6!hH5*;*)hB`atxd59d2zr0^dQxcyFu`Et_(#nd(* zbn*0iz2_CiLOr^3UZMNglbLvVSm5=ww@=(1oGM5Ag1r4iVs{Yj_*Xabjgns`$n98W zfpcbITQK<73)NmxiDW>$uDu9k>4KvjbW(NI`S#(X5!wk^n?DAFdcy30M4@1Ld2YUW zcSMalL9{iQmXS@`cgw$%CRMvb=WD%lAKmcoJiT}zt;|Og{d0l#Pcr+NgQO<9``YtD zQU5~QwBR#E2TuRx!zqEp0Sv7C7yWyIcSbYwnKjHGm`9lxnU|T@m^XvLJq9V}mK4aP ziV?b_V-y1}bt1Vt{B@b6n`QHw?)je!p8G*BN+tp_&D6683jrlK^rLuEp3!k$2GOzS zRciY$Vg_3l!NY@u)J_mHHAKft`AV^dpaj-t;@^gOs>k zDPogWrF9e4vc$QIQl9YxyTD~=gFytqx#SPK=hv^L^O%xO>s&nHNsM4QQeDZ%dr--h z6LS@%iA3}e2{B{jb)CA)nR^-ef{_IyG9%?JJ#+lq81RX`VvKIZBNvsdT?kb!5~;fy zzyzE8Qr=SZiG}*k*k=t3!);4@VRq0(i~X@Nvg!REe5S3Kr>zU58kD>us}DX>cv zPhBW>y!7)k7l1!6ixF_( zMnSK+mu7pcN(wTLeQ6^1_(WLuL~5U=!#WICouxc9=`bt|mV4rxAe{>sgAj`NB9knT z6y87roOU9~U^py3i6@Uu#C2mL?MO|<% zha4c8ey?l2X3H+F?)AwQmqpAPFsoc9ajZ}F@yywaYZt}X_T38?pInUS*0-t&et2>r zV_si;_J1o5_Q`n+?6T=TU*sJde|O=yPvDHp$fpTDQwogZw+QFrII}_KR9~!gDSWOd z7w`Iyt$%m3ypoCiAB(Pi>)8LrnA@i&{$Gs4eMy--MigT64CrKc1v8Ub$v}rKx9FVu zo3a(%TIxi~`ChJg^`7o2T|X{3q8{tVmGl|11>{1ME)=E6UPzaayTW$IS|62jzSa%H zsx7hq1367rkgJo~0(!S=1-Y{|2D#AvJI8H4?)C`g(a*x7ac4!S&{u)1Bq!C9;=84A zQYb-ccO{eKM{#0}4$KwoiZ{{1Q}P_QIV>T@FNfZHvzY6c9n2%5rIizg(#6e9yF3Wn zLHK_u$sJHq;8HSyN4zNJ3x>M*-~~6UC1-~KLc`00KYYfFj`k~MFD27-Il*vg8A*yA z<#~tc)E+#{9AQod!by@_^naVZx{#8%>{za=iHb|hhCbp*VSfHv@Jj?f{6VyC61N2_ zL46sT$KXejQhMW3@@$YpNzcjuOUlJkJSo*cxXan3LS=!&s`zyzF zKJJzJqsfFsye>fsuw7r_6ZFYq-?Yxg*E@aO&AI1a;EGGpnaxvb0AgVn^03~823J&1 zzVWrd-y^1{H~MH70I?kOM8$E6!>R?&o~U%c2iSG#3$Yg}r`ocGpLzBnxE6Y%%B}?& zB0D0L!Vm0LX?WGWABt+h*@w1-)YvW1oEv)1IqwtuqA-X`mymoBJSobO(7M|7K(3FE zq>GofQ3#n2w*|7w+0whApN#X}#4bAf$;dK}R8oWy$mS(wwHxvwLCt>G+MBL)f#RYe zTL~rNo}E+`zeyv9cJ!{X%i|+PHhMV%Wy7aHQFAN%vNJGs)sdIrlu}Tr2!QwKuS)xV zwF^9~U6#>J-V;^Q%QA<8@ySmy(zODKsfv~J9({xt>+wTe<@>=Xy6|)q*(fRF=BipJ zBJ0_5mCf+J(1E?LQ>zxs`3BZ!c;HU-1)Xvy@rPh@x{p21C;m(1!V_eq2I7kZAJJs( zz1O;QxxRsQ8cy7M`yY&na+<`Hl>3A)g*=%=7`1e%Ah;@Wv9M02)cpyx_e?b+?WJA! zd-Vv8LZl&$T)m#W9F}0+;;kEq+4ocz#bSY*%<*tM>fMD^=lvDC#>c&iujTS0*(Y&5 zlUz=^W1bZA2)l>_5E`elto+?_`y}R4{k%Q4V;S>lGbKMtQp%ooR53^1lR{{w+IDvb zye`=%_nxQ{d&+U=$bw#25B_ceOb7 zW48lGOIM9~z^Lkqh4;2mQcqOh*pt4!V0PapPA_neQeRlMKj3Zm)xmQRBpW5>isU^} zB|OWeSNb-n*bl&OxEMqU#F@A_gzCt_fLdLbZ|AEgszfIl^n@A# zqrM2-MkdugypfCUpvZj$R}Aa5WSY`jup6Gvq}=aAFG;#Z3^;uDTl4HF#T|3SLe6%7 z&>Y{#E)8gh+`o~01Tpp(dZJQ3m4~mCMdbr!C8m{K=NmwuI>OV(3AAe%YCord1_Xu& z+7s0&tL|&I1Bl@L82!%Rq|3>QK=I@&*zdq=3LJNme<06&&~-e)&3|+orCoKex`XB} zcwB*_p7a`U*%ew2RW_anX3tuO2JPxNI9KOkdD-7dC*SG{RsV0 zCI29()C<6m>x`fUnW%xdcbAUP9k_gfQyymm zX$8(P@;L?}78LuV`gFczafIAKq1SfS=M1!6XCQ7U8t5Z|<121=_f6&b8~6UG-G)8@ zedx;(4-_eZ^f2}1uLq2%www-ff0BPD@Qu7bYPYfHmHi4dSJ)k#cDY??w-EjNULUO6 zffo%^v0gr!dwzL}I*0>kFDSRz z&R2ibZgY=DdV-`tE>W(yJ9gu8nBDFcgPnWsGDtm>{-~~)QocWqS00G6jZjEJ`9_+4 z@T$TgmkLEV5{J>-<@QCE0)U#Sp!YFVHcNUQ(%`f#3uf3r<-01hNR^$u0>^n76ySJX zrRKurId8ddEbOr=^+%QEy{Vhz1-DPcbQ7<#^tcN;&+NFYOHeTI-9ZwaI~Pp!yZOWJ zxpvxrsN;;WJe-vk$#@bYXpU4@3khXZa?L_?ql0@FQurQ}6AC5-$&rdDe25M`Daeld zb!wSE?3wGQy-_=+o}@+sh(#_?2Gr+tOIPERi$LZs1TGhV^rZKYn@{7}KgP?>1Wg1l zf|$!}STLm3b8aHYTyi0&FfIh^ko^KYe3Ln_OAOgrc_Xt2_M3Rkd$uYVUWz;px_CBR z#!JDl&r*DJu{;6~_M)#9YMNXl@H87vKT9ZicDsshg4IqTt_Qz~FY|QV0(9@dzkpst zE?y&bH=~$2uov--%z9=M>_z+>>`ei^P%o$Xl?&y%Tpn{VK~{a2e9FdyUxVRQ(R~`6 zJnPj9RlaiPf^mxEX-UCgiN`vjAQMtjYm$>GEkz1GmW7;+dx5tsH!rVw5__S_B0w2h z<+_lr zxTI_-&1;Eqq_5tml9zhnvKW^KZw5J%^h|GDLT(LyG%2l6yreA5$m2<&Mp3K-Aak?N zGH)=am|wiJA(Y{|TUjUb`TW!Z$oN{))pB=U`qtB#7n(Ma2gtm3`WjDHo_^`s5`f+= zW9SQ%*Z0hfc=9-Xt!J#@ngR$`FGCOZ7Uv4Y+D@_D&?BcuF6%;hfsEf>fJlLe>nmjS z(Qq>GIAp$$yGa}ZJx<%rpSXIQ3S8!)yaQuBWw85=3Eqk4D#5@86AU@<$f^8))#o$7 zG>cVaT(>T3lnGrCvY+;@?2SI|mAb55T6v*;OI5R=$7wjDW0JuVWW;OYiVa0Jjn!x} z6v2VfkO2osW6+?3EiL>DEiG+z{0nE!wAGzKxqLt6FD<{VZ)s62Z)rL6+xjzSRLjr& z`o0SNcAlZVS?IG9m`tXCDP}6+`C3M&jgN!;iZM=SEU_7t#tc%o=>Nr>fh$Hvi$P`N zKdeKQp~=VQ*QZt9UYS-u|5$P;s&r&{jEWt!4n@3oC(^HNz|S_U?t475| z06J0z2nX7Y9(L@_s6k_AkFs9dfACG^w>*vylm!Zpy=KY6^fFXCXVZ)$PnBQS*LqFw1ucu_kG}HC zDbpuq%^Wu1`qJ%>j1LrM$1O1nhOb-~AGbU?X=vYpjq_`&Dtg7}uGYjXo7QJC!0yeH z)m?x-6ai0aisOy(Mw`JFAUWBs_zh&!KDd7Uc04sufbbviL^j3o^@8W0hi#g@`Epnn zMy~+Aj4vrIAqIyeTPPKwLncs9;M4#CLJ0`tDvEi5W3yuP6!%v@g4aLdS%W5?X`(3A7$KMP+6 ziU!ASt8Kz~tIcK|Kfz{2Q)k76g%4`HqcAC{aq!yJLx+5J@|C5_LPCA=||rZrygdt?9vcn+9@{tiiO=3Y`PpYD-~Y_MkA1gCv&DYc z%m3)r1y~iu8qn@evm78?=;_sUwc84_M)nO9k~5CK-`2O!t{T7&Vv`r5XmS=&X;+w(%Op?z`^Zz31-H zV^>WI8#QI}s8N%rpq&BvyId~%@Z(QD{P2@MzLqt&3|)_|+PxcZ-@Py}x7XXJ=!%!F zE7qXmP%tT)K)v)ctI^z6JO>?o2)C>bls;$h9yA4Ci|f%2ynxt3$)Ag73`|dmGRlB9 zl4TD?)Fu$a?l-cL1sEr^rPU)hRmWb3kK?1)#nx;bT~+E}+mA2Mv&*Xc-PW^m_a3|u z-FnZxl|66kSI3_SG`6M;e(NIW6H*^8OjSx7q_ zOaugYps_@tDCklwA>agjt3?3W%SW;UgTUYJt2ui5Uu+UJS_~ zw-YmTPV4#$7;g6Ezs7p_uYTeMTo9NaD~t04dUe|4mIn&~5y&l82$U}E#0p9#hDn2X zp$E{UAQTnAfBvRDWWmAf=yp6C&%_%%@aZw%!2a&|*>R3lD#O|j0c3a-#zXRW9gN1W z)9-I=e*FA)#^~3z_Zlye(+P#?M-&;oUvJ?UiX zkWQkL>~HXrU);{{L|0gr3l;bz2W-pO4#&_9=hxq`JL&JX16x;ITrYmBW(IeNh0Z#) z{y-1Vk8KC!fL&KFdgnrpt7F~Jv9szAHh=zUJHT}0l6u*WoDM1F?u7aqtK@gKGdjuD z^cn~8T{_TE{+&yIgYxZ9wlhGVE~FcOComaI9#i2OE!Una>BpDho#VCnOg7`Co^FlP zk74V4rkA-zUhWO#V?A|a#~zm48T5xxH~+64Ji5DlQf*5pLp)Um#Trm-D2hb}f9@Wi zuob*9o5q8$CWU3j+@G44d zO4w>r%t*suJl^8R~miMOh29vxJ;68&vu;h;xr)VC(u z9vM(>f6ZgO9?q$~vF#X#B6{Cu&D;{ZX6_F^%v}?^CDVFq-w335xvf$4lNU5@Wic}P z3UH0=CRBbM+Rnh}$I0zHtbzEx0^HNP33tGbacA(*fwSCse00W#7Wo|F-0twXhlAZI z@a0Z-=YjR(iwkf;_N+Tlb?m5j2GI7M_s&BekWVk*VGuK~dzk2S2E8+g2{Z`kJc>FW z8wmKS?;f_qz@alpkb;TMgXts25a8&~%!J;7-I9TB1R$LOzmq{p=W*1{SVh1mt%B-~ zM(J!I(-{;77~FIobzO;h1bhvEu7cgv!5s%goxzd6AgS|6=|t=#%3`%EU7149RD31_ft={|#KM0>zpXvB=~vn&T6u z<3mU}1F4W=8dBgtPkjtMjSo&HapzS09C`*1_K4&7h4`%__{}3nQ1KD;3tp6kzr-Uy z{~SGxGP1Z)UQrvVjY7=c^K(^?DHp=p4klL381#&W{@%+*p=Pv{jd1)IZ^D}$KeIo; zQMBVHdh}m5f?-(Ky(D&K6vC~%MvY|8;d4$I#@qG|z`dqr<2QE;#y=;~eJE zSF~`q%Gv4HYF`=cXnT@iqf@i*f>+o^*2N*f|ofSxk7olc?L8jv@&5t}ko!Ay?ig+t+w0K_6fqQYP-s@?iGI`!-}V;4!L{D- z$e)jZswRprFS>GT&}4isc?EjG^Cfr%;*gzH{)B7sG4eh)oW;7sg97zZy%l_`p089vT2k`p~s?o4BhlWXHj3AZ8(24jt zc)zuzNE@fjC?(~jbd^db9GT%;o$DL%niA(3Wl=R(8mm)P^RT!D(l*tIF64=Vg)cf4 z$>EqYRHX3S0(I14p{h=)BInaMouxE3jf3qyoQrYM88o0>H}BQ<&G33{N@IO`mI&{RE-Z5)*DEr}Tq+1iyd(DWUQ>PB7D=6(Ut=CIGC7LlqLN3BFxS*Kwa%L}Z0wE3tm4w!2R80#p4XV(ro^vQ zkC|AmWR>fVJhyq{l6|kvfAzjq#YqiDl%D>0?Y;#YH!j#$`*?afGBzX?ueuLT?_08Q z^K(bm0jt_>3s-FhT#p?QeZ7(MxN4=2hXWS@VMflG*+igClvv(#6d@v zICF$C(pV@~S4F9EkTM$4B@ZNL2n+|Tf}9EHV2 zrYT}LrSNX_uf5qd$RbijFFsm z3VwcyCcX5Yd8^oW7p_?d|0mbQYtmB_V@|$@HVNOb2YP<|e8Nu0;P>9!u`IJelQ^id zG$SOkp>j~7rXh1#WOVFo+nB+YxbO(QrZ6nKu@vCWN;1YqWoQx;huk=0!Gak#4oOVZ zWJJXpld=Hb(#GttLXAEmJkBzBjBR#o^bqGe**pKdGvWD<+y0%Md&Q>%LPL@xbEC^c zE9MQiPO@bbjfk-%BwFH!rzQ^>lAJm`-jbMLi5XFpVVh(fKCdFQJUTZrIV5zzr&r`= z7i3*s-%!v$&zziW&g);$P=9q6KBd)W##_w5=OIk5^K(N|RdH0?Widre9n83{W)1>} z6W*jhIw(`Ozz@ zZ;%%9H;RM%Oge>D_@&hYo0>`$^cOrFRA)&I0-@1?imgWQ5%`w}Z3#?Iisdb=N@>tr z%pAyo*#d_THuafMF>++Zgg#C4w-0RSGhjP9SbgnF*H({ThwVAT^jUpN;%)hLeP;~G zEKub1iP55iis^mp^KJ1ZeY5n#mPaHNWU2Xx$lO}ABPJ|N%O_|5=Z@yP?rFZ`KiSEO z`0%h8R3C<4h|;07B>cs!)&uB=1Ff_07fC2BJ{lhlJ9kv0ij7ED=*-bo+Z+?;d^u;L zV_T)#tW%^%#Huv&!xlvA7bY!Odh8>73V;65i^~=yEl5)@2t%8v*5>BcPMw~Tf*x+^ z)vF~BDH~J5jhQ|B735Aa7i307tE?tXYVRqz1^s$v8pBg~PMeSt6~R?Lw5B<4X7#ef z`yQ$|9v^?a;-UMJm(JUjfsK;R5fdHFw=;X0L%ysdN7v*Q7m;ZR#%T|cRp1Z8Jy6Nyw4;>MN=kJ~ zLxwp9m;gAYnsu^`ikL;B0f7w&o5kpPU<1N-bh;x7fhGg>r2?guho~B)YK+=J9cVv} zFdMbEpwlWrADT@{SnVb1VYt|s!6goF9zMMJ7Hz3oTc%FPHKoB18%e*!=M&ORx#S0> z(ew7N=B{~b^8U)X591%N|6wCK`p1VzY6i_&an-`dN*fzXA6t0UiaCR7CY0o^Z&lv4VWs0lyefKlMOyJ6^5fU97&CeD zm=){e^Z!tsRxvypj3L=CRf-d|be_@5l*5cwJ(;sY)KUtoq)fz%5wUF#pepV6vuypZ*$o3 zPWI`sjjbD68`+5dDbpSL87bWP%3<(G`Xu`I6L+5(ViLEI2F=A7??Q7w56?y>{2&^S zKgqsh`1FGZXS%_!1FtckvB6Ah4bvNB#4U1g1C-*zXf=Z*7-XMSeh`2PJA{@ywE6hv z^}R;+a`bS1_}nk}5S+M$2%g}w+D$LNylKQW*NhPV?rR7BNuVEohd7b+UyJ~2B4A-0 zvkKq`;sH6y!X6FCF3{CPA&iy5EQjC87@+9svP>{K;0v)T2tE-gdoVs^u^q7u=2C%e zti(Ezi{J*3XoDUug46U;i;}AXQuhFw*`1f~n!eSEB8%xr3RZXlb21CgvGhEkmLyv^~J3qrO;p3<7%undC zp(nXE8KL_Q&b(sybSJ}v6XsbjAQC+;VpjZnzsPZ^$?0*Rb<8E{iRF6yJ&XV;-$B~6 z^2GEKvnf3>HZ3JpBwt)?5?r;RXH@iG?mTtsu2mqPq5UOPK z6X2@^4~?vf)M;Ikpy(d7%7^Px5K2mJEJ<#AB1nMqx!0Fvy5q9x!CvhP0 zuoC)mCxY)mVsZwVbl?P1LB9Wz`FcOWEuR*D}(Vz_u`Mp2gfg6VqD(x z*1}C27rr%W)LRQTZd&O0rL%miVzxn^;Z@Z%=r)wjWP`OB0NGr!M!OV*j0Z=UgpAYA628@y81y>g2Z2M+re2+r zwGHjqYDvA?RP?OF{%jExp*WLCpGAFxKg56gN7N~9r_;hZj)+DVN3v;XHM$;JNqi{^ z!B<%E$stj~5C0bpM1y)i`PrvWKKbcq=-qy~<}GNeCAWWh(SZZSXqY6+r=rTsqfTYZ ztnaenBiN>OM~*G;ln8KiKgKppob> zUuYB&g1%gfve%+NKPIBJwW;^RcPf*{2=ve2d?8 z;U@oEwg75`MExEOYXmG1zm+?A$Pc6*{)fmwJrNZq${ihn@DPLwZ7e*f@z z`5Nm1C%^>L1-bHqtC&_R64{W!#dT8e`G79B3;NCzwEu{DP5j$|ej_|A(T(&>Dg{50 zbRuX6o+1cwl}1RQ7RP~eY%2y)Pemnyw99F#AkhuTIq*4jX5eQ!;d8lzcqb9|4a;WK z<@5w&x^q2BMLSW-`W2<`ifrpeUxj*TQ@S}bSsiIWi1lI9h-CLDn6H44hkYG?gHm4m z;NI!e_>WPs({6h>(j~n!vl4V6vE>S7o*Wkf5BsDwA`v8jt%dBDLH1eHk3@>)dfx}F zdB%whTq$%?w3nLWk4Bkl>Z;#9($E;6*nsry>1E*WP*3;GUDkJGsI67{d*&Xj6i?#s~0jVRWfUD^01hk!5IQb z;nK*351xJy{$DuCi?`9$UiNS@zf+qaxbX>6jCAbYq0_f+olbs+-s{276WmQ5SDBP} z>Qth;oRhdn1Gb7(v)V|>q9Hz(NGY*K27lD$Z%2FEPNKc@Uw0ZBjP0vBBpSDQJ^XX* zb6OL&ynRY|j+59_lHZ}@1f3+>2tT2_o76RONA1f*Yv2mg0|*b$;`Qs<&4Lktz@CQV zA9ZfrD%yX}DB+jjxg*Tt&D_y*y8}h(H|y7<ImaEGAv&SVVb6U2+M88unh?(Qy3mU^KSvQ}{I)f8Q0h z;r3l`8(LB_)Q0;2G=Ds^=%DC}+J+^ll@x~`C5-wL#A1^Tl)#yb*S`M3$b z(zx#R>x%7lh^wl?j=Jqv*!Op=+dR{tIJ0`lvMpot^2TmiHl!LF^0;R~Ju3^O_*@5> z-yT#`kah9Ilkwr<$kc^1>Ieu><=mvCDi$1@-PLTExi$+N8#W@tK3Zg1DfC#^N%+|( ze0Vfyh``X!fCTG0g%US9>uBdvA?pTu-aFqL5d7Xbsb4z@r?=ydCw2}hIsZn$tT^e& zO5k#1)J`f)?yMXPwy`U^^LsfM?2DrI6#sUpMcwm=!u&-U%wG7DOn);MCNLOA3ctZf zA{8H*(m-Y`z@GmMXh5Uhf<(S|j3tT{41wg;Ic2c(AV~se zKhUANB|eG_CWo7FeHS=H5~zLWb}yA+Lc|GU`aVT@o9_(AdC6=gYd}Sj9SPJz#3xY&4VPu&&$g z)oDl(vi!5fnIsH^gtjG>*LKava+u1BAq!a6Ki2}Odkd_Rm-(5|Q2$752g&30VW8ia zNi^;R7_j;%I2hqRSgv-ObyY~($g~i)@&ce}4>kN?@MG0gRcdZ}un;Ea7a{N219+dz zuR?Yc^1?piG(<9@GLK5`Ie77lVjanB;vCVUy23XcMU$b})S)Zk%`b{sklg&t-8n?3 zAq(pGseQM?n_;B5M9rkodaP19zwGP}rw3oq#rtxgv{N_B&%X&hPIxADY| zB+wp~WEKFTDTtavy(y{Fl6pUDsXv=91X1W9jgaj5-UR!&J{ds_pVFr4P#B!i)6XET;(By6_V!)k|2Z<0UzF30EsI8KlW%q z?E}bSe}p}p&}SZgZ*CuNC#`+uW^ert^@V!F$&JlRp%JXy7Rr5rN|+a5x@P;_K@EZ{ z;1lkydIMhYN4auN;ou7-LJi`0SS>i8X<^nf8=39QF6M6Le!vCo<11{2fShDhP@*~& zzSREwO5r4;o$Q6y!4|Q_ zGZ^%JPp>=n=GdJ6s zU@#q7EYn%51_Eku~}guKgWfd(-PJidcK#KdUsEQ zLlu53G*0FR65bDY=HGf!zh2Z~!e7|9lFai6vtI28HcbMF`s)*tzHuI$JJg{Igt-74RCDyBHW{V@z=I?CELzy8G;%U)97yKTUE&qT zM?sa4HZn3ZCQK1wNw16%4R9wWzkK3?eYLqLI-HNlh>MSk&Wux|qoN@e|8^8_dmu%M z>AFzg;SP0I>N|V_*~tPA4~R&fM68EXKn^_?diPC*s7BCKZZWBoqk~oJrfd}zjpLwa zxtyyj9l+^ zWY_U`gXRtzG}r!&NO`dm#j8BeuO-KEum9+Tjk9}IK8{rE_elA8Wv|&A6Gr!6Z@wY*TGmowQbx_` zQFf&zdBZ~7wtPdf<;t=ibE1@{3JZH}>J4Vpcnu1jpImTDnWjp^hD1aZM{A0=7F?vSj zIG~uko?WcFBzAfN?HDa{26eIsq*Uge%D*@HaU@xREi(K`H}~_cO>@_7nl@=$^R`LT zHm#l8bZdd=T;3$QgZLpYM^HoQXaBBap--B*VaJ4Nn>I}&KNEIrnCbKqhdMpFL=RWa zkwvM(nmbYkVJ?4uAmsC|1nV~wWZ^2NnORON!UaFh3XVFs=kYq?jgyVAoIe`a7)xU* z1ut8#iicHn^w@QlTm@&rLx;QFeE3W!LSx|uRBW^8ift;3CLW%HY^rz;{PR)`d=oDv zENUCl%t~d0wL$ndVeqbp@YIKP4W8iq!rGuzn$jEUy!>&FrJ6Oi0jV1rHdwhrYoh)4 zhKA%sYau74F7|H2H=+OJX3gS5anB9(A6te$MCzJFb5=~AykgFx8hi%zaJ(v1iEhfqwXk96twVkw#@M=ihe5p)HFT=8CPdstHp~>U@d5CpC)^zf&tl0G zK?tYI?jSUm>ZihJuezQ9kg*U@~m_is=?bzW}U%DFWAm)uDE zvf~J98ByFD+ArEpeyLS_n0!Pi`8twviqG|2=#HKz6;=NbZPR*`fT!&E=ryF-jgOKg2gJOv~GdM zdb~cJnb&_L=_sW z!23g@kX4IcjnU40fGm%^Z&s2Tzo|ueQ6czw1?s2twXE`bMLWwT6?6D`A@Q@d(_@pH zj|vMXk2a^OuhdSB3!TAph4F>;h4Jgjbm?oZkGLW;E2$_avxk1e-?1mD%Rj%&KmT?;Stf z>SKB3;lX{{TSnP1Sk<5!Jtng@gVbPbCJQOK+7f+j#?Z;ChG9A5`}7$HWyi-iOP?^O z3Ri{QqTts~v-Ay{G9?t!e#8fv41Dw(@KFuZANCn}81~ve&b-B(WMFquBx43WB2 zY00W5(rgq~aMOjg;O>!vX(tZ>PIa&G^;k+y9%LqKFR*V-v2}kgF-qEl3Gbi@XI(Z@+)`{+YmA zCxExqAt?p9R(0OS;r3Svk4~NG3I37rXjKNg>)saoN>gdIb$rN7e!4OwCPL3A zn4@5!?v-=Cm^;z2wMuQ)!b06RB|n>=tK`R9t4cC+tuavvxy?ua<~aKC(dO(Vbte0@ zwxGT!ZUbSs*Ige4hRe;&0*12!!}X1;uC;P2vvPfKPhPeqH!*iZag}LIqbJWbOwOt* z-jJL4giltjD>3C-HL2V{Rf94B7PKa&YOJ}YlB(kD*;7SEoOo5wMd-N1deSGKOz5u5 zvSEeF-LT$wKXZ(Erz2fP)m$2aZP$S9E~a856QQK4mMjUR%{qj&=`epqz9Cb5Z~<8h zBQ#=w4cFRNZC5S1rl!Vr^oPSm{VSH*ue&6A4t+VTclAV7L8Bq7cUg!-Sic_6o)0PO zZOR;+A5zq_viG#sh@`x1VF9}zWj8xLv`^#UK4I*Ti>mbY^qn-OvQI*|K{p^r9~r64 zH$?YL)fplZd)H^1Ctb_M#V1CDb5O?t^(yjy1Ou5HVSV{ypzVlpq(79a2tzr05s+0* z7q+bca<*S_mf{2RK#JA`EJn)pfs@1H|Emhh72%{hCP%!j^2vR)?-$cs3` z*G{OuW;z54+{1ykF}d+-U!GEQ=9)UOk%>ZZ%@xj8CS0t0?-EstYU3EOeMyMu?SwcR zm_$#$A=}MmZ>#7vl|W^2APY3 z*ZT%R{kzJXp)$cjR@z_36=xDPX@WAa;PBA}>VU)bgJS#1P?3kXA7GUSCU1TH)$K?p zvJpB<3)5E6vZ}y&>Y`XP96N2=q^hc44#1$dqH~mw*j}J2PePFv$uo)mj2`-jS()k3 zLky}IKp)Tv5m@dcv{Wk9fd+x@UET{EIZ9Ez3Ypb#3HTXo|A^PkWG)~qi3Dw0UrKxkExe~;A zq`8t>A1kRRe#55yQ8i>)PcFyVpc_)&w1m`}sQqrONbDaA7=L9YQXZc>#j~N&loR*9 zD(hy1PoivBH=}>xv^KFLQqG!T8@4+*h61~o4o^zFB;58&s~Dq3kaiIivn{iHmve0@BGfMUHLX%!>ShstxkvIYw#=-~$v zCYJmanXXQ?Y{m1zLkgfE6nU+W=T)Q-uBe<;LvJ(~KQqowJ zv@QLKjhf;a6IC8^~n>34E!oU2F~a>jFKNZ zu7qvo2oJONmle$UO2t{)np*r>XY`9r^&5Vr;7>@G%z&5kNxF; z{u6Eb=RXx^;U9ShedqZh^ciIb7-;lJUU{6{cf5cZ^kl@yv9RI%`J>PVwt4Ku#n`W>(fH656e`aJbm)?QB6#FOga1$hJW&OQH-t} zzAJZ)D3gvT6Ozl$5jBM}p(vCM<-()G)!~}(nDE%pxNvQRE+Qd1F*+$aIXWdeH99Ri zJ=B=QB%vfWiA#=7RwrwcW0GT&gB%#cxlNm?uD2;yiG6;0ZO7RQ0kg~-*6*)mSmGew`ZiJdpbG|*BRZ&8~pb46;8Bbl)M;00mA14rssu4LG1dtPwfheC0U) zijV+>5Zc<;0}YnLbCpb=+EAWRuqvK~iM5l*1oO`%fn4u8UewOJ65&m3G#{;i zcd_Ywx&q$D=JWZAh>3_R)|D1>j+yj*pYuPWko)fk7DM(Y0k$guwn%0~Z3GYXWl^dd zLeLFN6lEdGz(prq3=>7+i-Nu)PWVzOe5&XW3ZW`JguQ$?@CN`*!Z!r#RcIs;buw>(>+cxkka@n13u3Z*5JGnX2OAEl-3HcBi8n9d#a#zkh_)~oI z538UPH>yQ5ix2l7`R3jKDXh&vGu0(U^9HTKKi_ZdF_=ZEgOPq?)0N{V)Fw7#8MU#WeatY ztRu51B_}^6$*3)`PIp|z)>fK^>(KIl4x1X1a?64{zMng+mtk@K)*0;36mw;&8l@%` zW~IhB{(_j$xIRkMZ{%8Q?tNw12vziK9rxHD?yWD*bdE{!R~VC?^kHX+dq7_3!YL#V za*zfHEewe`fEI|iV9abX+D!2B&_l-w4v){Ad3?`{^YV{B^iZaC3>tBBUgFxsJnj@l z#i})N|Bt-)fUl~`8ou|r_ndQY0!Sd#pmYN$3ermyRIDHhA_j~KQbZ}zMHv*+lu@3+ zktQt+A|eJw2L&;M5M#vNu;bWA$6*}D!A6pMzyDh2oa811bl#`@zW03sYwdk@S$nNr z)>*rqONFI&>y}#IGL5otSv_n{r&y@Rq@lfAw(LE0lCa1B_o}|b;(q^>c1>}cGD^JuDs{?pyWshl{h5ll zp0IZ4cO1-#Qo%^xq#Ng$SiDC_4B&1}t?p^fFYMOs!scl?0|xFKFmT|2odXZFPix-o z#Pn`y&2QT|kiVS+2MmbEO?GTU^seymlnzasha;gPzQo$nn3PDe+e`rDY zE8;tu=VJRMoq3=1ZqrsCzi~I58N|okg!tAH@96~l4#Hc6BjNAJ2YpZO(DhDB2{-Q( zUrEoHaAvh|kIvdyUFTirrIZfN0#g+4!+2jA&~YNpBn|%t{@h0QR))V@Eqs;oWv{1UpTa6!~6ND$wvHw7Lv(OB?PD;AS zMg6x3%{3WX|8<>+eYzJPegL=f%X4ksKq*bPJTCEl@JKJV7I@1cWT2Va^wFgc|cnljX@ zeoB2il5&v$qxhk~25lP1u2Y+yV*l~+^#=2tKl$T>)ZkjlxVry)Z^HzCAxa9DF zk8Ya#x2)U4+sZSLs}O!4wZ||H3@0Asz0`&SQr)d=YvS|I$5y@lwml}+tT=X|^+YlC z5Q=S#4GQfdeG~bG!c@uO@{Jr6R-?vp38H;!!xOtl+IB!)>4$F%t%;la%&I?n%F8p- zn%9ecZrfJ(*PS~DP6}C9ojftUnLVbw>l@a(adYK_M4HutUpsu$8qzm%>hbZob(@X<(jiMb13yn*ONE(`{Do(~?V@dDDh0X}#>|W71#MQUI z3f)?bW)Ce-;u_f5HR5h_$HR-4Z;Hfed3Al7L0ki;ZjHFH?wNL)$j~&!-fdl4jhD0B zOuJ`vE^(>IP@NYqpUCIu^W@a>&T_9I-&Ep|FLWa^kl&iEab7-;&v{By^K0DM?l@<9 z^ak=ZB>f!n)py&5ZVKY;FRH~gaEB$t^^D$?kPn)?H>9q|x@RDt#5IEECD5#jn?jsd z*Fl`tx#k;6TwSftAg+PECUmRDNxr(#vXl<=v|XVLXlj~(PiJ=YX^C^Eg=B=QED~3K zHumKzcN%d!F*!%4xS_|qu}k0fY(YcsZeuNpO&9Ru;-7_c7>8JAJsWtlC(@+I_n|M? zG-6zqb=w!QpRa!PLThGb*6dru@0TaX{_(dS+Rx$-#p=3|P&ztuVd#yYTcUeW1;&za z=k`##NmKic(b1-Xo{Z?w1G`P$_F}iS4IgTfe(OhniSdD(HLEVZAk@Q}SSP7%zs?tw zl#NUq*7r}>Ot8$Lv!_njaraGaTQBI}S?x5lB=+Y>pGb+68P2zspuhHu>}tQgY_)n2dQP=RLbw$>43rT{?JM zgJGjHpEPcKPoGhzvEhH8`);Jm!Oy!6OuD4rn0nLeEv#o-SE6bfQE!cz`t(Gp44D|6 z|MI(Tqq1GMXZ`K(pJ;oSJZ!yhLf=s4$13B3_-9VJ^N$qQ`dptg0=+n&JC?2eU$GP8M*7+JGEWdO>Gl)?USwEDCFKfuRPVh8{g_2 z`}yT>nw~N7%JkT?DSa<{G`zp;+ozrL%C>*}&8)0vXq!-My69N?@wWI?d~m=O{s`X^ zyC~GKlHW*ZfB0(Ux5zrrdc|Js@tev#t^rUaQ#k>9@ei?0%;+rcx0&#A`Z~HkRn$C3 zS5e>%a>ET@c%l58efDEAdn=#846a@HcgC{V4R?~vxAM+AkyD&bQu)Sjzx|dX;bpu1 zVt8=$yOeb2W@&$CHg%R6geOg?44+dOzKir<5l%|dlZ*FnK&N$O`Wq|LLqCDeyvlH) zBk4)$)9DPI1NJN7_7UtZ>>3FtR_SYal2sWF9qW+y-V41!T{y;gwLquZqAER+wAa@&}huFe5HfK^{K4OaA%>l z!Q|)Y@XP&%_v<(OwV|V)p>H*|@~y@l?g^d!^__QqeP>0t69_4^8pr-CpH1<^LDA|}c4XidTSSFy;SvT>C>QRqBZjFj< zwEiQM8y*%*vVJUoB=#E>)2n~Y#~W5mlFFQoti_30Eo0TptnFg=_sUGjTRmq&zKY*? zd^&@}YZ$|(4L|D2zwQmfkHx-bBD2ccX)Uq_6o$^K*d1O|F&-AR3{5X`k-kCq#2nXd z65&E%Ft%S(pRl< zbVlK(lDNl{q-A`2{n1OUy;72UoCF!XdiublU6npa9V9LvFMJ<`kI?fKz3na#w$@li zYbK~0pJ%CmpNsIKqolQk2gaG@r?o#QYaofkRD(yEu{4E#wBPv_+2~P*pJ?cIh93KK zse8GW!f(;EW`9a%t-RqsY1{AIer*MXUN3*|#CEgt^Z#O{e3_RwtNn@AUVHKA!Ka)u zSWsEV(ARZSdhL97=aea+UJdHRnn2%MH}J}9Q=>fPvSyLhN-S$;?X6yBLW$)a<5Z`0 zWT{@6BWjhAGLKPW#b1w6URlQ@ORG>By*715q66t&)MIM*Ft|;4Osw#;x5kJ1mo>2e z5qghXK>R8f7jA=kaaJEA&*5RtBemqQKR9Y0Ykn=|7_9urCDcV@6dIaC{_*PP)!M5~ z>xL)5Cc4wRoGrJeoz5J-eDc139(3&CS8!$i+>N2Rd&+Wp+|a*M-`SxxT!ZNJZOMk4 z@?sw^Unku(yk^=h3vN7P*tkF@Ela)&quS;dN^9f{JVtTSWsg;$wzIn=kS!P?)ul_2 zt=7`Y&-P?HqOkJuiL&XqwHKfZ(FyXN3;q>`8^kWN9*SKSn(Vw4H?ijcQEdEqdO`Bk zOVlHhv(cWaZ1SF~mQnMC|KycbrB4!bRpqG|@9C6)w}3Bc*U;r2YvBfaLZ}t1uVwt# zvI$jSx!DUM{AxF=R?NgJ1(J*vUxXr|$(5NS=l`@*>L-CjH6A-9-d6DL=EWL;}nzq67~yqi8Ze)Q>v{5nA=cCh%*?rxH*`0|#U(1}I^vw}6aKInYss$`^KLklUgns7;|6Y8Nop zDj@mJ-b&5_qI+WB`TBh+wD@JiHmrtq;5tNuHmQ2kuW6eGp~Wrgoe|5kJ623vwyMJ^ zDXwE}@BPr&{BZa8=mT%Wo|~O>cJmeq{m1cX(YtHXY81MyLC+erEOYtHqtZg}zlFsl zBeNPU1guV}bxktA-6H*2-WcIOKttZ`4J>R4Q6BTLJg%^=-D9tdJzdudiNqZ8Fy=IkxHunX3w}NUud?uifo7vF#Yn22Ip`1JZ@hA==dYeSA#Zt+ z=o$K{yN!GeL^mXACuKnc+--+9`V4dm_^;?5dnb?~kRvpx0+OB`qcr92(-G2$WEN1x zS2dzl(gkG2bn!|1wB0t0L5Q!{J!PDm4>SpH!A16TRwX1h1eYN-0~p=a|JvRVNliooiX{p`*%Et*k0} zs+Uw#oP=_uFL?7C@4bw!@J6i=rssY4F*Cr4AIo%WQ0#|rqu3AD-GM!#xumCJyx z^pe^sS3Dkejz*mNu0h_X|J#~;A3@*e`v~flj8~&w@tllHZ=FGOHZvJde8Hl9!mo;s zx8Jf%+?31ePL+Pwd2&^1)q-AfUfNX|guc8#Ri{J0N~c%l@Y9!_e58)3W662~s|h!} zxj%Nft|d&pg#u0~e=}};B~epH)Uhz*s&ciz#hS``LRGc|72(%wm5vDVYI%OnCxh~Q z9ie^57TZyOCBUCu%F3mfef)A7|KuZl+|6v$pxSKv-d3HMOwVe0QtZXh>h!jA&OH0< zjGH^Ov9?yUsho3Lvy)O~O5N+Y5EF`54roHVkw{u)-yzsbwMpiYj-OSL*VDkrg5s;cA|eDJ#f300Dyi?lBX8b$R` zxNwjCR_upRvaf)u^pD?{gVde|A-VMAsti>+$M45p`XF_XSQU-06YWj%Rt>aMf<_FT z%k<1si25q_c_F>d8xwN``iv|L-o#A7*s?Rda)cj`C#(`*e}>Mj%EW89YCe`EC8_!+ z7p5~g3q$8t>_Y5{_dgD=31*I(-Ftt_I97cv_rV#-)pIx6Ql4 zr+i()*t6zT4!z8NI`k68TOGchUX2GUaqJz7i;9Y>k#{Uc5_)_socQk>TgKZF^>GYd zSTV1xkE3x?y+V%8N9-=Dz7bgruniyD`!(87UL3zlAI8m`qbo$=NBXGp(}u4U z%iE@gPCOPz)pXIZSW2iBbo8&|N!sctdb%1v z=VfHPk)bdza^AP|_+y99GDWeGk-4-tt87d>Wl|L&PT1a4@kwmBH8s@Ade~YRON+&A zQ;sQ9&Y8!up`1k=DdURwM{J~fmOZ8>jmB0xexP$@Y-{W;rm&Y;v#o1m1HTOot9Zm7 zQ&AWiQNBPaSY|zEWL)x}$o``qdhN-^W+Q%9UOrnT=UiYa#jsP~!QZ(LuOIgK)Z!Pd zNulE!G&%3o=?kriv4>(s*OiRBYWo%2Hf^}(%5Odk6;8h*_V-h7zp+KT^ul{Xoyr^V zQyQPOZeum=)pONG?I#OjOYA>#HY>f+df7{C+R3^swuJt(Ahw}ecr!kq%-Jq4-1*T@ z&j}<6XAg2nJQjB)KK_aQM`vCoJ-%pbe_9#7r81mfS#uh($F6(ma;|{WV-@Vd>mGWw z@MhtavGb1_E*vy79jnKOpMYNTP-eJw^>BL|;U|PL?X)1AvjKJMj3a$|qs_<OKlNvrv>rRJ{r&Zo8+$^@6l(U-lNYME$4fwC(g*# zjr7!Tp-XspZ4e&qqv1lYGTfsB{{f$A&eh6iHF_HF@tMZSIgz6pU5)qntPwBtlVhPT zpubJaZSH&@$QNm%;g5RZp|>i-f6#Ewols75FWjS}<#=?`?6Pock(WJ=CK~S1Nek7h z4F5sHJvx3k-=;Ou``t$Hvs3A(aV&qhN5_q8_>*3E=;t6j@{xw`N(?u1IHPf=b1roD zc;VKA;U_#g_Ji&~!uJN@_BKC!rKT_T!*7)I$hASv1asE0jfOW1f92Q1em$F+E@v~T zhi0MavHe0PwqMU^(jz2<^D^ypyeShf-vqgBa$7jX+)%fH@pvPy$`#zr(MEzq$BNENyohqI%(Di_O9x5yzo$S4Tlc;H9P)j@&L}%^x!;4 zkKm9lN3gjHB4>tAY~O%Wti72=GLdW2)M=91(&FS%o3K|FOFK&w#GA`oV zqUY$i^ZH3AcVK1vKA_>RYyasKDyj^BO2gks3^z;S`y#h%_-kH&3-@)-_50fc?o7t1 zN2i%}j&r~de@eqWI)1oWQn9%jofd(rI)51C@=>K*iKYq9;SL8g(?db8DD3^wJ zO5|Vd*rzo7q{ML18_{zT==ge4^n?9C0-fdoKZGaJ@xwiSqCG14VH~*|gZj~MkDoL% zxH9}H4fpu*!~HXL>!7pWt7oTMBx4dv`ND$7MIthO}G2El0^gTLh_O_th z&}a?!=%kq!g79#rhI@4UaI>WR<47NEcaKhs(0vu}3qP^Cq02Pfqtn7X9K0XHnHuiV zX<=ScyW^Jf=OX8Y8^9+TLbOx3Z~1eokM9f3S9)thmxbSx80+%bTJ#Y+5E5@)9zNTP z=S+HHeCxz`b4&Td)#!H$-B zdS;SS4sab&F7|afRDQ54ry$y->MFU_s=F2H9$SeudAhYBc2&hQ_6%!$Yz-utGcM*F zRx4$`s)2bZiRh*=wM3h?@%#M zCt`_PUs~6lIdx#49%Duh`_qIQU(7lbH$$%)IOrtny4VWqy6^|54ZCH0zwTLG&b?&N zS+UZSIzG31-0IAJrw=*h8EZWH$>aUahLMJ>NLX`_N6&U#wezN>UDjS*KjVATip>rF z-Yh=(=fM4OX8FVQUrw4pT8We#iX&5FtpBI9`ElmY-Ri&WhijyuX5Hqgg2XQz(#KObt3+~aI%>i9&T>HeLW;A zH+P$BfG>d!z#mdlRyWI;YBIy~$+rtx9y5iZ-2(9?JiCO? zC;uGs?~R^s#``cy>R#(z>b?dmv(64wFM*fusM^m+XU?(ZBY%jBjd~F z6m1J>4=bc96D60I3(AhiY3$ zdjvpRNLx#rh}=?sO;=>s@{i(bAEnJje(fXDUxm+KaHT&>`lGt^Y3H%{-y<(jU&GBN z>bNy>YF*>D=eaX(eQg8jlQJ%FokQgNjXcK}OFz|dLSL2sD&s}dc<$Zu9Ddsiw`b$F zi*F456#qclQTlXEH}avmj<7$ppBlSZ0}(Y=H-24x)h?%lz&j7u3CM|Byq zI&NyX(r2XIeyuCxUB{e^cWGyT-0Rq5{3p8p_-^Pfh|gBtL!ZDMM*H;8zVElav@sUO zZ1*^`MB93y*Us*XW)fp{k#l2wad>|GPSsVJ#))Q`!tigXhZ7iAqOWL!(5EKZE{cCG zdc%DzzBs5$x57-JKCg~GXeLI6P=9B}XH$mOA9dA}I%_3;%Dz6nN9*SS(=woqw;wY5a`MyaOMwwiYcmA7=fLZR%I9V18Oo9VA&GE~4+DaKeBWo8K zcSrEy_4gZteqOVmR`&OxU+0@e_5m}&<17A^j4StV=!2Wk{pZlHg0}Pd4fr{t+@KzO zSNl2rJ^T;o0d_OfLh2^EopuD=)8d~yAH|=tcgMeTn#U`gIq`fMk1`(IGtDsjYcrC* zUl;znYF+qxtWuwRYR0)ENZZNO4SyGZ+bb{rBf4|FjtSAHfapxsn?7JTuLC-%L|IC28ax>mYl&>FzWJJUy-Y#=erVlyA0(YtN&MyXdpK&BN|f zrjW6;!3W;O=)6qg9{|ux5vj{rW|Dg~@4lhr1)T2CLN@_h>=MENryV*8kh)-XrigL; zSNk2}{P8AZEkfChn+;AD@BHAMuDZqKI*Z|b9?;s10_NC^t3=RtOQ9U(<#t7;bGz^# z+vt2i8J9p8`GfRH158%Z4&Zc?6?xgTaMLOK2Gb(i%XD!6LfX^Gv&)>y`~Otu`uK(J zCGiWx_nT<~*53I3P(F3)L-+!7yrvy#QbO08_1Jdnu?OA+#4d=1zA@a%0oKs30qlf2 z9+=0(rT}gi!2bIH7dyk6ihEVnv$;ybxXX2=f=`dIG@x~Ogt;NK-rPW*Z9LzI`x)*? z+>OBA&?{0HO7F{_jYZZfWv1}_?TQC0vcoraCMFH-oKx=?>nwA+|#m64RC0{`I2f`>P))QET z{|e&120q81?78LZa5wQBl-C&lHGm6@1f)FS>smng6!6Qf#xs1EVZWF2d(b~$WX$1W zTx|3TRuv_G1+xOB@gx2};}3^@gCGl6I4dWl!+3~j`t>f=U-ibdS=@5S=+|qOr{iE+= z?37AfgkF>~WIV|`OWvyz7t8~kbTbPrDrh688qLb<2jy8GjA*Ip5FDp~y2~#_vrio;xAaY1Km9{B5I{YteiFM{T&Uxm6$Y?XuvCS#b-PFS$%{+IrXKV5s07c|K$@#On z-05Miaxcc_xXO%oZH<43`BGndr|B(a1pKRRmhw89-#Q)4{f^k{QZLv-5~1E{I}OL~llB76lzxzuVXjI__R_e&r46M`Pd5G4_1isY`$%guU+5*h zXj)R|w`&?nFZu2_R|Rcft=)we+FfWy{y{y^?jpZ?qq#rnQ|y}6l%2~Q=t9Cg9&?h$ zsY{&<&f8kqpA>Q_gO)DDoWsc4k2Eu5_L-9i@C7N4%GK-^n|# zowP~h8#6kxiS!?vj*jplJjuI=^0nQiFFgsbpP7zP89zHrA$+9J7rH0^8T;)g%J=(G z(q}xw19ssJ^z&iSdriaW0@E;v$4z#Y=(D;>UCo&2D3cjoNxgn)GV7edcJ(!cNq?i< z%6{2LeoLY3H1q{KB^8Z4_<2J(^T(Ot%%7r>&G5y%gZl4ke{L+9ziZ!uUy<9n)bz76 z>HE^3Mq_)@{?Z202c#WztRTDe1E~YtuDHkXg`RHi8tQfv^yg9^Z{WsEVRBdGY)3t; zW&D3goA`FU^b=d!DsiqrUFv!PbN1+8SU+H0Mf#4kUo{tfzS%x^Mlyu4@Ua=ahIA0?YTTZY94eiGPgL7n-xw^ljOWZ+MTAov%#E-4fdcTYbm^y zoh`WU@jTfKbH62io0+5W@6j(M{axr;X!6dSW3Pec7Rp}6cuK?mf7gr--Dlno6`9$g zxts*3U>zlkFTX?kh2Mg% zJa>sNwtq0AnPU!Me(?LyC*~FS9S_G>v)FhlkOpA8=rcB#^(im`;Fd!iOHV-jq3a}# ztY679bBA3( z{2jnMg#X^`a$Yc*nr=PM)6J942;7N;pAB4SnmT>W+0N%?m;E|pr~&%(M$^c-gy%)j z>R|2&FGlw~42+DI3q%^4yri>C9`?#UjHMsL-OWB(GqanTW$5B}8MCYGpW`xi*F-Ke z*)oQs$tK%=(p)31fKy`D24J@^3lvtzAF_cu#0w-p<3aRdvqS*C{wNSCiXTiGY_cOA z%w*^i>K5D5I$hFXi@j)nYCR3Kv_EBS z(u0+_*}z~x!UfI*@}z%K54YJ_=5mosc!Jih&`2{Wko9P8Ab)Lcc!^o?OCWWX2+pkP z&xv(evp%IBr4DNYtykoTo<{w5roC{bo&%8Q+CbW&8qglnCW#PPNL$hN(ng68w3oQr zhDWx6w8a^~BS2*vpc`e4eKBxfEwGO;fhE!hIh&JdkJ2^gR%)N{-m&+fQ|0}WLELpb z1K5g%&O&V8#k}j#?{+lHHbI|l!e-q79FD)~ zE;gN(vM<^4|{x1+g+x$_8TyE&Wq>!JhEaW9%F?m6a~ z$UMr)HWx6zdJY|PiTz3WN%)yJB|`a1Y?nTg2Dp=X|HXD|^N{1@@6E+7Yrv8E%v<8T=iesnK+}Y; zL3E4^X0Gxh@Pi-zcQeF!!Sr*I*%SEDoZ}c|_@1~s&6TVgM99C zFU(nm`;^IWU&p-}8&1+l-YM9+cQF>P+Sl2@p9Q`=L4%@?01_5j&(I_FD}%=``%PmVoa{UiD)`2Cn4i zy<22wnEBy}W}rex{0Trk4GcfS9vbNq!;>E8-TS#oPTIwMWUOcRRpYm*SstkcYVsL8 z`+P31=C(85Gp^9GSDX3Pe#T3}K8*VF&2qOo%;I@gbQX1U4N%iXmgo&;c{I_zp7iqU zyWtPbeBK2`3SCLtmU+~7jK}Y=i>g4L1JLkjf7>EnKdTLJj4hF6$A zfg6M;y5R-LH;(>=8~GAF{v~n-FpIoZFarOGBhm?_ocW0E!Yoo&(VENEvPR5Hc0vehma}5FWTe zc!C@LC-OWD;6}zl!-u3M$ejp<@Vl0<8g3o>c%3XW;%F}GF!SA>jMJX9Sry2002&^3 z>8la+N*etCh(BjyChys_@vF4!tI+a6=gA*Zj~hWZo%q&1%#_B;yJM zZKKcBO)JqoE@umX$>ATVZvobvg-64<<+B2kS13 zA3W|S!fe8Rekh1rVPKBhVsI*~o;f4KzAQRK*4$Yakn;~A+~K%wbX|@9UelE|D&n``o`u`q zf9~YD@h>8*SZCF{~Wl3D))o`56?r$nx*VX zitR@I{PMX7X>ZXbz8kEW{gPX`rsuEmRj!fx`_sWbb)`#N>0ar0&O6C^G<{6kJ3K%B zfw+;A;g|iC%KjJh!~bIU-|3IK-d>~s($8+E|4hc!{uH$HzwP?xI)d{ZM|EqqV{oS9 z7u?GBsIhh(ghvXf?{w3UIv;l|koFLWjxaWB`;o|eem`bAXF48X-TNaGk@rk(;9h1T z?iD5)eTjU}nh0OT4@V~(&b2WXjscM+l)?Ah_->WW25N*eCE=t^(3l3Th5Qr%`)eM= z_k~-=7vUd>dk828ehB}WG+)D8Z+JZ4L?|oFJk@3{7zHB!J1%(FRl1S3lzXFzCOvEH zq!-|K3jA({U)l3J21I6%=O*}E0gvO6nSG990p|`P*s;;1pOB9)RYq4+&O7Aoi+rn< zKW&eoPJ_Bawil3fT_yiMPeED7YD0gm%K3^ll^4T zD=z!o=#$>a#+eE|8=;4H$*(RpfeGQaI6dIpt?RDFx|e{LfLi`!Jzapb)1Wbp^Rxn- zYt=KPvThrk`?yEe;5b9^rktYy?(xr4^dw(*=LD;R0B3?X@LjkK(AdEF)NQpCSs5gJ z)yXqw)o;do_juEhHT#aNIdx3*^KN`KJjAR6_C}s#kIH5ZUDnZ|;;xVH5eRLFFGGiP zBJ5dfWNeb0)0H#2(KF1s?jJa(3b1xQ-f3!flV+6y=~4`~ns$eE-fLXK6Fk=DZEN@isFS7z&I4E&|T9 z`?81SLue>xV1}A&vHzwKmjTQN^qem4ug~w>!fMYlU-50qX=3+UoSpG)-)R~y=V-7K zIX83>{b3@I0o)5L5c>zWeckrV|L(&clCw=2tU2Co&T#IIzlSSno7HJc-?-Zx51b1K zjb!&@<_~w%Ux){;l`vo+HYQ7mN9Nxjrd1o}{AofPqws(nauI9m!)0Az89MqehTda*wu%b*MEerlR4mHrd85w zrd6G9@b4jvygiyfNmiyKv|Dt~_)8p5O4T z20AuLW72?RKVOcYZ?X5xoa6|4N?XRYJwnhEfZiozL)4{9PQ%_?s5TVw|930nxbdM%N-2oZfiKt-#Hdf7&JZROXb@fzt8p=Nx|=NC!;%aGV6HS6{&>RMpCdFoeyw0R}45B5kR*q5_M z3M7Wr=7)xq_gCMolnGnmW&y$lMnP*K^XfM$A>e&Cc8Uk%aK}0P?vnP`5NG*G1C1j< z%esZ}EU?||*5~b-o;=oX{AcB*&RDZlATjK}!XGu^A@HVloVZD6o29jl(_qZjh+pcD z=l57A9th0j-IWXPzE1Mo@K@Fefvpy}?!3@zE_-&BE_GyIY+T;4TScz$9&EckCO>fP zPpnTEx2GiaF>3_sT;jWTnR)mvx7;kpZkKcBg<@OleCJD(CTWRlM}J>f9YSKq*9enm zFWfbuS;)58a})h$v+x3sy(7OfyQEyV18bajn@gNs{6?Y3U&^`4Ujg>(@q-?On%S>g z`>4MR503UM;X$0F5Ap}@zZ)+!5+R`T|5vwW{Rp4dJiktG#h=K#*44ieo|yM&exVt} zss90<1Are13r+G|NhkFy&p~@txo!v6_Wx55PNnaeDiC_k43DP7)keQ6T>9^?0cQ$l zqktf-eJ$sq0Lpa}!M0hS2ZFGg&qoVCS~^W%#ysp0G;x8MzAOHt0(%G3fnA(&-4%JJ z3c}5q=O;kGPfb_mw}GsQZelvlEly926aNuBCDzYI;sN$V6oeK!^&xcbB;4`979a=6 z6X49<7Un_{wk5)uFahUk=4WYULDG-rF4o5GCT=INLx6AeuEG^MD}h2E3UD7vcz(?O zh%+Uf&7;1%z>kx1#&eE#Jo}hioNl~>&f)$GcUcG*cuZW*kcwaE1>wKs-WR>xYze^2 z7y3|K`>*B^>Oz6%4Ux{)rNAEiKjGTILHt(&BAz3@uvR_ZZLi`k#7**C@mm$ZwSz=+zWiaJkJBfcK9Ri$-ompPv6bN z{Vj3basQ4R#uZvJCu8o0E~o}FXRzu5XZYb_M+)Ck&ZWNpa$JF~fP{-%6S@%wPi7?` zWefy_PC!rm0uuLt4`RRk0hs1PP_BfDOlyE_K%U3?pmb=HiNMV@09!EZFt6MOxa<)= z49v41GYc0(k-JN#FyZ9ncrJ47icF5?~7ciNGIz zjqRdow0}q+`7Z;RYf5`2y5g@5J|{c?Ki)c6Bdzo!z-sIP=Lok8SQ)s|2KNJ!H)y-S zKZ~&Czy=@YV7E>Ku9tTaYiipRHk-Ez+vt>-w}FkM4cfXP{!=*@Jf{veE)cj!^Gp03 zcOdWbfmY|ELpb;7agy)<_V{DT{=Xsa|MvF#&+`Ajp^c9rW98bORUaJ%7+Gt4)Q#|s z3;|h3xY~zW))UlDCXJ>urXRMYLcI&C*0p49>(~%4sSz)0WG&%G%NN@J4dAU&9i8?s z#s6n`lK0IXAaHx*2ZA-y%J78v%JorsUtA<`#9ScJ_7_`U<_CvNdj(lD@Sv^CBM7@l zfc5rd`33}c?>}Tetgf63;f%ytdS+r1e)h~|FG9|81!pQaZ+?xe&FlWC+`sR~+ItCm zT(k6y#n9j`uFL&Wdnozj+}Av_UhabP4s+$KiO_N`0w$T(+=02&iE@_yLhkyV$=SiD zxg&U{xy5z0{HN;OgmvGl>gfoM4eN8odB>>a@ zuk&FRbSw9>DOc~5y4Q1t@vqcv6ZUt@sT15FZ-}#@&Oy^z_J<-D$BUgYJbwYqVBMMg zth+3SryRF0Yd)lrFxfAWXU+REd?oNAX(Zg`esfTU>}5p4*bH(W2EWkIcJb-y`H-cA z$$25xiS*k#^m%Lu-Ny`E3C9LZm@EA6^Xr*2{|qbh<{~-M1k`cmTTikd*F9crv!kf> zEOjk?*zX5A9;D7?|BC)C;|S=aZNWZ;w4Ls|oo;r?87FNo_Ub8fNsz{;wOsoE?ImZa z1Z1xcekO;On&m(@XFUA}z<(OB%*JjMpj`bfi+~mki zy;wQZT*y7n`H=~nk$;vu%R{)I*qCtk*|e`PW}`#k;h)^69msy!d)$ZIX8J|ABf!2% zRO&{~Xu5J26CDwxVSV%2|5ISke6B!f2=iSZ!i&wKa4Yt%hjYdk&~ZX}+?`2w4{&GD zzniINPq~wv%-$mBfisiO#mzC9++|4SUO;Aa1AD35KdN-k_nz779VFiaa0bxU+2}vc z^>end(3xv4wFjDckxb6^<*;Ar*8w_0zN?fRS_qrR!DPmo_ngfc4y9w?%^e)hOgMG9qa%EL z4t&S+)zHPJ;mk%BcZa5N52tpRPIw|L=h+8$C3D&uV1Gt@EgVITV- zfJ^&!h;}sB*GV%g>ohd$>$m`JJ?6+E?uc@VW{%wLbcUIsksQ7oGnDa_#rygK=pE3r zT)W)g6V^)iL*J8op@|@OQ3GI)qS~F*@GWK(XO~CGeN@gkj;eMamAk0n;2vsl2ep>_ zry=gO3SGI!>c~CSM;JTYujC$cc9`F82oK_%(SPx?-i5rKyQ!yhj;YwYW15uk%zW3s zvr2r4z`ys*Ih_U6g?HDrHdpR*9`^5W;s$pt?FU#>2mak>xpx`q?%lr>H>fx604<3m za}V<_WH_I9z)Ic$yUmjDtCTYt;BF>o`1O8fZEl1+n$c!e?NCX#M!5M;|H=1b9n*zfdy>iZ_|m-^p-x_{K@4|0dM&c*1kKhqc5bC06Nv)-5fn)s)s!pD1Y(BH>RTlswlsI*7KcyZo2erS=Uf_lH6?0C$-Hm{ zcHKJibi{7kjGa6ad-ogq>jvIKySO9do$b0p&d783yNmM*Huz(D=SaRUxz_m){btEx z`k8z`X_~yBB_EJwpTb!(Y()DwzA5w=_QEF47)rN;=qRp@K2KlBB=LURv{@cFmS}6~_ zieKen-XgLHuR7NV&Kk;`Ugj`0zFDQRNj=DXNaideBlAscW&LiIp11lR_&$}M^OEmA z$+xKFyHk9FO6rhxj8mBh$ae?|fMb2@cbcE>7rzOd{8#kO{{z4`4fp-O0NC^U{>NY- z>z)6T<<%@JVgEYV$FAmPntPMxnZbmeo;0v(uRCcJ-)lWG@9$~}tK1*|pN^}A$94e^ zb>FIz#SiO8`Z4(X0jD1YwqT#iy~1aGcO!nj?^S-g58M-|;5KOadLU|+GxOr>7y$&& ziS}jUoFmb`3hW+>FBvALPxN~>C-1Au`N^^UcDh(d<=fD^ugcv`{RZbe>o%u4^hkIf zi~lSj(LI~z03>`0Fw}STzNN^kYgc@uM!r*%Xcs2VC1n1iXQ;8SUH{v!@(k#?aNH2E zMZYn@yO1^Otq36B@~I8<+dp1@<_){CYvmg-W5fmc7L43s)_crykGD5Q|aAkhi}U`3-JT2FSQDD-&sJu zH4{BmT=Mc=8M~giyzlt-jJrnM>gCE=^nhpiCQW1rJOI_o;u|&2X2O6(nu&S6Z`BaL zvPRxSo)i3u=@b3*qfdUxo{R1dT^RAdKZXsoUgyIy7fuA31J{6R^Pa>xP=Y^ku9N7m zF~_N#-z1K+qxloZU!p(xWahvtXshJ_-$T+l4|C_l`A?$1GL1iv59UaT;fZ77sQ$!x z{89Y+n+2?=^H2UPW7?;2S~S$mnB=;3O^WFqdlTF@J{jCEz7gC%J_?+n;RS-NbjAI^ z?M;1?4sM|M1jQ{C_l}Pxyic5OSg5r(8SxD8sQ3Fqc<~^kT?!M1_@OU&q2g@C--6Sr z(JtU#K)Q9jVyU-utF_{`ir*KUTy6%N^g0IIfn4d}3|gmyDG-c|g8L~xBsl3?!O0cz z1Ke7%z@1F}*bZB zGFwyTD9%-!r#N5n2BmPH;*E;$SG-B_1By2*-lFs$Qe3EbtK#j7A6NW@;vI^2D&D2| zDdnd~@t+j$R{XSbxL0wp^7D+ARigf9)nBUq=hXj}QhP`7dx}3${Gnj0zTyUoQx!K> z+*InsYOc72;*+Ix>lDRZ6rZNJyW*aT`wCZ<)`q2$T8}8Te=7c7Vw3(Un6^#_SH$3< zjs-r+^ri(*qQ&0?7YL^R6GDr>X-=h0hl11Tx2KwJiu(|ID(xtExZ+I3S#W!*S)^%} zDqf~|x#AUyS1Mi=f1Z@9HP;%&YZb3kyhZUtiVGEQRlHsCebnDK z_80v981G%sU3i^dj-QA<)RNM z*XpYNev&4+Jl4r{sbgY|O*d1Ymg=S>x0`98{`S;xH#CXh{^aUL`wGt1kQ~Liit`lb zD=v^UwEGUzoe_NpIE8xX&WIL&dvsKHM)C9Dks6*w&2)#Rgy$&ERh*|dU-1S_f1l!w zitksvN$~@UH!FTxsqGbPwGsMOJHhnWzTk@3SkoOHMJ)Yxtm&ch_SCmSPklS|q$h7Q zJymD+q%FiRnzN^QTK#(k)3*hS{_JH$hxf8tD{c$!jnoIgDQK|XNc}um^jL4zW4)$tr}U-H#eV{A(U&?G+@4X;m(h0sJczdFi{=qLL_>zFKa(EY zmr^8Uj^bR!d5ZHDFV*zR6fal2Lh(w)s}yfgYWFGLsQ7-xn-o8wc(dXyiXT#3sCcX5 z?TQ~){Dk5iigzmBrT8i3wn*`x6z^92p~N!Yk(7EC|7jA=d$yJ7%X@Z^>BmSP1x}%6 z`Z3bQe*$&bkGc}vUc(2Gs~@!_c(~%rpxKZ5kz6^7a~0<)&R4uaQ{Ja|qvHD&Z&Lh# z;?0V;D1JzBq2jHIw<~^J@e_)7DBh`fm*NivBc0%;!WF&ffa#A!qrmBe_g78ZAO4@m zzeqzwqxLtVQTrRwsQry-)c!^^YJVddwZGY-=^s*DsCcX5eH#0U;twT6HEMs=?fq4^ zXV3$;nhYKF8T3H$pTJu$gIX2bo)MR!yk#hF8T7+Jgq*KW|%95e7WT-3|DoX~k93agGrFoy?jf(GAyh-r`iZ?6XqWB@jg^IT--mds@ z#ZM^Sp?Ig_U5cMlo{JR!N%3yQQezoLYAnNiC@HD2jo`-WKTXmw#_up0jB(C#=sSY5 zNA$o!Xj;L0!57e1mw@FBasho6Kbm~8xd0tL(hSx19ZLUv9>28RP$O-}c`3!xc0LFSCqn?0@lpFEn+Qk*%|g>?9fK*;whs>MSE$XBpW#%gEMQMvlsxqw?mc zyg4c_=PIC_qw?mcyg4dwj>?;(^5&?#IVx|C%A2F|@>^)|oTKvQsJuBUZ;r~Fqw?mc zyg4dwj>?;(^5&?#IVx|C%A2F|=BT_mDsPU;o1^mPsJuBUZ;r~Fqw?mcyg4dwj>?;( z^5&|%xhik2%A2e5=Bm88DsQgJo2&BXs=T=>Z?4LltMcZmytyiGuF9LM^5&|%xhik2 z%A2e5=Bm88DsQgJo2&BXs=T=>Z?4LltMcZmytyiGuF9LM^5&|%xhik2%A2e5=Bm88 zDsQgJo2&BXsl0hAZ=TAVr}E~hym=~bp30l2^5&_$c`9$7%F7qcY0W&9H&5lwQ+e}L z-aM5zPvy;1dGl1>Je4<3<;_!h^HknEl{Zi2%~N^vRNg$5H&5lwQ+e}L-aM5zPvy;1 zdGl1>Je4<3<;_!h^Hkn^l{a7I%~yHzRo;A+H(%w=S9$YQ-h7oeU**kLdGl4?e3ds} z<;_=l^Htt_l{a7I%~yHzRo;A+H(%w=S9$YQ-h7oeU**kLdGl4?e3ds}<;_=l^Htt_ zl{a7I%~yHzRo;A+H(%w=S9$YQ-aCxw)kQkTU!-&VMV8F*7g?gU7U>*+ktK8dMV8F* z7oiUan?*Xu|Giqyzo!N!o8KcH7!C!?9RK%l1*UYc&hdY*bNr=f%QwwZ&ASwxDSnw{ zETvWj%PeClGzH5nV=3=J!7|HOYGjtN)W|GjDJ7DIvUZqdN^_agT&6UaDa~a{bD7dy zrZkr+&1Fh+nbKUQG?yvOWlD3I(p;`Imn+TXN^`l=T&^^iE6wFfbGg#wYbS8ETxl*> zn#+~ua;3RkX|7P3E0pF6rMW_Bu27mQl;#Shxk72KP?{^0<_e{`LTRp0nk$s%N~O6{ zX|7b7E0yL-rMXgRu2h;UmF7yNxl(DaRGKT5=1QfxQfaPInyZxNDy6v!ng`4(XbP4# zS_Mt?rPYpuYDwN_xnS}QPOtrZxt*7$myVzJf=j96<0My$00wblyMS}Ra%tw61{ z0!ys50=3o()LPqsuG?!ipv?q}opzsw+@~S;X~;$m*{C5KHROH`xnD!>*N{ybvPnZW zX~+W_@_>dspdnAw8^@Zb>4#W^>ffvWV%62fs;i4tR~M_UE>>M#th&0G9y`YrtFA7l z$7bM{72RS=5iIYfV%62fs;i4tR~IuDB&FC|#qa=DU0tlYx>$8}vFhq#)z!tStBX}v z7ptx=R$X1Jy1JPD4>i@*#j2}|RaY0Qt}a$xU97sgSao%=>grh>#s`8eqyrn8{smfcb z@|LQ+r7CZ!%3G@Pma4p^DsQRETdMMws=TEtZ>h>#s`8eqyrn8{smfcb@|LQkr7CHu zN?NLtma3%t(6sDc>-%?~zJK@W`*)wdfA{J8cb~q0_v!n0pT2)z&|EKQt`{`d3!3W% z&GmxjdO>r&pt)YqTrX*^mo(Q)n(HOa^^)d#NproVxn9y-FKMnlMxQispJn zbG@RuUeR2yXs%Z@*K6cTH?PqylfhykyrveyYt)$d#X@*ZEri$9LU>Irgf}$T8=C74 z&Gm-ndP8%)p}F4BTyJQuH#FDB^oj%KV{*L-mi6b4X-z`N^`N3^UWx7gGM!%9YYZS}6YZ?7Yu&le5(XWJ# zth<)!DnXg9yOz<5NMp&mYniUQmg%}{TzQKtZ*k=dID{pb- zEv~%9mAAO^7FXWl^!XhouDr#Sx47~aSKi{vTU>dID{pb-Ev~%rV}Y^8R>)i&PqxCs zA(&NbFtrD!_Q2F0nA!tVdtho0%o+=rH5M>yEMV4Hz^t)=sXZ{Y2Zlp1wFjp5z|&E#1q9j5P?x8U$kvg0Tj{Sc71!K`?7~VAk%e zeqs%RS-S&c4O;!g8npU}HE0bm%pyYzsHMi>Q~15{1+1W_gEP!vFuSo}c4NWp#)8?6 z1+yCqz9aS%xIj`;+Ti4Wp=aI%v$GFoFCNU!KA4?-FgyFn|3W7SW@kUSOv(jQE|_w` zlnbU@Fy(?N7fiWe$^}y{m~xZR$>0jg9ScUYf&0bT-K4}--~z#vNGv6;N{*ZM?y8&jh0r zz~}@pIsuGM0HYJY=mao20gO%nqZ7dB1TZ=Qj7|Wf6Ts*MFggK@P5`45z~}@pIswdH z5*VETW-kfMUJ{tSBrtnPU~~c)od9Mp35-qvvzG*BFA2_mgvi3YP14Q3}Ayh|}V(fHYk2D1|lW+xiV zPBfUEXfQj`V0NOx>_n%wWVEgVvl9*Os+gVV)Ry$+^wgI0vh>tevT_b)Qr{&}g*Yn8qD}yMWJ) zX|mForo=ZL0qirT8FZQz8Pgnp8a%ZiuEib398dfS1C41p2`Dk9RR(a-m^RRByWg00 z@Z7#DFdNtm5O*TaCuRcBNn3JJ(@)Bb@M}e0NKPwCn zcPet6T5e1ic_3F#rm^ZiqOO$Rz34WHiyjt9;M?f}Z!cA5u3Yb3Nr?lb0c(p-*w znNfaj4gV<8kAjy`LxAZ3`9^Iw<_h?^A`>9&3c{{f50n638Ix5PAWzmLK2uJ)^11P= zpmP;rSB(HD^Qtw5pLR25%q75V;4WZ0@GkJJF=Lkin}N^ybZQhB1VHbag}_Q+8?X=f z82HJUaVbDY0KUd$0@DG~joZv;w#hdh{>JYI;AaA9Cy;gmX(y0&0%<3ZcEUDb9{|k> zKN&NTbQ4K8k#rMDH<5G`NjLFbW3C;~C(~?z_(?;6c>pp^+5>zJlpAwhBcKm}eAkih zx*~wM>+1sTfed3N8=x~V1y}-X2B0zdkTFw8H-&Ulc%BN4sdoVz0q9KK4;0HnEr^f!=ydTW64r(a^sj7G-H>8oEaP=D?-z@UY zBHye@z(Qapunjl>KzlYcX8&Z&oQ}XiU>;Bi5I=|bxpjdIU<5$iT*{hDS#$RRUm0^_ z6rh|N2LV~YYyjSGM7|q~fc?hI>k1s?=Ron_^f{kDCH`jI`I!LjZ=kn;ybGonbIb9- zN@H$?mxXl!!fxvbkS-g4PG@6sQ~0?@8z5c20j2{l8FM>%Z~qNYV$2xqB-47h%Q}o2I$^b?HQvm3!g3hY#z)JvhRzYWVU7$Tc+SR08 zP1@C@T}|3Ggs*|GH6H^%8M8J8fbX@)zBUt>4%`8(2X+FaTT8liq+3V2b);KIx^;Vu zDS)4X&cGlb3z!Yu1#AS0fc?Nh!;$3wkG%VVi>xXiKmOc*Gc=N+k)e@ZS1id?ED(dvGZ+iMfe(41w>CFE6 zHRI`}_HX*``RIqe&VkaQ0IEK-H?J|{!02L z5OX8Be_xDJQ1>SC4KUV$Mv`+sS>q8|1rvOyrJa zw1^C)g7`a$zmxX63ee9#=NrPf$gm$l^n!8RP5rxjME>YQ3x-AR$wi;YNC`$n?xp6v z4VV(SF9*{if1<`{F^IcgnGt!wgAgJj4`zaxG5U_Rf$b0ZF(mRZ{T`<7!?Zop0O~$M z&Zrw~i;jvs>P4T(V~qdtG)#z$w~0KF4#x2$%TJ}k59asOjL1X<$n&%hjN$27{u*%d zJVX9xXn!^U`aL^_$=I!(Os4SD262;&Ws+Ra(e_*j#6Cx!=cxUBGRXh@5Y#&LUPwhY ziV;K;Izh|}#JoWLDf&%i!H-6Ci2OMREWb#d7i&abYR9C=bOuV$g#nSj(C06V{V!~L zIUN<~#*D}-nec#^SAwVqaj(pY%#e46Tr<>}@u3u9^kPut)oc_X0P4R=jaSM0>L{i~ zUb8{J*XZ+F2l_FLasHWW6XgD@7tM%(_F39zvp~Pu2J~PEQIXe)f4vw%FwWQ8K+ZQ( zK>Qozd4oD{P~#19y)nbT5s`#+kn>Gq-mCy|Z+2r0bNrqKdFL9@$L|&q`?nkr`?pds z_P;fu6GNC1`Fkon2q4P8JI>F45ciKBjK*k^%x?;0B7in@^G}zjAOkt@qXrY0*IrF(aBuO*0+DnB+If&)@iq19i@FF6&c7D%|%TYHC_Fp?a_iRP>atf z+8$G)C7WP-GO-^`6K&5V(LP51kIjgdG9ubujB&47(e~~Y?c*sRPihm|MEgXRX#0?V zANudZ_D>droP18v(&)c0_4X^_pXnerJsY%rn)pv=zym)*pzr=UU|a{V?Ev=i0rWe7 zeQWzLE!u$r42!miev7)nI1b7}D+WZ%pnnE+4kqWpQPDn=iw@B~n~qu0GHWm)+98bX zP}&ZSh;|q?4x`UuBcizj7{VAPL7&4bz&f9Iw8L3noP+|9WATh=ONv3vl18+nSF|j~ zpXCAlvgnsZza!{(L>lOK1Z_upLA@ixXaVCtk}(`bzN1P(u59A7Ge!GcDx#tt&3-sK z2=Xl@ZYgm~Ye4O#gBZmG7*|fcXrIqQF381aFKropmPPod-;zH`By|Sg*nl@9*`?P8(wsP`YY+TG9ub4 z6X|FLbqeTTm;<&KQnPRv6QZ5a2I}!yPCH=`qoSQi?h}bWaauHA5^T`d7ZPoCGRV8S z0b`;S1wfuPnPB@G@)omPOx@yH(Y_GIlxS;*L|fM@nm-lwXhu7tqOB+Y`W!H}4Q$^q zAlgZ6FR1}}O6XTY|B`XhPWGS^d#thJZV??w~eHSsmX*A$~2)c7KOzSsc9QA@pA=2FXgEwQyDqSYmX_PT6%5kMna(TRSjxJl8% z#^)&Q%j9baVM4TXSU-n4=ZuPWE;;x- zrJc*z&SO01b%Gk_4T#p5f>N;j6&uw53VFU7#GGj7GrsfF;RZF&Zv*w4sM8b`?P~#0 z=WDZ~eVv%EvwQ*Z7cjO9h->yDf+^9y;lYGx-(+mx?7@g=-^#|AXf5<@X%_9<#po36 z!VJ`lb`iNQs+s?V-U5D-|6;aX%)GuspYM?KJJk9vdA{2yT3ZfELA~#V(Ina>nFxWn zOL{RY+NEh=+oj#2wNs;=TJ7}teldDP`vKd3K)oL@mdp5gS)XVfDWDFYnY17J&?VZB z1pT7@n0P+tXneNOI?2&V9X_{cKWP)~a<*OGBHB;s^HcJ4B_o6>(SGKIAN80M?dSab zd9!H0p#2xr{>3n8@3uj{Zu;@LL+g%UOtdSK;6@4Pdj);3=*AExMB~?|wJS4_ivWnZ zlKxk+?JD|S#c~h1d+5_ME7~vF{>y&Renrk-b%^$B`u@5Cdi}>(>p7c6}PiaeX_8 zy@9$nv|?7YND4B+93u3K)Sv~7Jrcnv7{iSw*mfg%Zydp-Xuo&EE80zLyNU7KG=^!> z1_Geo&4M&!!-t?~w`8DEv|Cd^-CNs48>DTJoP*@NEfu{W*KISR@mWc`y;HP1h`FNz zY`bF+Y#(BMs1-ekigu?5eWKmP&%5Yz7vuf|%YSGQZ8!ytVOTA9U_`XLvoMZ1(f;U1 z2-N!{+y5BBD5gZa$3!}^L5_QZXh0i!z0^l!Q#=q69T)2J;=w0r^MCe?R%}Pe(R<2%-UP=)oYU zaX&R4pvD8#c)*Kp41oRez^rHwlJ`N@A7p<&Nc}PDkJ(_~jTN92jA5)1t>{FrXb(~M zA$~s07#?=R1IF<%wI3cA?U5AF_DBef>5&K~MT^>KKs$(gG!?n10Qny?!8{-9#E58* z3mC`aE$A0*+>KIDXPhxVkp%ia(Sd2vo=gMrPY#2*KV_o?#7+d!2=Y!$iS~2~n8(vi z=*A!>MSCV0SqOl!KhrDPv*dV|nv=9o(l$9Q+H*ccMSDIMw7rmo3eYx{gBFa7_U8~r zMSIZ;a=k>{OSHW-Bic0a)03k8rCzj`X@8mVy<&rWuMj&UC_pKCFelopEWbJ=+H1tU zMvd2~_g7;6%9v(7@FODH>*)xK_6B+1$V823Z_jJU{-W3BD&syanX$|G+{<`GZ*cc6WuCBGiZ0P>=+f@=>~a{1jXnT z{Ua=Y#E&u2T_vEuD=PXPHd;ZyWDmMU|0w?i&`0YrDEgksAn%?XqVu^&{}?$w)+Krh zu_=rvWm@#T!lLg@pS{Vu_mJox_o83)RBEOMME?XiK0(YUMnvBy2koHWCu#fSfaqzo zrFDwFZvn`?Uj~{){}lZ{Rf=KJ)6+rBr)|_AD*FD6Wq-CEkcBqU?G&&t>^ad741sNn ziqQk&4{{>_>K;U$gCdv|osZ9YMjFVILA{K6w4xgW7{j#a2Pc902Q%J-$$M}G8qtnk z3}GCzqJJh8xhMrOpP|-gX#Z?B>Ot<$j$lgkO!8)C!H*D_du9jvK)y`+9l}02!~<#` zLcT-VLCr&=m=XQZWDs*GF^7`pQ1To~oKP(k)co6_`hjn67bhm(Z zH|=inyNAFS+>GIHAA)E=8+tH^C}u=ooQw>3;715e=s+KaMPFhg2gP76d^XgV(0>X2 zvuMkrEsLC4v}MtD1Z_vqb_8)pFy|u}(-Dm62*z{-V>&VgnaD*6YS4^M^kYQyqZrds z4QK;nK8pNDkv}^f*$ATrj4yivbE1FF13yA&LI?Ul%;$*t95F|y!VND1AkWb)=t2ZD zqAz9pQXhh70(q7WU<}iu=a3_Zm>hECkRyj2IpoM8M-Dl1MlmJ&=S`#|8|3?Z5DjPp z^IXP$SeAuGv}02AV+6&h0PV+&fOZeV8d5$N~@!c4}7^X$fO@fUa6r&l#qUX_`M|)lXVf11M zJxnpefi9Sb}zpi@qrv zAqfV^s9bY~S1?`j#BfwuL?wX*O$zC`^m1<`{^(Z5`Q8POYjqMzdiV>^fTa|0L@{XFuXHz9gs7}RSd$5)CG z5&f&FXh1)vML(a|^NBfsM)W3Pnub98*V-^9`qvr%*BQ$N*(d-tE~r5h=yw5QYED50 zazKq{;=hrE4n#%&W-hu#{}$W7#kLl5v~+?we>({Je4CmVW}*btzQ_de7g6h?R?%B+ zkndt@UEBcbekTp&{VsjJOTIQiBbdwg81MIp|K1>2zr+jrT$&1EF6{!_E}ay;Jqgrm z4}#q7Z6LOt?d?&}|NF_vfCqkr&;)9HzYoKhz?|qmNQE0-1kivs^k5KC%!qzjGKjm( zhaiZ%jJV5)yNtNYh`Wrq4&pj8;DH|@G@%217{&zVME_wb-0&iRFj~-s2%?w~{YS~j zfCqkr(1Z^3VHgvb6aB}jaKnoL!e~JkA{fP#=$$6gkqsY$Xh0i!Fo-B-ME^-LGT?z9 zAvB=_eHg}s=$D%y?sDQTC+>3ME+_7C;w~rda^fymadV>oG!<@m5kMF%=t2aem=V2; zxGv(ldP$;f~QeuU734)kFd6POeI=c#bRivYrCK^Gzz#gyp3Fp-XI z_|O4zbn~;j2ZM-WM)WI^kpU0<2%!nYUeSkP(D#Zt(XUK}8(stuMhm(S!6>Fgzsf{9 zvf)Dz4d_50hB1LT(R)(ih8F>Z(Sj~SFp4SBe`z8e+3+EV2DG6EgNR~A^j{?-10MJh zLK8aBhha=$PV`@=!VND12%`mEh+q^`qW79eM>c#2q5*B_!62fT5&bvG$bcX1=*1Am zF)R9SxxV~16S?5J^4l6TqZ9oY!KCO{3#fTDHLs@T)zrM2npacvYHD6h&Z{RdCwgBh z-0&iRFj~-s2u3j_`tMBG@W77{n$Q7i|Bkrd5qAx7*Q6sGJ_ON#HZY%ShB1LT(XUN~ z8wDWlTH>xH?%EyXWspjqF=|nuS-J~$ax(( zuOsJmBI~euD`c9{54d8_0P>3y8g;55tIJ zM)U~rk#xA>1$`nRG@%2;M~IJ1U{3TKQ$g&F#NHS{7%k{R1f!S|{r4u)kqsY$Xh0i! zFo-B-M87E+8Suc55Sq||J`7_5bD|HV!VND12%`mEh+q^`qTg&H9og_9hz7Kw2ZJE? zW)(Xp`Yp*I_7*P!2%`mEh=ABzh`oi_TT_t%4>%ULax8A;Slrr)evE+Qb}PqikmEMU zaU0~g4H7$8fhKgI55t%Md2eG3w~_ZY^4{i02*ln->}|x}HVE?GM&8?#kcKQ2pcM6J zMK}7vIBqBYcH-|K{tjaQWz@N&2Av@Pkbt~HjA4jvL$nW#i+-mKFM343i~V&MW4o(Y z^gl4iKeT}{4bwhM-{Alv82-QeBm3tb`rK2D3N)h|1EB7R2_L92GK2}y?+9vw_%Wc7GSx&kvCA z0k%ItjRzv4KbQu#KiDezm>>uA{ij7me~A7M(f^@t(H~|U4+lhlBni!+)+1x0M~R7g zP>&HX=jg2Hk20=D8SA6;dzA4#O5aBr3g{#Xh!kOLn|5eD@h>p(9C zF@`D8AE)-?4Wf@zV|+;TCz4Pv`jgatvQhM>=sQ84r-^&I0<=BTim2$%(r2_Z$-AV<~75BP9tvV(gU;A6h}&-YoA;-@RGioBkgUh>=Qc zYA>e6_yptq1moC;8vA$=L<@Q_j43fbnG8342%!Z%7{-(sY002}8e>oMA%rHhp$Efa z>}!It?dygYL4-lvzQpa@g+8d*DKYjlkqYAX^MTm?TF?RF_8Y|nX2kduv7bssM2t^+ z#MnQC1`xmhlo$sjgKakL2c~0Kj779(q=0>&QG-s5h;eWlO2K~rOe@C3_^b`~_h)-S zdnSD{$)DK|>K~GYMllX$zaC1T!+c`6Sw37)3g&h=c^0Rj0K_h)@8W4OmehcsSy|{1 zm1? zrK~S4MFjNA@t^^$e_oIa@_e2#^Q_NU#`3aJF^)+G{f;63F%x2VY_RU>#JCv8vVJUi zj%A$3QTw=NOo_qsI^%f8c>JswxgNBNkyio6lSjYh8DM?+pcpHtu_6rGy{RZbJE)&e zj+H(%Vp5D%9Uy-JeG14`*Z|^A@QA^)EaSvB^o!vWkjKZi)hw@O+iJ$Rni@sPC_xAv zVywvp>uYK-Cq{8MhCrP!w1~0Rgbn7fmfY(aK+HOF`6D8u_rf* zaf)AzQ~4R_1u=nHF-~LqY1BN8ny0maeQ?@@7^i#DCB_-lI->%Np)?cZDrH<{^_Ui8 zW3w2WXb%z>jEGSl7GrY-#>Lys#hA`w zJRvVe#MtUbRE(+=gwQKSHOtj3SF7b|F=~kCxsLHg69pi?)`w0ohPnU-#0Y!PFUB^; zv^@>9ZzpC)26`|lMm@_spE2r(#WoNMlrrd+t*9PxS#-Y zVl+>R@eSg?Nv?0!pbg~u7GwWb2(4gVExDj?OCM&$_;wD6{WfF2keU~g=OVUW)P)f- zT9e_$gcui7_hPnx#|=MPFbL{@m-X*9p%28i`M`3UTAmT(dzom*xEPmYpaQI4G9<>O zSz!IrPBGf~`F+;EKPAQwy2ZH61Z|gfAu2|P7c6(oit)n&G=MrkN&@5m(X<#p4ujZE zVmn*G@=yF2665k>jEV76YW%brjIFB_O(1URy=va$Gqg##Kq6-&N${GqrJ5rx-l~8(sv_j9xIFU$X6&nJ7Sq7{6lM zuX;ePUopmCr-FRHrv2AZF?xyZEyb`HzsVBgcavgVB*slSVhl`*aVz<5OA_Ob6fy1$iE-D27(Mv_DjgdeHvRD2RWU_J?VIm^=@Y=iy-x{|N1m_)vom3}IS~Xd1kr zJ=zZ1qvUxs3qjEKC^;TuA8_AlJVxAO)O&1PjK@<^0BSwniwQBtlaP&4w4e`BF}Qa% zo}m4S3bbJWGh#exgK<6Ch#riI@l-NApw?6Le~P>lX($0XCnA^=<7vkDGLH4o-IHHnlOlQ(07t;lZq|zXn5%7&tB5fbjf=Ua zRLo-Lu(nUkb>#5VZ#{iBw2N8d7W3o`bcuNi?Wg8oSj<2!Cd53A?WeJRdK)IiJcIF; zdc-WFPgxKHVs2!4V-pzDCL7cVhQ%xoh`FUg%nF~Fm5kxc7BSCi5Hr*&=2l{=+Qh6b z5wnIoU+fT*do8n$8ewvUS>Dzo=Jswexvw(M4vG2YY>bH6K>vnWG0!3HoK6g39JHOA zf=p2B++i`#D;Be{0Ob2>G6uvvKNrL|k@xHUVt#{|Zwb60XG;?NVt$)?7p9AOk%=}j zTbsqaxKGUQ^oYrSPcqw>U)z9~-(yafjEdRr7xVkn`~m%c(1HmuFUtjeJIK)y0&zd| zfNeh-6!XVpV*aE6<6`pPAllNouhDk9a=_o-5hQ;Ll*u1ev%-=Jvn^?Yyn45{cHA~Ff z$?L;sPSwn7z@{Z^Z6+;r)c|gub3~+i8;;qrpf!4 zTy%^1GC5u**UPQw!H}4*Fs4`7{tDY?$i?;9#vjZjSz@^ zV^YjFiRC(Kz8M7D-|WYPm~*tx(LUEH=HFQU8~Og;CYA^W#L}k4GKR!5bH#GBiVa*d0XY>M^K04)mf0 z<6!tM>Vm=!dE7K2R4ow&9FqRJ^&P`o+ zFIYa@2JMHFi)RPc;Sr3Awb%{Dx`h3al_J&=$za=&A+e5X!LV4_v}Ln@vgw!2_&(@gA#<%jvfqw*riFxKmkHv`%<%nP;*TTGaUB=~^^d3hc;b&Q0QHY=2KA3;`|;GzO#}6F z>6c6W+_ZTaWe0e3HPF^>tpEoPka`G*weL3yRX zSJS?l_SK_e6(xcABJ%KD#VQ&D`PZa@{A*}mL;f}WAb&CK#k3dGUfhNu5dVct1kjEM zCdFEtiUNeuji^}b=)ca3dN7}L#QD=v0`mFCK)&_Ft@oe;)L-8Z>TjTZ1MM4V-$49^ zArOC3CIV{2N;*nFzEj39C)TN%@S_=hATB^$ zfVe;t`Y|QeX~dltKs!doIz0{KKfNC0=RU$ZgMMd}fc$5SiB+160+6S4NUSmwte3Tb z?c8Hn8*9)H#+i7+NW-tEb7 zgTC84F)7v#)^`xIgYnc03dA})4Q%^T4w}UJGI_tuSR0B#?sKw1{JB0v#X66;^V%^d zR$~AxH;#(+m2?ErjVZCdO59hO`&WrOzd@{~RFLm$S*XW=SYOWoHNPGe>jK&@pl`D+ z);CNrrf>F&^(|s~CS-9BWVJA+7V5Q(i}meHkoVhN7{-iP7t;4a#(5!qE~NcJ@?J#U ziwe+)elWJyGOHu{tvm2HSoT06#BJ2V?oEfP6ol6syaJReQ)d)>-V{!?@cM7-%YgLG=xd929n_hH3mvik5+VJ0ArXI>*gfbp#ROpa!+gB z+=zDcVhH1y73-E1WFi+Os6jJ2(T@>Kigl|X4Ou8aDeBRRZVX@y(_#%K!A1^>QGrIZ zqZdOM$E;Ylr63czC_xRH(TRSHU{b8x1!>4a0ZKva?Tr}17>K(g1vZGgqXPA4MmxIE zk0B6$$0TOO8cISM8qflc>rf9OVEdhHzmx5EW}+S4=*JM|#Nso7byqq#Hg_?myBO15 zQA~mDe@F$}{@{TR_2@(|1~7tgv4-h)H+k;n{J5LAyV>?f`u&midy>KVa}RaznH6g! z2Mvf|6jNf|8^)wq_az}ytUr-|Gz0V>CD$nZ?kDg40fa#R`@1lV8L=KnM=mPR3Tizt zF4lvbrw@|n!2;0lLAE_e?gyh{jZtfi@s5>(`ePByiS>{h0d$M?a0=SRdW5(~yqFLx zN?X)MlUR?IU{tKf8bLjt=UI;riZxEX@lLUxpx+bpe=-NOJxTnNU6>Z@sZ1238U12S zc)@(0uE2~~&#>(o#`G+GpQXkmeJ9ENTn1V}j^`QY^VEF49jw1Vju-r(?FC|AAkUPE z8uWL)qhB+neNbBup(RII--j=%MY^>-637!&IsjO!nR;*b!A z#i5mgbv*~2;xKH~U_u;b33|j~rK3e04nYOz=Oo_QD~_aGu>O&DOpC)s9~bL;WP(0> z%!nhIw&VeEd^8)~;@Fcsd(yUNL>wQZ?PL5*DaMdE_TuMW{M_4*DRF$f0_05%gY{3) zf1gsY{K*k22cpH2wA`ZvT4pfH@wJiUxFHRvdh;bl7aS zsc+AS<3K;yejxo1q|brFm=eb#6Y0nXeRv+{SVY_+;uiISxJ47$7fREh8F>Z z(Sj~SFp4R0eAYxdvf)Dz4QN9T1`)-KI5Lxw0T28Lp$Q%6!!RZ=Cyql>;f5ChgwcX7 zL@t{s(Ik$=)LcyaVh{WXLA7_F55t(ioH&+{V+pZK$gv~x<{HwM-~bY0OLE7`5)PdJ}{Rfi9d2i97iQ1 z10MLnSdU_?M|FT$o>w@In!ubmvWd<1B7iVj(1i#_F(r=AnMg-AdlK z(Zn9zA&#Xj+_9(V0#X+IUL{5ryvtK;#fxCW#m4F`5se%Qq-dr z%-2I-4|$HI@3DOt#sp|PE*a!Kj-1ES=Xm-Y-;Du`VNx8q4Hy?ko*yAJfn0gy;@N^D zk6d}=TAm6wya*r+Vpq^_1^K)l_|T7OapY%%*nDcNB$np|j#czuMcXR+^W4C(iv9%x z`V`W)koLk^aqxV=aY7d&7{!!0PBf8@Y!G{55DjPp+kO6bLI2gMXhxqnic(MvY8R<> z#=3^(HJxCe6f>S;FX}NOjxR8#FR<+kY+LI=3kE^Ib&O|SDaOU&XW7p-KXL0bz!=xJ zp$ns!5C@;{9UG{{ae6iapvLLF7!$`C)Hs70XHeq|YMjx9VNj#gMggc% zN{v!#lv1NC6&_HdtQGyB#ztyvq{c>SY-~agsIf_q32JPj#wKcPqDC+s{4Do^`0@d9 zZ1#cW%~5e|q5c-uw{(l6!Xu7K@>G()vJW%jI5Pm|aVBFut5Y1I477`5D|xr7pL61< zB4;&os3vE1R2((L)P%(GMf!emLL9X$*G`M0t{y|;2)BWJ+lb#r-|ghuUV~wA>_`Ud zJKXTV2lDI)p#d%EKo24qMif(+6GweA(&2^&J_Ha#16t659z-yVD5fwcj!-!%EbK*EB8R>At10Mnip#d%EKo24q zMif)xIG5vj?w~l%<6JmzTpW#V5cd@?8pZKdj{o^7u#tsa6r&Uz|MQ7CzZIS61$moN zLEG1S;`lmwFQCRZL>%Ab{QOoHsM~@IGsSUHmpCpa*LVHmXiE{t_mahN34JbQOy3WS zKK|9$6fTjJ69a{u>HOkaokUzF>;Qv?IChK)FqCG zOU3aBb))U#c#OJ_6Fcq|#}gusC-D^dCi=zkOjsO~72@DCjpKP+952vkYD^q2l5@IM z950jil>u?g%!%W*264>hh~tfHam>|-1-6|N2bJ?+$qjI z+4iwfaqcxJ&QuZSJ`LjBH%FZ5ZgGBkTAT;WigQt}I5XJ(*=BJbS})GSyT!TK#DF-L zbci#nU7Sahi1SEt9~BU1c9J+h=Mm@8#o}B_-=#C+%o!Hv=X=DttU{c}*dVWm{KwLE zT$?y~-*x5^pVuhP<*nje!8p8(Azu&`=SpH$Wq`33bcwSt8#CfOfo&%S#OVu)bG1*L zyni{17|$BUvW6PPP2&6lIe33^t{o94&zzn90dcM$66XfCpTzRX^f@J0oTt)1kS@;C zSU)`(x#Hfw6|u#JP>OZFAz>&iW3IIk!7_0+oF5BlD~ z`VI8G!3OmsA83J>@m0Y)` zBL~dqR`T7-oNlGwt%Hby{Dax>f%d@xjA2@wwDS%ONj*@4TxKZkjlK1{>G$Vo;aXydQChpJK@FR>i z^k5KCalV*^DRI6eqKTws8%1)M)C<39A}Nw9Ny6hk{Xl-2BC?-$oQjJ5U%PhX{IVu{ zXiv>A>tbrJ&o3L2qTBP!Cd=#Qmn})w&z)c9UmMY{nqN+mz4*18c>X=))BO5DeEFk$ z|1k4{`Q<$&`Hpn(IY@&ZzESnme&9a)2&A6-hvxbJ6xYQjSVwcb^SZJsR+clF5L1%n)gk_T=Pqgw&xh^Q+5W&?HpGs89eYq6 zL3Lg&=B!#OvZ1`TuCltyK63Fp*Yr>D&c8b3V~bKhKD z#eoQOcqDd;hdIQ{_@@S!uqWcD#dZ$)V)|C|vzEhNE-GIwr&~GgRs0#IYdBo9Y{`-! zJ9PWD#dX!&YB!Z{uCCouzPPHK%`0~rLE?l;yp(o->8O{PdReH`ZX| z-V-1EWL23~k@sw7TM^qYm7K^mv3aRI6lD8m=BQ3@_2N}8f$gz2b(rFN^6m3jcrk7x zX5q#7ZnJUmVt=Q($4`kes_nejcE1?8o4Qyk>MT&R+Qb(1 zR^sBPnn5@=3RP?8^J!BoPMwGG?1>C2IzIOJg}0o{>h+G+zh%Uz zac!b++5G%mY*8)SIImR}HP$fO+#z8_p~&0+TnD!bYbn;6+P@+S7l4wh7JbyZSt z%xcf5>uP*<$Pyx+Y- z{FSE8Ky_7DXRDfF{K^-vsLm8Mlj_*K>tcK2Od>YL_IErcas1SItmdn((}^RbX0Fae zbxh)CSRL;y>ecCwRZ{zGBQfgMXWD{ll~zt;B0(VUMZT zLE;?Wxu2Syy4g`9cQF<guR&LF40B)zv;%ujRxQO^sc>-qh@2Cy4_Q+^Z0(=Mi#Z^VqKjn>b0Quy}CJ8*Q3PQy@j}i_tki%#5GjSE7FlE$=<2#L-so6KVzvXPBC)&3NAL2zIUW_WiN@>!>cakJRy271RuNKEmo%5WhQ6 zBU5|Zj{RB1n!2te_One?yhY75en!S$0r4xc+AoTF_b89eF8-diFrFQ;b1WF!>xRvnkzOw84Z@kYY?v2VgTU7Pb6Fy6;G2 z{C8Zb-hEc_52@aA3B~Il&nOK!u-NhHh)=nh8h+OJwmoFu; z8u?^f$7^8?^;GWFwEFm|YN|NZV+AeiSy#)eXj?vCuZUi14k~^%{PQFA)4ou3*HNj= zY8LU4t!8a4`3vU9oJa1$SUxp=H{)6v%UcxdrTVEor$(BGV*Xr9)j~3?r(^BM~3b3Zjasts+)2E`Mwn9rxq0X2Ug|5N)`?ZhH%Q!`QHR(nSsdv#3J_zGE56_&FtepJ-{^u^W|_FMd1P{%Zn9;;&`SN+vY)E6Wi`paVyi#ZW3TCiy#>LNj zwZ9Xw@x7pqPf_g1eu0_Ck4QY9`h>jmEYxv2DRv|ljz|0ms1d63LRC!cvxTFtYN|0O z#-q+=b(STL!@^!suRnE;sZp!5K&`0?>NTRyF?E#Gw#4gG)llb7{2H)6);Ez=_1ks- z+C-|?Q6etU@4c=a@qLu2z3UNFXRF$m@e#(aBx*mz^TyAm_$%S<*QEGWKA-nB^$uAx z|Grj7-}s$w;&Wg8eSYEICjQ>D^L?k<8;SRso$mzVpAJ^>ZWMpV-8pWdHU4QS{+_k) z=}pBZ-jjF#e5}sV_@hV_w{X|HaQ6|vdyIc3QtwFd@vA!`b$=ee2UPcZ@w*cBKCM2> z#%EC*yX%jCB29c+i9b705$atjG21%EsNVb4DB`se_bCgx;`fy*E?!OT;rM7&miXR$ z_xD&=Y%D4=@ySqqB2{<)wdC0mTMoxYRmFN4qlm|o|krpQS2edsy91E@nh(W@@DI&t>t-YF+Jt&9QCjo;5K_wI3JG zK6P)sEY>%1AF5`k?v>OXdiIla_L8v45VLlI1b$5Rr6h9mObI*g+DB@42-sxU^ z;X1MNo&2WQIh=TcpkmZ>iNqe;{k699)5OHNy!*YldS6tpssF}vrJesXO8mK!dM>A~ zY`Z=mTeznG|MgsH;R%C!J^a7-T*PgK1+H)oK{Brl_N(-;)|IBkG z*LyrK_|H67ir>k_ulMS;uCD#>{ai`CD}4CRl@?xaiKj&By?+t+#P9r{mlwsxs_se> zSK&mz_~-NZoy7mz(b~8?+Nkw#P68?y-%0aQ@D5AyXsR^Vh{drKV@=pzN+`) zx8KeD=btjE_wxVMr%WzBaqj$-Y2mZ(fAT4lEB379y`D0uSB84(^6!7jq@J^>CvxxS zDUP%gDZuZ{Kj@0W%ok#EVJp14K>?rYc|J~nFc7NiN`0t(n z%o86~C-Fo={de9E>xqy0^rOC&^ueC^sHZyW>i@4k@p18dCGm})ciWR6))SiWZg*C> zTy+xPJaNUI%BZ!)A}eEG&{E%PQ(vlk>&tX@W?gx?y|Fx0z2lI@_WSr2++urG=VP%h2U2F0b8MSr_{bU1gnJ zQC?fl7Yeu3mQ^uzH*;t2(T(p7@+CF59j>;^s?N4+_|_d?x~tw8=6i#c?1D0T6JKg{ z5gD#1Pwb~no2s|g5Uv8k6=dhThUHat9HB+AU9#v9k_GLuy1MF3m1Wd(1*RSgQ6e9c*^g=54iA zm30-Id~^&}+jZ4$yKdXYGs`!HRg0S6=IRjVw3^VS>Z)L++F^CeTrNN9$~IPSFOSV2 z{w>qk0Ny$Ys;a{r2EGEShNX^5Y+&&-AimA6t0)VFTpP>h_Zq|CyP`DhG|%cP&Wl=m zYc(&pcbc{xKD(xTa~Xve#|O3R9JiL8&5M%m!OG2*>O?CGg*o+DAZb}J7@K))AIH9? zT2{-Lw}r}TU21m)%j+t)RK<4pmiTLxPU;LT+e8vxxm9oN)jIoamDIFd6o~DxvXK3b z3FiAG#<7r%;Z=pswkvl!&0XqpP+MMAwl#jV)Iy!jj#S4b@$x9=oGY)5<=IhP8?3Vz zy>*FLq-LyUr8c-0sh91d*e>J9_~u_P8_RhmsjS;L2I{zNuda-p8meD;eVA8_T~<@W z%d2c-h||A%{*psxwcA~Z*9~>b!gfVj9s9n#>aD#WOG&wfvpZ;Ss|wB!cwwln*x>Bg z4BzXh*73z)Ue$IDhfSRvWj04{3+d|SU%zbGbXM6GuFJd*tEye<#ijz^|4EfNtg%vD zu=wtDd1$j5R6)MIa!rxnUbkkY|D?RN`F7ztyLj!I4Tau(ue~U59qWtS_DO~Qf;H>? zHW6#{iu@XhmI;kK(HV-C{$N#U0jVw0( zBBrbI_}8puhs+P@pg^cJju=YchTj;EY~X z#S1sy7F**d`JaqPAVr$iVnHn!w zWxnXXb$;rxYvZQyvc#=I*xsV{6z_Fm7hi{8Y`a{sJ1#ZaI(tRp7bgDsTc`K?`w<_` zeGqqBiEEkKVVh&4FMEIYL9T`SAa=tCx({-x_lAY5cUB$+c+b;l@5UF8YvfnOs%XZ(U|S@GX<;L%n5k&EGP`-gQ6NEtBi*w@mg2 zxn**_<1Lf@&)hP({COKzpRh*V>E#uCpt~d2!p-8pa(CpKzX9WR^U0x_}-T0`_o$q|(6ThW-e>Xm^_rCFY>nXr{-1xX+ z4}NwYd&%DNaY>a=$UgE({?3wp zWk30pq|2vee>s4MeFyTN01uK3Iaod;pXJxB4v|CoJ#P2^;p(jerKtY@|DEoxD@dpa zA_DjB&ddcB5ZI+lLRz?VH;8nHotS_E(jXwxNO!A*Qc9<-pww@;^L&5w`}+gVzUJQD z=Q(p`UXSxUuid@TNBYV{gU?RnM4tssCHzE?2&2z~mP?e6-rDt4;^{<%M8!m<=yTrp z-zHf#+OW?=+s^mjqFXa6W7LjLTHR<1`u>}DpN+Q9@4tbzNmSx!8Wo_LM`LN3Xq9N4 zcs|i4(Kb303llRF;}YW&>l0HFml6{auO(hiOij#7%p%CdONs9jV-s&DeoOqGcs21} zVp3vD;#A_-#I(fx#Gi>j5`QITBo-xhC3YkhM{hZApLiqM!rc>X;_giBP8>+=P3%kT zPh5^RG`~q4OdLvl9=*}*m&BWiBZ+SlhokAenz){r9DU}vYxKtTp3$~%uf!+O)^guy z+V6j;>Hb^t21OUgmFTUOL!vh@3{4DA3`?v^e3}@U7?Bv27@fG5_$jf5pa_~^2$tXo zK5-{;mkpTtq(38FMnhA2y96FEeZND)2}5FwFElq1R$ zPbSVJ&Js@%PZJf0ibN&i8KN>#g{VrTi40MVs7}-%Y9^K>mJ+py+C&|qE>VxDPc$H& zB^nZq61Nh!6Xz1=iN-_|;yI!z(Tr$Lv>;j%t%%md^F$k>Es;mGBia)kh>k=jqBGHj z=$cqdbR)VGJ&2x(3yF(FFQPZmhv-Z6Bl;5qh=If);ss(b@ggyV7)lHyh7%)*k;JIP zY+^Jqh8RnXBgPXGh>64`Vlwd(@iOrW@hb5e@jCGa@h0&W@iy@e@h&lic#n9W_<;D3 z_=xzJm`Y3|rW2nKpAs{OnZzvOGh#L|hnP#uBjyteh=s%=VlnYKv4mJkEF-=kmJ?qR zD~OfEDq=OUhFD9iBi0jN5gUko`hv4z-5Y$LW4JBXdcE@C&ahuBN(BlZ&qh=ar- z;%nj?;#=Y{afCQZ93#FXz9)_oCy0~8DdIHo1MwqqhB!-{BhC{Sh>OG};xciCxJq0j zt`k2IKNG(YzY@O@zY~8De-eKYH;9|W-^4$}E#fwDhqz1JBNHS+k|agaBtxXkMiex478L~22g{(@Z z$qZSItWMS-Ym&9d+GHKFE?JMPPc|T*B^#2B$i`$7@;S08*^F#Xwjf)Qt;p8o^JE*c zEtyBQBioZ5$c|(uvNPF*>`HbcyOTZ0o@6hwH`#~mOZFrClLN?sw>TD{=$5k=#UXCbuMxCr%_zCVohKmpDys zCAX2=$sOcQau>Oq+(Ygq_mTU_1LQ&S5cxIv4f!p3m^?xrC6AHck>8WY$rI#B@)UWR z{DJ(DJVTx(&ynZJ3*<%e5_y@tLS7}Wk=Mze$e+ny$Y06d$lu97$Un)y$Q$HM@^A7V z@)miUyhGk4?@NV2dDy6 zLFz%O5LK8eLKUSRq8_Fmp^8zDQpKqf)MHdh>T#+R^#oO#Dnpf}vZ)*@Nu?;C3aF6E zrOHv|sVAwYsHdq4R7I*1^$b;+szOzz(o}}3MpdV3P&KJqRBfsbRhOzq)u$Rz&r%Jk zMpR>}3H2P+lxjvbr&>@gsa8~L>UpXS)t1UjOsCpW?Wqn_N2(Lmnd(AyrMgkwsUB2M zsu$Ip>O=LV`ceI<0n|Wh5cNXhBWf`9A~l2>N)4liQzNL6)F^5+HHI2Xjibg>6R3&Q zBx*AC67@3m3iT@W8udE$2K6TO7WFpu4)rcIg?f*ApZb9Mkot)Fn3_sWqoz}zP@hsW zsF~C(>N9FKHHVr@&7zqpnjwQ9o0^P`^^YQNL4v zP=8W?Q8%cY)Zf%U)Gg{Zb%(l3-J=sUL6bB^(=N4KNf(;euJbSJtq z-G%N-ccZ)0J?NfvFS<9~hwe-Fqx;hX=z;Vg`UQG0{USYt9!d|RhtnhIk@P5fG(CnM zOOK<+(-Y{4^dx#R{Sy5${R;gm{aW;Alir};q~D_7rr)98rKiyE(eKkA&>zwtMSl!w zDm{&!PJcpwO3$EY(zEE#=-KofdM-VWo=-2J7t)L9#q{U&5_&1UjQ)aNPJc%)`thOflwBrZ`iAd5kH^ zJkFG2o?uEdWtg%|Hj~37nH1wQ0TVL0OgW}J^Ca^W^E6X|smN4fo?$98RhX(wn#nNL znCeUorY2L1sm;`3>N541`b-1nS*9V=h-u6;VV+}}GR>IgObezZ(~4=$JkPXY+A?`e zJElF;f$7L}VmdQjn66AWraRMv>B;nBdNX~PzDz%+KQn+C$P8j$U$F)uT(Ft0MNF|RXkFmEz%F>f>PFz+%`nD?0X znGcu`nU9!{nW@Y)W;*i;^C>ffnaRvzK4WGxbC|izJZ3(#fLX{aViq%>GfSAI%rfQ+ zW;ydEvw~U4tYTI(YnZjnI%Yld6|;fa$ZTRZGh3Lg%r<5_vxC{m>|%B^dzihkg^C$BcbA!3b{LTEs++uDscbL1(JvPA-EXh(V%`z;@ zaxBjZtjJ2N%qpzPYOKy0tjSue%{r{hdTbW^09$}9$UevxVhgiH*rM!1?8EFMY%%sx zwm4gYeT*&1KF*e6pI}R~W!SQ8Hk-pH*%a%u0UNTpY&o_(`y~4m`!rjDt;kklpJ6Mr zRoJR*n$57)*y?NzwkBJPt$3IO`fLOCS+*hDh;7U^VV`50vd!4$Yzwv}+lp9VJGMRBf$hk4Vmq^4*sg3hwmaK{?aB6Hd$WDmzHC3XKRbXO$PQv(U@apXJAxg_j$%i%W7x6mICeZcft|=sVkfgNu`jc)u&=VOv9Ggluy3+&v2U~Q zuzc*^k(d*{SR_b~^hB`zbqvoypE(KVxUJbJ)4;Ja#_2fL+KgVi&WY zvrE{e>@xNXb~*bcyMkTGu3}fSYuL5yI(9w#6}y4m$Zldcvs>7$>^62gyMx`y?qYYd zd)U3~K6XEQfIY|_V!vj;VZUV$vq#vY>@oH`_Ivg?dxAa5o?=h4Kd?WtXV|msIrcnz zfxXCHVlT5-*sJU{_B#6$`!o9s`z!k!`#bvw`zQMsdxO2n{>}cw-ePaFci6k^Jubl! z9LZ4}%`qIyaU9PHoXAO>%qg78X`Id(oXJ_7%{iRQd0ZCv09Sx3$UVpv;tF#`xT4%c z+{4@>TruuZt~ghMdyFf|JT>nC`dkC;hy7~a?QBr zTnnxx*NSV+J&f-vdUJiazFa@9KR19I z$PMCN;0ALqaznVG+%Rr9H-a0 zfLq8d;udqCb4$3T+%oP9ZaMcQw}M;At>RX5Yq+)CI&MAp6}N%g$Zg^_b6dEr+%|4I zw}acs?c#QGd$_&aK5jpEfIG+?;=bm-;lAY#b4R$N+%fJu?tAVycY-^~o#IY&KX5;C zXSlQ6Iqp1nfxF0E;x2PnxU1YX?mG7q_cQkk_bc}s_dE9o_b2xkcZ0jh{muQu-QsR@ zceuOUJwEzUF`ncpp5_^zKFw$NYJ7FR249n}#nl`8E7nejUG_|BBzhZ{#=e zoB1vLR(>15o!`Olm=+5uupys8C!eAv`9O6do5!2~P;6g)%}}AzR21l0r)G zg+K^}T%nv$UU*V?N_bkRAXF483C{?Xg(^Z-AuVKtYC?6PhEP+eCDaz`2z7;eLVclu z@T|~KXe2Zinh4JcO@(GcbD@RMQfMW#7M>T{2yKNtp`FlP=pb|yItiVHE<#tKo6ue8 zA@me_3B83rLSLbu&|erJ3={?lF9?H$7lk3hP+^!bTo@sY6h;Z7g)zcdVVp2tm>^6P zCJB>;mxPyvSADv8mWhY%aDCTZ*m3*5dPG8?mjJC$?U>>dx$;7USe;tkJwl2C-xTyhy%qz;tS$n@kMcnI8+=a4i`s=BgIkTXmN}< zRvage7bl1l#Yy61@g?zP@fGn^@ip;v@eT1!@h$Of@g4D9afk8nY;le_SDYu#7Z->N#YN&`@pEyBxKvywejzRwzZ6%9E5%jf zYH^LYR$M2p7rzoWh#SRC;%0G+xK-RHZWnimJH=h%ZgG#eSKKG=7Y~RB#Y5uP;y2>A z;$iWKcvL(lekXn}9v4rDC&g3ZY4Hc~NAZk!Ry-%37cYnx#Y^I4@rrm=ye3{3e-eKd ze-VEbe-nQf{}BHa{}OMAH^sljf5cnjZSjtHSG*@BBtjx3N}?r3VkJ)EB|#D;Ns=W+ zQYB5&B||bLOR^vNrj~% zi3L(o=^^Q1=@F@z^r%!^DiQrXnC((Y>2ax)^n_GeDkGJZvJ+n=Hb^;AQc6j_6iA_z zE0vSVC)P<%N>52oOBJMwQYGmbsj^f>sw$5+Djdzj#4M7v(!cEDs_{(OFg8X zQZK2u)JN(o^^^Kb1Ehh{An65Zu=JudL>ej$lZHzpq><7nX|yy(8Y_*H#!C~ViP9u# zvhU-#NH?XwrGKPb(rxLEbXU43CuBkl%JBHmMh2=hXP5CYPZTTJfU3rT9p8UT2f&8KTk^FJu zeR--pO`e{ZD}N$?D$kH-%CqFpSw@BV zD9$r^ZIwKwozh!rN>`Pl(&_4ly{XW%6rQD$_L7a%16q_%2Z{VGF|yZ`Ba&q%v5G6pDDAI zIm%pRo-$uqpe$4tDT|fQl_knjWtsAYvRwI6S)r^{Rw=8MHOg9Low8o}O4*=nR5mG_ zl`YCvWt*~H*`e%Ib}74+J<48XpR!*$pd3^VDPJq!DBmiFl_Sbg<(TrF^1X6gIiZ|X zPAR9AACw=JGs;=zoN`{dpj=cgDVLQi%2nl>a$WgJ`C0iz`BnK%`Ca)#`BV8zxuM)t z{#O1`ZYj5wJIY<x zKrNsaR3B6esfE=dYEkte^MgwVYaBeNuf&eOj%cR#Ypg�BvDr!|Vt!C6}YIU`ST2rm1)>iANb=7)meYJu5 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 literal 0 HcmV?d00001 diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ufm b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ufm new file mode 100644 index 0000000..e927992 --- /dev/null +++ b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-Bold.ufm @@ -0,0 +1,6067 @@ +StartFontMetrics 4.1 +Notice Converted by PHP-font-lib +Comment https://github.com/PhenX/php-font-lib +EncodingScheme FontSpecific +FontName DejaVu Sans +FontSubfamily Bold +UniqueID DejaVu Sans Bold +FullName DejaVu Sans Bold +Version Version 2.37 +PostScriptName DejaVuSans-Bold +Manufacturer DejaVu fonts team +FontVendorURL http://dejavu.sourceforge.net +LicenseURL http://dejavu.sourceforge.net/wiki/index.php/License +PreferredFamily DejaVu Sans +PreferredSubfamily Bold +Weight Bold +ItalicAngle 0 +IsFixedPitch false +UnderlineThickness 44 +UnderlinePosition -63 +FontHeightOffset 0 +Ascender 928 +Descender -236 +FontBBox -1069 -415 1975 1174 +StartCharMetrics 6196 +U 32 ; WX 348 ; N space ; G 3 +U 33 ; WX 456 ; N exclam ; G 4 +U 34 ; WX 521 ; N quotedbl ; G 5 +U 35 ; WX 838 ; N numbersign ; G 6 +U 36 ; WX 696 ; N dollar ; G 7 +U 37 ; WX 1002 ; N percent ; G 8 +U 38 ; WX 872 ; N ampersand ; G 9 +U 39 ; WX 306 ; N quotesingle ; G 10 +U 40 ; WX 457 ; N parenleft ; G 11 +U 41 ; WX 457 ; N parenright ; G 12 +U 42 ; WX 523 ; N asterisk ; G 13 +U 43 ; WX 838 ; N plus ; G 14 +U 44 ; WX 380 ; N comma ; G 15 +U 45 ; WX 415 ; N hyphen ; G 16 +U 46 ; WX 380 ; N period ; G 17 +U 47 ; WX 365 ; N slash ; G 18 +U 48 ; WX 696 ; N zero ; G 19 +U 49 ; WX 696 ; N one ; G 20 +U 50 ; WX 696 ; N two ; G 21 +U 51 ; WX 696 ; N three ; G 22 +U 52 ; WX 696 ; N four ; G 23 +U 53 ; WX 696 ; N five ; G 24 +U 54 ; WX 696 ; N six ; G 25 +U 55 ; WX 696 ; N seven ; G 26 +U 56 ; WX 696 ; N eight ; G 27 +U 57 ; WX 696 ; N nine ; G 28 +U 58 ; WX 400 ; N colon ; G 29 +U 59 ; WX 400 ; N semicolon ; G 30 +U 60 ; WX 838 ; N less ; G 31 +U 61 ; WX 838 ; N equal ; G 32 +U 62 ; WX 838 ; N greater ; G 33 +U 63 ; WX 580 ; N question ; G 34 +U 64 ; WX 1000 ; N at ; G 35 +U 65 ; WX 774 ; N A ; G 36 +U 66 ; WX 762 ; N B ; G 37 +U 67 ; WX 734 ; N C ; G 38 +U 68 ; WX 830 ; N D ; G 39 +U 69 ; WX 683 ; N E ; G 40 +U 70 ; WX 683 ; N F ; G 41 +U 71 ; WX 821 ; N G ; G 42 +U 72 ; WX 837 ; N H ; G 43 +U 73 ; WX 372 ; N I ; G 44 +U 74 ; WX 372 ; N J ; G 45 +U 75 ; WX 775 ; N K ; G 46 +U 76 ; WX 637 ; N L ; G 47 +U 77 ; WX 995 ; N M ; G 48 +U 78 ; WX 837 ; N N ; G 49 +U 79 ; WX 850 ; N O ; G 50 +U 80 ; WX 733 ; N P ; G 51 +U 81 ; WX 850 ; N Q ; G 52 +U 82 ; WX 770 ; N R ; G 53 +U 83 ; WX 720 ; N S ; G 54 +U 84 ; WX 682 ; N T ; G 55 +U 85 ; WX 812 ; N U ; G 56 +U 86 ; WX 774 ; N V ; G 57 +U 87 ; WX 1103 ; N W ; G 58 +U 88 ; WX 771 ; N X ; G 59 +U 89 ; WX 724 ; N Y ; G 60 +U 90 ; WX 725 ; N Z ; G 61 +U 91 ; WX 457 ; N bracketleft ; G 62 +U 92 ; WX 365 ; N backslash ; G 63 +U 93 ; WX 457 ; N bracketright ; G 64 +U 94 ; WX 838 ; N asciicircum ; G 65 +U 95 ; WX 500 ; N underscore ; G 66 +U 96 ; WX 500 ; N grave ; G 67 +U 97 ; WX 675 ; N a ; G 68 +U 98 ; WX 716 ; N b ; G 69 +U 99 ; WX 593 ; N c ; G 70 +U 100 ; WX 716 ; N d ; G 71 +U 101 ; WX 678 ; N e ; G 72 +U 102 ; WX 435 ; N f ; G 73 +U 103 ; WX 716 ; N g ; G 74 +U 104 ; WX 712 ; N h ; G 75 +U 105 ; WX 343 ; N i ; G 76 +U 106 ; WX 343 ; N j ; G 77 +U 107 ; WX 665 ; N k ; G 78 +U 108 ; WX 343 ; N l ; G 79 +U 109 ; WX 1042 ; N m ; G 80 +U 110 ; WX 712 ; N n ; G 81 +U 111 ; WX 687 ; N o ; G 82 +U 112 ; WX 716 ; N p ; G 83 +U 113 ; WX 716 ; N q ; G 84 +U 114 ; WX 493 ; N r ; G 85 +U 115 ; WX 595 ; N s ; G 86 +U 116 ; WX 478 ; N t ; G 87 +U 117 ; WX 712 ; N u ; G 88 +U 118 ; WX 652 ; N v ; G 89 +U 119 ; WX 924 ; N w ; G 90 +U 120 ; WX 645 ; N x ; G 91 +U 121 ; WX 652 ; N y ; G 92 +U 122 ; WX 582 ; N z ; G 93 +U 123 ; WX 712 ; N braceleft ; G 94 +U 124 ; WX 365 ; N bar ; G 95 +U 125 ; WX 712 ; N braceright ; G 96 +U 126 ; WX 838 ; N asciitilde ; G 97 +U 160 ; WX 348 ; N nbspace ; G 98 +U 161 ; WX 456 ; N exclamdown ; G 99 +U 162 ; WX 696 ; N cent ; G 100 +U 163 ; WX 696 ; N sterling ; G 101 +U 164 ; WX 636 ; N currency ; G 102 +U 165 ; WX 696 ; N yen ; G 103 +U 166 ; WX 365 ; N brokenbar ; G 104 +U 167 ; WX 500 ; N section ; G 105 +U 168 ; WX 500 ; N dieresis ; G 106 +U 169 ; WX 1000 ; N copyright ; G 107 +U 170 ; WX 564 ; N ordfeminine ; G 108 +U 171 ; WX 646 ; N guillemotleft ; G 109 +U 172 ; WX 838 ; N logicalnot ; G 110 +U 173 ; WX 415 ; N sfthyphen ; G 111 +U 174 ; WX 1000 ; N registered ; G 112 +U 175 ; WX 500 ; N macron ; G 113 +U 176 ; WX 500 ; N degree ; G 114 +U 177 ; WX 838 ; N plusminus ; G 115 +U 178 ; WX 438 ; N twosuperior ; G 116 +U 179 ; WX 438 ; N threesuperior ; G 117 +U 180 ; WX 500 ; N acute ; G 118 +U 181 ; WX 736 ; N mu ; G 119 +U 182 ; WX 636 ; N paragraph ; G 120 +U 183 ; WX 380 ; N periodcentered ; G 121 +U 184 ; WX 500 ; N cedilla ; G 122 +U 185 ; WX 438 ; N onesuperior ; G 123 +U 186 ; WX 564 ; N ordmasculine ; G 124 +U 187 ; WX 646 ; N guillemotright ; G 125 +U 188 ; WX 1035 ; N onequarter ; G 126 +U 189 ; WX 1035 ; N onehalf ; G 127 +U 190 ; WX 1035 ; N threequarters ; G 128 +U 191 ; WX 580 ; N questiondown ; G 129 +U 192 ; WX 774 ; N Agrave ; G 130 +U 193 ; WX 774 ; N Aacute ; G 131 +U 194 ; WX 774 ; N Acircumflex ; G 132 +U 195 ; WX 774 ; N Atilde ; G 133 +U 196 ; WX 774 ; N Adieresis ; G 134 +U 197 ; WX 774 ; N Aring ; G 135 +U 198 ; WX 1085 ; N AE ; G 136 +U 199 ; WX 734 ; N Ccedilla ; G 137 +U 200 ; WX 683 ; N Egrave ; G 138 +U 201 ; WX 683 ; N Eacute ; G 139 +U 202 ; WX 683 ; N Ecircumflex ; G 140 +U 203 ; WX 683 ; N Edieresis ; G 141 +U 204 ; WX 372 ; N Igrave ; G 142 +U 205 ; WX 372 ; N Iacute ; G 143 +U 206 ; WX 372 ; N Icircumflex ; G 144 +U 207 ; WX 372 ; N Idieresis ; G 145 +U 208 ; WX 838 ; N Eth ; G 146 +U 209 ; WX 837 ; N Ntilde ; G 147 +U 210 ; WX 850 ; N Ograve ; G 148 +U 211 ; WX 850 ; N Oacute ; G 149 +U 212 ; WX 850 ; N Ocircumflex ; G 150 +U 213 ; WX 850 ; N Otilde ; G 151 +U 214 ; WX 850 ; N Odieresis ; G 152 +U 215 ; WX 838 ; N multiply ; G 153 +U 216 ; WX 850 ; N Oslash ; G 154 +U 217 ; WX 812 ; N Ugrave ; G 155 +U 218 ; WX 812 ; N Uacute ; G 156 +U 219 ; WX 812 ; N Ucircumflex ; G 157 +U 220 ; WX 812 ; N Udieresis ; G 158 +U 221 ; WX 724 ; N Yacute ; G 159 +U 222 ; WX 738 ; N Thorn ; G 160 +U 223 ; WX 719 ; N germandbls ; G 161 +U 224 ; WX 675 ; N agrave ; G 162 +U 225 ; WX 675 ; N aacute ; G 163 +U 226 ; WX 675 ; N acircumflex ; G 164 +U 227 ; WX 675 ; N atilde ; G 165 +U 228 ; WX 675 ; N adieresis ; G 166 +U 229 ; WX 675 ; N aring ; G 167 +U 230 ; WX 1048 ; N ae ; G 168 +U 231 ; WX 593 ; N ccedilla ; G 169 +U 232 ; WX 678 ; N egrave ; G 170 +U 233 ; WX 678 ; N eacute ; G 171 +U 234 ; WX 678 ; N ecircumflex ; G 172 +U 235 ; WX 678 ; N edieresis ; G 173 +U 236 ; WX 343 ; N igrave ; G 174 +U 237 ; WX 343 ; N iacute ; G 175 +U 238 ; WX 343 ; N icircumflex ; G 176 +U 239 ; WX 343 ; N idieresis ; G 177 +U 240 ; WX 687 ; N eth ; G 178 +U 241 ; WX 712 ; N ntilde ; G 179 +U 242 ; WX 687 ; N ograve ; G 180 +U 243 ; WX 687 ; N oacute ; G 181 +U 244 ; WX 687 ; N ocircumflex ; G 182 +U 245 ; WX 687 ; N otilde ; G 183 +U 246 ; WX 687 ; N odieresis ; G 184 +U 247 ; WX 838 ; N divide ; G 185 +U 248 ; WX 687 ; N oslash ; G 186 +U 249 ; WX 712 ; N ugrave ; G 187 +U 250 ; WX 712 ; N uacute ; G 188 +U 251 ; WX 712 ; N ucircumflex ; G 189 +U 252 ; WX 712 ; N udieresis ; G 190 +U 253 ; WX 652 ; N yacute ; G 191 +U 254 ; WX 716 ; N thorn ; G 192 +U 255 ; WX 652 ; N ydieresis ; G 193 +U 256 ; WX 774 ; N Amacron ; G 194 +U 257 ; WX 675 ; N amacron ; G 195 +U 258 ; WX 774 ; N Abreve ; G 196 +U 259 ; WX 675 ; N abreve ; G 197 +U 260 ; WX 774 ; N Aogonek ; G 198 +U 261 ; WX 675 ; N aogonek ; G 199 +U 262 ; WX 734 ; N Cacute ; G 200 +U 263 ; WX 593 ; N cacute ; G 201 +U 264 ; WX 734 ; N Ccircumflex ; G 202 +U 265 ; WX 593 ; N ccircumflex ; G 203 +U 266 ; WX 734 ; N Cdotaccent ; G 204 +U 267 ; WX 593 ; N cdotaccent ; G 205 +U 268 ; WX 734 ; N Ccaron ; G 206 +U 269 ; WX 593 ; N ccaron ; G 207 +U 270 ; WX 830 ; N Dcaron ; G 208 +U 271 ; WX 716 ; N dcaron ; G 209 +U 272 ; WX 838 ; N Dcroat ; G 210 +U 273 ; WX 716 ; N dmacron ; G 211 +U 274 ; WX 683 ; N Emacron ; G 212 +U 275 ; WX 678 ; N emacron ; G 213 +U 276 ; WX 683 ; N Ebreve ; G 214 +U 277 ; WX 678 ; N ebreve ; G 215 +U 278 ; WX 683 ; N Edotaccent ; G 216 +U 279 ; WX 678 ; N edotaccent ; G 217 +U 280 ; WX 683 ; N Eogonek ; G 218 +U 281 ; WX 678 ; N eogonek ; G 219 +U 282 ; WX 683 ; N Ecaron ; G 220 +U 283 ; WX 678 ; N ecaron ; G 221 +U 284 ; WX 821 ; N Gcircumflex ; G 222 +U 285 ; WX 716 ; N gcircumflex ; G 223 +U 286 ; WX 821 ; N Gbreve ; G 224 +U 287 ; WX 716 ; N gbreve ; G 225 +U 288 ; WX 821 ; N Gdotaccent ; G 226 +U 289 ; WX 716 ; N gdotaccent ; G 227 +U 290 ; WX 821 ; N Gcommaaccent ; G 228 +U 291 ; WX 716 ; N gcommaaccent ; G 229 +U 292 ; WX 837 ; N Hcircumflex ; G 230 +U 293 ; WX 712 ; N hcircumflex ; G 231 +U 294 ; WX 974 ; N Hbar ; G 232 +U 295 ; WX 790 ; N hbar ; G 233 +U 296 ; WX 372 ; N Itilde ; G 234 +U 297 ; WX 343 ; N itilde ; G 235 +U 298 ; WX 372 ; N Imacron ; G 236 +U 299 ; WX 343 ; N imacron ; G 237 +U 300 ; WX 372 ; N Ibreve ; G 238 +U 301 ; WX 343 ; N ibreve ; G 239 +U 302 ; WX 372 ; N Iogonek ; G 240 +U 303 ; WX 343 ; N iogonek ; G 241 +U 304 ; WX 372 ; N Idot ; G 242 +U 305 ; WX 343 ; N dotlessi ; G 243 +U 306 ; WX 744 ; N IJ ; G 244 +U 307 ; WX 686 ; N ij ; G 245 +U 308 ; WX 372 ; N Jcircumflex ; G 246 +U 309 ; WX 343 ; N jcircumflex ; G 247 +U 310 ; WX 775 ; N Kcommaaccent ; G 248 +U 311 ; WX 665 ; N kcommaaccent ; G 249 +U 312 ; WX 665 ; N kgreenlandic ; G 250 +U 313 ; WX 637 ; N Lacute ; G 251 +U 314 ; WX 343 ; N lacute ; G 252 +U 315 ; WX 637 ; N Lcommaaccent ; G 253 +U 316 ; WX 343 ; N lcommaaccent ; G 254 +U 317 ; WX 637 ; N Lcaron ; G 255 +U 318 ; WX 479 ; N lcaron ; G 256 +U 319 ; WX 637 ; N Ldot ; G 257 +U 320 ; WX 557 ; N ldot ; G 258 +U 321 ; WX 642 ; N Lslash ; G 259 +U 322 ; WX 371 ; N lslash ; G 260 +U 323 ; WX 837 ; N Nacute ; G 261 +U 324 ; WX 712 ; N nacute ; G 262 +U 325 ; WX 837 ; N Ncommaaccent ; G 263 +U 326 ; WX 712 ; N ncommaaccent ; G 264 +U 327 ; WX 837 ; N Ncaron ; G 265 +U 328 ; WX 712 ; N ncaron ; G 266 +U 329 ; WX 983 ; N napostrophe ; G 267 +U 330 ; WX 837 ; N Eng ; G 268 +U 331 ; WX 712 ; N eng ; G 269 +U 332 ; WX 850 ; N Omacron ; G 270 +U 333 ; WX 687 ; N omacron ; G 271 +U 334 ; WX 850 ; N Obreve ; G 272 +U 335 ; WX 687 ; N obreve ; G 273 +U 336 ; WX 850 ; N Ohungarumlaut ; G 274 +U 337 ; WX 687 ; N ohungarumlaut ; G 275 +U 338 ; WX 1167 ; N OE ; G 276 +U 339 ; WX 1094 ; N oe ; G 277 +U 340 ; WX 770 ; N Racute ; G 278 +U 341 ; WX 493 ; N racute ; G 279 +U 342 ; WX 770 ; N Rcommaaccent ; G 280 +U 343 ; WX 493 ; N rcommaaccent ; G 281 +U 344 ; WX 770 ; N Rcaron ; G 282 +U 345 ; WX 493 ; N rcaron ; G 283 +U 346 ; WX 720 ; N Sacute ; G 284 +U 347 ; WX 595 ; N sacute ; G 285 +U 348 ; WX 720 ; N Scircumflex ; G 286 +U 349 ; WX 595 ; N scircumflex ; G 287 +U 350 ; WX 720 ; N Scedilla ; G 288 +U 351 ; WX 595 ; N scedilla ; G 289 +U 352 ; WX 720 ; N Scaron ; G 290 +U 353 ; WX 595 ; N scaron ; G 291 +U 354 ; WX 682 ; N Tcommaaccent ; G 292 +U 355 ; WX 478 ; N tcommaaccent ; G 293 +U 356 ; WX 682 ; N Tcaron ; G 294 +U 357 ; WX 478 ; N tcaron ; G 295 +U 358 ; WX 682 ; N Tbar ; G 296 +U 359 ; WX 478 ; N tbar ; G 297 +U 360 ; WX 812 ; N Utilde ; G 298 +U 361 ; WX 712 ; N utilde ; G 299 +U 362 ; WX 812 ; N Umacron ; G 300 +U 363 ; WX 712 ; N umacron ; G 301 +U 364 ; WX 812 ; N Ubreve ; G 302 +U 365 ; WX 712 ; N ubreve ; G 303 +U 366 ; WX 812 ; N Uring ; G 304 +U 367 ; WX 712 ; N uring ; G 305 +U 368 ; WX 812 ; N Uhungarumlaut ; G 306 +U 369 ; WX 712 ; N uhungarumlaut ; G 307 +U 370 ; WX 812 ; N Uogonek ; G 308 +U 371 ; WX 712 ; N uogonek ; G 309 +U 372 ; WX 1103 ; N Wcircumflex ; G 310 +U 373 ; WX 924 ; N wcircumflex ; G 311 +U 374 ; WX 724 ; N Ycircumflex ; G 312 +U 375 ; WX 652 ; N ycircumflex ; G 313 +U 376 ; WX 724 ; N Ydieresis ; G 314 +U 377 ; WX 725 ; N Zacute ; G 315 +U 378 ; WX 582 ; N zacute ; G 316 +U 379 ; WX 725 ; N Zdotaccent ; G 317 +U 380 ; WX 582 ; N zdotaccent ; G 318 +U 381 ; WX 725 ; N Zcaron ; G 319 +U 382 ; WX 582 ; N zcaron ; G 320 +U 383 ; WX 435 ; N longs ; G 321 +U 384 ; WX 716 ; N uni0180 ; G 322 +U 385 ; WX 811 ; N uni0181 ; G 323 +U 386 ; WX 762 ; N uni0182 ; G 324 +U 387 ; WX 716 ; N uni0183 ; G 325 +U 388 ; WX 762 ; N uni0184 ; G 326 +U 389 ; WX 716 ; N uni0185 ; G 327 +U 390 ; WX 734 ; N uni0186 ; G 328 +U 391 ; WX 734 ; N uni0187 ; G 329 +U 392 ; WX 593 ; N uni0188 ; G 330 +U 393 ; WX 838 ; N uni0189 ; G 331 +U 394 ; WX 879 ; N uni018A ; G 332 +U 395 ; WX 757 ; N uni018B ; G 333 +U 396 ; WX 716 ; N uni018C ; G 334 +U 397 ; WX 688 ; N uni018D ; G 335 +U 398 ; WX 683 ; N uni018E ; G 336 +U 399 ; WX 849 ; N uni018F ; G 337 +U 400 ; WX 696 ; N uni0190 ; G 338 +U 401 ; WX 683 ; N uni0191 ; G 339 +U 402 ; WX 435 ; N florin ; G 340 +U 403 ; WX 821 ; N uni0193 ; G 341 +U 404 ; WX 793 ; N uni0194 ; G 342 +U 405 ; WX 1045 ; N uni0195 ; G 343 +U 406 ; WX 436 ; N uni0196 ; G 344 +U 407 ; WX 389 ; N uni0197 ; G 345 +U 408 ; WX 775 ; N uni0198 ; G 346 +U 409 ; WX 665 ; N uni0199 ; G 347 +U 410 ; WX 360 ; N uni019A ; G 348 +U 411 ; WX 592 ; N uni019B ; G 349 +U 412 ; WX 1042 ; N uni019C ; G 350 +U 413 ; WX 837 ; N uni019D ; G 351 +U 414 ; WX 712 ; N uni019E ; G 352 +U 415 ; WX 850 ; N uni019F ; G 353 +U 416 ; WX 874 ; N Ohorn ; G 354 +U 417 ; WX 687 ; N ohorn ; G 355 +U 418 ; WX 1083 ; N uni01A2 ; G 356 +U 419 ; WX 912 ; N uni01A3 ; G 357 +U 420 ; WX 782 ; N uni01A4 ; G 358 +U 421 ; WX 716 ; N uni01A5 ; G 359 +U 422 ; WX 770 ; N uni01A6 ; G 360 +U 423 ; WX 720 ; N uni01A7 ; G 361 +U 424 ; WX 595 ; N uni01A8 ; G 362 +U 425 ; WX 683 ; N uni01A9 ; G 363 +U 426 ; WX 552 ; N uni01AA ; G 364 +U 427 ; WX 478 ; N uni01AB ; G 365 +U 428 ; WX 707 ; N uni01AC ; G 366 +U 429 ; WX 478 ; N uni01AD ; G 367 +U 430 ; WX 682 ; N uni01AE ; G 368 +U 431 ; WX 835 ; N Uhorn ; G 369 +U 432 ; WX 712 ; N uhorn ; G 370 +U 433 ; WX 850 ; N uni01B1 ; G 371 +U 434 ; WX 813 ; N uni01B2 ; G 372 +U 435 ; WX 797 ; N uni01B3 ; G 373 +U 436 ; WX 778 ; N uni01B4 ; G 374 +U 437 ; WX 725 ; N uni01B5 ; G 375 +U 438 ; WX 582 ; N uni01B6 ; G 376 +U 439 ; WX 772 ; N uni01B7 ; G 377 +U 440 ; WX 772 ; N uni01B8 ; G 378 +U 441 ; WX 641 ; N uni01B9 ; G 379 +U 442 ; WX 582 ; N uni01BA ; G 380 +U 443 ; WX 696 ; N uni01BB ; G 381 +U 444 ; WX 772 ; N uni01BC ; G 382 +U 445 ; WX 641 ; N uni01BD ; G 383 +U 446 ; WX 573 ; N uni01BE ; G 384 +U 447 ; WX 716 ; N uni01BF ; G 385 +U 448 ; WX 372 ; N uni01C0 ; G 386 +U 449 ; WX 659 ; N uni01C1 ; G 387 +U 450 ; WX 544 ; N uni01C2 ; G 388 +U 451 ; WX 372 ; N uni01C3 ; G 389 +U 452 ; WX 1555 ; N uni01C4 ; G 390 +U 453 ; WX 1412 ; N uni01C5 ; G 391 +U 454 ; WX 1298 ; N uni01C6 ; G 392 +U 455 ; WX 1009 ; N uni01C7 ; G 393 +U 456 ; WX 980 ; N uni01C8 ; G 394 +U 457 ; WX 686 ; N uni01C9 ; G 395 +U 458 ; WX 1209 ; N uni01CA ; G 396 +U 459 ; WX 1180 ; N uni01CB ; G 397 +U 460 ; WX 1055 ; N uni01CC ; G 398 +U 461 ; WX 774 ; N uni01CD ; G 399 +U 462 ; WX 675 ; N uni01CE ; G 400 +U 463 ; WX 372 ; N uni01CF ; G 401 +U 464 ; WX 343 ; N uni01D0 ; G 402 +U 465 ; WX 850 ; N uni01D1 ; G 403 +U 466 ; WX 687 ; N uni01D2 ; G 404 +U 467 ; WX 812 ; N uni01D3 ; G 405 +U 468 ; WX 712 ; N uni01D4 ; G 406 +U 469 ; WX 812 ; N uni01D5 ; G 407 +U 470 ; WX 712 ; N uni01D6 ; G 408 +U 471 ; WX 812 ; N uni01D7 ; G 409 +U 472 ; WX 712 ; N uni01D8 ; G 410 +U 473 ; WX 812 ; N uni01D9 ; G 411 +U 474 ; WX 712 ; N uni01DA ; G 412 +U 475 ; WX 812 ; N uni01DB ; G 413 +U 476 ; WX 712 ; N uni01DC ; G 414 +U 477 ; WX 678 ; N uni01DD ; G 415 +U 478 ; WX 774 ; N uni01DE ; G 416 +U 479 ; WX 675 ; N uni01DF ; G 417 +U 480 ; WX 774 ; N uni01E0 ; G 418 +U 481 ; WX 675 ; N uni01E1 ; G 419 +U 482 ; WX 1085 ; N uni01E2 ; G 420 +U 483 ; WX 1048 ; N uni01E3 ; G 421 +U 484 ; WX 821 ; N uni01E4 ; G 422 +U 485 ; WX 716 ; N uni01E5 ; G 423 +U 486 ; WX 821 ; N Gcaron ; G 424 +U 487 ; WX 716 ; N gcaron ; G 425 +U 488 ; WX 775 ; N uni01E8 ; G 426 +U 489 ; WX 665 ; N uni01E9 ; G 427 +U 490 ; WX 850 ; N uni01EA ; G 428 +U 491 ; WX 687 ; N uni01EB ; G 429 +U 492 ; WX 850 ; N uni01EC ; G 430 +U 493 ; WX 687 ; N uni01ED ; G 431 +U 494 ; WX 772 ; N uni01EE ; G 432 +U 495 ; WX 582 ; N uni01EF ; G 433 +U 496 ; WX 343 ; N uni01F0 ; G 434 +U 497 ; WX 1555 ; N uni01F1 ; G 435 +U 498 ; WX 1412 ; N uni01F2 ; G 436 +U 499 ; WX 1298 ; N uni01F3 ; G 437 +U 500 ; WX 821 ; N uni01F4 ; G 438 +U 501 ; WX 716 ; N uni01F5 ; G 439 +U 502 ; WX 1289 ; N uni01F6 ; G 440 +U 503 ; WX 787 ; N uni01F7 ; G 441 +U 504 ; WX 837 ; N uni01F8 ; G 442 +U 505 ; WX 712 ; N uni01F9 ; G 443 +U 506 ; WX 774 ; N Aringacute ; G 444 +U 507 ; WX 675 ; N aringacute ; G 445 +U 508 ; WX 1085 ; N AEacute ; G 446 +U 509 ; WX 1048 ; N aeacute ; G 447 +U 510 ; WX 850 ; N Oslashacute ; G 448 +U 511 ; WX 687 ; N oslashacute ; G 449 +U 512 ; WX 774 ; N uni0200 ; G 450 +U 513 ; WX 675 ; N uni0201 ; G 451 +U 514 ; WX 774 ; N uni0202 ; G 452 +U 515 ; WX 675 ; N uni0203 ; G 453 +U 516 ; WX 683 ; N uni0204 ; G 454 +U 517 ; WX 678 ; N uni0205 ; G 455 +U 518 ; WX 683 ; N uni0206 ; G 456 +U 519 ; WX 678 ; N uni0207 ; G 457 +U 520 ; WX 372 ; N uni0208 ; G 458 +U 521 ; WX 343 ; N uni0209 ; G 459 +U 522 ; WX 372 ; N uni020A ; G 460 +U 523 ; WX 343 ; N uni020B ; G 461 +U 524 ; WX 850 ; N uni020C ; G 462 +U 525 ; WX 687 ; N uni020D ; G 463 +U 526 ; WX 850 ; N uni020E ; G 464 +U 527 ; WX 687 ; N uni020F ; G 465 +U 528 ; WX 770 ; N uni0210 ; G 466 +U 529 ; WX 493 ; N uni0211 ; G 467 +U 530 ; WX 770 ; N uni0212 ; G 468 +U 531 ; WX 493 ; N uni0213 ; G 469 +U 532 ; WX 812 ; N uni0214 ; G 470 +U 533 ; WX 712 ; N uni0215 ; G 471 +U 534 ; WX 812 ; N uni0216 ; G 472 +U 535 ; WX 712 ; N uni0217 ; G 473 +U 536 ; WX 720 ; N Scommaaccent ; G 474 +U 537 ; WX 595 ; N scommaaccent ; G 475 +U 538 ; WX 682 ; N uni021A ; G 476 +U 539 ; WX 478 ; N uni021B ; G 477 +U 540 ; WX 690 ; N uni021C ; G 478 +U 541 ; WX 607 ; N uni021D ; G 479 +U 542 ; WX 837 ; N uni021E ; G 480 +U 543 ; WX 712 ; N uni021F ; G 481 +U 544 ; WX 837 ; N uni0220 ; G 482 +U 545 ; WX 865 ; N uni0221 ; G 483 +U 546 ; WX 809 ; N uni0222 ; G 484 +U 547 ; WX 659 ; N uni0223 ; G 485 +U 548 ; WX 725 ; N uni0224 ; G 486 +U 549 ; WX 582 ; N uni0225 ; G 487 +U 550 ; WX 774 ; N uni0226 ; G 488 +U 551 ; WX 675 ; N uni0227 ; G 489 +U 552 ; WX 683 ; N uni0228 ; G 490 +U 553 ; WX 678 ; N uni0229 ; G 491 +U 554 ; WX 850 ; N uni022A ; G 492 +U 555 ; WX 687 ; N uni022B ; G 493 +U 556 ; WX 850 ; N uni022C ; G 494 +U 557 ; WX 687 ; N uni022D ; G 495 +U 558 ; WX 850 ; N uni022E ; G 496 +U 559 ; WX 687 ; N uni022F ; G 497 +U 560 ; WX 850 ; N uni0230 ; G 498 +U 561 ; WX 687 ; N uni0231 ; G 499 +U 562 ; WX 724 ; N uni0232 ; G 500 +U 563 ; WX 652 ; N uni0233 ; G 501 +U 564 ; WX 492 ; N uni0234 ; G 502 +U 565 ; WX 867 ; N uni0235 ; G 503 +U 566 ; WX 512 ; N uni0236 ; G 504 +U 567 ; WX 343 ; N dotlessj ; G 505 +U 568 ; WX 1088 ; N uni0238 ; G 506 +U 569 ; WX 1088 ; N uni0239 ; G 507 +U 570 ; WX 774 ; N uni023A ; G 508 +U 571 ; WX 734 ; N uni023B ; G 509 +U 572 ; WX 593 ; N uni023C ; G 510 +U 573 ; WX 637 ; N uni023D ; G 511 +U 574 ; WX 682 ; N uni023E ; G 512 +U 575 ; WX 595 ; N uni023F ; G 513 +U 576 ; WX 582 ; N uni0240 ; G 514 +U 577 ; WX 782 ; N uni0241 ; G 515 +U 578 ; WX 614 ; N uni0242 ; G 516 +U 579 ; WX 762 ; N uni0243 ; G 517 +U 580 ; WX 812 ; N uni0244 ; G 518 +U 581 ; WX 774 ; N uni0245 ; G 519 +U 582 ; WX 683 ; N uni0246 ; G 520 +U 583 ; WX 678 ; N uni0247 ; G 521 +U 584 ; WX 372 ; N uni0248 ; G 522 +U 585 ; WX 343 ; N uni0249 ; G 523 +U 586 ; WX 860 ; N uni024A ; G 524 +U 587 ; WX 791 ; N uni024B ; G 525 +U 588 ; WX 770 ; N uni024C ; G 526 +U 589 ; WX 493 ; N uni024D ; G 527 +U 590 ; WX 724 ; N uni024E ; G 528 +U 591 ; WX 652 ; N uni024F ; G 529 +U 592 ; WX 675 ; N uni0250 ; G 530 +U 593 ; WX 716 ; N uni0251 ; G 531 +U 594 ; WX 716 ; N uni0252 ; G 532 +U 595 ; WX 716 ; N uni0253 ; G 533 +U 596 ; WX 593 ; N uni0254 ; G 534 +U 597 ; WX 593 ; N uni0255 ; G 535 +U 598 ; WX 717 ; N uni0256 ; G 536 +U 599 ; WX 792 ; N uni0257 ; G 537 +U 600 ; WX 678 ; N uni0258 ; G 538 +U 601 ; WX 678 ; N uni0259 ; G 539 +U 602 ; WX 876 ; N uni025A ; G 540 +U 603 ; WX 557 ; N uni025B ; G 541 +U 604 ; WX 545 ; N uni025C ; G 542 +U 605 ; WX 815 ; N uni025D ; G 543 +U 606 ; WX 731 ; N uni025E ; G 544 +U 607 ; WX 343 ; N uni025F ; G 545 +U 608 ; WX 792 ; N uni0260 ; G 546 +U 609 ; WX 716 ; N uni0261 ; G 547 +U 610 ; WX 627 ; N uni0262 ; G 548 +U 611 ; WX 644 ; N uni0263 ; G 549 +U 612 ; WX 635 ; N uni0264 ; G 550 +U 613 ; WX 712 ; N uni0265 ; G 551 +U 614 ; WX 712 ; N uni0266 ; G 552 +U 615 ; WX 712 ; N uni0267 ; G 553 +U 616 ; WX 545 ; N uni0268 ; G 554 +U 617 ; WX 440 ; N uni0269 ; G 555 +U 618 ; WX 545 ; N uni026A ; G 556 +U 619 ; WX 559 ; N uni026B ; G 557 +U 620 ; WX 693 ; N uni026C ; G 558 +U 621 ; WX 343 ; N uni026D ; G 559 +U 622 ; WX 841 ; N uni026E ; G 560 +U 623 ; WX 1042 ; N uni026F ; G 561 +U 624 ; WX 1042 ; N uni0270 ; G 562 +U 625 ; WX 1042 ; N uni0271 ; G 563 +U 626 ; WX 712 ; N uni0272 ; G 564 +U 627 ; WX 793 ; N uni0273 ; G 565 +U 628 ; WX 707 ; N uni0274 ; G 566 +U 629 ; WX 687 ; N uni0275 ; G 567 +U 630 ; WX 909 ; N uni0276 ; G 568 +U 631 ; WX 681 ; N uni0277 ; G 569 +U 632 ; WX 796 ; N uni0278 ; G 570 +U 633 ; WX 538 ; N uni0279 ; G 571 +U 634 ; WX 538 ; N uni027A ; G 572 +U 635 ; WX 650 ; N uni027B ; G 573 +U 636 ; WX 493 ; N uni027C ; G 574 +U 637 ; WX 493 ; N uni027D ; G 575 +U 638 ; WX 596 ; N uni027E ; G 576 +U 639 ; WX 596 ; N uni027F ; G 577 +U 640 ; WX 642 ; N uni0280 ; G 578 +U 641 ; WX 642 ; N uni0281 ; G 579 +U 642 ; WX 595 ; N uni0282 ; G 580 +U 643 ; WX 415 ; N uni0283 ; G 581 +U 644 ; WX 435 ; N uni0284 ; G 582 +U 645 ; WX 605 ; N uni0285 ; G 583 +U 646 ; WX 552 ; N uni0286 ; G 584 +U 647 ; WX 478 ; N uni0287 ; G 585 +U 648 ; WX 478 ; N uni0288 ; G 586 +U 649 ; WX 920 ; N uni0289 ; G 587 +U 650 ; WX 772 ; N uni028A ; G 588 +U 651 ; WX 670 ; N uni028B ; G 589 +U 652 ; WX 652 ; N uni028C ; G 590 +U 653 ; WX 924 ; N uni028D ; G 591 +U 654 ; WX 652 ; N uni028E ; G 592 +U 655 ; WX 724 ; N uni028F ; G 593 +U 656 ; WX 694 ; N uni0290 ; G 594 +U 657 ; WX 684 ; N uni0291 ; G 595 +U 658 ; WX 641 ; N uni0292 ; G 596 +U 659 ; WX 641 ; N uni0293 ; G 597 +U 660 ; WX 573 ; N uni0294 ; G 598 +U 661 ; WX 573 ; N uni0295 ; G 599 +U 662 ; WX 573 ; N uni0296 ; G 600 +U 663 ; WX 573 ; N uni0297 ; G 601 +U 664 ; WX 850 ; N uni0298 ; G 602 +U 665 ; WX 633 ; N uni0299 ; G 603 +U 666 ; WX 731 ; N uni029A ; G 604 +U 667 ; WX 685 ; N uni029B ; G 605 +U 668 ; WX 691 ; N uni029C ; G 606 +U 669 ; WX 343 ; N uni029D ; G 607 +U 670 ; WX 732 ; N uni029E ; G 608 +U 671 ; WX 539 ; N uni029F ; G 609 +U 672 ; WX 792 ; N uni02A0 ; G 610 +U 673 ; WX 573 ; N uni02A1 ; G 611 +U 674 ; WX 573 ; N uni02A2 ; G 612 +U 675 ; WX 1156 ; N uni02A3 ; G 613 +U 676 ; WX 1214 ; N uni02A4 ; G 614 +U 677 ; WX 1155 ; N uni02A5 ; G 615 +U 678 ; WX 975 ; N uni02A6 ; G 616 +U 679 ; WX 769 ; N uni02A7 ; G 617 +U 680 ; WX 929 ; N uni02A8 ; G 618 +U 681 ; WX 1026 ; N uni02A9 ; G 619 +U 682 ; WX 862 ; N uni02AA ; G 620 +U 683 ; WX 780 ; N uni02AB ; G 621 +U 684 ; WX 591 ; N uni02AC ; G 622 +U 685 ; WX 415 ; N uni02AD ; G 623 +U 686 ; WX 677 ; N uni02AE ; G 624 +U 687 ; WX 789 ; N uni02AF ; G 625 +U 688 ; WX 456 ; N uni02B0 ; G 626 +U 689 ; WX 456 ; N uni02B1 ; G 627 +U 690 ; WX 219 ; N uni02B2 ; G 628 +U 691 ; WX 315 ; N uni02B3 ; G 629 +U 692 ; WX 315 ; N uni02B4 ; G 630 +U 693 ; WX 315 ; N uni02B5 ; G 631 +U 694 ; WX 411 ; N uni02B6 ; G 632 +U 695 ; WX 591 ; N uni02B7 ; G 633 +U 696 ; WX 417 ; N uni02B8 ; G 634 +U 697 ; WX 302 ; N uni02B9 ; G 635 +U 698 ; WX 521 ; N uni02BA ; G 636 +U 699 ; WX 380 ; N uni02BB ; G 637 +U 700 ; WX 380 ; N uni02BC ; G 638 +U 701 ; WX 380 ; N uni02BD ; G 639 +U 702 ; WX 366 ; N uni02BE ; G 640 +U 703 ; WX 366 ; N uni02BF ; G 641 +U 704 ; WX 326 ; N uni02C0 ; G 642 +U 705 ; WX 326 ; N uni02C1 ; G 643 +U 706 ; WX 500 ; N uni02C2 ; G 644 +U 707 ; WX 500 ; N uni02C3 ; G 645 +U 708 ; WX 500 ; N uni02C4 ; G 646 +U 709 ; WX 500 ; N uni02C5 ; G 647 +U 710 ; WX 500 ; N circumflex ; G 648 +U 711 ; WX 500 ; N caron ; G 649 +U 712 ; WX 306 ; N uni02C8 ; G 650 +U 713 ; WX 500 ; N uni02C9 ; G 651 +U 714 ; WX 500 ; N uni02CA ; G 652 +U 715 ; WX 500 ; N uni02CB ; G 653 +U 716 ; WX 306 ; N uni02CC ; G 654 +U 717 ; WX 500 ; N uni02CD ; G 655 +U 718 ; WX 500 ; N uni02CE ; G 656 +U 719 ; WX 500 ; N uni02CF ; G 657 +U 720 ; WX 337 ; N uni02D0 ; G 658 +U 721 ; WX 337 ; N uni02D1 ; G 659 +U 722 ; WX 366 ; N uni02D2 ; G 660 +U 723 ; WX 366 ; N uni02D3 ; G 661 +U 724 ; WX 500 ; N uni02D4 ; G 662 +U 725 ; WX 500 ; N uni02D5 ; G 663 +U 726 ; WX 416 ; N uni02D6 ; G 664 +U 727 ; WX 328 ; N uni02D7 ; G 665 +U 728 ; WX 500 ; N breve ; G 666 +U 729 ; WX 500 ; N dotaccent ; G 667 +U 730 ; WX 500 ; N ring ; G 668 +U 731 ; WX 500 ; N ogonek ; G 669 +U 732 ; WX 500 ; N tilde ; G 670 +U 733 ; WX 500 ; N hungarumlaut ; G 671 +U 734 ; WX 351 ; N uni02DE ; G 672 +U 735 ; WX 500 ; N uni02DF ; G 673 +U 736 ; WX 412 ; N uni02E0 ; G 674 +U 737 ; WX 219 ; N uni02E1 ; G 675 +U 738 ; WX 381 ; N uni02E2 ; G 676 +U 739 ; WX 413 ; N uni02E3 ; G 677 +U 740 ; WX 326 ; N uni02E4 ; G 678 +U 741 ; WX 500 ; N uni02E5 ; G 679 +U 742 ; WX 500 ; N uni02E6 ; G 680 +U 743 ; WX 500 ; N uni02E7 ; G 681 +U 744 ; WX 500 ; N uni02E8 ; G 682 +U 745 ; WX 500 ; N uni02E9 ; G 683 +U 748 ; WX 500 ; N uni02EC ; G 684 +U 749 ; WX 500 ; N uni02ED ; G 685 +U 750 ; WX 657 ; N uni02EE ; G 686 +U 755 ; WX 500 ; N uni02F3 ; G 687 +U 759 ; WX 500 ; N uni02F7 ; G 688 +U 768 ; WX 0 ; N gravecomb ; G 689 +U 769 ; WX 0 ; N acutecomb ; G 690 +U 770 ; WX 0 ; N uni0302 ; G 691 +U 771 ; WX 0 ; N tildecomb ; G 692 +U 772 ; WX 0 ; N uni0304 ; G 693 +U 773 ; WX 0 ; N uni0305 ; G 694 +U 774 ; WX 0 ; N uni0306 ; G 695 +U 775 ; WX 0 ; N uni0307 ; G 696 +U 776 ; WX 0 ; N uni0308 ; G 697 +U 777 ; WX 0 ; N hookabovecomb ; G 698 +U 778 ; WX 0 ; N uni030A ; G 699 +U 779 ; WX 0 ; N uni030B ; G 700 +U 780 ; WX 0 ; N uni030C ; G 701 +U 781 ; WX 0 ; N uni030D ; G 702 +U 782 ; WX 0 ; N uni030E ; G 703 +U 783 ; WX 0 ; N uni030F ; G 704 +U 784 ; WX 0 ; N uni0310 ; G 705 +U 785 ; WX 0 ; N uni0311 ; G 706 +U 786 ; WX 0 ; N uni0312 ; G 707 +U 787 ; WX 0 ; N uni0313 ; G 708 +U 788 ; WX 0 ; N uni0314 ; G 709 +U 789 ; WX 0 ; N uni0315 ; G 710 +U 790 ; WX 0 ; N uni0316 ; G 711 +U 791 ; WX 0 ; N uni0317 ; G 712 +U 792 ; WX 0 ; N uni0318 ; G 713 +U 793 ; WX 0 ; N uni0319 ; G 714 +U 794 ; WX 0 ; N uni031A ; G 715 +U 795 ; WX 0 ; N uni031B ; G 716 +U 796 ; WX 0 ; N uni031C ; G 717 +U 797 ; WX 0 ; N uni031D ; G 718 +U 798 ; WX 0 ; N uni031E ; G 719 +U 799 ; WX 0 ; N uni031F ; G 720 +U 800 ; WX 0 ; N uni0320 ; G 721 +U 801 ; WX 0 ; N uni0321 ; G 722 +U 802 ; WX 0 ; N uni0322 ; G 723 +U 803 ; WX 0 ; N dotbelowcomb ; G 724 +U 804 ; WX 0 ; N uni0324 ; G 725 +U 805 ; WX 0 ; N uni0325 ; G 726 +U 806 ; WX 0 ; N uni0326 ; G 727 +U 807 ; WX 0 ; N uni0327 ; G 728 +U 808 ; WX 0 ; N uni0328 ; G 729 +U 809 ; WX 0 ; N uni0329 ; G 730 +U 810 ; WX 0 ; N uni032A ; G 731 +U 811 ; WX 0 ; N uni032B ; G 732 +U 812 ; WX 0 ; N uni032C ; G 733 +U 813 ; WX 0 ; N uni032D ; G 734 +U 814 ; WX 0 ; N uni032E ; G 735 +U 815 ; WX 0 ; N uni032F ; G 736 +U 816 ; WX 0 ; N uni0330 ; G 737 +U 817 ; WX 0 ; N uni0331 ; G 738 +U 818 ; WX 0 ; N uni0332 ; G 739 +U 819 ; WX 0 ; N uni0333 ; G 740 +U 820 ; WX 0 ; N uni0334 ; G 741 +U 821 ; WX 0 ; N uni0335 ; G 742 +U 822 ; WX 0 ; N uni0336 ; G 743 +U 823 ; WX 0 ; N uni0337 ; G 744 +U 824 ; WX 0 ; N uni0338 ; G 745 +U 825 ; WX 0 ; N uni0339 ; G 746 +U 826 ; WX 0 ; N uni033A ; G 747 +U 827 ; WX 0 ; N uni033B ; G 748 +U 828 ; WX 0 ; N uni033C ; G 749 +U 829 ; WX 0 ; N uni033D ; G 750 +U 830 ; WX 0 ; N uni033E ; G 751 +U 831 ; WX 0 ; N uni033F ; G 752 +U 832 ; WX 0 ; N uni0340 ; G 753 +U 833 ; WX 0 ; N uni0341 ; G 754 +U 834 ; WX 0 ; N uni0342 ; G 755 +U 835 ; WX 0 ; N uni0343 ; G 756 +U 836 ; WX 0 ; N uni0344 ; G 757 +U 837 ; WX 0 ; N uni0345 ; G 758 +U 838 ; WX 0 ; N uni0346 ; G 759 +U 839 ; WX 0 ; N uni0347 ; G 760 +U 840 ; WX 0 ; N uni0348 ; G 761 +U 841 ; WX 0 ; N uni0349 ; G 762 +U 842 ; WX 0 ; N uni034A ; G 763 +U 843 ; WX 0 ; N uni034B ; G 764 +U 844 ; WX 0 ; N uni034C ; G 765 +U 845 ; WX 0 ; N uni034D ; G 766 +U 846 ; WX 0 ; N uni034E ; G 767 +U 847 ; WX 0 ; N uni034F ; G 768 +U 849 ; WX 0 ; N uni0351 ; G 769 +U 850 ; WX 0 ; N uni0352 ; G 770 +U 851 ; WX 0 ; N uni0353 ; G 771 +U 855 ; WX 0 ; N uni0357 ; G 772 +U 856 ; WX 0 ; N uni0358 ; G 773 +U 858 ; WX 0 ; N uni035A ; G 774 +U 860 ; WX 0 ; N uni035C ; G 775 +U 861 ; WX 0 ; N uni035D ; G 776 +U 862 ; WX 0 ; N uni035E ; G 777 +U 863 ; WX 0 ; N uni035F ; G 778 +U 864 ; WX 0 ; N uni0360 ; G 779 +U 865 ; WX 0 ; N uni0361 ; G 780 +U 866 ; WX 0 ; N uni0362 ; G 781 +U 880 ; WX 698 ; N uni0370 ; G 782 +U 881 ; WX 565 ; N uni0371 ; G 783 +U 882 ; WX 1022 ; N uni0372 ; G 784 +U 883 ; WX 836 ; N uni0373 ; G 785 +U 884 ; WX 302 ; N uni0374 ; G 786 +U 885 ; WX 302 ; N uni0375 ; G 787 +U 886 ; WX 837 ; N uni0376 ; G 788 +U 887 ; WX 701 ; N uni0377 ; G 789 +U 890 ; WX 500 ; N uni037A ; G 790 +U 891 ; WX 593 ; N uni037B ; G 791 +U 892 ; WX 550 ; N uni037C ; G 792 +U 893 ; WX 549 ; N uni037D ; G 793 +U 894 ; WX 400 ; N uni037E ; G 794 +U 895 ; WX 372 ; N uni037F ; G 795 +U 900 ; WX 441 ; N tonos ; G 796 +U 901 ; WX 500 ; N dieresistonos ; G 797 +U 902 ; WX 797 ; N Alphatonos ; G 798 +U 903 ; WX 380 ; N anoteleia ; G 799 +U 904 ; WX 846 ; N Epsilontonos ; G 800 +U 905 ; WX 1009 ; N Etatonos ; G 801 +U 906 ; WX 563 ; N Iotatonos ; G 802 +U 908 ; WX 891 ; N Omicrontonos ; G 803 +U 910 ; WX 980 ; N Upsilontonos ; G 804 +U 911 ; WX 894 ; N Omegatonos ; G 805 +U 912 ; WX 390 ; N iotadieresistonos ; G 806 +U 913 ; WX 774 ; N Alpha ; G 807 +U 914 ; WX 762 ; N Beta ; G 808 +U 915 ; WX 637 ; N Gamma ; G 809 +U 916 ; WX 774 ; N uni0394 ; G 810 +U 917 ; WX 683 ; N Epsilon ; G 811 +U 918 ; WX 725 ; N Zeta ; G 812 +U 919 ; WX 837 ; N Eta ; G 813 +U 920 ; WX 850 ; N Theta ; G 814 +U 921 ; WX 372 ; N Iota ; G 815 +U 922 ; WX 775 ; N Kappa ; G 816 +U 923 ; WX 774 ; N Lambda ; G 817 +U 924 ; WX 995 ; N Mu ; G 818 +U 925 ; WX 837 ; N Nu ; G 819 +U 926 ; WX 632 ; N Xi ; G 820 +U 927 ; WX 850 ; N Omicron ; G 821 +U 928 ; WX 837 ; N Pi ; G 822 +U 929 ; WX 733 ; N Rho ; G 823 +U 931 ; WX 683 ; N Sigma ; G 824 +U 932 ; WX 682 ; N Tau ; G 825 +U 933 ; WX 724 ; N Upsilon ; G 826 +U 934 ; WX 850 ; N Phi ; G 827 +U 935 ; WX 771 ; N Chi ; G 828 +U 936 ; WX 850 ; N Psi ; G 829 +U 937 ; WX 850 ; N Omega ; G 830 +U 938 ; WX 372 ; N Iotadieresis ; G 831 +U 939 ; WX 724 ; N Upsilondieresis ; G 832 +U 940 ; WX 687 ; N alphatonos ; G 833 +U 941 ; WX 557 ; N epsilontonos ; G 834 +U 942 ; WX 712 ; N etatonos ; G 835 +U 943 ; WX 390 ; N iotatonos ; G 836 +U 944 ; WX 675 ; N upsilondieresistonos ; G 837 +U 945 ; WX 687 ; N alpha ; G 838 +U 946 ; WX 716 ; N beta ; G 839 +U 947 ; WX 681 ; N gamma ; G 840 +U 948 ; WX 687 ; N delta ; G 841 +U 949 ; WX 557 ; N epsilon ; G 842 +U 950 ; WX 591 ; N zeta ; G 843 +U 951 ; WX 712 ; N eta ; G 844 +U 952 ; WX 687 ; N theta ; G 845 +U 953 ; WX 390 ; N iota ; G 846 +U 954 ; WX 710 ; N kappa ; G 847 +U 955 ; WX 633 ; N lambda ; G 848 +U 956 ; WX 736 ; N uni03BC ; G 849 +U 957 ; WX 681 ; N nu ; G 850 +U 958 ; WX 591 ; N xi ; G 851 +U 959 ; WX 687 ; N omicron ; G 852 +U 960 ; WX 791 ; N pi ; G 853 +U 961 ; WX 716 ; N rho ; G 854 +U 962 ; WX 593 ; N sigma1 ; G 855 +U 963 ; WX 779 ; N sigma ; G 856 +U 964 ; WX 638 ; N tau ; G 857 +U 965 ; WX 675 ; N upsilon ; G 858 +U 966 ; WX 782 ; N phi ; G 859 +U 967 ; WX 645 ; N chi ; G 860 +U 968 ; WX 794 ; N psi ; G 861 +U 969 ; WX 869 ; N omega ; G 862 +U 970 ; WX 390 ; N iotadieresis ; G 863 +U 971 ; WX 675 ; N upsilondieresis ; G 864 +U 972 ; WX 687 ; N omicrontonos ; G 865 +U 973 ; WX 675 ; N upsilontonos ; G 866 +U 974 ; WX 869 ; N omegatonos ; G 867 +U 975 ; WX 775 ; N uni03CF ; G 868 +U 976 ; WX 651 ; N uni03D0 ; G 869 +U 977 ; WX 661 ; N theta1 ; G 870 +U 978 ; WX 746 ; N Upsilon1 ; G 871 +U 979 ; WX 981 ; N uni03D3 ; G 872 +U 980 ; WX 746 ; N uni03D4 ; G 873 +U 981 ; WX 796 ; N phi1 ; G 874 +U 982 ; WX 869 ; N omega1 ; G 875 +U 983 ; WX 744 ; N uni03D7 ; G 876 +U 984 ; WX 850 ; N uni03D8 ; G 877 +U 985 ; WX 687 ; N uni03D9 ; G 878 +U 986 ; WX 734 ; N uni03DA ; G 879 +U 987 ; WX 593 ; N uni03DB ; G 880 +U 988 ; WX 683 ; N uni03DC ; G 881 +U 989 ; WX 494 ; N uni03DD ; G 882 +U 990 ; WX 702 ; N uni03DE ; G 883 +U 991 ; WX 660 ; N uni03DF ; G 884 +U 992 ; WX 919 ; N uni03E0 ; G 885 +U 993 ; WX 627 ; N uni03E1 ; G 886 +U 994 ; WX 1093 ; N uni03E2 ; G 887 +U 995 ; WX 837 ; N uni03E3 ; G 888 +U 996 ; WX 832 ; N uni03E4 ; G 889 +U 997 ; WX 716 ; N uni03E5 ; G 890 +U 998 ; WX 928 ; N uni03E6 ; G 891 +U 999 ; WX 744 ; N uni03E7 ; G 892 +U 1000 ; WX 733 ; N uni03E8 ; G 893 +U 1001 ; WX 650 ; N uni03E9 ; G 894 +U 1002 ; WX 789 ; N uni03EA ; G 895 +U 1003 ; WX 671 ; N uni03EB ; G 896 +U 1004 ; WX 752 ; N uni03EC ; G 897 +U 1005 ; WX 716 ; N uni03ED ; G 898 +U 1006 ; WX 682 ; N uni03EE ; G 899 +U 1007 ; WX 590 ; N uni03EF ; G 900 +U 1008 ; WX 744 ; N uni03F0 ; G 901 +U 1009 ; WX 716 ; N uni03F1 ; G 902 +U 1010 ; WX 593 ; N uni03F2 ; G 903 +U 1011 ; WX 343 ; N uni03F3 ; G 904 +U 1012 ; WX 850 ; N uni03F4 ; G 905 +U 1013 ; WX 645 ; N uni03F5 ; G 906 +U 1014 ; WX 644 ; N uni03F6 ; G 907 +U 1015 ; WX 738 ; N uni03F7 ; G 908 +U 1016 ; WX 716 ; N uni03F8 ; G 909 +U 1017 ; WX 734 ; N uni03F9 ; G 910 +U 1018 ; WX 995 ; N uni03FA ; G 911 +U 1019 ; WX 732 ; N uni03FB ; G 912 +U 1020 ; WX 716 ; N uni03FC ; G 913 +U 1021 ; WX 698 ; N uni03FD ; G 914 +U 1022 ; WX 734 ; N uni03FE ; G 915 +U 1023 ; WX 698 ; N uni03FF ; G 916 +U 1024 ; WX 683 ; N uni0400 ; G 917 +U 1025 ; WX 683 ; N uni0401 ; G 918 +U 1026 ; WX 878 ; N uni0402 ; G 919 +U 1027 ; WX 637 ; N uni0403 ; G 920 +U 1028 ; WX 734 ; N uni0404 ; G 921 +U 1029 ; WX 720 ; N uni0405 ; G 922 +U 1030 ; WX 372 ; N uni0406 ; G 923 +U 1031 ; WX 372 ; N uni0407 ; G 924 +U 1032 ; WX 372 ; N uni0408 ; G 925 +U 1033 ; WX 1154 ; N uni0409 ; G 926 +U 1034 ; WX 1130 ; N uni040A ; G 927 +U 1035 ; WX 878 ; N uni040B ; G 928 +U 1036 ; WX 817 ; N uni040C ; G 929 +U 1037 ; WX 837 ; N uni040D ; G 930 +U 1038 ; WX 771 ; N uni040E ; G 931 +U 1039 ; WX 837 ; N uni040F ; G 932 +U 1040 ; WX 774 ; N uni0410 ; G 933 +U 1041 ; WX 762 ; N uni0411 ; G 934 +U 1042 ; WX 762 ; N uni0412 ; G 935 +U 1043 ; WX 637 ; N uni0413 ; G 936 +U 1044 ; WX 891 ; N uni0414 ; G 937 +U 1045 ; WX 683 ; N uni0415 ; G 938 +U 1046 ; WX 1224 ; N uni0416 ; G 939 +U 1047 ; WX 710 ; N uni0417 ; G 940 +U 1048 ; WX 837 ; N uni0418 ; G 941 +U 1049 ; WX 837 ; N uni0419 ; G 942 +U 1050 ; WX 817 ; N uni041A ; G 943 +U 1051 ; WX 831 ; N uni041B ; G 944 +U 1052 ; WX 995 ; N uni041C ; G 945 +U 1053 ; WX 837 ; N uni041D ; G 946 +U 1054 ; WX 850 ; N uni041E ; G 947 +U 1055 ; WX 837 ; N uni041F ; G 948 +U 1056 ; WX 733 ; N uni0420 ; G 949 +U 1057 ; WX 734 ; N uni0421 ; G 950 +U 1058 ; WX 682 ; N uni0422 ; G 951 +U 1059 ; WX 771 ; N uni0423 ; G 952 +U 1060 ; WX 992 ; N uni0424 ; G 953 +U 1061 ; WX 771 ; N uni0425 ; G 954 +U 1062 ; WX 928 ; N uni0426 ; G 955 +U 1063 ; WX 808 ; N uni0427 ; G 956 +U 1064 ; WX 1235 ; N uni0428 ; G 957 +U 1065 ; WX 1326 ; N uni0429 ; G 958 +U 1066 ; WX 939 ; N uni042A ; G 959 +U 1067 ; WX 1036 ; N uni042B ; G 960 +U 1068 ; WX 762 ; N uni042C ; G 961 +U 1069 ; WX 734 ; N uni042D ; G 962 +U 1070 ; WX 1174 ; N uni042E ; G 963 +U 1071 ; WX 770 ; N uni042F ; G 964 +U 1072 ; WX 675 ; N uni0430 ; G 965 +U 1073 ; WX 698 ; N uni0431 ; G 966 +U 1074 ; WX 633 ; N uni0432 ; G 967 +U 1075 ; WX 522 ; N uni0433 ; G 968 +U 1076 ; WX 808 ; N uni0434 ; G 969 +U 1077 ; WX 678 ; N uni0435 ; G 970 +U 1078 ; WX 995 ; N uni0436 ; G 971 +U 1079 ; WX 581 ; N uni0437 ; G 972 +U 1080 ; WX 701 ; N uni0438 ; G 973 +U 1081 ; WX 701 ; N uni0439 ; G 974 +U 1082 ; WX 679 ; N uni043A ; G 975 +U 1083 ; WX 732 ; N uni043B ; G 976 +U 1084 ; WX 817 ; N uni043C ; G 977 +U 1085 ; WX 691 ; N uni043D ; G 978 +U 1086 ; WX 687 ; N uni043E ; G 979 +U 1087 ; WX 691 ; N uni043F ; G 980 +U 1088 ; WX 716 ; N uni0440 ; G 981 +U 1089 ; WX 593 ; N uni0441 ; G 982 +U 1090 ; WX 580 ; N uni0442 ; G 983 +U 1091 ; WX 652 ; N uni0443 ; G 984 +U 1092 ; WX 992 ; N uni0444 ; G 985 +U 1093 ; WX 645 ; N uni0445 ; G 986 +U 1094 ; WX 741 ; N uni0446 ; G 987 +U 1095 ; WX 687 ; N uni0447 ; G 988 +U 1096 ; WX 1062 ; N uni0448 ; G 989 +U 1097 ; WX 1105 ; N uni0449 ; G 990 +U 1098 ; WX 751 ; N uni044A ; G 991 +U 1099 ; WX 904 ; N uni044B ; G 992 +U 1100 ; WX 632 ; N uni044C ; G 993 +U 1101 ; WX 593 ; N uni044D ; G 994 +U 1102 ; WX 972 ; N uni044E ; G 995 +U 1103 ; WX 642 ; N uni044F ; G 996 +U 1104 ; WX 678 ; N uni0450 ; G 997 +U 1105 ; WX 678 ; N uni0451 ; G 998 +U 1106 ; WX 714 ; N uni0452 ; G 999 +U 1107 ; WX 522 ; N uni0453 ; G 1000 +U 1108 ; WX 593 ; N uni0454 ; G 1001 +U 1109 ; WX 595 ; N uni0455 ; G 1002 +U 1110 ; WX 343 ; N uni0456 ; G 1003 +U 1111 ; WX 343 ; N uni0457 ; G 1004 +U 1112 ; WX 343 ; N uni0458 ; G 1005 +U 1113 ; WX 991 ; N uni0459 ; G 1006 +U 1114 ; WX 956 ; N uni045A ; G 1007 +U 1115 ; WX 734 ; N uni045B ; G 1008 +U 1116 ; WX 679 ; N uni045C ; G 1009 +U 1117 ; WX 701 ; N uni045D ; G 1010 +U 1118 ; WX 652 ; N uni045E ; G 1011 +U 1119 ; WX 691 ; N uni045F ; G 1012 +U 1120 ; WX 1093 ; N uni0460 ; G 1013 +U 1121 ; WX 869 ; N uni0461 ; G 1014 +U 1122 ; WX 840 ; N uni0462 ; G 1015 +U 1123 ; WX 736 ; N uni0463 ; G 1016 +U 1124 ; WX 1012 ; N uni0464 ; G 1017 +U 1125 ; WX 839 ; N uni0465 ; G 1018 +U 1126 ; WX 992 ; N uni0466 ; G 1019 +U 1127 ; WX 832 ; N uni0467 ; G 1020 +U 1128 ; WX 1358 ; N uni0468 ; G 1021 +U 1129 ; WX 1121 ; N uni0469 ; G 1022 +U 1130 ; WX 850 ; N uni046A ; G 1023 +U 1131 ; WX 687 ; N uni046B ; G 1024 +U 1132 ; WX 1236 ; N uni046C ; G 1025 +U 1133 ; WX 1007 ; N uni046D ; G 1026 +U 1134 ; WX 696 ; N uni046E ; G 1027 +U 1135 ; WX 557 ; N uni046F ; G 1028 +U 1136 ; WX 1075 ; N uni0470 ; G 1029 +U 1137 ; WX 1061 ; N uni0471 ; G 1030 +U 1138 ; WX 850 ; N uni0472 ; G 1031 +U 1139 ; WX 687 ; N uni0473 ; G 1032 +U 1140 ; WX 850 ; N uni0474 ; G 1033 +U 1141 ; WX 695 ; N uni0475 ; G 1034 +U 1142 ; WX 850 ; N uni0476 ; G 1035 +U 1143 ; WX 695 ; N uni0477 ; G 1036 +U 1144 ; WX 1148 ; N uni0478 ; G 1037 +U 1145 ; WX 1043 ; N uni0479 ; G 1038 +U 1146 ; WX 1074 ; N uni047A ; G 1039 +U 1147 ; WX 863 ; N uni047B ; G 1040 +U 1148 ; WX 1405 ; N uni047C ; G 1041 +U 1149 ; WX 1173 ; N uni047D ; G 1042 +U 1150 ; WX 1093 ; N uni047E ; G 1043 +U 1151 ; WX 869 ; N uni047F ; G 1044 +U 1152 ; WX 734 ; N uni0480 ; G 1045 +U 1153 ; WX 593 ; N uni0481 ; G 1046 +U 1154 ; WX 652 ; N uni0482 ; G 1047 +U 1155 ; WX 0 ; N uni0483 ; G 1048 +U 1156 ; WX 0 ; N uni0484 ; G 1049 +U 1157 ; WX 0 ; N uni0485 ; G 1050 +U 1158 ; WX 0 ; N uni0486 ; G 1051 +U 1159 ; WX 0 ; N uni0487 ; G 1052 +U 1160 ; WX 418 ; N uni0488 ; G 1053 +U 1161 ; WX 418 ; N uni0489 ; G 1054 +U 1162 ; WX 957 ; N uni048A ; G 1055 +U 1163 ; WX 807 ; N uni048B ; G 1056 +U 1164 ; WX 762 ; N uni048C ; G 1057 +U 1165 ; WX 611 ; N uni048D ; G 1058 +U 1166 ; WX 733 ; N uni048E ; G 1059 +U 1167 ; WX 716 ; N uni048F ; G 1060 +U 1168 ; WX 637 ; N uni0490 ; G 1061 +U 1169 ; WX 522 ; N uni0491 ; G 1062 +U 1170 ; WX 666 ; N uni0492 ; G 1063 +U 1171 ; WX 543 ; N uni0493 ; G 1064 +U 1172 ; WX 808 ; N uni0494 ; G 1065 +U 1173 ; WX 669 ; N uni0495 ; G 1066 +U 1174 ; WX 1224 ; N uni0496 ; G 1067 +U 1175 ; WX 995 ; N uni0497 ; G 1068 +U 1176 ; WX 710 ; N uni0498 ; G 1069 +U 1177 ; WX 581 ; N uni0499 ; G 1070 +U 1178 ; WX 775 ; N uni049A ; G 1071 +U 1179 ; WX 679 ; N uni049B ; G 1072 +U 1180 ; WX 817 ; N uni049C ; G 1073 +U 1181 ; WX 679 ; N uni049D ; G 1074 +U 1182 ; WX 817 ; N uni049E ; G 1075 +U 1183 ; WX 679 ; N uni049F ; G 1076 +U 1184 ; WX 1015 ; N uni04A0 ; G 1077 +U 1185 ; WX 826 ; N uni04A1 ; G 1078 +U 1186 ; WX 956 ; N uni04A2 ; G 1079 +U 1187 ; WX 808 ; N uni04A3 ; G 1080 +U 1188 ; WX 1103 ; N uni04A4 ; G 1081 +U 1189 ; WX 874 ; N uni04A5 ; G 1082 +U 1190 ; WX 1273 ; N uni04A6 ; G 1083 +U 1191 ; WX 1017 ; N uni04A7 ; G 1084 +U 1192 ; WX 952 ; N uni04A8 ; G 1085 +U 1193 ; WX 858 ; N uni04A9 ; G 1086 +U 1194 ; WX 734 ; N uni04AA ; G 1087 +U 1195 ; WX 593 ; N uni04AB ; G 1088 +U 1196 ; WX 682 ; N uni04AC ; G 1089 +U 1197 ; WX 580 ; N uni04AD ; G 1090 +U 1198 ; WX 724 ; N uni04AE ; G 1091 +U 1199 ; WX 652 ; N uni04AF ; G 1092 +U 1200 ; WX 724 ; N uni04B0 ; G 1093 +U 1201 ; WX 652 ; N uni04B1 ; G 1094 +U 1202 ; WX 771 ; N uni04B2 ; G 1095 +U 1203 ; WX 645 ; N uni04B3 ; G 1096 +U 1204 ; WX 1112 ; N uni04B4 ; G 1097 +U 1205 ; WX 1000 ; N uni04B5 ; G 1098 +U 1206 ; WX 808 ; N uni04B6 ; G 1099 +U 1207 ; WX 687 ; N uni04B7 ; G 1100 +U 1208 ; WX 808 ; N uni04B8 ; G 1101 +U 1209 ; WX 687 ; N uni04B9 ; G 1102 +U 1210 ; WX 808 ; N uni04BA ; G 1103 +U 1211 ; WX 712 ; N uni04BB ; G 1104 +U 1212 ; WX 1026 ; N uni04BC ; G 1105 +U 1213 ; WX 810 ; N uni04BD ; G 1106 +U 1214 ; WX 1026 ; N uni04BE ; G 1107 +U 1215 ; WX 810 ; N uni04BF ; G 1108 +U 1216 ; WX 372 ; N uni04C0 ; G 1109 +U 1217 ; WX 1224 ; N uni04C1 ; G 1110 +U 1218 ; WX 995 ; N uni04C2 ; G 1111 +U 1219 ; WX 775 ; N uni04C3 ; G 1112 +U 1220 ; WX 630 ; N uni04C4 ; G 1113 +U 1221 ; WX 951 ; N uni04C5 ; G 1114 +U 1222 ; WX 805 ; N uni04C6 ; G 1115 +U 1223 ; WX 837 ; N uni04C7 ; G 1116 +U 1224 ; WX 691 ; N uni04C8 ; G 1117 +U 1225 ; WX 957 ; N uni04C9 ; G 1118 +U 1226 ; WX 807 ; N uni04CA ; G 1119 +U 1227 ; WX 808 ; N uni04CB ; G 1120 +U 1228 ; WX 687 ; N uni04CC ; G 1121 +U 1229 ; WX 1115 ; N uni04CD ; G 1122 +U 1230 ; WX 933 ; N uni04CE ; G 1123 +U 1231 ; WX 343 ; N uni04CF ; G 1124 +U 1232 ; WX 774 ; N uni04D0 ; G 1125 +U 1233 ; WX 675 ; N uni04D1 ; G 1126 +U 1234 ; WX 774 ; N uni04D2 ; G 1127 +U 1235 ; WX 675 ; N uni04D3 ; G 1128 +U 1236 ; WX 1085 ; N uni04D4 ; G 1129 +U 1237 ; WX 1048 ; N uni04D5 ; G 1130 +U 1238 ; WX 683 ; N uni04D6 ; G 1131 +U 1239 ; WX 678 ; N uni04D7 ; G 1132 +U 1240 ; WX 849 ; N uni04D8 ; G 1133 +U 1241 ; WX 678 ; N uni04D9 ; G 1134 +U 1242 ; WX 849 ; N uni04DA ; G 1135 +U 1243 ; WX 678 ; N uni04DB ; G 1136 +U 1244 ; WX 1224 ; N uni04DC ; G 1137 +U 1245 ; WX 995 ; N uni04DD ; G 1138 +U 1246 ; WX 710 ; N uni04DE ; G 1139 +U 1247 ; WX 581 ; N uni04DF ; G 1140 +U 1248 ; WX 772 ; N uni04E0 ; G 1141 +U 1249 ; WX 641 ; N uni04E1 ; G 1142 +U 1250 ; WX 837 ; N uni04E2 ; G 1143 +U 1251 ; WX 701 ; N uni04E3 ; G 1144 +U 1252 ; WX 837 ; N uni04E4 ; G 1145 +U 1253 ; WX 701 ; N uni04E5 ; G 1146 +U 1254 ; WX 850 ; N uni04E6 ; G 1147 +U 1255 ; WX 687 ; N uni04E7 ; G 1148 +U 1256 ; WX 850 ; N uni04E8 ; G 1149 +U 1257 ; WX 687 ; N uni04E9 ; G 1150 +U 1258 ; WX 850 ; N uni04EA ; G 1151 +U 1259 ; WX 687 ; N uni04EB ; G 1152 +U 1260 ; WX 734 ; N uni04EC ; G 1153 +U 1261 ; WX 593 ; N uni04ED ; G 1154 +U 1262 ; WX 771 ; N uni04EE ; G 1155 +U 1263 ; WX 652 ; N uni04EF ; G 1156 +U 1264 ; WX 771 ; N uni04F0 ; G 1157 +U 1265 ; WX 652 ; N uni04F1 ; G 1158 +U 1266 ; WX 771 ; N uni04F2 ; G 1159 +U 1267 ; WX 652 ; N uni04F3 ; G 1160 +U 1268 ; WX 808 ; N uni04F4 ; G 1161 +U 1269 ; WX 687 ; N uni04F5 ; G 1162 +U 1270 ; WX 637 ; N uni04F6 ; G 1163 +U 1271 ; WX 522 ; N uni04F7 ; G 1164 +U 1272 ; WX 1036 ; N uni04F8 ; G 1165 +U 1273 ; WX 904 ; N uni04F9 ; G 1166 +U 1274 ; WX 666 ; N uni04FA ; G 1167 +U 1275 ; WX 543 ; N uni04FB ; G 1168 +U 1276 ; WX 771 ; N uni04FC ; G 1169 +U 1277 ; WX 645 ; N uni04FD ; G 1170 +U 1278 ; WX 771 ; N uni04FE ; G 1171 +U 1279 ; WX 645 ; N uni04FF ; G 1172 +U 1280 ; WX 762 ; N uni0500 ; G 1173 +U 1281 ; WX 608 ; N uni0501 ; G 1174 +U 1282 ; WX 1159 ; N uni0502 ; G 1175 +U 1283 ; WX 893 ; N uni0503 ; G 1176 +U 1284 ; WX 1119 ; N uni0504 ; G 1177 +U 1285 ; WX 920 ; N uni0505 ; G 1178 +U 1286 ; WX 828 ; N uni0506 ; G 1179 +U 1287 ; WX 693 ; N uni0507 ; G 1180 +U 1288 ; WX 1242 ; N uni0508 ; G 1181 +U 1289 ; WX 1017 ; N uni0509 ; G 1182 +U 1290 ; WX 1289 ; N uni050A ; G 1183 +U 1291 ; WX 1013 ; N uni050B ; G 1184 +U 1292 ; WX 839 ; N uni050C ; G 1185 +U 1293 ; WX 638 ; N uni050D ; G 1186 +U 1294 ; WX 938 ; N uni050E ; G 1187 +U 1295 ; WX 803 ; N uni050F ; G 1188 +U 1296 ; WX 696 ; N uni0510 ; G 1189 +U 1297 ; WX 557 ; N uni0511 ; G 1190 +U 1298 ; WX 831 ; N uni0512 ; G 1191 +U 1299 ; WX 732 ; N uni0513 ; G 1192 +U 1300 ; WX 1286 ; N uni0514 ; G 1193 +U 1301 ; WX 1068 ; N uni0515 ; G 1194 +U 1302 ; WX 1065 ; N uni0516 ; G 1195 +U 1303 ; WX 979 ; N uni0517 ; G 1196 +U 1304 ; WX 1082 ; N uni0518 ; G 1197 +U 1305 ; WX 1013 ; N uni0519 ; G 1198 +U 1306 ; WX 850 ; N uni051A ; G 1199 +U 1307 ; WX 716 ; N uni051B ; G 1200 +U 1308 ; WX 1103 ; N uni051C ; G 1201 +U 1309 ; WX 924 ; N uni051D ; G 1202 +U 1310 ; WX 817 ; N uni051E ; G 1203 +U 1311 ; WX 679 ; N uni051F ; G 1204 +U 1312 ; WX 1267 ; N uni0520 ; G 1205 +U 1313 ; WX 1059 ; N uni0521 ; G 1206 +U 1314 ; WX 1273 ; N uni0522 ; G 1207 +U 1315 ; WX 1017 ; N uni0523 ; G 1208 +U 1316 ; WX 957 ; N uni0524 ; G 1209 +U 1317 ; WX 807 ; N uni0525 ; G 1210 +U 1329 ; WX 813 ; N uni0531 ; G 1211 +U 1330 ; WX 729 ; N uni0532 ; G 1212 +U 1331 ; WX 728 ; N uni0533 ; G 1213 +U 1332 ; WX 731 ; N uni0534 ; G 1214 +U 1333 ; WX 729 ; N uni0535 ; G 1215 +U 1334 ; WX 733 ; N uni0536 ; G 1216 +U 1335 ; WX 652 ; N uni0537 ; G 1217 +U 1336 ; WX 720 ; N uni0538 ; G 1218 +U 1337 ; WX 903 ; N uni0539 ; G 1219 +U 1338 ; WX 728 ; N uni053A ; G 1220 +U 1339 ; WX 666 ; N uni053B ; G 1221 +U 1340 ; WX 558 ; N uni053C ; G 1222 +U 1341 ; WX 961 ; N uni053D ; G 1223 +U 1342 ; WX 788 ; N uni053E ; G 1224 +U 1343 ; WX 713 ; N uni053F ; G 1225 +U 1344 ; WX 651 ; N uni0540 ; G 1226 +U 1345 ; WX 730 ; N uni0541 ; G 1227 +U 1346 ; WX 715 ; N uni0542 ; G 1228 +U 1347 ; WX 704 ; N uni0543 ; G 1229 +U 1348 ; WX 780 ; N uni0544 ; G 1230 +U 1349 ; WX 689 ; N uni0545 ; G 1231 +U 1350 ; WX 715 ; N uni0546 ; G 1232 +U 1351 ; WX 708 ; N uni0547 ; G 1233 +U 1352 ; WX 731 ; N uni0548 ; G 1234 +U 1353 ; WX 677 ; N uni0549 ; G 1235 +U 1354 ; WX 867 ; N uni054A ; G 1236 +U 1355 ; WX 711 ; N uni054B ; G 1237 +U 1356 ; WX 780 ; N uni054C ; G 1238 +U 1357 ; WX 731 ; N uni054D ; G 1239 +U 1358 ; WX 715 ; N uni054E ; G 1240 +U 1359 ; WX 693 ; N uni054F ; G 1241 +U 1360 ; WX 666 ; N uni0550 ; G 1242 +U 1361 ; WX 698 ; N uni0551 ; G 1243 +U 1362 ; WX 576 ; N uni0552 ; G 1244 +U 1363 ; WX 833 ; N uni0553 ; G 1245 +U 1364 ; WX 698 ; N uni0554 ; G 1246 +U 1365 ; WX 763 ; N uni0555 ; G 1247 +U 1366 ; WX 855 ; N uni0556 ; G 1248 +U 1369 ; WX 330 ; N uni0559 ; G 1249 +U 1370 ; WX 342 ; N uni055A ; G 1250 +U 1371 ; WX 308 ; N uni055B ; G 1251 +U 1372 ; WX 374 ; N uni055C ; G 1252 +U 1373 ; WX 313 ; N uni055D ; G 1253 +U 1374 ; WX 461 ; N uni055E ; G 1254 +U 1375 ; WX 468 ; N uni055F ; G 1255 +U 1377 ; WX 938 ; N uni0561 ; G 1256 +U 1378 ; WX 642 ; N uni0562 ; G 1257 +U 1379 ; WX 704 ; N uni0563 ; G 1258 +U 1380 ; WX 708 ; N uni0564 ; G 1259 +U 1381 ; WX 642 ; N uni0565 ; G 1260 +U 1382 ; WX 644 ; N uni0566 ; G 1261 +U 1383 ; WX 565 ; N uni0567 ; G 1262 +U 1384 ; WX 642 ; N uni0568 ; G 1263 +U 1385 ; WX 756 ; N uni0569 ; G 1264 +U 1386 ; WX 704 ; N uni056A ; G 1265 +U 1387 ; WX 643 ; N uni056B ; G 1266 +U 1388 ; WX 310 ; N uni056C ; G 1267 +U 1389 ; WX 984 ; N uni056D ; G 1268 +U 1390 ; WX 638 ; N uni056E ; G 1269 +U 1391 ; WX 643 ; N uni056F ; G 1270 +U 1392 ; WX 643 ; N uni0570 ; G 1271 +U 1393 ; WX 603 ; N uni0571 ; G 1272 +U 1394 ; WX 643 ; N uni0572 ; G 1273 +U 1395 ; WX 642 ; N uni0573 ; G 1274 +U 1396 ; WX 643 ; N uni0574 ; G 1275 +U 1397 ; WX 309 ; N uni0575 ; G 1276 +U 1398 ; WX 643 ; N uni0576 ; G 1277 +U 1399 ; WX 486 ; N uni0577 ; G 1278 +U 1400 ; WX 643 ; N uni0578 ; G 1279 +U 1401 ; WX 366 ; N uni0579 ; G 1280 +U 1402 ; WX 938 ; N uni057A ; G 1281 +U 1403 ; WX 573 ; N uni057B ; G 1282 +U 1404 ; WX 666 ; N uni057C ; G 1283 +U 1405 ; WX 643 ; N uni057D ; G 1284 +U 1406 ; WX 643 ; N uni057E ; G 1285 +U 1407 ; WX 934 ; N uni057F ; G 1286 +U 1408 ; WX 643 ; N uni0580 ; G 1287 +U 1409 ; WX 643 ; N uni0581 ; G 1288 +U 1410 ; WX 479 ; N uni0582 ; G 1289 +U 1411 ; WX 934 ; N uni0583 ; G 1290 +U 1412 ; WX 648 ; N uni0584 ; G 1291 +U 1413 ; WX 620 ; N uni0585 ; G 1292 +U 1414 ; WX 813 ; N uni0586 ; G 1293 +U 1415 ; WX 812 ; N uni0587 ; G 1294 +U 1417 ; WX 360 ; N uni0589 ; G 1295 +U 1418 ; WX 374 ; N uni058A ; G 1296 +U 1456 ; WX 0 ; N uni05B0 ; G 1297 +U 1457 ; WX 0 ; N uni05B1 ; G 1298 +U 1458 ; WX 0 ; N uni05B2 ; G 1299 +U 1459 ; WX 0 ; N uni05B3 ; G 1300 +U 1460 ; WX 0 ; N uni05B4 ; G 1301 +U 1461 ; WX 0 ; N uni05B5 ; G 1302 +U 1462 ; WX 0 ; N uni05B6 ; G 1303 +U 1463 ; WX 0 ; N uni05B7 ; G 1304 +U 1464 ; WX 0 ; N uni05B8 ; G 1305 +U 1465 ; WX 0 ; N uni05B9 ; G 1306 +U 1466 ; WX 0 ; N uni05BA ; G 1307 +U 1467 ; WX 0 ; N uni05BB ; G 1308 +U 1468 ; WX 0 ; N uni05BC ; G 1309 +U 1469 ; WX 0 ; N uni05BD ; G 1310 +U 1470 ; WX 415 ; N uni05BE ; G 1311 +U 1471 ; WX 0 ; N uni05BF ; G 1312 +U 1472 ; WX 372 ; N uni05C0 ; G 1313 +U 1473 ; WX 0 ; N uni05C1 ; G 1314 +U 1474 ; WX 0 ; N uni05C2 ; G 1315 +U 1475 ; WX 372 ; N uni05C3 ; G 1316 +U 1478 ; WX 497 ; N uni05C6 ; G 1317 +U 1479 ; WX 0 ; N uni05C7 ; G 1318 +U 1488 ; WX 728 ; N uni05D0 ; G 1319 +U 1489 ; WX 610 ; N uni05D1 ; G 1320 +U 1490 ; WX 447 ; N uni05D2 ; G 1321 +U 1491 ; WX 588 ; N uni05D3 ; G 1322 +U 1492 ; WX 687 ; N uni05D4 ; G 1323 +U 1493 ; WX 343 ; N uni05D5 ; G 1324 +U 1494 ; WX 400 ; N uni05D6 ; G 1325 +U 1495 ; WX 687 ; N uni05D7 ; G 1326 +U 1496 ; WX 679 ; N uni05D8 ; G 1327 +U 1497 ; WX 294 ; N uni05D9 ; G 1328 +U 1498 ; WX 578 ; N uni05DA ; G 1329 +U 1499 ; WX 566 ; N uni05DB ; G 1330 +U 1500 ; WX 605 ; N uni05DC ; G 1331 +U 1501 ; WX 696 ; N uni05DD ; G 1332 +U 1502 ; WX 724 ; N uni05DE ; G 1333 +U 1503 ; WX 343 ; N uni05DF ; G 1334 +U 1504 ; WX 453 ; N uni05E0 ; G 1335 +U 1505 ; WX 680 ; N uni05E1 ; G 1336 +U 1506 ; WX 666 ; N uni05E2 ; G 1337 +U 1507 ; WX 675 ; N uni05E3 ; G 1338 +U 1508 ; WX 658 ; N uni05E4 ; G 1339 +U 1509 ; WX 661 ; N uni05E5 ; G 1340 +U 1510 ; WX 653 ; N uni05E6 ; G 1341 +U 1511 ; WX 736 ; N uni05E7 ; G 1342 +U 1512 ; WX 602 ; N uni05E8 ; G 1343 +U 1513 ; WX 758 ; N uni05E9 ; G 1344 +U 1514 ; WX 683 ; N uni05EA ; G 1345 +U 1520 ; WX 664 ; N uni05F0 ; G 1346 +U 1521 ; WX 567 ; N uni05F1 ; G 1347 +U 1522 ; WX 519 ; N uni05F2 ; G 1348 +U 1523 ; WX 444 ; N uni05F3 ; G 1349 +U 1524 ; WX 710 ; N uni05F4 ; G 1350 +U 1542 ; WX 667 ; N uni0606 ; G 1351 +U 1543 ; WX 667 ; N uni0607 ; G 1352 +U 1545 ; WX 884 ; N uni0609 ; G 1353 +U 1546 ; WX 1157 ; N uni060A ; G 1354 +U 1548 ; WX 380 ; N uni060C ; G 1355 +U 1557 ; WX 0 ; N uni0615 ; G 1356 +U 1563 ; WX 400 ; N uni061B ; G 1357 +U 1567 ; WX 580 ; N uni061F ; G 1358 +U 1569 ; WX 511 ; N uni0621 ; G 1359 +U 1570 ; WX 343 ; N uni0622 ; G 1360 +U 1571 ; WX 343 ; N uni0623 ; G 1361 +U 1572 ; WX 622 ; N uni0624 ; G 1362 +U 1573 ; WX 343 ; N uni0625 ; G 1363 +U 1574 ; WX 917 ; N uni0626 ; G 1364 +U 1575 ; WX 343 ; N uni0627 ; G 1365 +U 1576 ; WX 1005 ; N uni0628 ; G 1366 +U 1577 ; WX 590 ; N uni0629 ; G 1367 +U 1578 ; WX 1005 ; N uni062A ; G 1368 +U 1579 ; WX 1005 ; N uni062B ; G 1369 +U 1580 ; WX 721 ; N uni062C ; G 1370 +U 1581 ; WX 721 ; N uni062D ; G 1371 +U 1582 ; WX 721 ; N uni062E ; G 1372 +U 1583 ; WX 513 ; N uni062F ; G 1373 +U 1584 ; WX 513 ; N uni0630 ; G 1374 +U 1585 ; WX 576 ; N uni0631 ; G 1375 +U 1586 ; WX 576 ; N uni0632 ; G 1376 +U 1587 ; WX 1380 ; N uni0633 ; G 1377 +U 1588 ; WX 1380 ; N uni0634 ; G 1378 +U 1589 ; WX 1345 ; N uni0635 ; G 1379 +U 1590 ; WX 1345 ; N uni0636 ; G 1380 +U 1591 ; WX 1039 ; N uni0637 ; G 1381 +U 1592 ; WX 1039 ; N uni0638 ; G 1382 +U 1593 ; WX 683 ; N uni0639 ; G 1383 +U 1594 ; WX 683 ; N uni063A ; G 1384 +U 1600 ; WX 342 ; N uni0640 ; G 1385 +U 1601 ; WX 1162 ; N uni0641 ; G 1386 +U 1602 ; WX 894 ; N uni0642 ; G 1387 +U 1603 ; WX 917 ; N uni0643 ; G 1388 +U 1604 ; WX 868 ; N uni0644 ; G 1389 +U 1605 ; WX 733 ; N uni0645 ; G 1390 +U 1606 ; WX 854 ; N uni0646 ; G 1391 +U 1607 ; WX 590 ; N uni0647 ; G 1392 +U 1608 ; WX 622 ; N uni0648 ; G 1393 +U 1609 ; WX 917 ; N uni0649 ; G 1394 +U 1610 ; WX 917 ; N uni064A ; G 1395 +U 1611 ; WX 0 ; N uni064B ; G 1396 +U 1612 ; WX 0 ; N uni064C ; G 1397 +U 1613 ; WX 0 ; N uni064D ; G 1398 +U 1614 ; WX 0 ; N uni064E ; G 1399 +U 1615 ; WX 0 ; N uni064F ; G 1400 +U 1616 ; WX 0 ; N uni0650 ; G 1401 +U 1617 ; WX 0 ; N uni0651 ; G 1402 +U 1618 ; WX 0 ; N uni0652 ; G 1403 +U 1619 ; WX 0 ; N uni0653 ; G 1404 +U 1620 ; WX 0 ; N uni0654 ; G 1405 +U 1621 ; WX 0 ; N uni0655 ; G 1406 +U 1623 ; WX 0 ; N uni0657 ; G 1407 +U 1626 ; WX 500 ; N uni065A ; G 1408 +U 1632 ; WX 610 ; N uni0660 ; G 1409 +U 1633 ; WX 610 ; N uni0661 ; G 1410 +U 1634 ; WX 610 ; N uni0662 ; G 1411 +U 1635 ; WX 610 ; N uni0663 ; G 1412 +U 1636 ; WX 610 ; N uni0664 ; G 1413 +U 1637 ; WX 610 ; N uni0665 ; G 1414 +U 1638 ; WX 610 ; N uni0666 ; G 1415 +U 1639 ; WX 610 ; N uni0667 ; G 1416 +U 1640 ; WX 610 ; N uni0668 ; G 1417 +U 1641 ; WX 610 ; N uni0669 ; G 1418 +U 1642 ; WX 610 ; N uni066A ; G 1419 +U 1643 ; WX 374 ; N uni066B ; G 1420 +U 1644 ; WX 380 ; N uni066C ; G 1421 +U 1645 ; WX 545 ; N uni066D ; G 1422 +U 1646 ; WX 1005 ; N uni066E ; G 1423 +U 1647 ; WX 894 ; N uni066F ; G 1424 +U 1648 ; WX 0 ; N uni0670 ; G 1425 +U 1652 ; WX 292 ; N uni0674 ; G 1426 +U 1657 ; WX 1005 ; N uni0679 ; G 1427 +U 1658 ; WX 1005 ; N uni067A ; G 1428 +U 1659 ; WX 1005 ; N uni067B ; G 1429 +U 1660 ; WX 1005 ; N uni067C ; G 1430 +U 1661 ; WX 1005 ; N uni067D ; G 1431 +U 1662 ; WX 1005 ; N uni067E ; G 1432 +U 1663 ; WX 1005 ; N uni067F ; G 1433 +U 1664 ; WX 1005 ; N uni0680 ; G 1434 +U 1665 ; WX 721 ; N uni0681 ; G 1435 +U 1666 ; WX 721 ; N uni0682 ; G 1436 +U 1667 ; WX 721 ; N uni0683 ; G 1437 +U 1668 ; WX 721 ; N uni0684 ; G 1438 +U 1669 ; WX 721 ; N uni0685 ; G 1439 +U 1670 ; WX 721 ; N uni0686 ; G 1440 +U 1671 ; WX 721 ; N uni0687 ; G 1441 +U 1672 ; WX 445 ; N uni0688 ; G 1442 +U 1673 ; WX 445 ; N uni0689 ; G 1443 +U 1674 ; WX 445 ; N uni068A ; G 1444 +U 1675 ; WX 445 ; N uni068B ; G 1445 +U 1676 ; WX 445 ; N uni068C ; G 1446 +U 1677 ; WX 445 ; N uni068D ; G 1447 +U 1678 ; WX 445 ; N uni068E ; G 1448 +U 1679 ; WX 445 ; N uni068F ; G 1449 +U 1680 ; WX 445 ; N uni0690 ; G 1450 +U 1681 ; WX 576 ; N uni0691 ; G 1451 +U 1682 ; WX 576 ; N uni0692 ; G 1452 +U 1683 ; WX 576 ; N uni0693 ; G 1453 +U 1684 ; WX 576 ; N uni0694 ; G 1454 +U 1685 ; WX 681 ; N uni0695 ; G 1455 +U 1686 ; WX 576 ; N uni0696 ; G 1456 +U 1687 ; WX 576 ; N uni0697 ; G 1457 +U 1688 ; WX 576 ; N uni0698 ; G 1458 +U 1689 ; WX 576 ; N uni0699 ; G 1459 +U 1690 ; WX 1380 ; N uni069A ; G 1460 +U 1691 ; WX 1380 ; N uni069B ; G 1461 +U 1692 ; WX 1380 ; N uni069C ; G 1462 +U 1693 ; WX 1345 ; N uni069D ; G 1463 +U 1694 ; WX 1345 ; N uni069E ; G 1464 +U 1695 ; WX 1039 ; N uni069F ; G 1465 +U 1696 ; WX 683 ; N uni06A0 ; G 1466 +U 1697 ; WX 1162 ; N uni06A1 ; G 1467 +U 1698 ; WX 1162 ; N uni06A2 ; G 1468 +U 1699 ; WX 1162 ; N uni06A3 ; G 1469 +U 1700 ; WX 1162 ; N uni06A4 ; G 1470 +U 1701 ; WX 1162 ; N uni06A5 ; G 1471 +U 1702 ; WX 1162 ; N uni06A6 ; G 1472 +U 1703 ; WX 894 ; N uni06A7 ; G 1473 +U 1704 ; WX 894 ; N uni06A8 ; G 1474 +U 1705 ; WX 1024 ; N uni06A9 ; G 1475 +U 1706 ; WX 1271 ; N uni06AA ; G 1476 +U 1707 ; WX 1024 ; N uni06AB ; G 1477 +U 1708 ; WX 917 ; N uni06AC ; G 1478 +U 1709 ; WX 917 ; N uni06AD ; G 1479 +U 1710 ; WX 917 ; N uni06AE ; G 1480 +U 1711 ; WX 1024 ; N uni06AF ; G 1481 +U 1712 ; WX 1024 ; N uni06B0 ; G 1482 +U 1713 ; WX 1024 ; N uni06B1 ; G 1483 +U 1714 ; WX 1024 ; N uni06B2 ; G 1484 +U 1715 ; WX 1024 ; N uni06B3 ; G 1485 +U 1716 ; WX 1024 ; N uni06B4 ; G 1486 +U 1717 ; WX 868 ; N uni06B5 ; G 1487 +U 1718 ; WX 868 ; N uni06B6 ; G 1488 +U 1719 ; WX 868 ; N uni06B7 ; G 1489 +U 1720 ; WX 868 ; N uni06B8 ; G 1490 +U 1721 ; WX 854 ; N uni06B9 ; G 1491 +U 1722 ; WX 854 ; N uni06BA ; G 1492 +U 1723 ; WX 854 ; N uni06BB ; G 1493 +U 1724 ; WX 854 ; N uni06BC ; G 1494 +U 1725 ; WX 854 ; N uni06BD ; G 1495 +U 1726 ; WX 938 ; N uni06BE ; G 1496 +U 1727 ; WX 721 ; N uni06BF ; G 1497 +U 1734 ; WX 622 ; N uni06C6 ; G 1498 +U 1735 ; WX 622 ; N uni06C7 ; G 1499 +U 1736 ; WX 622 ; N uni06C8 ; G 1500 +U 1739 ; WX 622 ; N uni06CB ; G 1501 +U 1740 ; WX 917 ; N uni06CC ; G 1502 +U 1742 ; WX 917 ; N uni06CE ; G 1503 +U 1744 ; WX 917 ; N uni06D0 ; G 1504 +U 1749 ; WX 590 ; N uni06D5 ; G 1505 +U 1776 ; WX 610 ; N uni06F0 ; G 1506 +U 1777 ; WX 610 ; N uni06F1 ; G 1507 +U 1778 ; WX 610 ; N uni06F2 ; G 1508 +U 1779 ; WX 610 ; N uni06F3 ; G 1509 +U 1780 ; WX 610 ; N uni06F4 ; G 1510 +U 1781 ; WX 610 ; N uni06F5 ; G 1511 +U 1782 ; WX 610 ; N uni06F6 ; G 1512 +U 1783 ; WX 610 ; N uni06F7 ; G 1513 +U 1784 ; WX 610 ; N uni06F8 ; G 1514 +U 1785 ; WX 610 ; N uni06F9 ; G 1515 +U 1984 ; WX 696 ; N uni07C0 ; G 1516 +U 1985 ; WX 696 ; N uni07C1 ; G 1517 +U 1986 ; WX 696 ; N uni07C2 ; G 1518 +U 1987 ; WX 696 ; N uni07C3 ; G 1519 +U 1988 ; WX 696 ; N uni07C4 ; G 1520 +U 1989 ; WX 696 ; N uni07C5 ; G 1521 +U 1990 ; WX 696 ; N uni07C6 ; G 1522 +U 1991 ; WX 696 ; N uni07C7 ; G 1523 +U 1992 ; WX 696 ; N uni07C8 ; G 1524 +U 1993 ; WX 696 ; N uni07C9 ; G 1525 +U 1994 ; WX 343 ; N uni07CA ; G 1526 +U 1995 ; WX 547 ; N uni07CB ; G 1527 +U 1996 ; WX 543 ; N uni07CC ; G 1528 +U 1997 ; WX 652 ; N uni07CD ; G 1529 +U 1998 ; WX 691 ; N uni07CE ; G 1530 +U 1999 ; WX 691 ; N uni07CF ; G 1531 +U 2000 ; WX 594 ; N uni07D0 ; G 1532 +U 2001 ; WX 691 ; N uni07D1 ; G 1533 +U 2002 ; WX 904 ; N uni07D2 ; G 1534 +U 2003 ; WX 551 ; N uni07D3 ; G 1535 +U 2004 ; WX 551 ; N uni07D4 ; G 1536 +U 2005 ; WX 627 ; N uni07D5 ; G 1537 +U 2006 ; WX 688 ; N uni07D6 ; G 1538 +U 2007 ; WX 444 ; N uni07D7 ; G 1539 +U 2008 ; WX 1022 ; N uni07D8 ; G 1540 +U 2009 ; WX 506 ; N uni07D9 ; G 1541 +U 2010 ; WX 826 ; N uni07DA ; G 1542 +U 2011 ; WX 691 ; N uni07DB ; G 1543 +U 2012 ; WX 652 ; N uni07DC ; G 1544 +U 2013 ; WX 912 ; N uni07DD ; G 1545 +U 2014 ; WX 627 ; N uni07DE ; G 1546 +U 2015 ; WX 707 ; N uni07DF ; G 1547 +U 2016 ; WX 506 ; N uni07E0 ; G 1548 +U 2017 ; WX 652 ; N uni07E1 ; G 1549 +U 2018 ; WX 574 ; N uni07E2 ; G 1550 +U 2019 ; WX 627 ; N uni07E3 ; G 1551 +U 2020 ; WX 627 ; N uni07E4 ; G 1552 +U 2021 ; WX 627 ; N uni07E5 ; G 1553 +U 2022 ; WX 574 ; N uni07E6 ; G 1554 +U 2023 ; WX 574 ; N uni07E7 ; G 1555 +U 2027 ; WX 0 ; N uni07EB ; G 1556 +U 2028 ; WX 0 ; N uni07EC ; G 1557 +U 2029 ; WX 0 ; N uni07ED ; G 1558 +U 2030 ; WX 0 ; N uni07EE ; G 1559 +U 2031 ; WX 0 ; N uni07EF ; G 1560 +U 2032 ; WX 0 ; N uni07F0 ; G 1561 +U 2033 ; WX 0 ; N uni07F1 ; G 1562 +U 2034 ; WX 0 ; N uni07F2 ; G 1563 +U 2035 ; WX 0 ; N uni07F3 ; G 1564 +U 2036 ; WX 380 ; N uni07F4 ; G 1565 +U 2037 ; WX 380 ; N uni07F5 ; G 1566 +U 2040 ; WX 691 ; N uni07F8 ; G 1567 +U 2041 ; WX 691 ; N uni07F9 ; G 1568 +U 2042 ; WX 415 ; N uni07FA ; G 1569 +U 3647 ; WX 696 ; N uni0E3F ; G 1570 +U 3713 ; WX 790 ; N uni0E81 ; G 1571 +U 3714 ; WX 748 ; N uni0E82 ; G 1572 +U 3716 ; WX 749 ; N uni0E84 ; G 1573 +U 3719 ; WX 569 ; N uni0E87 ; G 1574 +U 3720 ; WX 742 ; N uni0E88 ; G 1575 +U 3722 ; WX 744 ; N uni0E8A ; G 1576 +U 3725 ; WX 761 ; N uni0E8D ; G 1577 +U 3732 ; WX 706 ; N uni0E94 ; G 1578 +U 3733 ; WX 704 ; N uni0E95 ; G 1579 +U 3734 ; WX 747 ; N uni0E96 ; G 1580 +U 3735 ; WX 819 ; N uni0E97 ; G 1581 +U 3737 ; WX 730 ; N uni0E99 ; G 1582 +U 3738 ; WX 727 ; N uni0E9A ; G 1583 +U 3739 ; WX 727 ; N uni0E9B ; G 1584 +U 3740 ; WX 922 ; N uni0E9C ; G 1585 +U 3741 ; WX 827 ; N uni0E9D ; G 1586 +U 3742 ; WX 866 ; N uni0E9E ; G 1587 +U 3743 ; WX 866 ; N uni0E9F ; G 1588 +U 3745 ; WX 836 ; N uni0EA1 ; G 1589 +U 3746 ; WX 761 ; N uni0EA2 ; G 1590 +U 3747 ; WX 770 ; N uni0EA3 ; G 1591 +U 3749 ; WX 769 ; N uni0EA5 ; G 1592 +U 3751 ; WX 713 ; N uni0EA7 ; G 1593 +U 3754 ; WX 827 ; N uni0EAA ; G 1594 +U 3755 ; WX 1031 ; N uni0EAB ; G 1595 +U 3757 ; WX 724 ; N uni0EAD ; G 1596 +U 3758 ; WX 784 ; N uni0EAE ; G 1597 +U 3759 ; WX 934 ; N uni0EAF ; G 1598 +U 3760 ; WX 688 ; N uni0EB0 ; G 1599 +U 3761 ; WX 0 ; N uni0EB1 ; G 1600 +U 3762 ; WX 610 ; N uni0EB2 ; G 1601 +U 3763 ; WX 610 ; N uni0EB3 ; G 1602 +U 3764 ; WX 0 ; N uni0EB4 ; G 1603 +U 3765 ; WX 0 ; N uni0EB5 ; G 1604 +U 3766 ; WX 0 ; N uni0EB6 ; G 1605 +U 3767 ; WX 0 ; N uni0EB7 ; G 1606 +U 3768 ; WX 0 ; N uni0EB8 ; G 1607 +U 3769 ; WX 0 ; N uni0EB9 ; G 1608 +U 3771 ; WX 0 ; N uni0EBB ; G 1609 +U 3772 ; WX 0 ; N uni0EBC ; G 1610 +U 3773 ; WX 670 ; N uni0EBD ; G 1611 +U 3776 ; WX 516 ; N uni0EC0 ; G 1612 +U 3777 ; WX 860 ; N uni0EC1 ; G 1613 +U 3778 ; WX 516 ; N uni0EC2 ; G 1614 +U 3779 ; WX 650 ; N uni0EC3 ; G 1615 +U 3780 ; WX 632 ; N uni0EC4 ; G 1616 +U 3782 ; WX 759 ; N uni0EC6 ; G 1617 +U 3784 ; WX 0 ; N uni0EC8 ; G 1618 +U 3785 ; WX 0 ; N uni0EC9 ; G 1619 +U 3786 ; WX 0 ; N uni0ECA ; G 1620 +U 3787 ; WX 0 ; N uni0ECB ; G 1621 +U 3788 ; WX 0 ; N uni0ECC ; G 1622 +U 3789 ; WX 0 ; N uni0ECD ; G 1623 +U 3792 ; WX 771 ; N uni0ED0 ; G 1624 +U 3793 ; WX 771 ; N uni0ED1 ; G 1625 +U 3794 ; WX 693 ; N uni0ED2 ; G 1626 +U 3795 ; WX 836 ; N uni0ED3 ; G 1627 +U 3796 ; WX 729 ; N uni0ED4 ; G 1628 +U 3797 ; WX 729 ; N uni0ED5 ; G 1629 +U 3798 ; WX 849 ; N uni0ED6 ; G 1630 +U 3799 ; WX 790 ; N uni0ED7 ; G 1631 +U 3800 ; WX 759 ; N uni0ED8 ; G 1632 +U 3801 ; WX 910 ; N uni0ED9 ; G 1633 +U 3804 ; WX 1363 ; N uni0EDC ; G 1634 +U 3805 ; WX 1363 ; N uni0EDD ; G 1635 +U 4256 ; WX 874 ; N uni10A0 ; G 1636 +U 4257 ; WX 733 ; N uni10A1 ; G 1637 +U 4258 ; WX 679 ; N uni10A2 ; G 1638 +U 4259 ; WX 834 ; N uni10A3 ; G 1639 +U 4260 ; WX 615 ; N uni10A4 ; G 1640 +U 4261 ; WX 768 ; N uni10A5 ; G 1641 +U 4262 ; WX 753 ; N uni10A6 ; G 1642 +U 4263 ; WX 914 ; N uni10A7 ; G 1643 +U 4264 ; WX 453 ; N uni10A8 ; G 1644 +U 4265 ; WX 620 ; N uni10A9 ; G 1645 +U 4266 ; WX 843 ; N uni10AA ; G 1646 +U 4267 ; WX 882 ; N uni10AB ; G 1647 +U 4268 ; WX 625 ; N uni10AC ; G 1648 +U 4269 ; WX 854 ; N uni10AD ; G 1649 +U 4270 ; WX 781 ; N uni10AE ; G 1650 +U 4271 ; WX 629 ; N uni10AF ; G 1651 +U 4272 ; WX 912 ; N uni10B0 ; G 1652 +U 4273 ; WX 621 ; N uni10B1 ; G 1653 +U 4274 ; WX 620 ; N uni10B2 ; G 1654 +U 4275 ; WX 854 ; N uni10B3 ; G 1655 +U 4276 ; WX 866 ; N uni10B4 ; G 1656 +U 4277 ; WX 724 ; N uni10B5 ; G 1657 +U 4278 ; WX 630 ; N uni10B6 ; G 1658 +U 4279 ; WX 621 ; N uni10B7 ; G 1659 +U 4280 ; WX 625 ; N uni10B8 ; G 1660 +U 4281 ; WX 620 ; N uni10B9 ; G 1661 +U 4282 ; WX 818 ; N uni10BA ; G 1662 +U 4283 ; WX 874 ; N uni10BB ; G 1663 +U 4284 ; WX 615 ; N uni10BC ; G 1664 +U 4285 ; WX 623 ; N uni10BD ; G 1665 +U 4286 ; WX 625 ; N uni10BE ; G 1666 +U 4287 ; WX 725 ; N uni10BF ; G 1667 +U 4288 ; WX 844 ; N uni10C0 ; G 1668 +U 4289 ; WX 596 ; N uni10C1 ; G 1669 +U 4290 ; WX 688 ; N uni10C2 ; G 1670 +U 4291 ; WX 596 ; N uni10C3 ; G 1671 +U 4292 ; WX 594 ; N uni10C4 ; G 1672 +U 4293 ; WX 738 ; N uni10C5 ; G 1673 +U 4304 ; WX 554 ; N uni10D0 ; G 1674 +U 4305 ; WX 563 ; N uni10D1 ; G 1675 +U 4306 ; WX 622 ; N uni10D2 ; G 1676 +U 4307 ; WX 834 ; N uni10D3 ; G 1677 +U 4308 ; WX 555 ; N uni10D4 ; G 1678 +U 4309 ; WX 564 ; N uni10D5 ; G 1679 +U 4310 ; WX 551 ; N uni10D6 ; G 1680 +U 4311 ; WX 828 ; N uni10D7 ; G 1681 +U 4312 ; WX 563 ; N uni10D8 ; G 1682 +U 4313 ; WX 556 ; N uni10D9 ; G 1683 +U 4314 ; WX 1074 ; N uni10DA ; G 1684 +U 4315 ; WX 568 ; N uni10DB ; G 1685 +U 4316 ; WX 568 ; N uni10DC ; G 1686 +U 4317 ; WX 814 ; N uni10DD ; G 1687 +U 4318 ; WX 554 ; N uni10DE ; G 1688 +U 4319 ; WX 563 ; N uni10DF ; G 1689 +U 4320 ; WX 823 ; N uni10E0 ; G 1690 +U 4321 ; WX 568 ; N uni10E1 ; G 1691 +U 4322 ; WX 700 ; N uni10E2 ; G 1692 +U 4323 ; WX 591 ; N uni10E3 ; G 1693 +U 4324 ; WX 852 ; N uni10E4 ; G 1694 +U 4325 ; WX 560 ; N uni10E5 ; G 1695 +U 4326 ; WX 814 ; N uni10E6 ; G 1696 +U 4327 ; WX 563 ; N uni10E7 ; G 1697 +U 4328 ; WX 553 ; N uni10E8 ; G 1698 +U 4329 ; WX 568 ; N uni10E9 ; G 1699 +U 4330 ; WX 622 ; N uni10EA ; G 1700 +U 4331 ; WX 568 ; N uni10EB ; G 1701 +U 4332 ; WX 553 ; N uni10EC ; G 1702 +U 4333 ; WX 566 ; N uni10ED ; G 1703 +U 4334 ; WX 568 ; N uni10EE ; G 1704 +U 4335 ; WX 540 ; N uni10EF ; G 1705 +U 4336 ; WX 554 ; N uni10F0 ; G 1706 +U 4337 ; WX 559 ; N uni10F1 ; G 1707 +U 4338 ; WX 553 ; N uni10F2 ; G 1708 +U 4339 ; WX 554 ; N uni10F3 ; G 1709 +U 4340 ; WX 553 ; N uni10F4 ; G 1710 +U 4341 ; WX 587 ; N uni10F5 ; G 1711 +U 4342 ; WX 853 ; N uni10F6 ; G 1712 +U 4343 ; WX 604 ; N uni10F7 ; G 1713 +U 4344 ; WX 563 ; N uni10F8 ; G 1714 +U 4345 ; WX 622 ; N uni10F9 ; G 1715 +U 4346 ; WX 554 ; N uni10FA ; G 1716 +U 4347 ; WX 448 ; N uni10FB ; G 1717 +U 4348 ; WX 324 ; N uni10FC ; G 1718 +U 5121 ; WX 774 ; N uni1401 ; G 1719 +U 5122 ; WX 774 ; N uni1402 ; G 1720 +U 5123 ; WX 774 ; N uni1403 ; G 1721 +U 5124 ; WX 774 ; N uni1404 ; G 1722 +U 5125 ; WX 905 ; N uni1405 ; G 1723 +U 5126 ; WX 905 ; N uni1406 ; G 1724 +U 5127 ; WX 905 ; N uni1407 ; G 1725 +U 5129 ; WX 905 ; N uni1409 ; G 1726 +U 5130 ; WX 905 ; N uni140A ; G 1727 +U 5131 ; WX 905 ; N uni140B ; G 1728 +U 5132 ; WX 1018 ; N uni140C ; G 1729 +U 5133 ; WX 1009 ; N uni140D ; G 1730 +U 5134 ; WX 1018 ; N uni140E ; G 1731 +U 5135 ; WX 1009 ; N uni140F ; G 1732 +U 5136 ; WX 1018 ; N uni1410 ; G 1733 +U 5137 ; WX 1009 ; N uni1411 ; G 1734 +U 5138 ; WX 1149 ; N uni1412 ; G 1735 +U 5139 ; WX 1140 ; N uni1413 ; G 1736 +U 5140 ; WX 1149 ; N uni1414 ; G 1737 +U 5141 ; WX 1140 ; N uni1415 ; G 1738 +U 5142 ; WX 905 ; N uni1416 ; G 1739 +U 5143 ; WX 1149 ; N uni1417 ; G 1740 +U 5144 ; WX 1142 ; N uni1418 ; G 1741 +U 5145 ; WX 1149 ; N uni1419 ; G 1742 +U 5146 ; WX 1142 ; N uni141A ; G 1743 +U 5147 ; WX 905 ; N uni141B ; G 1744 +U 5149 ; WX 310 ; N uni141D ; G 1745 +U 5150 ; WX 529 ; N uni141E ; G 1746 +U 5151 ; WX 425 ; N uni141F ; G 1747 +U 5152 ; WX 425 ; N uni1420 ; G 1748 +U 5153 ; WX 395 ; N uni1421 ; G 1749 +U 5154 ; WX 395 ; N uni1422 ; G 1750 +U 5155 ; WX 395 ; N uni1423 ; G 1751 +U 5156 ; WX 395 ; N uni1424 ; G 1752 +U 5157 ; WX 564 ; N uni1425 ; G 1753 +U 5158 ; WX 470 ; N uni1426 ; G 1754 +U 5159 ; WX 310 ; N uni1427 ; G 1755 +U 5160 ; WX 395 ; N uni1428 ; G 1756 +U 5161 ; WX 395 ; N uni1429 ; G 1757 +U 5162 ; WX 395 ; N uni142A ; G 1758 +U 5163 ; WX 1213 ; N uni142B ; G 1759 +U 5164 ; WX 986 ; N uni142C ; G 1760 +U 5165 ; WX 1216 ; N uni142D ; G 1761 +U 5166 ; WX 1297 ; N uni142E ; G 1762 +U 5167 ; WX 774 ; N uni142F ; G 1763 +U 5168 ; WX 774 ; N uni1430 ; G 1764 +U 5169 ; WX 774 ; N uni1431 ; G 1765 +U 5170 ; WX 774 ; N uni1432 ; G 1766 +U 5171 ; WX 886 ; N uni1433 ; G 1767 +U 5172 ; WX 886 ; N uni1434 ; G 1768 +U 5173 ; WX 886 ; N uni1435 ; G 1769 +U 5175 ; WX 886 ; N uni1437 ; G 1770 +U 5176 ; WX 886 ; N uni1438 ; G 1771 +U 5177 ; WX 886 ; N uni1439 ; G 1772 +U 5178 ; WX 1018 ; N uni143A ; G 1773 +U 5179 ; WX 1009 ; N uni143B ; G 1774 +U 5180 ; WX 1018 ; N uni143C ; G 1775 +U 5181 ; WX 1009 ; N uni143D ; G 1776 +U 5182 ; WX 1018 ; N uni143E ; G 1777 +U 5183 ; WX 1009 ; N uni143F ; G 1778 +U 5184 ; WX 1149 ; N uni1440 ; G 1779 +U 5185 ; WX 1140 ; N uni1441 ; G 1780 +U 5186 ; WX 1149 ; N uni1442 ; G 1781 +U 5187 ; WX 1140 ; N uni1443 ; G 1782 +U 5188 ; WX 1149 ; N uni1444 ; G 1783 +U 5189 ; WX 1142 ; N uni1445 ; G 1784 +U 5190 ; WX 1149 ; N uni1446 ; G 1785 +U 5191 ; WX 1142 ; N uni1447 ; G 1786 +U 5192 ; WX 886 ; N uni1448 ; G 1787 +U 5193 ; WX 576 ; N uni1449 ; G 1788 +U 5194 ; WX 229 ; N uni144A ; G 1789 +U 5196 ; WX 812 ; N uni144C ; G 1790 +U 5197 ; WX 812 ; N uni144D ; G 1791 +U 5198 ; WX 812 ; N uni144E ; G 1792 +U 5199 ; WX 812 ; N uni144F ; G 1793 +U 5200 ; WX 815 ; N uni1450 ; G 1794 +U 5201 ; WX 815 ; N uni1451 ; G 1795 +U 5202 ; WX 815 ; N uni1452 ; G 1796 +U 5204 ; WX 815 ; N uni1454 ; G 1797 +U 5205 ; WX 815 ; N uni1455 ; G 1798 +U 5206 ; WX 815 ; N uni1456 ; G 1799 +U 5207 ; WX 1056 ; N uni1457 ; G 1800 +U 5208 ; WX 1048 ; N uni1458 ; G 1801 +U 5209 ; WX 1056 ; N uni1459 ; G 1802 +U 5210 ; WX 1048 ; N uni145A ; G 1803 +U 5211 ; WX 1056 ; N uni145B ; G 1804 +U 5212 ; WX 1048 ; N uni145C ; G 1805 +U 5213 ; WX 1060 ; N uni145D ; G 1806 +U 5214 ; WX 1054 ; N uni145E ; G 1807 +U 5215 ; WX 1060 ; N uni145F ; G 1808 +U 5216 ; WX 1054 ; N uni1460 ; G 1809 +U 5217 ; WX 1060 ; N uni1461 ; G 1810 +U 5218 ; WX 1052 ; N uni1462 ; G 1811 +U 5219 ; WX 1060 ; N uni1463 ; G 1812 +U 5220 ; WX 1052 ; N uni1464 ; G 1813 +U 5221 ; WX 1060 ; N uni1465 ; G 1814 +U 5222 ; WX 483 ; N uni1466 ; G 1815 +U 5223 ; WX 1005 ; N uni1467 ; G 1816 +U 5224 ; WX 1005 ; N uni1468 ; G 1817 +U 5225 ; WX 1023 ; N uni1469 ; G 1818 +U 5226 ; WX 1017 ; N uni146A ; G 1819 +U 5227 ; WX 743 ; N uni146B ; G 1820 +U 5228 ; WX 743 ; N uni146C ; G 1821 +U 5229 ; WX 743 ; N uni146D ; G 1822 +U 5230 ; WX 743 ; N uni146E ; G 1823 +U 5231 ; WX 743 ; N uni146F ; G 1824 +U 5232 ; WX 743 ; N uni1470 ; G 1825 +U 5233 ; WX 743 ; N uni1471 ; G 1826 +U 5234 ; WX 743 ; N uni1472 ; G 1827 +U 5235 ; WX 743 ; N uni1473 ; G 1828 +U 5236 ; WX 1029 ; N uni1474 ; G 1829 +U 5237 ; WX 975 ; N uni1475 ; G 1830 +U 5238 ; WX 980 ; N uni1476 ; G 1831 +U 5239 ; WX 975 ; N uni1477 ; G 1832 +U 5240 ; WX 980 ; N uni1478 ; G 1833 +U 5241 ; WX 975 ; N uni1479 ; G 1834 +U 5242 ; WX 1029 ; N uni147A ; G 1835 +U 5243 ; WX 975 ; N uni147B ; G 1836 +U 5244 ; WX 1029 ; N uni147C ; G 1837 +U 5245 ; WX 975 ; N uni147D ; G 1838 +U 5246 ; WX 980 ; N uni147E ; G 1839 +U 5247 ; WX 975 ; N uni147F ; G 1840 +U 5248 ; WX 980 ; N uni1480 ; G 1841 +U 5249 ; WX 975 ; N uni1481 ; G 1842 +U 5250 ; WX 980 ; N uni1482 ; G 1843 +U 5251 ; WX 501 ; N uni1483 ; G 1844 +U 5252 ; WX 501 ; N uni1484 ; G 1845 +U 5253 ; WX 938 ; N uni1485 ; G 1846 +U 5254 ; WX 938 ; N uni1486 ; G 1847 +U 5255 ; WX 938 ; N uni1487 ; G 1848 +U 5256 ; WX 938 ; N uni1488 ; G 1849 +U 5257 ; WX 743 ; N uni1489 ; G 1850 +U 5258 ; WX 743 ; N uni148A ; G 1851 +U 5259 ; WX 743 ; N uni148B ; G 1852 +U 5260 ; WX 743 ; N uni148C ; G 1853 +U 5261 ; WX 743 ; N uni148D ; G 1854 +U 5262 ; WX 743 ; N uni148E ; G 1855 +U 5263 ; WX 743 ; N uni148F ; G 1856 +U 5264 ; WX 743 ; N uni1490 ; G 1857 +U 5265 ; WX 743 ; N uni1491 ; G 1858 +U 5266 ; WX 1029 ; N uni1492 ; G 1859 +U 5267 ; WX 975 ; N uni1493 ; G 1860 +U 5268 ; WX 1029 ; N uni1494 ; G 1861 +U 5269 ; WX 975 ; N uni1495 ; G 1862 +U 5270 ; WX 1029 ; N uni1496 ; G 1863 +U 5271 ; WX 975 ; N uni1497 ; G 1864 +U 5272 ; WX 1029 ; N uni1498 ; G 1865 +U 5273 ; WX 975 ; N uni1499 ; G 1866 +U 5274 ; WX 1029 ; N uni149A ; G 1867 +U 5275 ; WX 975 ; N uni149B ; G 1868 +U 5276 ; WX 1029 ; N uni149C ; G 1869 +U 5277 ; WX 975 ; N uni149D ; G 1870 +U 5278 ; WX 1029 ; N uni149E ; G 1871 +U 5279 ; WX 975 ; N uni149F ; G 1872 +U 5280 ; WX 1029 ; N uni14A0 ; G 1873 +U 5281 ; WX 501 ; N uni14A1 ; G 1874 +U 5282 ; WX 501 ; N uni14A2 ; G 1875 +U 5283 ; WX 626 ; N uni14A3 ; G 1876 +U 5284 ; WX 626 ; N uni14A4 ; G 1877 +U 5285 ; WX 626 ; N uni14A5 ; G 1878 +U 5286 ; WX 626 ; N uni14A6 ; G 1879 +U 5287 ; WX 626 ; N uni14A7 ; G 1880 +U 5288 ; WX 626 ; N uni14A8 ; G 1881 +U 5289 ; WX 626 ; N uni14A9 ; G 1882 +U 5290 ; WX 626 ; N uni14AA ; G 1883 +U 5291 ; WX 626 ; N uni14AB ; G 1884 +U 5292 ; WX 881 ; N uni14AC ; G 1885 +U 5293 ; WX 854 ; N uni14AD ; G 1886 +U 5294 ; WX 863 ; N uni14AE ; G 1887 +U 5295 ; WX 874 ; N uni14AF ; G 1888 +U 5296 ; WX 863 ; N uni14B0 ; G 1889 +U 5297 ; WX 874 ; N uni14B1 ; G 1890 +U 5298 ; WX 881 ; N uni14B2 ; G 1891 +U 5299 ; WX 874 ; N uni14B3 ; G 1892 +U 5300 ; WX 881 ; N uni14B4 ; G 1893 +U 5301 ; WX 874 ; N uni14B5 ; G 1894 +U 5302 ; WX 863 ; N uni14B6 ; G 1895 +U 5303 ; WX 874 ; N uni14B7 ; G 1896 +U 5304 ; WX 863 ; N uni14B8 ; G 1897 +U 5305 ; WX 874 ; N uni14B9 ; G 1898 +U 5306 ; WX 863 ; N uni14BA ; G 1899 +U 5307 ; WX 436 ; N uni14BB ; G 1900 +U 5308 ; WX 548 ; N uni14BC ; G 1901 +U 5309 ; WX 436 ; N uni14BD ; G 1902 +U 5312 ; WX 988 ; N uni14C0 ; G 1903 +U 5313 ; WX 988 ; N uni14C1 ; G 1904 +U 5314 ; WX 988 ; N uni14C2 ; G 1905 +U 5315 ; WX 988 ; N uni14C3 ; G 1906 +U 5316 ; WX 931 ; N uni14C4 ; G 1907 +U 5317 ; WX 931 ; N uni14C5 ; G 1908 +U 5318 ; WX 931 ; N uni14C6 ; G 1909 +U 5319 ; WX 931 ; N uni14C7 ; G 1910 +U 5320 ; WX 931 ; N uni14C8 ; G 1911 +U 5321 ; WX 1238 ; N uni14C9 ; G 1912 +U 5322 ; WX 1247 ; N uni14CA ; G 1913 +U 5323 ; WX 1200 ; N uni14CB ; G 1914 +U 5324 ; WX 1228 ; N uni14CC ; G 1915 +U 5325 ; WX 1200 ; N uni14CD ; G 1916 +U 5326 ; WX 1228 ; N uni14CE ; G 1917 +U 5327 ; WX 931 ; N uni14CF ; G 1918 +U 5328 ; WX 660 ; N uni14D0 ; G 1919 +U 5329 ; WX 497 ; N uni14D1 ; G 1920 +U 5330 ; WX 660 ; N uni14D2 ; G 1921 +U 5331 ; WX 988 ; N uni14D3 ; G 1922 +U 5332 ; WX 988 ; N uni14D4 ; G 1923 +U 5333 ; WX 988 ; N uni14D5 ; G 1924 +U 5334 ; WX 988 ; N uni14D6 ; G 1925 +U 5335 ; WX 931 ; N uni14D7 ; G 1926 +U 5336 ; WX 931 ; N uni14D8 ; G 1927 +U 5337 ; WX 931 ; N uni14D9 ; G 1928 +U 5338 ; WX 931 ; N uni14DA ; G 1929 +U 5339 ; WX 931 ; N uni14DB ; G 1930 +U 5340 ; WX 1231 ; N uni14DC ; G 1931 +U 5341 ; WX 1247 ; N uni14DD ; G 1932 +U 5342 ; WX 1283 ; N uni14DE ; G 1933 +U 5343 ; WX 1228 ; N uni14DF ; G 1934 +U 5344 ; WX 1283 ; N uni14E0 ; G 1935 +U 5345 ; WX 1228 ; N uni14E1 ; G 1936 +U 5346 ; WX 1228 ; N uni14E2 ; G 1937 +U 5347 ; WX 1214 ; N uni14E3 ; G 1938 +U 5348 ; WX 1228 ; N uni14E4 ; G 1939 +U 5349 ; WX 1214 ; N uni14E5 ; G 1940 +U 5350 ; WX 1283 ; N uni14E6 ; G 1941 +U 5351 ; WX 1228 ; N uni14E7 ; G 1942 +U 5352 ; WX 1283 ; N uni14E8 ; G 1943 +U 5353 ; WX 1228 ; N uni14E9 ; G 1944 +U 5354 ; WX 660 ; N uni14EA ; G 1945 +U 5356 ; WX 886 ; N uni14EC ; G 1946 +U 5357 ; WX 730 ; N uni14ED ; G 1947 +U 5358 ; WX 730 ; N uni14EE ; G 1948 +U 5359 ; WX 730 ; N uni14EF ; G 1949 +U 5360 ; WX 730 ; N uni14F0 ; G 1950 +U 5361 ; WX 730 ; N uni14F1 ; G 1951 +U 5362 ; WX 730 ; N uni14F2 ; G 1952 +U 5363 ; WX 730 ; N uni14F3 ; G 1953 +U 5364 ; WX 730 ; N uni14F4 ; G 1954 +U 5365 ; WX 730 ; N uni14F5 ; G 1955 +U 5366 ; WX 998 ; N uni14F6 ; G 1956 +U 5367 ; WX 958 ; N uni14F7 ; G 1957 +U 5368 ; WX 967 ; N uni14F8 ; G 1958 +U 5369 ; WX 989 ; N uni14F9 ; G 1959 +U 5370 ; WX 967 ; N uni14FA ; G 1960 +U 5371 ; WX 989 ; N uni14FB ; G 1961 +U 5372 ; WX 998 ; N uni14FC ; G 1962 +U 5373 ; WX 958 ; N uni14FD ; G 1963 +U 5374 ; WX 998 ; N uni14FE ; G 1964 +U 5375 ; WX 958 ; N uni14FF ; G 1965 +U 5376 ; WX 967 ; N uni1500 ; G 1966 +U 5377 ; WX 989 ; N uni1501 ; G 1967 +U 5378 ; WX 967 ; N uni1502 ; G 1968 +U 5379 ; WX 989 ; N uni1503 ; G 1969 +U 5380 ; WX 967 ; N uni1504 ; G 1970 +U 5381 ; WX 493 ; N uni1505 ; G 1971 +U 5382 ; WX 460 ; N uni1506 ; G 1972 +U 5383 ; WX 493 ; N uni1507 ; G 1973 +U 5392 ; WX 923 ; N uni1510 ; G 1974 +U 5393 ; WX 923 ; N uni1511 ; G 1975 +U 5394 ; WX 923 ; N uni1512 ; G 1976 +U 5395 ; WX 1136 ; N uni1513 ; G 1977 +U 5396 ; WX 1136 ; N uni1514 ; G 1978 +U 5397 ; WX 1136 ; N uni1515 ; G 1979 +U 5398 ; WX 1136 ; N uni1516 ; G 1980 +U 5399 ; WX 1209 ; N uni1517 ; G 1981 +U 5400 ; WX 1202 ; N uni1518 ; G 1982 +U 5401 ; WX 1209 ; N uni1519 ; G 1983 +U 5402 ; WX 1202 ; N uni151A ; G 1984 +U 5403 ; WX 1209 ; N uni151B ; G 1985 +U 5404 ; WX 1202 ; N uni151C ; G 1986 +U 5405 ; WX 1431 ; N uni151D ; G 1987 +U 5406 ; WX 1420 ; N uni151E ; G 1988 +U 5407 ; WX 1431 ; N uni151F ; G 1989 +U 5408 ; WX 1420 ; N uni1520 ; G 1990 +U 5409 ; WX 1431 ; N uni1521 ; G 1991 +U 5410 ; WX 1420 ; N uni1522 ; G 1992 +U 5411 ; WX 1431 ; N uni1523 ; G 1993 +U 5412 ; WX 1420 ; N uni1524 ; G 1994 +U 5413 ; WX 746 ; N uni1525 ; G 1995 +U 5414 ; WX 776 ; N uni1526 ; G 1996 +U 5415 ; WX 776 ; N uni1527 ; G 1997 +U 5416 ; WX 776 ; N uni1528 ; G 1998 +U 5417 ; WX 776 ; N uni1529 ; G 1999 +U 5418 ; WX 776 ; N uni152A ; G 2000 +U 5419 ; WX 776 ; N uni152B ; G 2001 +U 5420 ; WX 776 ; N uni152C ; G 2002 +U 5421 ; WX 776 ; N uni152D ; G 2003 +U 5422 ; WX 776 ; N uni152E ; G 2004 +U 5423 ; WX 1003 ; N uni152F ; G 2005 +U 5424 ; WX 1003 ; N uni1530 ; G 2006 +U 5425 ; WX 1013 ; N uni1531 ; G 2007 +U 5426 ; WX 996 ; N uni1532 ; G 2008 +U 5427 ; WX 1013 ; N uni1533 ; G 2009 +U 5428 ; WX 996 ; N uni1534 ; G 2010 +U 5429 ; WX 1003 ; N uni1535 ; G 2011 +U 5430 ; WX 1003 ; N uni1536 ; G 2012 +U 5431 ; WX 1003 ; N uni1537 ; G 2013 +U 5432 ; WX 1003 ; N uni1538 ; G 2014 +U 5433 ; WX 1013 ; N uni1539 ; G 2015 +U 5434 ; WX 996 ; N uni153A ; G 2016 +U 5435 ; WX 1013 ; N uni153B ; G 2017 +U 5436 ; WX 996 ; N uni153C ; G 2018 +U 5437 ; WX 1013 ; N uni153D ; G 2019 +U 5438 ; WX 495 ; N uni153E ; G 2020 +U 5440 ; WX 395 ; N uni1540 ; G 2021 +U 5441 ; WX 510 ; N uni1541 ; G 2022 +U 5442 ; WX 1033 ; N uni1542 ; G 2023 +U 5443 ; WX 1033 ; N uni1543 ; G 2024 +U 5444 ; WX 976 ; N uni1544 ; G 2025 +U 5445 ; WX 976 ; N uni1545 ; G 2026 +U 5446 ; WX 976 ; N uni1546 ; G 2027 +U 5447 ; WX 976 ; N uni1547 ; G 2028 +U 5448 ; WX 733 ; N uni1548 ; G 2029 +U 5449 ; WX 733 ; N uni1549 ; G 2030 +U 5450 ; WX 733 ; N uni154A ; G 2031 +U 5451 ; WX 733 ; N uni154B ; G 2032 +U 5452 ; WX 733 ; N uni154C ; G 2033 +U 5453 ; WX 733 ; N uni154D ; G 2034 +U 5454 ; WX 1003 ; N uni154E ; G 2035 +U 5455 ; WX 959 ; N uni154F ; G 2036 +U 5456 ; WX 495 ; N uni1550 ; G 2037 +U 5458 ; WX 886 ; N uni1552 ; G 2038 +U 5459 ; WX 774 ; N uni1553 ; G 2039 +U 5460 ; WX 774 ; N uni1554 ; G 2040 +U 5461 ; WX 774 ; N uni1555 ; G 2041 +U 5462 ; WX 774 ; N uni1556 ; G 2042 +U 5463 ; WX 928 ; N uni1557 ; G 2043 +U 5464 ; WX 928 ; N uni1558 ; G 2044 +U 5465 ; WX 928 ; N uni1559 ; G 2045 +U 5466 ; WX 928 ; N uni155A ; G 2046 +U 5467 ; WX 1172 ; N uni155B ; G 2047 +U 5468 ; WX 1142 ; N uni155C ; G 2048 +U 5469 ; WX 602 ; N uni155D ; G 2049 +U 5470 ; WX 812 ; N uni155E ; G 2050 +U 5471 ; WX 812 ; N uni155F ; G 2051 +U 5472 ; WX 812 ; N uni1560 ; G 2052 +U 5473 ; WX 812 ; N uni1561 ; G 2053 +U 5474 ; WX 812 ; N uni1562 ; G 2054 +U 5475 ; WX 812 ; N uni1563 ; G 2055 +U 5476 ; WX 815 ; N uni1564 ; G 2056 +U 5477 ; WX 815 ; N uni1565 ; G 2057 +U 5478 ; WX 815 ; N uni1566 ; G 2058 +U 5479 ; WX 815 ; N uni1567 ; G 2059 +U 5480 ; WX 1060 ; N uni1568 ; G 2060 +U 5481 ; WX 1052 ; N uni1569 ; G 2061 +U 5482 ; WX 548 ; N uni156A ; G 2062 +U 5492 ; WX 977 ; N uni1574 ; G 2063 +U 5493 ; WX 977 ; N uni1575 ; G 2064 +U 5494 ; WX 977 ; N uni1576 ; G 2065 +U 5495 ; WX 977 ; N uni1577 ; G 2066 +U 5496 ; WX 977 ; N uni1578 ; G 2067 +U 5497 ; WX 977 ; N uni1579 ; G 2068 +U 5498 ; WX 977 ; N uni157A ; G 2069 +U 5499 ; WX 618 ; N uni157B ; G 2070 +U 5500 ; WX 837 ; N uni157C ; G 2071 +U 5501 ; WX 510 ; N uni157D ; G 2072 +U 5502 ; WX 1238 ; N uni157E ; G 2073 +U 5503 ; WX 1238 ; N uni157F ; G 2074 +U 5504 ; WX 1238 ; N uni1580 ; G 2075 +U 5505 ; WX 1238 ; N uni1581 ; G 2076 +U 5506 ; WX 1238 ; N uni1582 ; G 2077 +U 5507 ; WX 1238 ; N uni1583 ; G 2078 +U 5508 ; WX 1238 ; N uni1584 ; G 2079 +U 5509 ; WX 989 ; N uni1585 ; G 2080 +U 5514 ; WX 977 ; N uni158A ; G 2081 +U 5515 ; WX 977 ; N uni158B ; G 2082 +U 5516 ; WX 977 ; N uni158C ; G 2083 +U 5517 ; WX 977 ; N uni158D ; G 2084 +U 5518 ; WX 1591 ; N uni158E ; G 2085 +U 5519 ; WX 1591 ; N uni158F ; G 2086 +U 5520 ; WX 1591 ; N uni1590 ; G 2087 +U 5521 ; WX 1295 ; N uni1591 ; G 2088 +U 5522 ; WX 1295 ; N uni1592 ; G 2089 +U 5523 ; WX 1591 ; N uni1593 ; G 2090 +U 5524 ; WX 1591 ; N uni1594 ; G 2091 +U 5525 ; WX 848 ; N uni1595 ; G 2092 +U 5526 ; WX 1273 ; N uni1596 ; G 2093 +U 5536 ; WX 988 ; N uni15A0 ; G 2094 +U 5537 ; WX 988 ; N uni15A1 ; G 2095 +U 5538 ; WX 931 ; N uni15A2 ; G 2096 +U 5539 ; WX 931 ; N uni15A3 ; G 2097 +U 5540 ; WX 931 ; N uni15A4 ; G 2098 +U 5541 ; WX 931 ; N uni15A5 ; G 2099 +U 5542 ; WX 660 ; N uni15A6 ; G 2100 +U 5543 ; WX 776 ; N uni15A7 ; G 2101 +U 5544 ; WX 776 ; N uni15A8 ; G 2102 +U 5545 ; WX 776 ; N uni15A9 ; G 2103 +U 5546 ; WX 776 ; N uni15AA ; G 2104 +U 5547 ; WX 776 ; N uni15AB ; G 2105 +U 5548 ; WX 776 ; N uni15AC ; G 2106 +U 5549 ; WX 776 ; N uni15AD ; G 2107 +U 5550 ; WX 495 ; N uni15AE ; G 2108 +U 5551 ; WX 743 ; N uni15AF ; G 2109 +U 5598 ; WX 830 ; N uni15DE ; G 2110 +U 5601 ; WX 830 ; N uni15E1 ; G 2111 +U 5702 ; WX 496 ; N uni1646 ; G 2112 +U 5703 ; WX 496 ; N uni1647 ; G 2113 +U 5742 ; WX 413 ; N uni166E ; G 2114 +U 5743 ; WX 1238 ; N uni166F ; G 2115 +U 5744 ; WX 1591 ; N uni1670 ; G 2116 +U 5745 ; WX 2016 ; N uni1671 ; G 2117 +U 5746 ; WX 2016 ; N uni1672 ; G 2118 +U 5747 ; WX 1720 ; N uni1673 ; G 2119 +U 5748 ; WX 1678 ; N uni1674 ; G 2120 +U 5749 ; WX 2016 ; N uni1675 ; G 2121 +U 5750 ; WX 2016 ; N uni1676 ; G 2122 +U 5760 ; WX 543 ; N uni1680 ; G 2123 +U 5761 ; WX 637 ; N uni1681 ; G 2124 +U 5762 ; WX 945 ; N uni1682 ; G 2125 +U 5763 ; WX 1254 ; N uni1683 ; G 2126 +U 5764 ; WX 1563 ; N uni1684 ; G 2127 +U 5765 ; WX 1871 ; N uni1685 ; G 2128 +U 5766 ; WX 627 ; N uni1686 ; G 2129 +U 5767 ; WX 936 ; N uni1687 ; G 2130 +U 5768 ; WX 1254 ; N uni1688 ; G 2131 +U 5769 ; WX 1559 ; N uni1689 ; G 2132 +U 5770 ; WX 1871 ; N uni168A ; G 2133 +U 5771 ; WX 569 ; N uni168B ; G 2134 +U 5772 ; WX 877 ; N uni168C ; G 2135 +U 5773 ; WX 1187 ; N uni168D ; G 2136 +U 5774 ; WX 1497 ; N uni168E ; G 2137 +U 5775 ; WX 1807 ; N uni168F ; G 2138 +U 5776 ; WX 637 ; N uni1690 ; G 2139 +U 5777 ; WX 945 ; N uni1691 ; G 2140 +U 5778 ; WX 1240 ; N uni1692 ; G 2141 +U 5779 ; WX 1555 ; N uni1693 ; G 2142 +U 5780 ; WX 1871 ; N uni1694 ; G 2143 +U 5781 ; WX 569 ; N uni1695 ; G 2144 +U 5782 ; WX 569 ; N uni1696 ; G 2145 +U 5783 ; WX 789 ; N uni1697 ; G 2146 +U 5784 ; WX 1234 ; N uni1698 ; G 2147 +U 5785 ; WX 1559 ; N uni1699 ; G 2148 +U 5786 ; WX 740 ; N uni169A ; G 2149 +U 5787 ; WX 638 ; N uni169B ; G 2150 +U 5788 ; WX 638 ; N uni169C ; G 2151 +U 7424 ; WX 652 ; N uni1D00 ; G 2152 +U 7425 ; WX 833 ; N uni1D01 ; G 2153 +U 7426 ; WX 1048 ; N uni1D02 ; G 2154 +U 7427 ; WX 608 ; N uni1D03 ; G 2155 +U 7428 ; WX 593 ; N uni1D04 ; G 2156 +U 7429 ; WX 676 ; N uni1D05 ; G 2157 +U 7430 ; WX 676 ; N uni1D06 ; G 2158 +U 7431 ; WX 559 ; N uni1D07 ; G 2159 +U 7432 ; WX 557 ; N uni1D08 ; G 2160 +U 7433 ; WX 343 ; N uni1D09 ; G 2161 +U 7434 ; WX 494 ; N uni1D0A ; G 2162 +U 7435 ; WX 665 ; N uni1D0B ; G 2163 +U 7436 ; WX 539 ; N uni1D0C ; G 2164 +U 7437 ; WX 817 ; N uni1D0D ; G 2165 +U 7438 ; WX 701 ; N uni1D0E ; G 2166 +U 7439 ; WX 687 ; N uni1D0F ; G 2167 +U 7440 ; WX 593 ; N uni1D10 ; G 2168 +U 7441 ; WX 660 ; N uni1D11 ; G 2169 +U 7442 ; WX 660 ; N uni1D12 ; G 2170 +U 7443 ; WX 660 ; N uni1D13 ; G 2171 +U 7444 ; WX 1094 ; N uni1D14 ; G 2172 +U 7446 ; WX 687 ; N uni1D16 ; G 2173 +U 7447 ; WX 687 ; N uni1D17 ; G 2174 +U 7448 ; WX 556 ; N uni1D18 ; G 2175 +U 7449 ; WX 642 ; N uni1D19 ; G 2176 +U 7450 ; WX 642 ; N uni1D1A ; G 2177 +U 7451 ; WX 580 ; N uni1D1B ; G 2178 +U 7452 ; WX 634 ; N uni1D1C ; G 2179 +U 7453 ; WX 737 ; N uni1D1D ; G 2180 +U 7454 ; WX 948 ; N uni1D1E ; G 2181 +U 7455 ; WX 695 ; N uni1D1F ; G 2182 +U 7456 ; WX 652 ; N uni1D20 ; G 2183 +U 7457 ; WX 924 ; N uni1D21 ; G 2184 +U 7458 ; WX 582 ; N uni1D22 ; G 2185 +U 7459 ; WX 646 ; N uni1D23 ; G 2186 +U 7462 ; WX 539 ; N uni1D26 ; G 2187 +U 7463 ; WX 652 ; N uni1D27 ; G 2188 +U 7464 ; WX 691 ; N uni1D28 ; G 2189 +U 7465 ; WX 556 ; N uni1D29 ; G 2190 +U 7466 ; WX 781 ; N uni1D2A ; G 2191 +U 7467 ; WX 732 ; N uni1D2B ; G 2192 +U 7468 ; WX 487 ; N uni1D2C ; G 2193 +U 7469 ; WX 683 ; N uni1D2D ; G 2194 +U 7470 ; WX 480 ; N uni1D2E ; G 2195 +U 7472 ; WX 523 ; N uni1D30 ; G 2196 +U 7473 ; WX 430 ; N uni1D31 ; G 2197 +U 7474 ; WX 430 ; N uni1D32 ; G 2198 +U 7475 ; WX 517 ; N uni1D33 ; G 2199 +U 7476 ; WX 527 ; N uni1D34 ; G 2200 +U 7477 ; WX 234 ; N uni1D35 ; G 2201 +U 7478 ; WX 234 ; N uni1D36 ; G 2202 +U 7479 ; WX 488 ; N uni1D37 ; G 2203 +U 7480 ; WX 401 ; N uni1D38 ; G 2204 +U 7481 ; WX 626 ; N uni1D39 ; G 2205 +U 7482 ; WX 527 ; N uni1D3A ; G 2206 +U 7483 ; WX 527 ; N uni1D3B ; G 2207 +U 7484 ; WX 535 ; N uni1D3C ; G 2208 +U 7485 ; WX 509 ; N uni1D3D ; G 2209 +U 7486 ; WX 461 ; N uni1D3E ; G 2210 +U 7487 ; WX 485 ; N uni1D3F ; G 2211 +U 7488 ; WX 430 ; N uni1D40 ; G 2212 +U 7489 ; WX 511 ; N uni1D41 ; G 2213 +U 7490 ; WX 695 ; N uni1D42 ; G 2214 +U 7491 ; WX 458 ; N uni1D43 ; G 2215 +U 7492 ; WX 458 ; N uni1D44 ; G 2216 +U 7493 ; WX 479 ; N uni1D45 ; G 2217 +U 7494 ; WX 712 ; N uni1D46 ; G 2218 +U 7495 ; WX 479 ; N uni1D47 ; G 2219 +U 7496 ; WX 479 ; N uni1D48 ; G 2220 +U 7497 ; WX 479 ; N uni1D49 ; G 2221 +U 7498 ; WX 479 ; N uni1D4A ; G 2222 +U 7499 ; WX 386 ; N uni1D4B ; G 2223 +U 7500 ; WX 386 ; N uni1D4C ; G 2224 +U 7501 ; WX 479 ; N uni1D4D ; G 2225 +U 7502 ; WX 219 ; N uni1D4E ; G 2226 +U 7503 ; WX 487 ; N uni1D4F ; G 2227 +U 7504 ; WX 664 ; N uni1D50 ; G 2228 +U 7505 ; WX 456 ; N uni1D51 ; G 2229 +U 7506 ; WX 488 ; N uni1D52 ; G 2230 +U 7507 ; WX 414 ; N uni1D53 ; G 2231 +U 7508 ; WX 488 ; N uni1D54 ; G 2232 +U 7509 ; WX 488 ; N uni1D55 ; G 2233 +U 7510 ; WX 479 ; N uni1D56 ; G 2234 +U 7511 ; WX 388 ; N uni1D57 ; G 2235 +U 7512 ; WX 456 ; N uni1D58 ; G 2236 +U 7513 ; WX 462 ; N uni1D59 ; G 2237 +U 7514 ; WX 664 ; N uni1D5A ; G 2238 +U 7515 ; WX 501 ; N uni1D5B ; G 2239 +U 7517 ; WX 451 ; N uni1D5D ; G 2240 +U 7518 ; WX 429 ; N uni1D5E ; G 2241 +U 7519 ; WX 433 ; N uni1D5F ; G 2242 +U 7520 ; WX 493 ; N uni1D60 ; G 2243 +U 7521 ; WX 406 ; N uni1D61 ; G 2244 +U 7522 ; WX 219 ; N uni1D62 ; G 2245 +U 7523 ; WX 315 ; N uni1D63 ; G 2246 +U 7524 ; WX 456 ; N uni1D64 ; G 2247 +U 7525 ; WX 501 ; N uni1D65 ; G 2248 +U 7526 ; WX 451 ; N uni1D66 ; G 2249 +U 7527 ; WX 429 ; N uni1D67 ; G 2250 +U 7528 ; WX 451 ; N uni1D68 ; G 2251 +U 7529 ; WX 493 ; N uni1D69 ; G 2252 +U 7530 ; WX 406 ; N uni1D6A ; G 2253 +U 7543 ; WX 716 ; N uni1D77 ; G 2254 +U 7544 ; WX 527 ; N uni1D78 ; G 2255 +U 7547 ; WX 545 ; N uni1D7B ; G 2256 +U 7549 ; WX 747 ; N uni1D7D ; G 2257 +U 7557 ; WX 514 ; N uni1D85 ; G 2258 +U 7579 ; WX 479 ; N uni1D9B ; G 2259 +U 7580 ; WX 414 ; N uni1D9C ; G 2260 +U 7581 ; WX 414 ; N uni1D9D ; G 2261 +U 7582 ; WX 488 ; N uni1D9E ; G 2262 +U 7583 ; WX 386 ; N uni1D9F ; G 2263 +U 7584 ; WX 377 ; N uni1DA0 ; G 2264 +U 7585 ; WX 348 ; N uni1DA1 ; G 2265 +U 7586 ; WX 479 ; N uni1DA2 ; G 2266 +U 7587 ; WX 456 ; N uni1DA3 ; G 2267 +U 7588 ; WX 347 ; N uni1DA4 ; G 2268 +U 7589 ; WX 281 ; N uni1DA5 ; G 2269 +U 7590 ; WX 347 ; N uni1DA6 ; G 2270 +U 7591 ; WX 347 ; N uni1DA7 ; G 2271 +U 7592 ; WX 431 ; N uni1DA8 ; G 2272 +U 7593 ; WX 326 ; N uni1DA9 ; G 2273 +U 7594 ; WX 330 ; N uni1DAA ; G 2274 +U 7595 ; WX 370 ; N uni1DAB ; G 2275 +U 7596 ; WX 664 ; N uni1DAC ; G 2276 +U 7597 ; WX 664 ; N uni1DAD ; G 2277 +U 7598 ; WX 562 ; N uni1DAE ; G 2278 +U 7599 ; WX 562 ; N uni1DAF ; G 2279 +U 7600 ; WX 448 ; N uni1DB0 ; G 2280 +U 7601 ; WX 488 ; N uni1DB1 ; G 2281 +U 7602 ; WX 542 ; N uni1DB2 ; G 2282 +U 7603 ; WX 422 ; N uni1DB3 ; G 2283 +U 7604 ; WX 396 ; N uni1DB4 ; G 2284 +U 7605 ; WX 388 ; N uni1DB5 ; G 2285 +U 7606 ; WX 583 ; N uni1DB6 ; G 2286 +U 7607 ; WX 494 ; N uni1DB7 ; G 2287 +U 7608 ; WX 399 ; N uni1DB8 ; G 2288 +U 7609 ; WX 451 ; N uni1DB9 ; G 2289 +U 7610 ; WX 501 ; N uni1DBA ; G 2290 +U 7611 ; WX 417 ; N uni1DBB ; G 2291 +U 7612 ; WX 523 ; N uni1DBC ; G 2292 +U 7613 ; WX 470 ; N uni1DBD ; G 2293 +U 7614 ; WX 455 ; N uni1DBE ; G 2294 +U 7615 ; WX 425 ; N uni1DBF ; G 2295 +U 7620 ; WX 0 ; N uni1DC4 ; G 2296 +U 7621 ; WX 0 ; N uni1DC5 ; G 2297 +U 7622 ; WX 0 ; N uni1DC6 ; G 2298 +U 7623 ; WX 0 ; N uni1DC7 ; G 2299 +U 7624 ; WX 0 ; N uni1DC8 ; G 2300 +U 7625 ; WX 0 ; N uni1DC9 ; G 2301 +U 7680 ; WX 774 ; N uni1E00 ; G 2302 +U 7681 ; WX 675 ; N uni1E01 ; G 2303 +U 7682 ; WX 762 ; N uni1E02 ; G 2304 +U 7683 ; WX 716 ; N uni1E03 ; G 2305 +U 7684 ; WX 762 ; N uni1E04 ; G 2306 +U 7685 ; WX 716 ; N uni1E05 ; G 2307 +U 7686 ; WX 762 ; N uni1E06 ; G 2308 +U 7687 ; WX 716 ; N uni1E07 ; G 2309 +U 7688 ; WX 734 ; N uni1E08 ; G 2310 +U 7689 ; WX 593 ; N uni1E09 ; G 2311 +U 7690 ; WX 830 ; N uni1E0A ; G 2312 +U 7691 ; WX 716 ; N uni1E0B ; G 2313 +U 7692 ; WX 830 ; N uni1E0C ; G 2314 +U 7693 ; WX 716 ; N uni1E0D ; G 2315 +U 7694 ; WX 830 ; N uni1E0E ; G 2316 +U 7695 ; WX 716 ; N uni1E0F ; G 2317 +U 7696 ; WX 830 ; N uni1E10 ; G 2318 +U 7697 ; WX 716 ; N uni1E11 ; G 2319 +U 7698 ; WX 830 ; N uni1E12 ; G 2320 +U 7699 ; WX 716 ; N uni1E13 ; G 2321 +U 7700 ; WX 683 ; N uni1E14 ; G 2322 +U 7701 ; WX 678 ; N uni1E15 ; G 2323 +U 7702 ; WX 683 ; N uni1E16 ; G 2324 +U 7703 ; WX 678 ; N uni1E17 ; G 2325 +U 7704 ; WX 683 ; N uni1E18 ; G 2326 +U 7705 ; WX 678 ; N uni1E19 ; G 2327 +U 7706 ; WX 683 ; N uni1E1A ; G 2328 +U 7707 ; WX 678 ; N uni1E1B ; G 2329 +U 7708 ; WX 683 ; N uni1E1C ; G 2330 +U 7709 ; WX 678 ; N uni1E1D ; G 2331 +U 7710 ; WX 683 ; N uni1E1E ; G 2332 +U 7711 ; WX 435 ; N uni1E1F ; G 2333 +U 7712 ; WX 821 ; N uni1E20 ; G 2334 +U 7713 ; WX 716 ; N uni1E21 ; G 2335 +U 7714 ; WX 837 ; N uni1E22 ; G 2336 +U 7715 ; WX 712 ; N uni1E23 ; G 2337 +U 7716 ; WX 837 ; N uni1E24 ; G 2338 +U 7717 ; WX 712 ; N uni1E25 ; G 2339 +U 7718 ; WX 837 ; N uni1E26 ; G 2340 +U 7719 ; WX 712 ; N uni1E27 ; G 2341 +U 7720 ; WX 837 ; N uni1E28 ; G 2342 +U 7721 ; WX 712 ; N uni1E29 ; G 2343 +U 7722 ; WX 837 ; N uni1E2A ; G 2344 +U 7723 ; WX 712 ; N uni1E2B ; G 2345 +U 7724 ; WX 372 ; N uni1E2C ; G 2346 +U 7725 ; WX 343 ; N uni1E2D ; G 2347 +U 7726 ; WX 372 ; N uni1E2E ; G 2348 +U 7727 ; WX 343 ; N uni1E2F ; G 2349 +U 7728 ; WX 775 ; N uni1E30 ; G 2350 +U 7729 ; WX 665 ; N uni1E31 ; G 2351 +U 7730 ; WX 775 ; N uni1E32 ; G 2352 +U 7731 ; WX 665 ; N uni1E33 ; G 2353 +U 7732 ; WX 775 ; N uni1E34 ; G 2354 +U 7733 ; WX 665 ; N uni1E35 ; G 2355 +U 7734 ; WX 637 ; N uni1E36 ; G 2356 +U 7735 ; WX 343 ; N uni1E37 ; G 2357 +U 7736 ; WX 637 ; N uni1E38 ; G 2358 +U 7737 ; WX 343 ; N uni1E39 ; G 2359 +U 7738 ; WX 637 ; N uni1E3A ; G 2360 +U 7739 ; WX 343 ; N uni1E3B ; G 2361 +U 7740 ; WX 637 ; N uni1E3C ; G 2362 +U 7741 ; WX 343 ; N uni1E3D ; G 2363 +U 7742 ; WX 995 ; N uni1E3E ; G 2364 +U 7743 ; WX 1042 ; N uni1E3F ; G 2365 +U 7744 ; WX 995 ; N uni1E40 ; G 2366 +U 7745 ; WX 1042 ; N uni1E41 ; G 2367 +U 7746 ; WX 995 ; N uni1E42 ; G 2368 +U 7747 ; WX 1042 ; N uni1E43 ; G 2369 +U 7748 ; WX 837 ; N uni1E44 ; G 2370 +U 7749 ; WX 712 ; N uni1E45 ; G 2371 +U 7750 ; WX 837 ; N uni1E46 ; G 2372 +U 7751 ; WX 712 ; N uni1E47 ; G 2373 +U 7752 ; WX 837 ; N uni1E48 ; G 2374 +U 7753 ; WX 712 ; N uni1E49 ; G 2375 +U 7754 ; WX 837 ; N uni1E4A ; G 2376 +U 7755 ; WX 712 ; N uni1E4B ; G 2377 +U 7756 ; WX 850 ; N uni1E4C ; G 2378 +U 7757 ; WX 687 ; N uni1E4D ; G 2379 +U 7758 ; WX 850 ; N uni1E4E ; G 2380 +U 7759 ; WX 687 ; N uni1E4F ; G 2381 +U 7760 ; WX 850 ; N uni1E50 ; G 2382 +U 7761 ; WX 687 ; N uni1E51 ; G 2383 +U 7762 ; WX 850 ; N uni1E52 ; G 2384 +U 7763 ; WX 687 ; N uni1E53 ; G 2385 +U 7764 ; WX 733 ; N uni1E54 ; G 2386 +U 7765 ; WX 716 ; N uni1E55 ; G 2387 +U 7766 ; WX 733 ; N uni1E56 ; G 2388 +U 7767 ; WX 716 ; N uni1E57 ; G 2389 +U 7768 ; WX 770 ; N uni1E58 ; G 2390 +U 7769 ; WX 493 ; N uni1E59 ; G 2391 +U 7770 ; WX 770 ; N uni1E5A ; G 2392 +U 7771 ; WX 493 ; N uni1E5B ; G 2393 +U 7772 ; WX 770 ; N uni1E5C ; G 2394 +U 7773 ; WX 493 ; N uni1E5D ; G 2395 +U 7774 ; WX 770 ; N uni1E5E ; G 2396 +U 7775 ; WX 493 ; N uni1E5F ; G 2397 +U 7776 ; WX 720 ; N uni1E60 ; G 2398 +U 7777 ; WX 595 ; N uni1E61 ; G 2399 +U 7778 ; WX 720 ; N uni1E62 ; G 2400 +U 7779 ; WX 595 ; N uni1E63 ; G 2401 +U 7780 ; WX 720 ; N uni1E64 ; G 2402 +U 7781 ; WX 595 ; N uni1E65 ; G 2403 +U 7782 ; WX 720 ; N uni1E66 ; G 2404 +U 7783 ; WX 595 ; N uni1E67 ; G 2405 +U 7784 ; WX 720 ; N uni1E68 ; G 2406 +U 7785 ; WX 595 ; N uni1E69 ; G 2407 +U 7786 ; WX 682 ; N uni1E6A ; G 2408 +U 7787 ; WX 478 ; N uni1E6B ; G 2409 +U 7788 ; WX 682 ; N uni1E6C ; G 2410 +U 7789 ; WX 478 ; N uni1E6D ; G 2411 +U 7790 ; WX 682 ; N uni1E6E ; G 2412 +U 7791 ; WX 478 ; N uni1E6F ; G 2413 +U 7792 ; WX 682 ; N uni1E70 ; G 2414 +U 7793 ; WX 478 ; N uni1E71 ; G 2415 +U 7794 ; WX 812 ; N uni1E72 ; G 2416 +U 7795 ; WX 712 ; N uni1E73 ; G 2417 +U 7796 ; WX 812 ; N uni1E74 ; G 2418 +U 7797 ; WX 712 ; N uni1E75 ; G 2419 +U 7798 ; WX 812 ; N uni1E76 ; G 2420 +U 7799 ; WX 712 ; N uni1E77 ; G 2421 +U 7800 ; WX 812 ; N uni1E78 ; G 2422 +U 7801 ; WX 712 ; N uni1E79 ; G 2423 +U 7802 ; WX 812 ; N uni1E7A ; G 2424 +U 7803 ; WX 712 ; N uni1E7B ; G 2425 +U 7804 ; WX 774 ; N uni1E7C ; G 2426 +U 7805 ; WX 652 ; N uni1E7D ; G 2427 +U 7806 ; WX 774 ; N uni1E7E ; G 2428 +U 7807 ; WX 652 ; N uni1E7F ; G 2429 +U 7808 ; WX 1103 ; N Wgrave ; G 2430 +U 7809 ; WX 924 ; N wgrave ; G 2431 +U 7810 ; WX 1103 ; N Wacute ; G 2432 +U 7811 ; WX 924 ; N wacute ; G 2433 +U 7812 ; WX 1103 ; N Wdieresis ; G 2434 +U 7813 ; WX 924 ; N wdieresis ; G 2435 +U 7814 ; WX 1103 ; N uni1E86 ; G 2436 +U 7815 ; WX 924 ; N uni1E87 ; G 2437 +U 7816 ; WX 1103 ; N uni1E88 ; G 2438 +U 7817 ; WX 924 ; N uni1E89 ; G 2439 +U 7818 ; WX 771 ; N uni1E8A ; G 2440 +U 7819 ; WX 645 ; N uni1E8B ; G 2441 +U 7820 ; WX 771 ; N uni1E8C ; G 2442 +U 7821 ; WX 645 ; N uni1E8D ; G 2443 +U 7822 ; WX 724 ; N uni1E8E ; G 2444 +U 7823 ; WX 652 ; N uni1E8F ; G 2445 +U 7824 ; WX 725 ; N uni1E90 ; G 2446 +U 7825 ; WX 582 ; N uni1E91 ; G 2447 +U 7826 ; WX 725 ; N uni1E92 ; G 2448 +U 7827 ; WX 582 ; N uni1E93 ; G 2449 +U 7828 ; WX 725 ; N uni1E94 ; G 2450 +U 7829 ; WX 582 ; N uni1E95 ; G 2451 +U 7830 ; WX 712 ; N uni1E96 ; G 2452 +U 7831 ; WX 478 ; N uni1E97 ; G 2453 +U 7832 ; WX 924 ; N uni1E98 ; G 2454 +U 7833 ; WX 652 ; N uni1E99 ; G 2455 +U 7834 ; WX 675 ; N uni1E9A ; G 2456 +U 7835 ; WX 435 ; N uni1E9B ; G 2457 +U 7836 ; WX 435 ; N uni1E9C ; G 2458 +U 7837 ; WX 435 ; N uni1E9D ; G 2459 +U 7838 ; WX 896 ; N uni1E9E ; G 2460 +U 7839 ; WX 687 ; N uni1E9F ; G 2461 +U 7840 ; WX 774 ; N uni1EA0 ; G 2462 +U 7841 ; WX 675 ; N uni1EA1 ; G 2463 +U 7842 ; WX 774 ; N uni1EA2 ; G 2464 +U 7843 ; WX 675 ; N uni1EA3 ; G 2465 +U 7844 ; WX 774 ; N uni1EA4 ; G 2466 +U 7845 ; WX 675 ; N uni1EA5 ; G 2467 +U 7846 ; WX 774 ; N uni1EA6 ; G 2468 +U 7847 ; WX 675 ; N uni1EA7 ; G 2469 +U 7848 ; WX 774 ; N uni1EA8 ; G 2470 +U 7849 ; WX 675 ; N uni1EA9 ; G 2471 +U 7850 ; WX 774 ; N uni1EAA ; G 2472 +U 7851 ; WX 675 ; N uni1EAB ; G 2473 +U 7852 ; WX 774 ; N uni1EAC ; G 2474 +U 7853 ; WX 675 ; N uni1EAD ; G 2475 +U 7854 ; WX 774 ; N uni1EAE ; G 2476 +U 7855 ; WX 675 ; N uni1EAF ; G 2477 +U 7856 ; WX 774 ; N uni1EB0 ; G 2478 +U 7857 ; WX 675 ; N uni1EB1 ; G 2479 +U 7858 ; WX 774 ; N uni1EB2 ; G 2480 +U 7859 ; WX 675 ; N uni1EB3 ; G 2481 +U 7860 ; WX 774 ; N uni1EB4 ; G 2482 +U 7861 ; WX 675 ; N uni1EB5 ; G 2483 +U 7862 ; WX 774 ; N uni1EB6 ; G 2484 +U 7863 ; WX 675 ; N uni1EB7 ; G 2485 +U 7864 ; WX 683 ; N uni1EB8 ; G 2486 +U 7865 ; WX 678 ; N uni1EB9 ; G 2487 +U 7866 ; WX 683 ; N uni1EBA ; G 2488 +U 7867 ; WX 678 ; N uni1EBB ; G 2489 +U 7868 ; WX 683 ; N uni1EBC ; G 2490 +U 7869 ; WX 678 ; N uni1EBD ; G 2491 +U 7870 ; WX 683 ; N uni1EBE ; G 2492 +U 7871 ; WX 678 ; N uni1EBF ; G 2493 +U 7872 ; WX 683 ; N uni1EC0 ; G 2494 +U 7873 ; WX 678 ; N uni1EC1 ; G 2495 +U 7874 ; WX 683 ; N uni1EC2 ; G 2496 +U 7875 ; WX 678 ; N uni1EC3 ; G 2497 +U 7876 ; WX 683 ; N uni1EC4 ; G 2498 +U 7877 ; WX 678 ; N uni1EC5 ; G 2499 +U 7878 ; WX 683 ; N uni1EC6 ; G 2500 +U 7879 ; WX 678 ; N uni1EC7 ; G 2501 +U 7880 ; WX 372 ; N uni1EC8 ; G 2502 +U 7881 ; WX 343 ; N uni1EC9 ; G 2503 +U 7882 ; WX 372 ; N uni1ECA ; G 2504 +U 7883 ; WX 343 ; N uni1ECB ; G 2505 +U 7884 ; WX 850 ; N uni1ECC ; G 2506 +U 7885 ; WX 687 ; N uni1ECD ; G 2507 +U 7886 ; WX 850 ; N uni1ECE ; G 2508 +U 7887 ; WX 687 ; N uni1ECF ; G 2509 +U 7888 ; WX 850 ; N uni1ED0 ; G 2510 +U 7889 ; WX 687 ; N uni1ED1 ; G 2511 +U 7890 ; WX 850 ; N uni1ED2 ; G 2512 +U 7891 ; WX 687 ; N uni1ED3 ; G 2513 +U 7892 ; WX 850 ; N uni1ED4 ; G 2514 +U 7893 ; WX 687 ; N uni1ED5 ; G 2515 +U 7894 ; WX 850 ; N uni1ED6 ; G 2516 +U 7895 ; WX 687 ; N uni1ED7 ; G 2517 +U 7896 ; WX 850 ; N uni1ED8 ; G 2518 +U 7897 ; WX 687 ; N uni1ED9 ; G 2519 +U 7898 ; WX 874 ; N uni1EDA ; G 2520 +U 7899 ; WX 687 ; N uni1EDB ; G 2521 +U 7900 ; WX 874 ; N uni1EDC ; G 2522 +U 7901 ; WX 687 ; N uni1EDD ; G 2523 +U 7902 ; WX 874 ; N uni1EDE ; G 2524 +U 7903 ; WX 687 ; N uni1EDF ; G 2525 +U 7904 ; WX 874 ; N uni1EE0 ; G 2526 +U 7905 ; WX 687 ; N uni1EE1 ; G 2527 +U 7906 ; WX 874 ; N uni1EE2 ; G 2528 +U 7907 ; WX 687 ; N uni1EE3 ; G 2529 +U 7908 ; WX 812 ; N uni1EE4 ; G 2530 +U 7909 ; WX 712 ; N uni1EE5 ; G 2531 +U 7910 ; WX 812 ; N uni1EE6 ; G 2532 +U 7911 ; WX 712 ; N uni1EE7 ; G 2533 +U 7912 ; WX 835 ; N uni1EE8 ; G 2534 +U 7913 ; WX 712 ; N uni1EE9 ; G 2535 +U 7914 ; WX 835 ; N uni1EEA ; G 2536 +U 7915 ; WX 712 ; N uni1EEB ; G 2537 +U 7916 ; WX 835 ; N uni1EEC ; G 2538 +U 7917 ; WX 712 ; N uni1EED ; G 2539 +U 7918 ; WX 835 ; N uni1EEE ; G 2540 +U 7919 ; WX 712 ; N uni1EEF ; G 2541 +U 7920 ; WX 835 ; N uni1EF0 ; G 2542 +U 7921 ; WX 712 ; N uni1EF1 ; G 2543 +U 7922 ; WX 724 ; N Ygrave ; G 2544 +U 7923 ; WX 652 ; N ygrave ; G 2545 +U 7924 ; WX 724 ; N uni1EF4 ; G 2546 +U 7925 ; WX 652 ; N uni1EF5 ; G 2547 +U 7926 ; WX 724 ; N uni1EF6 ; G 2548 +U 7927 ; WX 652 ; N uni1EF7 ; G 2549 +U 7928 ; WX 724 ; N uni1EF8 ; G 2550 +U 7929 ; WX 652 ; N uni1EF9 ; G 2551 +U 7930 ; WX 953 ; N uni1EFA ; G 2552 +U 7931 ; WX 644 ; N uni1EFB ; G 2553 +U 7936 ; WX 687 ; N uni1F00 ; G 2554 +U 7937 ; WX 687 ; N uni1F01 ; G 2555 +U 7938 ; WX 687 ; N uni1F02 ; G 2556 +U 7939 ; WX 687 ; N uni1F03 ; G 2557 +U 7940 ; WX 687 ; N uni1F04 ; G 2558 +U 7941 ; WX 687 ; N uni1F05 ; G 2559 +U 7942 ; WX 687 ; N uni1F06 ; G 2560 +U 7943 ; WX 687 ; N uni1F07 ; G 2561 +U 7944 ; WX 774 ; N uni1F08 ; G 2562 +U 7945 ; WX 774 ; N uni1F09 ; G 2563 +U 7946 ; WX 1041 ; N uni1F0A ; G 2564 +U 7947 ; WX 1043 ; N uni1F0B ; G 2565 +U 7948 ; WX 935 ; N uni1F0C ; G 2566 +U 7949 ; WX 963 ; N uni1F0D ; G 2567 +U 7950 ; WX 835 ; N uni1F0E ; G 2568 +U 7951 ; WX 859 ; N uni1F0F ; G 2569 +U 7952 ; WX 557 ; N uni1F10 ; G 2570 +U 7953 ; WX 557 ; N uni1F11 ; G 2571 +U 7954 ; WX 557 ; N uni1F12 ; G 2572 +U 7955 ; WX 557 ; N uni1F13 ; G 2573 +U 7956 ; WX 557 ; N uni1F14 ; G 2574 +U 7957 ; WX 557 ; N uni1F15 ; G 2575 +U 7960 ; WX 792 ; N uni1F18 ; G 2576 +U 7961 ; WX 794 ; N uni1F19 ; G 2577 +U 7962 ; WX 1100 ; N uni1F1A ; G 2578 +U 7963 ; WX 1096 ; N uni1F1B ; G 2579 +U 7964 ; WX 1023 ; N uni1F1C ; G 2580 +U 7965 ; WX 1052 ; N uni1F1D ; G 2581 +U 7968 ; WX 712 ; N uni1F20 ; G 2582 +U 7969 ; WX 712 ; N uni1F21 ; G 2583 +U 7970 ; WX 712 ; N uni1F22 ; G 2584 +U 7971 ; WX 712 ; N uni1F23 ; G 2585 +U 7972 ; WX 712 ; N uni1F24 ; G 2586 +U 7973 ; WX 712 ; N uni1F25 ; G 2587 +U 7974 ; WX 712 ; N uni1F26 ; G 2588 +U 7975 ; WX 712 ; N uni1F27 ; G 2589 +U 7976 ; WX 945 ; N uni1F28 ; G 2590 +U 7977 ; WX 951 ; N uni1F29 ; G 2591 +U 7978 ; WX 1250 ; N uni1F2A ; G 2592 +U 7979 ; WX 1250 ; N uni1F2B ; G 2593 +U 7980 ; WX 1180 ; N uni1F2C ; G 2594 +U 7981 ; WX 1206 ; N uni1F2D ; G 2595 +U 7982 ; WX 1054 ; N uni1F2E ; G 2596 +U 7983 ; WX 1063 ; N uni1F2F ; G 2597 +U 7984 ; WX 390 ; N uni1F30 ; G 2598 +U 7985 ; WX 390 ; N uni1F31 ; G 2599 +U 7986 ; WX 390 ; N uni1F32 ; G 2600 +U 7987 ; WX 390 ; N uni1F33 ; G 2601 +U 7988 ; WX 390 ; N uni1F34 ; G 2602 +U 7989 ; WX 390 ; N uni1F35 ; G 2603 +U 7990 ; WX 390 ; N uni1F36 ; G 2604 +U 7991 ; WX 390 ; N uni1F37 ; G 2605 +U 7992 ; WX 483 ; N uni1F38 ; G 2606 +U 7993 ; WX 489 ; N uni1F39 ; G 2607 +U 7994 ; WX 777 ; N uni1F3A ; G 2608 +U 7995 ; WX 785 ; N uni1F3B ; G 2609 +U 7996 ; WX 712 ; N uni1F3C ; G 2610 +U 7997 ; WX 738 ; N uni1F3D ; G 2611 +U 7998 ; WX 604 ; N uni1F3E ; G 2612 +U 7999 ; WX 604 ; N uni1F3F ; G 2613 +U 8000 ; WX 687 ; N uni1F40 ; G 2614 +U 8001 ; WX 687 ; N uni1F41 ; G 2615 +U 8002 ; WX 687 ; N uni1F42 ; G 2616 +U 8003 ; WX 687 ; N uni1F43 ; G 2617 +U 8004 ; WX 687 ; N uni1F44 ; G 2618 +U 8005 ; WX 687 ; N uni1F45 ; G 2619 +U 8008 ; WX 892 ; N uni1F48 ; G 2620 +U 8009 ; WX 933 ; N uni1F49 ; G 2621 +U 8010 ; WX 1221 ; N uni1F4A ; G 2622 +U 8011 ; WX 1224 ; N uni1F4B ; G 2623 +U 8012 ; WX 1053 ; N uni1F4C ; G 2624 +U 8013 ; WX 1082 ; N uni1F4D ; G 2625 +U 8016 ; WX 675 ; N uni1F50 ; G 2626 +U 8017 ; WX 675 ; N uni1F51 ; G 2627 +U 8018 ; WX 675 ; N uni1F52 ; G 2628 +U 8019 ; WX 675 ; N uni1F53 ; G 2629 +U 8020 ; WX 675 ; N uni1F54 ; G 2630 +U 8021 ; WX 675 ; N uni1F55 ; G 2631 +U 8022 ; WX 675 ; N uni1F56 ; G 2632 +U 8023 ; WX 675 ; N uni1F57 ; G 2633 +U 8025 ; WX 930 ; N uni1F59 ; G 2634 +U 8027 ; WX 1184 ; N uni1F5B ; G 2635 +U 8029 ; WX 1199 ; N uni1F5D ; G 2636 +U 8031 ; WX 1049 ; N uni1F5F ; G 2637 +U 8032 ; WX 869 ; N uni1F60 ; G 2638 +U 8033 ; WX 869 ; N uni1F61 ; G 2639 +U 8034 ; WX 869 ; N uni1F62 ; G 2640 +U 8035 ; WX 869 ; N uni1F63 ; G 2641 +U 8036 ; WX 869 ; N uni1F64 ; G 2642 +U 8037 ; WX 869 ; N uni1F65 ; G 2643 +U 8038 ; WX 869 ; N uni1F66 ; G 2644 +U 8039 ; WX 869 ; N uni1F67 ; G 2645 +U 8040 ; WX 909 ; N uni1F68 ; G 2646 +U 8041 ; WX 958 ; N uni1F69 ; G 2647 +U 8042 ; WX 1246 ; N uni1F6A ; G 2648 +U 8043 ; WX 1251 ; N uni1F6B ; G 2649 +U 8044 ; WX 1076 ; N uni1F6C ; G 2650 +U 8045 ; WX 1105 ; N uni1F6D ; G 2651 +U 8046 ; WX 1028 ; N uni1F6E ; G 2652 +U 8047 ; WX 1076 ; N uni1F6F ; G 2653 +U 8048 ; WX 687 ; N uni1F70 ; G 2654 +U 8049 ; WX 687 ; N uni1F71 ; G 2655 +U 8050 ; WX 557 ; N uni1F72 ; G 2656 +U 8051 ; WX 557 ; N uni1F73 ; G 2657 +U 8052 ; WX 712 ; N uni1F74 ; G 2658 +U 8053 ; WX 712 ; N uni1F75 ; G 2659 +U 8054 ; WX 390 ; N uni1F76 ; G 2660 +U 8055 ; WX 390 ; N uni1F77 ; G 2661 +U 8056 ; WX 687 ; N uni1F78 ; G 2662 +U 8057 ; WX 687 ; N uni1F79 ; G 2663 +U 8058 ; WX 675 ; N uni1F7A ; G 2664 +U 8059 ; WX 675 ; N uni1F7B ; G 2665 +U 8060 ; WX 869 ; N uni1F7C ; G 2666 +U 8061 ; WX 869 ; N uni1F7D ; G 2667 +U 8064 ; WX 687 ; N uni1F80 ; G 2668 +U 8065 ; WX 687 ; N uni1F81 ; G 2669 +U 8066 ; WX 687 ; N uni1F82 ; G 2670 +U 8067 ; WX 687 ; N uni1F83 ; G 2671 +U 8068 ; WX 687 ; N uni1F84 ; G 2672 +U 8069 ; WX 687 ; N uni1F85 ; G 2673 +U 8070 ; WX 687 ; N uni1F86 ; G 2674 +U 8071 ; WX 687 ; N uni1F87 ; G 2675 +U 8072 ; WX 774 ; N uni1F88 ; G 2676 +U 8073 ; WX 774 ; N uni1F89 ; G 2677 +U 8074 ; WX 1041 ; N uni1F8A ; G 2678 +U 8075 ; WX 1043 ; N uni1F8B ; G 2679 +U 8076 ; WX 935 ; N uni1F8C ; G 2680 +U 8077 ; WX 963 ; N uni1F8D ; G 2681 +U 8078 ; WX 835 ; N uni1F8E ; G 2682 +U 8079 ; WX 859 ; N uni1F8F ; G 2683 +U 8080 ; WX 712 ; N uni1F90 ; G 2684 +U 8081 ; WX 712 ; N uni1F91 ; G 2685 +U 8082 ; WX 712 ; N uni1F92 ; G 2686 +U 8083 ; WX 712 ; N uni1F93 ; G 2687 +U 8084 ; WX 712 ; N uni1F94 ; G 2688 +U 8085 ; WX 712 ; N uni1F95 ; G 2689 +U 8086 ; WX 712 ; N uni1F96 ; G 2690 +U 8087 ; WX 712 ; N uni1F97 ; G 2691 +U 8088 ; WX 945 ; N uni1F98 ; G 2692 +U 8089 ; WX 951 ; N uni1F99 ; G 2693 +U 8090 ; WX 1250 ; N uni1F9A ; G 2694 +U 8091 ; WX 1250 ; N uni1F9B ; G 2695 +U 8092 ; WX 1180 ; N uni1F9C ; G 2696 +U 8093 ; WX 1206 ; N uni1F9D ; G 2697 +U 8094 ; WX 1054 ; N uni1F9E ; G 2698 +U 8095 ; WX 1063 ; N uni1F9F ; G 2699 +U 8096 ; WX 869 ; N uni1FA0 ; G 2700 +U 8097 ; WX 869 ; N uni1FA1 ; G 2701 +U 8098 ; WX 869 ; N uni1FA2 ; G 2702 +U 8099 ; WX 869 ; N uni1FA3 ; G 2703 +U 8100 ; WX 869 ; N uni1FA4 ; G 2704 +U 8101 ; WX 869 ; N uni1FA5 ; G 2705 +U 8102 ; WX 869 ; N uni1FA6 ; G 2706 +U 8103 ; WX 869 ; N uni1FA7 ; G 2707 +U 8104 ; WX 909 ; N uni1FA8 ; G 2708 +U 8105 ; WX 958 ; N uni1FA9 ; G 2709 +U 8106 ; WX 1246 ; N uni1FAA ; G 2710 +U 8107 ; WX 1251 ; N uni1FAB ; G 2711 +U 8108 ; WX 1076 ; N uni1FAC ; G 2712 +U 8109 ; WX 1105 ; N uni1FAD ; G 2713 +U 8110 ; WX 1028 ; N uni1FAE ; G 2714 +U 8111 ; WX 1076 ; N uni1FAF ; G 2715 +U 8112 ; WX 687 ; N uni1FB0 ; G 2716 +U 8113 ; WX 687 ; N uni1FB1 ; G 2717 +U 8114 ; WX 687 ; N uni1FB2 ; G 2718 +U 8115 ; WX 687 ; N uni1FB3 ; G 2719 +U 8116 ; WX 687 ; N uni1FB4 ; G 2720 +U 8118 ; WX 687 ; N uni1FB6 ; G 2721 +U 8119 ; WX 687 ; N uni1FB7 ; G 2722 +U 8120 ; WX 774 ; N uni1FB8 ; G 2723 +U 8121 ; WX 774 ; N uni1FB9 ; G 2724 +U 8122 ; WX 876 ; N uni1FBA ; G 2725 +U 8123 ; WX 797 ; N uni1FBB ; G 2726 +U 8124 ; WX 774 ; N uni1FBC ; G 2727 +U 8125 ; WX 500 ; N uni1FBD ; G 2728 +U 8126 ; WX 500 ; N uni1FBE ; G 2729 +U 8127 ; WX 500 ; N uni1FBF ; G 2730 +U 8128 ; WX 500 ; N uni1FC0 ; G 2731 +U 8129 ; WX 500 ; N uni1FC1 ; G 2732 +U 8130 ; WX 712 ; N uni1FC2 ; G 2733 +U 8131 ; WX 712 ; N uni1FC3 ; G 2734 +U 8132 ; WX 712 ; N uni1FC4 ; G 2735 +U 8134 ; WX 712 ; N uni1FC6 ; G 2736 +U 8135 ; WX 712 ; N uni1FC7 ; G 2737 +U 8136 ; WX 929 ; N uni1FC8 ; G 2738 +U 8137 ; WX 846 ; N uni1FC9 ; G 2739 +U 8138 ; WX 1080 ; N uni1FCA ; G 2740 +U 8139 ; WX 1009 ; N uni1FCB ; G 2741 +U 8140 ; WX 837 ; N uni1FCC ; G 2742 +U 8141 ; WX 500 ; N uni1FCD ; G 2743 +U 8142 ; WX 500 ; N uni1FCE ; G 2744 +U 8143 ; WX 500 ; N uni1FCF ; G 2745 +U 8144 ; WX 390 ; N uni1FD0 ; G 2746 +U 8145 ; WX 390 ; N uni1FD1 ; G 2747 +U 8146 ; WX 390 ; N uni1FD2 ; G 2748 +U 8147 ; WX 390 ; N uni1FD3 ; G 2749 +U 8150 ; WX 390 ; N uni1FD6 ; G 2750 +U 8151 ; WX 390 ; N uni1FD7 ; G 2751 +U 8152 ; WX 372 ; N uni1FD8 ; G 2752 +U 8153 ; WX 372 ; N uni1FD9 ; G 2753 +U 8154 ; WX 621 ; N uni1FDA ; G 2754 +U 8155 ; WX 563 ; N uni1FDB ; G 2755 +U 8157 ; WX 500 ; N uni1FDD ; G 2756 +U 8158 ; WX 500 ; N uni1FDE ; G 2757 +U 8159 ; WX 500 ; N uni1FDF ; G 2758 +U 8160 ; WX 675 ; N uni1FE0 ; G 2759 +U 8161 ; WX 675 ; N uni1FE1 ; G 2760 +U 8162 ; WX 675 ; N uni1FE2 ; G 2761 +U 8163 ; WX 675 ; N uni1FE3 ; G 2762 +U 8164 ; WX 716 ; N uni1FE4 ; G 2763 +U 8165 ; WX 716 ; N uni1FE5 ; G 2764 +U 8166 ; WX 675 ; N uni1FE6 ; G 2765 +U 8167 ; WX 675 ; N uni1FE7 ; G 2766 +U 8168 ; WX 724 ; N uni1FE8 ; G 2767 +U 8169 ; WX 724 ; N uni1FE9 ; G 2768 +U 8170 ; WX 1020 ; N uni1FEA ; G 2769 +U 8171 ; WX 980 ; N uni1FEB ; G 2770 +U 8172 ; WX 838 ; N uni1FEC ; G 2771 +U 8173 ; WX 500 ; N uni1FED ; G 2772 +U 8174 ; WX 500 ; N uni1FEE ; G 2773 +U 8175 ; WX 500 ; N uni1FEF ; G 2774 +U 8178 ; WX 869 ; N uni1FF2 ; G 2775 +U 8179 ; WX 869 ; N uni1FF3 ; G 2776 +U 8180 ; WX 869 ; N uni1FF4 ; G 2777 +U 8182 ; WX 869 ; N uni1FF6 ; G 2778 +U 8183 ; WX 869 ; N uni1FF7 ; G 2779 +U 8184 ; WX 1065 ; N uni1FF8 ; G 2780 +U 8185 ; WX 891 ; N uni1FF9 ; G 2781 +U 8186 ; WX 1084 ; N uni1FFA ; G 2782 +U 8187 ; WX 894 ; N uni1FFB ; G 2783 +U 8188 ; WX 850 ; N uni1FFC ; G 2784 +U 8189 ; WX 500 ; N uni1FFD ; G 2785 +U 8190 ; WX 500 ; N uni1FFE ; G 2786 +U 8192 ; WX 500 ; N uni2000 ; G 2787 +U 8193 ; WX 1000 ; N uni2001 ; G 2788 +U 8194 ; WX 500 ; N uni2002 ; G 2789 +U 8195 ; WX 1000 ; N uni2003 ; G 2790 +U 8196 ; WX 330 ; N uni2004 ; G 2791 +U 8197 ; WX 250 ; N uni2005 ; G 2792 +U 8198 ; WX 167 ; N uni2006 ; G 2793 +U 8199 ; WX 696 ; N uni2007 ; G 2794 +U 8200 ; WX 380 ; N uni2008 ; G 2795 +U 8201 ; WX 200 ; N uni2009 ; G 2796 +U 8202 ; WX 100 ; N uni200A ; G 2797 +U 8203 ; WX 0 ; N uni200B ; G 2798 +U 8204 ; WX 0 ; N uni200C ; G 2799 +U 8205 ; WX 0 ; N uni200D ; G 2800 +U 8206 ; WX 0 ; N uni200E ; G 2801 +U 8207 ; WX 0 ; N uni200F ; G 2802 +U 8208 ; WX 415 ; N uni2010 ; G 2803 +U 8209 ; WX 415 ; N uni2011 ; G 2804 +U 8210 ; WX 696 ; N figuredash ; G 2805 +U 8211 ; WX 500 ; N endash ; G 2806 +U 8212 ; WX 1000 ; N emdash ; G 2807 +U 8213 ; WX 1000 ; N uni2015 ; G 2808 +U 8214 ; WX 500 ; N uni2016 ; G 2809 +U 8215 ; WX 500 ; N underscoredbl ; G 2810 +U 8216 ; WX 380 ; N quoteleft ; G 2811 +U 8217 ; WX 380 ; N quoteright ; G 2812 +U 8218 ; WX 380 ; N quotesinglbase ; G 2813 +U 8219 ; WX 380 ; N quotereversed ; G 2814 +U 8220 ; WX 657 ; N quotedblleft ; G 2815 +U 8221 ; WX 657 ; N quotedblright ; G 2816 +U 8222 ; WX 657 ; N quotedblbase ; G 2817 +U 8223 ; WX 657 ; N uni201F ; G 2818 +U 8224 ; WX 500 ; N dagger ; G 2819 +U 8225 ; WX 500 ; N daggerdbl ; G 2820 +U 8226 ; WX 639 ; N bullet ; G 2821 +U 8227 ; WX 639 ; N uni2023 ; G 2822 +U 8228 ; WX 333 ; N onedotenleader ; G 2823 +U 8229 ; WX 667 ; N twodotenleader ; G 2824 +U 8230 ; WX 1000 ; N ellipsis ; G 2825 +U 8231 ; WX 348 ; N uni2027 ; G 2826 +U 8232 ; WX 0 ; N uni2028 ; G 2827 +U 8233 ; WX 0 ; N uni2029 ; G 2828 +U 8234 ; WX 0 ; N uni202A ; G 2829 +U 8235 ; WX 0 ; N uni202B ; G 2830 +U 8236 ; WX 0 ; N uni202C ; G 2831 +U 8237 ; WX 0 ; N uni202D ; G 2832 +U 8238 ; WX 0 ; N uni202E ; G 2833 +U 8239 ; WX 200 ; N uni202F ; G 2834 +U 8240 ; WX 1440 ; N perthousand ; G 2835 +U 8241 ; WX 1887 ; N uni2031 ; G 2836 +U 8242 ; WX 264 ; N minute ; G 2837 +U 8243 ; WX 447 ; N second ; G 2838 +U 8244 ; WX 630 ; N uni2034 ; G 2839 +U 8245 ; WX 264 ; N uni2035 ; G 2840 +U 8246 ; WX 447 ; N uni2036 ; G 2841 +U 8247 ; WX 630 ; N uni2037 ; G 2842 +U 8248 ; WX 733 ; N uni2038 ; G 2843 +U 8249 ; WX 412 ; N guilsinglleft ; G 2844 +U 8250 ; WX 412 ; N guilsinglright ; G 2845 +U 8251 ; WX 972 ; N uni203B ; G 2846 +U 8252 ; WX 627 ; N exclamdbl ; G 2847 +U 8253 ; WX 580 ; N uni203D ; G 2848 +U 8254 ; WX 500 ; N uni203E ; G 2849 +U 8255 ; WX 828 ; N uni203F ; G 2850 +U 8256 ; WX 828 ; N uni2040 ; G 2851 +U 8257 ; WX 329 ; N uni2041 ; G 2852 +U 8258 ; WX 1023 ; N uni2042 ; G 2853 +U 8259 ; WX 500 ; N uni2043 ; G 2854 +U 8260 ; WX 167 ; N fraction ; G 2855 +U 8261 ; WX 457 ; N uni2045 ; G 2856 +U 8262 ; WX 457 ; N uni2046 ; G 2857 +U 8263 ; WX 1030 ; N uni2047 ; G 2858 +U 8264 ; WX 829 ; N uni2048 ; G 2859 +U 8265 ; WX 829 ; N uni2049 ; G 2860 +U 8266 ; WX 513 ; N uni204A ; G 2861 +U 8267 ; WX 636 ; N uni204B ; G 2862 +U 8268 ; WX 500 ; N uni204C ; G 2863 +U 8269 ; WX 500 ; N uni204D ; G 2864 +U 8270 ; WX 523 ; N uni204E ; G 2865 +U 8271 ; WX 400 ; N uni204F ; G 2866 +U 8272 ; WX 828 ; N uni2050 ; G 2867 +U 8273 ; WX 523 ; N uni2051 ; G 2868 +U 8274 ; WX 556 ; N uni2052 ; G 2869 +U 8275 ; WX 1000 ; N uni2053 ; G 2870 +U 8276 ; WX 828 ; N uni2054 ; G 2871 +U 8277 ; WX 838 ; N uni2055 ; G 2872 +U 8278 ; WX 684 ; N uni2056 ; G 2873 +U 8279 ; WX 813 ; N uni2057 ; G 2874 +U 8280 ; WX 838 ; N uni2058 ; G 2875 +U 8281 ; WX 838 ; N uni2059 ; G 2876 +U 8282 ; WX 380 ; N uni205A ; G 2877 +U 8283 ; WX 872 ; N uni205B ; G 2878 +U 8284 ; WX 838 ; N uni205C ; G 2879 +U 8285 ; WX 380 ; N uni205D ; G 2880 +U 8286 ; WX 380 ; N uni205E ; G 2881 +U 8287 ; WX 222 ; N uni205F ; G 2882 +U 8288 ; WX 0 ; N uni2060 ; G 2883 +U 8289 ; WX 0 ; N uni2061 ; G 2884 +U 8290 ; WX 0 ; N uni2062 ; G 2885 +U 8291 ; WX 0 ; N uni2063 ; G 2886 +U 8292 ; WX 0 ; N uni2064 ; G 2887 +U 8298 ; WX 0 ; N uni206A ; G 2888 +U 8299 ; WX 0 ; N uni206B ; G 2889 +U 8300 ; WX 0 ; N uni206C ; G 2890 +U 8301 ; WX 0 ; N uni206D ; G 2891 +U 8302 ; WX 0 ; N uni206E ; G 2892 +U 8303 ; WX 0 ; N uni206F ; G 2893 +U 8304 ; WX 438 ; N uni2070 ; G 2894 +U 8305 ; WX 219 ; N uni2071 ; G 2895 +U 8308 ; WX 438 ; N uni2074 ; G 2896 +U 8309 ; WX 438 ; N uni2075 ; G 2897 +U 8310 ; WX 438 ; N uni2076 ; G 2898 +U 8311 ; WX 438 ; N uni2077 ; G 2899 +U 8312 ; WX 438 ; N uni2078 ; G 2900 +U 8313 ; WX 438 ; N uni2079 ; G 2901 +U 8314 ; WX 528 ; N uni207A ; G 2902 +U 8315 ; WX 528 ; N uni207B ; G 2903 +U 8316 ; WX 528 ; N uni207C ; G 2904 +U 8317 ; WX 288 ; N uni207D ; G 2905 +U 8318 ; WX 288 ; N uni207E ; G 2906 +U 8319 ; WX 456 ; N uni207F ; G 2907 +U 8320 ; WX 438 ; N uni2080 ; G 2908 +U 8321 ; WX 438 ; N uni2081 ; G 2909 +U 8322 ; WX 438 ; N uni2082 ; G 2910 +U 8323 ; WX 438 ; N uni2083 ; G 2911 +U 8324 ; WX 438 ; N uni2084 ; G 2912 +U 8325 ; WX 438 ; N uni2085 ; G 2913 +U 8326 ; WX 438 ; N uni2086 ; G 2914 +U 8327 ; WX 438 ; N uni2087 ; G 2915 +U 8328 ; WX 438 ; N uni2088 ; G 2916 +U 8329 ; WX 438 ; N uni2089 ; G 2917 +U 8330 ; WX 528 ; N uni208A ; G 2918 +U 8331 ; WX 528 ; N uni208B ; G 2919 +U 8332 ; WX 528 ; N uni208C ; G 2920 +U 8333 ; WX 288 ; N uni208D ; G 2921 +U 8334 ; WX 288 ; N uni208E ; G 2922 +U 8336 ; WX 458 ; N uni2090 ; G 2923 +U 8337 ; WX 479 ; N uni2091 ; G 2924 +U 8338 ; WX 488 ; N uni2092 ; G 2925 +U 8339 ; WX 413 ; N uni2093 ; G 2926 +U 8340 ; WX 479 ; N uni2094 ; G 2927 +U 8341 ; WX 456 ; N uni2095 ; G 2928 +U 8342 ; WX 487 ; N uni2096 ; G 2929 +U 8343 ; WX 219 ; N uni2097 ; G 2930 +U 8344 ; WX 664 ; N uni2098 ; G 2931 +U 8345 ; WX 456 ; N uni2099 ; G 2932 +U 8346 ; WX 479 ; N uni209A ; G 2933 +U 8347 ; WX 381 ; N uni209B ; G 2934 +U 8348 ; WX 388 ; N uni209C ; G 2935 +U 8352 ; WX 929 ; N uni20A0 ; G 2936 +U 8353 ; WX 696 ; N colonmonetary ; G 2937 +U 8354 ; WX 696 ; N uni20A2 ; G 2938 +U 8355 ; WX 696 ; N franc ; G 2939 +U 8356 ; WX 696 ; N lira ; G 2940 +U 8357 ; WX 1042 ; N uni20A5 ; G 2941 +U 8358 ; WX 696 ; N uni20A6 ; G 2942 +U 8359 ; WX 1518 ; N peseta ; G 2943 +U 8360 ; WX 1205 ; N uni20A8 ; G 2944 +U 8361 ; WX 1103 ; N uni20A9 ; G 2945 +U 8362 ; WX 904 ; N uni20AA ; G 2946 +U 8363 ; WX 696 ; N dong ; G 2947 +U 8364 ; WX 696 ; N Euro ; G 2948 +U 8365 ; WX 696 ; N uni20AD ; G 2949 +U 8366 ; WX 696 ; N uni20AE ; G 2950 +U 8367 ; WX 1392 ; N uni20AF ; G 2951 +U 8368 ; WX 696 ; N uni20B0 ; G 2952 +U 8369 ; WX 696 ; N uni20B1 ; G 2953 +U 8370 ; WX 696 ; N uni20B2 ; G 2954 +U 8371 ; WX 696 ; N uni20B3 ; G 2955 +U 8372 ; WX 859 ; N uni20B4 ; G 2956 +U 8373 ; WX 696 ; N uni20B5 ; G 2957 +U 8376 ; WX 696 ; N uni20B8 ; G 2958 +U 8377 ; WX 696 ; N uni20B9 ; G 2959 +U 8378 ; WX 696 ; N uni20BA ; G 2960 +U 8381 ; WX 696 ; N uni20BD ; G 2961 +U 8400 ; WX 0 ; N uni20D0 ; G 2962 +U 8401 ; WX 0 ; N uni20D1 ; G 2963 +U 8406 ; WX 0 ; N uni20D6 ; G 2964 +U 8407 ; WX 0 ; N uni20D7 ; G 2965 +U 8411 ; WX 0 ; N uni20DB ; G 2966 +U 8412 ; WX 0 ; N uni20DC ; G 2967 +U 8417 ; WX 0 ; N uni20E1 ; G 2968 +U 8448 ; WX 1120 ; N uni2100 ; G 2969 +U 8449 ; WX 1170 ; N uni2101 ; G 2970 +U 8450 ; WX 734 ; N uni2102 ; G 2971 +U 8451 ; WX 1211 ; N uni2103 ; G 2972 +U 8452 ; WX 896 ; N uni2104 ; G 2973 +U 8453 ; WX 1091 ; N uni2105 ; G 2974 +U 8454 ; WX 1144 ; N uni2106 ; G 2975 +U 8455 ; WX 614 ; N uni2107 ; G 2976 +U 8456 ; WX 698 ; N uni2108 ; G 2977 +U 8457 ; WX 1086 ; N uni2109 ; G 2978 +U 8459 ; WX 1073 ; N uni210B ; G 2979 +U 8460 ; WX 913 ; N uni210C ; G 2980 +U 8461 ; WX 888 ; N uni210D ; G 2981 +U 8462 ; WX 712 ; N uni210E ; G 2982 +U 8463 ; WX 712 ; N uni210F ; G 2983 +U 8464 ; WX 597 ; N uni2110 ; G 2984 +U 8465 ; WX 697 ; N Ifraktur ; G 2985 +U 8466 ; WX 856 ; N uni2112 ; G 2986 +U 8467 ; WX 472 ; N uni2113 ; G 2987 +U 8468 ; WX 974 ; N uni2114 ; G 2988 +U 8469 ; WX 837 ; N uni2115 ; G 2989 +U 8470 ; WX 1203 ; N uni2116 ; G 2990 +U 8471 ; WX 1000 ; N uni2117 ; G 2991 +U 8472 ; WX 697 ; N weierstrass ; G 2992 +U 8473 ; WX 750 ; N uni2119 ; G 2993 +U 8474 ; WX 850 ; N uni211A ; G 2994 +U 8475 ; WX 938 ; N uni211B ; G 2995 +U 8476 ; WX 814 ; N Rfraktur ; G 2996 +U 8477 ; WX 801 ; N uni211D ; G 2997 +U 8478 ; WX 896 ; N prescription ; G 2998 +U 8479 ; WX 710 ; N uni211F ; G 2999 +U 8480 ; WX 1020 ; N uni2120 ; G 3000 +U 8481 ; WX 1281 ; N uni2121 ; G 3001 +U 8482 ; WX 1000 ; N trademark ; G 3002 +U 8483 ; WX 755 ; N uni2123 ; G 3003 +U 8484 ; WX 754 ; N uni2124 ; G 3004 +U 8485 ; WX 578 ; N uni2125 ; G 3005 +U 8486 ; WX 850 ; N uni2126 ; G 3006 +U 8487 ; WX 850 ; N uni2127 ; G 3007 +U 8488 ; WX 763 ; N uni2128 ; G 3008 +U 8489 ; WX 338 ; N uni2129 ; G 3009 +U 8490 ; WX 775 ; N uni212A ; G 3010 +U 8491 ; WX 774 ; N uni212B ; G 3011 +U 8492 ; WX 928 ; N uni212C ; G 3012 +U 8493 ; WX 818 ; N uni212D ; G 3013 +U 8494 ; WX 854 ; N estimated ; G 3014 +U 8495 ; WX 636 ; N uni212F ; G 3015 +U 8496 ; WX 729 ; N uni2130 ; G 3016 +U 8497 ; WX 808 ; N uni2131 ; G 3017 +U 8498 ; WX 683 ; N uni2132 ; G 3018 +U 8499 ; WX 1184 ; N uni2133 ; G 3019 +U 8500 ; WX 465 ; N uni2134 ; G 3020 +U 8501 ; WX 794 ; N aleph ; G 3021 +U 8502 ; WX 731 ; N uni2136 ; G 3022 +U 8503 ; WX 494 ; N uni2137 ; G 3023 +U 8504 ; WX 684 ; N uni2138 ; G 3024 +U 8505 ; WX 380 ; N uni2139 ; G 3025 +U 8506 ; WX 945 ; N uni213A ; G 3026 +U 8507 ; WX 1348 ; N uni213B ; G 3027 +U 8508 ; WX 790 ; N uni213C ; G 3028 +U 8509 ; WX 737 ; N uni213D ; G 3029 +U 8510 ; WX 654 ; N uni213E ; G 3030 +U 8511 ; WX 863 ; N uni213F ; G 3031 +U 8512 ; WX 840 ; N uni2140 ; G 3032 +U 8513 ; WX 775 ; N uni2141 ; G 3033 +U 8514 ; WX 557 ; N uni2142 ; G 3034 +U 8515 ; WX 637 ; N uni2143 ; G 3035 +U 8516 ; WX 760 ; N uni2144 ; G 3036 +U 8517 ; WX 830 ; N uni2145 ; G 3037 +U 8518 ; WX 716 ; N uni2146 ; G 3038 +U 8519 ; WX 678 ; N uni2147 ; G 3039 +U 8520 ; WX 343 ; N uni2148 ; G 3040 +U 8521 ; WX 343 ; N uni2149 ; G 3041 +U 8523 ; WX 872 ; N uni214B ; G 3042 +U 8526 ; WX 547 ; N uni214E ; G 3043 +U 8528 ; WX 1035 ; N uni2150 ; G 3044 +U 8529 ; WX 1035 ; N uni2151 ; G 3045 +U 8530 ; WX 1483 ; N uni2152 ; G 3046 +U 8531 ; WX 1035 ; N onethird ; G 3047 +U 8532 ; WX 1035 ; N twothirds ; G 3048 +U 8533 ; WX 1035 ; N uni2155 ; G 3049 +U 8534 ; WX 1035 ; N uni2156 ; G 3050 +U 8535 ; WX 1035 ; N uni2157 ; G 3051 +U 8536 ; WX 1035 ; N uni2158 ; G 3052 +U 8537 ; WX 1035 ; N uni2159 ; G 3053 +U 8538 ; WX 1035 ; N uni215A ; G 3054 +U 8539 ; WX 1035 ; N oneeighth ; G 3055 +U 8540 ; WX 1035 ; N threeeighths ; G 3056 +U 8541 ; WX 1035 ; N fiveeighths ; G 3057 +U 8542 ; WX 1035 ; N seveneighths ; G 3058 +U 8543 ; WX 615 ; N uni215F ; G 3059 +U 8544 ; WX 372 ; N uni2160 ; G 3060 +U 8545 ; WX 659 ; N uni2161 ; G 3061 +U 8546 ; WX 945 ; N uni2162 ; G 3062 +U 8547 ; WX 1099 ; N uni2163 ; G 3063 +U 8548 ; WX 774 ; N uni2164 ; G 3064 +U 8549 ; WX 1099 ; N uni2165 ; G 3065 +U 8550 ; WX 1386 ; N uni2166 ; G 3066 +U 8551 ; WX 1672 ; N uni2167 ; G 3067 +U 8552 ; WX 1121 ; N uni2168 ; G 3068 +U 8553 ; WX 771 ; N uni2169 ; G 3069 +U 8554 ; WX 1120 ; N uni216A ; G 3070 +U 8555 ; WX 1407 ; N uni216B ; G 3071 +U 8556 ; WX 637 ; N uni216C ; G 3072 +U 8557 ; WX 734 ; N uni216D ; G 3073 +U 8558 ; WX 830 ; N uni216E ; G 3074 +U 8559 ; WX 995 ; N uni216F ; G 3075 +U 8560 ; WX 343 ; N uni2170 ; G 3076 +U 8561 ; WX 607 ; N uni2171 ; G 3077 +U 8562 ; WX 872 ; N uni2172 ; G 3078 +U 8563 ; WX 984 ; N uni2173 ; G 3079 +U 8564 ; WX 652 ; N uni2174 ; G 3080 +U 8565 ; WX 962 ; N uni2175 ; G 3081 +U 8566 ; WX 1227 ; N uni2176 ; G 3082 +U 8567 ; WX 1491 ; N uni2177 ; G 3083 +U 8568 ; WX 969 ; N uni2178 ; G 3084 +U 8569 ; WX 645 ; N uni2179 ; G 3085 +U 8570 ; WX 969 ; N uni217A ; G 3086 +U 8571 ; WX 1233 ; N uni217B ; G 3087 +U 8572 ; WX 343 ; N uni217C ; G 3088 +U 8573 ; WX 593 ; N uni217D ; G 3089 +U 8574 ; WX 716 ; N uni217E ; G 3090 +U 8575 ; WX 1042 ; N uni217F ; G 3091 +U 8576 ; WX 1289 ; N uni2180 ; G 3092 +U 8577 ; WX 830 ; N uni2181 ; G 3093 +U 8578 ; WX 1289 ; N uni2182 ; G 3094 +U 8579 ; WX 734 ; N uni2183 ; G 3095 +U 8580 ; WX 593 ; N uni2184 ; G 3096 +U 8581 ; WX 734 ; N uni2185 ; G 3097 +U 8585 ; WX 1035 ; N uni2189 ; G 3098 +U 8592 ; WX 838 ; N arrowleft ; G 3099 +U 8593 ; WX 838 ; N arrowup ; G 3100 +U 8594 ; WX 838 ; N arrowright ; G 3101 +U 8595 ; WX 838 ; N arrowdown ; G 3102 +U 8596 ; WX 838 ; N arrowboth ; G 3103 +U 8597 ; WX 838 ; N arrowupdn ; G 3104 +U 8598 ; WX 838 ; N uni2196 ; G 3105 +U 8599 ; WX 838 ; N uni2197 ; G 3106 +U 8600 ; WX 838 ; N uni2198 ; G 3107 +U 8601 ; WX 838 ; N uni2199 ; G 3108 +U 8602 ; WX 838 ; N uni219A ; G 3109 +U 8603 ; WX 838 ; N uni219B ; G 3110 +U 8604 ; WX 838 ; N uni219C ; G 3111 +U 8605 ; WX 838 ; N uni219D ; G 3112 +U 8606 ; WX 838 ; N uni219E ; G 3113 +U 8607 ; WX 838 ; N uni219F ; G 3114 +U 8608 ; WX 838 ; N uni21A0 ; G 3115 +U 8609 ; WX 838 ; N uni21A1 ; G 3116 +U 8610 ; WX 838 ; N uni21A2 ; G 3117 +U 8611 ; WX 838 ; N uni21A3 ; G 3118 +U 8612 ; WX 838 ; N uni21A4 ; G 3119 +U 8613 ; WX 838 ; N uni21A5 ; G 3120 +U 8614 ; WX 838 ; N uni21A6 ; G 3121 +U 8615 ; WX 838 ; N uni21A7 ; G 3122 +U 8616 ; WX 838 ; N arrowupdnbse ; G 3123 +U 8617 ; WX 838 ; N uni21A9 ; G 3124 +U 8618 ; WX 838 ; N uni21AA ; G 3125 +U 8619 ; WX 838 ; N uni21AB ; G 3126 +U 8620 ; WX 838 ; N uni21AC ; G 3127 +U 8621 ; WX 838 ; N uni21AD ; G 3128 +U 8622 ; WX 838 ; N uni21AE ; G 3129 +U 8623 ; WX 838 ; N uni21AF ; G 3130 +U 8624 ; WX 838 ; N uni21B0 ; G 3131 +U 8625 ; WX 838 ; N uni21B1 ; G 3132 +U 8626 ; WX 838 ; N uni21B2 ; G 3133 +U 8627 ; WX 838 ; N uni21B3 ; G 3134 +U 8628 ; WX 838 ; N uni21B4 ; G 3135 +U 8629 ; WX 838 ; N carriagereturn ; G 3136 +U 8630 ; WX 838 ; N uni21B6 ; G 3137 +U 8631 ; WX 838 ; N uni21B7 ; G 3138 +U 8632 ; WX 838 ; N uni21B8 ; G 3139 +U 8633 ; WX 838 ; N uni21B9 ; G 3140 +U 8634 ; WX 838 ; N uni21BA ; G 3141 +U 8635 ; WX 838 ; N uni21BB ; G 3142 +U 8636 ; WX 838 ; N uni21BC ; G 3143 +U 8637 ; WX 838 ; N uni21BD ; G 3144 +U 8638 ; WX 838 ; N uni21BE ; G 3145 +U 8639 ; WX 838 ; N uni21BF ; G 3146 +U 8640 ; WX 838 ; N uni21C0 ; G 3147 +U 8641 ; WX 838 ; N uni21C1 ; G 3148 +U 8642 ; WX 838 ; N uni21C2 ; G 3149 +U 8643 ; WX 838 ; N uni21C3 ; G 3150 +U 8644 ; WX 838 ; N uni21C4 ; G 3151 +U 8645 ; WX 838 ; N uni21C5 ; G 3152 +U 8646 ; WX 838 ; N uni21C6 ; G 3153 +U 8647 ; WX 838 ; N uni21C7 ; G 3154 +U 8648 ; WX 838 ; N uni21C8 ; G 3155 +U 8649 ; WX 838 ; N uni21C9 ; G 3156 +U 8650 ; WX 838 ; N uni21CA ; G 3157 +U 8651 ; WX 838 ; N uni21CB ; G 3158 +U 8652 ; WX 838 ; N uni21CC ; G 3159 +U 8653 ; WX 838 ; N uni21CD ; G 3160 +U 8654 ; WX 838 ; N uni21CE ; G 3161 +U 8655 ; WX 838 ; N uni21CF ; G 3162 +U 8656 ; WX 838 ; N arrowdblleft ; G 3163 +U 8657 ; WX 838 ; N arrowdblup ; G 3164 +U 8658 ; WX 838 ; N arrowdblright ; G 3165 +U 8659 ; WX 838 ; N arrowdbldown ; G 3166 +U 8660 ; WX 838 ; N arrowdblboth ; G 3167 +U 8661 ; WX 838 ; N uni21D5 ; G 3168 +U 8662 ; WX 838 ; N uni21D6 ; G 3169 +U 8663 ; WX 838 ; N uni21D7 ; G 3170 +U 8664 ; WX 838 ; N uni21D8 ; G 3171 +U 8665 ; WX 838 ; N uni21D9 ; G 3172 +U 8666 ; WX 838 ; N uni21DA ; G 3173 +U 8667 ; WX 838 ; N uni21DB ; G 3174 +U 8668 ; WX 838 ; N uni21DC ; G 3175 +U 8669 ; WX 838 ; N uni21DD ; G 3176 +U 8670 ; WX 838 ; N uni21DE ; G 3177 +U 8671 ; WX 838 ; N uni21DF ; G 3178 +U 8672 ; WX 838 ; N uni21E0 ; G 3179 +U 8673 ; WX 838 ; N uni21E1 ; G 3180 +U 8674 ; WX 838 ; N uni21E2 ; G 3181 +U 8675 ; WX 838 ; N uni21E3 ; G 3182 +U 8676 ; WX 838 ; N uni21E4 ; G 3183 +U 8677 ; WX 838 ; N uni21E5 ; G 3184 +U 8678 ; WX 838 ; N uni21E6 ; G 3185 +U 8679 ; WX 838 ; N uni21E7 ; G 3186 +U 8680 ; WX 838 ; N uni21E8 ; G 3187 +U 8681 ; WX 838 ; N uni21E9 ; G 3188 +U 8682 ; WX 838 ; N uni21EA ; G 3189 +U 8683 ; WX 838 ; N uni21EB ; G 3190 +U 8684 ; WX 838 ; N uni21EC ; G 3191 +U 8685 ; WX 838 ; N uni21ED ; G 3192 +U 8686 ; WX 838 ; N uni21EE ; G 3193 +U 8687 ; WX 838 ; N uni21EF ; G 3194 +U 8688 ; WX 838 ; N uni21F0 ; G 3195 +U 8689 ; WX 838 ; N uni21F1 ; G 3196 +U 8690 ; WX 838 ; N uni21F2 ; G 3197 +U 8691 ; WX 838 ; N uni21F3 ; G 3198 +U 8692 ; WX 838 ; N uni21F4 ; G 3199 +U 8693 ; WX 838 ; N uni21F5 ; G 3200 +U 8694 ; WX 838 ; N uni21F6 ; G 3201 +U 8695 ; WX 838 ; N uni21F7 ; G 3202 +U 8696 ; WX 838 ; N uni21F8 ; G 3203 +U 8697 ; WX 838 ; N uni21F9 ; G 3204 +U 8698 ; WX 838 ; N uni21FA ; G 3205 +U 8699 ; WX 838 ; N uni21FB ; G 3206 +U 8700 ; WX 838 ; N uni21FC ; G 3207 +U 8701 ; WX 838 ; N uni21FD ; G 3208 +U 8702 ; WX 838 ; N uni21FE ; G 3209 +U 8703 ; WX 838 ; N uni21FF ; G 3210 +U 8704 ; WX 774 ; N universal ; G 3211 +U 8705 ; WX 696 ; N uni2201 ; G 3212 +U 8706 ; WX 544 ; N partialdiff ; G 3213 +U 8707 ; WX 683 ; N existential ; G 3214 +U 8708 ; WX 683 ; N uni2204 ; G 3215 +U 8709 ; WX 856 ; N emptyset ; G 3216 +U 8710 ; WX 697 ; N increment ; G 3217 +U 8711 ; WX 697 ; N gradient ; G 3218 +U 8712 ; WX 896 ; N element ; G 3219 +U 8713 ; WX 896 ; N notelement ; G 3220 +U 8714 ; WX 750 ; N uni220A ; G 3221 +U 8715 ; WX 896 ; N suchthat ; G 3222 +U 8716 ; WX 896 ; N uni220C ; G 3223 +U 8717 ; WX 750 ; N uni220D ; G 3224 +U 8718 ; WX 636 ; N uni220E ; G 3225 +U 8719 ; WX 787 ; N product ; G 3226 +U 8720 ; WX 787 ; N uni2210 ; G 3227 +U 8721 ; WX 718 ; N summation ; G 3228 +U 8722 ; WX 838 ; N minus ; G 3229 +U 8723 ; WX 838 ; N uni2213 ; G 3230 +U 8724 ; WX 696 ; N uni2214 ; G 3231 +U 8725 ; WX 365 ; N uni2215 ; G 3232 +U 8726 ; WX 696 ; N uni2216 ; G 3233 +U 8727 ; WX 838 ; N asteriskmath ; G 3234 +U 8728 ; WX 626 ; N uni2218 ; G 3235 +U 8729 ; WX 380 ; N uni2219 ; G 3236 +U 8730 ; WX 667 ; N radical ; G 3237 +U 8731 ; WX 667 ; N uni221B ; G 3238 +U 8732 ; WX 667 ; N uni221C ; G 3239 +U 8733 ; WX 712 ; N proportional ; G 3240 +U 8734 ; WX 833 ; N infinity ; G 3241 +U 8735 ; WX 838 ; N orthogonal ; G 3242 +U 8736 ; WX 896 ; N angle ; G 3243 +U 8737 ; WX 896 ; N uni2221 ; G 3244 +U 8738 ; WX 838 ; N uni2222 ; G 3245 +U 8739 ; WX 500 ; N uni2223 ; G 3246 +U 8740 ; WX 500 ; N uni2224 ; G 3247 +U 8741 ; WX 500 ; N uni2225 ; G 3248 +U 8742 ; WX 500 ; N uni2226 ; G 3249 +U 8743 ; WX 812 ; N logicaland ; G 3250 +U 8744 ; WX 812 ; N logicalor ; G 3251 +U 8745 ; WX 812 ; N intersection ; G 3252 +U 8746 ; WX 812 ; N union ; G 3253 +U 8747 ; WX 610 ; N integral ; G 3254 +U 8748 ; WX 929 ; N uni222C ; G 3255 +U 8749 ; WX 1295 ; N uni222D ; G 3256 +U 8750 ; WX 563 ; N uni222E ; G 3257 +U 8751 ; WX 977 ; N uni222F ; G 3258 +U 8752 ; WX 1313 ; N uni2230 ; G 3259 +U 8753 ; WX 563 ; N uni2231 ; G 3260 +U 8754 ; WX 563 ; N uni2232 ; G 3261 +U 8755 ; WX 563 ; N uni2233 ; G 3262 +U 8756 ; WX 696 ; N therefore ; G 3263 +U 8757 ; WX 696 ; N uni2235 ; G 3264 +U 8758 ; WX 294 ; N uni2236 ; G 3265 +U 8759 ; WX 696 ; N uni2237 ; G 3266 +U 8760 ; WX 838 ; N uni2238 ; G 3267 +U 8761 ; WX 838 ; N uni2239 ; G 3268 +U 8762 ; WX 838 ; N uni223A ; G 3269 +U 8763 ; WX 838 ; N uni223B ; G 3270 +U 8764 ; WX 838 ; N similar ; G 3271 +U 8765 ; WX 838 ; N uni223D ; G 3272 +U 8766 ; WX 838 ; N uni223E ; G 3273 +U 8767 ; WX 838 ; N uni223F ; G 3274 +U 8768 ; WX 375 ; N uni2240 ; G 3275 +U 8769 ; WX 838 ; N uni2241 ; G 3276 +U 8770 ; WX 838 ; N uni2242 ; G 3277 +U 8771 ; WX 838 ; N uni2243 ; G 3278 +U 8772 ; WX 838 ; N uni2244 ; G 3279 +U 8773 ; WX 838 ; N congruent ; G 3280 +U 8774 ; WX 838 ; N uni2246 ; G 3281 +U 8775 ; WX 838 ; N uni2247 ; G 3282 +U 8776 ; WX 838 ; N approxequal ; G 3283 +U 8777 ; WX 838 ; N uni2249 ; G 3284 +U 8778 ; WX 838 ; N uni224A ; G 3285 +U 8779 ; WX 838 ; N uni224B ; G 3286 +U 8780 ; WX 838 ; N uni224C ; G 3287 +U 8781 ; WX 838 ; N uni224D ; G 3288 +U 8782 ; WX 838 ; N uni224E ; G 3289 +U 8783 ; WX 838 ; N uni224F ; G 3290 +U 8784 ; WX 838 ; N uni2250 ; G 3291 +U 8785 ; WX 838 ; N uni2251 ; G 3292 +U 8786 ; WX 838 ; N uni2252 ; G 3293 +U 8787 ; WX 838 ; N uni2253 ; G 3294 +U 8788 ; WX 1063 ; N uni2254 ; G 3295 +U 8789 ; WX 1063 ; N uni2255 ; G 3296 +U 8790 ; WX 838 ; N uni2256 ; G 3297 +U 8791 ; WX 838 ; N uni2257 ; G 3298 +U 8792 ; WX 838 ; N uni2258 ; G 3299 +U 8793 ; WX 838 ; N uni2259 ; G 3300 +U 8794 ; WX 838 ; N uni225A ; G 3301 +U 8795 ; WX 838 ; N uni225B ; G 3302 +U 8796 ; WX 838 ; N uni225C ; G 3303 +U 8797 ; WX 838 ; N uni225D ; G 3304 +U 8798 ; WX 838 ; N uni225E ; G 3305 +U 8799 ; WX 838 ; N uni225F ; G 3306 +U 8800 ; WX 838 ; N notequal ; G 3307 +U 8801 ; WX 838 ; N equivalence ; G 3308 +U 8802 ; WX 838 ; N uni2262 ; G 3309 +U 8803 ; WX 838 ; N uni2263 ; G 3310 +U 8804 ; WX 838 ; N lessequal ; G 3311 +U 8805 ; WX 838 ; N greaterequal ; G 3312 +U 8806 ; WX 838 ; N uni2266 ; G 3313 +U 8807 ; WX 838 ; N uni2267 ; G 3314 +U 8808 ; WX 841 ; N uni2268 ; G 3315 +U 8809 ; WX 841 ; N uni2269 ; G 3316 +U 8810 ; WX 1047 ; N uni226A ; G 3317 +U 8811 ; WX 1047 ; N uni226B ; G 3318 +U 8812 ; WX 500 ; N uni226C ; G 3319 +U 8813 ; WX 838 ; N uni226D ; G 3320 +U 8814 ; WX 838 ; N uni226E ; G 3321 +U 8815 ; WX 838 ; N uni226F ; G 3322 +U 8816 ; WX 838 ; N uni2270 ; G 3323 +U 8817 ; WX 838 ; N uni2271 ; G 3324 +U 8818 ; WX 838 ; N uni2272 ; G 3325 +U 8819 ; WX 838 ; N uni2273 ; G 3326 +U 8820 ; WX 838 ; N uni2274 ; G 3327 +U 8821 ; WX 838 ; N uni2275 ; G 3328 +U 8822 ; WX 838 ; N uni2276 ; G 3329 +U 8823 ; WX 838 ; N uni2277 ; G 3330 +U 8824 ; WX 838 ; N uni2278 ; G 3331 +U 8825 ; WX 838 ; N uni2279 ; G 3332 +U 8826 ; WX 838 ; N uni227A ; G 3333 +U 8827 ; WX 838 ; N uni227B ; G 3334 +U 8828 ; WX 838 ; N uni227C ; G 3335 +U 8829 ; WX 838 ; N uni227D ; G 3336 +U 8830 ; WX 838 ; N uni227E ; G 3337 +U 8831 ; WX 838 ; N uni227F ; G 3338 +U 8832 ; WX 838 ; N uni2280 ; G 3339 +U 8833 ; WX 838 ; N uni2281 ; G 3340 +U 8834 ; WX 838 ; N propersubset ; G 3341 +U 8835 ; WX 838 ; N propersuperset ; G 3342 +U 8836 ; WX 838 ; N notsubset ; G 3343 +U 8837 ; WX 838 ; N uni2285 ; G 3344 +U 8838 ; WX 838 ; N reflexsubset ; G 3345 +U 8839 ; WX 838 ; N reflexsuperset ; G 3346 +U 8840 ; WX 838 ; N uni2288 ; G 3347 +U 8841 ; WX 838 ; N uni2289 ; G 3348 +U 8842 ; WX 838 ; N uni228A ; G 3349 +U 8843 ; WX 838 ; N uni228B ; G 3350 +U 8844 ; WX 812 ; N uni228C ; G 3351 +U 8845 ; WX 812 ; N uni228D ; G 3352 +U 8846 ; WX 812 ; N uni228E ; G 3353 +U 8847 ; WX 838 ; N uni228F ; G 3354 +U 8848 ; WX 838 ; N uni2290 ; G 3355 +U 8849 ; WX 838 ; N uni2291 ; G 3356 +U 8850 ; WX 838 ; N uni2292 ; G 3357 +U 8851 ; WX 796 ; N uni2293 ; G 3358 +U 8852 ; WX 796 ; N uni2294 ; G 3359 +U 8853 ; WX 838 ; N circleplus ; G 3360 +U 8854 ; WX 838 ; N uni2296 ; G 3361 +U 8855 ; WX 838 ; N circlemultiply ; G 3362 +U 8856 ; WX 838 ; N uni2298 ; G 3363 +U 8857 ; WX 838 ; N uni2299 ; G 3364 +U 8858 ; WX 838 ; N uni229A ; G 3365 +U 8859 ; WX 838 ; N uni229B ; G 3366 +U 8860 ; WX 838 ; N uni229C ; G 3367 +U 8861 ; WX 838 ; N uni229D ; G 3368 +U 8862 ; WX 838 ; N uni229E ; G 3369 +U 8863 ; WX 838 ; N uni229F ; G 3370 +U 8864 ; WX 838 ; N uni22A0 ; G 3371 +U 8865 ; WX 838 ; N uni22A1 ; G 3372 +U 8866 ; WX 914 ; N uni22A2 ; G 3373 +U 8867 ; WX 914 ; N uni22A3 ; G 3374 +U 8868 ; WX 914 ; N uni22A4 ; G 3375 +U 8869 ; WX 914 ; N perpendicular ; G 3376 +U 8870 ; WX 542 ; N uni22A6 ; G 3377 +U 8871 ; WX 542 ; N uni22A7 ; G 3378 +U 8872 ; WX 914 ; N uni22A8 ; G 3379 +U 8873 ; WX 914 ; N uni22A9 ; G 3380 +U 8874 ; WX 914 ; N uni22AA ; G 3381 +U 8875 ; WX 914 ; N uni22AB ; G 3382 +U 8876 ; WX 914 ; N uni22AC ; G 3383 +U 8877 ; WX 914 ; N uni22AD ; G 3384 +U 8878 ; WX 914 ; N uni22AE ; G 3385 +U 8879 ; WX 914 ; N uni22AF ; G 3386 +U 8880 ; WX 838 ; N uni22B0 ; G 3387 +U 8881 ; WX 838 ; N uni22B1 ; G 3388 +U 8882 ; WX 838 ; N uni22B2 ; G 3389 +U 8883 ; WX 838 ; N uni22B3 ; G 3390 +U 8884 ; WX 838 ; N uni22B4 ; G 3391 +U 8885 ; WX 838 ; N uni22B5 ; G 3392 +U 8886 ; WX 1000 ; N uni22B6 ; G 3393 +U 8887 ; WX 1000 ; N uni22B7 ; G 3394 +U 8888 ; WX 838 ; N uni22B8 ; G 3395 +U 8889 ; WX 838 ; N uni22B9 ; G 3396 +U 8890 ; WX 542 ; N uni22BA ; G 3397 +U 8891 ; WX 812 ; N uni22BB ; G 3398 +U 8892 ; WX 812 ; N uni22BC ; G 3399 +U 8893 ; WX 812 ; N uni22BD ; G 3400 +U 8894 ; WX 838 ; N uni22BE ; G 3401 +U 8895 ; WX 838 ; N uni22BF ; G 3402 +U 8896 ; WX 843 ; N uni22C0 ; G 3403 +U 8897 ; WX 843 ; N uni22C1 ; G 3404 +U 8898 ; WX 843 ; N uni22C2 ; G 3405 +U 8899 ; WX 843 ; N uni22C3 ; G 3406 +U 8900 ; WX 626 ; N uni22C4 ; G 3407 +U 8901 ; WX 380 ; N dotmath ; G 3408 +U 8902 ; WX 626 ; N uni22C6 ; G 3409 +U 8903 ; WX 838 ; N uni22C7 ; G 3410 +U 8904 ; WX 1000 ; N uni22C8 ; G 3411 +U 8905 ; WX 1000 ; N uni22C9 ; G 3412 +U 8906 ; WX 1000 ; N uni22CA ; G 3413 +U 8907 ; WX 1000 ; N uni22CB ; G 3414 +U 8908 ; WX 1000 ; N uni22CC ; G 3415 +U 8909 ; WX 838 ; N uni22CD ; G 3416 +U 8910 ; WX 812 ; N uni22CE ; G 3417 +U 8911 ; WX 812 ; N uni22CF ; G 3418 +U 8912 ; WX 838 ; N uni22D0 ; G 3419 +U 8913 ; WX 838 ; N uni22D1 ; G 3420 +U 8914 ; WX 838 ; N uni22D2 ; G 3421 +U 8915 ; WX 838 ; N uni22D3 ; G 3422 +U 8916 ; WX 838 ; N uni22D4 ; G 3423 +U 8917 ; WX 838 ; N uni22D5 ; G 3424 +U 8918 ; WX 838 ; N uni22D6 ; G 3425 +U 8919 ; WX 838 ; N uni22D7 ; G 3426 +U 8920 ; WX 1422 ; N uni22D8 ; G 3427 +U 8921 ; WX 1422 ; N uni22D9 ; G 3428 +U 8922 ; WX 838 ; N uni22DA ; G 3429 +U 8923 ; WX 838 ; N uni22DB ; G 3430 +U 8924 ; WX 838 ; N uni22DC ; G 3431 +U 8925 ; WX 838 ; N uni22DD ; G 3432 +U 8926 ; WX 838 ; N uni22DE ; G 3433 +U 8927 ; WX 838 ; N uni22DF ; G 3434 +U 8928 ; WX 838 ; N uni22E0 ; G 3435 +U 8929 ; WX 838 ; N uni22E1 ; G 3436 +U 8930 ; WX 838 ; N uni22E2 ; G 3437 +U 8931 ; WX 838 ; N uni22E3 ; G 3438 +U 8932 ; WX 838 ; N uni22E4 ; G 3439 +U 8933 ; WX 838 ; N uni22E5 ; G 3440 +U 8934 ; WX 838 ; N uni22E6 ; G 3441 +U 8935 ; WX 838 ; N uni22E7 ; G 3442 +U 8936 ; WX 838 ; N uni22E8 ; G 3443 +U 8937 ; WX 838 ; N uni22E9 ; G 3444 +U 8938 ; WX 838 ; N uni22EA ; G 3445 +U 8939 ; WX 838 ; N uni22EB ; G 3446 +U 8940 ; WX 838 ; N uni22EC ; G 3447 +U 8941 ; WX 838 ; N uni22ED ; G 3448 +U 8942 ; WX 1000 ; N uni22EE ; G 3449 +U 8943 ; WX 1000 ; N uni22EF ; G 3450 +U 8944 ; WX 1000 ; N uni22F0 ; G 3451 +U 8945 ; WX 1000 ; N uni22F1 ; G 3452 +U 8946 ; WX 1158 ; N uni22F2 ; G 3453 +U 8947 ; WX 896 ; N uni22F3 ; G 3454 +U 8948 ; WX 750 ; N uni22F4 ; G 3455 +U 8949 ; WX 896 ; N uni22F5 ; G 3456 +U 8950 ; WX 896 ; N uni22F6 ; G 3457 +U 8951 ; WX 750 ; N uni22F7 ; G 3458 +U 8952 ; WX 896 ; N uni22F8 ; G 3459 +U 8953 ; WX 896 ; N uni22F9 ; G 3460 +U 8954 ; WX 1158 ; N uni22FA ; G 3461 +U 8955 ; WX 896 ; N uni22FB ; G 3462 +U 8956 ; WX 750 ; N uni22FC ; G 3463 +U 8957 ; WX 896 ; N uni22FD ; G 3464 +U 8958 ; WX 750 ; N uni22FE ; G 3465 +U 8959 ; WX 896 ; N uni22FF ; G 3466 +U 8960 ; WX 602 ; N uni2300 ; G 3467 +U 8961 ; WX 602 ; N uni2301 ; G 3468 +U 8962 ; WX 716 ; N house ; G 3469 +U 8963 ; WX 838 ; N uni2303 ; G 3470 +U 8964 ; WX 838 ; N uni2304 ; G 3471 +U 8965 ; WX 838 ; N uni2305 ; G 3472 +U 8966 ; WX 838 ; N uni2306 ; G 3473 +U 8967 ; WX 488 ; N uni2307 ; G 3474 +U 8968 ; WX 457 ; N uni2308 ; G 3475 +U 8969 ; WX 457 ; N uni2309 ; G 3476 +U 8970 ; WX 457 ; N uni230A ; G 3477 +U 8971 ; WX 457 ; N uni230B ; G 3478 +U 8972 ; WX 809 ; N uni230C ; G 3479 +U 8973 ; WX 809 ; N uni230D ; G 3480 +U 8974 ; WX 809 ; N uni230E ; G 3481 +U 8975 ; WX 809 ; N uni230F ; G 3482 +U 8976 ; WX 838 ; N revlogicalnot ; G 3483 +U 8977 ; WX 539 ; N uni2311 ; G 3484 +U 8984 ; WX 928 ; N uni2318 ; G 3485 +U 8985 ; WX 838 ; N uni2319 ; G 3486 +U 8988 ; WX 469 ; N uni231C ; G 3487 +U 8989 ; WX 469 ; N uni231D ; G 3488 +U 8990 ; WX 469 ; N uni231E ; G 3489 +U 8991 ; WX 469 ; N uni231F ; G 3490 +U 8992 ; WX 610 ; N integraltp ; G 3491 +U 8993 ; WX 610 ; N integralbt ; G 3492 +U 8996 ; WX 1152 ; N uni2324 ; G 3493 +U 8997 ; WX 1152 ; N uni2325 ; G 3494 +U 8998 ; WX 1414 ; N uni2326 ; G 3495 +U 8999 ; WX 1152 ; N uni2327 ; G 3496 +U 9000 ; WX 1443 ; N uni2328 ; G 3497 +U 9003 ; WX 1414 ; N uni232B ; G 3498 +U 9004 ; WX 873 ; N uni232C ; G 3499 +U 9075 ; WX 390 ; N uni2373 ; G 3500 +U 9076 ; WX 716 ; N uni2374 ; G 3501 +U 9077 ; WX 869 ; N uni2375 ; G 3502 +U 9082 ; WX 687 ; N uni237A ; G 3503 +U 9085 ; WX 863 ; N uni237D ; G 3504 +U 9095 ; WX 1152 ; N uni2387 ; G 3505 +U 9108 ; WX 873 ; N uni2394 ; G 3506 +U 9115 ; WX 500 ; N uni239B ; G 3507 +U 9116 ; WX 500 ; N uni239C ; G 3508 +U 9117 ; WX 500 ; N uni239D ; G 3509 +U 9118 ; WX 500 ; N uni239E ; G 3510 +U 9119 ; WX 500 ; N uni239F ; G 3511 +U 9120 ; WX 500 ; N uni23A0 ; G 3512 +U 9121 ; WX 500 ; N uni23A1 ; G 3513 +U 9122 ; WX 500 ; N uni23A2 ; G 3514 +U 9123 ; WX 500 ; N uni23A3 ; G 3515 +U 9124 ; WX 500 ; N uni23A4 ; G 3516 +U 9125 ; WX 500 ; N uni23A5 ; G 3517 +U 9126 ; WX 500 ; N uni23A6 ; G 3518 +U 9127 ; WX 750 ; N uni23A7 ; G 3519 +U 9128 ; WX 750 ; N uni23A8 ; G 3520 +U 9129 ; WX 750 ; N uni23A9 ; G 3521 +U 9130 ; WX 750 ; N uni23AA ; G 3522 +U 9131 ; WX 750 ; N uni23AB ; G 3523 +U 9132 ; WX 750 ; N uni23AC ; G 3524 +U 9133 ; WX 750 ; N uni23AD ; G 3525 +U 9134 ; WX 610 ; N uni23AE ; G 3526 +U 9166 ; WX 838 ; N uni23CE ; G 3527 +U 9167 ; WX 945 ; N uni23CF ; G 3528 +U 9187 ; WX 873 ; N uni23E3 ; G 3529 +U 9189 ; WX 769 ; N uni23E5 ; G 3530 +U 9192 ; WX 696 ; N uni23E8 ; G 3531 +U 9250 ; WX 716 ; N uni2422 ; G 3532 +U 9251 ; WX 716 ; N uni2423 ; G 3533 +U 9312 ; WX 847 ; N uni2460 ; G 3534 +U 9313 ; WX 847 ; N uni2461 ; G 3535 +U 9314 ; WX 847 ; N uni2462 ; G 3536 +U 9315 ; WX 847 ; N uni2463 ; G 3537 +U 9316 ; WX 847 ; N uni2464 ; G 3538 +U 9317 ; WX 847 ; N uni2465 ; G 3539 +U 9318 ; WX 847 ; N uni2466 ; G 3540 +U 9319 ; WX 847 ; N uni2467 ; G 3541 +U 9320 ; WX 847 ; N uni2468 ; G 3542 +U 9321 ; WX 847 ; N uni2469 ; G 3543 +U 9472 ; WX 602 ; N SF100000 ; G 3544 +U 9473 ; WX 602 ; N uni2501 ; G 3545 +U 9474 ; WX 602 ; N SF110000 ; G 3546 +U 9475 ; WX 602 ; N uni2503 ; G 3547 +U 9476 ; WX 602 ; N uni2504 ; G 3548 +U 9477 ; WX 602 ; N uni2505 ; G 3549 +U 9478 ; WX 602 ; N uni2506 ; G 3550 +U 9479 ; WX 602 ; N uni2507 ; G 3551 +U 9480 ; WX 602 ; N uni2508 ; G 3552 +U 9481 ; WX 602 ; N uni2509 ; G 3553 +U 9482 ; WX 602 ; N uni250A ; G 3554 +U 9483 ; WX 602 ; N uni250B ; G 3555 +U 9484 ; WX 602 ; N SF010000 ; G 3556 +U 9485 ; WX 602 ; N uni250D ; G 3557 +U 9486 ; WX 602 ; N uni250E ; G 3558 +U 9487 ; WX 602 ; N uni250F ; G 3559 +U 9488 ; WX 602 ; N SF030000 ; G 3560 +U 9489 ; WX 602 ; N uni2511 ; G 3561 +U 9490 ; WX 602 ; N uni2512 ; G 3562 +U 9491 ; WX 602 ; N uni2513 ; G 3563 +U 9492 ; WX 602 ; N SF020000 ; G 3564 +U 9493 ; WX 602 ; N uni2515 ; G 3565 +U 9494 ; WX 602 ; N uni2516 ; G 3566 +U 9495 ; WX 602 ; N uni2517 ; G 3567 +U 9496 ; WX 602 ; N SF040000 ; G 3568 +U 9497 ; WX 602 ; N uni2519 ; G 3569 +U 9498 ; WX 602 ; N uni251A ; G 3570 +U 9499 ; WX 602 ; N uni251B ; G 3571 +U 9500 ; WX 602 ; N SF080000 ; G 3572 +U 9501 ; WX 602 ; N uni251D ; G 3573 +U 9502 ; WX 602 ; N uni251E ; G 3574 +U 9503 ; WX 602 ; N uni251F ; G 3575 +U 9504 ; WX 602 ; N uni2520 ; G 3576 +U 9505 ; WX 602 ; N uni2521 ; G 3577 +U 9506 ; WX 602 ; N uni2522 ; G 3578 +U 9507 ; WX 602 ; N uni2523 ; G 3579 +U 9508 ; WX 602 ; N SF090000 ; G 3580 +U 9509 ; WX 602 ; N uni2525 ; G 3581 +U 9510 ; WX 602 ; N uni2526 ; G 3582 +U 9511 ; WX 602 ; N uni2527 ; G 3583 +U 9512 ; WX 602 ; N uni2528 ; G 3584 +U 9513 ; WX 602 ; N uni2529 ; G 3585 +U 9514 ; WX 602 ; N uni252A ; G 3586 +U 9515 ; WX 602 ; N uni252B ; G 3587 +U 9516 ; WX 602 ; N SF060000 ; G 3588 +U 9517 ; WX 602 ; N uni252D ; G 3589 +U 9518 ; WX 602 ; N uni252E ; G 3590 +U 9519 ; WX 602 ; N uni252F ; G 3591 +U 9520 ; WX 602 ; N uni2530 ; G 3592 +U 9521 ; WX 602 ; N uni2531 ; G 3593 +U 9522 ; WX 602 ; N uni2532 ; G 3594 +U 9523 ; WX 602 ; N uni2533 ; G 3595 +U 9524 ; WX 602 ; N SF070000 ; G 3596 +U 9525 ; WX 602 ; N uni2535 ; G 3597 +U 9526 ; WX 602 ; N uni2536 ; G 3598 +U 9527 ; WX 602 ; N uni2537 ; G 3599 +U 9528 ; WX 602 ; N uni2538 ; G 3600 +U 9529 ; WX 602 ; N uni2539 ; G 3601 +U 9530 ; WX 602 ; N uni253A ; G 3602 +U 9531 ; WX 602 ; N uni253B ; G 3603 +U 9532 ; WX 602 ; N SF050000 ; G 3604 +U 9533 ; WX 602 ; N uni253D ; G 3605 +U 9534 ; WX 602 ; N uni253E ; G 3606 +U 9535 ; WX 602 ; N uni253F ; G 3607 +U 9536 ; WX 602 ; N uni2540 ; G 3608 +U 9537 ; WX 602 ; N uni2541 ; G 3609 +U 9538 ; WX 602 ; N uni2542 ; G 3610 +U 9539 ; WX 602 ; N uni2543 ; G 3611 +U 9540 ; WX 602 ; N uni2544 ; G 3612 +U 9541 ; WX 602 ; N uni2545 ; G 3613 +U 9542 ; WX 602 ; N uni2546 ; G 3614 +U 9543 ; WX 602 ; N uni2547 ; G 3615 +U 9544 ; WX 602 ; N uni2548 ; G 3616 +U 9545 ; WX 602 ; N uni2549 ; G 3617 +U 9546 ; WX 602 ; N uni254A ; G 3618 +U 9547 ; WX 602 ; N uni254B ; G 3619 +U 9548 ; WX 602 ; N uni254C ; G 3620 +U 9549 ; WX 602 ; N uni254D ; G 3621 +U 9550 ; WX 602 ; N uni254E ; G 3622 +U 9551 ; WX 602 ; N uni254F ; G 3623 +U 9552 ; WX 602 ; N SF430000 ; G 3624 +U 9553 ; WX 602 ; N SF240000 ; G 3625 +U 9554 ; WX 602 ; N SF510000 ; G 3626 +U 9555 ; WX 602 ; N SF520000 ; G 3627 +U 9556 ; WX 602 ; N SF390000 ; G 3628 +U 9557 ; WX 602 ; N SF220000 ; G 3629 +U 9558 ; WX 602 ; N SF210000 ; G 3630 +U 9559 ; WX 602 ; N SF250000 ; G 3631 +U 9560 ; WX 602 ; N SF500000 ; G 3632 +U 9561 ; WX 602 ; N SF490000 ; G 3633 +U 9562 ; WX 602 ; N SF380000 ; G 3634 +U 9563 ; WX 602 ; N SF280000 ; G 3635 +U 9564 ; WX 602 ; N SF270000 ; G 3636 +U 9565 ; WX 602 ; N SF260000 ; G 3637 +U 9566 ; WX 602 ; N SF360000 ; G 3638 +U 9567 ; WX 602 ; N SF370000 ; G 3639 +U 9568 ; WX 602 ; N SF420000 ; G 3640 +U 9569 ; WX 602 ; N SF190000 ; G 3641 +U 9570 ; WX 602 ; N SF200000 ; G 3642 +U 9571 ; WX 602 ; N SF230000 ; G 3643 +U 9572 ; WX 602 ; N SF470000 ; G 3644 +U 9573 ; WX 602 ; N SF480000 ; G 3645 +U 9574 ; WX 602 ; N SF410000 ; G 3646 +U 9575 ; WX 602 ; N SF450000 ; G 3647 +U 9576 ; WX 602 ; N SF460000 ; G 3648 +U 9577 ; WX 602 ; N SF400000 ; G 3649 +U 9578 ; WX 602 ; N SF540000 ; G 3650 +U 9579 ; WX 602 ; N SF530000 ; G 3651 +U 9580 ; WX 602 ; N SF440000 ; G 3652 +U 9581 ; WX 602 ; N uni256D ; G 3653 +U 9582 ; WX 602 ; N uni256E ; G 3654 +U 9583 ; WX 602 ; N uni256F ; G 3655 +U 9584 ; WX 602 ; N uni2570 ; G 3656 +U 9585 ; WX 602 ; N uni2571 ; G 3657 +U 9586 ; WX 602 ; N uni2572 ; G 3658 +U 9587 ; WX 602 ; N uni2573 ; G 3659 +U 9588 ; WX 602 ; N uni2574 ; G 3660 +U 9589 ; WX 602 ; N uni2575 ; G 3661 +U 9590 ; WX 602 ; N uni2576 ; G 3662 +U 9591 ; WX 602 ; N uni2577 ; G 3663 +U 9592 ; WX 602 ; N uni2578 ; G 3664 +U 9593 ; WX 602 ; N uni2579 ; G 3665 +U 9594 ; WX 602 ; N uni257A ; G 3666 +U 9595 ; WX 602 ; N uni257B ; G 3667 +U 9596 ; WX 602 ; N uni257C ; G 3668 +U 9597 ; WX 602 ; N uni257D ; G 3669 +U 9598 ; WX 602 ; N uni257E ; G 3670 +U 9599 ; WX 602 ; N uni257F ; G 3671 +U 9600 ; WX 769 ; N upblock ; G 3672 +U 9601 ; WX 769 ; N uni2581 ; G 3673 +U 9602 ; WX 769 ; N uni2582 ; G 3674 +U 9603 ; WX 769 ; N uni2583 ; G 3675 +U 9604 ; WX 769 ; N dnblock ; G 3676 +U 9605 ; WX 769 ; N uni2585 ; G 3677 +U 9606 ; WX 769 ; N uni2586 ; G 3678 +U 9607 ; WX 769 ; N uni2587 ; G 3679 +U 9608 ; WX 769 ; N block ; G 3680 +U 9609 ; WX 769 ; N uni2589 ; G 3681 +U 9610 ; WX 769 ; N uni258A ; G 3682 +U 9611 ; WX 769 ; N uni258B ; G 3683 +U 9612 ; WX 769 ; N lfblock ; G 3684 +U 9613 ; WX 769 ; N uni258D ; G 3685 +U 9614 ; WX 769 ; N uni258E ; G 3686 +U 9615 ; WX 769 ; N uni258F ; G 3687 +U 9616 ; WX 769 ; N rtblock ; G 3688 +U 9617 ; WX 769 ; N ltshade ; G 3689 +U 9618 ; WX 769 ; N shade ; G 3690 +U 9619 ; WX 769 ; N dkshade ; G 3691 +U 9620 ; WX 769 ; N uni2594 ; G 3692 +U 9621 ; WX 769 ; N uni2595 ; G 3693 +U 9622 ; WX 769 ; N uni2596 ; G 3694 +U 9623 ; WX 769 ; N uni2597 ; G 3695 +U 9624 ; WX 769 ; N uni2598 ; G 3696 +U 9625 ; WX 769 ; N uni2599 ; G 3697 +U 9626 ; WX 769 ; N uni259A ; G 3698 +U 9627 ; WX 769 ; N uni259B ; G 3699 +U 9628 ; WX 769 ; N uni259C ; G 3700 +U 9629 ; WX 769 ; N uni259D ; G 3701 +U 9630 ; WX 769 ; N uni259E ; G 3702 +U 9631 ; WX 769 ; N uni259F ; G 3703 +U 9632 ; WX 945 ; N filledbox ; G 3704 +U 9633 ; WX 945 ; N H22073 ; G 3705 +U 9634 ; WX 945 ; N uni25A2 ; G 3706 +U 9635 ; WX 945 ; N uni25A3 ; G 3707 +U 9636 ; WX 945 ; N uni25A4 ; G 3708 +U 9637 ; WX 945 ; N uni25A5 ; G 3709 +U 9638 ; WX 945 ; N uni25A6 ; G 3710 +U 9639 ; WX 945 ; N uni25A7 ; G 3711 +U 9640 ; WX 945 ; N uni25A8 ; G 3712 +U 9641 ; WX 945 ; N uni25A9 ; G 3713 +U 9642 ; WX 678 ; N H18543 ; G 3714 +U 9643 ; WX 678 ; N H18551 ; G 3715 +U 9644 ; WX 945 ; N filledrect ; G 3716 +U 9645 ; WX 945 ; N uni25AD ; G 3717 +U 9646 ; WX 550 ; N uni25AE ; G 3718 +U 9647 ; WX 550 ; N uni25AF ; G 3719 +U 9648 ; WX 769 ; N uni25B0 ; G 3720 +U 9649 ; WX 769 ; N uni25B1 ; G 3721 +U 9650 ; WX 769 ; N triagup ; G 3722 +U 9651 ; WX 769 ; N uni25B3 ; G 3723 +U 9652 ; WX 502 ; N uni25B4 ; G 3724 +U 9653 ; WX 502 ; N uni25B5 ; G 3725 +U 9654 ; WX 769 ; N uni25B6 ; G 3726 +U 9655 ; WX 769 ; N uni25B7 ; G 3727 +U 9656 ; WX 502 ; N uni25B8 ; G 3728 +U 9657 ; WX 502 ; N uni25B9 ; G 3729 +U 9658 ; WX 769 ; N triagrt ; G 3730 +U 9659 ; WX 769 ; N uni25BB ; G 3731 +U 9660 ; WX 769 ; N triagdn ; G 3732 +U 9661 ; WX 769 ; N uni25BD ; G 3733 +U 9662 ; WX 502 ; N uni25BE ; G 3734 +U 9663 ; WX 502 ; N uni25BF ; G 3735 +U 9664 ; WX 769 ; N uni25C0 ; G 3736 +U 9665 ; WX 769 ; N uni25C1 ; G 3737 +U 9666 ; WX 502 ; N uni25C2 ; G 3738 +U 9667 ; WX 502 ; N uni25C3 ; G 3739 +U 9668 ; WX 769 ; N triaglf ; G 3740 +U 9669 ; WX 769 ; N uni25C5 ; G 3741 +U 9670 ; WX 769 ; N uni25C6 ; G 3742 +U 9671 ; WX 769 ; N uni25C7 ; G 3743 +U 9672 ; WX 769 ; N uni25C8 ; G 3744 +U 9673 ; WX 873 ; N uni25C9 ; G 3745 +U 9674 ; WX 494 ; N lozenge ; G 3746 +U 9675 ; WX 873 ; N circle ; G 3747 +U 9676 ; WX 873 ; N uni25CC ; G 3748 +U 9677 ; WX 873 ; N uni25CD ; G 3749 +U 9678 ; WX 873 ; N uni25CE ; G 3750 +U 9679 ; WX 873 ; N H18533 ; G 3751 +U 9680 ; WX 873 ; N uni25D0 ; G 3752 +U 9681 ; WX 873 ; N uni25D1 ; G 3753 +U 9682 ; WX 873 ; N uni25D2 ; G 3754 +U 9683 ; WX 873 ; N uni25D3 ; G 3755 +U 9684 ; WX 873 ; N uni25D4 ; G 3756 +U 9685 ; WX 873 ; N uni25D5 ; G 3757 +U 9686 ; WX 527 ; N uni25D6 ; G 3758 +U 9687 ; WX 527 ; N uni25D7 ; G 3759 +U 9688 ; WX 840 ; N invbullet ; G 3760 +U 9689 ; WX 970 ; N invcircle ; G 3761 +U 9690 ; WX 970 ; N uni25DA ; G 3762 +U 9691 ; WX 970 ; N uni25DB ; G 3763 +U 9692 ; WX 387 ; N uni25DC ; G 3764 +U 9693 ; WX 387 ; N uni25DD ; G 3765 +U 9694 ; WX 387 ; N uni25DE ; G 3766 +U 9695 ; WX 387 ; N uni25DF ; G 3767 +U 9696 ; WX 769 ; N uni25E0 ; G 3768 +U 9697 ; WX 769 ; N uni25E1 ; G 3769 +U 9698 ; WX 769 ; N uni25E2 ; G 3770 +U 9699 ; WX 769 ; N uni25E3 ; G 3771 +U 9700 ; WX 769 ; N uni25E4 ; G 3772 +U 9701 ; WX 769 ; N uni25E5 ; G 3773 +U 9702 ; WX 639 ; N openbullet ; G 3774 +U 9703 ; WX 945 ; N uni25E7 ; G 3775 +U 9704 ; WX 945 ; N uni25E8 ; G 3776 +U 9705 ; WX 945 ; N uni25E9 ; G 3777 +U 9706 ; WX 945 ; N uni25EA ; G 3778 +U 9707 ; WX 945 ; N uni25EB ; G 3779 +U 9708 ; WX 769 ; N uni25EC ; G 3780 +U 9709 ; WX 769 ; N uni25ED ; G 3781 +U 9710 ; WX 769 ; N uni25EE ; G 3782 +U 9711 ; WX 1119 ; N uni25EF ; G 3783 +U 9712 ; WX 945 ; N uni25F0 ; G 3784 +U 9713 ; WX 945 ; N uni25F1 ; G 3785 +U 9714 ; WX 945 ; N uni25F2 ; G 3786 +U 9715 ; WX 945 ; N uni25F3 ; G 3787 +U 9716 ; WX 873 ; N uni25F4 ; G 3788 +U 9717 ; WX 873 ; N uni25F5 ; G 3789 +U 9718 ; WX 873 ; N uni25F6 ; G 3790 +U 9719 ; WX 873 ; N uni25F7 ; G 3791 +U 9720 ; WX 769 ; N uni25F8 ; G 3792 +U 9721 ; WX 769 ; N uni25F9 ; G 3793 +U 9722 ; WX 769 ; N uni25FA ; G 3794 +U 9723 ; WX 830 ; N uni25FB ; G 3795 +U 9724 ; WX 830 ; N uni25FC ; G 3796 +U 9725 ; WX 732 ; N uni25FD ; G 3797 +U 9726 ; WX 732 ; N uni25FE ; G 3798 +U 9727 ; WX 769 ; N uni25FF ; G 3799 +U 9728 ; WX 896 ; N uni2600 ; G 3800 +U 9729 ; WX 1000 ; N uni2601 ; G 3801 +U 9730 ; WX 896 ; N uni2602 ; G 3802 +U 9731 ; WX 896 ; N uni2603 ; G 3803 +U 9732 ; WX 896 ; N uni2604 ; G 3804 +U 9733 ; WX 896 ; N uni2605 ; G 3805 +U 9734 ; WX 896 ; N uni2606 ; G 3806 +U 9735 ; WX 573 ; N uni2607 ; G 3807 +U 9736 ; WX 896 ; N uni2608 ; G 3808 +U 9737 ; WX 896 ; N uni2609 ; G 3809 +U 9738 ; WX 888 ; N uni260A ; G 3810 +U 9739 ; WX 888 ; N uni260B ; G 3811 +U 9740 ; WX 671 ; N uni260C ; G 3812 +U 9741 ; WX 1013 ; N uni260D ; G 3813 +U 9742 ; WX 1246 ; N uni260E ; G 3814 +U 9743 ; WX 1250 ; N uni260F ; G 3815 +U 9744 ; WX 896 ; N uni2610 ; G 3816 +U 9745 ; WX 896 ; N uni2611 ; G 3817 +U 9746 ; WX 896 ; N uni2612 ; G 3818 +U 9747 ; WX 532 ; N uni2613 ; G 3819 +U 9748 ; WX 896 ; N uni2614 ; G 3820 +U 9749 ; WX 896 ; N uni2615 ; G 3821 +U 9750 ; WX 896 ; N uni2616 ; G 3822 +U 9751 ; WX 896 ; N uni2617 ; G 3823 +U 9752 ; WX 896 ; N uni2618 ; G 3824 +U 9753 ; WX 896 ; N uni2619 ; G 3825 +U 9754 ; WX 896 ; N uni261A ; G 3826 +U 9755 ; WX 896 ; N uni261B ; G 3827 +U 9756 ; WX 896 ; N uni261C ; G 3828 +U 9757 ; WX 609 ; N uni261D ; G 3829 +U 9758 ; WX 896 ; N uni261E ; G 3830 +U 9759 ; WX 609 ; N uni261F ; G 3831 +U 9760 ; WX 896 ; N uni2620 ; G 3832 +U 9761 ; WX 896 ; N uni2621 ; G 3833 +U 9762 ; WX 896 ; N uni2622 ; G 3834 +U 9763 ; WX 896 ; N uni2623 ; G 3835 +U 9764 ; WX 669 ; N uni2624 ; G 3836 +U 9765 ; WX 746 ; N uni2625 ; G 3837 +U 9766 ; WX 649 ; N uni2626 ; G 3838 +U 9767 ; WX 784 ; N uni2627 ; G 3839 +U 9768 ; WX 545 ; N uni2628 ; G 3840 +U 9769 ; WX 896 ; N uni2629 ; G 3841 +U 9770 ; WX 896 ; N uni262A ; G 3842 +U 9771 ; WX 896 ; N uni262B ; G 3843 +U 9772 ; WX 710 ; N uni262C ; G 3844 +U 9773 ; WX 896 ; N uni262D ; G 3845 +U 9774 ; WX 896 ; N uni262E ; G 3846 +U 9775 ; WX 896 ; N uni262F ; G 3847 +U 9776 ; WX 896 ; N uni2630 ; G 3848 +U 9777 ; WX 896 ; N uni2631 ; G 3849 +U 9778 ; WX 896 ; N uni2632 ; G 3850 +U 9779 ; WX 896 ; N uni2633 ; G 3851 +U 9780 ; WX 896 ; N uni2634 ; G 3852 +U 9781 ; WX 896 ; N uni2635 ; G 3853 +U 9782 ; WX 896 ; N uni2636 ; G 3854 +U 9783 ; WX 896 ; N uni2637 ; G 3855 +U 9784 ; WX 896 ; N uni2638 ; G 3856 +U 9785 ; WX 1042 ; N uni2639 ; G 3857 +U 9786 ; WX 1042 ; N smileface ; G 3858 +U 9787 ; WX 1042 ; N invsmileface ; G 3859 +U 9788 ; WX 896 ; N sun ; G 3860 +U 9789 ; WX 896 ; N uni263D ; G 3861 +U 9790 ; WX 896 ; N uni263E ; G 3862 +U 9791 ; WX 614 ; N uni263F ; G 3863 +U 9792 ; WX 732 ; N female ; G 3864 +U 9793 ; WX 732 ; N uni2641 ; G 3865 +U 9794 ; WX 896 ; N male ; G 3866 +U 9795 ; WX 896 ; N uni2643 ; G 3867 +U 9796 ; WX 896 ; N uni2644 ; G 3868 +U 9797 ; WX 896 ; N uni2645 ; G 3869 +U 9798 ; WX 896 ; N uni2646 ; G 3870 +U 9799 ; WX 896 ; N uni2647 ; G 3871 +U 9800 ; WX 896 ; N uni2648 ; G 3872 +U 9801 ; WX 896 ; N uni2649 ; G 3873 +U 9802 ; WX 896 ; N uni264A ; G 3874 +U 9803 ; WX 896 ; N uni264B ; G 3875 +U 9804 ; WX 896 ; N uni264C ; G 3876 +U 9805 ; WX 896 ; N uni264D ; G 3877 +U 9806 ; WX 896 ; N uni264E ; G 3878 +U 9807 ; WX 896 ; N uni264F ; G 3879 +U 9808 ; WX 896 ; N uni2650 ; G 3880 +U 9809 ; WX 896 ; N uni2651 ; G 3881 +U 9810 ; WX 896 ; N uni2652 ; G 3882 +U 9811 ; WX 896 ; N uni2653 ; G 3883 +U 9812 ; WX 896 ; N uni2654 ; G 3884 +U 9813 ; WX 896 ; N uni2655 ; G 3885 +U 9814 ; WX 896 ; N uni2656 ; G 3886 +U 9815 ; WX 896 ; N uni2657 ; G 3887 +U 9816 ; WX 896 ; N uni2658 ; G 3888 +U 9817 ; WX 896 ; N uni2659 ; G 3889 +U 9818 ; WX 896 ; N uni265A ; G 3890 +U 9819 ; WX 896 ; N uni265B ; G 3891 +U 9820 ; WX 896 ; N uni265C ; G 3892 +U 9821 ; WX 896 ; N uni265D ; G 3893 +U 9822 ; WX 896 ; N uni265E ; G 3894 +U 9823 ; WX 896 ; N uni265F ; G 3895 +U 9824 ; WX 896 ; N spade ; G 3896 +U 9825 ; WX 896 ; N uni2661 ; G 3897 +U 9826 ; WX 896 ; N uni2662 ; G 3898 +U 9827 ; WX 896 ; N club ; G 3899 +U 9828 ; WX 896 ; N uni2664 ; G 3900 +U 9829 ; WX 896 ; N heart ; G 3901 +U 9830 ; WX 896 ; N diamond ; G 3902 +U 9831 ; WX 896 ; N uni2667 ; G 3903 +U 9832 ; WX 896 ; N uni2668 ; G 3904 +U 9833 ; WX 472 ; N uni2669 ; G 3905 +U 9834 ; WX 638 ; N musicalnote ; G 3906 +U 9835 ; WX 896 ; N musicalnotedbl ; G 3907 +U 9836 ; WX 896 ; N uni266C ; G 3908 +U 9837 ; WX 472 ; N uni266D ; G 3909 +U 9838 ; WX 357 ; N uni266E ; G 3910 +U 9839 ; WX 484 ; N uni266F ; G 3911 +U 9840 ; WX 748 ; N uni2670 ; G 3912 +U 9841 ; WX 766 ; N uni2671 ; G 3913 +U 9842 ; WX 896 ; N uni2672 ; G 3914 +U 9843 ; WX 896 ; N uni2673 ; G 3915 +U 9844 ; WX 896 ; N uni2674 ; G 3916 +U 9845 ; WX 896 ; N uni2675 ; G 3917 +U 9846 ; WX 896 ; N uni2676 ; G 3918 +U 9847 ; WX 896 ; N uni2677 ; G 3919 +U 9848 ; WX 896 ; N uni2678 ; G 3920 +U 9849 ; WX 896 ; N uni2679 ; G 3921 +U 9850 ; WX 896 ; N uni267A ; G 3922 +U 9851 ; WX 896 ; N uni267B ; G 3923 +U 9852 ; WX 896 ; N uni267C ; G 3924 +U 9853 ; WX 896 ; N uni267D ; G 3925 +U 9854 ; WX 896 ; N uni267E ; G 3926 +U 9855 ; WX 896 ; N uni267F ; G 3927 +U 9856 ; WX 869 ; N uni2680 ; G 3928 +U 9857 ; WX 869 ; N uni2681 ; G 3929 +U 9858 ; WX 869 ; N uni2682 ; G 3930 +U 9859 ; WX 869 ; N uni2683 ; G 3931 +U 9860 ; WX 869 ; N uni2684 ; G 3932 +U 9861 ; WX 869 ; N uni2685 ; G 3933 +U 9862 ; WX 896 ; N uni2686 ; G 3934 +U 9863 ; WX 896 ; N uni2687 ; G 3935 +U 9864 ; WX 896 ; N uni2688 ; G 3936 +U 9865 ; WX 896 ; N uni2689 ; G 3937 +U 9866 ; WX 896 ; N uni268A ; G 3938 +U 9867 ; WX 896 ; N uni268B ; G 3939 +U 9868 ; WX 896 ; N uni268C ; G 3940 +U 9869 ; WX 896 ; N uni268D ; G 3941 +U 9870 ; WX 896 ; N uni268E ; G 3942 +U 9871 ; WX 896 ; N uni268F ; G 3943 +U 9872 ; WX 896 ; N uni2690 ; G 3944 +U 9873 ; WX 896 ; N uni2691 ; G 3945 +U 9874 ; WX 896 ; N uni2692 ; G 3946 +U 9875 ; WX 896 ; N uni2693 ; G 3947 +U 9876 ; WX 896 ; N uni2694 ; G 3948 +U 9877 ; WX 541 ; N uni2695 ; G 3949 +U 9878 ; WX 896 ; N uni2696 ; G 3950 +U 9879 ; WX 896 ; N uni2697 ; G 3951 +U 9880 ; WX 896 ; N uni2698 ; G 3952 +U 9881 ; WX 896 ; N uni2699 ; G 3953 +U 9882 ; WX 896 ; N uni269A ; G 3954 +U 9883 ; WX 896 ; N uni269B ; G 3955 +U 9884 ; WX 896 ; N uni269C ; G 3956 +U 9886 ; WX 896 ; N uni269E ; G 3957 +U 9887 ; WX 896 ; N uni269F ; G 3958 +U 9888 ; WX 896 ; N uni26A0 ; G 3959 +U 9889 ; WX 702 ; N uni26A1 ; G 3960 +U 9890 ; WX 1004 ; N uni26A2 ; G 3961 +U 9891 ; WX 1089 ; N uni26A3 ; G 3962 +U 9892 ; WX 1175 ; N uni26A4 ; G 3963 +U 9893 ; WX 903 ; N uni26A5 ; G 3964 +U 9894 ; WX 838 ; N uni26A6 ; G 3965 +U 9895 ; WX 838 ; N uni26A7 ; G 3966 +U 9896 ; WX 838 ; N uni26A8 ; G 3967 +U 9897 ; WX 838 ; N uni26A9 ; G 3968 +U 9898 ; WX 838 ; N uni26AA ; G 3969 +U 9899 ; WX 838 ; N uni26AB ; G 3970 +U 9900 ; WX 838 ; N uni26AC ; G 3971 +U 9901 ; WX 838 ; N uni26AD ; G 3972 +U 9902 ; WX 838 ; N uni26AE ; G 3973 +U 9903 ; WX 838 ; N uni26AF ; G 3974 +U 9904 ; WX 844 ; N uni26B0 ; G 3975 +U 9905 ; WX 838 ; N uni26B1 ; G 3976 +U 9906 ; WX 732 ; N uni26B2 ; G 3977 +U 9907 ; WX 732 ; N uni26B3 ; G 3978 +U 9908 ; WX 732 ; N uni26B4 ; G 3979 +U 9909 ; WX 732 ; N uni26B5 ; G 3980 +U 9910 ; WX 850 ; N uni26B6 ; G 3981 +U 9911 ; WX 732 ; N uni26B7 ; G 3982 +U 9912 ; WX 732 ; N uni26B8 ; G 3983 +U 9920 ; WX 838 ; N uni26C0 ; G 3984 +U 9921 ; WX 838 ; N uni26C1 ; G 3985 +U 9922 ; WX 838 ; N uni26C2 ; G 3986 +U 9923 ; WX 838 ; N uni26C3 ; G 3987 +U 9954 ; WX 732 ; N uni26E2 ; G 3988 +U 9985 ; WX 838 ; N uni2701 ; G 3989 +U 9986 ; WX 838 ; N uni2702 ; G 3990 +U 9987 ; WX 838 ; N uni2703 ; G 3991 +U 9988 ; WX 838 ; N uni2704 ; G 3992 +U 9990 ; WX 838 ; N uni2706 ; G 3993 +U 9991 ; WX 838 ; N uni2707 ; G 3994 +U 9992 ; WX 838 ; N uni2708 ; G 3995 +U 9993 ; WX 838 ; N uni2709 ; G 3996 +U 9996 ; WX 838 ; N uni270C ; G 3997 +U 9997 ; WX 838 ; N uni270D ; G 3998 +U 9998 ; WX 838 ; N uni270E ; G 3999 +U 9999 ; WX 838 ; N uni270F ; G 4000 +U 10000 ; WX 838 ; N uni2710 ; G 4001 +U 10001 ; WX 838 ; N uni2711 ; G 4002 +U 10002 ; WX 838 ; N uni2712 ; G 4003 +U 10003 ; WX 838 ; N uni2713 ; G 4004 +U 10004 ; WX 838 ; N uni2714 ; G 4005 +U 10005 ; WX 838 ; N uni2715 ; G 4006 +U 10006 ; WX 838 ; N uni2716 ; G 4007 +U 10007 ; WX 838 ; N uni2717 ; G 4008 +U 10008 ; WX 838 ; N uni2718 ; G 4009 +U 10009 ; WX 838 ; N uni2719 ; G 4010 +U 10010 ; WX 838 ; N uni271A ; G 4011 +U 10011 ; WX 838 ; N uni271B ; G 4012 +U 10012 ; WX 838 ; N uni271C ; G 4013 +U 10013 ; WX 838 ; N uni271D ; G 4014 +U 10014 ; WX 838 ; N uni271E ; G 4015 +U 10015 ; WX 838 ; N uni271F ; G 4016 +U 10016 ; WX 838 ; N uni2720 ; G 4017 +U 10017 ; WX 838 ; N uni2721 ; G 4018 +U 10018 ; WX 838 ; N uni2722 ; G 4019 +U 10019 ; WX 838 ; N uni2723 ; G 4020 +U 10020 ; WX 838 ; N uni2724 ; G 4021 +U 10021 ; WX 838 ; N uni2725 ; G 4022 +U 10022 ; WX 838 ; N uni2726 ; G 4023 +U 10023 ; WX 838 ; N uni2727 ; G 4024 +U 10025 ; WX 838 ; N uni2729 ; G 4025 +U 10026 ; WX 838 ; N uni272A ; G 4026 +U 10027 ; WX 838 ; N uni272B ; G 4027 +U 10028 ; WX 838 ; N uni272C ; G 4028 +U 10029 ; WX 838 ; N uni272D ; G 4029 +U 10030 ; WX 838 ; N uni272E ; G 4030 +U 10031 ; WX 838 ; N uni272F ; G 4031 +U 10032 ; WX 838 ; N uni2730 ; G 4032 +U 10033 ; WX 838 ; N uni2731 ; G 4033 +U 10034 ; WX 838 ; N uni2732 ; G 4034 +U 10035 ; WX 838 ; N uni2733 ; G 4035 +U 10036 ; WX 838 ; N uni2734 ; G 4036 +U 10037 ; WX 838 ; N uni2735 ; G 4037 +U 10038 ; WX 838 ; N uni2736 ; G 4038 +U 10039 ; WX 838 ; N uni2737 ; G 4039 +U 10040 ; WX 838 ; N uni2738 ; G 4040 +U 10041 ; WX 838 ; N uni2739 ; G 4041 +U 10042 ; WX 838 ; N uni273A ; G 4042 +U 10043 ; WX 838 ; N uni273B ; G 4043 +U 10044 ; WX 838 ; N uni273C ; G 4044 +U 10045 ; WX 838 ; N uni273D ; G 4045 +U 10046 ; WX 838 ; N uni273E ; G 4046 +U 10047 ; WX 838 ; N uni273F ; G 4047 +U 10048 ; WX 838 ; N uni2740 ; G 4048 +U 10049 ; WX 838 ; N uni2741 ; G 4049 +U 10050 ; WX 838 ; N uni2742 ; G 4050 +U 10051 ; WX 838 ; N uni2743 ; G 4051 +U 10052 ; WX 838 ; N uni2744 ; G 4052 +U 10053 ; WX 838 ; N uni2745 ; G 4053 +U 10054 ; WX 838 ; N uni2746 ; G 4054 +U 10055 ; WX 838 ; N uni2747 ; G 4055 +U 10056 ; WX 838 ; N uni2748 ; G 4056 +U 10057 ; WX 838 ; N uni2749 ; G 4057 +U 10058 ; WX 838 ; N uni274A ; G 4058 +U 10059 ; WX 838 ; N uni274B ; G 4059 +U 10061 ; WX 896 ; N uni274D ; G 4060 +U 10063 ; WX 896 ; N uni274F ; G 4061 +U 10064 ; WX 896 ; N uni2750 ; G 4062 +U 10065 ; WX 896 ; N uni2751 ; G 4063 +U 10066 ; WX 896 ; N uni2752 ; G 4064 +U 10070 ; WX 896 ; N uni2756 ; G 4065 +U 10072 ; WX 838 ; N uni2758 ; G 4066 +U 10073 ; WX 838 ; N uni2759 ; G 4067 +U 10074 ; WX 838 ; N uni275A ; G 4068 +U 10075 ; WX 347 ; N uni275B ; G 4069 +U 10076 ; WX 347 ; N uni275C ; G 4070 +U 10077 ; WX 587 ; N uni275D ; G 4071 +U 10078 ; WX 587 ; N uni275E ; G 4072 +U 10081 ; WX 838 ; N uni2761 ; G 4073 +U 10082 ; WX 838 ; N uni2762 ; G 4074 +U 10083 ; WX 838 ; N uni2763 ; G 4075 +U 10084 ; WX 838 ; N uni2764 ; G 4076 +U 10085 ; WX 838 ; N uni2765 ; G 4077 +U 10086 ; WX 838 ; N uni2766 ; G 4078 +U 10087 ; WX 838 ; N uni2767 ; G 4079 +U 10088 ; WX 838 ; N uni2768 ; G 4080 +U 10089 ; WX 838 ; N uni2769 ; G 4081 +U 10090 ; WX 838 ; N uni276A ; G 4082 +U 10091 ; WX 838 ; N uni276B ; G 4083 +U 10092 ; WX 838 ; N uni276C ; G 4084 +U 10093 ; WX 838 ; N uni276D ; G 4085 +U 10094 ; WX 838 ; N uni276E ; G 4086 +U 10095 ; WX 838 ; N uni276F ; G 4087 +U 10096 ; WX 838 ; N uni2770 ; G 4088 +U 10097 ; WX 838 ; N uni2771 ; G 4089 +U 10098 ; WX 838 ; N uni2772 ; G 4090 +U 10099 ; WX 838 ; N uni2773 ; G 4091 +U 10100 ; WX 838 ; N uni2774 ; G 4092 +U 10101 ; WX 838 ; N uni2775 ; G 4093 +U 10102 ; WX 847 ; N uni2776 ; G 4094 +U 10103 ; WX 847 ; N uni2777 ; G 4095 +U 10104 ; WX 847 ; N uni2778 ; G 4096 +U 10105 ; WX 847 ; N uni2779 ; G 4097 +U 10106 ; WX 847 ; N uni277A ; G 4098 +U 10107 ; WX 847 ; N uni277B ; G 4099 +U 10108 ; WX 847 ; N uni277C ; G 4100 +U 10109 ; WX 847 ; N uni277D ; G 4101 +U 10110 ; WX 847 ; N uni277E ; G 4102 +U 10111 ; WX 847 ; N uni277F ; G 4103 +U 10112 ; WX 838 ; N uni2780 ; G 4104 +U 10113 ; WX 838 ; N uni2781 ; G 4105 +U 10114 ; WX 838 ; N uni2782 ; G 4106 +U 10115 ; WX 838 ; N uni2783 ; G 4107 +U 10116 ; WX 838 ; N uni2784 ; G 4108 +U 10117 ; WX 838 ; N uni2785 ; G 4109 +U 10118 ; WX 838 ; N uni2786 ; G 4110 +U 10119 ; WX 838 ; N uni2787 ; G 4111 +U 10120 ; WX 838 ; N uni2788 ; G 4112 +U 10121 ; WX 838 ; N uni2789 ; G 4113 +U 10122 ; WX 838 ; N uni278A ; G 4114 +U 10123 ; WX 838 ; N uni278B ; G 4115 +U 10124 ; WX 838 ; N uni278C ; G 4116 +U 10125 ; WX 838 ; N uni278D ; G 4117 +U 10126 ; WX 838 ; N uni278E ; G 4118 +U 10127 ; WX 838 ; N uni278F ; G 4119 +U 10128 ; WX 838 ; N uni2790 ; G 4120 +U 10129 ; WX 838 ; N uni2791 ; G 4121 +U 10130 ; WX 838 ; N uni2792 ; G 4122 +U 10131 ; WX 838 ; N uni2793 ; G 4123 +U 10132 ; WX 838 ; N uni2794 ; G 4124 +U 10136 ; WX 838 ; N uni2798 ; G 4125 +U 10137 ; WX 838 ; N uni2799 ; G 4126 +U 10138 ; WX 838 ; N uni279A ; G 4127 +U 10139 ; WX 838 ; N uni279B ; G 4128 +U 10140 ; WX 838 ; N uni279C ; G 4129 +U 10141 ; WX 838 ; N uni279D ; G 4130 +U 10142 ; WX 838 ; N uni279E ; G 4131 +U 10143 ; WX 838 ; N uni279F ; G 4132 +U 10144 ; WX 838 ; N uni27A0 ; G 4133 +U 10145 ; WX 838 ; N uni27A1 ; G 4134 +U 10146 ; WX 838 ; N uni27A2 ; G 4135 +U 10147 ; WX 838 ; N uni27A3 ; G 4136 +U 10148 ; WX 838 ; N uni27A4 ; G 4137 +U 10149 ; WX 838 ; N uni27A5 ; G 4138 +U 10150 ; WX 838 ; N uni27A6 ; G 4139 +U 10151 ; WX 838 ; N uni27A7 ; G 4140 +U 10152 ; WX 838 ; N uni27A8 ; G 4141 +U 10153 ; WX 838 ; N uni27A9 ; G 4142 +U 10154 ; WX 838 ; N uni27AA ; G 4143 +U 10155 ; WX 838 ; N uni27AB ; G 4144 +U 10156 ; WX 838 ; N uni27AC ; G 4145 +U 10157 ; WX 838 ; N uni27AD ; G 4146 +U 10158 ; WX 838 ; N uni27AE ; G 4147 +U 10159 ; WX 838 ; N uni27AF ; G 4148 +U 10161 ; WX 838 ; N uni27B1 ; G 4149 +U 10162 ; WX 838 ; N uni27B2 ; G 4150 +U 10163 ; WX 838 ; N uni27B3 ; G 4151 +U 10164 ; WX 838 ; N uni27B4 ; G 4152 +U 10165 ; WX 838 ; N uni27B5 ; G 4153 +U 10166 ; WX 838 ; N uni27B6 ; G 4154 +U 10167 ; WX 838 ; N uni27B7 ; G 4155 +U 10168 ; WX 838 ; N uni27B8 ; G 4156 +U 10169 ; WX 838 ; N uni27B9 ; G 4157 +U 10170 ; WX 838 ; N uni27BA ; G 4158 +U 10171 ; WX 838 ; N uni27BB ; G 4159 +U 10172 ; WX 838 ; N uni27BC ; G 4160 +U 10173 ; WX 838 ; N uni27BD ; G 4161 +U 10174 ; WX 838 ; N uni27BE ; G 4162 +U 10181 ; WX 457 ; N uni27C5 ; G 4163 +U 10182 ; WX 457 ; N uni27C6 ; G 4164 +U 10208 ; WX 494 ; N uni27E0 ; G 4165 +U 10214 ; WX 487 ; N uni27E6 ; G 4166 +U 10215 ; WX 487 ; N uni27E7 ; G 4167 +U 10216 ; WX 457 ; N uni27E8 ; G 4168 +U 10217 ; WX 457 ; N uni27E9 ; G 4169 +U 10218 ; WX 721 ; N uni27EA ; G 4170 +U 10219 ; WX 721 ; N uni27EB ; G 4171 +U 10224 ; WX 838 ; N uni27F0 ; G 4172 +U 10225 ; WX 838 ; N uni27F1 ; G 4173 +U 10226 ; WX 838 ; N uni27F2 ; G 4174 +U 10227 ; WX 838 ; N uni27F3 ; G 4175 +U 10228 ; WX 1157 ; N uni27F4 ; G 4176 +U 10229 ; WX 1434 ; N uni27F5 ; G 4177 +U 10230 ; WX 1434 ; N uni27F6 ; G 4178 +U 10231 ; WX 1434 ; N uni27F7 ; G 4179 +U 10232 ; WX 1434 ; N uni27F8 ; G 4180 +U 10233 ; WX 1434 ; N uni27F9 ; G 4181 +U 10234 ; WX 1434 ; N uni27FA ; G 4182 +U 10235 ; WX 1434 ; N uni27FB ; G 4183 +U 10236 ; WX 1434 ; N uni27FC ; G 4184 +U 10237 ; WX 1434 ; N uni27FD ; G 4185 +U 10238 ; WX 1434 ; N uni27FE ; G 4186 +U 10239 ; WX 1434 ; N uni27FF ; G 4187 +U 10240 ; WX 781 ; N uni2800 ; G 4188 +U 10241 ; WX 781 ; N uni2801 ; G 4189 +U 10242 ; WX 781 ; N uni2802 ; G 4190 +U 10243 ; WX 781 ; N uni2803 ; G 4191 +U 10244 ; WX 781 ; N uni2804 ; G 4192 +U 10245 ; WX 781 ; N uni2805 ; G 4193 +U 10246 ; WX 781 ; N uni2806 ; G 4194 +U 10247 ; WX 781 ; N uni2807 ; G 4195 +U 10248 ; WX 781 ; N uni2808 ; G 4196 +U 10249 ; WX 781 ; N uni2809 ; G 4197 +U 10250 ; WX 781 ; N uni280A ; G 4198 +U 10251 ; WX 781 ; N uni280B ; G 4199 +U 10252 ; WX 781 ; N uni280C ; G 4200 +U 10253 ; WX 781 ; N uni280D ; G 4201 +U 10254 ; WX 781 ; N uni280E ; G 4202 +U 10255 ; WX 781 ; N uni280F ; G 4203 +U 10256 ; WX 781 ; N uni2810 ; G 4204 +U 10257 ; WX 781 ; N uni2811 ; G 4205 +U 10258 ; WX 781 ; N uni2812 ; G 4206 +U 10259 ; WX 781 ; N uni2813 ; G 4207 +U 10260 ; WX 781 ; N uni2814 ; G 4208 +U 10261 ; WX 781 ; N uni2815 ; G 4209 +U 10262 ; WX 781 ; N uni2816 ; G 4210 +U 10263 ; WX 781 ; N uni2817 ; G 4211 +U 10264 ; WX 781 ; N uni2818 ; G 4212 +U 10265 ; WX 781 ; N uni2819 ; G 4213 +U 10266 ; WX 781 ; N uni281A ; G 4214 +U 10267 ; WX 781 ; N uni281B ; G 4215 +U 10268 ; WX 781 ; N uni281C ; G 4216 +U 10269 ; WX 781 ; N uni281D ; G 4217 +U 10270 ; WX 781 ; N uni281E ; G 4218 +U 10271 ; WX 781 ; N uni281F ; G 4219 +U 10272 ; WX 781 ; N uni2820 ; G 4220 +U 10273 ; WX 781 ; N uni2821 ; G 4221 +U 10274 ; WX 781 ; N uni2822 ; G 4222 +U 10275 ; WX 781 ; N uni2823 ; G 4223 +U 10276 ; WX 781 ; N uni2824 ; G 4224 +U 10277 ; WX 781 ; N uni2825 ; G 4225 +U 10278 ; WX 781 ; N uni2826 ; G 4226 +U 10279 ; WX 781 ; N uni2827 ; G 4227 +U 10280 ; WX 781 ; N uni2828 ; G 4228 +U 10281 ; WX 781 ; N uni2829 ; G 4229 +U 10282 ; WX 781 ; N uni282A ; G 4230 +U 10283 ; WX 781 ; N uni282B ; G 4231 +U 10284 ; WX 781 ; N uni282C ; G 4232 +U 10285 ; WX 781 ; N uni282D ; G 4233 +U 10286 ; WX 781 ; N uni282E ; G 4234 +U 10287 ; WX 781 ; N uni282F ; G 4235 +U 10288 ; WX 781 ; N uni2830 ; G 4236 +U 10289 ; WX 781 ; N uni2831 ; G 4237 +U 10290 ; WX 781 ; N uni2832 ; G 4238 +U 10291 ; WX 781 ; N uni2833 ; G 4239 +U 10292 ; WX 781 ; N uni2834 ; G 4240 +U 10293 ; WX 781 ; N uni2835 ; G 4241 +U 10294 ; WX 781 ; N uni2836 ; G 4242 +U 10295 ; WX 781 ; N uni2837 ; G 4243 +U 10296 ; WX 781 ; N uni2838 ; G 4244 +U 10297 ; WX 781 ; N uni2839 ; G 4245 +U 10298 ; WX 781 ; N uni283A ; G 4246 +U 10299 ; WX 781 ; N uni283B ; G 4247 +U 10300 ; WX 781 ; N uni283C ; G 4248 +U 10301 ; WX 781 ; N uni283D ; G 4249 +U 10302 ; WX 781 ; N uni283E ; G 4250 +U 10303 ; WX 781 ; N uni283F ; G 4251 +U 10304 ; WX 781 ; N uni2840 ; G 4252 +U 10305 ; WX 781 ; N uni2841 ; G 4253 +U 10306 ; WX 781 ; N uni2842 ; G 4254 +U 10307 ; WX 781 ; N uni2843 ; G 4255 +U 10308 ; WX 781 ; N uni2844 ; G 4256 +U 10309 ; WX 781 ; N uni2845 ; G 4257 +U 10310 ; WX 781 ; N uni2846 ; G 4258 +U 10311 ; WX 781 ; N uni2847 ; G 4259 +U 10312 ; WX 781 ; N uni2848 ; G 4260 +U 10313 ; WX 781 ; N uni2849 ; G 4261 +U 10314 ; WX 781 ; N uni284A ; G 4262 +U 10315 ; WX 781 ; N uni284B ; G 4263 +U 10316 ; WX 781 ; N uni284C ; G 4264 +U 10317 ; WX 781 ; N uni284D ; G 4265 +U 10318 ; WX 781 ; N uni284E ; G 4266 +U 10319 ; WX 781 ; N uni284F ; G 4267 +U 10320 ; WX 781 ; N uni2850 ; G 4268 +U 10321 ; WX 781 ; N uni2851 ; G 4269 +U 10322 ; WX 781 ; N uni2852 ; G 4270 +U 10323 ; WX 781 ; N uni2853 ; G 4271 +U 10324 ; WX 781 ; N uni2854 ; G 4272 +U 10325 ; WX 781 ; N uni2855 ; G 4273 +U 10326 ; WX 781 ; N uni2856 ; G 4274 +U 10327 ; WX 781 ; N uni2857 ; G 4275 +U 10328 ; WX 781 ; N uni2858 ; G 4276 +U 10329 ; WX 781 ; N uni2859 ; G 4277 +U 10330 ; WX 781 ; N uni285A ; G 4278 +U 10331 ; WX 781 ; N uni285B ; G 4279 +U 10332 ; WX 781 ; N uni285C ; G 4280 +U 10333 ; WX 781 ; N uni285D ; G 4281 +U 10334 ; WX 781 ; N uni285E ; G 4282 +U 10335 ; WX 781 ; N uni285F ; G 4283 +U 10336 ; WX 781 ; N uni2860 ; G 4284 +U 10337 ; WX 781 ; N uni2861 ; G 4285 +U 10338 ; WX 781 ; N uni2862 ; G 4286 +U 10339 ; WX 781 ; N uni2863 ; G 4287 +U 10340 ; WX 781 ; N uni2864 ; G 4288 +U 10341 ; WX 781 ; N uni2865 ; G 4289 +U 10342 ; WX 781 ; N uni2866 ; G 4290 +U 10343 ; WX 781 ; N uni2867 ; G 4291 +U 10344 ; WX 781 ; N uni2868 ; G 4292 +U 10345 ; WX 781 ; N uni2869 ; G 4293 +U 10346 ; WX 781 ; N uni286A ; G 4294 +U 10347 ; WX 781 ; N uni286B ; G 4295 +U 10348 ; WX 781 ; N uni286C ; G 4296 +U 10349 ; WX 781 ; N uni286D ; G 4297 +U 10350 ; WX 781 ; N uni286E ; G 4298 +U 10351 ; WX 781 ; N uni286F ; G 4299 +U 10352 ; WX 781 ; N uni2870 ; G 4300 +U 10353 ; WX 781 ; N uni2871 ; G 4301 +U 10354 ; WX 781 ; N uni2872 ; G 4302 +U 10355 ; WX 781 ; N uni2873 ; G 4303 +U 10356 ; WX 781 ; N uni2874 ; G 4304 +U 10357 ; WX 781 ; N uni2875 ; G 4305 +U 10358 ; WX 781 ; N uni2876 ; G 4306 +U 10359 ; WX 781 ; N uni2877 ; G 4307 +U 10360 ; WX 781 ; N uni2878 ; G 4308 +U 10361 ; WX 781 ; N uni2879 ; G 4309 +U 10362 ; WX 781 ; N uni287A ; G 4310 +U 10363 ; WX 781 ; N uni287B ; G 4311 +U 10364 ; WX 781 ; N uni287C ; G 4312 +U 10365 ; WX 781 ; N uni287D ; G 4313 +U 10366 ; WX 781 ; N uni287E ; G 4314 +U 10367 ; WX 781 ; N uni287F ; G 4315 +U 10368 ; WX 781 ; N uni2880 ; G 4316 +U 10369 ; WX 781 ; N uni2881 ; G 4317 +U 10370 ; WX 781 ; N uni2882 ; G 4318 +U 10371 ; WX 781 ; N uni2883 ; G 4319 +U 10372 ; WX 781 ; N uni2884 ; G 4320 +U 10373 ; WX 781 ; N uni2885 ; G 4321 +U 10374 ; WX 781 ; N uni2886 ; G 4322 +U 10375 ; WX 781 ; N uni2887 ; G 4323 +U 10376 ; WX 781 ; N uni2888 ; G 4324 +U 10377 ; WX 781 ; N uni2889 ; G 4325 +U 10378 ; WX 781 ; N uni288A ; G 4326 +U 10379 ; WX 781 ; N uni288B ; G 4327 +U 10380 ; WX 781 ; N uni288C ; G 4328 +U 10381 ; WX 781 ; N uni288D ; G 4329 +U 10382 ; WX 781 ; N uni288E ; G 4330 +U 10383 ; WX 781 ; N uni288F ; G 4331 +U 10384 ; WX 781 ; N uni2890 ; G 4332 +U 10385 ; WX 781 ; N uni2891 ; G 4333 +U 10386 ; WX 781 ; N uni2892 ; G 4334 +U 10387 ; WX 781 ; N uni2893 ; G 4335 +U 10388 ; WX 781 ; N uni2894 ; G 4336 +U 10389 ; WX 781 ; N uni2895 ; G 4337 +U 10390 ; WX 781 ; N uni2896 ; G 4338 +U 10391 ; WX 781 ; N uni2897 ; G 4339 +U 10392 ; WX 781 ; N uni2898 ; G 4340 +U 10393 ; WX 781 ; N uni2899 ; G 4341 +U 10394 ; WX 781 ; N uni289A ; G 4342 +U 10395 ; WX 781 ; N uni289B ; G 4343 +U 10396 ; WX 781 ; N uni289C ; G 4344 +U 10397 ; WX 781 ; N uni289D ; G 4345 +U 10398 ; WX 781 ; N uni289E ; G 4346 +U 10399 ; WX 781 ; N uni289F ; G 4347 +U 10400 ; WX 781 ; N uni28A0 ; G 4348 +U 10401 ; WX 781 ; N uni28A1 ; G 4349 +U 10402 ; WX 781 ; N uni28A2 ; G 4350 +U 10403 ; WX 781 ; N uni28A3 ; G 4351 +U 10404 ; WX 781 ; N uni28A4 ; G 4352 +U 10405 ; WX 781 ; N uni28A5 ; G 4353 +U 10406 ; WX 781 ; N uni28A6 ; G 4354 +U 10407 ; WX 781 ; N uni28A7 ; G 4355 +U 10408 ; WX 781 ; N uni28A8 ; G 4356 +U 10409 ; WX 781 ; N uni28A9 ; G 4357 +U 10410 ; WX 781 ; N uni28AA ; G 4358 +U 10411 ; WX 781 ; N uni28AB ; G 4359 +U 10412 ; WX 781 ; N uni28AC ; G 4360 +U 10413 ; WX 781 ; N uni28AD ; G 4361 +U 10414 ; WX 781 ; N uni28AE ; G 4362 +U 10415 ; WX 781 ; N uni28AF ; G 4363 +U 10416 ; WX 781 ; N uni28B0 ; G 4364 +U 10417 ; WX 781 ; N uni28B1 ; G 4365 +U 10418 ; WX 781 ; N uni28B2 ; G 4366 +U 10419 ; WX 781 ; N uni28B3 ; G 4367 +U 10420 ; WX 781 ; N uni28B4 ; G 4368 +U 10421 ; WX 781 ; N uni28B5 ; G 4369 +U 10422 ; WX 781 ; N uni28B6 ; G 4370 +U 10423 ; WX 781 ; N uni28B7 ; G 4371 +U 10424 ; WX 781 ; N uni28B8 ; G 4372 +U 10425 ; WX 781 ; N uni28B9 ; G 4373 +U 10426 ; WX 781 ; N uni28BA ; G 4374 +U 10427 ; WX 781 ; N uni28BB ; G 4375 +U 10428 ; WX 781 ; N uni28BC ; G 4376 +U 10429 ; WX 781 ; N uni28BD ; G 4377 +U 10430 ; WX 781 ; N uni28BE ; G 4378 +U 10431 ; WX 781 ; N uni28BF ; G 4379 +U 10432 ; WX 781 ; N uni28C0 ; G 4380 +U 10433 ; WX 781 ; N uni28C1 ; G 4381 +U 10434 ; WX 781 ; N uni28C2 ; G 4382 +U 10435 ; WX 781 ; N uni28C3 ; G 4383 +U 10436 ; WX 781 ; N uni28C4 ; G 4384 +U 10437 ; WX 781 ; N uni28C5 ; G 4385 +U 10438 ; WX 781 ; N uni28C6 ; G 4386 +U 10439 ; WX 781 ; N uni28C7 ; G 4387 +U 10440 ; WX 781 ; N uni28C8 ; G 4388 +U 10441 ; WX 781 ; N uni28C9 ; G 4389 +U 10442 ; WX 781 ; N uni28CA ; G 4390 +U 10443 ; WX 781 ; N uni28CB ; G 4391 +U 10444 ; WX 781 ; N uni28CC ; G 4392 +U 10445 ; WX 781 ; N uni28CD ; G 4393 +U 10446 ; WX 781 ; N uni28CE ; G 4394 +U 10447 ; WX 781 ; N uni28CF ; G 4395 +U 10448 ; WX 781 ; N uni28D0 ; G 4396 +U 10449 ; WX 781 ; N uni28D1 ; G 4397 +U 10450 ; WX 781 ; N uni28D2 ; G 4398 +U 10451 ; WX 781 ; N uni28D3 ; G 4399 +U 10452 ; WX 781 ; N uni28D4 ; G 4400 +U 10453 ; WX 781 ; N uni28D5 ; G 4401 +U 10454 ; WX 781 ; N uni28D6 ; G 4402 +U 10455 ; WX 781 ; N uni28D7 ; G 4403 +U 10456 ; WX 781 ; N uni28D8 ; G 4404 +U 10457 ; WX 781 ; N uni28D9 ; G 4405 +U 10458 ; WX 781 ; N uni28DA ; G 4406 +U 10459 ; WX 781 ; N uni28DB ; G 4407 +U 10460 ; WX 781 ; N uni28DC ; G 4408 +U 10461 ; WX 781 ; N uni28DD ; G 4409 +U 10462 ; WX 781 ; N uni28DE ; G 4410 +U 10463 ; WX 781 ; N uni28DF ; G 4411 +U 10464 ; WX 781 ; N uni28E0 ; G 4412 +U 10465 ; WX 781 ; N uni28E1 ; G 4413 +U 10466 ; WX 781 ; N uni28E2 ; G 4414 +U 10467 ; WX 781 ; N uni28E3 ; G 4415 +U 10468 ; WX 781 ; N uni28E4 ; G 4416 +U 10469 ; WX 781 ; N uni28E5 ; G 4417 +U 10470 ; WX 781 ; N uni28E6 ; G 4418 +U 10471 ; WX 781 ; N uni28E7 ; G 4419 +U 10472 ; WX 781 ; N uni28E8 ; G 4420 +U 10473 ; WX 781 ; N uni28E9 ; G 4421 +U 10474 ; WX 781 ; N uni28EA ; G 4422 +U 10475 ; WX 781 ; N uni28EB ; G 4423 +U 10476 ; WX 781 ; N uni28EC ; G 4424 +U 10477 ; WX 781 ; N uni28ED ; G 4425 +U 10478 ; WX 781 ; N uni28EE ; G 4426 +U 10479 ; WX 781 ; N uni28EF ; G 4427 +U 10480 ; WX 781 ; N uni28F0 ; G 4428 +U 10481 ; WX 781 ; N uni28F1 ; G 4429 +U 10482 ; WX 781 ; N uni28F2 ; G 4430 +U 10483 ; WX 781 ; N uni28F3 ; G 4431 +U 10484 ; WX 781 ; N uni28F4 ; G 4432 +U 10485 ; WX 781 ; N uni28F5 ; G 4433 +U 10486 ; WX 781 ; N uni28F6 ; G 4434 +U 10487 ; WX 781 ; N uni28F7 ; G 4435 +U 10488 ; WX 781 ; N uni28F8 ; G 4436 +U 10489 ; WX 781 ; N uni28F9 ; G 4437 +U 10490 ; WX 781 ; N uni28FA ; G 4438 +U 10491 ; WX 781 ; N uni28FB ; G 4439 +U 10492 ; WX 781 ; N uni28FC ; G 4440 +U 10493 ; WX 781 ; N uni28FD ; G 4441 +U 10494 ; WX 781 ; N uni28FE ; G 4442 +U 10495 ; WX 781 ; N uni28FF ; G 4443 +U 10502 ; WX 838 ; N uni2906 ; G 4444 +U 10503 ; WX 838 ; N uni2907 ; G 4445 +U 10506 ; WX 838 ; N uni290A ; G 4446 +U 10507 ; WX 838 ; N uni290B ; G 4447 +U 10560 ; WX 838 ; N uni2940 ; G 4448 +U 10561 ; WX 838 ; N uni2941 ; G 4449 +U 10627 ; WX 753 ; N uni2983 ; G 4450 +U 10628 ; WX 753 ; N uni2984 ; G 4451 +U 10702 ; WX 838 ; N uni29CE ; G 4452 +U 10703 ; WX 1046 ; N uni29CF ; G 4453 +U 10704 ; WX 1046 ; N uni29D0 ; G 4454 +U 10705 ; WX 1000 ; N uni29D1 ; G 4455 +U 10706 ; WX 1000 ; N uni29D2 ; G 4456 +U 10707 ; WX 1000 ; N uni29D3 ; G 4457 +U 10708 ; WX 1000 ; N uni29D4 ; G 4458 +U 10709 ; WX 1000 ; N uni29D5 ; G 4459 +U 10731 ; WX 494 ; N uni29EB ; G 4460 +U 10746 ; WX 838 ; N uni29FA ; G 4461 +U 10747 ; WX 838 ; N uni29FB ; G 4462 +U 10752 ; WX 1000 ; N uni2A00 ; G 4463 +U 10753 ; WX 1000 ; N uni2A01 ; G 4464 +U 10754 ; WX 1000 ; N uni2A02 ; G 4465 +U 10764 ; WX 1661 ; N uni2A0C ; G 4466 +U 10765 ; WX 563 ; N uni2A0D ; G 4467 +U 10766 ; WX 563 ; N uni2A0E ; G 4468 +U 10767 ; WX 563 ; N uni2A0F ; G 4469 +U 10768 ; WX 563 ; N uni2A10 ; G 4470 +U 10769 ; WX 563 ; N uni2A11 ; G 4471 +U 10770 ; WX 563 ; N uni2A12 ; G 4472 +U 10771 ; WX 563 ; N uni2A13 ; G 4473 +U 10772 ; WX 563 ; N uni2A14 ; G 4474 +U 10773 ; WX 563 ; N uni2A15 ; G 4475 +U 10774 ; WX 563 ; N uni2A16 ; G 4476 +U 10775 ; WX 563 ; N uni2A17 ; G 4477 +U 10776 ; WX 563 ; N uni2A18 ; G 4478 +U 10777 ; WX 563 ; N uni2A19 ; G 4479 +U 10778 ; WX 563 ; N uni2A1A ; G 4480 +U 10779 ; WX 563 ; N uni2A1B ; G 4481 +U 10780 ; WX 563 ; N uni2A1C ; G 4482 +U 10799 ; WX 838 ; N uni2A2F ; G 4483 +U 10858 ; WX 838 ; N uni2A6A ; G 4484 +U 10859 ; WX 838 ; N uni2A6B ; G 4485 +U 10877 ; WX 838 ; N uni2A7D ; G 4486 +U 10878 ; WX 838 ; N uni2A7E ; G 4487 +U 10879 ; WX 838 ; N uni2A7F ; G 4488 +U 10880 ; WX 838 ; N uni2A80 ; G 4489 +U 10881 ; WX 838 ; N uni2A81 ; G 4490 +U 10882 ; WX 838 ; N uni2A82 ; G 4491 +U 10883 ; WX 838 ; N uni2A83 ; G 4492 +U 10884 ; WX 838 ; N uni2A84 ; G 4493 +U 10885 ; WX 838 ; N uni2A85 ; G 4494 +U 10886 ; WX 838 ; N uni2A86 ; G 4495 +U 10887 ; WX 838 ; N uni2A87 ; G 4496 +U 10888 ; WX 838 ; N uni2A88 ; G 4497 +U 10889 ; WX 838 ; N uni2A89 ; G 4498 +U 10890 ; WX 838 ; N uni2A8A ; G 4499 +U 10891 ; WX 838 ; N uni2A8B ; G 4500 +U 10892 ; WX 838 ; N uni2A8C ; G 4501 +U 10893 ; WX 838 ; N uni2A8D ; G 4502 +U 10894 ; WX 838 ; N uni2A8E ; G 4503 +U 10895 ; WX 838 ; N uni2A8F ; G 4504 +U 10896 ; WX 838 ; N uni2A90 ; G 4505 +U 10897 ; WX 838 ; N uni2A91 ; G 4506 +U 10898 ; WX 838 ; N uni2A92 ; G 4507 +U 10899 ; WX 838 ; N uni2A93 ; G 4508 +U 10900 ; WX 838 ; N uni2A94 ; G 4509 +U 10901 ; WX 838 ; N uni2A95 ; G 4510 +U 10902 ; WX 838 ; N uni2A96 ; G 4511 +U 10903 ; WX 838 ; N uni2A97 ; G 4512 +U 10904 ; WX 838 ; N uni2A98 ; G 4513 +U 10905 ; WX 838 ; N uni2A99 ; G 4514 +U 10906 ; WX 838 ; N uni2A9A ; G 4515 +U 10907 ; WX 838 ; N uni2A9B ; G 4516 +U 10908 ; WX 838 ; N uni2A9C ; G 4517 +U 10909 ; WX 838 ; N uni2A9D ; G 4518 +U 10910 ; WX 838 ; N uni2A9E ; G 4519 +U 10911 ; WX 838 ; N uni2A9F ; G 4520 +U 10912 ; WX 838 ; N uni2AA0 ; G 4521 +U 10926 ; WX 838 ; N uni2AAE ; G 4522 +U 10927 ; WX 838 ; N uni2AAF ; G 4523 +U 10928 ; WX 838 ; N uni2AB0 ; G 4524 +U 10929 ; WX 838 ; N uni2AB1 ; G 4525 +U 10930 ; WX 838 ; N uni2AB2 ; G 4526 +U 10931 ; WX 838 ; N uni2AB3 ; G 4527 +U 10932 ; WX 838 ; N uni2AB4 ; G 4528 +U 10933 ; WX 838 ; N uni2AB5 ; G 4529 +U 10934 ; WX 838 ; N uni2AB6 ; G 4530 +U 10935 ; WX 838 ; N uni2AB7 ; G 4531 +U 10936 ; WX 838 ; N uni2AB8 ; G 4532 +U 10937 ; WX 838 ; N uni2AB9 ; G 4533 +U 10938 ; WX 838 ; N uni2ABA ; G 4534 +U 11001 ; WX 838 ; N uni2AF9 ; G 4535 +U 11002 ; WX 838 ; N uni2AFA ; G 4536 +U 11008 ; WX 838 ; N uni2B00 ; G 4537 +U 11009 ; WX 838 ; N uni2B01 ; G 4538 +U 11010 ; WX 838 ; N uni2B02 ; G 4539 +U 11011 ; WX 838 ; N uni2B03 ; G 4540 +U 11012 ; WX 838 ; N uni2B04 ; G 4541 +U 11013 ; WX 838 ; N uni2B05 ; G 4542 +U 11014 ; WX 838 ; N uni2B06 ; G 4543 +U 11015 ; WX 838 ; N uni2B07 ; G 4544 +U 11016 ; WX 838 ; N uni2B08 ; G 4545 +U 11017 ; WX 838 ; N uni2B09 ; G 4546 +U 11018 ; WX 838 ; N uni2B0A ; G 4547 +U 11019 ; WX 838 ; N uni2B0B ; G 4548 +U 11020 ; WX 838 ; N uni2B0C ; G 4549 +U 11021 ; WX 838 ; N uni2B0D ; G 4550 +U 11022 ; WX 838 ; N uni2B0E ; G 4551 +U 11023 ; WX 838 ; N uni2B0F ; G 4552 +U 11024 ; WX 838 ; N uni2B10 ; G 4553 +U 11025 ; WX 838 ; N uni2B11 ; G 4554 +U 11026 ; WX 945 ; N uni2B12 ; G 4555 +U 11027 ; WX 945 ; N uni2B13 ; G 4556 +U 11028 ; WX 945 ; N uni2B14 ; G 4557 +U 11029 ; WX 945 ; N uni2B15 ; G 4558 +U 11030 ; WX 769 ; N uni2B16 ; G 4559 +U 11031 ; WX 769 ; N uni2B17 ; G 4560 +U 11032 ; WX 769 ; N uni2B18 ; G 4561 +U 11033 ; WX 769 ; N uni2B19 ; G 4562 +U 11034 ; WX 945 ; N uni2B1A ; G 4563 +U 11039 ; WX 869 ; N uni2B1F ; G 4564 +U 11040 ; WX 869 ; N uni2B20 ; G 4565 +U 11041 ; WX 873 ; N uni2B21 ; G 4566 +U 11042 ; WX 873 ; N uni2B22 ; G 4567 +U 11043 ; WX 873 ; N uni2B23 ; G 4568 +U 11044 ; WX 1119 ; N uni2B24 ; G 4569 +U 11091 ; WX 869 ; N uni2B53 ; G 4570 +U 11092 ; WX 869 ; N uni2B54 ; G 4571 +U 11360 ; WX 637 ; N uni2C60 ; G 4572 +U 11361 ; WX 360 ; N uni2C61 ; G 4573 +U 11362 ; WX 637 ; N uni2C62 ; G 4574 +U 11363 ; WX 733 ; N uni2C63 ; G 4575 +U 11364 ; WX 770 ; N uni2C64 ; G 4576 +U 11365 ; WX 675 ; N uni2C65 ; G 4577 +U 11366 ; WX 478 ; N uni2C66 ; G 4578 +U 11367 ; WX 956 ; N uni2C67 ; G 4579 +U 11368 ; WX 712 ; N uni2C68 ; G 4580 +U 11369 ; WX 775 ; N uni2C69 ; G 4581 +U 11370 ; WX 665 ; N uni2C6A ; G 4582 +U 11371 ; WX 725 ; N uni2C6B ; G 4583 +U 11372 ; WX 582 ; N uni2C6C ; G 4584 +U 11373 ; WX 860 ; N uni2C6D ; G 4585 +U 11374 ; WX 995 ; N uni2C6E ; G 4586 +U 11375 ; WX 774 ; N uni2C6F ; G 4587 +U 11376 ; WX 860 ; N uni2C70 ; G 4588 +U 11377 ; WX 778 ; N uni2C71 ; G 4589 +U 11378 ; WX 1221 ; N uni2C72 ; G 4590 +U 11379 ; WX 1056 ; N uni2C73 ; G 4591 +U 11380 ; WX 652 ; N uni2C74 ; G 4592 +U 11381 ; WX 698 ; N uni2C75 ; G 4593 +U 11382 ; WX 565 ; N uni2C76 ; G 4594 +U 11383 ; WX 782 ; N uni2C77 ; G 4595 +U 11385 ; WX 538 ; N uni2C79 ; G 4596 +U 11386 ; WX 687 ; N uni2C7A ; G 4597 +U 11387 ; WX 559 ; N uni2C7B ; G 4598 +U 11388 ; WX 219 ; N uni2C7C ; G 4599 +U 11389 ; WX 487 ; N uni2C7D ; G 4600 +U 11390 ; WX 720 ; N uni2C7E ; G 4601 +U 11391 ; WX 725 ; N uni2C7F ; G 4602 +U 11520 ; WX 663 ; N uni2D00 ; G 4603 +U 11521 ; WX 676 ; N uni2D01 ; G 4604 +U 11522 ; WX 661 ; N uni2D02 ; G 4605 +U 11523 ; WX 629 ; N uni2D03 ; G 4606 +U 11524 ; WX 661 ; N uni2D04 ; G 4607 +U 11525 ; WX 1032 ; N uni2D05 ; G 4608 +U 11526 ; WX 718 ; N uni2D06 ; G 4609 +U 11527 ; WX 1032 ; N uni2D07 ; G 4610 +U 11528 ; WX 648 ; N uni2D08 ; G 4611 +U 11529 ; WX 667 ; N uni2D09 ; G 4612 +U 11530 ; WX 1032 ; N uni2D0A ; G 4613 +U 11531 ; WX 673 ; N uni2D0B ; G 4614 +U 11532 ; WX 677 ; N uni2D0C ; G 4615 +U 11533 ; WX 1036 ; N uni2D0D ; G 4616 +U 11534 ; WX 680 ; N uni2D0E ; G 4617 +U 11535 ; WX 886 ; N uni2D0F ; G 4618 +U 11536 ; WX 1032 ; N uni2D10 ; G 4619 +U 11537 ; WX 683 ; N uni2D11 ; G 4620 +U 11538 ; WX 674 ; N uni2D12 ; G 4621 +U 11539 ; WX 1035 ; N uni2D13 ; G 4622 +U 11540 ; WX 1033 ; N uni2D14 ; G 4623 +U 11541 ; WX 1027 ; N uni2D15 ; G 4624 +U 11542 ; WX 676 ; N uni2D16 ; G 4625 +U 11543 ; WX 673 ; N uni2D17 ; G 4626 +U 11544 ; WX 667 ; N uni2D18 ; G 4627 +U 11545 ; WX 667 ; N uni2D19 ; G 4628 +U 11546 ; WX 660 ; N uni2D1A ; G 4629 +U 11547 ; WX 671 ; N uni2D1B ; G 4630 +U 11548 ; WX 1039 ; N uni2D1C ; G 4631 +U 11549 ; WX 673 ; N uni2D1D ; G 4632 +U 11550 ; WX 692 ; N uni2D1E ; G 4633 +U 11551 ; WX 659 ; N uni2D1F ; G 4634 +U 11552 ; WX 1048 ; N uni2D20 ; G 4635 +U 11553 ; WX 660 ; N uni2D21 ; G 4636 +U 11554 ; WX 654 ; N uni2D22 ; G 4637 +U 11555 ; WX 670 ; N uni2D23 ; G 4638 +U 11556 ; WX 733 ; N uni2D24 ; G 4639 +U 11557 ; WX 1017 ; N uni2D25 ; G 4640 +U 11568 ; WX 691 ; N uni2D30 ; G 4641 +U 11569 ; WX 941 ; N uni2D31 ; G 4642 +U 11570 ; WX 941 ; N uni2D32 ; G 4643 +U 11571 ; WX 725 ; N uni2D33 ; G 4644 +U 11572 ; WX 725 ; N uni2D34 ; G 4645 +U 11573 ; WX 725 ; N uni2D35 ; G 4646 +U 11574 ; WX 676 ; N uni2D36 ; G 4647 +U 11575 ; WX 774 ; N uni2D37 ; G 4648 +U 11576 ; WX 774 ; N uni2D38 ; G 4649 +U 11577 ; WX 683 ; N uni2D39 ; G 4650 +U 11578 ; WX 683 ; N uni2D3A ; G 4651 +U 11579 ; WX 802 ; N uni2D3B ; G 4652 +U 11580 ; WX 989 ; N uni2D3C ; G 4653 +U 11581 ; WX 761 ; N uni2D3D ; G 4654 +U 11582 ; WX 623 ; N uni2D3E ; G 4655 +U 11583 ; WX 761 ; N uni2D3F ; G 4656 +U 11584 ; WX 941 ; N uni2D40 ; G 4657 +U 11585 ; WX 941 ; N uni2D41 ; G 4658 +U 11586 ; WX 373 ; N uni2D42 ; G 4659 +U 11587 ; WX 740 ; N uni2D43 ; G 4660 +U 11588 ; WX 837 ; N uni2D44 ; G 4661 +U 11589 ; WX 914 ; N uni2D45 ; G 4662 +U 11590 ; WX 672 ; N uni2D46 ; G 4663 +U 11591 ; WX 737 ; N uni2D47 ; G 4664 +U 11592 ; WX 680 ; N uni2D48 ; G 4665 +U 11593 ; WX 683 ; N uni2D49 ; G 4666 +U 11594 ; WX 602 ; N uni2D4A ; G 4667 +U 11595 ; WX 1039 ; N uni2D4B ; G 4668 +U 11596 ; WX 778 ; N uni2D4C ; G 4669 +U 11597 ; WX 837 ; N uni2D4D ; G 4670 +U 11598 ; WX 683 ; N uni2D4E ; G 4671 +U 11599 ; WX 372 ; N uni2D4F ; G 4672 +U 11600 ; WX 778 ; N uni2D50 ; G 4673 +U 11601 ; WX 373 ; N uni2D51 ; G 4674 +U 11602 ; WX 725 ; N uni2D52 ; G 4675 +U 11603 ; WX 691 ; N uni2D53 ; G 4676 +U 11604 ; WX 941 ; N uni2D54 ; G 4677 +U 11605 ; WX 941 ; N uni2D55 ; G 4678 +U 11606 ; WX 837 ; N uni2D56 ; G 4679 +U 11607 ; WX 373 ; N uni2D57 ; G 4680 +U 11608 ; WX 836 ; N uni2D58 ; G 4681 +U 11609 ; WX 941 ; N uni2D59 ; G 4682 +U 11610 ; WX 941 ; N uni2D5A ; G 4683 +U 11611 ; WX 734 ; N uni2D5B ; G 4684 +U 11612 ; WX 876 ; N uni2D5C ; G 4685 +U 11613 ; WX 771 ; N uni2D5D ; G 4686 +U 11614 ; WX 734 ; N uni2D5E ; G 4687 +U 11615 ; WX 683 ; N uni2D5F ; G 4688 +U 11616 ; WX 774 ; N uni2D60 ; G 4689 +U 11617 ; WX 837 ; N uni2D61 ; G 4690 +U 11618 ; WX 683 ; N uni2D62 ; G 4691 +U 11619 ; WX 850 ; N uni2D63 ; G 4692 +U 11620 ; WX 697 ; N uni2D64 ; G 4693 +U 11621 ; WX 850 ; N uni2D65 ; G 4694 +U 11631 ; WX 716 ; N uni2D6F ; G 4695 +U 11800 ; WX 580 ; N uni2E18 ; G 4696 +U 11807 ; WX 838 ; N uni2E1F ; G 4697 +U 11810 ; WX 457 ; N uni2E22 ; G 4698 +U 11811 ; WX 457 ; N uni2E23 ; G 4699 +U 11812 ; WX 457 ; N uni2E24 ; G 4700 +U 11813 ; WX 457 ; N uni2E25 ; G 4701 +U 11822 ; WX 580 ; N uni2E2E ; G 4702 +U 19904 ; WX 896 ; N uni4DC0 ; G 4703 +U 19905 ; WX 896 ; N uni4DC1 ; G 4704 +U 19906 ; WX 896 ; N uni4DC2 ; G 4705 +U 19907 ; WX 896 ; N uni4DC3 ; G 4706 +U 19908 ; WX 896 ; N uni4DC4 ; G 4707 +U 19909 ; WX 896 ; N uni4DC5 ; G 4708 +U 19910 ; WX 896 ; N uni4DC6 ; G 4709 +U 19911 ; WX 896 ; N uni4DC7 ; G 4710 +U 19912 ; WX 896 ; N uni4DC8 ; G 4711 +U 19913 ; WX 896 ; N uni4DC9 ; G 4712 +U 19914 ; WX 896 ; N uni4DCA ; G 4713 +U 19915 ; WX 896 ; N uni4DCB ; G 4714 +U 19916 ; WX 896 ; N uni4DCC ; G 4715 +U 19917 ; WX 896 ; N uni4DCD ; G 4716 +U 19918 ; WX 896 ; N uni4DCE ; G 4717 +U 19919 ; WX 896 ; N uni4DCF ; G 4718 +U 19920 ; WX 896 ; N uni4DD0 ; G 4719 +U 19921 ; WX 896 ; N uni4DD1 ; G 4720 +U 19922 ; WX 896 ; N uni4DD2 ; G 4721 +U 19923 ; WX 896 ; N uni4DD3 ; G 4722 +U 19924 ; WX 896 ; N uni4DD4 ; G 4723 +U 19925 ; WX 896 ; N uni4DD5 ; G 4724 +U 19926 ; WX 896 ; N uni4DD6 ; G 4725 +U 19927 ; WX 896 ; N uni4DD7 ; G 4726 +U 19928 ; WX 896 ; N uni4DD8 ; G 4727 +U 19929 ; WX 896 ; N uni4DD9 ; G 4728 +U 19930 ; WX 896 ; N uni4DDA ; G 4729 +U 19931 ; WX 896 ; N uni4DDB ; G 4730 +U 19932 ; WX 896 ; N uni4DDC ; G 4731 +U 19933 ; WX 896 ; N uni4DDD ; G 4732 +U 19934 ; WX 896 ; N uni4DDE ; G 4733 +U 19935 ; WX 896 ; N uni4DDF ; G 4734 +U 19936 ; WX 896 ; N uni4DE0 ; G 4735 +U 19937 ; WX 896 ; N uni4DE1 ; G 4736 +U 19938 ; WX 896 ; N uni4DE2 ; G 4737 +U 19939 ; WX 896 ; N uni4DE3 ; G 4738 +U 19940 ; WX 896 ; N uni4DE4 ; G 4739 +U 19941 ; WX 896 ; N uni4DE5 ; G 4740 +U 19942 ; WX 896 ; N uni4DE6 ; G 4741 +U 19943 ; WX 896 ; N uni4DE7 ; G 4742 +U 19944 ; WX 896 ; N uni4DE8 ; G 4743 +U 19945 ; WX 896 ; N uni4DE9 ; G 4744 +U 19946 ; WX 896 ; N uni4DEA ; G 4745 +U 19947 ; WX 896 ; N uni4DEB ; G 4746 +U 19948 ; WX 896 ; N uni4DEC ; G 4747 +U 19949 ; WX 896 ; N uni4DED ; G 4748 +U 19950 ; WX 896 ; N uni4DEE ; G 4749 +U 19951 ; WX 896 ; N uni4DEF ; G 4750 +U 19952 ; WX 896 ; N uni4DF0 ; G 4751 +U 19953 ; WX 896 ; N uni4DF1 ; G 4752 +U 19954 ; WX 896 ; N uni4DF2 ; G 4753 +U 19955 ; WX 896 ; N uni4DF3 ; G 4754 +U 19956 ; WX 896 ; N uni4DF4 ; G 4755 +U 19957 ; WX 896 ; N uni4DF5 ; G 4756 +U 19958 ; WX 896 ; N uni4DF6 ; G 4757 +U 19959 ; WX 896 ; N uni4DF7 ; G 4758 +U 19960 ; WX 896 ; N uni4DF8 ; G 4759 +U 19961 ; WX 896 ; N uni4DF9 ; G 4760 +U 19962 ; WX 896 ; N uni4DFA ; G 4761 +U 19963 ; WX 896 ; N uni4DFB ; G 4762 +U 19964 ; WX 896 ; N uni4DFC ; G 4763 +U 19965 ; WX 896 ; N uni4DFD ; G 4764 +U 19966 ; WX 896 ; N uni4DFE ; G 4765 +U 19967 ; WX 896 ; N uni4DFF ; G 4766 +U 42192 ; WX 762 ; N uniA4D0 ; G 4767 +U 42193 ; WX 733 ; N uniA4D1 ; G 4768 +U 42194 ; WX 733 ; N uniA4D2 ; G 4769 +U 42195 ; WX 830 ; N uniA4D3 ; G 4770 +U 42196 ; WX 682 ; N uniA4D4 ; G 4771 +U 42197 ; WX 682 ; N uniA4D5 ; G 4772 +U 42198 ; WX 821 ; N uniA4D6 ; G 4773 +U 42199 ; WX 775 ; N uniA4D7 ; G 4774 +U 42200 ; WX 775 ; N uniA4D8 ; G 4775 +U 42201 ; WX 530 ; N uniA4D9 ; G 4776 +U 42202 ; WX 734 ; N uniA4DA ; G 4777 +U 42203 ; WX 734 ; N uniA4DB ; G 4778 +U 42204 ; WX 725 ; N uniA4DC ; G 4779 +U 42205 ; WX 683 ; N uniA4DD ; G 4780 +U 42206 ; WX 683 ; N uniA4DE ; G 4781 +U 42207 ; WX 995 ; N uniA4DF ; G 4782 +U 42208 ; WX 837 ; N uniA4E0 ; G 4783 +U 42209 ; WX 637 ; N uniA4E1 ; G 4784 +U 42210 ; WX 720 ; N uniA4E2 ; G 4785 +U 42211 ; WX 770 ; N uniA4E3 ; G 4786 +U 42212 ; WX 770 ; N uniA4E4 ; G 4787 +U 42213 ; WX 774 ; N uniA4E5 ; G 4788 +U 42214 ; WX 774 ; N uniA4E6 ; G 4789 +U 42215 ; WX 837 ; N uniA4E7 ; G 4790 +U 42216 ; WX 775 ; N uniA4E8 ; G 4791 +U 42217 ; WX 530 ; N uniA4E9 ; G 4792 +U 42218 ; WX 1103 ; N uniA4EA ; G 4793 +U 42219 ; WX 771 ; N uniA4EB ; G 4794 +U 42220 ; WX 724 ; N uniA4EC ; G 4795 +U 42221 ; WX 762 ; N uniA4ED ; G 4796 +U 42222 ; WX 774 ; N uniA4EE ; G 4797 +U 42223 ; WX 774 ; N uniA4EF ; G 4798 +U 42224 ; WX 683 ; N uniA4F0 ; G 4799 +U 42225 ; WX 683 ; N uniA4F1 ; G 4800 +U 42226 ; WX 372 ; N uniA4F2 ; G 4801 +U 42227 ; WX 850 ; N uniA4F3 ; G 4802 +U 42228 ; WX 812 ; N uniA4F4 ; G 4803 +U 42229 ; WX 812 ; N uniA4F5 ; G 4804 +U 42230 ; WX 557 ; N uniA4F6 ; G 4805 +U 42231 ; WX 830 ; N uniA4F7 ; G 4806 +U 42232 ; WX 322 ; N uniA4F8 ; G 4807 +U 42233 ; WX 322 ; N uniA4F9 ; G 4808 +U 42234 ; WX 674 ; N uniA4FA ; G 4809 +U 42235 ; WX 674 ; N uniA4FB ; G 4810 +U 42236 ; WX 322 ; N uniA4FC ; G 4811 +U 42237 ; WX 322 ; N uniA4FD ; G 4812 +U 42238 ; WX 588 ; N uniA4FE ; G 4813 +U 42239 ; WX 588 ; N uniA4FF ; G 4814 +U 42564 ; WX 720 ; N uniA644 ; G 4815 +U 42565 ; WX 595 ; N uniA645 ; G 4816 +U 42566 ; WX 436 ; N uniA646 ; G 4817 +U 42567 ; WX 440 ; N uniA647 ; G 4818 +U 42572 ; WX 1405 ; N uniA64C ; G 4819 +U 42573 ; WX 1173 ; N uniA64D ; G 4820 +U 42576 ; WX 1234 ; N uniA650 ; G 4821 +U 42577 ; WX 1027 ; N uniA651 ; G 4822 +U 42580 ; WX 1174 ; N uniA654 ; G 4823 +U 42581 ; WX 972 ; N uniA655 ; G 4824 +U 42582 ; WX 1093 ; N uniA656 ; G 4825 +U 42583 ; WX 958 ; N uniA657 ; G 4826 +U 42594 ; WX 1085 ; N uniA662 ; G 4827 +U 42595 ; WX 924 ; N uniA663 ; G 4828 +U 42596 ; WX 1096 ; N uniA664 ; G 4829 +U 42597 ; WX 912 ; N uniA665 ; G 4830 +U 42598 ; WX 1260 ; N uniA666 ; G 4831 +U 42599 ; WX 997 ; N uniA667 ; G 4832 +U 42600 ; WX 850 ; N uniA668 ; G 4833 +U 42601 ; WX 687 ; N uniA669 ; G 4834 +U 42602 ; WX 1037 ; N uniA66A ; G 4835 +U 42603 ; WX 868 ; N uniA66B ; G 4836 +U 42604 ; WX 1406 ; N uniA66C ; G 4837 +U 42605 ; WX 1106 ; N uniA66D ; G 4838 +U 42606 ; WX 961 ; N uniA66E ; G 4839 +U 42634 ; WX 963 ; N uniA68A ; G 4840 +U 42635 ; WX 787 ; N uniA68B ; G 4841 +U 42636 ; WX 682 ; N uniA68C ; G 4842 +U 42637 ; WX 580 ; N uniA68D ; G 4843 +U 42644 ; WX 808 ; N uniA694 ; G 4844 +U 42645 ; WX 712 ; N uniA695 ; G 4845 +U 42648 ; WX 1406 ; N uniA698 ; G 4846 +U 42649 ; WX 1106 ; N uniA699 ; G 4847 +U 42760 ; WX 500 ; N uniA708 ; G 4848 +U 42761 ; WX 500 ; N uniA709 ; G 4849 +U 42762 ; WX 500 ; N uniA70A ; G 4850 +U 42763 ; WX 500 ; N uniA70B ; G 4851 +U 42764 ; WX 500 ; N uniA70C ; G 4852 +U 42765 ; WX 500 ; N uniA70D ; G 4853 +U 42766 ; WX 500 ; N uniA70E ; G 4854 +U 42767 ; WX 500 ; N uniA70F ; G 4855 +U 42768 ; WX 500 ; N uniA710 ; G 4856 +U 42769 ; WX 500 ; N uniA711 ; G 4857 +U 42770 ; WX 500 ; N uniA712 ; G 4858 +U 42771 ; WX 500 ; N uniA713 ; G 4859 +U 42772 ; WX 500 ; N uniA714 ; G 4860 +U 42773 ; WX 500 ; N uniA715 ; G 4861 +U 42774 ; WX 500 ; N uniA716 ; G 4862 +U 42779 ; WX 400 ; N uniA71B ; G 4863 +U 42780 ; WX 400 ; N uniA71C ; G 4864 +U 42781 ; WX 287 ; N uniA71D ; G 4865 +U 42782 ; WX 287 ; N uniA71E ; G 4866 +U 42783 ; WX 287 ; N uniA71F ; G 4867 +U 42786 ; WX 444 ; N uniA722 ; G 4868 +U 42787 ; WX 390 ; N uniA723 ; G 4869 +U 42788 ; WX 540 ; N uniA724 ; G 4870 +U 42789 ; WX 540 ; N uniA725 ; G 4871 +U 42790 ; WX 837 ; N uniA726 ; G 4872 +U 42791 ; WX 712 ; N uniA727 ; G 4873 +U 42792 ; WX 1031 ; N uniA728 ; G 4874 +U 42793 ; WX 857 ; N uniA729 ; G 4875 +U 42794 ; WX 696 ; N uniA72A ; G 4876 +U 42795 ; WX 557 ; N uniA72B ; G 4877 +U 42800 ; WX 559 ; N uniA730 ; G 4878 +U 42801 ; WX 595 ; N uniA731 ; G 4879 +U 42802 ; WX 1349 ; N uniA732 ; G 4880 +U 42803 ; WX 1052 ; N uniA733 ; G 4881 +U 42804 ; WX 1284 ; N uniA734 ; G 4882 +U 42805 ; WX 1064 ; N uniA735 ; G 4883 +U 42806 ; WX 1216 ; N uniA736 ; G 4884 +U 42807 ; WX 1054 ; N uniA737 ; G 4885 +U 42808 ; WX 1079 ; N uniA738 ; G 4886 +U 42809 ; WX 922 ; N uniA739 ; G 4887 +U 42810 ; WX 1079 ; N uniA73A ; G 4888 +U 42811 ; WX 922 ; N uniA73B ; G 4889 +U 42812 ; WX 1035 ; N uniA73C ; G 4890 +U 42813 ; WX 922 ; N uniA73D ; G 4891 +U 42814 ; WX 698 ; N uniA73E ; G 4892 +U 42815 ; WX 549 ; N uniA73F ; G 4893 +U 42816 ; WX 656 ; N uniA740 ; G 4894 +U 42817 ; WX 688 ; N uniA741 ; G 4895 +U 42822 ; WX 850 ; N uniA746 ; G 4896 +U 42823 ; WX 542 ; N uniA747 ; G 4897 +U 42824 ; WX 683 ; N uniA748 ; G 4898 +U 42825 ; WX 531 ; N uniA749 ; G 4899 +U 42826 ; WX 918 ; N uniA74A ; G 4900 +U 42827 ; WX 814 ; N uniA74B ; G 4901 +U 42830 ; WX 1406 ; N uniA74E ; G 4902 +U 42831 ; WX 1106 ; N uniA74F ; G 4903 +U 42832 ; WX 733 ; N uniA750 ; G 4904 +U 42833 ; WX 716 ; N uniA751 ; G 4905 +U 42834 ; WX 948 ; N uniA752 ; G 4906 +U 42835 ; WX 937 ; N uniA753 ; G 4907 +U 42838 ; WX 850 ; N uniA756 ; G 4908 +U 42839 ; WX 716 ; N uniA757 ; G 4909 +U 42852 ; WX 738 ; N uniA764 ; G 4910 +U 42853 ; WX 716 ; N uniA765 ; G 4911 +U 42854 ; WX 738 ; N uniA766 ; G 4912 +U 42855 ; WX 716 ; N uniA767 ; G 4913 +U 42880 ; WX 637 ; N uniA780 ; G 4914 +U 42881 ; WX 343 ; N uniA781 ; G 4915 +U 42882 ; WX 837 ; N uniA782 ; G 4916 +U 42883 ; WX 712 ; N uniA783 ; G 4917 +U 42889 ; WX 400 ; N uniA789 ; G 4918 +U 42890 ; WX 386 ; N uniA78A ; G 4919 +U 42891 ; WX 456 ; N uniA78B ; G 4920 +U 42892 ; WX 306 ; N uniA78C ; G 4921 +U 42893 ; WX 808 ; N uniA78D ; G 4922 +U 42894 ; WX 693 ; N uniA78E ; G 4923 +U 42896 ; WX 928 ; N uniA790 ; G 4924 +U 42897 ; WX 768 ; N uniA791 ; G 4925 +U 42912 ; WX 821 ; N uniA7A0 ; G 4926 +U 42913 ; WX 716 ; N uniA7A1 ; G 4927 +U 42914 ; WX 775 ; N uniA7A2 ; G 4928 +U 42915 ; WX 665 ; N uniA7A3 ; G 4929 +U 42916 ; WX 837 ; N uniA7A4 ; G 4930 +U 42917 ; WX 712 ; N uniA7A5 ; G 4931 +U 42918 ; WX 770 ; N uniA7A6 ; G 4932 +U 42919 ; WX 493 ; N uniA7A7 ; G 4933 +U 42920 ; WX 720 ; N uniA7A8 ; G 4934 +U 42921 ; WX 595 ; N uniA7A9 ; G 4935 +U 42922 ; WX 886 ; N uniA7AA ; G 4936 +U 43000 ; WX 613 ; N uniA7F8 ; G 4937 +U 43001 ; WX 689 ; N uniA7F9 ; G 4938 +U 43002 ; WX 1062 ; N uniA7FA ; G 4939 +U 43003 ; WX 683 ; N uniA7FB ; G 4940 +U 43004 ; WX 733 ; N uniA7FC ; G 4941 +U 43005 ; WX 995 ; N uniA7FD ; G 4942 +U 43006 ; WX 372 ; N uniA7FE ; G 4943 +U 43007 ; WX 1325 ; N uniA7FF ; G 4944 +U 61184 ; WX 216 ; N uni02E5.5 ; G 4945 +U 61185 ; WX 242 ; N uni02E6.5 ; G 4946 +U 61186 ; WX 267 ; N uni02E7.5 ; G 4947 +U 61187 ; WX 277 ; N uni02E8.5 ; G 4948 +U 61188 ; WX 282 ; N uni02E9.5 ; G 4949 +U 61189 ; WX 242 ; N uni02E5.4 ; G 4950 +U 61190 ; WX 216 ; N uni02E6.4 ; G 4951 +U 61191 ; WX 242 ; N uni02E7.4 ; G 4952 +U 61192 ; WX 267 ; N uni02E8.4 ; G 4953 +U 61193 ; WX 277 ; N uni02E9.4 ; G 4954 +U 61194 ; WX 267 ; N uni02E5.3 ; G 4955 +U 61195 ; WX 242 ; N uni02E6.3 ; G 4956 +U 61196 ; WX 216 ; N uni02E7.3 ; G 4957 +U 61197 ; WX 242 ; N uni02E8.3 ; G 4958 +U 61198 ; WX 267 ; N uni02E9.3 ; G 4959 +U 61199 ; WX 277 ; N uni02E5.2 ; G 4960 +U 61200 ; WX 267 ; N uni02E6.2 ; G 4961 +U 61201 ; WX 242 ; N uni02E7.2 ; G 4962 +U 61202 ; WX 216 ; N uni02E8.2 ; G 4963 +U 61203 ; WX 242 ; N uni02E9.2 ; G 4964 +U 61204 ; WX 282 ; N uni02E5.1 ; G 4965 +U 61205 ; WX 277 ; N uni02E6.1 ; G 4966 +U 61206 ; WX 267 ; N uni02E7.1 ; G 4967 +U 61207 ; WX 242 ; N uni02E8.1 ; G 4968 +U 61208 ; WX 216 ; N uni02E9.1 ; G 4969 +U 61209 ; WX 282 ; N stem ; G 4970 +U 62464 ; WX 612 ; N uniF400 ; G 4971 +U 62465 ; WX 612 ; N uniF401 ; G 4972 +U 62466 ; WX 653 ; N uniF402 ; G 4973 +U 62467 ; WX 902 ; N uniF403 ; G 4974 +U 62468 ; WX 622 ; N uniF404 ; G 4975 +U 62469 ; WX 622 ; N uniF405 ; G 4976 +U 62470 ; WX 661 ; N uniF406 ; G 4977 +U 62471 ; WX 895 ; N uniF407 ; G 4978 +U 62472 ; WX 589 ; N uniF408 ; G 4979 +U 62473 ; WX 622 ; N uniF409 ; G 4980 +U 62474 ; WX 1163 ; N uniF40A ; G 4981 +U 62475 ; WX 626 ; N uniF40B ; G 4982 +U 62476 ; WX 627 ; N uniF40C ; G 4983 +U 62477 ; WX 893 ; N uniF40D ; G 4984 +U 62478 ; WX 612 ; N uniF40E ; G 4985 +U 62479 ; WX 626 ; N uniF40F ; G 4986 +U 62480 ; WX 924 ; N uniF410 ; G 4987 +U 62481 ; WX 627 ; N uniF411 ; G 4988 +U 62482 ; WX 744 ; N uniF412 ; G 4989 +U 62483 ; WX 634 ; N uniF413 ; G 4990 +U 62484 ; WX 886 ; N uniF414 ; G 4991 +U 62485 ; WX 626 ; N uniF415 ; G 4992 +U 62486 ; WX 907 ; N uniF416 ; G 4993 +U 62487 ; WX 626 ; N uniF417 ; G 4994 +U 62488 ; WX 621 ; N uniF418 ; G 4995 +U 62489 ; WX 628 ; N uniF419 ; G 4996 +U 62490 ; WX 677 ; N uniF41A ; G 4997 +U 62491 ; WX 626 ; N uniF41B ; G 4998 +U 62492 ; WX 621 ; N uniF41C ; G 4999 +U 62493 ; WX 630 ; N uniF41D ; G 5000 +U 62494 ; WX 627 ; N uniF41E ; G 5001 +U 62495 ; WX 571 ; N uniF41F ; G 5002 +U 62496 ; WX 622 ; N uniF420 ; G 5003 +U 62497 ; WX 631 ; N uniF421 ; G 5004 +U 62498 ; WX 612 ; N uniF422 ; G 5005 +U 62499 ; WX 611 ; N uniF423 ; G 5006 +U 62500 ; WX 618 ; N uniF424 ; G 5007 +U 62501 ; WX 671 ; N uniF425 ; G 5008 +U 62502 ; WX 963 ; N uniF426 ; G 5009 +U 62504 ; WX 1023 ; N uniF428 ; G 5010 +U 62505 ; WX 844 ; N uniF429 ; G 5011 +U 62506 ; WX 563 ; N uniF42A ; G 5012 +U 62507 ; WX 563 ; N uniF42B ; G 5013 +U 62508 ; WX 563 ; N uniF42C ; G 5014 +U 62509 ; WX 563 ; N uniF42D ; G 5015 +U 62510 ; WX 563 ; N uniF42E ; G 5016 +U 62511 ; WX 563 ; N uniF42F ; G 5017 +U 62512 ; WX 555 ; N uniF430 ; G 5018 +U 62513 ; WX 555 ; N uniF431 ; G 5019 +U 62514 ; WX 555 ; N uniF432 ; G 5020 +U 62515 ; WX 555 ; N uniF433 ; G 5021 +U 62516 ; WX 573 ; N uniF434 ; G 5022 +U 62517 ; WX 573 ; N uniF435 ; G 5023 +U 62518 ; WX 573 ; N uniF436 ; G 5024 +U 62519 ; WX 824 ; N uniF437 ; G 5025 +U 62520 ; WX 824 ; N uniF438 ; G 5026 +U 62521 ; WX 824 ; N uniF439 ; G 5027 +U 62522 ; WX 824 ; N uniF43A ; G 5028 +U 62523 ; WX 824 ; N uniF43B ; G 5029 +U 62524 ; WX 611 ; N uniF43C ; G 5030 +U 62525 ; WX 611 ; N uniF43D ; G 5031 +U 62526 ; WX 611 ; N uniF43E ; G 5032 +U 62527 ; WX 611 ; N uniF43F ; G 5033 +U 62528 ; WX 611 ; N uniF440 ; G 5034 +U 62529 ; WX 611 ; N uniF441 ; G 5035 +U 63173 ; WX 687 ; N uniF6C5 ; G 5036 +U 64256 ; WX 810 ; N uniFB00 ; G 5037 +U 64257 ; WX 741 ; N fi ; G 5038 +U 64258 ; WX 741 ; N fl ; G 5039 +U 64259 ; WX 1115 ; N uniFB03 ; G 5040 +U 64260 ; WX 1116 ; N uniFB04 ; G 5041 +U 64261 ; WX 808 ; N uniFB05 ; G 5042 +U 64262 ; WX 1020 ; N uniFB06 ; G 5043 +U 64275 ; WX 1388 ; N uniFB13 ; G 5044 +U 64276 ; WX 1384 ; N uniFB14 ; G 5045 +U 64277 ; WX 1378 ; N uniFB15 ; G 5046 +U 64278 ; WX 1384 ; N uniFB16 ; G 5047 +U 64279 ; WX 1713 ; N uniFB17 ; G 5048 +U 64285 ; WX 294 ; N uniFB1D ; G 5049 +U 64286 ; WX 0 ; N uniFB1E ; G 5050 +U 64287 ; WX 519 ; N uniFB1F ; G 5051 +U 64288 ; WX 665 ; N uniFB20 ; G 5052 +U 64289 ; WX 939 ; N uniFB21 ; G 5053 +U 64290 ; WX 788 ; N uniFB22 ; G 5054 +U 64291 ; WX 920 ; N uniFB23 ; G 5055 +U 64292 ; WX 786 ; N uniFB24 ; G 5056 +U 64293 ; WX 857 ; N uniFB25 ; G 5057 +U 64294 ; WX 869 ; N uniFB26 ; G 5058 +U 64295 ; WX 821 ; N uniFB27 ; G 5059 +U 64296 ; WX 890 ; N uniFB28 ; G 5060 +U 64297 ; WX 838 ; N uniFB29 ; G 5061 +U 64298 ; WX 758 ; N uniFB2A ; G 5062 +U 64299 ; WX 758 ; N uniFB2B ; G 5063 +U 64300 ; WX 758 ; N uniFB2C ; G 5064 +U 64301 ; WX 758 ; N uniFB2D ; G 5065 +U 64302 ; WX 728 ; N uniFB2E ; G 5066 +U 64303 ; WX 728 ; N uniFB2F ; G 5067 +U 64304 ; WX 728 ; N uniFB30 ; G 5068 +U 64305 ; WX 610 ; N uniFB31 ; G 5069 +U 64306 ; WX 447 ; N uniFB32 ; G 5070 +U 64307 ; WX 588 ; N uniFB33 ; G 5071 +U 64308 ; WX 687 ; N uniFB34 ; G 5072 +U 64309 ; WX 437 ; N uniFB35 ; G 5073 +U 64310 ; WX 485 ; N uniFB36 ; G 5074 +U 64312 ; WX 679 ; N uniFB38 ; G 5075 +U 64313 ; WX 435 ; N uniFB39 ; G 5076 +U 64314 ; WX 578 ; N uniFB3A ; G 5077 +U 64315 ; WX 566 ; N uniFB3B ; G 5078 +U 64316 ; WX 605 ; N uniFB3C ; G 5079 +U 64318 ; WX 724 ; N uniFB3E ; G 5080 +U 64320 ; WX 453 ; N uniFB40 ; G 5081 +U 64321 ; WX 680 ; N uniFB41 ; G 5082 +U 64323 ; WX 675 ; N uniFB43 ; G 5083 +U 64324 ; WX 658 ; N uniFB44 ; G 5084 +U 64326 ; WX 653 ; N uniFB46 ; G 5085 +U 64327 ; WX 736 ; N uniFB47 ; G 5086 +U 64328 ; WX 602 ; N uniFB48 ; G 5087 +U 64329 ; WX 758 ; N uniFB49 ; G 5088 +U 64330 ; WX 683 ; N uniFB4A ; G 5089 +U 64331 ; WX 343 ; N uniFB4B ; G 5090 +U 64332 ; WX 610 ; N uniFB4C ; G 5091 +U 64333 ; WX 566 ; N uniFB4D ; G 5092 +U 64334 ; WX 658 ; N uniFB4E ; G 5093 +U 64335 ; WX 710 ; N uniFB4F ; G 5094 +U 64338 ; WX 1005 ; N uniFB52 ; G 5095 +U 64339 ; WX 1059 ; N uniFB53 ; G 5096 +U 64340 ; WX 375 ; N uniFB54 ; G 5097 +U 64341 ; WX 408 ; N uniFB55 ; G 5098 +U 64342 ; WX 1005 ; N uniFB56 ; G 5099 +U 64343 ; WX 1059 ; N uniFB57 ; G 5100 +U 64344 ; WX 375 ; N uniFB58 ; G 5101 +U 64345 ; WX 408 ; N uniFB59 ; G 5102 +U 64346 ; WX 1005 ; N uniFB5A ; G 5103 +U 64347 ; WX 1059 ; N uniFB5B ; G 5104 +U 64348 ; WX 375 ; N uniFB5C ; G 5105 +U 64349 ; WX 408 ; N uniFB5D ; G 5106 +U 64350 ; WX 1005 ; N uniFB5E ; G 5107 +U 64351 ; WX 1059 ; N uniFB5F ; G 5108 +U 64352 ; WX 375 ; N uniFB60 ; G 5109 +U 64353 ; WX 408 ; N uniFB61 ; G 5110 +U 64354 ; WX 1005 ; N uniFB62 ; G 5111 +U 64355 ; WX 1059 ; N uniFB63 ; G 5112 +U 64356 ; WX 375 ; N uniFB64 ; G 5113 +U 64357 ; WX 408 ; N uniFB65 ; G 5114 +U 64358 ; WX 1005 ; N uniFB66 ; G 5115 +U 64359 ; WX 1059 ; N uniFB67 ; G 5116 +U 64360 ; WX 375 ; N uniFB68 ; G 5117 +U 64361 ; WX 408 ; N uniFB69 ; G 5118 +U 64362 ; WX 1162 ; N uniFB6A ; G 5119 +U 64363 ; WX 1191 ; N uniFB6B ; G 5120 +U 64364 ; WX 655 ; N uniFB6C ; G 5121 +U 64365 ; WX 720 ; N uniFB6D ; G 5122 +U 64366 ; WX 1162 ; N uniFB6E ; G 5123 +U 64367 ; WX 1191 ; N uniFB6F ; G 5124 +U 64368 ; WX 655 ; N uniFB70 ; G 5125 +U 64369 ; WX 720 ; N uniFB71 ; G 5126 +U 64370 ; WX 721 ; N uniFB72 ; G 5127 +U 64371 ; WX 721 ; N uniFB73 ; G 5128 +U 64372 ; WX 721 ; N uniFB74 ; G 5129 +U 64373 ; WX 721 ; N uniFB75 ; G 5130 +U 64374 ; WX 721 ; N uniFB76 ; G 5131 +U 64375 ; WX 721 ; N uniFB77 ; G 5132 +U 64376 ; WX 721 ; N uniFB78 ; G 5133 +U 64377 ; WX 721 ; N uniFB79 ; G 5134 +U 64378 ; WX 721 ; N uniFB7A ; G 5135 +U 64379 ; WX 721 ; N uniFB7B ; G 5136 +U 64380 ; WX 721 ; N uniFB7C ; G 5137 +U 64381 ; WX 721 ; N uniFB7D ; G 5138 +U 64382 ; WX 721 ; N uniFB7E ; G 5139 +U 64383 ; WX 721 ; N uniFB7F ; G 5140 +U 64384 ; WX 721 ; N uniFB80 ; G 5141 +U 64385 ; WX 721 ; N uniFB81 ; G 5142 +U 64386 ; WX 513 ; N uniFB82 ; G 5143 +U 64387 ; WX 578 ; N uniFB83 ; G 5144 +U 64388 ; WX 513 ; N uniFB84 ; G 5145 +U 64389 ; WX 578 ; N uniFB85 ; G 5146 +U 64390 ; WX 513 ; N uniFB86 ; G 5147 +U 64391 ; WX 578 ; N uniFB87 ; G 5148 +U 64392 ; WX 513 ; N uniFB88 ; G 5149 +U 64393 ; WX 578 ; N uniFB89 ; G 5150 +U 64394 ; WX 576 ; N uniFB8A ; G 5151 +U 64395 ; WX 622 ; N uniFB8B ; G 5152 +U 64396 ; WX 576 ; N uniFB8C ; G 5153 +U 64397 ; WX 622 ; N uniFB8D ; G 5154 +U 64398 ; WX 1024 ; N uniFB8E ; G 5155 +U 64399 ; WX 1024 ; N uniFB8F ; G 5156 +U 64400 ; WX 582 ; N uniFB90 ; G 5157 +U 64401 ; WX 582 ; N uniFB91 ; G 5158 +U 64402 ; WX 1024 ; N uniFB92 ; G 5159 +U 64403 ; WX 1024 ; N uniFB93 ; G 5160 +U 64404 ; WX 582 ; N uniFB94 ; G 5161 +U 64405 ; WX 582 ; N uniFB95 ; G 5162 +U 64406 ; WX 1024 ; N uniFB96 ; G 5163 +U 64407 ; WX 1024 ; N uniFB97 ; G 5164 +U 64408 ; WX 582 ; N uniFB98 ; G 5165 +U 64409 ; WX 582 ; N uniFB99 ; G 5166 +U 64410 ; WX 1024 ; N uniFB9A ; G 5167 +U 64411 ; WX 1024 ; N uniFB9B ; G 5168 +U 64412 ; WX 582 ; N uniFB9C ; G 5169 +U 64413 ; WX 582 ; N uniFB9D ; G 5170 +U 64414 ; WX 854 ; N uniFB9E ; G 5171 +U 64415 ; WX 900 ; N uniFB9F ; G 5172 +U 64416 ; WX 854 ; N uniFBA0 ; G 5173 +U 64417 ; WX 900 ; N uniFBA1 ; G 5174 +U 64418 ; WX 375 ; N uniFBA2 ; G 5175 +U 64419 ; WX 408 ; N uniFBA3 ; G 5176 +U 64426 ; WX 938 ; N uniFBAA ; G 5177 +U 64427 ; WX 880 ; N uniFBAB ; G 5178 +U 64428 ; WX 693 ; N uniFBAC ; G 5179 +U 64429 ; WX 660 ; N uniFBAD ; G 5180 +U 64467 ; WX 824 ; N uniFBD3 ; G 5181 +U 64468 ; WX 843 ; N uniFBD4 ; G 5182 +U 64469 ; WX 476 ; N uniFBD5 ; G 5183 +U 64470 ; WX 552 ; N uniFBD6 ; G 5184 +U 64471 ; WX 622 ; N uniFBD7 ; G 5185 +U 64472 ; WX 627 ; N uniFBD8 ; G 5186 +U 64473 ; WX 622 ; N uniFBD9 ; G 5187 +U 64474 ; WX 627 ; N uniFBDA ; G 5188 +U 64475 ; WX 622 ; N uniFBDB ; G 5189 +U 64476 ; WX 627 ; N uniFBDC ; G 5190 +U 64478 ; WX 622 ; N uniFBDE ; G 5191 +U 64479 ; WX 627 ; N uniFBDF ; G 5192 +U 64484 ; WX 917 ; N uniFBE4 ; G 5193 +U 64485 ; WX 1012 ; N uniFBE5 ; G 5194 +U 64486 ; WX 375 ; N uniFBE6 ; G 5195 +U 64487 ; WX 408 ; N uniFBE7 ; G 5196 +U 64488 ; WX 375 ; N uniFBE8 ; G 5197 +U 64489 ; WX 408 ; N uniFBE9 ; G 5198 +U 64508 ; WX 917 ; N uniFBFC ; G 5199 +U 64509 ; WX 1012 ; N uniFBFD ; G 5200 +U 64510 ; WX 375 ; N uniFBFE ; G 5201 +U 64511 ; WX 408 ; N uniFBFF ; G 5202 +U 65024 ; WX 0 ; N uniFE00 ; G 5203 +U 65025 ; WX 0 ; N uniFE01 ; G 5204 +U 65026 ; WX 0 ; N uniFE02 ; G 5205 +U 65027 ; WX 0 ; N uniFE03 ; G 5206 +U 65028 ; WX 0 ; N uniFE04 ; G 5207 +U 65029 ; WX 0 ; N uniFE05 ; G 5208 +U 65030 ; WX 0 ; N uniFE06 ; G 5209 +U 65031 ; WX 0 ; N uniFE07 ; G 5210 +U 65032 ; WX 0 ; N uniFE08 ; G 5211 +U 65033 ; WX 0 ; N uniFE09 ; G 5212 +U 65034 ; WX 0 ; N uniFE0A ; G 5213 +U 65035 ; WX 0 ; N uniFE0B ; G 5214 +U 65036 ; WX 0 ; N uniFE0C ; G 5215 +U 65037 ; WX 0 ; N uniFE0D ; G 5216 +U 65038 ; WX 0 ; N uniFE0E ; G 5217 +U 65039 ; WX 0 ; N uniFE0F ; G 5218 +U 65056 ; WX 0 ; N uniFE20 ; G 5219 +U 65057 ; WX 0 ; N uniFE21 ; G 5220 +U 65058 ; WX 0 ; N uniFE22 ; G 5221 +U 65059 ; WX 0 ; N uniFE23 ; G 5222 +U 65136 ; WX 342 ; N uniFE70 ; G 5223 +U 65137 ; WX 342 ; N uniFE71 ; G 5224 +U 65138 ; WX 342 ; N uniFE72 ; G 5225 +U 65139 ; WX 346 ; N uniFE73 ; G 5226 +U 65140 ; WX 342 ; N uniFE74 ; G 5227 +U 65142 ; WX 342 ; N uniFE76 ; G 5228 +U 65143 ; WX 342 ; N uniFE77 ; G 5229 +U 65144 ; WX 342 ; N uniFE78 ; G 5230 +U 65145 ; WX 342 ; N uniFE79 ; G 5231 +U 65146 ; WX 342 ; N uniFE7A ; G 5232 +U 65147 ; WX 342 ; N uniFE7B ; G 5233 +U 65148 ; WX 342 ; N uniFE7C ; G 5234 +U 65149 ; WX 342 ; N uniFE7D ; G 5235 +U 65150 ; WX 342 ; N uniFE7E ; G 5236 +U 65151 ; WX 342 ; N uniFE7F ; G 5237 +U 65152 ; WX 511 ; N uniFE80 ; G 5238 +U 65153 ; WX 343 ; N uniFE81 ; G 5239 +U 65154 ; WX 375 ; N uniFE82 ; G 5240 +U 65155 ; WX 343 ; N uniFE83 ; G 5241 +U 65156 ; WX 375 ; N uniFE84 ; G 5242 +U 65157 ; WX 622 ; N uniFE85 ; G 5243 +U 65158 ; WX 627 ; N uniFE86 ; G 5244 +U 65159 ; WX 343 ; N uniFE87 ; G 5245 +U 65160 ; WX 375 ; N uniFE88 ; G 5246 +U 65161 ; WX 917 ; N uniFE89 ; G 5247 +U 65162 ; WX 917 ; N uniFE8A ; G 5248 +U 65163 ; WX 375 ; N uniFE8B ; G 5249 +U 65164 ; WX 408 ; N uniFE8C ; G 5250 +U 65165 ; WX 343 ; N uniFE8D ; G 5251 +U 65166 ; WX 375 ; N uniFE8E ; G 5252 +U 65167 ; WX 1005 ; N uniFE8F ; G 5253 +U 65168 ; WX 1059 ; N uniFE90 ; G 5254 +U 65169 ; WX 375 ; N uniFE91 ; G 5255 +U 65170 ; WX 408 ; N uniFE92 ; G 5256 +U 65171 ; WX 590 ; N uniFE93 ; G 5257 +U 65172 ; WX 606 ; N uniFE94 ; G 5258 +U 65173 ; WX 1005 ; N uniFE95 ; G 5259 +U 65174 ; WX 1059 ; N uniFE96 ; G 5260 +U 65175 ; WX 375 ; N uniFE97 ; G 5261 +U 65176 ; WX 408 ; N uniFE98 ; G 5262 +U 65177 ; WX 1005 ; N uniFE99 ; G 5263 +U 65178 ; WX 1059 ; N uniFE9A ; G 5264 +U 65179 ; WX 375 ; N uniFE9B ; G 5265 +U 65180 ; WX 408 ; N uniFE9C ; G 5266 +U 65181 ; WX 721 ; N uniFE9D ; G 5267 +U 65182 ; WX 721 ; N uniFE9E ; G 5268 +U 65183 ; WX 721 ; N uniFE9F ; G 5269 +U 65184 ; WX 721 ; N uniFEA0 ; G 5270 +U 65185 ; WX 721 ; N uniFEA1 ; G 5271 +U 65186 ; WX 721 ; N uniFEA2 ; G 5272 +U 65187 ; WX 721 ; N uniFEA3 ; G 5273 +U 65188 ; WX 721 ; N uniFEA4 ; G 5274 +U 65189 ; WX 721 ; N uniFEA5 ; G 5275 +U 65190 ; WX 721 ; N uniFEA6 ; G 5276 +U 65191 ; WX 721 ; N uniFEA7 ; G 5277 +U 65192 ; WX 721 ; N uniFEA8 ; G 5278 +U 65193 ; WX 513 ; N uniFEA9 ; G 5279 +U 65194 ; WX 578 ; N uniFEAA ; G 5280 +U 65195 ; WX 513 ; N uniFEAB ; G 5281 +U 65196 ; WX 578 ; N uniFEAC ; G 5282 +U 65197 ; WX 576 ; N uniFEAD ; G 5283 +U 65198 ; WX 622 ; N uniFEAE ; G 5284 +U 65199 ; WX 576 ; N uniFEAF ; G 5285 +U 65200 ; WX 622 ; N uniFEB0 ; G 5286 +U 65201 ; WX 1380 ; N uniFEB1 ; G 5287 +U 65202 ; WX 1414 ; N uniFEB2 ; G 5288 +U 65203 ; WX 983 ; N uniFEB3 ; G 5289 +U 65204 ; WX 1018 ; N uniFEB4 ; G 5290 +U 65205 ; WX 1380 ; N uniFEB5 ; G 5291 +U 65206 ; WX 1414 ; N uniFEB6 ; G 5292 +U 65207 ; WX 983 ; N uniFEB7 ; G 5293 +U 65208 ; WX 1018 ; N uniFEB8 ; G 5294 +U 65209 ; WX 1345 ; N uniFEB9 ; G 5295 +U 65210 ; WX 1364 ; N uniFEBA ; G 5296 +U 65211 ; WX 966 ; N uniFEBB ; G 5297 +U 65212 ; WX 985 ; N uniFEBC ; G 5298 +U 65213 ; WX 1345 ; N uniFEBD ; G 5299 +U 65214 ; WX 1364 ; N uniFEBE ; G 5300 +U 65215 ; WX 966 ; N uniFEBF ; G 5301 +U 65216 ; WX 985 ; N uniFEC0 ; G 5302 +U 65217 ; WX 1039 ; N uniFEC1 ; G 5303 +U 65218 ; WX 1071 ; N uniFEC2 ; G 5304 +U 65219 ; WX 942 ; N uniFEC3 ; G 5305 +U 65220 ; WX 974 ; N uniFEC4 ; G 5306 +U 65221 ; WX 1039 ; N uniFEC5 ; G 5307 +U 65222 ; WX 1071 ; N uniFEC6 ; G 5308 +U 65223 ; WX 942 ; N uniFEC7 ; G 5309 +U 65224 ; WX 974 ; N uniFEC8 ; G 5310 +U 65225 ; WX 683 ; N uniFEC9 ; G 5311 +U 65226 ; WX 683 ; N uniFECA ; G 5312 +U 65227 ; WX 683 ; N uniFECB ; G 5313 +U 65228 ; WX 564 ; N uniFECC ; G 5314 +U 65229 ; WX 683 ; N uniFECD ; G 5315 +U 65230 ; WX 683 ; N uniFECE ; G 5316 +U 65231 ; WX 683 ; N uniFECF ; G 5317 +U 65232 ; WX 564 ; N uniFED0 ; G 5318 +U 65233 ; WX 1162 ; N uniFED1 ; G 5319 +U 65234 ; WX 1191 ; N uniFED2 ; G 5320 +U 65235 ; WX 655 ; N uniFED3 ; G 5321 +U 65236 ; WX 720 ; N uniFED4 ; G 5322 +U 65237 ; WX 894 ; N uniFED5 ; G 5323 +U 65238 ; WX 901 ; N uniFED6 ; G 5324 +U 65239 ; WX 655 ; N uniFED7 ; G 5325 +U 65240 ; WX 720 ; N uniFED8 ; G 5326 +U 65241 ; WX 917 ; N uniFED9 ; G 5327 +U 65242 ; WX 931 ; N uniFEDA ; G 5328 +U 65243 ; WX 582 ; N uniFEDB ; G 5329 +U 65244 ; WX 582 ; N uniFEDC ; G 5330 +U 65245 ; WX 868 ; N uniFEDD ; G 5331 +U 65246 ; WX 893 ; N uniFEDE ; G 5332 +U 65247 ; WX 375 ; N uniFEDF ; G 5333 +U 65248 ; WX 408 ; N uniFEE0 ; G 5334 +U 65249 ; WX 733 ; N uniFEE1 ; G 5335 +U 65250 ; WX 784 ; N uniFEE2 ; G 5336 +U 65251 ; WX 619 ; N uniFEE3 ; G 5337 +U 65252 ; WX 670 ; N uniFEE4 ; G 5338 +U 65253 ; WX 854 ; N uniFEE5 ; G 5339 +U 65254 ; WX 900 ; N uniFEE6 ; G 5340 +U 65255 ; WX 375 ; N uniFEE7 ; G 5341 +U 65256 ; WX 408 ; N uniFEE8 ; G 5342 +U 65257 ; WX 590 ; N uniFEE9 ; G 5343 +U 65258 ; WX 606 ; N uniFEEA ; G 5344 +U 65259 ; WX 693 ; N uniFEEB ; G 5345 +U 65260 ; WX 660 ; N uniFEEC ; G 5346 +U 65261 ; WX 622 ; N uniFEED ; G 5347 +U 65262 ; WX 627 ; N uniFEEE ; G 5348 +U 65263 ; WX 917 ; N uniFEEF ; G 5349 +U 65264 ; WX 1012 ; N uniFEF0 ; G 5350 +U 65265 ; WX 917 ; N uniFEF1 ; G 5351 +U 65266 ; WX 1012 ; N uniFEF2 ; G 5352 +U 65267 ; WX 375 ; N uniFEF3 ; G 5353 +U 65268 ; WX 408 ; N uniFEF4 ; G 5354 +U 65269 ; WX 745 ; N uniFEF5 ; G 5355 +U 65270 ; WX 759 ; N uniFEF6 ; G 5356 +U 65271 ; WX 745 ; N uniFEF7 ; G 5357 +U 65272 ; WX 759 ; N uniFEF8 ; G 5358 +U 65273 ; WX 745 ; N uniFEF9 ; G 5359 +U 65274 ; WX 759 ; N uniFEFA ; G 5360 +U 65275 ; WX 745 ; N uniFEFB ; G 5361 +U 65276 ; WX 759 ; N uniFEFC ; G 5362 +U 65279 ; WX 0 ; N uniFEFF ; G 5363 +U 65529 ; WX 0 ; N uniFFF9 ; G 5364 +U 65530 ; WX 0 ; N uniFFFA ; G 5365 +U 65531 ; WX 0 ; N uniFFFB ; G 5366 +U 65532 ; WX 0 ; N uniFFFC ; G 5367 +U 65533 ; WX 1113 ; N uniFFFD ; G 5368 +EndCharMetrics +StartKernData +StartKernPairs 1538 + +KPX dollar seven -159 +KPX dollar eight -63 +KPX dollar nine -139 +KPX dollar colon -92 +KPX dollar less -196 +KPX dollar Y -73 +KPX dollar backslash -73 +KPX dollar questiondown -73 +KPX dollar Aacute -73 +KPX dollar Hcircumflex -159 +KPX dollar Hbar -159 +KPX dollar Imacron -63 +KPX dollar Ibreve -63 +KPX dollar Iogonek -63 +KPX dollar Idot -63 +KPX dollar IJ -63 +KPX dollar Kcommaaccent -92 +KPX dollar kgreenlandic -196 +KPX dollar Lacute -73 +KPX dollar lacute -196 +KPX dollar uni01DC -159 +KPX dollar uni01F4 -196 +KPX dollar uni01F5 -73 + +KPX percent nine -83 +KPX percent colon -112 +KPX percent less -112 +KPX percent Kcommaaccent -112 +KPX percent kgreenlandic -112 +KPX percent lacute -112 +KPX percent uni01F4 -112 + +KPX ampersand six 38 +KPX ampersand Gcircumflex 38 +KPX ampersand Gbreve 38 +KPX ampersand Gdotaccent 38 +KPX ampersand Gcommaaccent 38 +KPX ampersand uni01DA 38 + +KPX quotesingle less -149 +KPX quotesingle kgreenlandic -149 +KPX quotesingle lacute -149 +KPX quotesingle uni01F4 -149 + +KPX parenright dollar -235 +KPX parenright D -120 +KPX parenright H -83 +KPX parenright R -83 +KPX parenright U -131 +KPX parenright X -102 +KPX parenright backslash -112 +KPX parenright cent -120 +KPX parenright sterling -120 +KPX parenright currency -120 +KPX parenright yen -120 +KPX parenright brokenbar -120 +KPX parenright section -120 +KPX parenright dieresis -120 +KPX parenright ordfeminine -83 +KPX parenright guillemotleft -83 +KPX parenright logicalnot -83 +KPX parenright sfthyphen -83 +KPX parenright acute -83 +KPX parenright mu -83 +KPX parenright paragraph -83 +KPX parenright periodcentered -83 +KPX parenright cedilla -83 +KPX parenright ordmasculine -83 +KPX parenright guillemotright -102 +KPX parenright onequarter -102 +KPX parenright onehalf -102 +KPX parenright threequarters -102 +KPX parenright questiondown -112 +KPX parenright Aacute -112 +KPX parenright Acircumflex -235 +KPX parenright Atilde -120 +KPX parenright Adieresis -235 +KPX parenright Aring -120 +KPX parenright AE -235 +KPX parenright Ccedilla -120 +KPX parenright Otilde -83 +KPX parenright multiply -83 +KPX parenright Ugrave -83 +KPX parenright Ucircumflex -83 +KPX parenright Yacute -83 +KPX parenright dcaron -83 +KPX parenright dmacron -83 +KPX parenright emacron -83 +KPX parenright ebreve -83 +KPX parenright edotaccent -131 +KPX parenright eogonek -131 +KPX parenright ecaron -131 +KPX parenright imacron -102 +KPX parenright ibreve -102 +KPX parenright iogonek -102 +KPX parenright dotlessi -102 +KPX parenright ij -102 +KPX parenright jcircumflex -102 +KPX parenright Lacute -112 +KPX parenright uni01A5 -120 +KPX parenright uni01AD -83 +KPX parenright Uhorn -83 +KPX parenright uni01F1 -83 +KPX parenright uni01F5 -112 + +KPX asterisk seven -36 +KPX asterisk less -45 +KPX asterisk Hbar -36 +KPX asterisk lacute -45 + +KPX period ampersand -92 +KPX period two -92 +KPX period eight -36 +KPX period H -36 +KPX period R -36 +KPX period X -36 +KPX period backslash -131 +KPX period ordfeminine -36 +KPX period guillemotleft -36 +KPX period logicalnot -36 +KPX period sfthyphen -36 +KPX period acute -36 +KPX period mu -36 +KPX period paragraph -36 +KPX period periodcentered -36 +KPX period cedilla -36 +KPX period ordmasculine -36 +KPX period guillemotright -36 +KPX period onequarter -36 +KPX period onehalf -36 +KPX period threequarters -36 +KPX period questiondown -131 +KPX period Aacute -131 +KPX period Egrave -92 +KPX period Icircumflex -92 +KPX period Yacute -36 +KPX period Ebreve -102 +KPX period ebreve -36 +KPX period Idot -36 +KPX period dotlessi -36 + +KPX slash two -73 +KPX slash seven -339 +KPX slash eight -73 +KPX slash nine -282 +KPX slash colon -159 +KPX slash less -319 +KPX slash backslash -139 +KPX slash questiondown -139 +KPX slash Aacute -139 +KPX slash Ebreve -73 +KPX slash Hbar -339 +KPX slash Idot -73 +KPX slash lacute -319 + +KPX two dollar -55 +KPX two nine -55 +KPX two semicolon -73 +KPX two less -73 +KPX two lacute -73 + +KPX three dollar -188 +KPX three D -55 +KPX three V -36 +KPX three backslash 38 +KPX three cent -55 +KPX three sterling -55 +KPX three currency -55 +KPX three yen -55 +KPX three brokenbar -55 +KPX three section -55 +KPX three dieresis -55 +KPX three questiondown 38 +KPX three Aacute 38 +KPX three gdotaccent -36 +KPX three gcommaaccent -36 + + +KPX five seven -92 +KPX five less -112 +KPX five backslash -92 +KPX five questiondown -92 +KPX five Aacute -92 +KPX five Hbar -92 +KPX five lacute -112 + +KPX six six -92 +KPX six Gdotaccent -92 +KPX six Gcommaaccent -92 + +KPX seven dollar -159 +KPX seven seven 47 +KPX seven D -264 +KPX seven F -272 +KPX seven H -272 +KPX seven R -272 +KPX seven U -225 +KPX seven V -272 +KPX seven X -225 +KPX seven Z -225 +KPX seven backslash -243 +KPX seven cent -164 +KPX seven sterling -264 +KPX seven currency -164 +KPX seven yen -164 +KPX seven brokenbar -164 +KPX seven section -164 +KPX seven dieresis -196 +KPX seven copyright -272 +KPX seven ordfeminine -212 +KPX seven guillemotleft -272 +KPX seven logicalnot -212 +KPX seven sfthyphen -212 +KPX seven acute -192 +KPX seven mu -272 +KPX seven paragraph -192 +KPX seven periodcentered -192 +KPX seven cedilla -192 +KPX seven ordmasculine -159 +KPX seven guillemotright -195 +KPX seven onequarter -225 +KPX seven onehalf -195 +KPX seven threequarters -195 +KPX seven questiondown -243 +KPX seven Aacute -243 +KPX seven Eacute -272 +KPX seven Idieresis -272 +KPX seven Yacute -272 +KPX seven ebreve -159 +KPX seven edotaccent -225 +KPX seven ecaron -225 +KPX seven gdotaccent -272 +KPX seven gcommaaccent -272 +KPX seven dotlessi -225 + +KPX eight dollar -63 + +KPX nine dollar -139 +KPX nine two -36 +KPX nine D -112 +KPX nine H -112 +KPX nine L -36 +KPX nine R -112 +KPX nine X -73 +KPX nine cent -112 +KPX nine sterling -112 +KPX nine currency -112 +KPX nine yen -112 +KPX nine brokenbar -112 +KPX nine section -112 +KPX nine dieresis -112 +KPX nine ordfeminine -112 +KPX nine guillemotleft -112 +KPX nine logicalnot -112 +KPX nine sfthyphen -112 +KPX nine acute -112 +KPX nine mu -112 +KPX nine paragraph -112 +KPX nine periodcentered -112 +KPX nine cedilla -112 +KPX nine ordmasculine -112 +KPX nine guillemotright -73 +KPX nine onequarter -73 +KPX nine onehalf -73 +KPX nine threequarters -73 +KPX nine Yacute -112 +KPX nine Ebreve -36 +KPX nine ebreve -112 +KPX nine dotlessi -73 + +KPX colon dollar -92 +KPX colon D -73 +KPX colon H -73 +KPX colon R -73 +KPX colon U -36 +KPX colon cent -73 +KPX colon sterling -73 +KPX colon currency -73 +KPX colon yen -73 +KPX colon brokenbar -73 +KPX colon section -73 +KPX colon dieresis -73 +KPX colon ordfeminine -73 +KPX colon guillemotleft -73 +KPX colon logicalnot -73 +KPX colon sfthyphen -73 +KPX colon acute -73 +KPX colon mu -73 +KPX colon paragraph -73 +KPX colon periodcentered -73 +KPX colon cedilla -73 +KPX colon ordmasculine -73 +KPX colon Yacute -73 +KPX colon ebreve -73 +KPX colon edotaccent -36 +KPX colon ecaron -36 + +KPX semicolon ampersand -73 +KPX semicolon two -73 +KPX semicolon H -55 +KPX semicolon ordfeminine -55 +KPX semicolon guillemotleft -55 +KPX semicolon logicalnot -55 +KPX semicolon sfthyphen -55 +KPX semicolon Egrave -73 +KPX semicolon Icircumflex -73 +KPX semicolon Yacute -55 +KPX semicolon Ebreve -73 + +KPX less dollar -196 +KPX less ampersand -73 +KPX less two -73 +KPX less D -188 +KPX less H -188 +KPX less R -188 +KPX less X -149 +KPX less cent -188 +KPX less sterling -188 +KPX less currency -188 +KPX less yen -188 +KPX less brokenbar -188 +KPX less section -188 +KPX less dieresis -188 +KPX less ordfeminine -188 +KPX less guillemotleft -188 +KPX less logicalnot -188 +KPX less sfthyphen -188 +KPX less acute -188 +KPX less mu -188 +KPX less paragraph -188 +KPX less periodcentered -188 +KPX less cedilla -188 +KPX less ordmasculine -188 +KPX less guillemotright -149 +KPX less onequarter -149 +KPX less onehalf -149 +KPX less threequarters -149 +KPX less Egrave -73 +KPX less Icircumflex -73 +KPX less Yacute -188 +KPX less Ebreve -92 +KPX less ebreve -188 +KPX less dotlessi -149 + + +KPX D backslash -63 +KPX D questiondown -63 +KPX D Aacute -63 + + +KPX N H -55 +KPX N R -55 +KPX N ordfeminine -55 +KPX N guillemotleft -55 +KPX N logicalnot -55 +KPX N sfthyphen -55 +KPX N acute -55 +KPX N mu -55 +KPX N paragraph -55 +KPX N periodcentered -55 +KPX N cedilla -55 +KPX N ordmasculine -45 +KPX N Yacute -55 +KPX N ebreve -55 + + + + + +KPX cent backslash -63 +KPX cent questiondown -63 +KPX cent Aacute -63 + +KPX sterling backslash -63 +KPX sterling questiondown -63 +KPX sterling Aacute -63 + +KPX currency backslash -63 +KPX currency questiondown -63 +KPX currency Aacute -63 + +KPX yen backslash -63 +KPX yen questiondown -63 +KPX yen Aacute -63 + +KPX brokenbar backslash -63 +KPX brokenbar questiondown -63 +KPX brokenbar Aacute -63 + +KPX section backslash -63 +KPX section questiondown -63 +KPX section Aacute -63 + + + +KPX Acircumflex seven -159 +KPX Acircumflex eight -63 +KPX Acircumflex nine -139 +KPX Acircumflex colon -92 +KPX Acircumflex less -196 +KPX Acircumflex Y -73 +KPX Acircumflex backslash -73 +KPX Acircumflex questiondown -73 +KPX Acircumflex Aacute -73 +KPX Acircumflex Hcircumflex -159 +KPX Acircumflex Hbar -159 +KPX Acircumflex Imacron -63 +KPX Acircumflex Ibreve -63 +KPX Acircumflex Iogonek -63 +KPX Acircumflex Idot -63 +KPX Acircumflex IJ -63 +KPX Acircumflex Kcommaaccent -92 +KPX Acircumflex kgreenlandic -196 +KPX Acircumflex Lacute -73 +KPX Acircumflex lacute -196 +KPX Acircumflex uni01DC -159 +KPX Acircumflex uni01F4 -196 +KPX Acircumflex uni01F5 -73 + +KPX Adieresis seven -159 +KPX Adieresis eight -63 +KPX Adieresis nine -139 +KPX Adieresis colon -92 +KPX Adieresis less -196 +KPX Adieresis Y -73 +KPX Adieresis backslash -73 +KPX Adieresis questiondown -73 +KPX Adieresis Aacute -73 +KPX Adieresis Hcircumflex -159 +KPX Adieresis Hbar -159 +KPX Adieresis Imacron -63 +KPX Adieresis Ibreve -63 +KPX Adieresis Iogonek -63 +KPX Adieresis Idot -63 +KPX Adieresis IJ -63 +KPX Adieresis Kcommaaccent -92 +KPX Adieresis kgreenlandic -196 +KPX Adieresis Lacute -73 +KPX Adieresis lacute -196 +KPX Adieresis uni01DC -159 +KPX Adieresis uni01F4 -196 +KPX Adieresis uni01F5 -73 + +KPX AE seven -159 +KPX AE eight -63 +KPX AE nine -139 +KPX AE colon -92 +KPX AE less -196 +KPX AE Y -73 +KPX AE backslash -73 +KPX AE questiondown -73 +KPX AE Aacute -73 +KPX AE Hcircumflex -159 +KPX AE Hbar -159 +KPX AE Imacron -63 +KPX AE Ibreve -63 +KPX AE Iogonek -63 +KPX AE Idot -63 +KPX AE IJ -63 +KPX AE Kcommaaccent -92 +KPX AE kgreenlandic -196 +KPX AE Lacute -73 +KPX AE lacute -196 +KPX AE uni01DC -159 +KPX AE uni01F4 -196 +KPX AE uni01F5 -73 + +KPX Egrave six 38 +KPX Egrave Gcircumflex 38 +KPX Egrave Gbreve 38 +KPX Egrave Gdotaccent 38 +KPX Egrave Gcommaaccent 38 +KPX Egrave uni01DA 38 + +KPX Ecircumflex six 38 +KPX Ecircumflex Gcircumflex 38 +KPX Ecircumflex Gbreve 38 +KPX Ecircumflex Gdotaccent 38 +KPX Ecircumflex Gcommaaccent 38 +KPX Ecircumflex uni01DA 38 + +KPX Igrave six 38 +KPX Igrave Gcircumflex 38 +KPX Igrave Gbreve 38 +KPX Igrave Gdotaccent 38 +KPX Igrave Gcommaaccent 38 +KPX Igrave uni01DA 38 + +KPX Icircumflex six 38 +KPX Icircumflex Gcircumflex 38 +KPX Icircumflex Gbreve 38 +KPX Icircumflex Gdotaccent 38 +KPX Icircumflex Gcommaaccent 38 +KPX Icircumflex uni01DA 38 + +KPX Eth less -149 +KPX Eth kgreenlandic -149 +KPX Eth lacute -149 +KPX Eth uni01F4 -149 + +KPX Ograve less -149 +KPX Ograve kgreenlandic -149 +KPX Ograve lacute -149 +KPX Ograve uni01F4 -149 + +KPX agrave seven -36 +KPX agrave less -45 +KPX agrave Hbar -36 +KPX agrave lacute -45 + +KPX ucircumflex two -73 +KPX ucircumflex seven -339 +KPX ucircumflex eight -73 +KPX ucircumflex nine -282 +KPX ucircumflex colon -159 +KPX ucircumflex less -319 +KPX ucircumflex backslash -139 +KPX ucircumflex questiondown -139 +KPX ucircumflex Aacute -139 +KPX ucircumflex Ebreve -73 +KPX ucircumflex Hbar -339 +KPX ucircumflex Idot -73 +KPX ucircumflex lacute -319 + +KPX ydieresis two -73 +KPX ydieresis seven -339 +KPX ydieresis eight -73 +KPX ydieresis nine -282 +KPX ydieresis colon -159 +KPX ydieresis less -319 +KPX ydieresis backslash -139 +KPX ydieresis questiondown -139 +KPX ydieresis Aacute -139 +KPX ydieresis Ebreve -73 +KPX ydieresis Hbar -339 +KPX ydieresis Idot -73 +KPX ydieresis lacute -319 + +KPX Abreve O -246 + +KPX abreve two -73 +KPX abreve seven -339 +KPX abreve eight -73 +KPX abreve nine -282 +KPX abreve colon -159 +KPX abreve less -319 +KPX abreve backslash -139 +KPX abreve questiondown -139 +KPX abreve Aacute -139 +KPX abreve Ebreve -73 +KPX abreve Hbar -339 +KPX abreve Idot -73 +KPX abreve lacute -319 + +KPX Edotaccent seven -92 +KPX Edotaccent less -112 +KPX Edotaccent backslash -92 +KPX Edotaccent questiondown -92 +KPX Edotaccent Aacute -92 +KPX Edotaccent Hbar -92 +KPX Edotaccent lacute -112 + + +KPX Ecaron seven -92 +KPX Ecaron less -112 +KPX Ecaron backslash -92 +KPX Ecaron questiondown -92 +KPX Ecaron Aacute -92 +KPX Ecaron Hbar -92 +KPX Ecaron lacute -112 + + +KPX Gdotaccent six -92 +KPX Gdotaccent Gdotaccent -92 +KPX Gdotaccent Gcommaaccent -92 + +KPX Gcommaaccent six -92 +KPX Gcommaaccent Gdotaccent -92 +KPX Gcommaaccent Gcommaaccent -92 + +KPX Hbar dollar -159 +KPX Hbar seven 47 +KPX Hbar D -264 +KPX Hbar F -272 +KPX Hbar H -272 +KPX Hbar R -272 +KPX Hbar U -225 +KPX Hbar V -272 +KPX Hbar X -225 +KPX Hbar Z -225 +KPX Hbar backslash -243 +KPX Hbar cent -264 +KPX Hbar sterling -264 +KPX Hbar currency -264 +KPX Hbar yen -264 +KPX Hbar brokenbar -264 +KPX Hbar section -264 +KPX Hbar dieresis -196 +KPX Hbar copyright -272 +KPX Hbar ordfeminine -272 +KPX Hbar guillemotleft -272 +KPX Hbar logicalnot -272 +KPX Hbar sfthyphen -272 +KPX Hbar acute -272 +KPX Hbar mu -272 +KPX Hbar paragraph -272 +KPX Hbar periodcentered -272 +KPX Hbar cedilla -272 +KPX Hbar ordmasculine -159 +KPX Hbar guillemotright -225 +KPX Hbar onequarter -225 +KPX Hbar onehalf -225 +KPX Hbar threequarters -225 +KPX Hbar questiondown -243 +KPX Hbar Aacute -243 +KPX Hbar Eacute -272 +KPX Hbar Idieresis -272 +KPX Hbar Yacute -272 +KPX Hbar ebreve -159 +KPX Hbar edotaccent -225 +KPX Hbar ecaron -225 +KPX Hbar gdotaccent -272 +KPX Hbar gcommaaccent -272 +KPX Hbar Hbar 47 +KPX Hbar dotlessi -225 + +KPX Idot dollar -63 + +KPX lacute dollar -196 +KPX lacute ampersand -73 +KPX lacute two -73 +KPX lacute D -188 +KPX lacute H -188 +KPX lacute R -188 +KPX lacute X -149 +KPX lacute cent -188 +KPX lacute sterling -188 +KPX lacute currency -188 +KPX lacute yen -188 +KPX lacute brokenbar -188 +KPX lacute section -188 +KPX lacute dieresis -188 +KPX lacute ordfeminine -188 +KPX lacute guillemotleft -188 +KPX lacute logicalnot -188 +KPX lacute sfthyphen -188 +KPX lacute acute -188 +KPX lacute mu -188 +KPX lacute paragraph -188 +KPX lacute periodcentered -188 +KPX lacute cedilla -188 +KPX lacute ordmasculine -188 +KPX lacute guillemotright -149 +KPX lacute onequarter -149 +KPX lacute onehalf -149 +KPX lacute threequarters -149 +KPX lacute Egrave -73 +KPX lacute Icircumflex -73 +KPX lacute Yacute -188 +KPX lacute Ebreve -92 +KPX lacute ebreve -188 +KPX lacute dotlessi -149 + + +KPX uni027D dollar -235 +KPX uni027D hyphen -92 +KPX uni027D nine 38 +KPX uni027D less 75 +KPX uni027D lacute 75 +EndKernPairs +EndKernData +EndFontMetrics diff --git a/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ttf b/vendor/dompdf/dompdf/lib/fonts/DejaVuSans-BoldOblique.ttf new file mode 100644 index 0000000000000000000000000000000000000000..753f2d80b1f9a13026d641b6fd4cafb8d85dd479 GIT binary patch literal 643292 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�K>t5e2w`pONAN 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 _Sm54x-B)eBi#i*b3HrW76GSwDCbw}ep<%0yB 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 z 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